Skip to content
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

[TUF] Pull autoupdate config values from config file OR command-line args #1512

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 45 additions & 8 deletions ee/tuf/library_lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/kolide/launcher/pkg/launcher"
"github.com/kolide/launcher/pkg/traces"
"github.com/peterbourgon/ff/v3"
"github.com/spf13/pflag"
RebeccaMahany marked this conversation as resolved.
Show resolved Hide resolved
)

type BinaryUpdateInfo struct {
Expand All @@ -38,7 +39,7 @@ var channelsUsingNewAutoupdater = map[string]bool{
// For now, it is only available when launcher is on the nightly update channel.
func CheckOutLatestWithoutConfig(binary autoupdatableBinary, logger log.Logger) (*BinaryUpdateInfo, error) {
logger = log.With(logger, "component", "tuf_library_lookup")
cfg, err := getAutoupdateConfig()
cfg, err := getAutoupdateConfig(os.Args[1:])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You think os.Args, or should we be passing it in?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly just moved os.Args[1:] up from where it previously was in getAutoupdateConfig() so that I could unit test it. I don't have a strong opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@directionless I'm going to merge this as-is to move this forward, but I'm going to be doing another PR in this same area and I'm can update this there if you'd like

if err != nil {
return nil, fmt.Errorf("could not get autoupdate config: %w", err)
}
Expand All @@ -52,21 +53,57 @@ func CheckOutLatestWithoutConfig(binary autoupdatableBinary, logger log.Logger)
}

func UsingNewAutoupdater() bool {
cfg, err := getAutoupdateConfig()
cfg, err := getAutoupdateConfig(os.Args[1:])
if err != nil {
return false
}

return ChannelUsesNewAutoupdater(cfg.channel)
}

// getAutoupdateConfig reads launcher's config file to determine the configuration values
// needed to work with the autoupdate library.
func getAutoupdateConfig() (*autoupdateConfig, error) {
configFilePath := launcher.ConfigFilePath(os.Args[1:])
if configFilePath == "" {
return nil, errors.New("could not get config file path")
// getAutoupdateConfig pulls the configuration values necessary to work with the autoupdate library
// from either the given args or from the config file.
func getAutoupdateConfig(args []string) (*autoupdateConfig, error) {
// Create a flagset with options that are relevant to autoupdate only.
// Ensure that we won't fail out when we see other command-line options.
pflagSet := pflag.NewFlagSet("autoupdate options", pflag.ContinueOnError)
pflagSet.ParseErrorsWhitelist = pflag.ParseErrorsWhitelist{UnknownFlags: true}

// Extract the config flag plus the autoupdate flags
var flConfigFilePath, flRootDirectory, flUpdateDirectory, flUpdateChannel, flLocalDevelopmentPath string
pflagSet.StringVar(&flConfigFilePath, "config", "", "")
pflagSet.StringVar(&flRootDirectory, "root_directory", "", "")
pflagSet.StringVar(&flUpdateDirectory, "update_directory", "", "")
pflagSet.StringVar(&flUpdateChannel, "update_channel", "", "")
pflagSet.StringVar(&flLocalDevelopmentPath, "localdev_path", "", "")

if err := pflagSet.Parse(args); err != nil {
return nil, fmt.Errorf("parsing command-line flags: %w", err)
}

// If the config file wasn't set AND the other flags weren't set, fall back
// to looking in the default config flag file location
if flConfigFilePath == "" && flRootDirectory == "" && flUpdateChannel == "" {
zackattack01 marked this conversation as resolved.
Show resolved Hide resolved
return getAutoupdateConfigFromFile(launcher.ConfigFilePath(args))
}

if flConfigFilePath != "" {
return getAutoupdateConfigFromFile(flConfigFilePath)
}

cfg := &autoupdateConfig{
rootDirectory: flRootDirectory,
updateDirectory: flUpdateDirectory,
channel: flUpdateChannel,
localDevelopmentPath: flLocalDevelopmentPath,
}

return cfg, nil
}

// getAutoupdateConfigFromFile reads launcher's config file to determine the configuration values
// needed to work with the autoupdate library.
func getAutoupdateConfigFromFile(configFilePath string) (*autoupdateConfig, error) {
if _, err := os.Stat(configFilePath); err != nil && os.IsNotExist(err) {
return nil, fmt.Errorf("could not read config file because it does not exist at %s: %w", configFilePath, err)
}
Expand Down
59 changes: 59 additions & 0 deletions ee/tuf/library_lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,62 @@ func TestChannelUsesNewAutoupdater(t *testing.T) {
require.Equal(t, channel.usesNewAutoupdater, ChannelUsesNewAutoupdater(channel.channelName))
}
}

func Test_getAutoupdateConfig_ConfigFlagSet(t *testing.T) {
t.Parallel()

tempConfDir := t.TempDir()
configFilepath := filepath.Join(tempConfDir, "launcher.flags")

testRootDir := t.TempDir()
testChannel := "nightly"

fileContents := fmt.Sprintf(`
with_initial_runner
autoupdate
hostname localhost
root_directory %s
update_channel %s
transport jsonrpc
`,
testRootDir,
testChannel,
)

require.NoError(t, os.WriteFile(configFilepath, []byte(fileContents), 0755), "expected to set up test config file")

cfg, err := getAutoupdateConfig([]string{"--config", configFilepath})
require.NoError(t, err, "expected no error getting autoupdate config")

require.NotNil(t, cfg, "expected valid autoupdate config")
require.Equal(t, testRootDir, cfg.rootDirectory, "root directory is incorrect")
require.Equal(t, "", cfg.updateDirectory, "update directory should not have been set")
require.Equal(t, testChannel, cfg.channel, "channel is incorrect")
require.Equal(t, "", cfg.localDevelopmentPath, "local development path should not have been set")
}

func Test_getAutoupdateConfig_ConfigFlagNotSet(t *testing.T) {
t.Parallel()

testRootDir := t.TempDir()
testUpdateDir := t.TempDir()
testChannel := "nightly"
testLocaldevPath := filepath.Join("some", "path", "to", "a", "local", "build")

cfg, err := getAutoupdateConfig([]string{
"--root_directory", testRootDir,
"--osquery_flag", "enable_watchdog_debug=true",
"--update_directory", testUpdateDir,
"--autoupdate",
"--update_channel", testChannel,
"--localdev_path", testLocaldevPath,
"--transport", "jsonrpc",
})
require.NoError(t, err, "expected no error getting autoupdate config")

require.NotNil(t, cfg, "expected valid autoupdate config")
require.Equal(t, testRootDir, cfg.rootDirectory, "root directory is incorrect")
require.Equal(t, testUpdateDir, cfg.updateDirectory, "update directory is incorrect")
require.Equal(t, testChannel, cfg.channel, "channel is incorrect")
require.Equal(t, testLocaldevPath, cfg.localDevelopmentPath, "local development path is incorrect")
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ require (
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/tools v0.16.0 // indirect
Expand Down
Loading