exec: append custom store
This is primarily for chroot stores. This might not be useful however since chroot store breaks builds.
This commit is contained in:
parent
b6961508e8
commit
4d9d4bcef2
@ -85,7 +85,7 @@ func TestBuildBadCommand(t *testing.T) {
|
|||||||
wantErr := os.ErrNotExist
|
wantErr := os.ErrNotExist
|
||||||
breakNixCommand(t)
|
breakNixCommand(t)
|
||||||
if err := nix.Build(
|
if err := nix.Build(
|
||||||
nix.New(t.Context(), nil, nil, nil),
|
nix.New(t.Context(), nil, nil, nil, nil),
|
||||||
nil,
|
nil,
|
||||||
); !errors.Is(err, wantErr) {
|
); !errors.Is(err, wantErr) {
|
||||||
t.Errorf("Build: error = %v, want %v", err, wantErr)
|
t.Errorf("Build: error = %v, want %v", err, wantErr)
|
||||||
|
@ -45,11 +45,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var extraArgs []string
|
var (
|
||||||
|
store nix.Store
|
||||||
|
extraArgs []string
|
||||||
|
)
|
||||||
flagStore = strings.TrimSpace(flagStore)
|
flagStore = strings.TrimSpace(flagStore)
|
||||||
if flagStore != string(os.PathSeparator) {
|
if flagStore != string(os.PathSeparator) {
|
||||||
|
store = nix.Local(flagStore)
|
||||||
extraArgs = append(extraArgs,
|
extraArgs = append(extraArgs,
|
||||||
"--store", flagStore,
|
|
||||||
// do not use any binary cache
|
// do not use any binary cache
|
||||||
nix.FlagOption, nix.OptionBuildUseSubstitutes, nix.ValueFalse,
|
nix.FlagOption, nix.OptionBuildUseSubstitutes, nix.ValueFalse,
|
||||||
nix.FlagOption, nix.OptionSubstituters, "",
|
nix.FlagOption, nix.OptionSubstituters, "",
|
||||||
@ -62,7 +65,7 @@ func main() {
|
|||||||
if flagVerbose {
|
if flagVerbose {
|
||||||
stderr = os.Stderr
|
stderr = os.Stderr
|
||||||
}
|
}
|
||||||
ctx = nix.New(nixCtx, extraArgs, os.Stdout, stderr)
|
ctx = nix.New(nixCtx, store, extraArgs, os.Stdout, stderr)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}).
|
}).
|
||||||
@ -111,7 +114,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Println("copying to binary cache...")
|
log.Println("copying to binary cache...")
|
||||||
if err := nix.Copy(ctx, flagCacheKeyPath, &nix.BinaryCache{
|
if err := nix.Copy(ctx, &nix.BinaryCache{
|
||||||
Compression: flagCacheComp,
|
Compression: flagCacheComp,
|
||||||
ParallelCompression: flagCachePComp,
|
ParallelCompression: flagCachePComp,
|
||||||
Bucket: flagCacheBucket,
|
Bucket: flagCacheBucket,
|
||||||
@ -119,6 +122,7 @@ func main() {
|
|||||||
Region: flagCacheRegion,
|
Region: flagCacheRegion,
|
||||||
Scheme: flagCacheScheme,
|
Scheme: flagCacheScheme,
|
||||||
CredentialsPath: flagCacheCredPath,
|
CredentialsPath: flagCacheCredPath,
|
||||||
|
KeyPath: flagCacheKeyPath,
|
||||||
}, slices.Values(collective)); err != nil {
|
}, slices.Values(collective)); err != nil {
|
||||||
return commandHandlerError(fmt.Sprintf("cannot copy: %v", err))
|
return commandHandlerError(fmt.Sprintf("cannot copy: %v", err))
|
||||||
}
|
}
|
||||||
|
17
exec.go
17
exec.go
@ -19,6 +19,7 @@ var Nix = "nix"
|
|||||||
|
|
||||||
type nix struct {
|
type nix struct {
|
||||||
name string
|
name string
|
||||||
|
store Store
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
extra []string
|
extra []string
|
||||||
|
|
||||||
@ -40,12 +41,17 @@ A non-nil stderr implies verbose.
|
|||||||
|
|
||||||
Streams will not be connected for commands outputting JSON.
|
Streams will not be connected for commands outputting JSON.
|
||||||
*/
|
*/
|
||||||
func New(ctx context.Context, extraArgs []string, stdout, stderr io.Writer) Context {
|
func New(ctx context.Context, store Store, extraArgs []string, stdout, stderr io.Writer) Context {
|
||||||
|
extra := []string{ExtraExperimentalFeatures, ExperimentalFeaturesFlakes}
|
||||||
|
if store != nil {
|
||||||
|
extra = append(extraArgs, FlagStore, store.String())
|
||||||
|
}
|
||||||
return &nix{
|
return &nix{
|
||||||
name: Nix,
|
name: Nix,
|
||||||
ctx: ctx,
|
store: store,
|
||||||
|
ctx: ctx,
|
||||||
// since flakes are supposedly experimental
|
// since flakes are supposedly experimental
|
||||||
extra: append(extraArgs, ExtraExperimentalFeatures, ExperimentalFeaturesFlakes),
|
extra: append(extraArgs, extra...),
|
||||||
|
|
||||||
stdout: stdout,
|
stdout: stdout,
|
||||||
stderr: stderr,
|
stderr: stderr,
|
||||||
@ -56,6 +62,9 @@ func (n *nix) Nix(ctx context.Context, arg ...string) *exec.Cmd {
|
|||||||
cmd := exec.CommandContext(ctx, n.name, append(n.extra, arg...)...)
|
cmd := exec.CommandContext(ctx, n.name, append(n.extra, arg...)...)
|
||||||
cmd.Cancel = func() error { return cmd.Process.Signal(os.Interrupt) }
|
cmd.Cancel = func() error { return cmd.Process.Signal(os.Interrupt) }
|
||||||
cmd.WaitDelay = defaultWaitDelay
|
cmd.WaitDelay = defaultWaitDelay
|
||||||
|
if n.store != nil {
|
||||||
|
cmd.Env = append(cmd.Env, n.store.Environ()...)
|
||||||
|
}
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ func stubNixCommand(t *testing.T) {
|
|||||||
|
|
||||||
// newStubContext creates a context for use with the nix command stub.
|
// newStubContext creates a context for use with the nix command stub.
|
||||||
func newStubContext(ctx context.Context, extraArgs []string, stdout, stderr io.Writer) nix.Context {
|
func newStubContext(ctx context.Context, extraArgs []string, stdout, stderr io.Writer) nix.Context {
|
||||||
return nix.New(ctx, append(stubExtraArgs, extraArgs...), stdout, stderr)
|
return nix.New(ctx, nil, append(stubExtraArgs, extraArgs...), stdout, stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
type stubContextCommand struct {
|
type stubContextCommand struct {
|
||||||
|
30
exec_test.go
30
exec_test.go
@ -13,8 +13,36 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNixWriteStdin(t *testing.T) {
|
func TestNixWriteStdin(t *testing.T) {
|
||||||
|
t.Run("store", func(t *testing.T) {
|
||||||
|
ctx := nix.New(t.Context(), &nix.BinaryCache{
|
||||||
|
Compression: "none",
|
||||||
|
ParallelCompression: false,
|
||||||
|
Bucket: "example",
|
||||||
|
Endpoint: "s3.example.org",
|
||||||
|
Region: "us-east-1",
|
||||||
|
Scheme: "http",
|
||||||
|
CredentialsPath: "/dev/null",
|
||||||
|
KeyPath: nonexistent,
|
||||||
|
}, nil, nil, nil)
|
||||||
|
cmd := ctx.Nix(t.Context(), nix.FlagVersion)
|
||||||
|
|
||||||
|
wantArgs := []string{
|
||||||
|
nix.Nix,
|
||||||
|
nix.FlagStore,
|
||||||
|
"s3://example?compression=none¶llel-compression=false®ion=us-east-1&scheme=http&endpoint=s3.example.org&secret-key=/proc/nonexistent",
|
||||||
|
nix.FlagVersion}
|
||||||
|
if !slices.Equal(cmd.Args, wantArgs) {
|
||||||
|
t.Errorf("Args = %#v, want %#v", cmd.Args, wantArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
wantEnv := []string{nix.EnvAwsSharedCredentialsFile + "=/dev/null"}
|
||||||
|
if !slices.Equal(cmd.Env, wantEnv) {
|
||||||
|
t.Errorf("Env = %#v, want %#v", cmd.Env, wantEnv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("already set", func(t *testing.T) {
|
t.Run("already set", func(t *testing.T) {
|
||||||
ctx := nix.New(t.Context(), nil, os.Stdout, os.Stderr)
|
ctx := nix.New(t.Context(), nil, nil, os.Stdout, os.Stderr)
|
||||||
cmd := exec.CommandContext(t.Context(), nonexistent)
|
cmd := exec.CommandContext(t.Context(), nonexistent)
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
if _, err := ctx.WriteStdin(cmd, nil, nil); err == nil {
|
if _, err := ctx.WriteStdin(cmd, nil, nil); err == nil {
|
||||||
|
@ -80,6 +80,9 @@ const (
|
|||||||
// FlagVersion show version information.
|
// FlagVersion show version information.
|
||||||
FlagVersion = "--version"
|
FlagVersion = "--version"
|
||||||
|
|
||||||
|
// FlagStore is a loosely documented flag for specifying the store url to operate on.
|
||||||
|
FlagStore = "--store"
|
||||||
|
|
||||||
// FlagKeepGoing keep going in case of failed builds, to the greatest extent possible.
|
// FlagKeepGoing keep going in case of failed builds, to the greatest extent possible.
|
||||||
// That is, if building an input of some derivation fails, Nix will still build the other inputs,
|
// That is, if building an input of some derivation fails, Nix will still build the other inputs,
|
||||||
// but not the derivation itself.
|
// but not the derivation itself.
|
||||||
|
@ -107,7 +107,7 @@ func TestInstantiatedEvaluatorBadCommand(t *testing.T) {
|
|||||||
breakNixCommand(t)
|
breakNixCommand(t)
|
||||||
|
|
||||||
if _, err := nix.EvalInstantiated(
|
if _, err := nix.EvalInstantiated(
|
||||||
nix.New(t.Context(), nil, os.Stdout, os.Stderr),
|
nix.New(t.Context(), nil, nil, os.Stdout, os.Stderr),
|
||||||
"",
|
"",
|
||||||
); !errors.Is(err, wantErr) {
|
); !errors.Is(err, wantErr) {
|
||||||
t.Errorf("EvalInstantiated: error = %v, want %v", err, wantErr)
|
t.Errorf("EvalInstantiated: error = %v, want %v", err, wantErr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user