Skip to content

Commit 6fc1cfa

Browse files
committed
chore: extract constants package (#282)
Signed-off-by: Cian Johnston <[email protected]> (cherry picked from commit cc0b4c5)
1 parent 9aa5fe9 commit 6fc1cfa

File tree

4 files changed

+60
-51
lines changed

4 files changed

+60
-51
lines changed

constants/constants.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package constants
2+
3+
import (
4+
"errors"
5+
"path/filepath"
6+
)
7+
8+
const (
9+
// WorkspacesDir is the path to the directory where
10+
// all workspaces are stored by default.
11+
WorkspacesDir = "/workspaces"
12+
13+
// EmptyWorkspaceDir is the path to a workspace that has
14+
// nothing going on... it's empty!
15+
EmptyWorkspaceDir = WorkspacesDir + "/empty"
16+
17+
// MagicDir is where all envbuilder related files are stored.
18+
// This is a special directory that must not be modified
19+
// by the user or images.
20+
MagicDir = "/.envbuilder"
21+
)
22+
23+
var (
24+
ErrNoFallbackImage = errors.New("no fallback image has been specified")
25+
26+
// MagicFile is a file that is created in the workspace
27+
// when envbuilder has already been run. This is used
28+
// to skip building when a container is restarting.
29+
// e.g. docker stop -> docker start
30+
MagicFile = filepath.Join(MagicDir, "built")
31+
)

envbuilder.go

+17-41
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"syscall"
2525
"time"
2626

27+
"github.com/coder/envbuilder/constants"
2728
"github.com/coder/envbuilder/git"
2829
"github.com/coder/envbuilder/options"
2930

@@ -53,31 +54,6 @@ import (
5354
"golang.org/x/xerrors"
5455
)
5556

56-
const (
57-
// WorkspacesDir is the path to the directory where
58-
// all workspaces are stored by default.
59-
WorkspacesDir = "/workspaces"
60-
61-
// EmptyWorkspaceDir is the path to a workspace that has
62-
// nothing going on... it's empty!
63-
EmptyWorkspaceDir = WorkspacesDir + "/empty"
64-
65-
// MagicDir is where all envbuilder related files are stored.
66-
// This is a special directory that must not be modified
67-
// by the user or images.
68-
MagicDir = "/.envbuilder"
69-
)
70-
71-
var (
72-
ErrNoFallbackImage = errors.New("no fallback image has been specified")
73-
74-
// MagicFile is a file that is created in the workspace
75-
// when envbuilder has already been run. This is used
76-
// to skip building when a container is restarting.
77-
// e.g. docker stop -> docker start
78-
MagicFile = filepath.Join(MagicDir, "built")
79-
)
80-
8157
// DockerConfig represents the Docker configuration file.
8258
type DockerConfig configfile.ConfigFile
8359

@@ -171,7 +147,7 @@ func Run(ctx context.Context, opts options.Options) error {
171147
if err != nil {
172148
return fmt.Errorf("parse docker config: %w", err)
173149
}
174-
err = os.WriteFile(filepath.Join(MagicDir, "config.json"), decoded, 0o644)
150+
err = os.WriteFile(filepath.Join(constants.MagicDir, "config.json"), decoded, 0o644)
175151
if err != nil {
176152
return fmt.Errorf("write docker config: %w", err)
177153
}
@@ -237,19 +213,19 @@ func Run(ctx context.Context, opts options.Options) error {
237213
}
238214

239215
defaultBuildParams := func() (*devcontainer.Compiled, error) {
240-
dockerfile := filepath.Join(MagicDir, "Dockerfile")
216+
dockerfile := filepath.Join(constants.MagicDir, "Dockerfile")
241217
file, err := opts.Filesystem.OpenFile(dockerfile, os.O_CREATE|os.O_WRONLY, 0o644)
242218
if err != nil {
243219
return nil, err
244220
}
245221
defer file.Close()
246222
if opts.FallbackImage == "" {
247223
if fallbackErr != nil {
248-
return nil, xerrors.Errorf("%s: %w", fallbackErr.Error(), ErrNoFallbackImage)
224+
return nil, xerrors.Errorf("%s: %w", fallbackErr.Error(), constants.ErrNoFallbackImage)
249225
}
250226
// We can't use errors.Join here because our tests
251227
// don't support parsing a multiline error.
252-
return nil, ErrNoFallbackImage
228+
return nil, constants.ErrNoFallbackImage
253229
}
254230
content := "FROM " + opts.FallbackImage
255231
_, err = file.Write([]byte(content))
@@ -259,7 +235,7 @@ func Run(ctx context.Context, opts options.Options) error {
259235
return &devcontainer.Compiled{
260236
DockerfilePath: dockerfile,
261237
DockerfileContent: content,
262-
BuildContext: MagicDir,
238+
BuildContext: constants.MagicDir,
263239
}, nil
264240
}
265241

@@ -301,7 +277,7 @@ func Run(ctx context.Context, opts options.Options) error {
301277
opts.Logger(log.LevelInfo, "No Dockerfile or image specified; falling back to the default image...")
302278
fallbackDockerfile = defaultParams.DockerfilePath
303279
}
304-
buildParams, err = devContainer.Compile(opts.Filesystem, devcontainerDir, MagicDir, fallbackDockerfile, opts.WorkspaceFolder, false, os.LookupEnv)
280+
buildParams, err = devContainer.Compile(opts.Filesystem, devcontainerDir, constants.MagicDir, fallbackDockerfile, opts.WorkspaceFolder, false, os.LookupEnv)
305281
if err != nil {
306282
return fmt.Errorf("compile devcontainer.json: %w", err)
307283
}
@@ -399,7 +375,7 @@ func Run(ctx context.Context, opts options.Options) error {
399375
// So we add them to the default ignore list. See:
400376
// https://github.com/GoogleContainerTools/kaniko/blob/63be4990ca5a60bdf06ddc4d10aa4eca0c0bc714/cmd/executor/cmd/root.go#L136
401377
ignorePaths := append([]string{
402-
MagicDir,
378+
constants.MagicDir,
403379
opts.WorkspaceFolder,
404380
// See: https://github.com/coder/envbuilder/issues/37
405381
"/etc/resolv.conf",
@@ -441,7 +417,7 @@ ENTRYPOINT [%q]`, exePath, exePath, exePath)
441417
}
442418

443419
// temp move of all ro mounts
444-
tempRemountDest := filepath.Join("/", MagicDir, "mnt")
420+
tempRemountDest := filepath.Join("/", constants.MagicDir, "mnt")
445421
// ignorePrefixes is a superset of ignorePaths that we pass to kaniko's
446422
// IgnoreList.
447423
ignorePrefixes := append([]string{"/dev", "/proc", "/sys"}, ignorePaths...)
@@ -457,7 +433,7 @@ ENTRYPOINT [%q]`, exePath, exePath, exePath)
457433

458434
skippedRebuild := false
459435
build := func() (v1.Image, error) {
460-
_, err := opts.Filesystem.Stat(MagicFile)
436+
_, err := opts.Filesystem.Stat(constants.MagicFile)
461437
if err == nil && opts.SkipRebuild {
462438
endStage := startStage("🏗️ Skipping build because of cache...")
463439
imageRef, err := devcontainer.ImageFromDockerfile(buildParams.DockerfileContent)
@@ -640,7 +616,7 @@ ENTRYPOINT [%q]`, exePath, exePath, exePath)
640616

641617
// Create the magic file to indicate that this build
642618
// has already been ran before!
643-
file, err := opts.Filesystem.Create(MagicFile)
619+
file, err := opts.Filesystem.Create(constants.MagicFile)
644620
if err != nil {
645621
return fmt.Errorf("create magic file: %w", err)
646622
}
@@ -695,7 +671,7 @@ ENTRYPOINT [%q]`, exePath, exePath, exePath)
695671

696672
// Remove the Docker config secret file!
697673
if opts.DockerConfigBase64 != "" {
698-
c := filepath.Join(MagicDir, "config.json")
674+
c := filepath.Join(constants.MagicDir, "config.json")
699675
err = os.Remove(c)
700676
if err != nil {
701677
if !errors.Is(err, fs.ErrNotExist) {
@@ -855,7 +831,7 @@ ENTRYPOINT [%q]`, exePath, exePath, exePath)
855831
opts.Logger(log.LevelInfo, "=== Running the setup command %q as the root user...", opts.SetupScript)
856832

857833
envKey := "ENVBUILDER_ENV"
858-
envFile := filepath.Join("/", MagicDir, "environ")
834+
envFile := filepath.Join("/", constants.MagicDir, "environ")
859835
file, err := os.Create(envFile)
860836
if err != nil {
861837
return fmt.Errorf("create environ file: %w", err)
@@ -958,7 +934,7 @@ ENTRYPOINT [%q]`, exePath, exePath, exePath)
958934
// for a given repository URL.
959935
func DefaultWorkspaceFolder(repoURL string) (string, error) {
960936
if repoURL == "" {
961-
return EmptyWorkspaceDir, nil
937+
return constants.EmptyWorkspaceDir, nil
962938
}
963939
parsed, err := giturls.Parse(repoURL)
964940
if err != nil {
@@ -967,7 +943,7 @@ func DefaultWorkspaceFolder(repoURL string) (string, error) {
967943
name := strings.Split(parsed.Path, "/")
968944
hasOwnerAndRepo := len(name) >= 2
969945
if !hasOwnerAndRepo {
970-
return EmptyWorkspaceDir, nil
946+
return constants.EmptyWorkspaceDir, nil
971947
}
972948
repo := strings.TrimSuffix(name[len(name)-1], ".git")
973949
return fmt.Sprintf("/workspaces/%s", repo), nil
@@ -1180,7 +1156,7 @@ func findDevcontainerJSON(options options.Options) (string, string, error) {
11801156
// folks from unwittingly deleting their entire root directory.
11811157
func maybeDeleteFilesystem(logger log.Func, force bool) error {
11821158
kanikoDir, ok := os.LookupEnv("KANIKO_DIR")
1183-
if !ok || strings.TrimSpace(kanikoDir) != MagicDir {
1159+
if !ok || strings.TrimSpace(kanikoDir) != constants.MagicDir {
11841160
if force {
11851161
bailoutSecs := 10
11861162
logger(log.LevelWarn, "WARNING! BYPASSING SAFETY CHECK! THIS WILL DELETE YOUR ROOT FILESYSTEM!")
@@ -1190,7 +1166,7 @@ func maybeDeleteFilesystem(logger log.Func, force bool) error {
11901166
<-time.After(time.Second)
11911167
}
11921168
} else {
1193-
logger(log.LevelError, "KANIKO_DIR is not set to %s. Bailing!\n", MagicDir)
1169+
logger(log.LevelError, "KANIKO_DIR is not set to %s. Bailing!\n", constants.MagicDir)
11941170
logger(log.LevelError, "To bypass this check, set FORCE_SAFE=true.")
11951171
return errors.New("safety check failed")
11961172
}

envbuilder_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"testing"
55

66
"github.com/coder/envbuilder"
7+
"github.com/coder/envbuilder/constants"
8+
79
"github.com/stretchr/testify/require"
810
)
911

@@ -38,7 +40,7 @@ func TestDefaultWorkspaceFolder(t *testing.T) {
3840
{
3941
name: "empty",
4042
gitURL: "",
41-
expected: envbuilder.EmptyWorkspaceDir,
43+
expected: constants.EmptyWorkspaceDir,
4244
},
4345
}
4446
for _, tt := range successTests {
@@ -66,7 +68,7 @@ func TestDefaultWorkspaceFolder(t *testing.T) {
6668
t.Run(tt.name, func(t *testing.T) {
6769
dir, err := envbuilder.DefaultWorkspaceFolder(tt.invalidURL)
6870
require.NoError(t, err)
69-
require.Equal(t, envbuilder.EmptyWorkspaceDir, dir)
71+
require.Equal(t, constants.EmptyWorkspaceDir, dir)
7072
})
7173
}
7274
}

integration/integration_test.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ import (
2121
"testing"
2222
"time"
2323

24-
"github.com/coder/envbuilder/options"
25-
2624
"github.com/coder/envbuilder"
25+
"github.com/coder/envbuilder/constants"
2726
"github.com/coder/envbuilder/devcontainer/features"
27+
"github.com/coder/envbuilder/options"
2828
"github.com/coder/envbuilder/testutil/gittest"
2929
"github.com/coder/envbuilder/testutil/mwtest"
3030
"github.com/coder/envbuilder/testutil/registrytest"
@@ -366,7 +366,7 @@ func TestBuildFromDockerfile(t *testing.T) {
366366
require.Equal(t, "hello", strings.TrimSpace(output))
367367

368368
// Verify that the Docker configuration secret file is removed
369-
output = execContainer(t, ctr, "stat "+filepath.Join(envbuilder.MagicDir, "config.json"))
369+
output = execContainer(t, ctr, "stat "+filepath.Join(constants.MagicDir, "config.json"))
370370
require.Contains(t, output, "No such file or directory")
371371
}
372372

@@ -592,7 +592,7 @@ func TestCloneFailsFallback(t *testing.T) {
592592
_, err := runEnvbuilder(t, runOpts{env: []string{
593593
envbuilderEnv("GIT_URL", "bad-value"),
594594
}})
595-
require.ErrorContains(t, err, envbuilder.ErrNoFallbackImage.Error())
595+
require.ErrorContains(t, err, constants.ErrNoFallbackImage.Error())
596596
})
597597
}
598598

@@ -610,7 +610,7 @@ func TestBuildFailsFallback(t *testing.T) {
610610
envbuilderEnv("GIT_URL", srv.URL),
611611
envbuilderEnv("DOCKERFILE_PATH", "Dockerfile"),
612612
}})
613-
require.ErrorContains(t, err, envbuilder.ErrNoFallbackImage.Error())
613+
require.ErrorContains(t, err, constants.ErrNoFallbackImage.Error())
614614
require.ErrorContains(t, err, "dockerfile parse error")
615615
})
616616
t.Run("FailsBuild", func(t *testing.T) {
@@ -626,7 +626,7 @@ RUN exit 1`,
626626
envbuilderEnv("GIT_URL", srv.URL),
627627
envbuilderEnv("DOCKERFILE_PATH", "Dockerfile"),
628628
}})
629-
require.ErrorContains(t, err, envbuilder.ErrNoFallbackImage.Error())
629+
require.ErrorContains(t, err, constants.ErrNoFallbackImage.Error())
630630
})
631631
t.Run("BadDevcontainer", func(t *testing.T) {
632632
t.Parallel()
@@ -639,7 +639,7 @@ RUN exit 1`,
639639
_, err := runEnvbuilder(t, runOpts{env: []string{
640640
envbuilderEnv("GIT_URL", srv.URL),
641641
}})
642-
require.ErrorContains(t, err, envbuilder.ErrNoFallbackImage.Error())
642+
require.ErrorContains(t, err, constants.ErrNoFallbackImage.Error())
643643
})
644644
t.Run("NoImageOrDockerfile", func(t *testing.T) {
645645
t.Parallel()
@@ -972,7 +972,7 @@ func setupPassthroughRegistry(t *testing.T, image string, opts *setupPassthrough
972972

973973
func TestNoMethodFails(t *testing.T) {
974974
_, err := runEnvbuilder(t, runOpts{env: []string{}})
975-
require.ErrorContains(t, err, envbuilder.ErrNoFallbackImage.Error())
975+
require.ErrorContains(t, err, constants.ErrNoFallbackImage.Error())
976976
}
977977

978978
func TestDockerfileBuildContext(t *testing.T) {

0 commit comments

Comments
 (0)