cmd/nixbuild: implement cache command
The tool this entire library is created for.
This commit is contained in:
parent
149b9c6a2a
commit
270298c73d
@ -5,7 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.gensokyo.uk/yonah/nixbuild"
|
"gensokyo.uk/nix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func formatInstallable(name string, installable *string, flagNixOS bool, args []string) error {
|
func formatInstallable(name string, installable *string, flagNixOS bool, args []string) error {
|
||||||
@ -21,16 +21,32 @@ func formatInstallable(name string, installable *string, flagNixOS bool, args []
|
|||||||
fields := strings.SplitN(*installable, "#", 2)
|
fields := strings.SplitN(*installable, "#", 2)
|
||||||
switch len(fields) {
|
switch len(fields) {
|
||||||
case 2:
|
case 2:
|
||||||
*installable = nixbuild.NixOSInstallable(fields[0], fields[1])
|
*installable = nix.InstallableNixOS(fields[0], fields[1])
|
||||||
return nil
|
return nil
|
||||||
case 1:
|
case 1:
|
||||||
hostname, err := os.Hostname()
|
hostname, err := os.Hostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return commandHandlerError(fmt.Sprintf("cannot get hostname: %v", err))
|
return commandHandlerError(fmt.Sprintf("cannot get hostname: %v", err))
|
||||||
}
|
}
|
||||||
*installable = nixbuild.NixOSInstallable(fields[0], hostname)
|
*installable = nix.InstallableNixOS(fields[0], hostname)
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return commandHandlerError("unexpected installable")
|
return commandHandlerError("unexpected installable")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func replaceFromEnviron(v map[string]*string) error {
|
||||||
|
for key, p := range v {
|
||||||
|
if *p != "env" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if s, ok := os.LookupEnv(key); !ok {
|
||||||
|
return commandHandlerError(key + " not set")
|
||||||
|
} else {
|
||||||
|
*p = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -47,6 +47,68 @@ func main() {
|
|||||||
Flag(&flagVerbose, "v", command.BoolFlag(false), "Connect nix stderr").
|
Flag(&flagVerbose, "v", command.BoolFlag(false), "Connect nix stderr").
|
||||||
Flag(&flagJSON, "json", command.BoolFlag(false), "Serialise output in JSON when applicable")
|
Flag(&flagJSON, "json", command.BoolFlag(false), "Serialise output in JSON when applicable")
|
||||||
|
|
||||||
|
// this is most likely what you are here for
|
||||||
|
var (
|
||||||
|
flagCacheKeyPath string
|
||||||
|
|
||||||
|
flagCacheComp string
|
||||||
|
flagCachePComp bool
|
||||||
|
flagCacheBucket string
|
||||||
|
flagCacheEndpoint string
|
||||||
|
flagCacheRegion string
|
||||||
|
flagCacheScheme string
|
||||||
|
flagCacheCredPath string
|
||||||
|
)
|
||||||
|
c.NewCommand("cache", "Build an installable and upload it to a binary cache", func(args []string) error {
|
||||||
|
if err := replaceFromEnviron(map[string]*string{
|
||||||
|
"NIX_TOOL_CACHE_KEY": &flagCacheKeyPath,
|
||||||
|
"NIX_TOOL_CACHE_COMPRESSION": &flagCacheComp,
|
||||||
|
"NIX_TOOL_CACHE_BUCKET": &flagCacheBucket,
|
||||||
|
"NIX_TOOL_CACHE_ENDPOINT": &flagCacheEndpoint,
|
||||||
|
"NIX_TOOL_CACHE_REGION": &flagCacheRegion,
|
||||||
|
"NIX_TOOL_CACHE_SCHEME": &flagCacheScheme,
|
||||||
|
"NIX_TOOL_CACHE_CRED": &flagCacheCredPath,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
installable string
|
||||||
|
collective []string
|
||||||
|
)
|
||||||
|
if err := buildAndResolve(ctx, "cache", &installable, &collective, flagNixOS, args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("signing collected paths")
|
||||||
|
if err := nix.Sign(ctx, flagCacheKeyPath, slices.Values(collective)); err != nil {
|
||||||
|
return commandHandlerError(fmt.Sprintf("cannot sign: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("copying to binary cache")
|
||||||
|
if err := nix.Copy(ctx, flagCacheKeyPath, &nix.BinaryCache{
|
||||||
|
Compression: flagCacheComp,
|
||||||
|
ParallelCompression: flagCachePComp,
|
||||||
|
Bucket: flagCacheBucket,
|
||||||
|
Endpoint: flagCacheEndpoint,
|
||||||
|
Region: flagCacheRegion,
|
||||||
|
Scheme: flagCacheScheme,
|
||||||
|
CredentialsPath: flagCacheCredPath,
|
||||||
|
}, slices.Values(collective)); err != nil {
|
||||||
|
return commandHandlerError(fmt.Sprintf("cannot copy: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}).
|
||||||
|
Flag(&flagCacheKeyPath, "secret-key", command.StringFlag("env"), "Path to the secret key used to sign the binary cache").
|
||||||
|
Flag(&flagCacheComp, "compression", command.StringFlag("zstd"), "Name of the compression algorithm to use").
|
||||||
|
Flag(&flagCachePComp, "parallel-compression", command.BoolFlag(true), "Whether parallel compression is enabled").
|
||||||
|
Flag(&flagCacheBucket, "bucket", command.StringFlag("env"), "S3 bucket name").
|
||||||
|
Flag(&flagCacheEndpoint, "endpoint", command.StringFlag("env"), "S3 endpoint").
|
||||||
|
Flag(&flagCacheRegion, "region", command.StringFlag("env"), "S3 region").
|
||||||
|
Flag(&flagCacheScheme, "scheme", command.StringFlag("https"), "S3 scheme").
|
||||||
|
Flag(&flagCacheCredPath, "credentials-path", command.StringFlag("env"), "Path to the s3 shared credentials file")
|
||||||
|
|
||||||
c.Command("show", command.UsageInternal, func(args []string) error {
|
c.Command("show", command.UsageInternal, func(args []string) error {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return commandHandlerError("show requires at least 1 argument")
|
return commandHandlerError("show requires at least 1 argument")
|
||||||
@ -90,32 +152,14 @@ func main() {
|
|||||||
resolveFlagOut string
|
resolveFlagOut string
|
||||||
)
|
)
|
||||||
c.Command("resolve", "Resolve possible build-time dependencies", func(args []string) error {
|
c.Command("resolve", "Resolve possible build-time dependencies", func(args []string) error {
|
||||||
var installable string
|
var (
|
||||||
if err := formatInstallable("resolve", &installable, flagNixOS, args); err != nil {
|
installable string
|
||||||
|
collective []string
|
||||||
|
)
|
||||||
|
if err := buildAndResolve(ctx, "resolve", &installable, &collective, flagNixOS, args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("evaluating %s", installable)
|
|
||||||
var installables []string
|
|
||||||
if v, err := nix.EvalInstantiated(ctx, installable); err != nil {
|
|
||||||
return commandHandlerError(fmt.Sprintf("cannot evaluate for instantiated derivations: %v", err))
|
|
||||||
} else {
|
|
||||||
installables = v
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("building instantiated derivations")
|
|
||||||
if err := nix.Build(ctx, slices.Values(installables)); err != nil {
|
|
||||||
return commandHandlerError(fmt.Sprintf("cannot build: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
var collective []string
|
|
||||||
log.Println("collecting store paths")
|
|
||||||
if derivations, err := nix.DerivationShow(ctx, slices.Values(installables)); err != nil {
|
|
||||||
return commandHandlerError(fmt.Sprintf("cannot show: %v", err))
|
|
||||||
} else {
|
|
||||||
collective = nix.CollectFromDerivations(derivations)
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Create(resolveFlagOut)
|
f, err := os.Create(resolveFlagOut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return commandHandlerError(fmt.Sprintf("cannot create store paths file: %v", err))
|
return commandHandlerError(fmt.Sprintf("cannot create store paths file: %v", err))
|
||||||
|
36
cmd/nixbuild/resolve.go
Normal file
36
cmd/nixbuild/resolve.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"gensokyo.uk/nix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func buildAndResolve(ctx nix.Context, name string, installable *string, collective *[]string, flagNixOS bool, args []string) error {
|
||||||
|
if err := formatInstallable(name, installable, flagNixOS, args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("evaluating %s", *installable)
|
||||||
|
var installables []string
|
||||||
|
if v, err := nix.EvalInstantiated(ctx, *installable); err != nil {
|
||||||
|
return commandHandlerError(fmt.Sprintf("cannot evaluate: %v", err))
|
||||||
|
} else {
|
||||||
|
installables = v
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("building instantiated derivations")
|
||||||
|
if err := nix.Build(ctx, slices.Values(installables)); err != nil {
|
||||||
|
return commandHandlerError(fmt.Sprintf("cannot build: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("collecting store paths")
|
||||||
|
if derivations, err := nix.DerivationShow(ctx, slices.Values(installables)); err != nil {
|
||||||
|
return commandHandlerError(fmt.Sprintf("cannot get derivations: %v", err))
|
||||||
|
} else {
|
||||||
|
*collective = nix.CollectFromDerivations(derivations)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user