From c767f269375cc98422ba23516a987a4ba5c4a5ce Mon Sep 17 00:00:00 2001 From: EnumDev Date: Thu, 10 Apr 2025 14:59:41 +0300 Subject: [PATCH] Remove direct source compilation (To be reworked) --- src/bpm/main.go | 11 - src/bpmlib/config.go | 15 +- src/bpmlib/operations.go | 4 +- src/bpmlib/packages.go | 471 +-------------------------------------- 4 files changed, 7 insertions(+), 494 deletions(-) diff --git a/src/bpm/main.go b/src/bpm/main.go index 702e950..45349f3 100644 --- a/src/bpm/main.go +++ b/src/bpm/main.go @@ -27,9 +27,6 @@ var subcommandArgs []string var rootDir = "/" var verbose = false var yesAll = false -var buildSource = false -var skipCheck = false -var keepTempDir = false var force = false var pkgListNumbers = false var pkgListNames = false @@ -524,9 +521,6 @@ func printHelp() { fmt.Println(" -v Show additional information about what BPM is doing") fmt.Println(" -y skips the confirmation prompt") fmt.Println(" -f skips dependency, conflict and architecture checking") - fmt.Println(" -o= set the binary package output directory (defaults to /var/lib/bpm/compiled)") - fmt.Println(" -c= set the compilation directory (defaults to /var/tmp)") - fmt.Println(" -b creates a binary package from a source package after compilation and saves it in the binary package output directory") fmt.Println(" -k keeps the compilation directory created by BPM after source package installation") fmt.Println(" --reinstall Reinstalls packages even if they do not have a newer version available") fmt.Println(" --reinstall-all Same as --reinstall but also reinstalls dependencies") @@ -575,11 +569,6 @@ func resolveFlags() { installFlagSet.StringVar(&rootDir, "R", "/", "Set the destination root") installFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing") installFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts") - installFlagSet.StringVar(&bpmlib.BPMConfig.BinaryOutputDir, "o", bpmlib.BPMConfig.BinaryOutputDir, "Set the binary output directory") - installFlagSet.StringVar(&bpmlib.BPMConfig.CompilationDir, "c", bpmlib.BPMConfig.CompilationDir, "Set the compilation directory") - installFlagSet.BoolVar(&buildSource, "b", false, "Build binary package from source package") - installFlagSet.BoolVar(&skipCheck, "s", false, "Skip check function during source compilation") - installFlagSet.BoolVar(&keepTempDir, "k", false, "Keep temporary directory after source compilation") installFlagSet.BoolVar(&force, "f", false, "Force installation by skipping architecture and dependency resolution") installFlagSet.BoolVar(&reinstall, "reinstall", false, "Reinstalls packages even if they do not have a newer version available") installFlagSet.BoolVar(&reinstallAll, "reinstall-all", false, "Same as --reinstall but also reinstalls dependencies") diff --git a/src/bpmlib/config.go b/src/bpmlib/config.go index 8c3e50a..fdbf246 100644 --- a/src/bpmlib/config.go +++ b/src/bpmlib/config.go @@ -6,12 +6,8 @@ import ( ) type BPMConfigStruct struct { - CompilationEnv []string `yaml:"compilation_env"` - SilentCompilation bool `yaml:"silent_compilation"` - BinaryOutputDir string `yaml:"binary_output_dir"` - CompilationDir string `yaml:"compilation_dir"` - IgnorePackages []string `yaml:"ignore_packages"` - Repositories []*Repository `yaml:"repositories"` + IgnorePackages []string `yaml:"ignore_packages"` + Repositories []*Repository `yaml:"repositories"` } var BPMConfig BPMConfigStruct @@ -26,12 +22,7 @@ func ReadConfig() (err error) { return err } - BPMConfig = BPMConfigStruct{ - CompilationEnv: make([]string, 0), - SilentCompilation: false, - BinaryOutputDir: "/var/lib/bpm/compiled/", - CompilationDir: "/var/tmp/", - } + BPMConfig = BPMConfigStruct{} err = yaml.Unmarshal(bytes, &BPMConfig) if err != nil { return err diff --git a/src/bpmlib/operations.go b/src/bpmlib/operations.go index a23acae..cb56419 100644 --- a/src/bpmlib/operations.go +++ b/src/bpmlib/operations.go @@ -465,9 +465,9 @@ func (operation *BPMOperation) Execute(verbose, force bool) error { isReinstall := IsPackageInstalled(bpmpkg.PkgInfo.Name, operation.RootDir) var err error if value.IsDependency { - err = installPackage(value.File, operation.RootDir, verbose, true, false, false, false) + err = installPackage(value.File, operation.RootDir, verbose, true) } else { - err = installPackage(value.File, operation.RootDir, verbose, force, false, false, false) + err = installPackage(value.File, operation.RootDir, verbose, force) } if err != nil { return errors.New(fmt.Sprintf("could not install package (%s): %s\n", bpmpkg.PkgInfo.Name, err)) diff --git a/src/bpmlib/packages.go b/src/bpmlib/packages.go index dbc137c..91ebf5a 100644 --- a/src/bpmlib/packages.go +++ b/src/bpmlib/packages.go @@ -8,16 +8,13 @@ import ( version "github.com/knqyf263/go-rpm-version" "gopkg.in/yaml.v3" "io" - "io/fs" "os" "os/exec" "path" - "path/filepath" "slices" "sort" "strconv" "strings" - "syscall" ) type BPMPackage struct { @@ -309,11 +306,6 @@ func executePackageScripts(filename, rootDir string, operation packageOperation, } cmd := exec.Command("/bin/bash", temp.Name()) - if !BPMConfig.SilentCompilation { - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } cmd.Dir = rootDir cmd.Env = os.Environ() cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_ROOT=%s", rootDir)) @@ -433,14 +425,6 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) { return &pkgInfo, nil } -func CreateInfoFile(pkgInfo *PackageInfo) string { - b, err := yaml.Marshal(&pkgInfo) - if err != nil { - return "" - } - return string(b) -} - func CreateReadableInfo(showArchitecture, showType, showPackageRelations bool, pkgInfo *PackageInfo, rootDir string) string { ret := make([]string, 0) appendArray := func(label string, array []string) { @@ -611,447 +595,7 @@ func extractPackage(bpmpkg *BPMPackage, verbose bool, filename, rootDir string) return nil } -func isSplitPackage(filename string) bool { - pkgInfo, err := ReadPackage(filename) - if err != nil { - return false - } - if pkgInfo.PkgInfo.Type != "source" { - return false - } - cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("test $(tar -tf %s | grep '^pkg.info' | wc -l) -eq 1", filename)) - if err := cmd.Run(); err == nil { - return false - } - return true -} - -func compilePackage(bpmpkg *BPMPackage, filename, rootDir string, verbose, binaryPkgFromSrc, skipCheck, keepTempDir bool) (error, []string) { - var files []string - if !IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) { - err := executePackageScripts(filename, rootDir, packageOperationInstall, false) - if err != nil { - return err, nil - } - } else { - err := executePackageScripts(filename, rootDir, packageOperationUpdate, false) - if err != nil { - return err, nil - } - } - //seenHardlinks := make(map[string]string) - file, err := os.Open(filename) - if err != nil { - return err, nil - } - - tr := tar.NewReader(file) - - temp := path.Join(BPMConfig.CompilationDir, "bpm_source-"+bpmpkg.PkgInfo.Name) - err = os.RemoveAll(temp) - if err != nil { - return err, nil - } - if verbose { - fmt.Println("Creating temp directory at: " + temp) - } - err = os.Mkdir(temp, 0755) - if err != nil { - return err, nil - } - err = os.Chown(temp, 65534, 65534) - if err != nil { - return err, nil - } - - for { - header, err := tr.Next() - if err == io.EOF { - break - } - if err != nil { - return err, nil - } - if strings.HasPrefix(header.Name, "source-files/") && header.Name != "source-files/" { - extractFilename := path.Join(temp, strings.TrimPrefix(header.Name, "source-files/")) - switch header.Typeflag { - case tar.TypeDir: - if err := os.Mkdir(extractFilename, 0755); err != nil { - if !os.IsExist(err) { - return err, nil - } - } else { - if verbose { - fmt.Println("Creating Directory: " + extractFilename) - } - err = os.Chown(extractFilename, 65534, 65534) - if err != nil { - return err, nil - } - } - case tar.TypeReg: - err := os.Remove(extractFilename) - if err != nil && !os.IsNotExist(err) { - return err, nil - } - outFile, err := os.Create(extractFilename) - if verbose { - fmt.Println("Creating File: " + extractFilename) - } - if err != nil { - return err, nil - } - err = os.Chown(extractFilename, 65534, 65534) - if err != nil { - return err, nil - } - if _, err := io.Copy(outFile, tr); err != nil { - return err, nil - } - if err := os.Chmod(extractFilename, header.FileInfo().Mode()); err != nil { - return err, nil - } - err = outFile.Close() - if err != nil { - return err, nil - } - case tar.TypeSymlink: - if verbose { - fmt.Println("Skipping symlink (Bundling symlinks in source packages is not supported)") - } - case tar.TypeLink: - if verbose { - fmt.Println("Skipping hard link (Bundling hard links in source packages is not supported)") - } - default: - return errors.New("unknown type (" + strconv.Itoa(int(header.Typeflag)) + ") in " + extractFilename), nil - } - } - if header.Name == "source.sh" { - bs, err := io.ReadAll(tr) - if err != nil { - return err, nil - } - err = os.WriteFile(path.Join(temp, "source.sh"), bs, 0644) - if err != nil { - return err, nil - } - err = os.Chown(path.Join(temp, "source.sh"), 65534, 65534) - if err != nil { - return err, nil - } - } - } - if _, err := os.Stat(path.Join(temp, "source.sh")); os.IsNotExist(err) { - return errors.New("source.sh file could not be found in the temporary build directory"), nil - } - fmt.Println("Running source.sh file...") - if !IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) { - err = executePackageScripts(filename, rootDir, packageOperationInstall, false) - if err != nil { - return err, nil - } - } else { - err = executePackageScripts(filename, rootDir, packageOperationUpdate, false) - if err != nil { - return err, nil - } - } - bs, err := os.ReadFile(path.Join(temp, "source.sh")) - if err != nil { - return err, nil - } - - if !strings.Contains(string(bs), "package()") { - fmt.Print("This package does not seem to have the required 'package' function\nThe source.sh file may have been created for an older BPM version\nPlease update the source.sh file") - return errors.New("invalid source.sh format"), nil - } - - runScript := ` -cd "$BPM_WORKDIR" - -set -a -source "source.sh" -set +a - -if [[ $(type -t prepare) == function ]]; then - echo "Running prepare() function..." - bash -e -c prepare - if [ $? -ne 0 ]; then - echo "Failed to run prepare() function in source.sh" - exit 1 - fi -fi - -cd "$BPM_SOURCE" -if [[ $(type -t build) == function ]]; then - echo "Running build() function..." - bash -e -c build - if [ $? -ne 0 ]; then - echo "Failed to run build() function in source.sh" - exit 1 - fi -fi - -cd "$BPM_SOURCE" -if [[ $(type -t check) == function ]] && [ -z "$SKIPCHECK" ]; then - echo "Running check() function..." - bash -e -c check - if [ $? -ne 0 ]; then - echo "Failed to run check() function in source.sh" - exit 1 - fi -fi - - -cd "$BPM_SOURCE" -if ! [[ $(type -t package) == function ]]; then - echo "Failed to locate package() function in source.sh" - exit 1 -fi -echo "Running package() function..." -touch "$BPM_WORKDIR"/fakeroot_file -fakeroot -s "$BPM_WORKDIR"/fakeroot_file bash -e -c package -bash -e -c package -if [ $? -ne 0 ]; then - echo "Failed to run package() function in source.sh" -fi -` - err = os.WriteFile(path.Join(temp, "run.sh"), []byte(runScript), 0644) - if err != nil { - return err, nil - } - err = os.Chown(path.Join(temp, "run.sh"), 65534, 65534) - if err != nil { - return err, nil - } - - cmd := exec.Command("/bin/bash", "-e", "run.sh") - cmd.SysProcAttr = &syscall.SysProcAttr{} - cmd.SysProcAttr.Credential = &syscall.Credential{Uid: 65534, Gid: 65534} - cmd.Dir = temp - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "USER=nobody") - cmd.Env = append(cmd.Env, "HOME="+temp) - - err = os.Mkdir(path.Join(temp, "source"), 0755) - if err != nil { - return err, nil - } - err = os.Chown(path.Join(temp, "source"), 65534, 65534) - if err != nil { - return err, nil - } - err = os.Mkdir(path.Join(temp, "output"), 0755) - if err != nil { - return err, nil - } - err = os.Chown(path.Join(temp, "output"), 65534, 65534) - if err != nil { - return err, nil - } - cmd.Env = append(cmd.Env, "BPM_WORKDIR="+temp) - cmd.Env = append(cmd.Env, "BPM_SOURCE="+path.Join(temp, "source")) - cmd.Env = append(cmd.Env, "BPM_OUTPUT="+path.Join(temp, "output")) - cmd.Env = append(cmd.Env, "SKIPCHECK="+strconv.FormatBool(skipCheck)) - - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_ROOT=%s", rootDir)) - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_NAME=%s", bpmpkg.PkgInfo.Name)) - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_DESC=%s", bpmpkg.PkgInfo.Description)) - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_VERSION=%s", bpmpkg.PkgInfo.Version)) - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_REVISION=%d", bpmpkg.PkgInfo.Revision)) - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_URL=%s", bpmpkg.PkgInfo.Url)) - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_ARCH=%s", bpmpkg.PkgInfo.Arch)) - depends := make([]string, len(bpmpkg.PkgInfo.Depends)) - copy(depends, bpmpkg.PkgInfo.Depends) - for i := 0; i < len(depends); i++ { - depends[i] = fmt.Sprintf("\"%s\"", depends[i]) - } - makeDepends := make([]string, len(bpmpkg.PkgInfo.MakeDepends)) - copy(makeDepends, bpmpkg.PkgInfo.MakeDepends) - for i := 0; i < len(makeDepends); i++ { - makeDepends[i] = fmt.Sprintf("\"%s\"", makeDepends[i]) - } - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_DEPENDS=(%s)", strings.Join(depends, " "))) - cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_MAKE_DEPENDS=(%s)", strings.Join(makeDepends, " "))) - for _, value := range BPMConfig.CompilationEnv { - cmd.Env = append(cmd.Env, value) - } - cmd.Env = append(cmd.Env, "BPM_PKG_TYPE=source") - - if !BPMConfig.SilentCompilation { - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } - err = cmd.Run() - if err != nil { - return err, nil - } - if _, err := os.Stat(path.Join(temp, "output/")); err != nil { - if os.IsNotExist(err) { - return errors.New("output directory not be found at " + path.Join(temp, "output/")), nil - } - return err, nil - } - if dir, _ := os.ReadDir(path.Join(temp, "output/")); len(dir) == 0 { - return errors.New("output directory is empty"), nil - } - fmt.Println("Copying all files...") - err = filepath.WalkDir(path.Join(temp, "/output/"), func(fullpath string, d fs.DirEntry, err error) error { - relFilename, err := filepath.Rel(path.Join(temp, "/output/"), fullpath) - if relFilename == "." { - return nil - } - extractFilename := path.Join(rootDir, relFilename) - if err != nil { - return err - } - if d.Type() == os.ModeDir { - files = append(files, relFilename+"/") - if err := os.Mkdir(extractFilename, 0755); err != nil { - if !os.IsExist(err) { - return err - } - } else { - if verbose { - fmt.Println("Creating Directory: " + extractFilename) - } - } - } else if d.Type().IsRegular() { - if _, err := os.Stat(extractFilename); err == nil { - if slices.Contains(bpmpkg.PkgInfo.Keep, relFilename) { - if verbose { - fmt.Println("Skipping File: " + extractFilename + "(File is configured to be kept during installs/updates)") - } - files = append(files, relFilename) - return nil - } - } - err := os.Remove(extractFilename) - if err != nil && !os.IsNotExist(err) { - return err - } - outFile, err := os.Create(extractFilename) - if verbose { - fmt.Println("Creating File: " + extractFilename) - } - files = append(files, relFilename) - if err != nil { - return err - } - f, err := os.Open(fullpath) - if err != nil { - return err - } - if _, err := io.Copy(outFile, f); err != nil { - return err - } - info, err := os.Stat(fullpath) - if err != nil { - return err - } - if err := os.Chmod(extractFilename, info.Mode()); err != nil { - return err - } - err = outFile.Close() - if err != nil { - return err - } - err = f.Close() - if err != nil { - return err - } - } else if d.Type() == os.ModeSymlink { - link, err := os.Readlink(fullpath) - if err != nil { - return err - } - err = os.Remove(extractFilename) - if err != nil && !os.IsNotExist(err) { - return err - } - if verbose { - fmt.Println("Creating Symlink: "+extractFilename, " -> "+link) - } - files = append(files, relFilename) - err = os.Symlink(link, extractFilename) - if err != nil { - return err - } - } - return nil - }) - if err != nil { - return err, nil - } - if binaryPkgFromSrc { - compiledDir := path.Join(BPMConfig.BinaryOutputDir) - err = os.MkdirAll(compiledDir, 0755) - compiledInfo := PackageInfo{} - compiledInfo = *bpmpkg.PkgInfo - compiledInfo.Type = "binary" - compiledInfo.Arch = GetArch() - err = os.WriteFile(path.Join(temp, "pkg.info"), []byte(CreateInfoFile(&compiledInfo)), 0644) - if err != nil { - return err, nil - } - err = os.Chown(path.Join(temp, "pkg.info"), 65534, 65534) - if err != nil { - return err, nil - } - scripts, err := ReadPackageScripts(filename) - for key, val := range scripts { - err = os.WriteFile(path.Join(temp, key), []byte(val), 0644) - if err != nil { - return err, nil - } - err = os.Chown(path.Join(temp, key), 65534, 65534) - if err != nil { - return err, nil - } - } - sed := fmt.Sprintf("s/output/files/") - fileName := compiledInfo.Name + "-" + compiledInfo.GetFullVersion() + "-" + compiledInfo.Arch + ".bpm" - cmd := exec.Command("/usr/bin/fakeroot", "-i fakeroot_file", "tar", "-czvpf", fileName, "pkg.info", "output/", "--transform", sed) - if !BPMConfig.SilentCompilation { - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } - cmd.SysProcAttr = &syscall.SysProcAttr{} - cmd.SysProcAttr.Credential = &syscall.Credential{Uid: 65534, Gid: 65534} - cmd.Dir = temp - cmd.Env = os.Environ() - fmt.Printf("running command: %s\n", strings.Join(cmd.Args, " ")) - err = cmd.Run() - if err != nil { - return err, nil - } - err = copyFileContents(path.Join(temp, fileName), path.Join(compiledDir, fileName)) - if err != nil { - return err, nil - } - err = os.Chown(path.Join(compiledDir, fileName), 0, 0) - if err != nil { - return err, nil - } - } - if !keepTempDir { - err := os.RemoveAll(temp) - if err != nil { - return err, nil - } - } - if len(files) == 0 { - return errors.New("no output files for source package. Cancelling package installation"), nil - } - - defer file.Close() - return nil, files -} - -func installPackage(filename, rootDir string, verbose, force, binaryPkgFromSrc, skipCheck, keepTempDir bool) error { +func installPackage(filename, rootDir string, verbose, force bool) error { if _, err := os.Stat(filename); os.IsNotExist(err) { return err } @@ -1170,13 +714,7 @@ func installPackage(filename, rootDir string, verbose, force, binaryPkgFromSrc, return err } } else if bpmpkg.PkgInfo.Type == "source" { - if isSplitPackage(filename) { - return errors.New("BPM is unable to install split source packages") - } - err, _ := compilePackage(bpmpkg, filename, rootDir, verbose, binaryPkgFromSrc, skipCheck, keepTempDir) - if err != nil { - return err - } + return errors.New("direct source package compilation in BPM has been temporarily removed and is being reworked on") } else { return errors.New("unknown package type: " + bpmpkg.PkgInfo.Type) } @@ -1649,11 +1187,6 @@ func removePackage(pkg string, verbose bool, rootDir string) error { // Executing post_remove script if _, err := os.Stat(path.Join(pkgDir, "post_remove.sh")); err == nil { cmd := exec.Command("/bin/bash", path.Join(pkgDir, "post_remove.sh")) - if !BPMConfig.SilentCompilation { - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } cmd.Dir = rootDir cmd.Env = os.Environ() cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_ROOT=%s", rootDir))