dist & cache cleaning + preseeding
This commit is contained in:
@@ -132,15 +132,19 @@ func buildInitrd(out io.Writer, ctx *renderContext) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func getSigner(clusterName string) (signer crypto.Signer, err error) {
|
||||
ca, err := getUsableClusterCA(clusterName, "boot-signer")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return ca.ParseKey()
|
||||
}
|
||||
|
||||
func buildBootstrap(out io.Writer, ctx *renderContext) (err error) {
|
||||
arch := tar.NewWriter(out)
|
||||
defer arch.Close()
|
||||
|
||||
ca, err := getUsableClusterCA(ctx.Host.ClusterName, "boot-signer")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
signer, err := ca.ParseKey()
|
||||
signer, err := getSigner(ctx.Host.ClusterName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -245,7 +249,7 @@ func buildBootstrap(out io.Writer, ctx *renderContext) (err error) {
|
||||
}
|
||||
|
||||
if allErofs {
|
||||
layerPath, e := layersCombo(ctx, cfg, signer)
|
||||
layerPath, e := layersCombo(ctx.Host, cfg, signer)
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
@@ -275,15 +279,38 @@ func buildBootstrap(out io.Writer, ctx *renderContext) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func layersCombo(ctx *renderContext, cfg *config.Config, signer crypto.Signer) (path string, err error) {
|
||||
key := layersComboKey(ctx.Host, cfg)
|
||||
|
||||
func layersCombo(host *localconfig.Host, cfg *config.Config, signer crypto.Signer) (path string, err error) {
|
||||
key := layersComboKey(host, cfg)
|
||||
return opMutex(key, func() (path string, err error) {
|
||||
return buildLayersCombo(host, cfg, signer)
|
||||
})
|
||||
}
|
||||
|
||||
func layersComboKey(host *localconfig.Host, cfg *config.Config) string {
|
||||
key := new(strings.Builder)
|
||||
key.WriteString("layers")
|
||||
for _, layer := range cfg.Layers {
|
||||
if layer == "modules" {
|
||||
continue
|
||||
}
|
||||
key.WriteByte(':')
|
||||
key.WriteString(layer)
|
||||
if v, ok := host.Versions[layer]; ok {
|
||||
key.WriteByte('@')
|
||||
key.WriteString(v)
|
||||
}
|
||||
}
|
||||
|
||||
return key.String()
|
||||
}
|
||||
|
||||
func buildLayersCombo(host *localconfig.Host, cfg *config.Config, signer crypto.Signer) (path string, err error) {
|
||||
path = filepath.Join(*dataDir, "cache")
|
||||
if err = os.MkdirAll(path, 0o700); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
key := layersComboKey(host, cfg)
|
||||
path = filepath.Join(path, key) + ".fs"
|
||||
|
||||
if _, statErr := os.Stat(path); statErr == nil {
|
||||
@@ -322,7 +349,7 @@ func layersCombo(ctx *renderContext, cfg *config.Config, signer crypto.Signer) (
|
||||
continue // modules are in the initrd with boot v2
|
||||
}
|
||||
|
||||
layerFile, e := fetchHostLayer(ctx.Host, layer)
|
||||
layerFile, e := fetchHostLayer(host, layer)
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
@@ -453,25 +480,6 @@ func layersCombo(ctx *renderContext, cfg *config.Config, signer crypto.Signer) (
|
||||
|
||||
err = os.Rename(outPath, path)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func layersComboKey(host *localconfig.Host, cfg *config.Config) string {
|
||||
key := new(strings.Builder)
|
||||
key.WriteString("layers")
|
||||
for _, layer := range cfg.Layers {
|
||||
if layer == "modules" {
|
||||
continue
|
||||
}
|
||||
key.WriteByte(':')
|
||||
key.WriteString(layer)
|
||||
if v, ok := host.Versions[layer]; ok {
|
||||
key.WriteByte('@')
|
||||
key.WriteString(v)
|
||||
}
|
||||
}
|
||||
|
||||
return key.String()
|
||||
}
|
||||
|
||||
func fetchHostLayer(host *localconfig.Host, layer string) (path string, err error) {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func updateCache() {
|
||||
log.Print("updating cache")
|
||||
|
||||
cfg, err := readConfig()
|
||||
if err != nil {
|
||||
log.Printf("update cache failed: read config failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
errs := 0
|
||||
inUse := map[string]bool{}
|
||||
|
||||
fetch := func(path ...string) {
|
||||
assetPath, err := distFetch(path...)
|
||||
if err != nil {
|
||||
log.Printf("update cache: dist fetch failed: %v", err)
|
||||
errs += 1
|
||||
}
|
||||
inUse[assetPath] = true
|
||||
}
|
||||
|
||||
fetch("grub-support", *grubSupportVersion)
|
||||
|
||||
for _, host := range cfg.Hosts {
|
||||
ctx, err := newRenderContext(host, cfg)
|
||||
if err != nil {
|
||||
log.Printf("update cache: %s: build context failed: %v", host.Name, err)
|
||||
errs += 1
|
||||
continue
|
||||
}
|
||||
|
||||
_, cfg, err := ctx.Config()
|
||||
if err != nil {
|
||||
log.Printf("update cache: %s: render config failed: %v", host.Name, err)
|
||||
errs += 1
|
||||
continue
|
||||
}
|
||||
|
||||
signer, err := getSigner(host.ClusterName)
|
||||
if err != nil {
|
||||
log.Printf("update cache: %s: get signer failed: %v", host.Name, err)
|
||||
errs += 1
|
||||
continue
|
||||
}
|
||||
|
||||
fetch("kernels", host.Kernel)
|
||||
fetch("layers", "modules", host.Kernel)
|
||||
fetch("initrd", host.Initrd)
|
||||
|
||||
allErofs := true
|
||||
for layer, version := range host.Versions {
|
||||
fetch("layers", layer, version)
|
||||
|
||||
if layer != "modules" && !strings.HasSuffix(version, ".erofs") {
|
||||
allErofs = false
|
||||
}
|
||||
}
|
||||
|
||||
if allErofs {
|
||||
path, err := layersCombo(host, cfg, signer)
|
||||
if err != nil {
|
||||
log.Printf("update cache: layer combo failed: %v", err)
|
||||
continue
|
||||
}
|
||||
inUse[path] = true
|
||||
}
|
||||
}
|
||||
|
||||
if errs != 0 {
|
||||
log.Printf("update cache: %d errors, not cleaning", errs)
|
||||
return
|
||||
}
|
||||
|
||||
distDir := filepath.Join(*dataDir, "dist")
|
||||
cacheDir := filepath.Join(*dataDir, "cache")
|
||||
|
||||
existing := []string{}
|
||||
|
||||
for _, dir := range []string{distDir, cacheDir} {
|
||||
fs.WalkDir(os.DirFS(dir), ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
log.Printf("update cache: walking %s failed: %v", dir, err)
|
||||
return nil
|
||||
}
|
||||
if !d.IsDir() {
|
||||
existing = append(existing, filepath.Join(dir, path))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
log.Printf("update cache: %d/%d assets in use", len(inUse), len(existing))
|
||||
|
||||
for _, path := range existing {
|
||||
if inUse[path] {
|
||||
continue
|
||||
}
|
||||
log.Print("update cache: removing ", path)
|
||||
if err := os.Remove(path); err != nil {
|
||||
log.Print("update cache: failed to remove: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func hash(values ...interface{}) string {
|
||||
func hash(values ...any) string {
|
||||
ba, err := json.Marshal(values)
|
||||
if err != nil {
|
||||
panic(err) // should not happen
|
||||
|
||||
@@ -137,7 +137,9 @@ func unlockSecretStore(name string, passphrase []byte) (err httperr.Error) {
|
||||
})
|
||||
|
||||
go updateState()
|
||||
go migrateSecrets()
|
||||
|
||||
migrateSecrets() // we can probably remove it now
|
||||
go updateCache()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ func writeNewConfig(cfgBytes []byte) (err error) {
|
||||
err = os.Rename(out.Name(), cfgPath)
|
||||
|
||||
updateState()
|
||||
go updateCache()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ func wsError(resp *restful.Response, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func wsRender(resp *restful.Response, sslCfg *cfsslconfig.Config, tmplStr string, value interface{}) {
|
||||
func wsRender(resp *restful.Response, sslCfg *cfsslconfig.Config, tmplStr string, value any) {
|
||||
tmpl, err := template.New("wsRender").Funcs(templateFuncs(sslCfg)).Parse(tmplStr)
|
||||
if err != nil {
|
||||
wsError(resp, err)
|
||||
|
||||
Reference in New Issue
Block a user