Skip to content

Commit

Permalink
Merge pull request #53 from nlewo/rm-profile
Browse files Browse the repository at this point in the history
Remove the profile path when a deployment gets evicted
  • Loading branch information
nlewo authored Aug 17, 2024
2 parents 21c5719 + 8a5ec13 commit a5f735b
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 44 deletions.
6 changes: 5 additions & 1 deletion internal/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/nlewo/comin/internal/deployment"
"github.com/nlewo/comin/internal/generation"
"github.com/nlewo/comin/internal/nix"
"github.com/nlewo/comin/internal/profile"
"github.com/nlewo/comin/internal/prometheus"
"github.com/nlewo/comin/internal/repository"
"github.com/nlewo/comin/internal/store"
Expand Down Expand Up @@ -148,7 +149,10 @@ func (m Manager) onDeployment(ctx context.Context, deploymentResult deployment.D
}
m.isRunning = false
m.prometheus.SetDeploymentInfo(m.deployment.Generation.SelectedCommitId, deployment.StatusToString(m.deployment.Status))
m.storage.DeploymentInsertAndCommit(m.deployment)
getsEvicted, evicted := m.storage.DeploymentInsertAndCommit(m.deployment)
if getsEvicted && evicted.ProfilePath != "" {
profile.RemoveProfilePath(evicted.ProfilePath)
}
return m
}

Expand Down
43 changes: 2 additions & 41 deletions internal/nix/nix.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
"io"
"os"
"os/exec"
"path"
"path/filepath"
"strings"

"github.com/nlewo/comin/internal/profile"
"github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -154,45 +154,6 @@ func Build(ctx context.Context, drvPath string) (err error) {
return
}

// setSystemProfile creates a link into the directory
// /nix/var/nix/profiles/system-profiles/comin to the built system
// store path. This is used by the switch-to-configuration script to
// install all entries into the bootloader.
// Note also comin uses these links as gcroots
// See https://github.com/nixos/nixpkgs/blob/df98ab81f908bed57c443a58ec5230f7f7de9bd3/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh#L711
// and https://github.com/nixos/nixpkgs/blob/df98ab81f908bed57c443a58ec5230f7f7de9bd3/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py#L247
func setSystemProfile(operation string, outPath string, dryRun bool) (profilePath string, err error) {
systemProfilesDir := "/nix/var/nix/profiles/system-profiles"
profile := systemProfilesDir + "/comin"
if operation == "switch" || operation == "boot" {
err := os.MkdirAll(systemProfilesDir, os.ModeDir)
if err != nil && !os.IsExist(err) {
return profilePath, fmt.Errorf("nix: failed to create the profile directory: %s", systemProfilesDir)
}
cmdStr := fmt.Sprintf("nix-env --profile %s --set %s", profile, outPath)
logrus.Infof("nix: running '%s'", cmdStr)
cmd := exec.Command("nix-env", "--profile", profile, "--set", outPath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if dryRun {
logrus.Infof("nix: dry-run enabled: '%s' has not been executed", cmdStr)
} else {
err := cmd.Run()
if err != nil {
return profilePath, fmt.Errorf("nix: command '%s' fails with %s", cmdStr, err)
}
logrus.Infof("nix: command '%s' succeeded", cmdStr)
dst, err := os.Readlink(profile)
if err != nil {
return profilePath, fmt.Errorf("nix: failed to os.Readlink(%s)", profile)
}
profilePath = path.Join(systemProfilesDir, dst)
logrus.Infof("nix: the profile %s has been created", profilePath)
}
}
return
}

func cominUnitFileHash() string {
logrus.Infof("nix: generating the comin.service unit file sha256: 'systemctl cat comin.service | sha256sum'")
cmd := exec.Command("systemctl", "cat", "comin.service")
Expand Down Expand Up @@ -231,7 +192,7 @@ func Deploy(ctx context.Context, expectedMachineId, outPath, operation string) (

// This is required to write boot entries
// Only do this is operation is switch or boot
if profilePath, err = setSystemProfile(operation, outPath, false); err != nil {
if profilePath, err = profile.SetSystemProfile(operation, outPath, false); err != nil {
return
}

Expand Down
57 changes: 57 additions & 0 deletions internal/profile/profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package profile

import "os"
import "fmt"
import "github.com/sirupsen/logrus"
import "os/exec"
import "path"

var systemProfilesDir string = "/nix/var/nix/profiles/system-profiles"
var cominProfileDir string = systemProfilesDir + "/comin"

// setSystemProfile creates a link into the directory
// /nix/var/nix/profiles/system-profiles/comin to the built system
// store path. This is used by the switch-to-configuration script to
// install all entries into the bootloader.
// Note also comin uses these links as gcroots
// See https://github.com/nixos/nixpkgs/blob/df98ab81f908bed57c443a58ec5230f7f7de9bd3/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh#L711
// and https://github.com/nixos/nixpkgs/blob/df98ab81f908bed57c443a58ec5230f7f7de9bd3/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py#L247
func SetSystemProfile(operation string, outPath string, dryRun bool) (profilePath string, err error) {
if operation == "switch" || operation == "boot" {
err := os.MkdirAll(systemProfilesDir, os.ModeDir)
if err != nil && !os.IsExist(err) {
return profilePath, fmt.Errorf("nix: failed to create the profile directory: %s", systemProfilesDir)
}
cmdStr := fmt.Sprintf("nix-env --profile %s --set %s", cominProfileDir, outPath)
logrus.Infof("nix: running '%s'", cmdStr)
cmd := exec.Command("nix-env", "--profile", cominProfileDir, "--set", outPath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if dryRun {
logrus.Infof("nix: dry-run enabled: '%s' has not been executed", cmdStr)
} else {
err := cmd.Run()
if err != nil {
return profilePath, fmt.Errorf("nix: command '%s' fails with %s", cmdStr, err)
}
logrus.Infof("nix: command '%s' succeeded", cmdStr)
dst, err := os.Readlink(cominProfileDir)
if err != nil {
return profilePath, fmt.Errorf("nix: failed to os.Readlink(%s)", cominProfileDir)
}
profilePath = path.Join(systemProfilesDir, dst)
logrus.Infof("nix: the profile %s has been created", profilePath)
}
}
return
}

// RemoveProfilePath removes a profile path.
func RemoveProfilePath(profilePath string) (err error) {
logrus.Infof("Removing profile path %s", profilePath)
err = os.Remove(profilePath)
if err != nil {
logrus.Errorf("Failed to remove profile path %s: %s", profilePath, err)
}
return
}
27 changes: 27 additions & 0 deletions internal/profile/profile_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package profile

import (
"path"
"testing"

"os"

"github.com/stretchr/testify/assert"
)

func TestRemoveProfilePath(t *testing.T) {
dir := t.TempDir()
file1 := path.Join(dir, "file1")
os.Create(file1)
file2 := path.Join(dir, "file2")
os.Create(file2)

RemoveProfilePath(file1)
entries, _ := os.ReadDir(dir)
files := make([]string, len(entries))
for i, e := range entries {
files[i] = e.Name()
}
expected := []string{"file2"}
assert.Equal(t, expected, files)
}
6 changes: 4 additions & 2 deletions internal/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ func New(filename string, capacityMain, capacityTesting int) Store {

}

func (s *Store) DeploymentInsertAndCommit(dpl deployment.Deployment) {
ok, evicted := s.DeploymentInsert(dpl)
func (s *Store) DeploymentInsertAndCommit(dpl deployment.Deployment) (ok bool, evicted deployment.Deployment) {
ok, evicted = s.DeploymentInsert(dpl)
if ok {
logrus.Infof("The deployment %s has been removed from store.json file", evicted.UUID)
}
if err := s.Commit(); err != nil {
logrus.Errorf("Error while commiting the store.json file: %s", err)
return
}
logrus.Infof("The new deployment %s has been commited to store.json file", dpl.UUID)
return
}

// DeploymentInsert inserts a deployment and return an evicted
Expand Down

0 comments on commit a5f735b

Please sign in to comment.