// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. package extensions import ( "fmt" "io" "io/fs" "os" "os/exec" "path/filepath" "github.com/siderolabs/talos/pkg/machinery/constants" ) // List of paths to be moved to the future initramfs. var initramfsPaths = []string{ constants.FirmwarePath, } // Compress builds the squashfs image in the specified destination folder. // // Components which should be placed to the initramfs are moved to the initramfsPath. func (ext *Extension) Compress(squashPath, initramfsPath string) (string, error) { for _, path := range initramfsPaths { if _, err := os.Stat(filepath.Join(ext.rootfsPath, path)); err == nil { if err = moveFiles(filepath.Join(ext.rootfsPath, path), filepath.Join(initramfsPath, path)); err != nil { return "", err } } } squashPath = filepath.Join(squashPath, fmt.Sprintf("%s.sqsh", ext.directory)) cmd := exec.Command("mksquashfs", ext.rootfsPath, squashPath, "-all-root", "-noappend", "-comp", "xz", "-Xdict-size", "100%", "-no-progress") cmd.Stderr = os.Stderr return squashPath, cmd.Run() } func moveFiles(srcPath, dstPath string) error { st, err := os.Stat(srcPath) if err != nil { return err } if st.IsDir() { return moveDirectory(st, srcPath, dstPath) } return moveFile(st, srcPath, dstPath) } func moveFile(st fs.FileInfo, srcPath, dstPath string) error { src, err := os.Open(srcPath) if err != nil { return err } defer src.Close() //nolint:errcheck dst, err := os.OpenFile(dstPath, os.O_CREATE|os.O_WRONLY, st.Mode().Perm()) if err != nil { return err } defer dst.Close() //nolint:errcheck _, err = io.Copy(dst, src) if err != nil { return err } return os.Remove(srcPath) } func moveDirectory(st fs.FileInfo, srcPath, dstPath string) error { if err := os.MkdirAll(dstPath, st.Mode().Perm()); err != nil { return err } contents, err := os.ReadDir(srcPath) if err != nil { return err } for _, item := range contents { if err = moveFiles(filepath.Join(srcPath, item.Name()), filepath.Join(dstPath, item.Name())); err != nil { return err } } return os.Remove(srcPath) }