diff --git a/build.sh b/build.sh index 9c1320d..2e979a0 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -e + userID=$(id -u) groupID=$(id -g) diff --git a/docker/Dockerfile b/docker/Dockerfile index 4b5f5a6..e28ba7d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,9 +1,11 @@ -FROM golang:latest AS builder +FROM golang:1.21-rc-alpine AS builder ARG UID=1000 ARG GID=1000 -RUN addgroup --gid ${GID} bobthebuilder && adduser --gid ${GID} --uid ${UID} bobthebuilder +RUN apk add upx shadow + +RUN groupadd --gid ${GID} bobthebuilder && useradd -m --gid ${GID} --uid ${UID} bobthebuilder RUN mkdir /build RUN chown -Rv bobthebuilder:bobthebuilder /build @@ -14,7 +16,9 @@ RUN chown -Rv bobthebuilder:bobthebuilder /workspace USER bobthebuilder WORKDIR /workspace -RUN [ "go", "build", "-o", "/build/docker_launcher", "." ] +RUN [ "go", "build", "-ldflags", "-s -w", "-o", "/build/docker_launcher", "." ] + +RUN [ "upx", "/build/docker_launcher" ] FROM alpine:latest diff --git a/main.go b/main.go index 2b406cc..b37474f 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,9 @@ import ( "flag" "log" "os" + "os/exec" "regexp" + "strings" ) type file struct { @@ -18,9 +20,19 @@ type config struct { VariableRegex string RegexGroup int ForceOverwrite bool + + UpdateUID bool + User string + UIDVariable string + + UpdateGID bool + Group string + GIDVariable string } -var defaultVariableRegex = `\$\{([a-zA-Z0-9_-]+)\}` +const defaultVariableRegex = `\$\{([a-zA-Z0-9_-]+)\}` +const defaultUIDVariable = "UID" +const defaultGIDVariable = "GID" func loadConfig(path string) (*config, error) { raw, err := os.ReadFile(path) @@ -121,11 +133,55 @@ func filterFiles(config config) error { return nil } +func updateUID(config config) error { + uidVariable := config.UIDVariable + if len(uidVariable) == 0 { + uidVariable = defaultUIDVariable + } + + newUID := os.Getenv(uidVariable) + if len(newUID) == 0 { + log.Println("UID variable is not set. Not updating UID") + return nil + } + + err := exec.Command("usermod", "-u", newUID, config.User).Run() + if err != nil { + return err + } + + return nil +} + +func updateGID(config config) error { + gidVariable := config.GIDVariable + if len(gidVariable) == 0 { + gidVariable = defaultGIDVariable + } + + newGID := os.Getenv(gidVariable) + if len(newGID) == 0 { + log.Println("GID variable is not set. Not updating GID") + return nil + } + + err := exec.Command("groupmod", "-g", newGID, config.Group).Run() + if err != nil { + return err + } + + return nil +} + func main() { configPath := flag.String("config", "config.json", "Path to config file") force := flag.Bool("force", false, "Forcibly overwrite existing files (equivalent to setting forceOverwrite to true in the config)") flag.Parse() + if flag.NArg() == 0 { + log.Fatal("Missing command") + } + config, err := loadConfig(*configPath) if err != nil { log.Fatalln("Failed to load config:", err) @@ -137,4 +193,31 @@ func main() { if err != nil { log.Fatalln(err) } + + if config.UpdateUID { + log.Println("Updating UID") + err = updateUID(*config) + if err != nil { + log.Fatalln(err) + } + } + + if config.UpdateGID { + log.Println("Updating GID") + err = updateGID(*config) + if err != nil { + log.Fatalln(err) + } + } + + command := flag.Args() + log.Println(">", strings.Join(command, " ")) + cmd := exec.Command(command[0], command[1:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + err = cmd.Run() + if err != nil { + log.Fatal("Error: ", err) + } }