Skip to content

Commit

Permalink
feat: package install/uninstall hooks (#184)
Browse files Browse the repository at this point in the history
Fixes #177
  • Loading branch information
agaffney authored Apr 8, 2024
1 parent c4c0aa9 commit dd20601
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 18 deletions.
67 changes: 55 additions & 12 deletions pkgmgr/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"io/fs"
"log/slog"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
Expand All @@ -30,16 +31,20 @@ import (
)

type Package struct {
Name string `yaml:"name,omitempty"`
Version string `yaml:"version,omitempty"`
Description string `yaml:"description,omitempty"`
InstallSteps []PackageInstallStep `yaml:"installSteps,omitempty"`
Dependencies []string `yaml:"dependencies,omitempty"`
Tags []string `yaml:"tags,omitempty"`
PostInstallNotes string `yaml:"postInstallNotes,omitempty"`
Options []PackageOption `yaml:"options,omitempty"`
Outputs []PackageOutput `yaml:"outputs,omitempty"`
filePath string
Name string `yaml:"name,omitempty"`
Version string `yaml:"version,omitempty"`
Description string `yaml:"description,omitempty"`
InstallSteps []PackageInstallStep `yaml:"installSteps,omitempty"`
Dependencies []string `yaml:"dependencies,omitempty"`
Tags []string `yaml:"tags,omitempty"`
PreInstallScript string `yaml:"preInstallScript,omitempty"`
PostInstallScript string `yaml:"postInstallScript,omitempty"`
PreUninstallScript string `yaml:"preUninstallScript,omitempty"`
PostUninstallScript string `yaml:"postUninstallScript,omitempty"`
PostInstallNotes string `yaml:"postInstallNotes,omitempty"`
Options []PackageOption `yaml:"options,omitempty"`
Outputs []PackageOutput `yaml:"outputs,omitempty"`
filePath string
}

type PackageOption struct {
Expand Down Expand Up @@ -101,7 +106,7 @@ func (p Package) hasTags(tags []string) bool {
return true
}

func (p Package) install(cfg Config, context string, opts map[string]bool) (string, map[string]string, error) {
func (p Package) install(cfg Config, context string, opts map[string]bool, runHooks bool) (string, map[string]string, error) {
// Update template vars
pkgName := fmt.Sprintf("%s-%s-%s", p.Name, p.Version, context)
pkgCacheDir := filepath.Join(
Expand Down Expand Up @@ -154,6 +159,12 @@ func (p Package) install(cfg Config, context string, opts map[string]bool) (stri
if err := os.MkdirAll(pkgDataDir, fs.ModePerm); err != nil {
return "", nil, err
}
// Run pre-install script
if runHooks && p.PreInstallScript != "" {
if err := p.runHookScript(cfg, p.PreInstallScript); err != nil {
return "", nil, err
}
}
// Perform install
for _, installStep := range p.InstallSteps {
// Evaluate condition if defined
Expand Down Expand Up @@ -235,6 +246,12 @@ func (p Package) install(cfg Config, context string, opts map[string]bool) (stri
}
retOutputs[key] = val
}
// Run post-install script
if runHooks && p.PostInstallScript != "" {
if err := p.runHookScript(cfg, p.PostInstallScript); err != nil {
return "", nil, err
}
}
// Render notes and return
var retNotes string
if p.PostInstallNotes != "" {
Expand All @@ -247,8 +264,14 @@ func (p Package) install(cfg Config, context string, opts map[string]bool) (stri
return retNotes, retOutputs, nil
}

func (p Package) uninstall(cfg Config, context string, keepData bool) error {
func (p Package) uninstall(cfg Config, context string, keepData bool, runHooks bool) error {
pkgName := fmt.Sprintf("%s-%s-%s", p.Name, p.Version, context)
// Run pre-uninstall script
if runHooks && p.PreUninstallScript != "" {
if err := p.runHookScript(cfg, p.PreUninstallScript); err != nil {
return err
}
}
// Iterate over install steps in reverse
for idx := len(p.InstallSteps) - 1; idx >= 0; idx-- {
installStep := p.InstallSteps[idx]
Expand Down Expand Up @@ -331,6 +354,12 @@ func (p Package) uninstall(cfg Config, context string, keepData bool) error {
)
}
}
// Run post-uninstall script
if runHooks && p.PostUninstallScript != "" {
if err := p.runHookScript(cfg, p.PostUninstallScript); err != nil {
return err
}
}
return nil
}

Expand Down Expand Up @@ -535,6 +564,20 @@ func (p Package) services(cfg Config, context string) ([]*DockerService, error)
return ret, nil
}

func (p Package) runHookScript(cfg Config, hookScript string) error {
renderedScript, err := cfg.Template.Render(hookScript, nil)
if err != nil {
return fmt.Errorf("failed to render hook script template: %s", err)
}
cmd := exec.Command("/bin/sh", "-c", renderedScript)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to run hook script: %s", err)
}
return nil
}

type PackageInstallStep struct {
Condition string `yaml:"condition,omitempty"`
Docker *PackageInstallStepDocker `yaml:"docker,omitempty"`
Expand Down
12 changes: 6 additions & 6 deletions pkgmgr/pkgmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (p *PackageManager) Install(pkgs ...string) error {
tmpPkgOpts[k] = v
}
// Install package
notes, outputs, err := installPkg.Install.install(p.config, activeContextName, tmpPkgOpts)
notes, outputs, err := installPkg.Install.install(p.config, activeContextName, tmpPkgOpts, true)
if err != nil {
return err
}
Expand Down Expand Up @@ -262,11 +262,11 @@ func (p *PackageManager) Upgrade(pkgs ...string) error {
)
}
// Uninstall old version
if err := p.uninstallPackage(upgradePkg.Installed, true); err != nil {
if err := p.uninstallPackage(upgradePkg.Installed, true, false); err != nil {
return err
}
// Install new version
notes, outputs, err := upgradePkg.Upgrade.install(p.config, activeContextName, pkgOpts)
notes, outputs, err := upgradePkg.Upgrade.install(p.config, activeContextName, pkgOpts, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -349,7 +349,7 @@ func (p *PackageManager) Uninstall(pkgName string, keepData bool, force bool) er
fmt.Sprintf("failed to deactivate package: %s", err),
)
}
if err := p.uninstallPackage(uninstallPkg, keepData); err != nil {
if err := p.uninstallPackage(uninstallPkg, keepData, true); err != nil {
return err
}
if err := p.state.Save(); err != nil {
Expand Down Expand Up @@ -498,9 +498,9 @@ func (p *PackageManager) Info(pkgs ...string) error {
return nil
}

func (p *PackageManager) uninstallPackage(uninstallPkg InstalledPackage, keepData bool) error {
func (p *PackageManager) uninstallPackage(uninstallPkg InstalledPackage, keepData bool, runHooks bool) error {
// Uninstall package
if err := uninstallPkg.Package.uninstall(p.config, uninstallPkg.Context, keepData); err != nil {
if err := uninstallPkg.Package.uninstall(p.config, uninstallPkg.Context, keepData, runHooks); err != nil {
return err
}
// Remove package from installed packages
Expand Down

0 comments on commit dd20601

Please sign in to comment.