diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index a7b7e255fc..50db33ebc1 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -140,11 +140,16 @@ jobs: test-install-script: name: Test Install Script runs-on: ${{ matrix.runs_on }} + container: + image: ${{ inputs.container-image }} strategy: matrix: include: - arch_os: linux_amd64 runs_on: ubuntu-20.04 + - arch_os: linux_amd64 + runs_on: ubuntu-20.04 + container-image: rocky:9 - arch_os: darwin_amd64 runs_on: macos-latest - arch_os: windows_amd64 diff --git a/pkg/scripts_test/.dockerignore b/pkg/scripts_test/.dockerignore new file mode 100644 index 0000000000..3edb0b5eed --- /dev/null +++ b/pkg/scripts_test/.dockerignore @@ -0,0 +1,34 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/engine/reference/builder/#dockerignore-file + +**/.DS_Store +**/__pycache__ +**/.venv +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/pkg/scripts_test/check.go b/pkg/scripts_test/check.go index 708d566601..54db5de5c7 100644 --- a/pkg/scripts_test/check.go +++ b/pkg/scripts_test/check.go @@ -56,7 +56,13 @@ func checkRun(c check) { } func checkConfigDirectoryOwnershipAndPermissions(c check) { - PathHasOwner(c.test, etcPath, rootUser, rootGroup) + ownerUser := systemUser + ownerGroup := systemGroup + if !c.installOptions.useNativePackaging { + ownerUser = rootUser + ownerGroup = rootGroup + } + PathHasOwner(c.test, etcPath, ownerUser, ownerGroup) PathHasPermissions(c.test, etcPath, etcPathPermissions) } @@ -144,6 +150,54 @@ func checkAbortedDueToNoToken(c check) { require.Contains(c.test, c.output[len(c.output)-1], "You can ignore this requirement by adding '--skip-installation-token argument.") } +func preActionInstallPackage(c check) { + c.installOptions.installToken = installToken + c.installOptions.uninstall = false + c.installOptions.purge = false + c.installOptions.apiBaseURL = mockAPIBaseURL + c.code, c.output, c.errorOutput, c.err = runScript(c) +} + +func preActionInstallPackageWithOptions(o installOptions) checkFunc { + return func(c check) { + c.installOptions = o + c.code, c.output, c.errorOutput, c.err = runScript(c) + } +} + +func preActionInstallPackageWithDifferentAPIBaseURL(c check) { + c.installOptions.apiBaseURL = "different" + c.installOptions.apiBaseURL + c.code, c.output, c.errorOutput, c.err = runScript(c) +} + +func preActionInstallPackageWithDifferentTags(c check) { + c.installOptions.tags = map[string]string{ + "some": "tag", + } + c.code, c.output, c.errorOutput, c.err = runScript(c) +} + +func preActionInstallPackageWithNoAPIBaseURL(c check) { + c.installOptions.apiBaseURL = "" + c.code, c.output, c.errorOutput, c.err = runScript(c) +} + +func preActionInstallPackageWithNoTags(c check) { + c.installOptions.tags = nil + c.code, c.output, c.errorOutput, c.err = runScript(c) +} + +func preActionInstallPackageVersion(version string) checkFunc { + return func(c check) { + c.installOptions.installToken = installToken + c.installOptions.uninstall = false + c.installOptions.purge = false + c.installOptions.version = version + c.installOptions.apiBaseURL = mockAPIBaseURL + c.code, c.output, c.errorOutput, c.err = runScript(c) + } +} + func preActionMockConfig(c check) { err := os.MkdirAll(etcPath, fs.FileMode(etcPathPermissions)) require.NoError(c.test, err) @@ -199,10 +253,7 @@ func preActionWriteDifferentTagsToUserConfig(c check) { } func preActionWriteEmptyUserConfig(c check) { - conf, err := getConfig(userConfigPath) - require.NoError(c.test, err) - - err = saveConfig(userConfigPath, conf) + err := saveConfig(userConfigPath, config{}) require.NoError(c.test, err) } @@ -232,6 +283,16 @@ func checkAbortedDueToDifferentTags(c check) { require.Contains(c.test, c.output[len(c.output)-1], "You are trying to install with different tags than in your configuration file!") } +func checkAbortedDueToMissingInstallationToken(c check) { + require.Greater(c.test, len(c.output), 0) + require.Contains(c.test, c.output[len(c.output)-1], "failed to create extension \"sumologic\": access credentials not provided: need installation_token") +} + +func checkAbortedDueToSkipConfigUnsupported(c check) { + require.Greater(c.test, len(c.output), 0) + require.Contains(c.test, c.output[len(c.output)-1], "SKIP_CONFIG is not supported") +} + func PathHasPermissions(t *testing.T, path string, perms uint32) { info, err := os.Stat(path) require.NoError(t, err) diff --git a/pkg/scripts_test/check_darwin.go b/pkg/scripts_test/check_darwin.go index eb8c2a8f99..46176b9232 100644 --- a/pkg/scripts_test/check_darwin.go +++ b/pkg/scripts_test/check_darwin.go @@ -84,7 +84,7 @@ func checkLaunchdConfigNotCreated(c check) { } func checkPackageCreated(c check) { - re, err := regexp.Compile("Package downloaded to: .*/otelcol-sumo.pkg") + re, err := regexp.Compile(`^Package downloaded to: .*/otelcol\-sumo\_\d+\.\d+\.\d+\-\d+\-.*\.pkg$`) require.NoError(c.test, err) matchedLine := "" @@ -118,32 +118,6 @@ func checkUserNotExists(c check) { require.False(c.test, exists, "user has been created") } -func preActionInstallPackage(c check) { - c.code, c.output, c.errorOutput, c.err = runScript(c) -} - -func preActionInstallPackageWithDifferentAPIBaseURL(c check) { - c.installOptions.apiBaseURL = "different" + c.installOptions.apiBaseURL - c.code, c.output, c.errorOutput, c.err = runScript(c) -} - -func preActionInstallPackageWithDifferentTags(c check) { - c.installOptions.tags = map[string]string{ - "some": "tag", - } - c.code, c.output, c.errorOutput, c.err = runScript(c) -} - -func preActionInstallPackageWithNoAPIBaseURL(c check) { - c.installOptions.apiBaseURL = "" - c.code, c.output, c.errorOutput, c.err = runScript(c) -} - -func preActionInstallPackageWithNoTags(c check) { - c.installOptions.tags = nil - c.code, c.output, c.errorOutput, c.err = runScript(c) -} - func preActionMockLaunchdConfig(c check) { f, err := os.Create(launchdPath) require.NoError(c.test, err) diff --git a/pkg/scripts_test/check_linux.go b/pkg/scripts_test/check_linux.go index 28a3514623..0dc95e2a70 100644 --- a/pkg/scripts_test/check_linux.go +++ b/pkg/scripts_test/check_linux.go @@ -7,6 +7,7 @@ import ( "os/exec" "os/user" "path/filepath" + "regexp" "strconv" "strings" "testing" @@ -35,7 +36,20 @@ func checkConfigFilesOwnershipAndPermissions(ownerName string, ownerGroup string if info.IsDir() { permissions = configPathDirPermissions } else { - permissions = configPathFilePermissions + switch path { + case configPath: + // /etc/otelcol-sumo/sumologic.yaml + permissions = configPathFilePermissions + case userConfigPath: + // /etc/otelcol-sumo/conf.d/common.yaml + permissions = commonConfigPathFilePermissions + case tokenEnvFilePath: + // /etc/otelcol-sumo/env/token.env + permissions = commonConfigPathFilePermissions + default: + // /etc/otelcol-sumo/conf.d/**/ + permissions = confDPathFilePermissions + } } PathHasPermissions(c.test, path, permissions) PathHasOwner(c.test, configPath, ownerName, ownerGroup) @@ -45,6 +59,14 @@ func checkConfigFilesOwnershipAndPermissions(ownerName string, ownerGroup string } } +func checkDeprecatedSystemdConfigCreated(c check) { + require.FileExists(c.test, deprecatedSystemdPath, "deprecated systemd configuration has not been created properly") +} + +func checkDeprecatedSystemdConfigNotCreated(c check) { + require.NoFileExists(c.test, deprecatedSystemdPath, "deprecated systemd configuration has been created") +} + func checkDeprecatedTokenInConfig(c check) { require.NotEmpty(c.test, c.installOptions.deprecatedInstallToken, "installation token has not been provided") @@ -80,10 +102,20 @@ func checkDownloadTimeout(c check) { require.Equal(c.test, 6, count) } +func checkGroupExists(c check) { + _, err := user.LookupGroup(systemGroup) + require.NoError(c.test, err, "group has not been created") +} + +func checkGroupNotExists(c check) { + _, err := user.LookupGroup(systemGroup) + require.Error(c.test, err, "group has been created") +} + func checkHostmetricsOwnershipAndPermissions(ownerName string, ownerGroup string) func(c check) { return func(c check) { PathHasOwner(c.test, hostmetricsConfigPath, ownerName, ownerGroup) - PathHasPermissions(c.test, hostmetricsConfigPath, configPathFilePermissions) + PathHasPermissions(c.test, hostmetricsConfigPath, confDPathFilePermissions) } } @@ -95,6 +127,22 @@ func checkOutputUserAddWarnings(c check) { require.NotContains(c.test, errOutput, "useradd", "unexpected useradd output") } +func checkPackageCreated(c check) { + re, err := regexp.Compile(`^Package downloaded to: .*/otelcol\-sumo\-\d+\.\d+\.\d+\-\d+\..*\.(deb|rpm)$`) + require.NoError(c.test, err) + + matchedLine := "" + for _, line := range c.output { + if re.MatchString(line) { + matchedLine = line + } + } + require.NotEmpty(c.test, matchedLine, "package path not in output") + + packagePath := strings.TrimPrefix(matchedLine, "Package downloaded to: ") + require.FileExists(c.test, packagePath, "package has not been created") +} + func checkSystemdAvailability(c check) bool { return assert.DirExists(&testing.T{}, systemdDirectoryPath, "systemd is not supported") } @@ -202,6 +250,13 @@ func preActionMockConfigs(c check) { preActionMockUserConfig(c) } +func preActionMockDeprecatedSystemdStructure(c check) { + preActionMockStructure(c) + + _, err := os.Create(deprecatedSystemdPath) + require.NoError(c.test, err) +} + func preActionMockEnvFiles(c check) { err := os.MkdirAll(envDirectoryPath, fs.FileMode(etcPathPermissions)) require.NoError(c.test, err) diff --git a/pkg/scripts_test/command.go b/pkg/scripts_test/command.go index ea2ef5703b..446a72001e 100644 --- a/pkg/scripts_test/command.go +++ b/pkg/scripts_test/command.go @@ -31,6 +31,8 @@ type installOptions struct { dontKeepDownloads bool installHostmetrics bool timeout float64 + useNativePackaging bool + version string } func (io *installOptions) string() []string { @@ -96,6 +98,14 @@ func (io *installOptions) string() []string { opts = append(opts, "--download-timeout", fmt.Sprintf("%f", io.timeout)) } + if io.useNativePackaging { + opts = append(opts, "--use-native-packaging") + } + + if io.version != "" { + opts = append(opts, "--version", io.version) + } + return opts } @@ -114,6 +124,11 @@ func (io *installOptions) buildEnvs() []string { e = append(e, fmt.Sprintf("%s=%s", deprecatedInstallTokenEnv, io.deprecatedInstallToken)) } + // Enable non-interactive deb package installation & force default config + // conflict resolution + e = append(e, "DEBIAN_FRONTEND=noninteractive") + e = append(e, "DPKG_FORCE=confdef") + return e } diff --git a/pkg/scripts_test/common.go b/pkg/scripts_test/common.go index b086ed05f6..4d93f193f1 100644 --- a/pkg/scripts_test/common.go +++ b/pkg/scripts_test/common.go @@ -3,6 +3,9 @@ package sumologic_scripts_tests import ( + "context" + "io" + "net/http" "os" "testing" @@ -43,6 +46,25 @@ func runTest(t *testing.T, spec *testSpec) { defer tearDown(t) + t.Log("Starting HTTP server") + mux := http.NewServeMux() + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "200 OK\n") + }) + httpServer := &http.Server{ + Addr: ":3333", + Handler: mux, + } + go func() { + err := httpServer.ListenAndServe() + if err != nil && err != http.ErrServerClosed { + require.NoError(t, err) + } + }() + defer func() { + require.NoError(t, httpServer.Shutdown(context.Background())) + }() + t.Log("Running pre actions") for _, a := range spec.preActions { a(ch) @@ -53,6 +75,7 @@ func runTest(t *testing.T, spec *testSpec) { c(ch) } + t.Log("Running install script") ch.code, ch.output, ch.errorOutput, ch.err = runScript(ch) // Remove cache in case of curl issue diff --git a/pkg/scripts_test/consts.go b/pkg/scripts_test/consts.go index 1eb155e95f..bd7f6df9a4 100644 --- a/pkg/scripts_test/consts.go +++ b/pkg/scripts_test/consts.go @@ -17,6 +17,18 @@ const ( installTokenEnv string = "SUMOLOGIC_INSTALLATION_TOKEN" deprecatedInstallTokenEnv string = "SUMOLOGIC_INSTALL_TOKEN" apiBaseURL string = "https://open-collectors.sumologic.com" + mockAPIBaseURL string = "http://127.0.0.1:3333" + + // previousVersion specifies a previous version to test upgrades from. It is + // necessary to upgrade from an older version as same-version package + // upgrades can behave differently than proper upgrades. + previousVersion string = "0.79.0-453" curlTimeoutErrorCode int = 28 + + commonConfigPathFilePermissions uint32 = 0660 + configPathDirPermissions uint32 = 0770 + configPathFilePermissions uint32 = 0640 + confDPathFilePermissions uint32 = 0644 + etcPathPermissions uint32 = 0751 ) diff --git a/pkg/scripts_test/consts_darwin.go b/pkg/scripts_test/consts_darwin.go index 193502575f..982e3af4d5 100644 --- a/pkg/scripts_test/consts_darwin.go +++ b/pkg/scripts_test/consts_darwin.go @@ -7,14 +7,6 @@ const ( launchdPathFilePermissions uint32 = 0640 uninstallScriptPath string = appSupportDirPath + "/uninstall.sh" - // TODO: fix mismatch between darwin permissions & linux binary install permissions - // common.yaml must be writable as the install scripts mutate it - commonConfigPathFilePermissions uint32 = 0660 - configPathDirPermissions uint32 = 0770 - configPathFilePermissions uint32 = 0440 - confDPathFilePermissions uint32 = 0644 - etcPathPermissions uint32 = 0755 - rootGroup string = "wheel" rootUser string = "root" systemGroup string = "_otelcol-sumo" diff --git a/pkg/scripts_test/consts_linux.go b/pkg/scripts_test/consts_linux.go index 84126e572d..6beca24a43 100644 --- a/pkg/scripts_test/consts_linux.go +++ b/pkg/scripts_test/consts_linux.go @@ -1,17 +1,11 @@ package sumologic_scripts_tests const ( - envDirectoryPath string = etcPath + "/env" - systemdDirectoryPath string = "/run/systemd/system" - systemdPath string = "/etc/systemd/system/otelcol-sumo.service" - tokenEnvFilePath string = envDirectoryPath + "/token.env" - - // TODO: fix mismatch between package permissions & expected permissions - commonConfigPathFilePermissions uint32 = 0550 - configPathDirPermissions uint32 = 0550 - configPathFilePermissions uint32 = 0440 - confDPathFilePermissions uint32 = 0644 - etcPathPermissions uint32 = 0551 + envDirectoryPath string = etcPath + "/env" + systemdDirectoryPath string = "/run/systemd/system" + systemdPath string = "/lib/systemd/system/otelcol-sumo.service" + deprecatedSystemdPath string = "/etc/systemd/system/otelcol-sumo.service" + tokenEnvFilePath string = envDirectoryPath + "/token.env" rootGroup string = "root" rootUser string = "root" diff --git a/pkg/scripts_test/install_darwin_test.go b/pkg/scripts_test/install_darwin_test.go index 80af459425..70ac64359b 100644 --- a/pkg/scripts_test/install_darwin_test.go +++ b/pkg/scripts_test/install_darwin_test.go @@ -3,6 +3,7 @@ package sumologic_scripts_tests import ( + "fmt" "testing" ) @@ -108,12 +109,14 @@ func TestInstallScriptDarwin(t *testing.T) { skipInstallToken: true, autoconfirm: true, }, - preActions: []checkFunc{preActionMockConfig}, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + }, preChecks: []checkFunc{ - checkBinaryNotCreated, + checkBinaryCreated, checkConfigCreated, - checkUserConfigNotCreated, - checkUserNotExists, + checkUserConfigCreated, + checkUserExists, }, postChecks: []checkFunc{ checkBinaryCreated, @@ -224,11 +227,11 @@ func TestInstallScriptDarwin(t *testing.T) { { name: "same api base url", options: installOptions{ - apiBaseURL: apiBaseURL, + apiBaseURL: mockAPIBaseURL, skipInstallToken: true, }, preActions: []checkFunc{ - preActionInstallPackage, + preActionInstallPackageVersion(previousVersion), }, preChecks: []checkFunc{ checkBinaryCreated, @@ -423,6 +426,10 @@ func TestInstallScriptDarwin(t *testing.T) { }, }, } { + // Always use native packaging on Darwin + spec.name = fmt.Sprintf("native packaging -- %s", spec.name) + spec.options.useNativePackaging = true + t.Run(spec.name, func(t *testing.T) { runTest(t, &spec) }) diff --git a/pkg/scripts_test/install_unix_test.go b/pkg/scripts_test/install_unix_test.go index bc3d3a78f2..b2ad511e3d 100644 --- a/pkg/scripts_test/install_unix_test.go +++ b/pkg/scripts_test/install_unix_test.go @@ -7,12 +7,32 @@ import ( ) func TestInstallScript(t *testing.T) { + notInstalledChecks := []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + checkGroupNotExists, + checkUserConfigNotCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + } + for _, spec := range []testSpec{ { name: "no arguments", options: installOptions{}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkAbortedDueToNoToken, checkUserNotExists}, + preChecks: notInstalledChecks, + postChecks: append(notInstalledChecks, checkAbortedDueToNoToken), + installCode: 1, + }, + { + name: "native packaging -- no arguments", + options: installOptions{ + useNativePackaging: true, + }, + preChecks: notInstalledChecks, + postChecks: append(notInstalledChecks, checkAbortedDueToNoToken), installCode: 1, }, { @@ -20,8 +40,25 @@ func TestInstallScript(t *testing.T) { options: installOptions{ downloadOnly: true, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkSystemdConfigNotCreated, checkUserNotExists}, + preChecks: notInstalledChecks, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + checkUserNotExists, + checkGroupNotExists, + }, + }, + { + name: "native packaging -- download only", + options: installOptions{ + downloadOnly: true, + useNativePackaging: true, + }, + preChecks: notInstalledChecks, + postChecks: append(notInstalledChecks, checkPackageCreated), }, { name: "download only with timeout", @@ -32,26 +69,64 @@ func TestInstallScript(t *testing.T) { }, // Skip this test as getting binary in github actions takes less than one second conditionalChecks: []condCheckFunc{checkSkipTest}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkSystemdConfigNotCreated, checkUserNotExists, - checkDownloadTimeout}, + preChecks: notInstalledChecks, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + checkUserNotExists, + checkDownloadTimeout, + }, installCode: curlTimeoutErrorCode, }, + { + name: "native packaging -- download only with timeout", + options: installOptions{ + downloadOnly: true, + timeout: 1, + dontKeepDownloads: true, + useNativePackaging: true, + }, + // Skip this test as getting binary in github actions takes less than one second + conditionalChecks: []condCheckFunc{checkSkipTest}, + preChecks: notInstalledChecks, + postChecks: append(notInstalledChecks, checkDownloadTimeout), + installCode: curlTimeoutErrorCode, + }, { name: "skip config", options: installOptions{ skipConfig: true, skipInstallToken: true, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkConfigNotCreated, checkUserConfigNotCreated}, + preChecks: notInstalledChecks, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + }, + }, + { + name: "native packaging -- skip config", + options: installOptions{ + skipConfig: true, + skipInstallToken: true, + useNativePackaging: true, + }, + preChecks: notInstalledChecks, + postChecks: append(notInstalledChecks, []checkFunc{ + checkAbortedDueToSkipConfigUnsupported, + }...), + installCode: 1, }, { name: "skip installation token", options: installOptions{ skipInstallToken: true, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, + preChecks: notInstalledChecks, postChecks: []checkFunc{ checkBinaryCreated, checkBinaryIsRunning, @@ -59,7 +134,26 @@ func TestInstallScript(t *testing.T) { checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup), checkUserConfigNotCreated, checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- skip installation token", + options: installOptions{ + skipInstallToken: true, + useNativePackaging: true, + }, + preChecks: notInstalledChecks, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup), + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, }, + installCode: 1, }, { name: "override default config", @@ -68,9 +162,47 @@ func TestInstallScript(t *testing.T) { autoconfirm: true, }, preActions: []checkFunc{preActionMockConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigCreated, checkUserConfigNotCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkConfigOverrided, checkUserConfigNotCreated, - checkSystemdConfigNotCreated}, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigOverrided, + checkUserConfigNotCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- override default config", + options: installOptions{ + installToken: installToken, + autoconfirm: true, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigOverrided, + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, }, { name: "installation token only", @@ -78,7 +210,12 @@ func TestInstallScript(t *testing.T) { skipSystemd: true, installToken: installToken, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, postChecks: []checkFunc{ checkBinaryCreated, checkBinaryIsRunning, @@ -87,18 +224,45 @@ func TestInstallScript(t *testing.T) { checkUserConfigCreated, checkTokenInConfig, checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, checkUserNotExists, checkHostmetricsConfigNotCreated, checkTokenEnvFileNotCreated, }, }, + { + name: "native packaging -- installation token only", + options: installOptions{ + installToken: installToken, + useNativePackaging: true, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup), + checkUserConfigCreated, + checkTokenInEnvFile, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkUserExists, + checkHostmetricsConfigNotCreated, + checkTokenEnvFileCreated, + }, + }, { name: "deprecated installation token only", options: installOptions{ skipSystemd: true, deprecatedInstallToken: installToken, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, + preChecks: notInstalledChecks, postChecks: []checkFunc{ checkBinaryCreated, checkBinaryIsRunning, @@ -107,6 +271,7 @@ func TestInstallScript(t *testing.T) { checkUserConfigCreated, checkDeprecatedTokenInConfig, checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, checkUserNotExists, checkHostmetricsConfigNotCreated, }, @@ -118,7 +283,7 @@ func TestInstallScript(t *testing.T) { installToken: installToken, installHostmetrics: true, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, + preChecks: notInstalledChecks, postChecks: []checkFunc{ checkBinaryCreated, checkBinaryIsRunning, @@ -127,11 +292,34 @@ func TestInstallScript(t *testing.T) { checkUserConfigCreated, checkTokenInConfig, checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, checkUserNotExists, checkHostmetricsConfigCreated, checkHostmetricsOwnershipAndPermissions(rootUser, rootGroup), }, }, + { + name: "native packaging -- installation token and hostmetrics", + options: installOptions{ + installToken: installToken, + installHostmetrics: true, + useNativePackaging: true, + }, + preChecks: notInstalledChecks, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup), + checkUserConfigCreated, + checkTokenInEnvFile, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkUserExists, + checkHostmetricsConfigCreated, + checkHostmetricsOwnershipAndPermissions(systemUser, systemGroup), + }, + }, { name: "installation token only, binary not in PATH", options: installOptions{ @@ -141,7 +329,7 @@ func TestInstallScript(t *testing.T) { "PATH": "/sbin:/bin:/usr/sbin:/usr/bin", }, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, + preChecks: notInstalledChecks, postChecks: []checkFunc{ checkBinaryCreated, checkBinaryIsRunning, @@ -150,370 +338,1348 @@ func TestInstallScript(t *testing.T) { checkUserConfigCreated, checkTokenInConfig, checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, checkUserNotExists, }, }, { - name: "same installation token", + name: "native packaging -- installation token only, binary not in PATH", options: installOptions{ - skipSystemd: true, installToken: installToken, + envs: map[string]string{ + "PATH": "/sbin:/bin:/usr/sbin:/usr/bin", + }, + useNativePackaging: true, + }, + preChecks: notInstalledChecks, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup), + checkUserConfigCreated, + checkTokenInEnvFile, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkUserExists, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteTokenToUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkUserConfigCreated, checkTokenInConfig, checkSystemdConfigNotCreated}, }, { - name: "different installation token", + name: "same installation token", options: installOptions{ skipSystemd: true, installToken: installToken, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentTokenToUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkSystemdConfigNotCreated, checkAbortedDueToDifferentToken}, - installCode: 1, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteTokenToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkTokenInConfig, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, }, { - name: "adding installation token", + name: "native packaging -- same installation token", options: installOptions{ - skipSystemd: true, - installToken: installToken, + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkTokenInEnvFile, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, }, - preActions: []checkFunc{preActionMockUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkTokenInConfig, checkSystemdConfigNotCreated}, }, { - name: "editing installation token", + name: "different installation token", options: installOptions{ skipSystemd: true, - apiBaseURL: apiBaseURL, installToken: installToken, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteEmptyUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkTokenInConfig, checkSystemdConfigNotCreated}, - }, - { - name: "same api base url", - options: installOptions{ - skipSystemd: true, - apiBaseURL: apiBaseURL, - skipInstallToken: true, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteDifferentTokenToUserConfig, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteAPIBaseURLToUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkUserConfigCreated, checkAPIBaseURLInConfig, - checkSystemdConfigNotCreated}, - }, - { - name: "different api base url", - options: installOptions{ - skipSystemd: true, - apiBaseURL: apiBaseURL, - skipInstallToken: true, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentAPIBaseURLToUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkSystemdConfigNotCreated, - checkAbortedDueToDifferentAPIBaseURL}, - installCode: 1, - }, - { - name: "adding api base url", - options: installOptions{ - skipSystemd: true, - apiBaseURL: apiBaseURL, - skipInstallToken: true, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + checkAbortedDueToDifferentToken, }, - preActions: []checkFunc{preActionMockUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkAPIBaseURLInConfig, checkSystemdConfigNotCreated}, + installCode: 1, }, { - name: "editing api base url", + name: "native packaging -- different installation token", options: installOptions{ - skipSystemd: true, - apiBaseURL: apiBaseURL, - skipInstallToken: true, + installToken: installToken, + useNativePackaging: true, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteEmptyUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkAPIBaseURLInConfig, checkSystemdConfigNotCreated}, - }, - { - name: "empty installation token", - options: installOptions{ - skipSystemd: true, + preActions: []checkFunc{ + preActionInstallPackage, + preActionWriteDifferentTokenToUserConfig, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentTokenToUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkSystemdConfigNotCreated, checkDifferentTokenInConfig}, - }, - { - name: "configuration with tags", - options: installOptions{ - skipSystemd: true, - skipInstallToken: true, - tags: map[string]string{ - "lorem": "ipsum", - "foo": "bar", - "escape_me": "'\\/", - "slash": "a/b", - "numeric": "1_024", - }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, postChecks: []checkFunc{ checkBinaryCreated, - checkBinaryIsRunning, checkConfigCreated, - checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup), - checkTags, - checkSystemdConfigNotCreated, + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkAbortedDueToDifferentToken, }, + installCode: 1, }, { - name: "same tags", + name: "adding installation token", options: installOptions{ - skipSystemd: true, + skipSystemd: true, + installToken: installToken, + }, + preActions: []checkFunc{preActionMockUserConfig}, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkTokenInConfig, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- adding installation token", + options: installOptions{ + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkTokenInEnvFile, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "editing installation token", + options: installOptions{ + skipSystemd: true, + apiBaseURL: apiBaseURL, + installToken: installToken, + }, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteEmptyUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkTokenInConfig, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- editing installation token", + options: installOptions{ + apiBaseURL: apiBaseURL, + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + preActionWriteEmptyUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkTokenInEnvFile, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "same api base url", + options: installOptions{ + skipSystemd: true, + apiBaseURL: apiBaseURL, skipInstallToken: true, - tags: map[string]string{ - "lorem": "ipsum", - "foo": "bar", - "escape_me": "'\\/", - "slash": "a/b", - "numeric": "1_024", - }, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteTagsToUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkUserConfigCreated, checkTags, - checkSystemdConfigNotCreated}, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteAPIBaseURLToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkAPIBaseURLInConfig, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- same api base url", + options: installOptions{ + apiBaseURL: apiBaseURL, + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + preActionWriteAPIBaseURLToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkAPIBaseURLInConfig, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "different api base url", + options: installOptions{ + skipSystemd: true, + apiBaseURL: apiBaseURL, + skipInstallToken: true, + }, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteDifferentAPIBaseURLToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + checkAbortedDueToDifferentAPIBaseURL, + }, + installCode: 1, + }, + { + name: "native packaging -- different api base url", + options: installOptions{ + apiBaseURL: apiBaseURL, + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackage, + preActionWriteDifferentAPIBaseURLToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkAbortedDueToDifferentAPIBaseURL, + }, + installCode: 1, + }, + { + name: "adding api base url", + options: installOptions{ + skipSystemd: true, + apiBaseURL: apiBaseURL, + skipInstallToken: true, + }, + preActions: []checkFunc{preActionMockUserConfig}, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkAPIBaseURLInConfig, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- adding api base url", + options: installOptions{ + apiBaseURL: apiBaseURL, + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageWithOptions(installOptions{ + apiBaseURL: mockAPIBaseURL, + installToken: installToken, + useNativePackaging: true, + version: previousVersion, + }), + preActionWriteEmptyUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkAPIBaseURLInConfig, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "editing api base url", + options: installOptions{ + skipSystemd: true, + apiBaseURL: apiBaseURL, + skipInstallToken: true, + }, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteEmptyUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkAPIBaseURLInConfig, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- editing api base url", + options: installOptions{ + apiBaseURL: apiBaseURL, + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageWithOptions(installOptions{ + apiBaseURL: mockAPIBaseURL, + installToken: installToken, + useNativePackaging: true, + }), + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + installCode: 1, + }, + { + name: "empty installation token", + options: installOptions{ + skipSystemd: true, + }, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteDifferentTokenToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + checkDifferentTokenInConfig, + }, + }, + { + name: "native packaging -- upgrade with empty installation token", + options: installOptions{ + installToken: "", + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + preActionWriteDifferentTokenToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkDifferentTokenInConfig, + }, + }, + { + name: "configuration with tags", + options: installOptions{ + skipSystemd: true, + skipInstallToken: true, + tags: map[string]string{ + "lorem": "ipsum", + "foo": "bar", + "escape_me": "'\\/", + "slash": "a/b", + "numeric": "1_024", + }, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup), + checkTags, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- configuration with tags", + options: installOptions{ + installToken: installToken, + tags: map[string]string{ + "lorem": "ipsum", + "foo": "bar", + }, + useNativePackaging: true, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup), + checkTags, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "same tags", + options: installOptions{ + skipSystemd: true, + skipInstallToken: true, + tags: map[string]string{ + "lorem": "ipsum", + "foo": "bar", + "escape_me": "'\\/", + "slash": "a/b", + "numeric": "1_024", + }, + }, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteTagsToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkTags, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- same tags", + options: installOptions{ + installToken: installToken, + tags: map[string]string{ + "lorem": "ipsum", + "foo": "bar", + }, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + preActionWriteTagsToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkTags, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "different tags", + options: installOptions{ + skipSystemd: true, + skipInstallToken: true, + tags: map[string]string{ + "lorem": "ipsum", + "foo": "bar", + "escape_me": "'\\/", + "slash": "a/b", + "numeric": "1_024", + }, + }, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteDifferentTagsToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkDifferentTags, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + checkAbortedDueToDifferentTags, + }, + installCode: 1, + }, + { + name: "native packaging -- different tags", + options: installOptions{ + skipSystemd: true, + skipInstallToken: true, + tags: map[string]string{ + "lorem": "ipsum", + "foo": "bar", + }, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + preActionWriteDifferentTagsToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkDifferentTags, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkAbortedDueToDifferentTags, + }, + installCode: 1, + }, + { + name: "editing tags", + options: installOptions{ + skipSystemd: true, + skipInstallToken: true, + tags: map[string]string{ + "lorem": "ipsum", + "foo": "bar", + "escape_me": "'\\/", + "slash": "a/b", + "numeric": "1_024", + }, + }, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteEmptyUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkTags, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- editing tags", + options: installOptions{ + installToken: installToken, + tags: map[string]string{ + "lorem": "ipsum", + "foo": "bar", + }, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + preActionWriteEmptyUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkTags, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "systemd", + options: installOptions{ + installToken: installToken, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + checkTokenEnvFileNotCreated, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), + checkUserConfigNotCreated, + checkDeprecatedSystemdConfigCreated, + checkSystemdConfigNotCreated, + checkSystemdEnvDirExists, + checkSystemdEnvDirPermissions, + checkTokenEnvFileCreated, + checkTokenInEnvFile, + checkUserExists, + checkVarLogACL, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + installCode: 3, // because of invalid installation token + }, + { + name: "native packaging -- systemd", + options: installOptions{ + installToken: installToken, + useNativePackaging: true, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + checkTokenEnvFileNotCreated, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), + checkUserConfigNotCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkSystemdEnvDirExists, + checkSystemdEnvDirPermissions, + checkTokenEnvFileCreated, + checkTokenInEnvFile, + checkUserExists, + checkVarLogACL, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + installCode: 3, // because of invalid installation token + }, + { + name: "systemd installation token with existing user directory", + options: installOptions{ + installToken: installToken, + }, + preActions: []checkFunc{preActionCreateHomeDirectory}, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + checkHomeDirectoryCreated, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigCreated, + checkSystemdEnvDirExists, + checkSystemdEnvDirPermissions, + checkTokenEnvFileCreated, + checkTokenInEnvFile, + checkUserExists, + checkVarLogACL, + checkOutputUserAddWarnings, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + installCode: 3, // because of invalid install token + }, + { + name: "native packaging -- systemd installation token with existing user directory", + options: installOptions{ + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{preActionCreateHomeDirectory}, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + checkHomeDirectoryCreated, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkSystemdEnvDirExists, + checkSystemdEnvDirPermissions, + checkTokenEnvFileCreated, + checkTokenInEnvFile, + checkUserExists, + checkVarLogACL, + checkOutputUserAddWarnings, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + installCode: 3, // because of invalid install token + }, + { + name: "systemd existing installation different token env", + options: installOptions{ + installToken: installToken, + }, + preActions: []checkFunc{preActionCreateHomeDirectory}, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + checkHomeDirectoryCreated, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigCreated, + checkSystemdEnvDirExists, + checkSystemdEnvDirPermissions, + checkTokenEnvFileCreated, + checkTokenInEnvFile, + checkUserExists, + checkVarLogACL, + checkOutputUserAddWarnings, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + installCode: 3, // because of invalid install token + }, + { + name: "native packaging -- systemd existing installation different token env", + options: installOptions{ + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{preActionCreateHomeDirectory}, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + checkHomeDirectoryCreated, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkSystemdEnvDirExists, + checkSystemdEnvDirPermissions, + checkTokenEnvFileCreated, + checkTokenInEnvFile, + checkUserExists, + checkVarLogACL, + checkOutputUserAddWarnings, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + installCode: 3, // because of invalid install token + }, + { + name: "installation of hostmetrics in systemd during upgrade", + options: installOptions{ + installToken: installToken, + installHostmetrics: true, + }, + preActions: []checkFunc{ + preActionMockDeprecatedSystemdStructure, + preActionCreateUser, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkTokenInEnvFile, + checkUserExists, + checkHostmetricsConfigCreated, + checkHostmetricsOwnershipAndPermissions(systemUser, systemUser), + }, + }, + { + name: "native packaging -- installation of hostmetrics in systemd during upgrade", + options: installOptions{ + installToken: installToken, + installHostmetrics: true, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionMockSystemdStructure, + preActionCreateUser, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkTokenInEnvFile, + checkUserExists, + checkHostmetricsConfigCreated, + checkHostmetricsOwnershipAndPermissions(systemUser, systemUser), + }, + }, + { + name: "uninstallation without autoconfirm fails", + options: installOptions{ + uninstall: true, + }, + installCode: 1, + preActions: []checkFunc{preActionMockStructure}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + }, + }, + { + name: "native packaging -- uninstallation without autoconfirm fails", + options: installOptions{ + uninstall: true, + useNativePackaging: true, + }, + installCode: 1, + preActions: []checkFunc{preActionInstallPackage}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + }, + }, + { + name: "uninstallation with autoconfirm", + options: installOptions{ + autoconfirm: true, + uninstall: true, + }, + preActions: []checkFunc{preActionMockStructure}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUninstallationOutput, + }, + }, + { + name: "native packaging -- uninstallation with autoconfirm", + options: installOptions{ + autoconfirm: true, + uninstall: true, + useNativePackaging: true, + }, + preActions: []checkFunc{preActionInstallPackage}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, + }, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkUninstallationOutput, + }, + }, + { + name: "systemd uninstallation", + options: installOptions{ + autoconfirm: true, + uninstall: true, + }, + preActions: []checkFunc{preActionMockDeprecatedSystemdStructure}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigCreated, + checkUserNotExists, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, }, { - name: "different tags", + name: "native packaging -- systemd uninstallation", options: installOptions{ - skipSystemd: true, - skipInstallToken: true, - tags: map[string]string{ - "lorem": "ipsum", - "foo": "bar", - "escape_me": "'\\/", - "slash": "a/b", - "numeric": "1_024", - }, + autoconfirm: true, + uninstall: true, + useNativePackaging: true, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentTagsToUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkDifferentTags, checkSystemdConfigNotCreated, - checkAbortedDueToDifferentTags}, - installCode: 1, + preActions: []checkFunc{preActionMockSystemdStructure}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + checkUserNotExists, + }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, }, { - name: "editing tags", + name: "purge", options: installOptions{ - skipSystemd: true, - skipInstallToken: true, - tags: map[string]string{ - "lorem": "ipsum", - "foo": "bar", - "escape_me": "'\\/", - "slash": "a/b", - "numeric": "1_024", - }, + uninstall: true, + purge: true, + autoconfirm: true, + }, + preActions: []checkFunc{preActionMockStructure}, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, }, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteEmptyUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkTags, checkSystemdConfigNotCreated}, }, { - name: "systemd", + name: "native packaging -- purge", options: installOptions{ - installToken: installToken, + uninstall: true, + purge: true, + autoconfirm: true, + useNativePackaging: true, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists, checkTokenEnvFileNotCreated}, - postChecks: []checkFunc{ + preActions: []checkFunc{preActionInstallPackage}, + preChecks: []checkFunc{ checkBinaryCreated, - checkBinaryIsRunning, checkConfigCreated, - checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), - checkUserConfigNotCreated, - checkSystemdConfigCreated, - checkSystemdEnvDirExists, - checkSystemdEnvDirPermissions, - checkTokenEnvFileCreated, - checkTokenInEnvFile, + checkUserConfigCreated, checkUserExists, - checkVarLogACL, }, - conditionalChecks: []condCheckFunc{checkSystemdAvailability}, - installCode: 3, // because of invalid installation token + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + }, }, { - name: "systemd installation token with existing user directory", + name: "systemd purge", options: installOptions{ - installToken: installToken, + uninstall: true, + purge: true, + autoconfirm: true, }, - preActions: []checkFunc{preActionCreateHomeDirectory}, + preActions: []checkFunc{preActionMockSystemdStructure}, preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, checkUserNotExists, - checkHomeDirectoryCreated, }, - postChecks: []checkFunc{ + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + }, + { + name: "native packaging -- systemd purge", + options: installOptions{ + uninstall: true, + purge: true, + autoconfirm: true, + useNativePackaging: true, + }, + preActions: []checkFunc{preActionMockSystemdStructure}, + preChecks: []checkFunc{ checkBinaryCreated, - checkBinaryIsRunning, checkConfigCreated, - checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), + checkUserConfigCreated, checkSystemdConfigCreated, - checkSystemdEnvDirExists, - checkSystemdEnvDirPermissions, - checkTokenEnvFileCreated, - checkTokenInEnvFile, - checkUserExists, - checkVarLogACL, - checkOutputUserAddWarnings, + checkDeprecatedSystemdConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkBinaryNotCreated, + checkConfigNotCreated, + checkUserConfigNotCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + checkUserNotExists, }, conditionalChecks: []condCheckFunc{checkSystemdAvailability}, - installCode: 3, // because of invalid install token }, { - name: "systemd existing installation different token env", - options: installOptions{ - installToken: installToken, + name: "systemd creation if token in file", + options: installOptions{}, + preActions: []checkFunc{ + preActionMockUserConfig, + preActionWriteDifferentTokenToUserConfig, + preActionWriteDefaultAPIBaseURLToUserConfig, }, - preActions: []checkFunc{preActionCreateHomeDirectory}, preChecks: []checkFunc{ checkBinaryNotCreated, checkConfigNotCreated, - checkUserConfigNotCreated, + checkUserConfigCreated, checkUserNotExists, - checkHomeDirectoryCreated, }, postChecks: []checkFunc{ checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, - checkConfigFilesOwnershipAndPermissions(systemUser, systemUser), - checkSystemdConfigCreated, - checkSystemdEnvDirExists, - checkSystemdEnvDirPermissions, - checkTokenEnvFileCreated, - checkTokenInEnvFile, + checkDifferentTokenInConfig, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigCreated, checkUserExists, - checkVarLogACL, - checkOutputUserAddWarnings, + checkTokenEnvFileNotCreated, }, conditionalChecks: []condCheckFunc{checkSystemdAvailability}, - installCode: 3, // because of invalid install token + installCode: 3, // because of invalid installation token }, { - name: "installation of hostmetrics in systemd during upgrade", + name: "native packaging -- systemd creation if token in file", options: installOptions{ - installToken: installToken, - installHostmetrics: true, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionInstallPackageVersion(previousVersion), + preActionWriteDifferentTokenToUserConfig, + preActionWriteDefaultAPIBaseURLToUserConfig, + }, + preChecks: []checkFunc{ + checkBinaryCreated, + checkConfigCreated, + checkUserConfigCreated, + checkUserExists, }, - preActions: []checkFunc{preActionMockSystemdStructure, preActionCreateUser}, - conditionalChecks: []condCheckFunc{checkSystemdAvailability}, - preChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkUserExists}, postChecks: []checkFunc{ checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, - checkUserConfigCreated, - checkTokenInEnvFile, + checkDifferentTokenInConfig, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, checkUserExists, - checkHostmetricsConfigCreated, - checkHostmetricsOwnershipAndPermissions(systemUser, systemUser), + checkTokenEnvFileNotCreated, }, + conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + installCode: 3, // because of invalid installation token }, { - name: "uninstallation without autoconfirm fails", + name: "systemd installation if token in file", options: installOptions{ - uninstall: true, + installToken: installToken, }, - installCode: 1, - preActions: []checkFunc{preActionMockStructure}, - preChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated}, - }, - { - name: "uninstallation with autoconfirm", - options: installOptions{ - autoconfirm: true, - uninstall: true, + preActions: []checkFunc{ + preActionWriteDifferentTokenToEnvFile, }, - preActions: []checkFunc{preActionMockStructure}, - preChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigCreated, checkUserConfigCreated, checkUninstallationOutput}, - }, - { - name: "systemd uninstallation", - options: installOptions{ - autoconfirm: true, - uninstall: true, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkDifferentTokenInEnvFile, + checkAbortedDueToDifferentToken, }, - preActions: []checkFunc{preActionMockSystemdStructure}, - preChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkSystemdConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigCreated, checkUserConfigCreated, checkSystemdConfigCreated, checkUserNotExists}, conditionalChecks: []condCheckFunc{checkSystemdAvailability}, + installCode: 1, // because of invalid installation token }, { - name: "purge", + name: "native packaging -- systemd installation if token in file", options: installOptions{ - uninstall: true, - purge: true, - autoconfirm: true, + installToken: installToken, + useNativePackaging: true, }, - preActions: []checkFunc{preActionMockStructure}, - preChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated}, - }, - { - name: "systemd purge", - options: installOptions{ - uninstall: true, - purge: true, - autoconfirm: true, + preActions: []checkFunc{ + preActionWriteDifferentTokenToEnvFile, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkDifferentTokenInEnvFile, + checkAbortedDueToDifferentToken, }, - preActions: []checkFunc{preActionMockSystemdStructure}, - preChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkSystemdConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkSystemdConfigNotCreated, checkUserNotExists}, - conditionalChecks: []condCheckFunc{checkSystemdAvailability}, - }, - { - name: "systemd creation if token in file", - options: installOptions{}, - preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentTokenToUserConfig, preActionWriteDefaultAPIBaseURLToUserConfig}, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkDifferentTokenInConfig, checkSystemdConfigCreated, - checkUserExists, checkTokenEnvFileNotCreated}, conditionalChecks: []condCheckFunc{checkSystemdAvailability}, - installCode: 3, // because of invalid installation token + installCode: 1, // because of invalid installation token }, { - name: "systemd installation if token in file", + name: "systemd installation if deprecated token in file", options: installOptions{ installToken: installToken, }, - preActions: []checkFunc{preActionWriteDifferentTokenToEnvFile}, - preChecks: []checkFunc{checkBinaryNotCreated, checkUserConfigNotCreated, checkUserNotExists}, - postChecks: []checkFunc{checkDifferentTokenInEnvFile, checkAbortedDueToDifferentToken}, + preActions: []checkFunc{ + preActionWriteDifferentDeprecatedTokenToEnvFile, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkDifferentTokenInEnvFile, + checkAbortedDueToDifferentToken, + }, conditionalChecks: []condCheckFunc{checkSystemdAvailability}, installCode: 1, // because of invalid installation token }, { - name: "systemd installation if deprecated token in file", + name: "native packaging -- systemd installation if deprecated token in file", options: installOptions{ - installToken: installToken, + installToken: installToken, + useNativePackaging: true, + }, + preActions: []checkFunc{ + preActionWriteDifferentDeprecatedTokenToEnvFile, + }, + preChecks: []checkFunc{ + checkBinaryNotCreated, + checkUserConfigNotCreated, + checkUserNotExists, + }, + postChecks: []checkFunc{ + checkDifferentTokenInEnvFile, + checkAbortedDueToDifferentToken, }, - preActions: []checkFunc{preActionWriteDifferentDeprecatedTokenToEnvFile}, - preChecks: []checkFunc{checkBinaryNotCreated, checkUserConfigNotCreated, checkUserNotExists}, - postChecks: []checkFunc{checkDifferentTokenInEnvFile, checkAbortedDueToDifferentToken}, conditionalChecks: []condCheckFunc{checkSystemdAvailability}, installCode: 1, // because of invalid installation token }, @@ -523,8 +1689,32 @@ func TestInstallScript(t *testing.T) { skipInstallToken: true, dontKeepDownloads: true, }, - preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated, checkUserNotExists}, - postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkUserConfigNotCreated, checkSystemdConfigNotCreated}, + preChecks: notInstalledChecks, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigNotCreated, + checkSystemdConfigNotCreated, + checkDeprecatedSystemdConfigNotCreated, + }, + }, + { + name: "native packaging -- don't keep downloads", + options: installOptions{ + installToken: installToken, + dontKeepDownloads: true, + useNativePackaging: true, + }, + preChecks: notInstalledChecks, + postChecks: []checkFunc{ + checkBinaryCreated, + checkBinaryIsRunning, + checkConfigCreated, + checkUserConfigCreated, + checkSystemdConfigCreated, + checkDeprecatedSystemdConfigNotCreated, + }, }, } { t.Run(spec.name, func(t *testing.T) { diff --git a/scripts/install.sh b/scripts/install.sh index 20fa782ac3..fe0e04de8c 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -46,6 +46,11 @@ ARG_SHORT_INSTALL_HOSTMETRICS='H' ARG_LONG_INSTALL_HOSTMETRICS='install-hostmetrics' ARG_SHORT_TIMEOUT='m' ARG_LONG_TIMEOUT='download-timeout' +ARG_SHORT_USE_NATIVE_PACKAGING='x' +ARG_LONG_USE_NATIVE_PACKAGING='use-native-packaging' + +BINARY_GITHUB_ORG="SumoLogic" +BINARY_GITHUB_REPO="sumologic-otel-collector" PACKAGE_GITHUB_ORG="SumoLogic" PACKAGE_GITHUB_REPO="sumologic-otel-collector-packaging" @@ -59,6 +64,7 @@ readonly ARG_SHORT_BRANCH ARG_LONG_BRANCH ARG_SHORT_SKIP_CONFIG ARG_LONG_SKIP_CO readonly ARG_SHORT_SKIP_TOKEN ARG_LONG_SKIP_TOKEN ARG_SHORT_FIPS ARG_LONG_FIPS ENV_TOKEN readonly ARG_SHORT_INSTALL_HOSTMETRICS ARG_LONG_INSTALL_HOSTMETRICS readonly ARG_SHORT_TIMEOUT ARG_LONG_TIMEOUT +readonly ARG_SHORT_USE_NATIVE_PACKAGING ARG_LONG_USE_NATIVE_PACKAGING readonly DEPRECATED_ARG_LONG_TOKEN DEPRECATED_ENV_TOKEN DEPRECATED_ARG_LONG_SKIP_TOKEN readonly PACKAGE_GITHUB_ORG PACKAGE_GITHUB_REPO @@ -90,9 +96,11 @@ SKIP_TOKEN="" SKIP_CONFIG=false CONFIG_PATH="" COMMON_CONFIG_PATH="" +HOSTMETRICS_CONFIG_PATH="" PURGE="" DOWNLOAD_ONLY="" INSTALL_HOSTMETRICS=false +USE_NATIVE_PACKAGING=false LAUNCHD_CONFIG="" LAUNCHD_ENV_KEY="" @@ -128,14 +136,15 @@ function usage() { cat << EOF Usage: bash install.sh [--${ARG_LONG_TOKEN} ] [--${ARG_LONG_TAG} = [ --${ARG_LONG_TAG} ...]] [--${ARG_LONG_API} ] [--${ARG_LONG_VERSION} ] \\ - [--${ARG_LONG_YES}] [--${ARG_LONG_VERSION} ] [--${ARG_LONG_HELP}] + [--${ARG_LONG_YES}] [--${ARG_LONG_VERSION} ] [--${ARG_LONG_USE_NATIVE_PACKAGING}] [--${ARG_LONG_HELP}] Supported arguments: -${ARG_SHORT_TOKEN}, --${ARG_LONG_TOKEN} Installation token. It has precedence over 'SUMOLOGIC_INSTALLATION_TOKEN' env variable. - -${ARG_SHORT_SKIP_TOKEN}, --${ARG_LONG_SKIP_TOKEN} Skips requirement for installation token. + -${ARG_SHORT_SKIP_TOKEN}, --${ARG_LONG_SKIP_TOKEN} Skips requirement for installation token. This option do not disable default configuration creation. + -${ARG_SHORT_USE_NATIVE_PACKAGING}, --${ARG_LONG_USE_NATIVE_PACKAGING} Use native package installation rather than binary installation. -${ARG_SHORT_TAG}, --${ARG_LONG_TAG} Sets tag for collector. This argument can be use multiple times. One per tag. - -${ARG_SHORT_DOWNLOAD}, --${ARG_LONG_DOWNLOAD} Download new binary only and skip configuration part. + -${ARG_SHORT_DOWNLOAD}, --${ARG_LONG_DOWNLOAD} Download new binary or package only and skip configuration part. -${ARG_SHORT_UNINSTALL}, --${ARG_LONG_UNINSTALL} Removes Sumo Logic Distribution for OpenTelemetry Collector from the system and disable Systemd service eventually. @@ -156,7 +165,7 @@ Supported arguments: -${ARG_SHORT_HELP}, --${ARG_LONG_HELP} Prints this help and usage. Supported env variables: - ${ENV_TOKEN}= Installation token.' + ${ENV_TOKEN}= Installation token. EOF } @@ -173,6 +182,7 @@ function set_defaults() { CONFIG_PATH="${CONFIG_DIRECTORY}/sumologic.yaml" COMMON_CONFIG_PATH="${USER_CONFIG_DIRECTORY}/common.yaml" COMMON_CONFIG_BAK_PATH="${USER_CONFIG_DIRECTORY}/common.yaml.bak" + HOSTMETRICS_CONFIG_PATH="${CONFIG_DIRECTORY}/conf.d/hostmetrics.yaml" INDENTATION=" " EXT_INDENTATION="${INDENTATION}${INDENTATION}" @@ -258,6 +268,9 @@ function parse_options() { "--${ARG_LONG_INSTALL_HOSTMETRICS}") set -- "$@" "-${ARG_SHORT_INSTALL_HOSTMETRICS}" ;; + "-${ARG_SHORT_USE_NATIVE_PACKAGING}"|--"${ARG_LONG_USE_NATIVE_PACKAGING}") + set -- "$@" "-${ARG_SHORT_USE_NATIVE_PACKAGING}" + ;; -*) echo "Unknown option ${arg}"; usage; exit 1 ;; *) @@ -270,7 +283,7 @@ function parse_options() { while true; do set +e - getopts "${ARG_SHORT_HELP}${ARG_SHORT_TOKEN}:${ARG_SHORT_API}:${ARG_SHORT_TAG}:${ARG_SHORT_VERSION}:${ARG_SHORT_FIPS}${ARG_SHORT_YES}${ARG_SHORT_SKIP_SYSTEMD}${ARG_SHORT_UNINSTALL}${ARG_SHORT_PURGE}${ARG_SHORT_SKIP_TOKEN}${ARG_SHORT_SKIP_CONFIG}${ARG_SHORT_DOWNLOAD}${ARG_SHORT_KEEP_DOWNLOADS}${ARG_SHORT_CONFIG_BRANCH}:${ARG_SHORT_BINARY_BRANCH}:${ARG_SHORT_BRANCH}:${ARG_SHORT_INSTALL_HOSTMETRICS}${ARG_SHORT_TIMEOUT}:" opt + getopts "${ARG_SHORT_HELP}${ARG_SHORT_TOKEN}:${ARG_SHORT_API}:${ARG_SHORT_TAG}:${ARG_SHORT_VERSION}:${ARG_SHORT_FIPS}${ARG_SHORT_YES}${ARG_SHORT_SKIP_SYSTEMD}${ARG_SHORT_UNINSTALL}${ARG_SHORT_PURGE}${ARG_SHORT_SKIP_TOKEN}${ARG_SHORT_SKIP_CONFIG}${ARG_SHORT_DOWNLOAD}${ARG_SHORT_KEEP_DOWNLOADS}${ARG_SHORT_CONFIG_BRANCH}:${ARG_SHORT_BINARY_BRANCH}:${ARG_SHORT_BRANCH}:${ARG_SHORT_INSTALL_HOSTMETRICS}${ARG_SHORT_TIMEOUT}:${ARG_SHORT_USE_NATIVE_PACKAGING}" opt set -e # Invalid argument catched, print and exit @@ -306,6 +319,7 @@ function parse_options() { "${ARG_SHORT_INSTALL_HOSTMETRICS}") INSTALL_HOSTMETRICS=true ;; "${ARG_SHORT_KEEP_DOWNLOADS}") KEEP_DOWNLOADS=true ;; "${ARG_SHORT_TIMEOUT}") CURL_MAX_TIME="${OPTARG}" ;; + "${ARG_SHORT_USE_NATIVE_PACKAGING}") USE_NATIVE_PACKAGING=true ;; "${ARG_SHORT_TAG}") if [[ "${OPTARG}" != ?*"="* ]]; then echo "Invalid tag: '${OPTARG}'. Should be in 'key=value' format" @@ -648,6 +662,50 @@ function print_breaking_changes() { fi } +function write_env_token() { + if [[ -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && -z "${USER_TOKEN}" ]]; then + echo 'Writing installation token to env file' + write_installation_token_env "${SUMOLOGIC_INSTALLATION_TOKEN}" "${TOKEN_ENV_FILE}" + fi +} + +function install_hostmetrics() { + if [[ "${INSTALL_HOSTMETRICS}" == "true" ]]; then + echo -e "Installing ${OS_TYPE} hostmetrics configuration" + HOSTMETRICS_CONFIG_URL="https://raw.githubusercontent.com/SumoLogic/sumologic-otel-collector/${CONFIG_BRANCH}/examples/conf.d/${OS_TYPE}.yaml" + if ! curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 --retry-max-time 150 -f -s "${HOSTMETRICS_CONFIG_URL}" -o "${HOSTMETRICS_CONFIG_PATH}"; then + echo "Cannot obtain hostmetrics configuration for '${CONFIG_BRANCH}' branch. Either '${HOSTMETRICS_CONFIG_URL}' is invalid, or the network connection is unstable." + exit 1 + fi + + if [[ "${SYSTEMD_DISABLED}" != "true" || "${USE_NATIVE_PACKAGING}" == "true" ]]; then + chown "${SYSTEM_USER}":"${SYSTEM_USER}" "${HOSTMETRICS_CONFIG_PATH}" + fi + + chmod 644 "${HOSTMETRICS_CONFIG_PATH}" + fi +} + +function update_api_base_url() { + # get user api url again as it may have changed after package installation + USER_API_URL="$(get_user_api_url "${COMMON_CONFIG_PATH}")" + + # fill in api base url + if [[ -n "${API_BASE_URL}" && -z "${USER_API_URL}" ]]; then + write_api_url "${API_BASE_URL}" "${COMMON_CONFIG_PATH}" "${EXT_INDENTATION}" + fi +} + +function update_tags() { + # get user fields again as they may have changed after package installation + USER_FIELDS="$(get_user_tags "${COMMON_CONFIG_PATH}" "${INDENTATION}" "${EXT_INDENTATION}")" + + # fill in tags + if [[ -n "${FIELDS}" && -z "${USER_FIELDS}" ]]; then + write_tags "${FIELDS}" "${COMMON_CONFIG_PATH}" "${INDENTATION}" "${EXT_INDENTATION}" + fi +} + # set up configuration function setup_config() { echo 'We are going to get and set up a default configuration for you' @@ -665,10 +723,10 @@ function setup_config() { mkdir -p "${USER_ENV_DIRECTORY}" echo 'Changing permissions for config files and storage' - chmod 551 "${CONFIG_DIRECTORY}" # config directory world traversable, as is the /etc/ standard + chmod 751 "${CONFIG_DIRECTORY}" # config directory world traversable, as is the /etc/ standard echo 'Changing permissions for user env directory' - chmod 550 "${USER_ENV_DIRECTORY}" + chmod 770 "${USER_ENV_DIRECTORY}" chmod g+s "${USER_ENV_DIRECTORY}" echo "Generating configuration and saving as ${CONFIG_PATH}" @@ -679,14 +737,7 @@ function setup_config() { exit 1 fi - if [[ "${INSTALL_HOSTMETRICS}" == "true" ]]; then - echo -e "Installing ${OS_TYPE} hostmetrics configuration" - HOSTMETRICS_CONFIG_URL="https://raw.githubusercontent.com/SumoLogic/sumologic-otel-collector/${CONFIG_BRANCH}/examples/conf.d/${OS_TYPE}.yaml" - if ! curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 --retry-max-time 150 -f -s "${HOSTMETRICS_CONFIG_URL}" -o "${CONFIG_DIRECTORY}/conf.d/hostmetrics.yaml"; then - echo "Cannot obtain hostmetrics configuration for '${CONFIG_BRANCH}' branch. Either '${HOSTMETRICS_CONFIG_URL}' is invalid, or the network connection is unstable." - exit 1 - fi - fi + install_hostmetrics # Ensure that configuration is created if [[ -f "${COMMON_CONFIG_PATH}" ]]; then @@ -703,37 +754,44 @@ function setup_config() { write_installation_token "${SUMOLOGIC_INSTALLATION_TOKEN}" "${COMMON_CONFIG_PATH}" "${EXT_INDENTATION}" fi - # fill in api base url - if [[ -n "${API_BASE_URL}" && -z "${USER_API_URL}" ]]; then - write_api_url "${API_BASE_URL}" "${COMMON_CONFIG_PATH}" "${EXT_INDENTATION}" - fi - - if [[ -n "${FIELDS}" && -z "${USER_FIELDS}" ]]; then - write_tags "${FIELDS}" "${COMMON_CONFIG_PATH}" "${INDENTATION}" "${EXT_INDENTATION}" - fi + update_api_base_url + update_tags # clean up bak file rm -f "${COMMON_CONFIG_BAK_PATH}" fi # Finish setting permissions after we're done creating config files - chmod -R 440 "${CONFIG_DIRECTORY}"/* # all files only readable by the owner - find "${CONFIG_DIRECTORY}/" -mindepth 1 -type d -exec chmod 550 {} \; # directories also traversable + chmod -R 640 "${CONFIG_DIRECTORY}"/* # all files only readable by the owner + if [[ -f "${USER_CONFIG_DIRECTORY}" ]]; then + chmod -R 640 "${USER_CONFIG_DIRECTORY}" + fi + if [[ -f "${COMMON_CONFIG_PATH}" ]]; then + chmod 660 "${COMMON_CONFIG_PATH}" + fi + if [[ -f "${HOSTMETRICS_CONFIG_PATH}" ]]; then + chmod 644 "${HOSTMETRICS_CONFIG_PATH}" + fi + find "${CONFIG_DIRECTORY}/" -mindepth 1 -type d -exec chmod 770 {} \; # directories also traversable } function setup_config_darwin() { - create_user_config_file "${COMMON_CONFIG_PATH}" add_extension_to_config "${COMMON_CONFIG_PATH}" write_sumologic_extension "${COMMON_CONFIG_PATH}" "${INDENTATION}" + update_api_base_url + update_tags - # fill in api base url - if [[ -n "${API_BASE_URL}" ]]; then - write_api_url "${API_BASE_URL}" "${COMMON_CONFIG_PATH}" "${EXT_INDENTATION}" - fi + # clean up bak file + rm -f "${COMMON_CONFIG_BAK_PATH}" +} - if [[ -n "${FIELDS}" ]]; then - write_tags "${FIELDS}" "${COMMON_CONFIG_PATH}" "${INDENTATION}" "${EXT_INDENTATION}" - fi +# setup config for linux packages +function setup_config_linux() { + add_extension_to_config "${COMMON_CONFIG_PATH}" + write_sumologic_extension "${COMMON_CONFIG_PATH}" "${INDENTATION}" + update_api_base_url + update_tags + write_env_token # clean up bak file rm -f "${COMMON_CONFIG_BAK_PATH}" @@ -758,7 +816,7 @@ function uninstall_darwin() { local UNINSTALL_SCRIPT_PATH UNINSTALL_SCRIPT_PATH="/Library/Application Support/otelcol-sumo/uninstall.sh" - echo "Going to uninstall otelcol-sumo." + echo "Going to uninstall otelcol-sumo otelcol-sumo package" if [[ "${PURGE}" == "true" ]]; then echo "WARNING: purge is not yet supported on darwin" @@ -769,26 +827,65 @@ function uninstall_darwin() { "${UNINSTALL_SCRIPT_PATH}" } +function deb_is_installed() { + local name + readonly name="${1}" + + command -v dpkg &> /dev/null && dpkg -s "${name}" +} + +function rpm_is_installed() { + local name + readonly name="${1}" + + command -v rpm &> /dev/null && rpm -q "${name}" +} + # uninstall otelcol-sumo on linux function uninstall_linux() { - local MSG - MSG="Going to remove Otelcol binary" + local INSTALL_TYPE + INSTALL_TYPE="binary" - if [[ "${PURGE}" == "true" ]]; then - MSG="${MSG}, user, file storage and configurations" + if rpm_is_installed "otelcol-sumo"; then + INSTALL_TYPE="rpm" fi - echo "${MSG}." - ask_to_continue - - # disable systemd service - if [[ -f "${SYSTEMD_CONFIG}" ]]; then - systemctl stop otelcol-sumo || true - systemctl disable otelcol-sumo || true + if deb_is_installed "otelcol-sumo"; then + INSTALL_TYPE="deb" fi - # remove binary - rm -f "${SUMO_BINARY_PATH}" + case "$INSTALL_TYPE" in + deb) + echo "Going to remove otelcol-sumo deb package" + ask_to_continue + dpkg -P otelcol-sumo + ;; + rpm) + echo "Going to remove otelcol-sumo rpm package" + ask_to_continue + rpm -e otelcol-sumo + ;; + binary) + local MSG + MSG="Going to remove Otelcol binary" + + if [[ "${PURGE}" == "true" ]]; then + MSG="${MSG}, user, file storage and configurations" + fi + + echo "${MSG}." + ask_to_continue + + # disable systemd service + if [[ -f "${SYSTEMD_CONFIG}" ]]; then + systemctl stop otelcol-sumo || true + systemctl disable otelcol-sumo || true + fi + + # remove binary + rm -f "${SUMO_BINARY_PATH}" + ;; + esac if [[ "${PURGE}" == "true" ]]; then # remove configuration and data @@ -803,8 +900,6 @@ function uninstall_linux() { fi fi fi - - echo "Uninstallation completed" } function escape_sed() { @@ -1068,7 +1163,7 @@ function create_user_config_file() { fi touch "${file}" - chmod 440 "${file}" + chmod 660 "${file}" } # write extensions section to user configuration file @@ -1235,55 +1330,19 @@ function write_tags() { fi } -function get_binary_from_branch() { - local branch - readonly branch="${1}" - - local name - readonly name="${2}" - - - local actions_url actions_output artifacts_link artifact_id - readonly actions_url="https://api.github.com/repos/SumoLogic/sumologic-otel-collector/actions/runs?status=success&branch=${branch}&event=push&per_page=1" - echo -e "Getting artifacts from latest CI run for branch \"${branch}\":\t\t${actions_url}" - actions_output="$(curl -f -sS \ - --connect-timeout 5 \ - --max-time 30 \ - --retry 5 \ - --retry-delay 0 \ - --retry-max-time 150 \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${actions_url}")" - readonly actions_output - - # get latest action run - artifacts_link="$(echo "${actions_output}" | grep '"url"' | grep -oE '"https.*collector/actions.*"' -m 1)" - # strip first and last double-quote from $artifacts_link - artifacts_link=${artifacts_link%\"} - artifacts_link="${artifacts_link#\"}" - artifacts_link="${artifacts_link}/artifacts" - readonly artifacts_link +function get_file_from_url() { + local url download_path download_filename extra_curl_args + readonly url="${1}" + readonly download_path="${2}" + shift 2 + readonly extra_curl_args=("$@") - echo -e "Getting artifact id for CI run:\t\t${artifacts_link}" - artifact_id="$(curl -f -sS \ - --connect-timeout 5 \ - --max-time 30 \ - --retry 5 \ - --retry-delay 0 \ - --retry-max-time 150 \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${artifacts_link}" \ - | grep -E '"(id|name)"' \ - | grep -B 1 "\"${name}\"" -m 1 \ - | grep -oE "[0-9]+" -m 1)" - readonly artifact_id + local download_filename download_cache_path + download_filename="$(basename "${download_path}")" + download_cache_path="${DOWNLOAD_CACHE_DIR}/${download_filename}" + readonly download_filename download_cache_path - local artifact_url download_path curl_args - readonly artifact_url="https://api.github.com/repos/SumoLogic/sumologic-otel-collector/actions/artifacts/${artifact_id}/zip" - readonly download_path="${DOWNLOAD_CACHE_DIR}/${name}.zip" - echo -e "Downloading binary from: ${artifact_url}" + echo -e "Downloading:\t\t${url}" curl_args=( "-fL" "--connect-timeout" "5" @@ -1291,156 +1350,107 @@ function get_binary_from_branch() { "--retry" "5" "--retry-delay" "0" "--retry-max-time" "150" - "--output" "${download_path}" + "--output" "${download_cache_path}" "--progress-bar" ) + curl_args+=( "${extra_curl_args[@]}" ) + if [ "${KEEP_DOWNLOADS}" == "true" ]; then - curl_args+=("-z" "${download_path}") + curl_args+=("-z" "${download_cache_path}") fi - curl "${curl_args[@]}" \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${artifact_url}" - unzip -p "$download_path" "${name}" >"${TMPDIR}"/otelcol-sumo + curl "${curl_args[@]}" "${url}" + + cp -f "${download_cache_path}" "${download_path}" + if [ "${KEEP_DOWNLOADS}" == "false" ]; then - rm -f "${download_path}" + rm -f "${download_cache_path}" fi } -function get_binary_from_url() { - local url download_filename download_path curl_args +function get_output_from_github_api() { + local url readonly url="${1}" - echo -e "Downloading:\t\t${url}" - download_filename=$(basename "${url}") - readonly download_filename - readonly download_path="${DOWNLOAD_CACHE_DIR}/${download_filename}" curl_args=( - "-fL" + "-f" + "-sS" "--connect-timeout" "5" - "--max-time" "${CURL_MAX_TIME}" + "--max-time" "30" "--retry" "5" "--retry-delay" "0" "--retry-max-time" "150" - "--output" "${download_path}" - "--progress-bar" + "-H" "Accept: application/vnd.github+json" + "-H" "Authorization: token ${GITHUB_TOKEN}" ) - if [ "${KEEP_DOWNLOADS}" == "true" ]; then - curl_args+=("-z" "${download_path}") - fi - curl "${curl_args[@]}" "${url}" - - cp -f "${download_path}" "${TMPDIR}"/otelcol-sumo - if [ "${KEEP_DOWNLOADS}" == "false" ]; then - rm -f "${download_path}" - fi + curl "${curl_args[@]}" "${url}" } -function get_package_from_branch() { - local branch - readonly branch="${1}" +function get_github_actions_artifact() { + local org repo branch artifact_regex destination_path + readonly org="${1}" + readonly repo="${2}" + readonly branch="${3}" + readonly artifact_regex="${4}" + readonly destination_path="${5}" - local name - readonly name="${2}" + local base_url actions_url + readonly base_url="https://api.github.com/repos/${org}/${repo}/actions" + readonly actions_url="${base_url}/runs?status=success&branch=${branch}&event=push&per_page=1" - local actions_url actions_output artifacts_link artifact_id - readonly actions_url="https://api.github.com/repos/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/actions/runs?status=success&branch=${branch}&event=push&per_page=1" echo -e "Getting artifacts from latest CI run for branch \"${branch}\":\t\t${actions_url}" - actions_output="$(curl -f -sS \ - --connect-timeout 5 \ - --max-time 30 \ - --retry 5 \ - --retry-delay 0 \ - --retry-max-time 150 \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${actions_url}")" + actions_output="$(get_output_from_github_api "${actions_url}")" readonly actions_output # get latest action run - artifacts_link="$(echo "${actions_output}" | grep '"url"' | grep -oE '"https.*packaging/actions.*"' -m 1)" - + url_regex="\"https.*${org}/${repo}/actions.*\"" + artifacts_link="$(echo "${actions_output}" | grep '"url"' | grep -oE "${url_regex}" -m 1)" # strip first and last double-quote from $artifacts_link artifacts_link=${artifacts_link%\"} artifacts_link="${artifacts_link#\"}" artifacts_link="${artifacts_link}/artifacts" readonly artifacts_link - echo -e "Getting artifact id for CI run:\t\t${artifacts_link}" - artifact_id="$(curl -f -sS \ - --connect-timeout 5 \ - --max-time 30 \ - --retry 5 \ - --retry-delay 0 \ - --retry-max-time 150 \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${artifacts_link}" \ - | grep -E '"(id|name)"' \ - | grep -B 1 "\"${name}\"" -m 1 \ - | grep -oE "[0-9]+" -m 1)" + echo -e "Getting artifact id and name from CI run:\t\t${artifacts_link}" + artifacts_output="$(get_output_from_github_api "${artifacts_link}")" + artifact_name_ids="$(echo "${artifacts_output}" | grep -E '"(id|name)"')" + artifact_name_id="$(echo "${artifact_name_ids}" | grep -B 1 "\"${artifact_regex}\"" -m 1)" + artifact_id="$(echo "${artifact_name_id}" | grep -oE "[0-9]+" -m 1)" readonly artifact_id - echo "Artifact ID: ${artifact_id}" - - local artifact_url download_path curl_args - readonly artifact_url="https://api.github.com/repos/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/actions/artifacts/${artifact_id}/zip" - readonly download_path="${DOWNLOAD_CACHE_DIR}/${artifact_id}.zip" - echo -e "Downloading package from: ${artifact_url}" - curl_args=( - "-fL" - "--connect-timeout" "5" - "--max-time" "${CURL_MAX_TIME}" - "--retry" "5" - "--retry-delay" "0" - "--retry-max-time" "150" - "--output" "${download_path}" - "--progress-bar" + artifact_name="$(echo "${artifact_name_ids}" | grep -oE "\"${artifact_regex}\"" -m 1)" + # strip first and last double-quote from $artifact_name + artifact_name=${artifact_name%\"} + artifact_name="${artifact_name#\"}" + readonly artifact_name + + local artifact_url artifact_zip extra_curl_args + readonly artifact_url="${base_url}/artifacts/${artifact_id}/zip" + readonly artifact_zip="${TMPDIR}/${artifact_name}.zip" + readonly extra_curl_args=( + "-H" "Accept: application/vnd.github+json" + "-H" "Authorization: token ${GITHUB_TOKEN}" ) - if [ "${KEEP_DOWNLOADS}" == "true" ]; then - curl_args+=("-z" "${download_path}") - fi - curl "${curl_args[@]}" \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${artifact_url}" - unzip -p "$download_path" > "${TMPDIR}/otelcol-sumo.pkg" - if [ "${KEEP_DOWNLOADS}" == "false" ]; then - rm -f "${download_path}" - fi + get_file_from_url "${artifact_url}" "${artifact_zip}" "${extra_curl_args[@]}" + + unzip -p "${artifact_zip}" "${artifact_name}" > "${destination_path}" } -function get_package_from_url() { - local url download_filename download_path curl_args - readonly url="${1}" - echo -e "Downloading:\t\t${url}" +function get_github_release_artifact() { + local org repo artifact_name version destination_path + readonly org="${1}" + readonly repo="${2}" + readonly artifact_name="${3}" + readonly version="${4}" + readonly destination_path="${5}" - download_filename=$(basename "${url}") - readonly download_filename - readonly download_path="${DOWNLOAD_CACHE_DIR}/${download_filename}" - curl_args=( - "-fL" - "--connect-timeout" "5" - "--max-time" "${CURL_MAX_TIME}" - "--retry" "5" - "--retry-delay" "0" - "--retry-max-time" "150" - "--output" "${download_path}" - "--progress-bar" - ) - if [ "${KEEP_DOWNLOADS}" == "true" ]; then - curl_args+=("-z" "${download_path}") - fi - curl "${curl_args[@]}" "${url}" - - cp -f "${download_path}" "${TMPDIR}/otelcol-sumo.pkg" + local url + url="https://github.com/${org}/${repo}/releases/download/v${version}/${artifact_name}" + readonly url - if [ "${KEEP_DOWNLOADS}" == "false" ]; then - rm -f "${download_path}" - fi + get_file_from_url "${url}" "${destination_path}" } function set_acl_on_log_paths() { @@ -1530,108 +1540,76 @@ function plutil_replace_key() { fi } -############################ Main code - -OS_TYPE="$(get_os_type)" -ARCH_TYPE="$(get_arch_type)" -readonly OS_TYPE ARCH_TYPE - -echo -e "Detected OS type:\t${OS_TYPE}" -echo -e "Detected architecture:\t${ARCH_TYPE}" - -set_defaults -parse_options "$@" -set_tmpdir -install_missing_dependencies -check_dependencies - -readonly SUMOLOGIC_INSTALLATION_TOKEN API_BASE_URL FIELDS CONTINUE FILE_STORAGE CONFIG_DIRECTORY SYSTEMD_CONFIG UNINSTALL -readonly USER_CONFIG_DIRECTORY USER_ENV_DIRECTORY CONFIG_DIRECTORY CONFIG_PATH COMMON_CONFIG_PATH -readonly ACL_LOG_FILE_PATHS -readonly INSTALL_HOSTMETRICS -readonly CURL_MAX_TIME -readonly LAUNCHD_CONFIG LAUNCHD_ENV_KEY LAUNCHD_TOKEN_KEY +function get_existing_user_token() { + local user_token -if [[ "${UNINSTALL}" == "true" ]]; then - uninstall - exit 0 -fi + # Attempt to find a token from an existing installation + case "${OS_TYPE}" in + darwin) + user_token="$(plutil_extract_key "${LAUNCHD_CONFIG}" "${LAUNCHD_TOKEN_KEY}")" + ;; + linux) + user_token="$(get_user_config "${COMMON_CONFIG_PATH}")" -# Attempt to find a token from an existing installation -case "${OS_TYPE}" in -darwin) - USER_TOKEN="$(plutil_extract_key "${LAUNCHD_CONFIG}" "${LAUNCHD_TOKEN_KEY}")" - ;; -*) - USER_TOKEN="$(get_user_config "${COMMON_CONFIG_PATH}")" - - # If Systemd is not disabled, try to extract token from systemd env file - if [[ -z "${USER_TOKEN}" && "${SYSTEMD_DISABLED}" == "false" ]]; then - USER_TOKEN="$(get_user_env_config "${TOKEN_ENV_FILE}")" - fi - ;; -esac -readonly USER_TOKEN + # If Systemd is not disabled, try to extract token from systemd env file + if [[ -z "${user_token}" && "${SYSTEMD_DISABLED}" == "false" ]]; then + user_token="$(get_user_env_config "${TOKEN_ENV_FILE}")" + fi + ;; + *) + user_token="$(get_user_config "${COMMON_CONFIG_PATH}")" + ;; + esac -# Exit if installation token is not set and there is no user configuration -if [[ -z "${SUMOLOGIC_INSTALLATION_TOKEN}" && "${SKIP_TOKEN}" != "true" && -z "${USER_TOKEN}" && -z "${DOWNLOAD_ONLY}" ]]; then - echo "Installation token has not been provided. Please set the '${ENV_TOKEN}' environment variable." - echo "You can ignore this requirement by adding '--${ARG_LONG_SKIP_TOKEN} argument." - exit 1 -fi + echo "${user_token}" +} -# verify if passed arguments are the same like in user's configuration -if [[ -z "${DOWNLOAD_ONLY}" ]]; then - if [[ -n "${USER_TOKEN}" && -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && "${USER_TOKEN}" != "${SUMOLOGIC_INSTALLATION_TOKEN}" ]]; then - echo "You are trying to install with different token than in your configuration file!" - exit 1 +function detect_distro_type() { + if test -f /etc/debian_version; then + echo "debian" + elif test -f /etc/redhat-release; then + echo "redhat" fi +} - if [[ -f "${COMMON_CONFIG_PATH}" ]]; then - INDENTATION="$(get_indentation "${COMMON_CONFIG_PATH}" "${INDENTATION}")" - EXT_INDENTATION="$(get_extension_indentation "${COMMON_CONFIG_PATH}" "${INDENTATION}")" - readonly INDENTATION EXT_INDENTATION - - USER_API_URL="$(get_user_api_url "${COMMON_CONFIG_PATH}")" - if [[ -n "${USER_API_URL}" && -n "${API_BASE_URL}" && "${USER_API_URL}" != "${API_BASE_URL}" ]]; then - echo "You are trying to install with different api base url than in your configuration file!" - exit 1 - fi - - USER_FIELDS="$(get_user_tags "${COMMON_CONFIG_PATH}" "${INDENTATION}" "${EXT_INDENTATION}")" - FIELDS_TO_COMPARE="$(get_fields_to_compare "${FIELDS}")" +function install_package() { + echo -e "Getting versions..." + # Get versions, but ignore errors as we fallback to other methods later + VERSIONS="$(get_package_versions || echo "")" - if [[ -n "${USER_FIELDS}" && -n "${FIELDS_TO_COMPARE}" && "${USER_FIELDS}" != "${FIELDS_TO_COMPARE}" ]]; then - echo "You are trying to install with different tags than in your configuration file!" - exit 1 - fi + # Use user's version if set, otherwise get latest version from API (or website) + if [[ -z "${VERSION}" ]]; then + VERSION="$(get_latest_package_version "${VERSIONS}")" fi -fi -set +u -if [[ -n "${BINARY_BRANCH}" && -z "${GITHUB_TOKEN}" ]]; then - echo "GITHUB_TOKEN env is required for '${ARG_LONG_BINARY_BRANCH}' option" - exit 1 -fi -set -u + VERSION_PREFIX="${VERSION%.*}" # cut off the suffix starting with the last stop + MAJOR_VERSION="${VERSION_PREFIX%.*}" # take the prefix from before the first stop + MINOR_VERSION="${VERSION_PREFIX#*.}" # take the suffix after the first stop -# Disable systemd if token is not specified at all -if [[ -z "${SUMOLOGIC_INSTALLATION_TOKEN}" && -z "${USER_TOKEN}" ]]; then - SYSTEMD_DISABLED=true -fi + readonly VERSIONS VERSION INSTALLED_VERSION VERSION_PREFIX MAJOR_VERSION MINOR_VERSION -readonly SYSTEMD_DISABLED + echo -e "Version to install:\t${VERSION}" -if [ "${FIPS}" == "true" ]; then - if [ "${OS_TYPE}" != "linux" ] || [ "${ARCH_TYPE}" != "amd64" ]; then - echo "Error: The FIPS-approved binary is only available for linux/amd64" - exit 1 - fi -fi + case "${OS_TYPE}" in + "darwin") + install_darwin_package "${ARCH_TYPE}" + ;; + "linux") + install_linux_package "${ARCH_TYPE}" + ;; + *) + echo "Error: Unsupported OS for package installation" + exit 1 + ;; + esac +} + +function install_darwin_package() { + local arch_type + readonly arch_type="${1}" -if [[ "${OS_TYPE}" == "darwin" ]]; then package_arch="" - case "${ARCH_TYPE}" in + case "${arch_type}" in "amd64") package_arch="intel" ;; "arm64") package_arch="apple" ;; *) @@ -1646,41 +1624,28 @@ if [[ "${OS_TYPE}" == "darwin" ]]; then exit 1 fi - echo -e "Getting versions..." - # Get versions, but ignore errors as we fallback to other methods later - VERSIONS="$(get_package_versions || echo "")" - - # Use user's version if set, otherwise get latest version from API (or website) - if [[ -z "${VERSION}" ]]; then - VERSION="$(get_latest_package_version "${VERSIONS}")" - fi - - VERSION_PREFIX="${VERSION%.*}" # cut off the suffix starting with the last stop - MAJOR_VERSION="${VERSION_PREFIX%.*}" # take the prefix from before the first stop - MINOR_VERSION="${VERSION_PREFIX#*.}" # take the suffix after the first stop - - readonly VERSIONS VERSION INSTALLED_VERSION VERSION_PREFIX MAJOR_VERSION MINOR_VERSION - - echo -e "Version to install:\t${VERSION}" - package_suffix="${package_arch}.pkg" + pkg="${TMPDIR}/otelcol-sumo-${package_suffix}" + readonly package_suffix pkg if [[ -n "${BINARY_BRANCH}" ]]; then - artifact_name="otelcol-sumo_.*-${package_suffix}" - get_package_from_branch "${BINARY_BRANCH}" "${artifact_name}" + get_github_actions_artifact \ + "${PACKAGE_GITHUB_ORG}" \ + "${PACKAGE_GITHUB_REPO}" \ + "${BINARY_BRANCH}" \ + "otelcol-sumo_.*-${package_suffix}" \ + "${pkg}" else - artifact_name="otelcol-sumo_${VERSION}-${package_suffix}" - readonly artifact_name - - LINK="https://github.com/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/releases/download/v${VERSION}/${artifact_name}" - readonly LINK - - get_package_from_url "${LINK}" + get_github_release_artifact \ + "${PACKAGE_GITHUB_ORG}" \ + "${PACKAGE_GITHUB_REPO}" \ + "otelcol-sumo_${VERSION}-${package_suffix}" \ + "${VERSION}" \ + "${pkg}" fi - pkg="${TMPDIR}/otelcol-sumo.pkg" choices="${TMPDIR}/otelcol-sumo-choices.xml" - readonly pkg choices + readonly choices if [[ "${DOWNLOAD_ONLY}" == "true" ]]; then echo "Package downloaded to: ${pkg}" @@ -1733,10 +1698,249 @@ if [[ "${OS_TYPE}" == "darwin" ]]; then # Run an unload/load launchd config to pull in new changes & restart the service launchctl unload "${LAUNCHD_CONFIG}" launchctl load -w "${LAUNCHD_CONFIG}" +} + +function install_linux_package() { + local arch_type + readonly arch_type="${1}" + + local distro_type + distro_type="$(detect_distro_type)" + readonly distro_type + + if [[ "${SKIP_CONFIG}" == "true" ]]; then + echo "SKIP_CONFIG is not supported with linux packages" + exit 1 + fi + case "${distro_type}" in + "debian") install_linux_deb_package "${arch_type}" ;; + "redhat") install_linux_rpm_package "${arch_type}" ;; + *) + echo "Error: Could not detect if OS is debian or redhat based" + exit 1 + esac +} + +function install_linux_deb_package() { + local arch_type + readonly arch_type="${1}" + + package_arch="" + case "${arch_type}" in + "amd64") package_arch="amd64" ;; + "arm64") package_arch="arm64" ;; + *) + echo "Error: Unsupported architecture for linux deb packages: ${arch_type}" + exit 1 + ;; + esac + readonly package_arch + + package_suffix="${package_arch}.deb" + pkg="${TMPDIR}/otelcol-sumo_${package_suffix}" + readonly package_suffix pkg + + if [[ -n "${BINARY_BRANCH}" ]]; then + get_package_from_branch \ + "${PACKAGE_GITHUB_ORG}" \ + "${PACKAGE_GITHUB_REPO}" \ + "${BINARY_BRANCH}" \ + "${pkg}" + else + get_github_release_artifact \ + "${PACKAGE_GITHUB_ORG}" \ + "${PACKAGE_GITHUB_REPO}" \ + "otelcol-sumo_${VERSION}_${package_suffix}" \ + "${VERSION}" \ + "${pkg}" + fi + + if [[ "${DOWNLOAD_ONLY}" == "true" ]]; then + echo "Package downloaded to: ${pkg}" + exit 0 + fi + + echo "Installing otelcol-sumo package" + dpkg -i "${pkg}" + + setup_config_linux + install_hostmetrics + + # Enable and start the systemd service for otelcol-sumo + systemctl enable otelcol-sumo + systemctl start otelcol-sumo +} + +function install_linux_rpm_package() { + local arch_type + readonly arch_type="${1}" + + package_arch="" + case "${arch_type}" in + "amd64") package_arch="x86_64" ;; + "arm64") package_arch="aarch64" ;; + *) + echo "Error: Unsupported architecture for linux rpm packages: ${arch_type}" + exit 1 + ;; + esac + readonly package_arch + + package_suffix="${package_arch}.rpm" + pkg="${TMPDIR}/otelcol-sumo.${package_suffix}" + readonly package_suffix pkg + + if [[ -n "${BINARY_BRANCH}" ]]; then + get_package_from_branch \ + "${PACKAGE_GITHUB_ORG}" \ + "${PACKAGE_GITHUB_REPO}" \ + "${BINARY_BRANCH}" \ + "otelcol-sumo-.*.${package_suffix}" \ + "${pkg}" + else + get_github_release_artifact \ + "${PACKAGE_GITHUB_ORG}" \ + "${PACKAGE_GITHUB_REPO}" \ + "otelcol-sumo-${VERSION}.${package_suffix}" \ + "${VERSION}" \ + "${pkg}" + fi + + if [[ "${DOWNLOAD_ONLY}" == "true" ]]; then + echo "Package downloaded to: ${pkg}" + exit 0 + fi + + if rpm_is_installed "otelcol-sumo"; then + echo "Upgrading otelcol-sumo package" + rpm -Uvh "${pkg}" + else + echo "Installing otelcol-sumo package" + rpm -ivh "${pkg}" + fi + + setup_config_linux + install_hostmetrics + + # Enable and start the systemd service for otelcol-sumo + systemctl enable otelcol-sumo + set +e + systemctl start otelcol-sumo + RC=$? + if [ "$RC" != "0" ]; then + echo "error starting otelcol-sumo service" + journalctl --no-pager -u otelcol-sumo + exit $RC + fi + set -e +} + +############################ Main code + +OS_TYPE="$(get_os_type)" +ARCH_TYPE="$(get_arch_type)" +readonly OS_TYPE ARCH_TYPE + +echo -e "Detected OS type:\t${OS_TYPE}" +echo -e "Detected architecture:\t${ARCH_TYPE}" + +set_defaults +parse_options "$@" +set_tmpdir +install_missing_dependencies +check_dependencies + +# Force native packaging on darwin +if [[ "${OS_TYPE}" == "darwin" ]]; then + USE_NATIVE_PACKAGING="true" +fi + +if [ "${FIPS}" == "true" ]; then + if [ "${OS_TYPE}" != "linux" ] || [ "${ARCH_TYPE}" != "amd64" ] || [ "${USE_NATIVE_PACKAGING}" == "true" ]; then + echo "Error: The FIPS-approved binary is only available for linux/amd64" + exit 1 + fi +fi + +readonly SUMOLOGIC_INSTALLATION_TOKEN API_BASE_URL FIELDS CONTINUE FILE_STORAGE CONFIG_DIRECTORY SYSTEMD_CONFIG UNINSTALL +readonly USER_CONFIG_DIRECTORY USER_ENV_DIRECTORY CONFIG_DIRECTORY CONFIG_PATH COMMON_CONFIG_PATH +readonly ACL_LOG_FILE_PATHS +readonly INSTALL_HOSTMETRICS +readonly CURL_MAX_TIME +readonly LAUNCHD_CONFIG LAUNCHD_ENV_KEY LAUNCHD_TOKEN_KEY +readonly USE_NATIVE_PACKAGING + +if [[ "${UNINSTALL}" == "true" ]]; then + uninstall exit 0 fi +USER_TOKEN="$(get_existing_user_token)" +readonly USER_TOKEN + +# Exit if installation token is not set and there is no user configuration +if [[ -z "${SUMOLOGIC_INSTALLATION_TOKEN}" && "${SKIP_TOKEN}" != "true" && -z "${USER_TOKEN}" && -z "${DOWNLOAD_ONLY}" ]]; then + echo "Installation token has not been provided. Please set the '${ENV_TOKEN}' environment variable." + echo "You can ignore this requirement by adding '--${ARG_LONG_SKIP_TOKEN} argument." + exit 1 +fi + +# verify if passed arguments are the same like in user's configuration +if [[ -z "${DOWNLOAD_ONLY}" ]]; then + if [[ -n "${USER_TOKEN}" && -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && "${USER_TOKEN}" != "${SUMOLOGIC_INSTALLATION_TOKEN}" ]]; then + echo "You are trying to install with different token than in your configuration file!" + exit 1 + fi + + if [[ -f "${COMMON_CONFIG_PATH}" ]]; then + INDENTATION="$(get_indentation "${COMMON_CONFIG_PATH}" "${INDENTATION}")" + EXT_INDENTATION="$(get_extension_indentation "${COMMON_CONFIG_PATH}" "${INDENTATION}")" + readonly INDENTATION EXT_INDENTATION + + USER_API_URL="$(get_user_api_url "${COMMON_CONFIG_PATH}")" + if [[ -n "${USER_API_URL}" && -n "${API_BASE_URL}" && "${USER_API_URL}" != "${API_BASE_URL}" ]]; then + echo "You are trying to install with different api base url than in your configuration file!" + exit 1 + fi + + USER_FIELDS="$(get_user_tags "${COMMON_CONFIG_PATH}" "${INDENTATION}" "${EXT_INDENTATION}")" + FIELDS_TO_COMPARE="$(get_fields_to_compare "${FIELDS}")" + + if [[ -n "${USER_FIELDS}" && -n "${FIELDS_TO_COMPARE}" && "${USER_FIELDS}" != "${FIELDS_TO_COMPARE}" ]]; then + echo "You are trying to install with different tags than in your configuration file!" + exit 1 + fi + fi +fi + +set +u +if [[ -n "${BINARY_BRANCH}" && -z "${GITHUB_TOKEN}" ]]; then + echo "GITHUB_TOKEN env is required for '${ARG_LONG_BINARY_BRANCH}' option" + exit 1 +fi +set -u + +# Disable systemd if token is not specified at all +if [[ -z "${SUMOLOGIC_INSTALLATION_TOKEN}" && -z "${USER_TOKEN}" ]]; then + SYSTEMD_DISABLED=true +fi + +readonly SYSTEMD_DISABLED + +################################################################################ +# Native package installation +################################################################################ + +if [[ "${USE_NATIVE_PACKAGING}" == "true" ]]; then + install_package + exit 0 +fi + +################################################################################ +# Binary installation +################################################################################ + echo -e "Getting installed version..." INSTALLED_VERSION="$(get_installed_version)" echo -e "Installed version:\t${INSTALLED_VERSION:-none}" @@ -1754,7 +1958,6 @@ VERSION_PREFIX="${VERSION%.*}" # cut off the suffix starting with the last MAJOR_VERSION="${VERSION_PREFIX%.*}" # take the prefix from before the first stop MINOR_VERSION="${VERSION_PREFIX#*.}" # take the suffix after the first stop - readonly VERSIONS VERSION INSTALLED_VERSION VERSION_PREFIX MAJOR_VERSION MINOR_VERSION echo -e "Version to install:\t${VERSION}" @@ -1793,18 +1996,26 @@ else echo "Getting FIPS-compliant binary" binary_suffix="fips-${binary_suffix}" fi + binary_path="${TMPDIR}/otelcol-sumo" if [[ -n "${BINARY_BRANCH}" ]]; then - get_binary_from_branch "${BINARY_BRANCH}" "otelcol-sumo-${binary_suffix}" + get_github_actions_artifact \ + "${BINARY_GITHUB_ORG}" \ + "${BINARY_GITHUB_REPO}" \ + "${BINARY_BRANCH}" \ + "otelcol-sumo-${binary_suffix}" \ + "${binary_path}" else - LINK="https://github.com/SumoLogic/sumologic-otel-collector/releases/download/v${VERSION}/otelcol-sumo-${VERSION}-${binary_suffix}" - readonly LINK - - get_binary_from_url "${LINK}" + get_github_release_artifact \ + "${BINARY_GITHUB_ORG}" \ + "${BINARY_GITHUB_REPO}" \ + "otelcol-sumo-${VERSION}-${binary_suffix}" \ + "${VERSION}" \ + "${binary_path}" fi echo -e "Moving otelcol-sumo to /usr/local/bin" - mv "${TMPDIR}"/otelcol-sumo "${SUMO_BINARY_PATH}" + mv "${binary_path}" "${SUMO_BINARY_PATH}" echo -e "Setting ${SUMO_BINARY_PATH} to be executable" chmod +x "${SUMO_BINARY_PATH}" @@ -1835,11 +2046,8 @@ fi echo 'We are going to set up a systemd service' -if [[ -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && -z "${USER_TOKEN}" ]]; then - echo 'Writing installation token to env file' - write_installation_token_env "${SUMOLOGIC_INSTALLATION_TOKEN}" "${TOKEN_ENV_FILE}" - chmod -R 440 "${TOKEN_ENV_FILE}" -fi +write_env_token +chmod -R 640 "${TOKEN_ENV_FILE}" if [[ -f "${SYSTEMD_CONFIG}" ]]; then # This is required for configuration being installed after systemd setup