Alpine will automatically add/remove packages based on the contents of /etc/apk/world. Start leveraging this. Bug: the two package arrays were not being merged, but rather overwritten.

This commit is contained in:
root 2025-03-17 21:02:50 -04:00
parent c502b0d5e0
commit e5eff8ede0
4 changed files with 49 additions and 31 deletions

View file

@ -121,7 +121,7 @@ func GetValue(i interface{}, path string) (interface{}, error) {
v := reflect.ValueOf(i) v := reflect.ValueOf(i)
if v.IsValid() == false { return nil, ErrKey } if v.IsValid() == false { return nil, ErrKey }
i = v.MapIndex(reflect.ValueOf(p)).Interface() i = v.MapIndex(reflect.ValueOf(p)).Interface()
case reflect.Array: case reflect.Array, reflect.Slice:
return i, nil return i, nil
case reflect.String: case reflect.String:
return i, nil return i, nil

View file

@ -4,7 +4,7 @@
"base": "alpine", "base": "alpine",
"packages": [ "packages": [
"tmux", "vim", "ripgrep", "tmux", "vim", "ripgrep",
"go" "go", "tailscale",
] ]
}, },

54
main.go
View file

@ -5,6 +5,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"slices"
"strings" "strings"
"text/template" "text/template"
@ -21,6 +22,7 @@ type Config struct {
type SystemConfig struct { type SystemConfig struct {
Base string Base string
Packages []string Packages []string
SystemPackages []string `json:"system_packages"`
} }
type NetworkingConfig struct { type NetworkingConfig struct {
@ -100,8 +102,9 @@ func main() {
// Scripted actions for the service // Scripted actions for the service
// Add service packages to the global list // Add service packages to the global list
pkgs := &config.System.Packages config.System.Packages = append(
*pkgs = append(*pkgs, s.Packages...) config.System.Packages,
s.Packages...)
// If a proxy definition exists, append it // If a proxy definition exists, append it
if s.Proxy != "" { if s.Proxy != "" {
@ -199,37 +202,48 @@ func main() {
} }
// Parse package list // Parse package list
{
var err error
// Add extra packages needed err = os.MkdirAll("/config" + "/etc/apk/", 0555)
// ...
// Install packages
fmt.Println("Installing packages")
var installString = []string{"add", "--no-interactive", "--no-progress"}
var testArgs, args []string
var out []byte
testArgs = append(installString, "-s")
testArgs = append(testArgs, config.System.Packages...)
out, err = exec.Command("/sbin/apk", testArgs...).CombinedOutput()
if err != nil { if err != nil {
fmt.Println("===") fmt.Println("Error creating config directory.")
fmt.Println(err) fmt.Println(err)
fmt.Println(string(out))
fmt.Println("===")
fmt.Println("Error preparing packages")
return return
} }
args = append(installString, config.System.Packages...) slices.Sort(config.System.Packages)
out, err = exec.Command("/sbin/apk", args...).CombinedOutput() slices.Sort(config.System.SystemPackages)
config.System.Packages = append(
config.System.SystemPackages,
config.System.Packages...)
config.System.Packages = slices.Compact(
config.System.Packages)
p := strings.Join(config.System.Packages, "\n")
err = os.WriteFile("/config/etc/apk/world",[]byte(p), 0444)
if err != nil {
fmt.Println("Error creating package list")
fmt.Println(err)
return
}
}
// Install and remove packages
{
fmt.Println("Installing packages")
args := []string{"add", "-s", "-u", "-l"}
out, err := exec.Command("/sbin/apk", args...).CombinedOutput()
if err != nil { if err != nil {
fmt.Println("===") fmt.Println("===")
fmt.Println(err) fmt.Println(err)
fmt.Println(string(out)) fmt.Println(string(out))
fmt.Println("===") fmt.Println("===")
fmt.Println("Error installing packages") fmt.Println("Error updating packages")
return return
} }
}
// (Re)start services // (Re)start services

View file

@ -2,7 +2,11 @@
system: { system: {
base: "alpine", base: "alpine",
packages: [], system_packages: [
"alpine-base", "doas", "linux-lts", "syslinux",
"ifupdown-ng", "util-linux", "mount",
"podman", "podman-compose",
],
} }
services: { services: {