Deployment and lifecycle management for Nix
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

client(services): can build an env with the units

+159 -36
+78 -35
cmd/client/main.go
··· 84 84 Yes bool `arg:"--yes,-y"` 85 85 } 86 86 87 - type Service string 88 - 89 87 type servicesCmd struct { 90 88 List *servicesListCmd `arg:"subcommand:list"` 91 89 Upgrade *servicesUpgradeCmd `arg:"subcommand:upgrade"` 92 - Services []Service 90 + Services []client.SeedSeedType 93 91 } 94 92 95 93 type servicesListCmd struct{} ··· 199 197 servicesCommand(cfg) 200 198 default: 201 199 parsedConfig.WriteHelp(os.Stdout) 202 - } 203 - } 204 - 205 - func servicesCommand(cfg config) { 206 - if len(cfg.Services.Services) == 0 { 207 - slog.Warn("No services configured") 208 - os.Exit(0) 209 - } 210 - 211 - switch { 212 - case cfg.Services.List != nil: 213 - seedClient, err := client.NewSeedClient(cfg.Endpoint, cfg.ApiToken) 214 - if err != nil { 215 - slog.Error("Failed to initialize seed client") 216 - os.Exit(1) 217 - } 218 - 219 - for _, service := range cfg.Services.Services { 220 - seed, err := seedClient.GetSeed(string(service), string(client.Service)) 221 - if err != nil { 222 - slog.Error("Failed to get seed", "error", err, "name", string(service), "type", client.Service) 223 - continue 224 - } 225 - 226 - storePath, err := seedClient.GetSeedLatestPath(seed) 227 - if err != nil { 228 - slog.Error("Failed to get seed store path", "error", err) 229 - continue 230 - } 231 - 232 - slog.Info("Found service", "service", service, "store_path", storePath.Path) 233 - } 234 200 } 235 201 } 236 202 ··· 460 426 } 461 427 462 428 return nil 429 + } 430 + 431 + func servicesCommand(cfg config) { 432 + if len(cfg.Services.Services) == 0 { 433 + slog.Warn("No services configured") 434 + os.Exit(0) 435 + } 436 + 437 + switch { 438 + case cfg.Services.List != nil: 439 + seedClient, err := client.NewSeedClient(cfg.Endpoint, cfg.ApiToken) 440 + if err != nil { 441 + slog.Error("Failed to initialize seed client") 442 + os.Exit(1) 443 + } 444 + 445 + for _, service := range cfg.Services.Services { 446 + seed, err := seedClient.GetSeed(string(service), string(client.Service)) 447 + if err != nil { 448 + slog.Error("Failed to get seed", "error", err, "name", string(service), "type", client.Service) 449 + continue 450 + } 451 + 452 + storePath, err := seedClient.GetSeedLatestPath(seed) 453 + if err != nil { 454 + slog.Error("Failed to get seed store path", "error", err) 455 + continue 456 + } 457 + 458 + slog.Info("Found service", "service", service, "store_path", storePath.Path) 459 + } 460 + case cfg.Services.Upgrade != nil: 461 + seedClient, err := client.NewSeedClient(cfg.Endpoint, cfg.ApiToken) 462 + if err != nil { 463 + slog.Error("Failed to initialize seed client") 464 + os.Exit(1) 465 + } 466 + 467 + paths := []client.StorePath{} 468 + 469 + for _, service := range cfg.Services.Services { 470 + seed, err := seedClient.GetSeed(string(service), string(client.Service)) 471 + if err != nil { 472 + slog.Error("Failed to get seed", "error", err, "name", string(service), "type", client.Service) 473 + continue 474 + } 475 + 476 + storePath, err := seedClient.GetSeedLatestPath(seed) 477 + if err != nil { 478 + slog.Error("Failed to get seed store path", "error", err) 479 + continue 480 + } 481 + 482 + slog.Info("Found service", "service", service, "store_path", storePath.Path) 483 + 484 + caches, err := seedClient.GetNixCaches() 485 + if err != nil { 486 + slog.Error("Failed to get nix caches", "error", err) 487 + os.Exit(1) 488 + } 489 + 490 + if err := realize(storePath.Path, caches, false); err != nil { 491 + slog.Error("Failed realizing seed", "error", err) 492 + os.Exit(1) 493 + } 494 + 495 + slog.Info("Downloaded seed", "name", seed.Name, "type", seed.SeedType, "path", storePath.Path) 496 + 497 + paths = append(paths, *storePath) 498 + } 499 + 500 + err = buildServicesEnv(paths) 501 + if err != nil { 502 + slog.Error("Failed to build services environment", "error", err) 503 + os.Exit(1) 504 + } 505 + } 463 506 } 464 507 465 508 func default_config_path() (string, error) {
+73
cmd/client/services.go
··· 1 + package main 2 + 3 + import ( 4 + "fmt" 5 + "log/slog" 6 + "os" 7 + "os/exec" 8 + "text/template" 9 + 10 + "codeberg.org/adamcstephens/sower/client" 11 + "codeberg.org/adamcstephens/sower/cmd/client/commands" 12 + ) 13 + 14 + var nixpkgsref = "refs/heads/nixos-unstable" 15 + 16 + type EnvTemplate struct { 17 + Nixpkgsref string 18 + Paths []client.StorePath 19 + } 20 + 21 + // https://github.com/NixOS/nixpkgs/archive/refs/heads/master.zip 22 + func buildServicesEnv(paths []client.StorePath) error { 23 + slog.Debug("Building services environment", "nixpkgs", nixpkgsref) 24 + 25 + envTemplate := `{ 26 + pkgs ? 27 + import 28 + (fetchTarball "https://github.com/NixOS/nixpkgs/archive/{{ .Nixpkgsref }}.tar.gz") 29 + { }, 30 + }: 31 + pkgs.buildEnv { 32 + name = "sower-services"; 33 + paths = [{{ range .Paths }} 34 + {{ .Path }} 35 + {{ end }} ]; 36 + 37 + pathsToLink = [ 38 + "/.sower" 39 + ]; 40 + 41 + postBuild = '' 42 + mv $out/.sower/* $out/ 43 + rmdir $out/.sower 44 + ''; 45 + } 46 + ` 47 + 48 + envFileNix, err := os.CreateTemp("", "services-env") 49 + if err != nil { 50 + return fmt.Errorf("failed to create tempfile: %v", err) 51 + } 52 + defer os.Remove(envFileNix.Name()) 53 + 54 + templateParser, err := template.New("services-env").Parse(envTemplate) 55 + if err != nil { 56 + return fmt.Errorf("failed to parse template: %v", err) 57 + } 58 + 59 + err = templateParser.Execute(envFileNix, &EnvTemplate{Paths: paths, Nixpkgsref: nixpkgsref}) 60 + if err != nil { 61 + return fmt.Errorf("failed to parse template: %v", err) 62 + } 63 + 64 + cmd := exec.Command("nix-build", envFileNix.Name()) 65 + err = commands.SimpleRun(cmd) 66 + if err != nil { 67 + return fmt.Errorf("failed to build services env file: %v", err) 68 + } 69 + 70 + slog.Debug("Successfully built services environment", "nixpkgs", nixpkgsref) 71 + 72 + return nil 73 + }
+8 -1
nix/packages/client.nix
··· 3 3 buildGoModule, 4 4 version, 5 5 }: 6 + let 7 + nixpkgsref = lib.elemAt (lib.splitString "." lib.version) 3; 8 + in 9 + 6 10 buildGoModule rec { 7 11 pname = "sower"; 8 12 inherit version; ··· 22 26 23 27 env.CGO_ENABLED = 0; 24 28 25 - ldflags = [ "-X main.version=${version}" ]; 29 + ldflags = [ 30 + "-X main.version=${version}" 31 + "-X main.nixpkgsref=${nixpkgsref}" 32 + ]; 26 33 27 34 postInstall = '' 28 35 mv $out/bin/client $out/bin/sower