From 12dac1fd51c7dec10b21a76a921dacc1de4f4a92 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Wed, 6 Mar 2024 15:11:08 +0900 Subject: [PATCH] Prefer to specify username over sudo with inherit ENV (#434) * Prefer to specify username over sudo with inherit ENV * Replace where with which for bash I know nothing about Unix and shells https://unix.stackexchange.com/questions/63781/what-is-the-difference-between-which-and-where * Failing to build conatiner root have nix path here * Ah... removing paren here? * Do not wait other checks except release Now build is enought fast, so needles this waiting * Split layers for debug * Using nix run with sudo without -E made root owned file... * Fix to handle sudo and keeping env * Run nix gc after each nix run to make better layers --- .github/workflows/ci-home.yml | 2 +- .github/workflows/container.yml | 18 +++++----- Containerfile | 9 +++-- README.md | 2 +- cmd/uinit/main.go | 60 +++++++++++++++++++++++---------- flake.nix | 12 ------- 6 files changed, 59 insertions(+), 44 deletions(-) diff --git a/.github/workflows/ci-home.yml b/.github/workflows/ci-home.yml index dca276ee..99ac81b2 100644 --- a/.github/workflows/ci-home.yml +++ b/.github/workflows/ci-home.yml @@ -63,4 +63,4 @@ jobs: zsh -c 'la' zsh -c "p cowsay hello --command 'cowsay \$(hello)'" - name: Make Nix provided shells can be a login shell - run: nix run '.#sudo_uinit' -- --dry_run=false + run: nix shell '.#uinit' --command bash -c 'sudo "$(which uinit)" --user="$(whoami)" --dry_run=false' diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index 5b9b301f..5af6380a 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -21,6 +21,15 @@ jobs: timeout-minutes: 60 steps: - uses: actions/checkout@v4 + - name: Build Image + id: build-image + uses: redhat-actions/buildah-build@v2.13 + with: + image: home + tags: latest ${{ github.sha }} + containerfiles: | + Containerfile + oci: true - name: Wait other jobs uses: kachick/wait-other-jobs@v2 timeout-minutes: 10 @@ -31,15 +40,6 @@ jobs: "workflowFile": "release.yml" } ] - - name: Build Image - id: build-image - uses: redhat-actions/buildah-build@v2.13 - with: - image: home - tags: latest ${{ github.sha }} - containerfiles: | - Containerfile - oci: true - name: Push To ghcr.io id: push-to-ghcr if: ${{ github.event_name != 'pull_request' }} diff --git a/Containerfile b/Containerfile index 212fbc6c..f26f2f3c 100644 --- a/Containerfile +++ b/Containerfile @@ -18,9 +18,12 @@ COPY ./ /tmp/dotfiles/ RUN mkdir -p ~/.local/state/nix/profiles \ && nix-shell --packages git --command 'git config --global --add safe.directory /tmp/dotfiles' \ && nix run '/tmp/dotfiles#home-manager' -- switch -b backup --flake '/tmp/dotfiles/#user' \ - && nix run '/tmp/dotfiles#sudo_uinit' -- --dry_run=false \ + && nix store gc + +RUN nix shell '/tmp/dotfiles#uinit' --command bash -c 'sudo "$(which uinit)" --user=user --dry_run=false' \ && sudo chsh user -s "$HOME/.nix-profile/bin/zsh" \ - && nix store gc \ - && sudo rm -rf /tmp/dotfiles + && nix store gc + +RUN sudo rm -rf /tmp/dotfiles CMD [ "/home/user/.nix-profile/bin/zsh" ] diff --git a/README.md b/README.md index 4d4fbfc9..008780e3 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Also known as [盆栽(bonsai)](https://en.wikipedia.org/wiki/Bonsai) 🌳 ``` 1. Make shells installed by nix into a login shell ```bash - nix run 'github:kachick/dotfiles#sudo_uinit' -- --dry_run=false + nix shell 'github:kachick/dotfiles#uinit' --command bash -c 'sudo "$(which uinit)" --user="$(whoami)" --dry_run=false' ``` 1. If you are developing this repository, the simple reactivation is as follows. ```bash diff --git a/cmd/uinit/main.go b/cmd/uinit/main.go index 464a4bcb..e2984b8d 100644 --- a/cmd/uinit/main.go +++ b/cmd/uinit/main.go @@ -7,31 +7,52 @@ import ( "fmt" "log" "os" + "os/user" "strings" ) -// Called should be `sudo -E ...`, See https://stackoverflow.com/a/40438345/1212807 +func usage() string { + return `Usage: uinit [OPTIONS] -// This script requires sudo execution, if it is a reasonable way, including in *.nix may be better +Linux and macOS initialization + +- Require root privileges as sudo +- Specify one of non root user for the target + +$ sudo uinit --user=runner # dry_run by default +$ sudo uinit --user="$(whoami)" --dry_run=false +` +} func getShellPath(homePath string, shellName string) string { return homePath + "/.nix-profile/bin/" + shellName } func main() { + userFlag := flag.String("user", "", "affect for the given user") dryRunFlag := flag.Bool("dry_run", true, "no side effect if true") + flag.Usage = func() { + // https://github.com/golang/go/issues/57059#issuecomment-1336036866 + fmt.Printf("%s", usage()+"\n\n") + fmt.Println("Usage of command:") + flag.PrintDefaults() + fmt.Println("") + } flag.Parse() - if *dryRunFlag { - log.Println("Running in dry run mode. Will not make actual changes even if DONE is shown. Specify --dry_run flag to change it") + username := *userFlag + if username == "" || username == "root" { + flag.Usage() + os.Exit(1) } - homePath, ok := os.LookupEnv("HOME") - if !ok { - log.Fatalln("$HOME is not found") + target, err := user.Lookup(username) + if err != nil { + log.Fatalf("Given user %s is not found: %v", username, err) } - if homePath == "/root" { - log.Fatalln("used by root looks wrong. You should run `sudo -E ...` instead of `sudo ...`") + + if *dryRunFlag { + log.Println("Running in DRY RUN mode. You can toggle by --dry_run flag") } const primaryShell = "zsh" @@ -46,7 +67,7 @@ func main() { dirty := strings.Clone(etcShells) for _, sh := range loginableShells { - shellPath := getShellPath(homePath, sh) + shellPath := getShellPath(target.HomeDir, sh) if strings.Contains(etcShells, shellPath) { log.Printf("skip - %s is already registered in /etc/shells\n", shellPath) } else { @@ -55,16 +76,19 @@ func main() { } } - if (dirty != etcShells) && !*dryRunFlag { - err = os.WriteFile("/etc/shells", []byte(dirty), os.ModePerm) - if err != nil { - log.Fatalf("failed - could you correctly run this with sudo? - %v\n", err) + if dirty == etcShells { + log.Printf("No changes have been made") + } else { + if !*dryRunFlag { + err = os.WriteFile("/etc/shells", []byte(dirty), os.ModePerm) + if err != nil { + log.Fatalf("You should run this command with root privileges as sudo - %v\n", err) + } } - } - log.Printf(`Done! Set one of your favorite shell as follows + log.Printf(`Done! Set one of your favorite shell as follows chsh -s %s "$(whoami)" -`, getShellPath(homePath, primaryShell)) - +`, getShellPath(target.HomeDir, primaryShell)) + } } diff --git a/flake.nix b/flake.nix index 1b0055c2..eb2b12ee 100644 --- a/flake.nix +++ b/flake.nix @@ -94,13 +94,6 @@ ''; }; - packages.sudo_uinit = pkgs.writeShellScriptBin "sudo_uinit" '' - set -euo pipefail - - # Don't use nixpkgs provided sudo here to avoid "sudo must be owned by uid 0 and have the setuid bit set" - sudo -E ${packages.uinit}/bin/uinit "$@" - ''; - packages.bump_completions = pkgs.writeShellScriptBin "bump_completions" '' set -euo pipefail @@ -128,11 +121,6 @@ drv = home-manager.defaultPackage.${system}; }; - sudo_uinit = { - type = "app"; - program = "${packages.sudo_uinit}/bin/sudo_uinit"; - }; - bump_completions = { type = "app"; program = "${packages.bump_completions}/bin/bump_completions";