mirror of
https://github.com/crowdsecurity/crowdsec.git
synced 2025-05-11 12:25:53 +02:00
111 lines
2.4 KiB
Go
111 lines
2.4 KiB
Go
package hubops
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
|
)
|
|
|
|
// EnableCommand installs a hub item and its dependencies.
|
|
// In case this command is called during an upgrade, the sub-items list it taken from the
|
|
// latest version in the index, otherwise from the version that is currently installed.
|
|
type EnableCommand struct {
|
|
Item *cwhub.Item
|
|
Force bool
|
|
FromLatest bool
|
|
}
|
|
|
|
func NewEnableCommand(item *cwhub.Item, force bool) *EnableCommand {
|
|
return &EnableCommand{Item: item, Force: force}
|
|
}
|
|
|
|
func (c *EnableCommand) Prepare(plan *ActionPlan) (bool, error) {
|
|
var dependencies cwhub.Dependencies
|
|
|
|
i := c.Item
|
|
|
|
if c.FromLatest {
|
|
// we are upgrading
|
|
dependencies = i.LatestDependencies()
|
|
} else {
|
|
dependencies = i.CurrentDependencies()
|
|
}
|
|
|
|
for sub := range dependencies.SubItems(plan.hub) {
|
|
if err := plan.AddCommand(NewEnableCommand(sub, c.Force)); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
|
|
if i.State.IsInstalled() {
|
|
return false, nil
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
// CreateInstallLink creates a symlink between the actual config file at hub.HubDir and hub.ConfigDir.
|
|
func CreateInstallLink(i *cwhub.Item) error {
|
|
dest, err := i.PathForInstall()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
destDir := filepath.Dir(dest)
|
|
if err = os.MkdirAll(destDir, os.ModePerm); err != nil {
|
|
return fmt.Errorf("while creating %s: %w", destDir, err)
|
|
}
|
|
|
|
if _, err = os.Lstat(dest); err == nil {
|
|
// already exists
|
|
return nil
|
|
} else if !os.IsNotExist(err) {
|
|
return fmt.Errorf("failed to stat %s: %w", dest, err)
|
|
}
|
|
|
|
src := i.State.DownloadPath
|
|
|
|
if err = os.Symlink(src, dest); err != nil {
|
|
return fmt.Errorf("while creating symlink from %s to %s: %w", src, dest, err)
|
|
}
|
|
|
|
i.State.LocalPath = dest
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *EnableCommand) Run(ctx context.Context, plan *ActionPlan) error {
|
|
i := c.Item
|
|
|
|
fmt.Println("enabling " + colorizeItemName(i.FQName()))
|
|
|
|
if !i.State.IsDownloaded() {
|
|
// XXX: this a warning?
|
|
return fmt.Errorf("can't enable %s: not downloaded", i.FQName())
|
|
}
|
|
|
|
if err := CreateInstallLink(i); err != nil {
|
|
return fmt.Errorf("while enabling %s: %w", i.FQName(), err)
|
|
}
|
|
|
|
plan.ReloadNeeded = true
|
|
|
|
i.State.Tainted = false
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *EnableCommand) OperationType() string {
|
|
return "enable"
|
|
}
|
|
|
|
func (c *EnableCommand) ItemType() string {
|
|
return c.Item.Type
|
|
}
|
|
|
|
func (c *EnableCommand) Detail() string {
|
|
return colorizeItemName(c.Item.Name)
|
|
}
|