Skip to content

Commit

Permalink
[TUF] Pull autoupdate config values from config file OR command-line …
Browse files Browse the repository at this point in the history
…args (#1512)
  • Loading branch information
RebeccaMahany authored Dec 15, 2023
1 parent 977dff8 commit bc7d373
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 8 deletions.
57 changes: 49 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"
)

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:])
if err != nil {
return nil, fmt.Errorf("could not get autoupdate config: %w", err)
}
Expand All @@ -52,21 +53,61 @@ 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 critical flags weren't set, fall back
// to looking in the default config flag file location. (The update directory and local
// development path are both optional flags and not critical to library lookup
// functionality.) We expect all the flags to be set either via config flag (flConfigFilePath
// is set) or via command line (flRootDirectory and flUpdateChannel are set), but do not
// support a mix of both for this usage.
if flConfigFilePath == "" && flRootDirectory == "" && flUpdateChannel == "" {
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

0 comments on commit bc7d373

Please sign in to comment.