Skip to content

Commit d30bed7

Browse files
committed
Added --root-user flag to devbox generate
1 parent 5e1b7e9 commit d30bed7

File tree

4 files changed

+91
-23
lines changed

4 files changed

+91
-23
lines changed

internal/boxcli/generate.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type generateCmdFlags struct {
1818
force bool
1919
printEnvrcContent bool
2020
githubUsername string
21+
rootUser bool
2122
}
2223

2324
func generateCmd() *cobra.Command {
@@ -64,6 +65,8 @@ func devcontainerCmd() *cobra.Command {
6465
}
6566
command.Flags().BoolVarP(
6667
&flags.force, "force", "f", false, "force overwrite on existing files")
68+
command.Flags().BoolVarP(
69+
&flags.rootUser, "root-user", "r", false, "Use root as default user inside the container")
6770
return command
6871
}
6972

@@ -81,6 +84,8 @@ func dockerfileCmd() *cobra.Command {
8184
}
8285
command.Flags().BoolVarP(
8386
&flags.force, "force", "f", false, "force overwrite existing files")
87+
command.Flags().BoolVarP(
88+
&flags.rootUser, "root-user", "r", false, "Use root as default user inside the container")
8489
flags.config.register(command)
8590
return command
8691
}
@@ -143,9 +148,9 @@ func runGenerateCmd(cmd *cobra.Command, flags *generateCmdFlags) error {
143148
case "debug":
144149
return box.Generate(cmd.Context())
145150
case "devcontainer":
146-
return box.GenerateDevcontainer(cmd.Context(), flags.force)
151+
return box.GenerateDevcontainer(cmd.Context(), flags.force, flags.rootUser)
147152
case "dockerfile":
148-
return box.GenerateDockerfile(cmd.Context(), flags.force)
153+
return box.GenerateDockerfile(cmd.Context(), flags.force, flags.rootUser)
149154
}
150155
return nil
151156
}

internal/impl/devbox.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ func (d *Devbox) Info(ctx context.Context, pkg string, markdown bool) error {
370370

371371
// GenerateDevcontainer generates devcontainer.json and Dockerfile for vscode run-in-container
372372
// and GitHub Codespaces
373-
func (d *Devbox) GenerateDevcontainer(ctx context.Context, force bool) error {
373+
func (d *Devbox) GenerateDevcontainer(ctx context.Context, force bool, rootUser bool) error {
374374
ctx, task := trace.NewTask(ctx, "devboxGenerateDevcontainer")
375375
defer task.End()
376376

@@ -394,15 +394,21 @@ func (d *Devbox) GenerateDevcontainer(ctx context.Context, force bool) error {
394394
return redact.Errorf("error creating dev container directory in <project>/%s: %w",
395395
redact.Safe(filepath.Base(devContainerPath)), err)
396396
}
397+
isDevcontainer := true
398+
399+
// Setup generate parameters
400+
g := generate.Open(
401+
ctx, devContainerPath, rootUser, isDevcontainer, d.Packages(), d.getLocalFlakesDirs(),
402+
)
403+
397404
// generate dockerfile
398-
err = generate.CreateDockerfile(ctx,
399-
devContainerPath, d.getLocalFlakesDirs(), true /* isDevcontainer */)
405+
err = g.CreateDockerfile()
400406
if err != nil {
401407
return redact.Errorf("error generating dev container Dockerfile in <project>/%s: %w",
402408
redact.Safe(filepath.Base(devContainerPath)), err)
403409
}
404410
// generate devcontainer.json
405-
err = generate.CreateDevcontainer(ctx, devContainerPath, d.Packages())
411+
err = g.CreateDevcontainer()
406412
if err != nil {
407413
return redact.Errorf("error generating devcontainer.json in <project>/%s: %w",
408414
redact.Safe(filepath.Base(devContainerPath)), err)
@@ -411,7 +417,7 @@ func (d *Devbox) GenerateDevcontainer(ctx context.Context, force bool) error {
411417
}
412418

413419
// GenerateDockerfile generates a Dockerfile that replicates the devbox shell
414-
func (d *Devbox) GenerateDockerfile(ctx context.Context, force bool) error {
420+
func (d *Devbox) GenerateDockerfile(ctx context.Context, force bool, rootUser bool) error {
415421
ctx, task := trace.NewTask(ctx, "devboxGenerateDockerfile")
416422
defer task.End()
417423

@@ -424,11 +430,15 @@ func (d *Devbox) GenerateDockerfile(ctx context.Context, force bool) error {
424430
"Remove it or use --force to overwrite it.",
425431
)
426432
}
433+
isDevcontainer := false
434+
435+
// Setup Generate parameters
436+
g := generate.Open(
437+
ctx, dockerfilePath, rootUser, isDevcontainer, d.Packages(), d.getLocalFlakesDirs(),
438+
)
427439

428440
// generate dockerfile
429-
return errors.WithStack(
430-
generate.CreateDockerfile(ctx,
431-
d.projectDir, d.getLocalFlakesDirs(), false /* isDevcontainer */))
441+
return errors.WithStack(g.CreateDockerfile())
432442
}
433443

434444
func PrintEnvrcContent(w io.Writer, envFlags devopt.EnvFlags) error {

internal/impl/generate/devcontainer_util.go

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ import (
2525
//go:embed tmpl/*
2626
var tmplFS embed.FS
2727

28+
type Generate struct {
29+
Ctx context.Context
30+
Path string
31+
RootUser bool
32+
IsDevcontainer bool
33+
Pkgs []string
34+
LocalFlakeDirs []string
35+
}
36+
2837
type devcontainerObject struct {
2938
Name string `json:"name"`
3039
Build *build `json:"build"`
@@ -48,15 +57,35 @@ type vscode struct {
4857

4958
type dockerfileData struct {
5059
IsDevcontainer bool
60+
RootUser bool
5161
LocalFlakeDirs []string
5262
}
5363

64+
func Open(
65+
ctx context.Context,
66+
path string,
67+
rootUser bool,
68+
isDevcontainer bool,
69+
pkgs []string,
70+
localFlakeDirs []string,
71+
) *Generate {
72+
73+
return &Generate{
74+
Ctx: ctx,
75+
Path: path,
76+
RootUser: rootUser,
77+
IsDevcontainer: isDevcontainer,
78+
Pkgs: pkgs,
79+
LocalFlakeDirs: localFlakeDirs,
80+
}
81+
}
82+
5483
// CreateDockerfile creates a Dockerfile in path and writes devcontainerDockerfile.tmpl's content into it
55-
func CreateDockerfile(ctx context.Context, path string, localFlakeDirs []string, isDevcontainer bool) error {
56-
defer trace.StartRegion(ctx, "createDockerfile").End()
84+
func (g *Generate) CreateDockerfile() error {
85+
defer trace.StartRegion(g.Ctx, "createDockerfile").End()
5786

5887
// create dockerfile
59-
file, err := os.Create(filepath.Join(path, "Dockerfile"))
88+
file, err := os.Create(g.Path)
6089
if err != nil {
6190
return err
6291
}
@@ -66,23 +95,24 @@ func CreateDockerfile(ctx context.Context, path string, localFlakeDirs []string,
6695
t := template.Must(template.ParseFS(tmplFS, "tmpl/"+tmplName))
6796
// write content into file
6897
return t.Execute(file, &dockerfileData{
69-
IsDevcontainer: isDevcontainer,
70-
LocalFlakeDirs: localFlakeDirs,
98+
IsDevcontainer: g.IsDevcontainer,
99+
RootUser: g.RootUser,
100+
LocalFlakeDirs: g.LocalFlakeDirs,
71101
})
72102
}
73103

74104
// CreateDevcontainer creates a devcontainer.json in path and writes getDevcontainerContent's output into it
75-
func CreateDevcontainer(ctx context.Context, path string, pkgs []string) error {
76-
defer trace.StartRegion(ctx, "createDevcontainer").End()
105+
func (g *Generate) CreateDevcontainer() error {
106+
defer trace.StartRegion(g.Ctx, "createDevcontainer").End()
77107

78108
// create devcontainer.json file
79-
file, err := os.Create(filepath.Join(path, "devcontainer.json"))
109+
file, err := os.Create(filepath.Join(g.Path, "devcontainer.json"))
80110
if err != nil {
81111
return err
82112
}
83113
defer file.Close()
84114
// get devcontainer.json's content
85-
devcontainerContent := getDevcontainerContent(pkgs)
115+
devcontainerContent := g.getDevcontainerContent()
86116
devcontainerFileBytes, err := json.MarshalIndent(devcontainerContent, "", " ")
87117
if err != nil {
88118
return err
@@ -121,7 +151,7 @@ func CreateEnvrc(ctx context.Context, path string, envFlags devopt.EnvFlags) err
121151
})
122152
}
123153

124-
func getDevcontainerContent(pkgs []string) *devcontainerObject {
154+
func (g *Generate) getDevcontainerContent() *devcontainerObject {
125155
// object that gets written in devcontainer.json
126156
devcontainerContent := &devcontainerObject{
127157
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
@@ -143,7 +173,10 @@ func getDevcontainerContent(pkgs []string) *devcontainerObject {
143173
},
144174
},
145175
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
146-
RemoteUser: "root",
176+
RemoteUser: "devbox",
177+
}
178+
if g.RootUser {
179+
devcontainerContent.RemoteUser = "root"
147180
}
148181

149182
// match only python3 or python3xx as package names
@@ -152,7 +185,7 @@ func getDevcontainerContent(pkgs []string) *devcontainerObject {
152185
debug.Log("Failed to compile regex")
153186
return nil
154187
}
155-
for _, pkg := range pkgs {
188+
for _, pkg := range g.Pkgs {
156189
if py3pattern.MatchString(pkg) {
157190
// Setup python3 interpreter path to devbox in the container
158191
devcontainerContent.Customizations.Vscode.Settings = map[string]any{

internal/impl/generate/tmpl/devcontainerDockerfile.tmpl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,38 @@ FROM debian:stable-slim
44
RUN apt-get update
55
RUN apt-get -y install bash binutils git{{if .IsDevcontainer}} gnupg2{{- end}} xz-utils wget sudo
66

7+
{{- if not .RootUser }}
8+
9+
# Step 1.5: Setting up devbox user
10+
ENV DEVBOX_USER=devbox
11+
RUN adduser $DEVBOX_USER
12+
RUN usermod -aG sudo $DEVBOX_USER
13+
RUN echo "devbox ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/$DEVBOX_USER
14+
USER $DEVBOX_USER
15+
{{- end}}
16+
717
# Step 2: Installing Nix
8-
RUN wget --output-document=/dev/stdout https://nixos.org/nix/install | sh -s -- --daemon
18+
RUN wget --output-document=/dev/stdout https://nixos.org/nix/install | sh -s -- --{{if not .RootUser}}no-{{- end}}daemon
919
RUN . ~/.nix-profile/etc/profile.d/nix.sh
20+
{{ if .RootUser }}
1021
ENV PATH="/root/.nix-profile/bin:$PATH"
22+
{{ else }}
23+
ENV PATH="/home/${DEVBOX_USER}/.nix-profile/bin:$PATH"
24+
{{- end}}
1125

1226
# Step 3: Installing devbox
1327
RUN wget --quiet --output-document=/dev/stdout https://get.jetpack.io/devbox | bash -s -- -f
28+
{{- if not .RootUser }}
29+
RUN chown -R "${DEVBOX_USER}:${DEVBOX_USER}" /usr/local/bin/devbox
30+
{{- end}}
1431

1532
# Step 4: Installing your devbox project
1633
WORKDIR /code
1734
COPY devbox.json devbox.json
1835
COPY devbox.lock devbox.lock
36+
{{- if not .RootUser }}
37+
RUN sudo chown -R "${DEVBOX_USER}:${DEVBOX_USER}" /code
38+
{{- end}}
1939
{{if len .LocalFlakeDirs}}
2040
# Step 6: Copying local flakes directories
2141
{{- end}}

0 commit comments

Comments
 (0)