From 58ed80e0bb56d08cd2374ae298e3839a253f6819 Mon Sep 17 00:00:00 2001 From: Mike Landau Date: Wed, 25 Sep 2024 16:26:40 -0700 Subject: [PATCH] [nix] Add DetSys installer behind feature flag (#2303) ## Summary * Adds detsys installer. * Puts it behind disabled flag. Add CICD matrix to test. * Special casing: Handles missing systemd by just skipping it. ## How was it tested? * Tested `devbox setup nix` in linux docker container. * Will test in CICD * Much more testing needed before removing feature flag --- .github/workflows/cli-tests.yaml | 2 ++ internal/boxcli/featureflag/detsys.go | 3 +++ internal/boxcli/setup.go | 10 +++++++-- internal/nix/install.go | 29 ++++++++++++++++++++++++--- 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 internal/boxcli/featureflag/detsys.go diff --git a/.github/workflows/cli-tests.yaml b/.github/workflows/cli-tests.yaml index 635f66dd219..0365fccbcb4 100644 --- a/.github/workflows/cli-tests.yaml +++ b/.github/workflows/cli-tests.yaml @@ -183,6 +183,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-13] + use-detsys: [true, false] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -197,6 +198,7 @@ jobs: - name: Install nix and devbox packages run: | export NIX_INSTALLER_NO_CHANNEL_ADD=1 + export DEVBOX_FEATURE_DETSYS_INSTALLER=${{ matrix.use-detsys }} # Setup github authentication to ensure Github's rate limits are not hit. # If this works, we can consider refactoring this into a reusable github action helper. diff --git a/internal/boxcli/featureflag/detsys.go b/internal/boxcli/featureflag/detsys.go new file mode 100644 index 00000000000..bfc8b457486 --- /dev/null +++ b/internal/boxcli/featureflag/detsys.go @@ -0,0 +1,3 @@ +package featureflag + +var UseDetSysInstaller = disable("DETSYS_INSTALLER") diff --git a/internal/boxcli/setup.go b/internal/boxcli/setup.go index c20f50e3032..279b7c45c60 100644 --- a/internal/boxcli/setup.go +++ b/internal/boxcli/setup.go @@ -29,13 +29,19 @@ func setupCmd() *cobra.Command { }, } - installNixCommand.Flags().Bool(nixDaemonFlag, false, "Install Nix in multi-user mode.") + installNixCommand.Flags().Bool( + nixDaemonFlag, + false, + "Install Nix in multi-user mode. This flag is not supported if you are using DetSys installer", + ) setupCommand.AddCommand(installNixCommand) return setupCommand } func runInstallNixCmd(cmd *cobra.Command) error { if nix.BinaryInstalled() { + // TODO: If existing installation is not detsys, but new installation is detsys can we detect + // that and replace it? ux.Finfof( cmd.ErrOrStderr(), "Nix is already installed. If this is incorrect "+ @@ -43,7 +49,7 @@ func runInstallNixCmd(cmd *cobra.Command) error { ) return nil } - return nix.Install(cmd.ErrOrStderr(), nixDaemonFlagVal(cmd)()) + return nix.Install(cmd.ErrOrStderr(), nixDaemonFlagVal(cmd)) } // ensureNixInstalled verifies that nix is installed and that it is of a supported version diff --git a/internal/nix/install.go b/internal/nix/install.go index 2f8b46eeee3..32b0a483650 100644 --- a/internal/nix/install.go +++ b/internal/nix/install.go @@ -16,6 +16,7 @@ import ( "github.com/mattn/go-isatty" "github.com/pkg/errors" + "go.jetpack.io/devbox/internal/boxcli/featureflag" "go.jetpack.io/devbox/internal/boxcli/usererr" "go.jetpack.io/devbox/internal/build" "go.jetpack.io/devbox/internal/cmdutil" @@ -28,7 +29,7 @@ const rootError = "warning: installing Nix as root is not supported by this scri // Install runs the install script for Nix. daemon has 3 states // nil is unset. false is --no-daemon. true is --daemon. -func Install(writer io.Writer, daemon *bool) error { +func Install(writer io.Writer, daemonFn func() *bool) error { if isRoot() && build.OS() == build.OSWSL { return usererr.New("Nix cannot be installed as root on WSL. Please run as a normal user with sudo access.") } @@ -39,7 +40,18 @@ func Install(writer io.Writer, daemon *bool) error { defer r.Close() installScript := "curl -L https://releases.nixos.org/nix/nix-2.24.7/install | sh -s" - if daemon != nil { + if featureflag.UseDetSysInstaller.Enabled() { + // Should we pin version? Or just trust detsys + installScript = "curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install" + if isLinuxWithoutSystemd() { + ux.Fwarningf( + writer, + "Could not detect systemd on your system. Installing Nix in root only mode (--init none).\n", + ) + installScript += " linux --init none" + } + installScript += " --no-confirm" + } else if daemon := daemonFn(); daemon != nil { if *daemon { installScript += " -- --daemon" } else { @@ -157,7 +169,7 @@ func EnsureNixInstalled(writer io.Writer, withDaemonFunc func() *bool) (err erro fmt.Scanln() //nolint:errcheck } - if err = Install(writer, withDaemonFunc()); err != nil { + if err = Install(writer, withDaemonFunc); err != nil { return err } @@ -169,3 +181,14 @@ func EnsureNixInstalled(writer io.Writer, withDaemonFunc func() *bool) (err erro fmt.Fprintln(writer, "Nix installed successfully. Devbox is ready to use!") return nil } + +func isLinuxWithoutSystemd() bool { + if build.OS() != build.OSLinux { + return false + } + // My best interpretation of https://github.com/DeterminateSystems/nix-installer/blob/66ad2759a3ecb6da345373e3c413c25303305e25/src/action/common/configure_init_service.rs#L108-L118 + if _, err := os.Stat("/run/systemd/system"); errors.Is(err, os.ErrNotExist) { + return true + } + return !cmdutil.Exists("systemctl") +}