Skip to content

Commit

Permalink
[nix] Add DetSys installer behind feature flag (#2303)
Browse files Browse the repository at this point in the history
## 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
  • Loading branch information
mikeland73 authored Sep 25, 2024
1 parent 68edd30 commit 58ed80e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/cli-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions internal/boxcli/featureflag/detsys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package featureflag

var UseDetSysInstaller = disable("DETSYS_INSTALLER")
10 changes: 8 additions & 2 deletions internal/boxcli/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,27 @@ 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 "+
"please remove the nix-shell binary from your path.\n",
)
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
Expand Down
29 changes: 26 additions & 3 deletions internal/nix/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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.")
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}

Expand All @@ -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")
}

0 comments on commit 58ed80e

Please sign in to comment.