mirror of
https://github.com/crowdsecurity/crowdsec.git
synced 2025-05-10 20:05:55 +02:00
112 lines
2.3 KiB
Go
112 lines
2.3 KiB
Go
package hubops
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
|
)
|
|
|
|
// RemoveInstallLink removes the item's symlink between the installation directory and the local hub.
|
|
func RemoveInstallLink(i *cwhub.Item) error {
|
|
stat, err := os.Lstat(i.State.LocalPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// if it's managed by hub, it's a symlink to csconfig.GConfig.hub.HubDir / ...
|
|
if stat.Mode()&os.ModeSymlink == 0 {
|
|
return fmt.Errorf("%s isn't managed by hub", i.Name)
|
|
}
|
|
|
|
target, err := os.Readlink(i.State.LocalPath)
|
|
if err != nil {
|
|
return fmt.Errorf("while reading symlink: %w", err)
|
|
}
|
|
|
|
if target != i.State.DownloadPath {
|
|
return fmt.Errorf("%s isn't managed by hub", i.Name)
|
|
}
|
|
|
|
if err := os.Remove(i.State.LocalPath); err != nil {
|
|
return fmt.Errorf("while removing symlink: %w", err)
|
|
}
|
|
|
|
i.State.LocalPath = ""
|
|
|
|
return nil
|
|
}
|
|
|
|
// DisableCommand uninstalls an item and its dependencies, ensuring that no
|
|
// sub-item is left in an inconsistent state.
|
|
type DisableCommand struct {
|
|
Item *cwhub.Item
|
|
Force bool
|
|
}
|
|
|
|
func NewDisableCommand(item *cwhub.Item, force bool) *DisableCommand {
|
|
return &DisableCommand{Item: item, Force: force}
|
|
}
|
|
|
|
func (c *DisableCommand) Prepare(plan *ActionPlan) (bool, error) {
|
|
i := c.Item
|
|
|
|
if i.State.IsLocal() {
|
|
plan.Warning(i.FQName() + " is a local item, please delete manually")
|
|
return false, nil
|
|
}
|
|
|
|
if i.State.Tainted && !c.Force {
|
|
return false, fmt.Errorf("%s is tainted, use '--force' to remove", i.Name)
|
|
}
|
|
|
|
if !i.State.IsInstalled() {
|
|
return false, nil
|
|
}
|
|
|
|
subsToRemove, err := i.SafeToRemoveDeps()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
for _, sub := range subsToRemove {
|
|
if !sub.State.IsInstalled() {
|
|
continue
|
|
}
|
|
|
|
if err := plan.AddCommand(NewDisableCommand(sub, c.Force)); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func (c *DisableCommand) Run(ctx context.Context, plan *ActionPlan) error {
|
|
i := c.Item
|
|
|
|
fmt.Println("disabling " + colorizeItemName(i.FQName()))
|
|
|
|
if err := RemoveInstallLink(i); err != nil {
|
|
return fmt.Errorf("while disabling %s: %w", i.FQName(), err)
|
|
}
|
|
|
|
plan.ReloadNeeded = true
|
|
|
|
i.State.Tainted = false
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *DisableCommand) OperationType() string {
|
|
return "disable"
|
|
}
|
|
|
|
func (c *DisableCommand) ItemType() string {
|
|
return c.Item.Type
|
|
}
|
|
|
|
func (c *DisableCommand) Detail() string {
|
|
return colorizeItemName(c.Item.Name)
|
|
}
|