Skip to content

Commit faaf2a3

Browse files
committed
feat: add option to skip logins during bootstrap for system preloading
1 parent d69e557 commit faaf2a3

9 files changed

Lines changed: 60 additions & 5 deletions

File tree

addons/bootstrap/addon.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package bootstrap
22

33
import (
44
"fmt"
5+
"strconv"
56

67
"github.com/spf13/cobra"
78

89
"fastcat.org/go/gdev/addons"
10+
b_internal "fastcat.org/go/gdev/addons/bootstrap/internal"
911
"fastcat.org/go/gdev/instance"
1012
"fastcat.org/go/gdev/internal"
1113
)
@@ -44,6 +46,17 @@ func Configure(opts ...Option) {
4446
func initialize() error {
4547
cmd := RunPlanCmd(addon.Config.plan)
4648
cmd.Use = "bootstrap"
49+
pf := cmd.PersistentFlags()
50+
pf.BoolFunc("skip-logins", "skip logging into any accounts", func(s string) error {
51+
if s == "" {
52+
b_internal.SetDefault(skipLoginsKey, true)
53+
} else if v, err := strconv.ParseBool(s); err != nil {
54+
return err
55+
} else {
56+
b_internal.SetDefault(skipLoginsKey, v)
57+
}
58+
return nil
59+
})
4760
instance.AddCommands(cmd)
4861

4962
for _, f := range addon.Config.cmdFactories {

addons/bootstrap/context-keys.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package bootstrap
2+
3+
var skipLoginsKey = NewKey[bool]("bootstrap.skipLogins")
4+
5+
// SkipLogins returns whether login steps should be skipped. This is set by a
6+
// command line argument. Custom bootstrap steps/plans should obey this.
7+
func SkipLogins(ctx *Context) bool {
8+
v, ok := Get(ctx, skipLoginsKey)
9+
return ok && v
10+
}
11+
12+
func SkipIfNoLogins() StepOpt {
13+
return SkipFunc(func(ctx *Context) (bool, error) {
14+
return SkipLogins(ctx), nil
15+
})
16+
}

addons/bootstrap/context.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ type (
1313
InfoKey[T any] = internal.InfoKey[T]
1414
)
1515

16-
func NewContext(ctx context.Context) *Context {
17-
return internal.NewContext(ctx)
16+
func NewContextWithDefaults(ctx context.Context) *Context {
17+
return internal.NewContextWithDefaults(ctx)
1818
}
1919

2020
func NewKey[T any](name string) InfoKey[T] {

addons/bootstrap/input/user.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,5 +229,6 @@ func UserInfoStep() *bootstrap.Step {
229229
GitHubUserPrompt,
230230
).With(
231231
bootstrap.AfterSteps(apt.StepNameInstall),
232+
bootstrap.SkipIfNoLogins(),
232233
)
233234
}

addons/bootstrap/internal/context.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,27 @@ package internal
33
import (
44
"context"
55
"fmt"
6+
"maps"
67
)
78

89
type Context struct {
910
context.Context
1011
info map[AnyInfoKey]any
1112
}
1213

13-
func NewContext(ctx context.Context) *Context {
14+
var defaults = map[AnyInfoKey]any{}
15+
16+
// NewContextWithDefaults creates a new Context with default InfoKey values as
17+
// configured with SetDefault.
18+
func NewContextWithDefaults(ctx context.Context) *Context {
19+
bCtx := NewEmptyContext(ctx)
20+
maps.Copy(bCtx.info, defaults)
21+
return bCtx
22+
}
23+
24+
// NewEmptyContext creates a new empty Context without any default InfoKey
25+
// values set.
26+
func NewEmptyContext(ctx context.Context) *Context {
1427
return &Context{
1528
Context: ctx,
1629
info: map[AnyInfoKey]any{},
@@ -32,6 +45,13 @@ func Set[T any](ctx *Context, k InfoKey[T], v T) {
3245
ctx.info[k] = v
3346
}
3447

48+
func SetDefault[T any](k InfoKey[T], v T) {
49+
if _, ok := defaults[k]; ok {
50+
panic(fmt.Errorf("already saved default %s for %v", k.k, k.typ()))
51+
}
52+
defaults[k] = v
53+
}
54+
3555
func Get[T any](ctx *Context, k InfoKey[T]) (T, bool) {
3656
v, ok := ctx.info[k]
3757
if !ok {

addons/bootstrap/plan.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func (p *Plan) Run(ctx context.Context) error {
111111
func (p *Plan) prepare(ctx context.Context) (*Context, error) {
112112
bc, ok := ctx.(*Context)
113113
if !ok {
114-
bc = NewContext(ctx)
114+
bc = NewContextWithDefaults(ctx)
115115
}
116116
if !p.Ready() {
117117
names := make([]string, 0, len(p.pending))

addons/gcloud/addon.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ func BootstrapSteps() []*bootstrap.Step {
115115
ConfigureStepName,
116116
configureGcloud,
117117
bootstrap.AfterSteps(apt.StepNameInstall),
118+
bootstrap.SkipIfNoLogins(),
118119
),
119120
)
120121
return steps
@@ -180,6 +181,7 @@ func verifyStep() *bootstrap.Step {
180181
return nil
181182
},
182183
// the two auth steps mark themselves before this to order things
184+
bootstrap.SkipIfNoLogins(),
183185
)
184186
}
185187

addons/github/gh-login.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ func GHLoginStep(opts GHLoginOpts) *bootstrap.Step {
6767
return nil
6868
},
6969
bootstrap.AfterSteps(apt.StepNameInstall),
70+
bootstrap.SkipIfNoLogins(),
7071
)
7172
}
7273

addons/tailscale/addon.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tailscale
22

33
import (
4+
"context"
45
_ "embed"
56
"fmt"
67
"sync"
@@ -95,6 +96,7 @@ var configureBootstrap = sync.OnceFunc(func() {
9596
configureTailscale,
9697
bootstrap.AfterSteps(apt.StepNameInstall),
9798
bootstrap.SkipInContainer(),
99+
bootstrap.SkipIfNoLogins(),
98100
)),
99101
)
100102
})
@@ -108,7 +110,7 @@ func configureTailscale(ctx *bootstrap.Context) error {
108110
return TailscaleUp(ctx)
109111
}
110112

111-
func TailscaleUp(ctx *bootstrap.Context) error {
113+
func TailscaleUp(ctx context.Context) error {
112114
fmt.Println("Bringing up tailscale...")
113115
_, err := shx.Run(
114116
ctx,

0 commit comments

Comments
 (0)