Compare commits
No commits in common. "a26737859cb23e1ec66af762e38c1cd9c759808d" and "87c492a30c58df7393a675fdc613f6de5259f01c" have entirely different histories.
a26737859c
...
87c492a30c
40
main.go
40
main.go
@ -224,7 +224,6 @@ func resolveCommand() {
|
|||||||
operation := utils.BPMOperation{
|
operation := utils.BPMOperation{
|
||||||
Actions: make([]utils.OperationAction, 0),
|
Actions: make([]utils.OperationAction, 0),
|
||||||
UnresolvedDepends: make([]string, 0),
|
UnresolvedDepends: make([]string, 0),
|
||||||
Changes: make(map[string]string),
|
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
ForceInstallationReason: ir,
|
ForceInstallationReason: ir,
|
||||||
}
|
}
|
||||||
@ -239,7 +238,7 @@ func resolveCommand() {
|
|||||||
if !reinstall && utils.IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) && utils.GetPackageInfo(bpmpkg.PkgInfo.Name, rootDir).GetFullVersion() == bpmpkg.PkgInfo.GetFullVersion() {
|
if !reinstall && utils.IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) && utils.GetPackageInfo(bpmpkg.PkgInfo.Name, rootDir).GetFullVersion() == bpmpkg.PkgInfo.GetFullVersion() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
operation.AppendAction(&utils.InstallPackageAction{
|
operation.Actions = append(operation.Actions, &utils.InstallPackageAction{
|
||||||
File: pkg,
|
File: pkg,
|
||||||
IsDependency: false,
|
IsDependency: false,
|
||||||
BpmPackage: bpmpkg,
|
BpmPackage: bpmpkg,
|
||||||
@ -262,7 +261,7 @@ func resolveCommand() {
|
|||||||
if !reinstall && utils.IsPackageInstalled(entry.Info.Name, rootDir) && utils.GetPackageInfo(entry.Info.Name, rootDir).GetFullVersion() == entry.Info.GetFullVersion() {
|
if !reinstall && utils.IsPackageInstalled(entry.Info.Name, rootDir) && utils.GetPackageInfo(entry.Info.Name, rootDir).GetFullVersion() == entry.Info.GetFullVersion() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
operation.AppendAction(&utils.FetchPackageAction{
|
operation.Actions = append(operation.Actions, &utils.FetchPackageAction{
|
||||||
IsDependency: false,
|
IsDependency: false,
|
||||||
RepositoryEntry: entry,
|
RepositoryEntry: entry,
|
||||||
})
|
})
|
||||||
@ -328,13 +327,6 @@ func resolveCommand() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error: could not complete operation: %s\n", err)
|
log.Fatalf("Error: could not complete operation: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executing hooks
|
|
||||||
fmt.Println("Running hooks...")
|
|
||||||
err = operation.RunHooks(verbose)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error: could not run hooks: %s\n", err)
|
|
||||||
}
|
|
||||||
case update:
|
case update:
|
||||||
if os.Getuid() != 0 {
|
if os.Getuid() != 0 {
|
||||||
log.Fatalf("Error: this subcommand needs to be run with superuser permissions")
|
log.Fatalf("Error: this subcommand needs to be run with superuser permissions")
|
||||||
@ -363,7 +355,6 @@ func resolveCommand() {
|
|||||||
operation := utils.BPMOperation{
|
operation := utils.BPMOperation{
|
||||||
Actions: make([]utils.OperationAction, 0),
|
Actions: make([]utils.OperationAction, 0),
|
||||||
UnresolvedDepends: make([]string, 0),
|
UnresolvedDepends: make([]string, 0),
|
||||||
Changes: make(map[string]string),
|
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
ForceInstallationReason: utils.Unknown,
|
ForceInstallationReason: utils.Unknown,
|
||||||
}
|
}
|
||||||
@ -387,7 +378,7 @@ func resolveCommand() {
|
|||||||
} else {
|
} else {
|
||||||
comparison := utils.ComparePackageVersions(*entry.Info, *installedInfo)
|
comparison := utils.ComparePackageVersions(*entry.Info, *installedInfo)
|
||||||
if comparison > 0 || reinstall {
|
if comparison > 0 || reinstall {
|
||||||
operation.AppendAction(&utils.FetchPackageAction{
|
operation.Actions = append(operation.Actions, &utils.FetchPackageAction{
|
||||||
IsDependency: false,
|
IsDependency: false,
|
||||||
RepositoryEntry: entry,
|
RepositoryEntry: entry,
|
||||||
})
|
})
|
||||||
@ -430,13 +421,6 @@ func resolveCommand() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error: could not complete operation: %s\n", err)
|
log.Fatalf("Error: could not complete operation: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executing hooks
|
|
||||||
fmt.Println("Running hooks...")
|
|
||||||
err = operation.RunHooks(verbose)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error: could not run hooks: %s\n", err)
|
|
||||||
}
|
|
||||||
case sync:
|
case sync:
|
||||||
if os.Getuid() != 0 {
|
if os.Getuid() != 0 {
|
||||||
log.Fatalf("Error: this subcommand needs to be run with superuser permissions")
|
log.Fatalf("Error: this subcommand needs to be run with superuser permissions")
|
||||||
@ -471,7 +455,6 @@ func resolveCommand() {
|
|||||||
operation := &utils.BPMOperation{
|
operation := &utils.BPMOperation{
|
||||||
Actions: make([]utils.OperationAction, 0),
|
Actions: make([]utils.OperationAction, 0),
|
||||||
UnresolvedDepends: make([]string, 0),
|
UnresolvedDepends: make([]string, 0),
|
||||||
Changes: make(map[string]string),
|
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,7 +464,7 @@ func resolveCommand() {
|
|||||||
if bpmpkg == nil {
|
if bpmpkg == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
operation.AppendAction(&utils.RemovePackageAction{BpmPackage: bpmpkg})
|
operation.Actions = append(operation.Actions, &utils.RemovePackageAction{BpmPackage: bpmpkg})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip needed packages if the --unused flag is on
|
// Skip needed packages if the --unused flag is on
|
||||||
@ -519,13 +502,6 @@ func resolveCommand() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error: could not complete operation: %s\n", err)
|
log.Fatalf("Error: could not complete operation: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executing hooks
|
|
||||||
fmt.Println("Running hooks...")
|
|
||||||
err = operation.RunHooks(verbose)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error: could not run hooks: %s\n", err)
|
|
||||||
}
|
|
||||||
case cleanup:
|
case cleanup:
|
||||||
if os.Getuid() != 0 {
|
if os.Getuid() != 0 {
|
||||||
log.Fatalf("Error: this subcommand needs to be run with superuser permissions")
|
log.Fatalf("Error: this subcommand needs to be run with superuser permissions")
|
||||||
@ -534,7 +510,6 @@ func resolveCommand() {
|
|||||||
operation := &utils.BPMOperation{
|
operation := &utils.BPMOperation{
|
||||||
Actions: make([]utils.OperationAction, 0),
|
Actions: make([]utils.OperationAction, 0),
|
||||||
UnresolvedDepends: make([]string, 0),
|
UnresolvedDepends: make([]string, 0),
|
||||||
Changes: make(map[string]string),
|
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,13 +538,6 @@ func resolveCommand() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error: could not complete operation: %s\n", err)
|
log.Fatalf("Error: could not complete operation: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Executing hooks
|
|
||||||
fmt.Println("Running hooks...")
|
|
||||||
err = operation.RunHooks(verbose)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error: could not run hooks: %s\n", err)
|
|
||||||
}
|
|
||||||
case file:
|
case file:
|
||||||
files := subcommandArgs
|
files := subcommandArgs
|
||||||
if len(files) == 0 {
|
if len(files) == 0 {
|
||||||
|
155
utils/hooks.go
155
utils/hooks.go
@ -1,155 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"slices"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BPMHook struct {
|
|
||||||
SourcePath string
|
|
||||||
SourceContent string
|
|
||||||
TriggerOperations []string `yaml:"trigger_operations"`
|
|
||||||
TargetType string `yaml:"target_type"`
|
|
||||||
Targets []string `yaml:"targets"`
|
|
||||||
Depends []string `yaml:"depends"`
|
|
||||||
Run string `yaml:"run"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateHook returns a BPMHook instance based on the content of the given string
|
|
||||||
func CreateHook(sourcePath string) (*BPMHook, error) {
|
|
||||||
// Read hook from source path
|
|
||||||
bytes, err := os.ReadFile(sourcePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create base hook structure
|
|
||||||
hook := &BPMHook{
|
|
||||||
SourcePath: sourcePath,
|
|
||||||
SourceContent: string(bytes),
|
|
||||||
TriggerOperations: nil,
|
|
||||||
TargetType: "",
|
|
||||||
Targets: nil,
|
|
||||||
Depends: nil,
|
|
||||||
Run: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal yaml string
|
|
||||||
err = yaml.Unmarshal(bytes, hook)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure hook is valid
|
|
||||||
if err := hook.IsValid(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return hook, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsValid ensures hook is valid
|
|
||||||
func (hook *BPMHook) IsValid() error {
|
|
||||||
ValidOperations := []string{"install", "upgrade", "remove"}
|
|
||||||
|
|
||||||
// Return error if any trigger operation is not valid or none are given
|
|
||||||
if len(hook.TriggerOperations) == 0 {
|
|
||||||
return errors.New("no trigger operations specified")
|
|
||||||
}
|
|
||||||
for _, operation := range hook.TriggerOperations {
|
|
||||||
if !slices.Contains(ValidOperations, operation) {
|
|
||||||
return errors.New("trigger operation '" + operation + "' is not valid")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if hook.TargetType != "package" && hook.TargetType != "path" {
|
|
||||||
return errors.New("target type '" + hook.TargetType + "' is not valid")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(hook.Run) == 0 {
|
|
||||||
return errors.New("command to run is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return nil as hook is valid
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute hook if all conditions are met
|
|
||||||
func (hook *BPMHook) Execute(packageChanges map[string]string, verbose bool, rootDir string) error {
|
|
||||||
// Check if package dependencies are met
|
|
||||||
installedPackages, err := GetInstalledPackages(rootDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, depend := range hook.Depends {
|
|
||||||
if !slices.Contains(installedPackages, depend) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get modified files slice
|
|
||||||
modifiedFiles := make([]*PackageFileEntry, 0)
|
|
||||||
for pkg := range packageChanges {
|
|
||||||
modifiedFiles = append(modifiedFiles, GetPackageFiles(pkg, rootDir)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if any targets are met
|
|
||||||
targetMet := false
|
|
||||||
for _, target := range hook.Targets {
|
|
||||||
if targetMet {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if hook.TargetType == "package" {
|
|
||||||
for change, operation := range packageChanges {
|
|
||||||
if target == change && slices.Contains(hook.TriggerOperations, operation) {
|
|
||||||
targetMet = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
glob, err := filepath.Glob(path.Join(rootDir, target))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, change := range modifiedFiles {
|
|
||||||
if slices.Contains(glob, path.Join(rootDir, change.Path)) {
|
|
||||||
targetMet = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !targetMet {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the command
|
|
||||||
splitCommand := strings.Split(hook.Run, " ")
|
|
||||||
cmd := exec.Command(splitCommand[0], splitCommand[1:]...)
|
|
||||||
// Setup subprocess environment
|
|
||||||
cmd.Dir = "/"
|
|
||||||
// Run hook in chroot if using the -R flag
|
|
||||||
if rootDir != "/" {
|
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{Chroot: rootDir}
|
|
||||||
}
|
|
||||||
|
|
||||||
if verbose {
|
|
||||||
fmt.Printf("Running hook (%s) with run command: %s\n", hook.SourcePath, strings.Join(splitCommand, " "))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -13,7 +12,6 @@ import (
|
|||||||
type BPMOperation struct {
|
type BPMOperation struct {
|
||||||
Actions []OperationAction
|
Actions []OperationAction
|
||||||
UnresolvedDepends []string
|
UnresolvedDepends []string
|
||||||
Changes map[string]string
|
|
||||||
RootDir string
|
RootDir string
|
||||||
ForceInstallationReason InstallationReason
|
ForceInstallationReason InstallationReason
|
||||||
}
|
}
|
||||||
@ -37,35 +35,12 @@ func (operation *BPMOperation) ActionsContainPackage(pkg string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (operation *BPMOperation) AppendAction(action OperationAction) {
|
|
||||||
operation.InsertActionAt(len(operation.Actions), action)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (operation *BPMOperation) InsertActionAt(index int, action OperationAction) {
|
func (operation *BPMOperation) InsertActionAt(index int, action OperationAction) {
|
||||||
if len(operation.Actions) == index { // nil or empty slice or after last element
|
if len(operation.Actions) == index { // nil or empty slice or after last element
|
||||||
operation.Actions = append(operation.Actions, action)
|
operation.Actions = append(operation.Actions, action)
|
||||||
} else {
|
|
||||||
operation.Actions = append(operation.Actions[:index+1], operation.Actions[index:]...) // index < len(a)
|
|
||||||
operation.Actions[index] = action
|
|
||||||
}
|
|
||||||
|
|
||||||
if action.GetActionType() == "install" {
|
|
||||||
pkgInfo := action.(*InstallPackageAction).BpmPackage.PkgInfo
|
|
||||||
if !IsPackageInstalled(pkgInfo.Name, operation.RootDir) {
|
|
||||||
operation.Changes[pkgInfo.Name] = "install"
|
|
||||||
} else {
|
|
||||||
operation.Changes[pkgInfo.Name] = "upgrade"
|
|
||||||
}
|
|
||||||
} else if action.GetActionType() == "fetch" {
|
|
||||||
pkgInfo := action.(*FetchPackageAction).RepositoryEntry.Info
|
|
||||||
if !IsPackageInstalled(pkgInfo.Name, operation.RootDir) {
|
|
||||||
operation.Changes[pkgInfo.Name] = "install"
|
|
||||||
} else {
|
|
||||||
operation.Changes[pkgInfo.Name] = "upgrade"
|
|
||||||
}
|
|
||||||
} else if action.GetActionType() == "remove" {
|
|
||||||
operation.Changes[action.(*RemovePackageAction).BpmPackage.PkgInfo.Name] = "remove"
|
|
||||||
}
|
}
|
||||||
|
operation.Actions = append(operation.Actions[:index+1], operation.Actions[index:]...) // index < len(a)
|
||||||
|
operation.Actions[index] = action
|
||||||
}
|
}
|
||||||
|
|
||||||
func (operation *BPMOperation) RemoveAction(pkg, actionType string) {
|
func (operation *BPMOperation) RemoveAction(pkg, actionType string) {
|
||||||
@ -381,32 +356,6 @@ func (operation *BPMOperation) ShowOperationSummary() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (operation *BPMOperation) RunHooks(verbose bool) error {
|
|
||||||
// Get directory entries in hooks directory
|
|
||||||
dirEntries, err := os.ReadDir(path.Join(operation.RootDir, "var/lib/bpm/hooks"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find all hooks, validate and execute them
|
|
||||||
for _, entry := range dirEntries {
|
|
||||||
if entry.Type().IsRegular() && strings.HasSuffix(entry.Name(), ".bpmhook") {
|
|
||||||
hook, err := CreateHook(path.Join(operation.RootDir, "var/lib/bpm/hooks", entry.Name()))
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Error while reading hook (%s): %s", entry.Name(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = hook.Execute(operation.Changes, verbose, operation.RootDir)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Warning: could not execute hook (%s): %s\n", entry.Name(), err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (operation *BPMOperation) Execute(verbose, force bool) error {
|
func (operation *BPMOperation) Execute(verbose, force bool) error {
|
||||||
// Fetch packages from repositories
|
// Fetch packages from repositories
|
||||||
if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool {
|
if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user