-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
converted updater initial delay to select statement, updated updater logging to specify binary being updated #812
Merged
Merged
Changes from 6 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
f96eb01
converted updater initial delay to select statement, updated updater …
James-Pickett 52db948
moved cmd/launcher updater cod eto cmd/launcher/updater package, code…
James-Pickett 44cbc40
added wg to intterupt test to confirm channel receive
James-Pickett f5993c0
removed duplicate logic in test, added wg to exectue test to ensure e…
James-Pickett 5f21f4a
updated comments and function names
James-Pickett c99a2a3
moved cmd/launcher/updater package to cmd/launcher/internal/updater
James-Pickett 34e109c
moving files back to original location before doing git move so they …
James-Pickett 81eec2c
moved files with git to try to get proper diff
James-Pickett 6b9de82
moving updater.go to move again with git to see diff
James-Pickett 7c5fad8
moved file with git to see diff
James-Pickett 15e0cef
fixing package import in launcher.go
James-Pickett 4a7fea0
Merge branch 'master' into initial_delay_bug
James-Pickett File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
package updater | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
"os" | ||
"path/filepath" | ||
"time" | ||
|
||
"github.com/go-kit/kit/log" | ||
"github.com/go-kit/kit/log/level" | ||
"github.com/kolide/kit/actor" | ||
"github.com/kolide/launcher/pkg/autoupdate" | ||
"github.com/kolide/updater/tuf" | ||
) | ||
|
||
// UpdaterConfig is a struct of update related options. It's used to | ||
// simplify the call to `createUpdater` from launcher's main blocks. | ||
type UpdaterConfig struct { | ||
Logger log.Logger | ||
RootDirectory string // launcher's root dir. use for holding tuf staging and updates | ||
AutoupdateInterval time.Duration | ||
UpdateChannel autoupdate.UpdateChannel | ||
InitialDelay time.Duration // start delay, to avoid whomping critical early data | ||
NotaryURL string | ||
MirrorURL string | ||
NotaryPrefix string | ||
HTTPClient *http.Client | ||
SigChannel chan os.Signal | ||
} | ||
|
||
// NewUpdater returns an Actor suitable for an oklog/run group. It | ||
// is a light wrapper around autoupdate.NewUpdater to simplify having | ||
// multiple ones in launcher. | ||
func NewUpdater( | ||
ctx context.Context, | ||
binaryPath string, | ||
finalizer autoupdate.UpdateFinalizer, | ||
config *UpdaterConfig, | ||
) (*actor.Actor, error) { | ||
|
||
if config.Logger == nil { | ||
config.Logger = log.NewNopLogger() | ||
} | ||
|
||
config.Logger = log.With(config.Logger, "updater", filepath.Base(binaryPath)) | ||
|
||
// create the updater | ||
updater, err := autoupdate.NewUpdater( | ||
binaryPath, | ||
config.RootDirectory, | ||
autoupdate.WithLogger(config.Logger), | ||
autoupdate.WithHTTPClient(config.HTTPClient), | ||
autoupdate.WithNotaryURL(config.NotaryURL), | ||
autoupdate.WithMirrorURL(config.MirrorURL), | ||
autoupdate.WithNotaryPrefix(config.NotaryPrefix), | ||
autoupdate.WithFinalizer(finalizer), | ||
autoupdate.WithUpdateChannel(config.UpdateChannel), | ||
autoupdate.WithSigChannel(config.SigChannel), | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
updateCmd := &updaterCmd{ | ||
updater: updater, | ||
ctx: ctx, | ||
stopChan: make(chan bool), | ||
config: config, | ||
runUpdaterRetryInterval: 30 * time.Minute, | ||
} | ||
|
||
return &actor.Actor{ | ||
Execute: updateCmd.execute, | ||
Interrupt: updateCmd.interrupt, | ||
}, nil | ||
} | ||
|
||
// updater allows us to mock *autoupdate.Updater during testing | ||
type updater interface { | ||
Run(opts ...tuf.Option) (stop func(), err error) | ||
} | ||
|
||
type updaterCmd struct { | ||
updater updater | ||
ctx context.Context | ||
stopChan chan bool | ||
stopExecution func() | ||
config *UpdaterConfig | ||
runUpdaterRetryInterval time.Duration | ||
} | ||
|
||
func (u *updaterCmd) execute() error { | ||
// When launcher first starts, we'd like the | ||
// server to start receiving data | ||
// immediately. But, if updater is trying to | ||
// run, this creates an awkward pause for restart. | ||
// So, delay starting updates by an hour or two. | ||
level.Debug(u.config.Logger).Log("msg", "updater entering initial delay", "delay", u.config.InitialDelay) | ||
|
||
select { | ||
case <-u.stopChan: | ||
level.Debug(u.config.Logger).Log("msg", "updater stopped requested during initial delay, Breaking loop") | ||
return nil | ||
case <-time.After(u.config.InitialDelay): | ||
level.Debug(u.config.Logger).Log("msg", "updater initial delay complete") | ||
break | ||
} | ||
|
||
// Failing to start the updater is not a fatal launcher | ||
// error. If there's a problem, sleep and try | ||
// again. Implementing this is a bit gnarly. In the event of a | ||
// success, we get a nil error, and a stop function. But I don't | ||
// see a simple way to ensure the updater is still running in | ||
// the background. | ||
for { | ||
level.Debug(u.config.Logger).Log("msg", "updater starting") | ||
|
||
// run the updater and set the stop function so that the interrupt has access to it | ||
stop, err := u.updater.Run(tuf.WithFrequency(u.config.AutoupdateInterval), tuf.WithLogger(u.config.Logger)) | ||
u.stopExecution = stop | ||
if err == nil { | ||
break | ||
} | ||
|
||
// err != nil, log it and loop again | ||
level.Error(u.config.Logger).Log("msg", "error running updater", "err", err) | ||
select { | ||
case <-u.stopChan: | ||
level.Debug(u.config.Logger).Log("msg", "updater stop requested, Breaking loop") | ||
return nil | ||
case <-time.After(u.runUpdaterRetryInterval): | ||
break | ||
} | ||
} | ||
|
||
level.Debug(u.config.Logger).Log("msg", "updater waiting ... just sitting until done signal") | ||
<-u.ctx.Done() | ||
|
||
return nil | ||
} | ||
|
||
func (u *updaterCmd) interrupt(err error) { | ||
|
||
level.Info(u.config.Logger).Log("msg", "updater interrupted", "err", err) | ||
|
||
// non-blocking channel send | ||
select { | ||
case u.stopChan <- true: | ||
level.Info(u.config.Logger).Log("msg", "updater interrupt sent signal over stop channel") | ||
default: | ||
level.Info(u.config.Logger).Log("msg", "updater interrupt without sending signal over stop channel (no one to receive)") | ||
} | ||
|
||
if u.stopExecution != nil { | ||
u.stopExecution() | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrm. Would this be cleaner if
actor.Actor
defined an interface, not a struct?