diff options
Diffstat (limited to 'installpkg.go')
-rw-r--r-- | installpkg.go | 378 |
1 files changed, 0 insertions, 378 deletions
diff --git a/installpkg.go b/installpkg.go deleted file mode 100644 index 488692e..0000000 --- a/installpkg.go +++ /dev/null @@ -1,378 +0,0 @@ -package pkgtools - -import ( - "archive/tar" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - "time" - - "github.com/juju/fslock" - "github.com/pkg/errors" -) - -const umask = "022" - -const DefaultPerms = 0755 - -// ExitStatusTarError is when tar returned error code. -const ExitStatusTarError = 1 - -// ExitStatusCorruptCompression is when corrupt compression envelope. -const ExitStatusCorruptCompression = 2 - -// ExitStatusIncorrectExt is when does not end in .tgz. -const ExitStatusIncorrectExt = 3 - -// ExitStatusNoSuchFile is when no such file. -const ExitStatusNoSuchFile = 4 - -// ExitStatusMissingCompressionUtility is when external compression utility. -// missing -const ExitStatusMissingCompressionUtility = 5 - -// ExitStatusUserAbortFromMenu is when user abort from menu mode. -const ExitStatusUserAbortFromMenu = 99 - -var ErrNotImplemented = errors.New("not implemented") - -// DefaultTerseLength is the default line length during terse mode. -const DefaultTerseLength = 80 - -// Ended at line 232 - -const ( - PriorityNone = "" - PriorityAdditional = "ADD" - PriorityRecommended = "REC" - PriorityOptional = "OPT" - PrioritySkip = "SKP" -) - -type InstallPkgFlags struct { - Ask bool - InfoBox bool - LockDir string - MD5Sum bool - Menu bool - NoOverwrite bool - Priority string - Root string - TagFile string - Terse bool - TerseLength int - Warn bool - - chown bool - chmod bool - Strict bool -} - -var DefaultInstallPkgFlags = InstallPkgFlags{ - // Official slackware configuration - Ask: false, - InfoBox: false, - LockDir: InstallLockDir, - MD5Sum: false, - Menu: false, - NoOverwrite: false, - Priority: PriorityNone, - Root: "/", - TagFile: "", - Terse: false, - TerseLength: DefaultTerseLength, - Warn: false, - - // ours - chown: false, - chmod: false, - Strict: true, -} - -func (s *InstallPkgFlags) SetEnvValues() { - if v := os.Getenv("INSTLOCKDIR"); v != "" { - s.LockDir = v - } - - // Official installpkg prefers the argument of the environment - // variable. - if v := os.Getenv("ROOT"); v != "" { - s.Root = v - } - - if v := os.Getenv("PKGTOOLS_GO_STRICT"); v != "NO" { - s.Strict = false - } -} - -func runInstallScript( - flags *InstallPkgFlags, - pkgBase string, -) error { - l := fslock.New(FileLockPath(flags.LockDir, filepath.Base(PackageInstallScript))) - if err := l.Lock(); err != nil { - return err - } - defer l.Unlock() - - cwd, err := os.Getwd() - if err != nil { - return err - } - err = os.Chdir(flags.Root) - if err != nil { - return err - } - defer os.Chdir(cwd) - - installScript := filepath.Join(flags.Root, ADMDir, "scripts", pkgBase) - if _, err := os.Stat(installScript); !os.IsNotExist(err) { - cmd := exec.Command("/bin/bash", installScript) - cmd.Stdin = os.Stdout - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err = cmd.Run() - if err != nil { - return err - } - } - - return nil -} - -const ADMDirPerms = 0755 - -const LogDirPerms = 0755 - -const TmpDirPerms = 0700 - -func initializeDirectories(flags *InstallPkgFlags) error { - err := os.MkdirAll(flags.LockDir, DefaultPerms) - if err != nil { - return err - } - - dirs := []string{ - "douninst.sh", - "packages", - "scripts", - "setup", - } - for _, f := range dirs { - fp := filepath.Join(flags.Root, ADMDir, f) - err := os.MkdirAll(fp, DefaultPerms) - if err != nil { - return err - } - err = os.Chmod(fp, ADMDirPerms) - if err != nil { - return err - } - } - - dirs = []string{ - "removed_packages", - "removed_scripts", - } - for _, f := range dirs { - fp := filepath.Join(flags.Root, LogDir, f) - if ok, err := IsDir(fp); !ok && !os.IsNotExist(err) { - err := os.Remove(fp) - if err != nil { - return err - } - } - - err := os.MkdirAll(fp, DefaultPerms) - if err != nil { - return err - } - err = os.Chmod(fp, LogDirPerms) - if err != nil { - return err - } - } - - dirs = []string{ - "packages", - "scripts", - "setup", - } - for _, f := range dirs { - fp := filepath.Join(flags.Root, LogDir, "..", f) - isDir, _ := IsDir(fp) - isSymlink, _ := IsSymlink(fp) - if isDir || isSymlink { - continue - } - - err := os.Symlink(filepath.Join("..", "lib", "pkgtools", f), fp) - if err != nil { - return err - } - } - - fp := filepath.Join(flags.Root, TmpDir) - if ok, _ := IsDir(TmpDir); !ok { - err := os.MkdirAll(fp, DefaultPerms) - if err != nil { - return err - } - - err = os.Chmod(fp, TmpDirPerms) - if err != nil { - return err - } - } - - return nil -} - -func showSlackDesc(target string) error { - return nil -} - -// TODO: Check permissions for written files -func writeToDatabase(target string, pkg string) error { - // copy install script - // TODO: include uninstall script - installScript := filepath.Join(target, ADMDir, "scripts", PackageBase(pkg)) - uninstallScript := filepath.Join(target, ADMDir, "douninst.sh", PackageBase(pkg)) - slackPkg, err := OpenSlackwarePkg(pkg) - if err != nil { - return err - } - defer slackPkg.Close() - for { - entry, err := slackPkg.Next() - if err == io.EOF { - break - } else if err != nil { - return err - } - if entry == nil { - continue - } - - switch entry.Name { - case PackageInstallScript: - f, err := os.Create(installScript) - if err != nil { - return err - } - defer f.Close() - _, err = io.Copy(f, slackPkg) - if err != nil { - return err - } - case PackageUninstallScript: - f, err := os.Create(uninstallScript) - if err != nil { - return err - } - defer f.Close() - _, err = io.Copy(f, slackPkg) - if err != nil { - return err - } - default: - _, _ = io.Copy(io.Discard, slackPkg) - } - } - - fp := filepath.Join(target, ADMDir, "packages", PackageBase(pkg)) - f, err := os.Create(fp) - if err != nil { - return err - } - defer f.Close() - - e := NewEncoder(f) - err = e.Encode(slackPkg.PkgInfo()) - if err != nil { - return err - } - - 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) 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, - Strict: flags.Strict, - }) - - err = FilterTar( - slackPkg, - TarFilterFunc(func(h *tar.Header, r io.Reader) error { - if ok, err := IsParentDir(PackageInstallPath, h.Name); ok { - // important install files are already written - // to the targets package database. - return nil - } else if err != nil { - return errors.Wrap(err, "installing package") - } - if flags.NoOverwrite { - ok, err := IsExist(filepath.Join(flags.Root, h.Name)) - if err != nil { - return err - } - if ok { - return nil - } - } - return toRoot.FilterTar(h, r) - }), - ) - return errors.Wrap(err, "installing package") -} - -func InstallPkg(flags *InstallPkgFlags, pkgs ...string) error { - // TODO: Apply default flag values - - err := initializeDirectories(flags) - if err != nil { - return err - } - - for _, pkg := range pkgs { - fmt.Printf("installing %s\n", PackageBase(pkg)) - err = writeToDatabase(flags.Root, pkg) - if err != nil { - return errors.Wrap(err, "writing package to database") - } - - err := extractSlackwarePkg(flags, pkg) - if err != nil { - return errors.Wrap(err, "writing package to database") - } - - _ = os.Chtimes( - filepath.Join(flags.Root, ADMDir, "packages", PackageBase(pkg)), - time.Now(), - time.Now(), - ) - - _ = runLDConfig(flags.LockDir) - - err = runInstallScript(flags, PackageBase(pkg)) - if err != nil { - fmt.Fprintln(os.Stderr, errors.Wrap(err, "running install script")) - } - } - - return nil -} |