diff options
Diffstat (limited to 'removepkg.go')
-rw-r--r-- | removepkg.go | 278 |
1 files changed, 0 insertions, 278 deletions
diff --git a/removepkg.go b/removepkg.go deleted file mode 100644 index a1fab5e..0000000 --- a/removepkg.go +++ /dev/null @@ -1,278 +0,0 @@ -package pkgtools - -import ( - "fmt" - "io" - "os" - "os/exec" - "path" - "path/filepath" - "sort" - "strings" - - "github.com/juju/fslock" - "github.com/pkg/errors" -) - -const UninstallScript = "var/lib/pkgtools/douinst.sh" - -func getPackageName(pkg string) string { - return PackageBase(pkg) -} - -// Official flags -// [ ROOT=/mnt ] removepkg [--copy] [--keep] [--preserve] [--skip-douninst] [--terse] [--warn] packagename ... - -type RemovePkgFlags struct { - LockDir string - Root string -} - -var DefaultRemovePkgFlags = RemovePkgFlags{ - LockDir: InstallLockDir, - Root: "/", -} - -func (s *RemovePkgFlags) 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 - } -} - -func guessPackagename(root string, str string) (string, bool) { - // TODO: check if package exists - return str, true -} - -func runUninstallScript(root string) error { - cwd, err := os.Getwd() - if err != nil { - return err - } - err = os.Chdir(root) - if err != nil { - return err - } - defer os.Chdir(cwd) - - uninstallScript := path.Join(root, PackageUninstallScript) - if _, err := os.Stat(uninstallScript); !os.IsNotExist(err) { - cmd := exec.Command("/bin/sh", uninstallScript) - cmd.Stdin = os.Stdout - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err = cmd.Run() - if err != nil { - return err - } - } - - return nil -} - -func runLDConfig(lockdir string) error { - l := fslock.New(FileLockPath(lockdir, "ldconfig")) - if err := l.Lock(); err != nil { - return err - } - defer l.Unlock() - - if _, err := os.Stat("/sbin/ldconfig"); !os.IsNotExist(err) { - cmd := exec.Command("/sbin/ldconfig") - cmd.Stdin = os.Stdout - cmd.Stdout = os.Stdout - cmd.Stderr = io.Discard - err = cmd.Run() - if err != nil { - return err - } - - } - - return nil -} - -func deletePackageFiles( - flags *RemovePkgFlags, - pkg string, -) error { - info, err := GetPackageInfo(flags.Root, pkg) - if err != nil { - return err - } - pkgFiles := info.FileList - links, err := GetPackageSoftLinks(flags.Root, pkg) - if err != nil { - return err - } - pkgFiles = append(pkgFiles, links...) - pkgFiles = append(pkgFiles, catPaths(pkgFiles)...) - - // get all other package files - otherPkgFiles := make(map[string]bool) - otherPkgs, err := ListPackages(flags.Root) - if err != nil { - return err - } - for _, o := range otherPkgs { - if o == pkg { - continue - } - info, err := GetPackageInfo(flags.Root, o) - if err != nil { - return err - } - paths := info.FileList - - links, err := GetPackageSoftLinks(flags.Root, o) - paths = append(paths, links...) - - paths = append(paths, catPaths(paths)...) - for _, p := range paths { - otherPkgFiles[p] = true - } - } - - var dirs []string - for _, fp := range pkgFiles { - if ok := otherPkgFiles[fp]; ok { - continue - } - - tfp := filepath.Join(flags.Root, fp) - if ok, _ := IsDir(tfp); ok { - dirs = append(dirs, fp) - continue - } - - // Bravely attempt removal ignoring errors. The os.Stat - // returns a NotExist error soft links whose target is missing, - // resulting in error. - _ = os.Remove(tfp) - } - - sort.Sort(sort.Reverse(sort.StringSlice(dirs))) - for _, fp := range dirs { - tfp := filepath.Join(flags.Root, fp) - // Remove deletes only empty directories - _ = os.Remove(tfp) - } - - return nil -} - -func catPaths(fps []string) []string { - var cats []string - for _, p := range fps { - if !strings.HasPrefix(p, "usr/man/man") { - continue - } - cat := strings.Replace(p, "usr/man/man", "usr/man/cat", -1) - cats = append(cats, cat) - } - return cats -} - -func RemovePkg( - flags *RemovePkgFlags, - pkgNames ...string, -) error { - // TODO: Apply default flag values - - err := os.MkdirAll(flags.LockDir, DefaultPerms) - if err != nil { - return err - } - - tmpDir := TargetTmpDir(flags.Root) - if ok, _ := IsDir(tmpDir); !ok { - err := os.MkdirAll(tmpDir, DefaultPerms) - if err != nil { - return err - } - err = os.Chmod(tmpDir, TmpDirPerms) - if err != nil { - return err - } - } - - var pkgs []string - for _, pkgName := range pkgNames { - pkg, ok, err := GetFullPackageName(flags.Root, pkgName) - if err != nil { - return errors.Wrap(err, "getting package information") - } - if !ok { - return errors.Errorf("package does not exist '%s'", pkgName) - } - pkgs = append(pkgs, pkg) - } - - for _, pkg := range pkgs { - fmt.Printf("removing %s\n", pkg) - - tmpUninstallScript := "" - if ok, _ := IsFile(filepath.Join(flags.Root, UninstallScript, pkg)); ok { - tmpUninstallScript = filepath.Join(tmpDir, pkg) - err := CopyFile( - tmpUninstallScript, - filepath.Join(flags.Root, UninstallScript, pkg), - ) - if err != nil { - return errors.Wrap(err, "removing package "+pkg) - } - } - - err := deletePackageFiles(flags, pkg) - if err != nil { - // TODO: should removepkg bail out on remove error - return errors.Wrap(err, "deleting package files") - } - - err = runUninstallScript(flags.Root) - if err != nil { - return err - } - - err = os.Rename( - TargetPackageInfoPath(flags.Root, pkg), - filepath.Join(flags.Root, InstalledRemovedPackagePath, pkg), - ) - if err != nil { - return errors.Wrap(err, "removing package "+pkg) - } - if ok, _ := IsFile(TargetScriptPath(flags.Root, pkg)); ok { - err := os.Rename( - TargetScriptPath(flags.Root, pkg), - filepath.Join(flags.Root, InstalledRemovedScriptsPath, pkg), - ) - if err != nil { - return errors.Wrap(err, "removing package "+pkg) - } - } - if ok, _ := IsFile(filepath.Join(tmpDir, pkg)); ok { - err := os.Rename( - tmpUninstallScript, - TargetRemovedUninstalllScriptPath(flags.Root, pkg), - ) - if err != nil { - return errors.Wrap(err, "removing package "+pkg) - } - } - - if flags.Root == "/" { - err = runLDConfig(flags.LockDir) - if err != nil { - return err - } - } - } - - return nil -} |