Loading bootstrap_asset.go +59 −1 Changes for bootstrap_asset.go: 59 added lines, 1 removed line. Original line number Diff line number Diff line package felis import "embed" import ( "archive/tar" "embed" "io" "io/fs" ) //go:embed deploy/bootstrap.sh var bootstrapScript string Loading @@ -8,6 +13,59 @@ var bootstrapScript string //go:embed deploy/crd/*.yaml var bootstrapAssets embed.FS // gameStackAssets carries everything deploy/bootstrap.sh needs to build the two // always-on game images (login limbo + lobby) and the Velocity plugin, for the TUI // install path — which pipes the embedded bootstrap.sh into bash and therefore has // NO source checkout on disk to build from. // // The patterns are file- and directory-explicit rather than a bare `plugins`: a // developer's working tree carries gradle output (plugins/*/build, plugins/*/bin, // and for the modded loaders a decompiled Minecraft under build/) which would // otherwise be baked into every felis binary. Keep them explicit — add a source // directory here, never a parent. // //go:embed deploy/limbo/Dockerfile deploy/limbo/entrypoint.sh //go:embed deploy/lobby/Dockerfile deploy/lobby/entrypoint.sh //go:embed plugins/limbo/build.gradle plugins/limbo/settings.gradle plugins/limbo/src //go:embed plugins/paper/build.gradle plugins/paper/settings.gradle plugins/paper/src //go:embed plugins/velocity/build.gradle plugins/velocity/settings.gradle plugins/velocity/src //go:embed plugins/shared/src var gameStackAssets embed.FS // GameStackTar streams the embedded game-stack sources as a tar, rooted so that // `tar -x` reproduces the repo-relative layout the two Dockerfiles expect // (deploy/limbo/..., plugins/shared/...). bootstrap.sh extracts it into a temp dir // and uses that as the docker build context when it has no source checkout. func GameStackTar(w io.Writer) error { tw := tar.NewWriter(w) err := fs.WalkDir(gameStackAssets, ".", func(path string, d fs.DirEntry, err error) error { if err != nil || d.IsDir() || path == "." { return err } data, err := gameStackAssets.ReadFile(path) if err != nil { return err } // Mode 0644 for everything: entrypoint.sh is invoked as `sh <file>` by both // Dockerfiles precisely because the +x bit does not survive a Windows checkout, // so nothing here needs to be executable. if err := tw.WriteHeader(&tar.Header{ Name: path, Mode: 0o644, Size: int64(len(data)), Typeflag: tar.TypeReg, }); err != nil { return err } _, err = tw.Write(data) return err }) if err != nil { return err } return tw.Close() } // BootstrapScript returns the host bootstrap installer embedded in the felis binary. func BootstrapScript() string { return bootstrapScript Loading cmd/felis/bootstrap_assets.go +16 −2 Changes for cmd/felis/bootstrap_assets.go: 16 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -8,10 +8,12 @@ import ( ) func cmdBootstrapAssets(args []string, stdout, stderr io.Writer) int { if len(args) != 1 || args[0] != "crd" { fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd") if len(args) != 1 { fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd|game-stack") return 2 } switch args[0] { case "crd": crd, err := felis.MinecraftServerCRD() if err != nil { fmt.Fprintf(stderr, "felis bootstrap-assets: %v\n", err) Loading @@ -21,5 +23,17 @@ func cmdBootstrapAssets(args []string, stdout, stderr io.Writer) int { fmt.Fprintf(stderr, "felis bootstrap-assets: write: %v\n", err) return 1 } case "game-stack": // A tar on stdout, not a directory on disk: the caller (bootstrap.sh) is the // one that knows where a build context may live, and piping keeps this command // side-effect-free. if err := felis.GameStackTar(stdout); err != nil { fmt.Fprintf(stderr, "felis bootstrap-assets: %v\n", err) return 1 } default: fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd|game-stack") return 2 } return 0 } deploy/bootstrap.sh +420 −4 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
bootstrap_asset.go +59 −1 Changes for bootstrap_asset.go: 59 added lines, 1 removed line. Original line number Diff line number Diff line package felis import "embed" import ( "archive/tar" "embed" "io" "io/fs" ) //go:embed deploy/bootstrap.sh var bootstrapScript string Loading @@ -8,6 +13,59 @@ var bootstrapScript string //go:embed deploy/crd/*.yaml var bootstrapAssets embed.FS // gameStackAssets carries everything deploy/bootstrap.sh needs to build the two // always-on game images (login limbo + lobby) and the Velocity plugin, for the TUI // install path — which pipes the embedded bootstrap.sh into bash and therefore has // NO source checkout on disk to build from. // // The patterns are file- and directory-explicit rather than a bare `plugins`: a // developer's working tree carries gradle output (plugins/*/build, plugins/*/bin, // and for the modded loaders a decompiled Minecraft under build/) which would // otherwise be baked into every felis binary. Keep them explicit — add a source // directory here, never a parent. // //go:embed deploy/limbo/Dockerfile deploy/limbo/entrypoint.sh //go:embed deploy/lobby/Dockerfile deploy/lobby/entrypoint.sh //go:embed plugins/limbo/build.gradle plugins/limbo/settings.gradle plugins/limbo/src //go:embed plugins/paper/build.gradle plugins/paper/settings.gradle plugins/paper/src //go:embed plugins/velocity/build.gradle plugins/velocity/settings.gradle plugins/velocity/src //go:embed plugins/shared/src var gameStackAssets embed.FS // GameStackTar streams the embedded game-stack sources as a tar, rooted so that // `tar -x` reproduces the repo-relative layout the two Dockerfiles expect // (deploy/limbo/..., plugins/shared/...). bootstrap.sh extracts it into a temp dir // and uses that as the docker build context when it has no source checkout. func GameStackTar(w io.Writer) error { tw := tar.NewWriter(w) err := fs.WalkDir(gameStackAssets, ".", func(path string, d fs.DirEntry, err error) error { if err != nil || d.IsDir() || path == "." { return err } data, err := gameStackAssets.ReadFile(path) if err != nil { return err } // Mode 0644 for everything: entrypoint.sh is invoked as `sh <file>` by both // Dockerfiles precisely because the +x bit does not survive a Windows checkout, // so nothing here needs to be executable. if err := tw.WriteHeader(&tar.Header{ Name: path, Mode: 0o644, Size: int64(len(data)), Typeflag: tar.TypeReg, }); err != nil { return err } _, err = tw.Write(data) return err }) if err != nil { return err } return tw.Close() } // BootstrapScript returns the host bootstrap installer embedded in the felis binary. func BootstrapScript() string { return bootstrapScript Loading
cmd/felis/bootstrap_assets.go +16 −2 Changes for cmd/felis/bootstrap_assets.go: 16 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -8,10 +8,12 @@ import ( ) func cmdBootstrapAssets(args []string, stdout, stderr io.Writer) int { if len(args) != 1 || args[0] != "crd" { fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd") if len(args) != 1 { fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd|game-stack") return 2 } switch args[0] { case "crd": crd, err := felis.MinecraftServerCRD() if err != nil { fmt.Fprintf(stderr, "felis bootstrap-assets: %v\n", err) Loading @@ -21,5 +23,17 @@ func cmdBootstrapAssets(args []string, stdout, stderr io.Writer) int { fmt.Fprintf(stderr, "felis bootstrap-assets: write: %v\n", err) return 1 } case "game-stack": // A tar on stdout, not a directory on disk: the caller (bootstrap.sh) is the // one that knows where a build context may live, and piping keeps this command // side-effect-free. if err := felis.GameStackTar(stdout); err != nil { fmt.Fprintf(stderr, "felis bootstrap-assets: %v\n", err) return 1 } default: fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd|game-stack") return 2 } return 0 }
deploy/bootstrap.sh +420 −4 File changed.Preview size limit exceeded, changes collapsed. Show changes