Move avoidable daemon shell-outs into Go
Reduce the control plane's dependency on helper scripts while keeping the hard Linux integration points in the approved shell-out layer. Replace the bash-driven image build path with a native Go builder that clones and optionally resizes the rootfs, boots a temporary Firecracker VM, provisions the guest over SSH, installs packages and modules, and preserves the package-manifest sidecar. Also replace a few small convenience shell-outs with Go helpers: read process stats from /proc, use os.Truncate for ext4 image growth, add file-clone and normalized-line helpers, drop the sh -c work-disk flattening path, and launch Firecracker via a direct sudo command. Add tests for the new SSH/archive and system helpers, plus a policy test that keeps os/exec imports confined to cli/firecracker/system. Update the docs to describe customize.sh as a manual helper rather than the daemon's image-build backend. Validated with go mod tidy, go test ./..., and make build.
This commit is contained in:
parent
0a0b0b617b
commit
942d242c03
17 changed files with 936 additions and 145 deletions
74
internal/system/files.go
Normal file
74
internal/system/files.go
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func CopyFilePreferClone(sourcePath, targetPath string) error {
|
||||
source, err := os.Open(sourcePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer source.Close()
|
||||
|
||||
info, err := source.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
target, err := os.OpenFile(targetPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, info.Mode().Perm())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer target.Close()
|
||||
|
||||
if err := unix.IoctlFileClone(int(target.Fd()), int(source.Fd())); err == nil {
|
||||
return nil
|
||||
}
|
||||
if _, err := source.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := target.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(target, source); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := target.Sync(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := target.Chmod(info.Mode().Perm()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ReadNormalizedLines(path string) ([]string, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var out []string
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
if strings.HasSuffix(line, "\r") {
|
||||
line = strings.TrimSuffix(line, "\r")
|
||||
}
|
||||
if idx := strings.Index(line, "#"); idx >= 0 {
|
||||
line = line[:idx]
|
||||
}
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
out = append(out, line)
|
||||
}
|
||||
if len(out) == 0 {
|
||||
return nil, fmt.Errorf("file has no entries: %s", path)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue