Compare commits

..

No commits in common. "07d276b2a3b969fd84165cfb5fd2678110ebd996" and "b4310c09a86aa1564e786cdb647c3298cdb15fc8" have entirely different histories.

12 changed files with 54 additions and 93 deletions

26
cli.go
View file

@ -1,26 +0,0 @@
package main
import (
"encoding/json"
"log"
"os"
"gitea.nulo.in/Nulo/repro-run/runner"
)
func main() {
config, err := readConfig()
must(err)
must(runner.Run(config, "rootfs/", "cache/"))
}
func must(err error, where ...string) {
if err != nil {
log.Fatal(err, where)
}
}
func readConfig() (config runner.Config, err error) {
err = json.NewDecoder(os.Stdin).Decode(&config)
return
}

16
config.go Normal file
View file

@ -0,0 +1,16 @@
package main
import (
"encoding/json"
"os"
)
type Config struct {
Command string
Cache []string
}
func readConfig() (config Config, err error) {
err = json.NewDecoder(os.Stdin).Decode(&config)
return
}

View file

@ -1,8 +1,7 @@
package runner package main
import ( import (
"embed" "embed"
"fmt"
"io" "io"
"log" "log"
"os" "os"
@ -14,71 +13,53 @@ import (
//go:embed alpine/keys //go:embed alpine/keys
var alpineKeys embed.FS var alpineKeys embed.FS
func Run(config Config, rootfs string, cache string) (err error) { func main() {
if err = os.RemoveAll("rootfs/"); err != nil { config, err := readConfig()
return must(err)
}
if err = os.MkdirAll("rootfs/etc/apk/keys", 0700); err != nil { must(os.RemoveAll("rootfs/"))
return
} must(os.MkdirAll("rootfs/etc/apk/keys", 0700))
if err = os.WriteFile("rootfs/etc/apk/repositories", []byte( must(os.WriteFile("rootfs/etc/apk/repositories", []byte(
`https://dl-cdn.alpinelinux.org/alpine/v3.17/main `https://dl-cdn.alpinelinux.org/alpine/v3.17/main
https://dl-cdn.alpinelinux.org/alpine/v3.17/community`), 0600); err != nil { https://dl-cdn.alpinelinux.org/alpine/v3.17/community`), 0600))
return must(os.WriteFile("rootfs/etc/resolv.conf", []byte(
} `nameserver 8.8.8.8`), 0644))
if err = os.WriteFile("rootfs/etc/resolv.conf", []byte(`nameserver 8.8.8.8`), 0644); err != nil {
return
}
keys, err := alpineKeys.ReadDir("alpine/keys") keys, err := alpineKeys.ReadDir("alpine/keys")
if err != nil { must(err)
return
}
for _, entry := range keys { for _, entry := range keys {
o, err := os.Create(path.Join("rootfs/etc/apk/keys/", entry.Name())) o, err := os.Create(path.Join("rootfs/etc/apk/keys/", entry.Name()))
if err != nil { must(err)
return err
}
s, err := alpineKeys.Open(path.Join("alpine/keys", entry.Name())) s, err := alpineKeys.Open(path.Join("alpine/keys", entry.Name()))
if err != nil { must(err)
return err _, err = io.Copy(o, s)
} must(err)
if _, err = io.Copy(o, s); err != nil {
return err
}
} }
if err = os.MkdirAll("cache/_var_cache_apk", 0700); err != nil { must(os.MkdirAll("cache/_var_cache_apk", 0700))
return
}
os.Remove("rootfs/etc/apk/cache") os.Remove("rootfs/etc/apk/cache")
if err = os.Symlink("/var/cache/apk", "rootfs/etc/apk/cache"); err != nil { must(os.Symlink("/var/cache/apk", "rootfs/etc/apk/cache"))
return // must(os.MkdirAll("rootfs/var/cache", 0700))
} // must(os.RemoveAll("rootfs/var/cache/apk"))
// must(os.Symlink("../../../cache/apk", "rootfs/var/cache/apk"))
cmd := exec.Command("apk", "add", cmd := exec.Command("apk", "add",
"--root", "rootfs", "--root", "rootfs",
"--initdb", "--initdb",
"--cache-dir", "../cache/_var_cache_apk", "--cache-dir", "../cache/_var_cache_apk",
"apk-tools") "apk-tools")
if err = cmd.Run(); err != nil { must(cmd.Run(), "apk add apk-tools")
return fmt.Errorf("apk add apk-tools: %w", err) // must(os.Remove("rootfs/var/cache/apk"))
}
cached := append(config.Cache, "/var/cache/apk") cached := append(config.Cache, "/var/cache/apk")
var cachedParams []string var cachedParams []string
for _, c := range cached { for _, c := range cached {
cacheDir := path.Join("./cache", strings.ReplaceAll(c, "/", "_")) cacheDir := path.Join("./cache", strings.ReplaceAll(c, "/", "_"))
if err = os.MkdirAll(cacheDir, 0700); err != nil { must(os.MkdirAll(cacheDir, 0700))
return
}
cachedParams = append(cachedParams, "--bind", cacheDir, c) cachedParams = append(cachedParams, "--bind", cacheDir, c)
} }
tmp, err := os.MkdirTemp("", "repro-run-") tmp, err := os.MkdirTemp("", "repro-run-")
if err != nil { must(err)
return
}
defer os.RemoveAll(tmp) defer os.RemoveAll(tmp)
log.Println("/work = " + tmp) log.Println("/work = " + tmp)
@ -97,23 +78,24 @@ https://dl-cdn.alpinelinux.org/alpine/v3.17/community`), 0600); err != nil {
cmd = exec.Command("bwrap", append(params, cmd = exec.Command("bwrap", append(params,
"apk", "add", "busybox", "busybox-suid", "libc-utils", "alpine-baselayout", "alpine-conf", "alpine-release")...) "apk", "add", "busybox", "busybox-suid", "libc-utils", "alpine-baselayout", "alpine-conf", "alpine-release")...)
if err = cmd.Run(); err != nil { // cmd.Stdout = os.Stdout
return fmt.Errorf("bwrap apk add: %w", err) // cmd.Stderr = os.Stderr
} must(cmd.Run(), "bwrap apk add")
cmd = exec.Command("bwrap", append(params, cmd = exec.Command("bwrap", append(params,
"--uid", "0", "--uid", "0",
"adduser", "-u", "1000", "-D", "repro")...) "adduser", "-u", "1000", "-D", "repro")...)
if err = cmd.Run(); err != nil { must(cmd.Run(), "bwrap adduser repro")
return fmt.Errorf("bwrap adduser repro: %w", err)
}
cmd = exec.Command("bwrap", append(params, strings.Split(config.Command, " ")...)...) cmd = exec.Command("bwrap", append(params, strings.Split(config.Command, " ")...)...)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
if err = cmd.Run(); err != nil { must(cmd.Run())
return fmt.Errorf("running Command: %w", err)
}
return }
func must(err error, where ...string) {
if err != nil {
log.Fatal(err, where)
}
} }

View file

@ -17,7 +17,8 @@ file repro-run
``` ```
```sh ```sh
echo '{"Command": "/src/test", "Cache": ["/home/repro/.cache/go-build"]}' | go run . echo '{"Command": "/src/test", "Cache": ["/home/repro/.cache/go-build"]}
' | go run .
``` ```
genera genera

View file

@ -1,5 +0,0 @@
#!/bin/sh -xe
apk add --quiet git go
git clone --quiet file:///src repo
cd repo
go build .

View file

@ -1 +0,0 @@
{ "Command": "/src/repro-build", "Cache": ["/home/repro/.cache/go-build"] }

View file

@ -1,6 +0,0 @@
package runner
type Config struct {
Command string
Cache []string
}