aboutsummaryrefslogtreecommitdiffsponsor
path: root/installpkg.go
diff options
context:
space:
mode:
Diffstat (limited to 'installpkg.go')
-rw-r--r--installpkg.go88
1 files changed, 63 insertions, 25 deletions
diff --git a/installpkg.go b/installpkg.go
index 7354ff0..7e10e61 100644
--- a/installpkg.go
+++ b/installpkg.go
@@ -1,12 +1,14 @@
package pkgtools
import (
+ "archive/tar"
"fmt"
"io"
"os"
"os/exec"
"path"
"path/filepath"
+ "strings"
"time"
"github.com/juju/fslock"
@@ -99,7 +101,12 @@ func (s *InstallPkgFlags) SetEnvValues() {
}
}
-func runInstallScript(flags *InstallPkgFlags) error {
+func runInstallScript(flags *InstallPkgFlags, installPath string) error {
+ installPath, err := filepath.Abs(installPath)
+ if err != nil {
+ return err
+ }
+
l := fslock.New(FileLockPath(flags.LockDir, filepath.Base(PackageInstallScript)))
if err := l.Lock(); err != nil {
return err
@@ -116,7 +123,7 @@ func runInstallScript(flags *InstallPkgFlags) error {
}
defer os.Chdir(cwd)
- installScript := path.Join(flags.Root, PackageInstallScript)
+ installScript := path.Join(installPath, filepath.Base(PackageInstallScript))
if _, err := os.Stat(installScript); !os.IsNotExist(err) {
cmd := exec.Command("/bin/bash", installScript)
cmd.Stdin = os.Stdout
@@ -287,19 +294,65 @@ func writeToDatabase(target string, pkg string) error {
return nil
}
+// ExtractSlackwarePkg unarchives the slackware package into the given
+// directory. The package metadata, under the archives '/install' path, is put
+// into a temporary directory and returned.
+func ExtractSlackwarePkg(flags *InstallPkgFlags, fp string) (string, error) {
+ slackPkg, err := OpenSlackwarePkg(fp)
+ if err != nil {
+ return "", errors.Wrap(err, "extracting package")
+ }
+ defer slackPkg.Close()
+
+ toRoot := NewTarExtractor(&TarCfg{
+ Root: flags.Root,
+ Chmod: flags.chmod,
+ Chown: flags.chown,
+ })
+
+ tmpDir := os.TempDir()
+ if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
+ tmpDir = "/"
+ } else if err != nil {
+ return "", errors.Wrap(err, "extracting package")
+ }
+ tempInstallDir, err := os.MkdirTemp(tmpDir, "installpkg-*")
+ if err != nil {
+ return "", errors.Wrap(err, "extracting package")
+ }
+ toTempInstallDir := NewTarExtractor(&TarCfg{
+ Root: tempInstallDir,
+ Chmod: flags.chmod,
+ Chown: flags.chown,
+ })
+
+ err = FilterTar(
+ slackPkg,
+ TarFilterFunc(func(h *tar.Header, r io.Reader) error {
+ if ok, err := IsParentDir(PackageInstallPath, h.Name); ok {
+ h.Name = strings.TrimPrefix(h.Name, PackageInstallPath+"/")
+ if h.Name == "" {
+ h.Name = "."
+ }
+ return toTempInstallDir.FilterTar(h, r)
+ } else if err != nil {
+ return errors.Wrap(err, "installing package")
+ }
+
+ return toRoot.FilterTar(h, r)
+ }),
+ )
+ return tempInstallDir, errors.Wrap(err, "installing package")
+}
+
func InstallPkg(flags *InstallPkgFlags, pkgs ...string) error {
- // Apply default flag values
+ // TODO: Apply default flag values
err := initializeDirectories(flags)
if err != nil {
return err
}
- installPath := path.Join(flags.Root, PackageInstallPath)
- if _, err := os.Stat(installPath); !errors.Is(err, os.ErrNotExist) {
- return errors.Errorf("The '%s' directory exists and would be used by installpkg and removed. Please consider renaming the directory or using Slackware's installpkg.", installPath)
- }
-
for _, pkg := range pkgs {
fmt.Printf("installing %s\n", PackageBase(pkg))
err = writeToDatabase(flags.Root, pkg)
@@ -307,22 +360,7 @@ func InstallPkg(flags *InstallPkgFlags, pkgs ...string) error {
return errors.Wrap(err, "writing package to database")
}
- err = func() error {
- slackPkg, err := OpenSlackwarePkg(pkg)
- if err != nil {
- return err
- }
- defer slackPkg.Close()
- err = InstallArchive(
- slackPkg,
- &InstallArchiveCfg{
- Root: flags.Root,
- Chmod: flags.chmod,
- Chown: flags.chown,
- },
- )
- return errors.Wrap(err, "installing package")
- }()
+ installPath, err := ExtractSlackwarePkg(flags, pkg)
if err != nil {
return errors.Wrap(err, "writing package to database")
}
@@ -336,7 +374,7 @@ func InstallPkg(flags *InstallPkgFlags, pkgs ...string) error {
_ = runLDConfig(flags.LockDir)
// TODO: command should still run after failed 'install script' execution
- err = runInstallScript(flags)
+ err = runInstallScript(flags, installPath)
if err != nil {
fmt.Fprintln(os.Stderr, errors.Wrap(err, "running install script"))
}