diff --git a/cmd/installer/cli/install.go b/cmd/installer/cli/install.go index c192e44d48..bfde92dde8 100644 --- a/cmd/installer/cli/install.go +++ b/cmd/installer/cli/install.go @@ -10,6 +10,7 @@ import ( "runtime" "sort" "strings" + "syscall" "time" "github.com/gosimple/slug" @@ -171,6 +172,10 @@ func preRunInstall(cmd *cobra.Command, flags *InstallCmdFlags) error { return fmt.Errorf("install command must be run as root") } + // set the umask to 022 so that we can create files/directories with 755 permissions + // this does not return an error - it returns the previous umask + _ = syscall.Umask(0o022) + p, err := parseProxyFlags(cmd) if err != nil { return err diff --git a/cmd/installer/cli/join.go b/cmd/installer/cli/join.go index 82a85ab4c0..d15e5741bd 100644 --- a/cmd/installer/cli/join.go +++ b/cmd/installer/cli/join.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "strings" + "syscall" ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1" "github.com/replicatedhq/embedded-cluster/pkg/addons" @@ -96,6 +97,10 @@ func preRunJoin(flags *JoinCmdFlags) error { flags.isAirgap = flags.airgapBundle != "" + // set the umask to 022 so that we can create files/directories with 755 permissions + // this does not return an error - it returns the previous umask + _ = syscall.Umask(0o022) + return nil } diff --git a/cmd/installer/cli/root.go b/cmd/installer/cli/root.go index 4d31e0c123..cdb3ecf2ac 100644 --- a/cmd/installer/cli/root.go +++ b/cmd/installer/cli/root.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "os" + "syscall" "github.com/replicatedhq/embedded-cluster/pkg/dryrun" "github.com/replicatedhq/embedded-cluster/pkg/metrics" @@ -68,6 +69,10 @@ func RootCmd(ctx context.Context, name string) *cobra.Command { metrics.DisableMetrics() } + // set the umask to 022 so that we can create files/directories with 755 permissions + // this does not return an error - it returns the previous umask + _ = syscall.Umask(0o022) + return nil }, PersistentPostRunE: func(cmd *cobra.Command, args []string) error { diff --git a/cmd/installer/main.go b/cmd/installer/main.go index c0e68ce72d..375d71b453 100644 --- a/cmd/installer/main.go +++ b/cmd/installer/main.go @@ -4,6 +4,7 @@ import ( "context" "os" "path" + "syscall" "github.com/mattn/go-isatty" "github.com/replicatedhq/embedded-cluster/cmd/installer/cli" @@ -19,5 +20,10 @@ func main() { name := path.Base(os.Args[0]) + // set the umask to 022 so that we can create files/directories with 755 permissions + // this does not return an error - it returns the previous umask + // we do this before calling cli.InitAndExecute so that it is set before the process forks + _ = syscall.Umask(0o022) + cli.InitAndExecute(ctx, name) } diff --git a/cmd/local-artifact-mirror/main.go b/cmd/local-artifact-mirror/main.go index c1c8f3bd3f..323d2a7205 100644 --- a/cmd/local-artifact-mirror/main.go +++ b/cmd/local-artifact-mirror/main.go @@ -19,6 +19,11 @@ func main() { name := path.Base(os.Args[0]) + // set the umask to 022 so that we can create files/directories with 755 permissions + // this does not return an error - it returns the previous umask + // we do this before calling cli.InitAndExecute so that it is set before the process forks + _ = syscall.Umask(0o022) + InitAndExecute(ctx, name) } diff --git a/go.mod b/go.mod index 9abe2c6694..4f38ef51bd 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/replicatedhq/embedded-cluster -go 1.23.2 +go 1.23.4 require ( github.com/AlecAivazis/survey/v2 v2.3.7 diff --git a/operator/pkg/cli/upgrade_job.go b/operator/pkg/cli/upgrade_job.go index e7c03d81de..d264f3fade 100644 --- a/operator/pkg/cli/upgrade_job.go +++ b/operator/pkg/cli/upgrade_job.go @@ -63,7 +63,7 @@ func UpgradeJobCmd() *cobra.Command { airgapChartsPath := "" if in.Spec.AirGap { - airgapChartsPath = runtimeconfig.EmbeddedClusterChartsSubDir() + airgapChartsPath = runtimeconfig.EmbeddedClusterChartsSubDirNoCreate() } hcli, err := helm.NewClient(helm.HelmOptions{ diff --git a/tests/dryrun/Dockerfile b/tests/dryrun/Dockerfile index 95f031da7b..ce6bd2bc99 100644 --- a/tests/dryrun/Dockerfile +++ b/tests/dryrun/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.23-alpine AS build +FROM golang:1.23.4-alpine AS build RUN apk add --no-cache ca-certificates curl git make bash diff --git a/tests/dryrun/install_test.go b/tests/dryrun/install_test.go index 1d0b0e34e8..3038b0be33 100644 --- a/tests/dryrun/install_test.go +++ b/tests/dryrun/install_test.go @@ -7,12 +7,14 @@ import ( "os" "path/filepath" "regexp" + "syscall" "testing" "time" "github.com/replicatedhq/embedded-cluster/pkg/dryrun" "github.com/replicatedhq/embedded-cluster/pkg/helm" "github.com/replicatedhq/embedded-cluster/pkg/kubeutils" + "github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -20,6 +22,11 @@ import ( ) func TestDefaultInstallation(t *testing.T) { + testDefaultInstallationImpl(t) + t.Logf("%s: test complete", time.Now().Format(time.RFC3339)) +} + +func testDefaultInstallationImpl(t *testing.T) { hcli := &helm.MockClient{} mock.InOrder( @@ -152,8 +159,6 @@ func TestDefaultInstallation(t *testing.T) { assert.Equal(t, "10.244.0.0/17", k0sConfig.Spec.Network.PodCIDR) assert.Equal(t, "10.244.128.0/17", k0sConfig.Spec.Network.ServiceCIDR) assert.Contains(t, k0sConfig.Spec.API.SANs, "kubernetes.default.svc.cluster.local") - - t.Logf("%s: test complete", time.Now().Format(time.RFC3339)) } func TestCustomDataDir(t *testing.T) { @@ -391,3 +396,36 @@ func TestConfigValuesInstallation(t *testing.T) { t.Logf("%s: test complete", time.Now().Format(time.RFC3339)) } + +func TestRestrictiveUmask(t *testing.T) { + oldUmask := syscall.Umask(0o077) + defer syscall.Umask(oldUmask) + + testDefaultInstallationImpl(t) + + // check that folders created in this test have the right permissions + folderList := []string{ + runtimeconfig.EmbeddedClusterHomeDirectory(), + runtimeconfig.EmbeddedClusterBinsSubDir(), + runtimeconfig.EmbeddedClusterChartsSubDir(), + runtimeconfig.PathToEmbeddedClusterBinary("kubectl-preflight"), + } + gotFailure := false + for _, folder := range folderList { + stat, err := os.Stat(folder) + if err != nil { + t.Logf("failed to stat %s: %v", folder, err) + gotFailure = true + continue + } + if stat.Mode().Perm() != 0755 { + t.Logf("expected folder %s to have mode 0755, got %O", folder, stat.Mode().Perm()) + gotFailure = true + } + } + if gotFailure { + t.Fatalf("at least one folder had incorrect permissions") + } + + t.Logf("%s: test complete", time.Now().Format(time.RFC3339)) +}