diff --git a/cmd/crowdsec-cli/config_backup.go b/cmd/crowdsec-cli/config_backup.go index d23aff80a78..afcf36f551c 100644 --- a/cmd/crowdsec-cli/config_backup.go +++ b/cmd/crowdsec-cli/config_backup.go @@ -1,234 +1,18 @@ package main import ( - "encoding/json" - "errors" "fmt" - "os" - "path/filepath" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - - "github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require" - "github.com/crowdsecurity/crowdsec/pkg/cwhub" ) -func (cli *cliConfig) backupHub(dirPath string) error { - hub, err := require.Hub(cli.cfg(), nil, nil) - if err != nil { - return err - } - - for _, itemType := range cwhub.ItemTypes { - clog := log.WithField("type", itemType) - - itemMap := hub.GetItemMap(itemType) - if itemMap == nil { - clog.Infof("No %s to backup.", itemType) - continue - } - - itemDirectory := fmt.Sprintf("%s/%s/", dirPath, itemType) - if err = os.MkdirAll(itemDirectory, os.ModePerm); err != nil { - return fmt.Errorf("error while creating %s: %w", itemDirectory, err) - } - - upstreamParsers := []string{} - - for k, v := range itemMap { - clog = clog.WithField("file", v.Name) - if !v.State.Installed { // only backup installed ones - clog.Debugf("[%s]: not installed", k) - continue - } - - // for the local/tainted ones, we back up the full file - if v.State.Tainted || v.State.IsLocal() || !v.State.UpToDate { - // we need to backup stages for parsers - if itemType == cwhub.PARSERS || itemType == cwhub.POSTOVERFLOWS { - fstagedir := fmt.Sprintf("%s%s", itemDirectory, v.Stage) - if err = os.MkdirAll(fstagedir, os.ModePerm); err != nil { - return fmt.Errorf("error while creating stage dir %s: %w", fstagedir, err) - } - } - - clog.Debugf("[%s]: backing up file (tainted:%t local:%t up-to-date:%t)", k, v.State.Tainted, v.State.IsLocal(), v.State.UpToDate) - - tfile := fmt.Sprintf("%s%s/%s", itemDirectory, v.Stage, v.FileName) - if err = CopyFile(v.State.LocalPath, tfile); err != nil { - return fmt.Errorf("failed copy %s %s to %s: %w", itemType, v.State.LocalPath, tfile, err) - } - - clog.Infof("local/tainted saved %s to %s", v.State.LocalPath, tfile) - - continue - } - - clog.Debugf("[%s]: from hub, just backup name (up-to-date:%t)", k, v.State.UpToDate) - clog.Infof("saving, version:%s, up-to-date:%t", v.Version, v.State.UpToDate) - upstreamParsers = append(upstreamParsers, v.Name) - } - // write the upstream items - upstreamParsersFname := fmt.Sprintf("%s/upstream-%s.json", itemDirectory, itemType) - - upstreamParsersContent, err := json.MarshalIndent(upstreamParsers, "", " ") - if err != nil { - return fmt.Errorf("failed to serialize upstream parsers: %w", err) - } - - err = os.WriteFile(upstreamParsersFname, upstreamParsersContent, 0o644) - if err != nil { - return fmt.Errorf("unable to write to %s %s: %w", itemType, upstreamParsersFname, err) - } - - clog.Infof("Wrote %d entries for %s to %s", len(upstreamParsers), itemType, upstreamParsersFname) - } - - return nil -} - -/* - Backup crowdsec configurations to directory : - -- Main config (config.yaml) -- Profiles config (profiles.yaml) -- Simulation config (simulation.yaml) -- Backup of API credentials (local API and online API) -- List of scenarios, parsers, postoverflows and collections that are up-to-date -- Tainted/local/out-of-date scenarios, parsers, postoverflows and collections -- Acquisition files (acquis.yaml, acquis.d/*.yaml) -*/ -func (cli *cliConfig) backup(dirPath string) error { - var err error - - cfg := cli.cfg() - - if dirPath == "" { - return errors.New("directory path can't be empty") - } - - log.Infof("Starting configuration backup") - - /*if parent directory doesn't exist, bail out. create final dir with Mkdir*/ - parentDir := filepath.Dir(dirPath) - if _, err = os.Stat(parentDir); err != nil { - return fmt.Errorf("while checking parent directory %s existence: %w", parentDir, err) - } - - if err = os.Mkdir(dirPath, 0o700); err != nil { - return fmt.Errorf("while creating %s: %w", dirPath, err) - } - - if cfg.ConfigPaths.SimulationFilePath != "" { - backupSimulation := filepath.Join(dirPath, "simulation.yaml") - if err = CopyFile(cfg.ConfigPaths.SimulationFilePath, backupSimulation); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", cfg.ConfigPaths.SimulationFilePath, backupSimulation, err) - } - - log.Infof("Saved simulation to %s", backupSimulation) - } - - /* - - backup AcquisitionFilePath - - backup the other files of acquisition directory - */ - if cfg.Crowdsec != nil && cfg.Crowdsec.AcquisitionFilePath != "" { - backupAcquisition := filepath.Join(dirPath, "acquis.yaml") - if err = CopyFile(cfg.Crowdsec.AcquisitionFilePath, backupAcquisition); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", cfg.Crowdsec.AcquisitionFilePath, backupAcquisition, err) - } - } - - acquisBackupDir := filepath.Join(dirPath, "acquis") - if err = os.Mkdir(acquisBackupDir, 0o700); err != nil { - return fmt.Errorf("error while creating %s: %w", acquisBackupDir, err) - } - - if cfg.Crowdsec != nil && len(cfg.Crowdsec.AcquisitionFiles) > 0 { - for _, acquisFile := range cfg.Crowdsec.AcquisitionFiles { - /*if it was the default one, it was already backup'ed*/ - if cfg.Crowdsec.AcquisitionFilePath == acquisFile { - continue - } - - targetFname, err := filepath.Abs(filepath.Join(acquisBackupDir, filepath.Base(acquisFile))) - if err != nil { - return fmt.Errorf("while saving %s to %s: %w", acquisFile, acquisBackupDir, err) - } - - if err = CopyFile(acquisFile, targetFname); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", acquisFile, targetFname, err) - } - - log.Infof("Saved acquis %s to %s", acquisFile, targetFname) - } - } - - if ConfigFilePath != "" { - backupMain := fmt.Sprintf("%s/config.yaml", dirPath) - if err = CopyFile(ConfigFilePath, backupMain); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", ConfigFilePath, backupMain, err) - } - - log.Infof("Saved default yaml to %s", backupMain) - } - - if cfg.API != nil && cfg.API.Server != nil && cfg.API.Server.OnlineClient != nil && cfg.API.Server.OnlineClient.CredentialsFilePath != "" { - backupCAPICreds := fmt.Sprintf("%s/online_api_credentials.yaml", dirPath) - if err = CopyFile(cfg.API.Server.OnlineClient.CredentialsFilePath, backupCAPICreds); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", cfg.API.Server.OnlineClient.CredentialsFilePath, backupCAPICreds, err) - } - - log.Infof("Saved online API credentials to %s", backupCAPICreds) - } - - if cfg.API != nil && cfg.API.Client != nil && cfg.API.Client.CredentialsFilePath != "" { - backupLAPICreds := fmt.Sprintf("%s/local_api_credentials.yaml", dirPath) - if err = CopyFile(cfg.API.Client.CredentialsFilePath, backupLAPICreds); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", cfg.API.Client.CredentialsFilePath, backupLAPICreds, err) - } - - log.Infof("Saved local API credentials to %s", backupLAPICreds) - } - - if cfg.API != nil && cfg.API.Server != nil && cfg.API.Server.ProfilesPath != "" { - backupProfiles := fmt.Sprintf("%s/profiles.yaml", dirPath) - if err = CopyFile(cfg.API.Server.ProfilesPath, backupProfiles); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", cfg.API.Server.ProfilesPath, backupProfiles, err) - } - - log.Infof("Saved profiles to %s", backupProfiles) - } - - if err = cli.backupHub(dirPath); err != nil { - return fmt.Errorf("failed to backup hub config: %w", err) - } - - return nil -} - func (cli *cliConfig) newBackupCmd() *cobra.Command { cmd := &cobra.Command{ - Use: `backup "directory"`, - Short: "Backup current config", - Long: `Backup the current crowdsec configuration including : - -- Main config (config.yaml) -- Simulation config (simulation.yaml) -- Profiles config (profiles.yaml) -- List of scenarios, parsers, postoverflows and collections that are up-to-date -- Tainted/local/out-of-date scenarios, parsers, postoverflows and collections -- Backup of API credentials (local API and online API)`, - Example: `cscli config backup ./my-backup`, - Args: cobra.ExactArgs(1), + Use: "backup", DisableAutoGenTag: true, - RunE: func(_ *cobra.Command, args []string) error { - if err := cli.backup(args[0]); err != nil { - return fmt.Errorf("failed to backup config: %w", err) - } - - return nil + RunE: func(_ *cobra.Command, _ []string) error { + configDir := cli.cfg().ConfigPaths.ConfigDir + return fmt.Errorf("'cscli config backup' has been removed, you can manually backup/restore %s instead", configDir) }, } diff --git a/cmd/crowdsec-cli/config_restore.go b/cmd/crowdsec-cli/config_restore.go index c32328485ec..2ecf274e05e 100644 --- a/cmd/crowdsec-cli/config_restore.go +++ b/cmd/crowdsec-cli/config_restore.go @@ -1,272 +1,18 @@ package main import ( - "context" - "encoding/json" "fmt" - "os" - "path/filepath" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - - "github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require" - "github.com/crowdsecurity/crowdsec/pkg/cwhub" ) -func (cli *cliConfig) restoreHub(ctx context.Context, dirPath string) error { - cfg := cli.cfg() - - hub, err := require.Hub(cfg, require.RemoteHub(ctx, cfg), nil) - if err != nil { - return err - } - - for _, itype := range cwhub.ItemTypes { - itemDirectory := fmt.Sprintf("%s/%s/", dirPath, itype) - if _, err = os.Stat(itemDirectory); err != nil { - log.Infof("no %s in backup", itype) - continue - } - /*restore the upstream items*/ - upstreamListFN := fmt.Sprintf("%s/upstream-%s.json", itemDirectory, itype) - - file, err := os.ReadFile(upstreamListFN) - if err != nil { - return fmt.Errorf("error while opening %s: %w", upstreamListFN, err) - } - - var upstreamList []string - - err = json.Unmarshal(file, &upstreamList) - if err != nil { - return fmt.Errorf("error parsing %s: %w", upstreamListFN, err) - } - - for _, toinstall := range upstreamList { - item := hub.GetItem(itype, toinstall) - if item == nil { - log.Errorf("Item %s/%s not found in hub", itype, toinstall) - continue - } - - if err = item.Install(ctx, false, false); err != nil { - log.Errorf("Error while installing %s : %s", toinstall, err) - } - } - - /*restore the local and tainted items*/ - files, err := os.ReadDir(itemDirectory) - if err != nil { - return fmt.Errorf("failed enumerating files of %s: %w", itemDirectory, err) - } - - for _, file := range files { - // this was the upstream data - if file.Name() == fmt.Sprintf("upstream-%s.json", itype) { - continue - } - - if itype == cwhub.PARSERS || itype == cwhub.POSTOVERFLOWS { - // we expect a stage here - if !file.IsDir() { - continue - } - - stage := file.Name() - stagedir := fmt.Sprintf("%s/%s/%s/", cfg.ConfigPaths.ConfigDir, itype, stage) - log.Debugf("Found stage %s in %s, target directory : %s", stage, itype, stagedir) - - if err = os.MkdirAll(stagedir, os.ModePerm); err != nil { - return fmt.Errorf("error while creating stage directory %s: %w", stagedir, err) - } - - // find items - ifiles, err := os.ReadDir(itemDirectory + "/" + stage + "/") - if err != nil { - return fmt.Errorf("failed enumerating files of %s: %w", itemDirectory+"/"+stage, err) - } - - // finally copy item - for _, tfile := range ifiles { - log.Infof("Going to restore local/tainted [%s]", tfile.Name()) - sourceFile := fmt.Sprintf("%s/%s/%s", itemDirectory, stage, tfile.Name()) - - destinationFile := fmt.Sprintf("%s%s", stagedir, tfile.Name()) - if err = CopyFile(sourceFile, destinationFile); err != nil { - return fmt.Errorf("failed copy %s %s to %s: %w", itype, sourceFile, destinationFile, err) - } - - log.Infof("restored %s to %s", sourceFile, destinationFile) - } - } else { - log.Infof("Going to restore local/tainted [%s]", file.Name()) - sourceFile := fmt.Sprintf("%s/%s", itemDirectory, file.Name()) - destinationFile := fmt.Sprintf("%s/%s/%s", cfg.ConfigPaths.ConfigDir, itype, file.Name()) - - if err = CopyFile(sourceFile, destinationFile); err != nil { - return fmt.Errorf("failed copy %s %s to %s: %w", itype, sourceFile, destinationFile, err) - } - - log.Infof("restored %s to %s", sourceFile, destinationFile) - } - } - } - - return nil -} - -/* - Restore crowdsec configurations to directory : - -- Main config (config.yaml) -- Profiles config (profiles.yaml) -- Simulation config (simulation.yaml) -- Backup of API credentials (local API and online API) -- List of scenarios, parsers, postoverflows and collections that are up-to-date -- Tainted/local/out-of-date scenarios, parsers, postoverflows and collections -- Acquisition files (acquis.yaml, acquis.d/*.yaml) -*/ -func (cli *cliConfig) restore(ctx context.Context, dirPath string) error { - var err error - - cfg := cli.cfg() - - backupMain := fmt.Sprintf("%s/config.yaml", dirPath) - if _, err = os.Stat(backupMain); err == nil { - if cfg.ConfigPaths != nil && cfg.ConfigPaths.ConfigDir != "" { - if err = CopyFile(backupMain, fmt.Sprintf("%s/config.yaml", cfg.ConfigPaths.ConfigDir)); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", backupMain, cfg.ConfigPaths.ConfigDir, err) - } - } - } - - // Now we have config.yaml, we should regenerate config struct to have rights paths etc - ConfigFilePath = fmt.Sprintf("%s/config.yaml", cfg.ConfigPaths.ConfigDir) - - log.Debug("Reloading configuration") - - csConfig, _, err = loadConfigFor("config") - if err != nil { - return fmt.Errorf("failed to reload configuration: %w", err) - } - - cfg = cli.cfg() - - backupCAPICreds := fmt.Sprintf("%s/online_api_credentials.yaml", dirPath) - if _, err = os.Stat(backupCAPICreds); err == nil { - if err = CopyFile(backupCAPICreds, cfg.API.Server.OnlineClient.CredentialsFilePath); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", backupCAPICreds, cfg.API.Server.OnlineClient.CredentialsFilePath, err) - } - } - - backupLAPICreds := fmt.Sprintf("%s/local_api_credentials.yaml", dirPath) - if _, err = os.Stat(backupLAPICreds); err == nil { - if err = CopyFile(backupLAPICreds, cfg.API.Client.CredentialsFilePath); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", backupLAPICreds, cfg.API.Client.CredentialsFilePath, err) - } - } - - backupProfiles := fmt.Sprintf("%s/profiles.yaml", dirPath) - if _, err = os.Stat(backupProfiles); err == nil { - if err = CopyFile(backupProfiles, cfg.API.Server.ProfilesPath); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", backupProfiles, cfg.API.Server.ProfilesPath, err) - } - } - - backupSimulation := fmt.Sprintf("%s/simulation.yaml", dirPath) - if _, err = os.Stat(backupSimulation); err == nil { - if err = CopyFile(backupSimulation, cfg.ConfigPaths.SimulationFilePath); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", backupSimulation, cfg.ConfigPaths.SimulationFilePath, err) - } - } - - /*if there is a acquisition dir, restore its content*/ - if cfg.Crowdsec.AcquisitionDirPath != "" { - if err = os.MkdirAll(cfg.Crowdsec.AcquisitionDirPath, 0o700); err != nil { - return fmt.Errorf("error while creating %s: %w", cfg.Crowdsec.AcquisitionDirPath, err) - } - } - - // if there was a single one - backupAcquisition := fmt.Sprintf("%s/acquis.yaml", dirPath) - if _, err = os.Stat(backupAcquisition); err == nil { - log.Debugf("restoring backup'ed %s", backupAcquisition) - - if err = CopyFile(backupAcquisition, cfg.Crowdsec.AcquisitionFilePath); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", backupAcquisition, cfg.Crowdsec.AcquisitionFilePath, err) - } - } - - // if there are files in the acquis backup dir, restore them - acquisBackupDir := filepath.Join(dirPath, "acquis", "*.yaml") - if acquisFiles, err := filepath.Glob(acquisBackupDir); err == nil { - for _, acquisFile := range acquisFiles { - targetFname, err := filepath.Abs(cfg.Crowdsec.AcquisitionDirPath + "/" + filepath.Base(acquisFile)) - if err != nil { - return fmt.Errorf("while saving %s to %s: %w", acquisFile, targetFname, err) - } - - log.Debugf("restoring %s to %s", acquisFile, targetFname) - - if err = CopyFile(acquisFile, targetFname); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", acquisFile, targetFname, err) - } - } - } - - if cfg.Crowdsec != nil && len(cfg.Crowdsec.AcquisitionFiles) > 0 { - for _, acquisFile := range cfg.Crowdsec.AcquisitionFiles { - log.Infof("backup filepath from dir -> %s", acquisFile) - - // if it was the default one, it has already been backed up - if cfg.Crowdsec.AcquisitionFilePath == acquisFile { - log.Infof("skip this one") - continue - } - - targetFname, err := filepath.Abs(filepath.Join(acquisBackupDir, filepath.Base(acquisFile))) - if err != nil { - return fmt.Errorf("while saving %s to %s: %w", acquisFile, acquisBackupDir, err) - } - - if err = CopyFile(acquisFile, targetFname); err != nil { - return fmt.Errorf("failed copy %s to %s: %w", acquisFile, targetFname, err) - } - - log.Infof("Saved acquis %s to %s", acquisFile, targetFname) - } - } - - if err = cli.restoreHub(ctx, dirPath); err != nil { - return fmt.Errorf("failed to restore hub config: %w", err) - } - - return nil -} - func (cli *cliConfig) newRestoreCmd() *cobra.Command { cmd := &cobra.Command{ - Use: `restore "directory"`, - Short: `Restore config in backup "directory"`, - Long: `Restore the crowdsec configuration from specified backup "directory" including: - -- Main config (config.yaml) -- Simulation config (simulation.yaml) -- Profiles config (profiles.yaml) -- List of scenarios, parsers, postoverflows and collections that are up-to-date -- Tainted/local/out-of-date scenarios, parsers, postoverflows and collections -- Backup of API credentials (local API and online API)`, - Args: cobra.ExactArgs(1), + Use: "restore", DisableAutoGenTag: true, - RunE: func(cmd *cobra.Command, args []string) error { - dirPath := args[0] - - if err := cli.restore(cmd.Context(), dirPath); err != nil { - return fmt.Errorf("failed to restore config from %s: %w", dirPath, err) - } - - return nil + RunE: func(cmd *cobra.Command, _ []string) error { + configDir := cli.cfg().ConfigPaths.ConfigDir + return fmt.Errorf("'cscli config restore' has been removed, you can manually backup/restore %s instead", configDir) }, } diff --git a/cmd/crowdsec-cli/copyfile.go b/cmd/crowdsec-cli/copyfile.go deleted file mode 100644 index 272fb3f7851..00000000000 --- a/cmd/crowdsec-cli/copyfile.go +++ /dev/null @@ -1,82 +0,0 @@ -package main - -import ( - "fmt" - "io" - "os" - "path/filepath" - - log "github.com/sirupsen/logrus" -) - -/*help to copy the file, ioutil doesn't offer the feature*/ - -func copyFileContents(src, dst string) (err error) { - in, err := os.Open(src) - if err != nil { - return - } - defer in.Close() - - out, err := os.Create(dst) - if err != nil { - return - } - - defer func() { - cerr := out.Close() - if err == nil { - err = cerr - } - }() - - if _, err = io.Copy(out, in); err != nil { - return - } - - err = out.Sync() - - return -} - -/*copy the file, ioutile doesn't offer the feature*/ -func CopyFile(sourceSymLink, destinationFile string) error { - sourceFile, err := filepath.EvalSymlinks(sourceSymLink) - if err != nil { - log.Infof("Not a symlink : %s", err) - - sourceFile = sourceSymLink - } - - sourceFileStat, err := os.Stat(sourceFile) - if err != nil { - return err - } - - if !sourceFileStat.Mode().IsRegular() { - // cannot copy non-regular files (e.g., directories, - // symlinks, devices, etc.) - return fmt.Errorf("copyFile: non-regular source file %s (%q)", sourceFileStat.Name(), sourceFileStat.Mode().String()) - } - - destinationFileStat, err := os.Stat(destinationFile) - if err != nil { - if !os.IsNotExist(err) { - return err - } - } else { - if !(destinationFileStat.Mode().IsRegular()) { - return fmt.Errorf("copyFile: non-regular destination file %s (%q)", destinationFileStat.Name(), destinationFileStat.Mode().String()) - } - - if os.SameFile(sourceFileStat, destinationFileStat) { - return err - } - } - - if err = os.Link(sourceFile, destinationFile); err != nil { - err = copyFileContents(sourceFile, destinationFile) - } - - return err -} diff --git a/debian/postinst b/debian/postinst index 77f2511f556..dd294cda8d5 100644 --- a/debian/postinst +++ b/debian/postinst @@ -11,14 +11,6 @@ if [ "$1" = configure ]; then mkdir -p /var/lib/crowdsec/data fi - if [[ -d /var/lib/crowdsec/backup ]]; then - cscli config restore /var/lib/crowdsec/backup/backup.config - rm -rf /var/lib/crowdsec/backup - /usr/bin/cscli hub update - /usr/bin/cscli hub upgrade - systemctl start crowdsec - fi - . /usr/share/crowdsec/wizard.sh -n if ! [[ -f /etc/crowdsec/acquis.yaml ]]; then echo Creating /etc/crowdsec/acquis.yaml @@ -82,12 +74,6 @@ if [ "$1" = configure ]; then set -e fi - - if [[ -f /var/lib/crowdsec/data/crowdsec.db.backup ]]; then - cp /var/lib/crowdsec/data/crowdsec.db.backup /var/lib/crowdsec/data/crowdsec.db - rm -f /var/lib/crowdsec/data/crowdsec.db.backup - fi - systemctl --quiet is-enabled crowdsec || systemctl unmask crowdsec && systemctl enable crowdsec API=$(cscli config show --key "Config.API.Server") diff --git a/debian/preinst b/debian/preinst index 217b836caa6..df5b56cef3f 100644 --- a/debian/preinst +++ b/debian/preinst @@ -5,39 +5,4 @@ set -e # Source debconf library. . /usr/share/debconf/confmodule - -OLD_MAJOR_VERSION=$(echo $2 | cut -d'.' -f1) -OLD_MINOR_VERSION=$(echo $2 | cut -d'.' -f2) -OLD_PATCH_VERSION=$(echo $2 | cut -d'.' -f3|cut -d'-' -f1) - -NEW_MAJOR_VERSION=$(echo $3 | cut -d'.' -f1) -NEW_MINOR_VERSION=$(echo $3 | cut -d'.' -f2) -NEW_PATCH_VERSION=$(echo $3 | cut -d'.' -f3|cut -d'-' -f1) - - - -if [ "$1" = upgrade ]; then - - OLD_MAJOR_VERSION=$(echo $2 | cut -d'.' -f1) - OLD_MINOR_VERSION=$(echo $2 | cut -d'.' -f2) - OLD_PATCH_VERSION=$(echo $2 | cut -d'.' -f3|cut -d'-' -f1) - - NEW_MAJOR_VERSION=$(echo $3 | cut -d'.' -f1) - NEW_MINOR_VERSION=$(echo $3 | cut -d'.' -f2) - NEW_PATCH_VERSION=$(echo $3 | cut -d'.' -f3|cut -d'-' -f1) - - - if [[ $OLD_MAJOR_VERSION -eq "1" ]] && [[ $OLD_MINOR_VERSION -eq "0" ]] && [[ $OLD_PATCH_VERSION -lt "9" ]]; then - if [[ -f /var/lib/crowdsec/data/crowdsec.db ]]; then - cp /var/lib/crowdsec/data/crowdsec.db /var/lib/crowdsec/data/crowdsec.db.backup - fi - fi - - if [[ $NEW_MAJOR_VERSION -gt $OLD_MAJOR_VERSION ]]; then - echo "Stopping crowdsec" - systemctl stop crowdsec || true - cscli config backup /var/lib/crowdsec/backup - fi -fi - echo "You can always run the configuration again interactively by using '/usr/share/crowdsec/wizard.sh -c'" diff --git a/debian/prerm b/debian/prerm index a463a6a1c80..10afcf1906d 100644 --- a/debian/prerm +++ b/debian/prerm @@ -1,9 +1,8 @@ if [ "$1" = "remove" ]; then - cscli dashboard remove -f -y --error || echo "Ignore the above error if you never installed the local dashboard." systemctl stop crowdsec systemctl disable crowdsec fi if [ "$1" = "upgrade" ]; then systemctl stop crowdsec -fi \ No newline at end of file +fi diff --git a/rpm/SPECS/crowdsec.spec b/rpm/SPECS/crowdsec.spec index ab71b650d11..f312f34eff5 100644 --- a/rpm/SPECS/crowdsec.spec +++ b/rpm/SPECS/crowdsec.spec @@ -143,18 +143,15 @@ rm -rf %{buildroot} #systemctl stop crowdsec || true -if [ $1 == 2 ];then - if [[ ! -d /var/lib/crowdsec/backup ]]; then - cscli config backup /var/lib/crowdsec/backup - fi -fi +#if [ $1 == 2 ]; then +# upgrade pre-install here +#fi %post -p /bin/bash #install if [ $1 == 1 ]; then - if [ ! -f "/var/lib/crowdsec/data/crowdsec.db" ] ; then touch /var/lib/crowdsec/data/crowdsec.db fi @@ -185,21 +182,6 @@ if [ $1 == 1 ]; then echo " * Detailed guides are available in our documentation: https://docs.crowdsec.net" echo " * Configuration items created by the community can be found at the Hub: https://hub.crowdsec.net" echo " * Gain insights into your use of CrowdSec with the help of the console https://app.crowdsec.net" - -#upgrade -elif [ $1 == 2 ] && [ -d /var/lib/crowdsec/backup ]; then - cscli config restore /var/lib/crowdsec/backup - if [ $? == 0 ]; then - rm -rf /var/lib/crowdsec/backup - fi - - if [[ -f %{_sysconfdir}/crowdsec/online_api_credentials.yaml ]] ; then - chmod 600 %{_sysconfdir}/crowdsec/online_api_credentials.yaml - fi - - if [[ -f %{_sysconfdir}/crowdsec/local_api_credentials.yaml ]] ; then - chmod 600 %{_sysconfdir}/crowdsec/local_api_credentials.yaml - fi fi %systemd_post %{name}.service diff --git a/test/bats/01_cscli.bats b/test/bats/01_cscli.bats index 264870501a5..e985d8435ab 100644 --- a/test/bats/01_cscli.bats +++ b/test/bats/01_cscli.bats @@ -172,41 +172,13 @@ teardown() { } @test "cscli config backup / restore" { - # test that we need a valid path - # disabled because in CI, the empty string is not passed as a parameter - #rune -1 cscli config backup "" - #assert_stderr --partial "failed to backup config: directory path can't be empty" + CONFIG_DIR=$(config_get '.config_paths.config_dir') rune -1 cscli config backup "/dev/null/blah" - assert_stderr --partial "failed to backup config: while creating /dev/null/blah: mkdir /dev/null/blah: not a directory" + assert_stderr --partial "'cscli config backup' has been removed, you can manually backup/restore $CONFIG_DIR instead" - # pick a dirpath - backupdir=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp -u) - - # succeed the first time - rune -0 cscli config backup "$backupdir" - assert_stderr --partial "Starting configuration backup" - - # don't overwrite an existing backup - rune -1 cscli config backup "$backupdir" - assert_stderr --partial "failed to backup config" - assert_stderr --partial "file exists" - - SIMULATION_YAML="$(config_get '.config_paths.simulation_path')" - - # restore - rm "$SIMULATION_YAML" - rune -0 cscli config restore "$backupdir" - assert_file_exists "$SIMULATION_YAML" - - # cleanup - rm -rf -- "${backupdir:?}" - - # backup: detect missing files - rm "$SIMULATION_YAML" - rune -1 cscli config backup "$backupdir" - assert_stderr --regexp "failed to backup config: failed copy .* to .*: stat .*: no such file or directory" - rm -rf -- "${backupdir:?}" + rune -1 cscli config restore "/dev/null/blah" + assert_stderr --partial "'cscli config restore' has been removed, you can manually backup/restore $CONFIG_DIR instead" } @test "'cscli completion' with or without configuration file" { diff --git a/test/bats/02_nolapi.bats b/test/bats/02_nolapi.bats index cefa6d798b4..70495a0ed91 100644 --- a/test/bats/02_nolapi.bats +++ b/test/bats/02_nolapi.bats @@ -66,18 +66,6 @@ teardown() { refute_output --partial "Local API Server" } -@test "cscli config backup" { - config_disable_lapi - backupdir=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp -u) - rune -0 cscli config backup "$backupdir" - assert_stderr --partial "Starting configuration backup" - rune -1 cscli config backup "$backupdir" - rm -rf -- "${backupdir:?}" - - assert_stderr --partial "failed to backup config" - assert_stderr --partial "file exists" -} - @test "lapi status shouldn't be ok without api.server" { config_disable_lapi rune -1 cscli machines list diff --git a/test/bats/03_noagent.bats b/test/bats/03_noagent.bats index 6be5101cee2..972b84977ad 100644 --- a/test/bats/03_noagent.bats +++ b/test/bats/03_noagent.bats @@ -60,18 +60,6 @@ teardown() { refute_output --partial "Crowdsec" } -@test "no agent: cscli config backup" { - config_disable_agent - backupdir=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp -u) - rune -0 cscli config backup "$backupdir" - assert_stderr --partial "Starting configuration backup" - rune -1 cscli config backup "$backupdir" - - assert_stderr --partial "failed to backup config" - assert_stderr --partial "file exists" - rm -rf -- "${backupdir:?}" -} - @test "no agent: lapi status should be ok" { config_disable_agent ./instance-crowdsec start diff --git a/test/bats/04_nocapi.bats b/test/bats/04_nocapi.bats index d22a6f0a953..e6cd2c28cd5 100644 --- a/test/bats/04_nocapi.bats +++ b/test/bats/04_nocapi.bats @@ -51,17 +51,6 @@ teardown() { assert_output --regexp "Global:.*Crowdsec.*cscli:.*Local API Server:" } -@test "no agent: cscli config backup" { - config_disable_capi - backupdir=$(TMPDIR="$BATS_TEST_TMPDIR" mktemp -u) - rune -0 cscli config backup "$backupdir" - assert_stderr --partial "Starting configuration backup" - rune -1 cscli config backup "$backupdir" - assert_stderr --partial "failed to backup config" - assert_stderr --partial "file exists" - rm -rf -- "${backupdir:?}" -} - @test "without capi: cscli lapi status -> success" { config_disable_capi ./instance-crowdsec start diff --git a/wizard.sh b/wizard.sh index 6e215365f6c..c3391b59c81 100755 --- a/wizard.sh +++ b/wizard.sh @@ -21,11 +21,8 @@ DOCKER_MODE="false" CROWDSEC_LIB_DIR="/var/lib/crowdsec" CROWDSEC_USR_DIR="/usr/local/lib/crowdsec" CROWDSEC_DATA_DIR="${CROWDSEC_LIB_DIR}/data" -CROWDSEC_DB_PATH="${CROWDSEC_DATA_DIR}/crowdsec.db" CROWDSEC_PATH="/etc/crowdsec" CROWDSEC_CONFIG_PATH="${CROWDSEC_PATH}" -CROWDSEC_LOG_FILE="/var/log/crowdsec.log" -LAPI_LOG_FILE="/var/log/crowdsec_api.log" CROWDSEC_PLUGIN_DIR="${CROWDSEC_USR_DIR}/plugins" CROWDSEC_CONSOLE_DIR="${CROWDSEC_PATH}/console" @@ -35,8 +32,6 @@ CSCLI_BIN="./cmd/crowdsec-cli/cscli" CLIENT_SECRETS="local_api_credentials.yaml" LAPI_SECRETS="online_api_credentials.yaml" -CONSOLE_FILE="console.yaml" - BIN_INSTALL_PATH="/usr/local/bin" CROWDSEC_BIN_INSTALLED="${BIN_INSTALL_PATH}/crowdsec" @@ -91,9 +86,6 @@ SENTINEL_PLUGIN_CONFIG="./cmd/notification-sentinel/sentinel.yaml" FILE_PLUGIN_CONFIG="./cmd/notification-file/file.yaml" -BACKUP_DIR=$(mktemp -d) -rm -rf -- "$BACKUP_DIR" - log_info() { msg=$1 date=$(date "+%Y-%m-%d %H:%M:%S") @@ -420,27 +412,20 @@ install_crowdsec() { mkdir -p "${CROWDSEC_CONFIG_PATH}/contexts" || exit mkdir -p "${CROWDSEC_CONSOLE_DIR}" || exit - # tmp - mkdir -p /tmp/data mkdir -p /etc/crowdsec/hub/ - install -v -m 600 -D "./config/${CLIENT_SECRETS}" "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - install -v -m 600 -D "./config/${LAPI_SECRETS}" "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - - ## end tmp - install -v -m 600 -D ./config/config.yaml "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - install -v -m 644 -D ./config/dev.yaml "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - install -v -m 644 -D ./config/user.yaml "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - install -v -m 644 -D ./config/acquis.yaml "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - install -v -m 644 -D ./config/profiles.yaml "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - install -v -m 644 -D ./config/simulation.yaml "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - install -v -m 644 -D ./config/"${CONSOLE_FILE}" "${CROWDSEC_CONFIG_PATH}" 1> /dev/null || exit - install -v -m 644 -D ./config/context.yaml "${CROWDSEC_CONSOLE_DIR}" 1> /dev/null || exit + # Don't overwrite existing files + [[ ! -f "${CROWDSEC_CONFIG_PATH}/${CLIENT_SECRETS}" ]] && install -v -m 600 -D "./config/${CLIENT_SECRETS}" "${CROWDSEC_CONFIG_PATH}" >/dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/${LAPI_SECRETS}" ]] && install -v -m 600 -D "./config/${LAPI_SECRETS}" "${CROWDSEC_CONFIG_PATH}" > /dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/config.yaml" ]] && install -v -m 600 -D ./config/config.yaml "${CROWDSEC_CONFIG_PATH}" > /dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/dev.yaml" ]] && install -v -m 644 -D ./config/dev.yaml "${CROWDSEC_CONFIG_PATH}" > /dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/user.yaml" ]] && install -v -m 644 -D ./config/user.yaml "${CROWDSEC_CONFIG_PATH}" > /dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/acquis.yaml" ]] && install -v -m 644 -D ./config/acquis.yaml "${CROWDSEC_CONFIG_PATH}" > /dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/profiles.yaml" ]] && install -v -m 644 -D ./config/profiles.yaml "${CROWDSEC_CONFIG_PATH}" > /dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/simulation.yaml" ]] && install -v -m 644 -D ./config/simulation.yaml "${CROWDSEC_CONFIG_PATH}" > /dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/console.yaml" ]] && install -v -m 644 -D ./config/console.yaml "${CROWDSEC_CONFIG_PATH}" > /dev/null || exit + [[ ! -f "${CROWDSEC_CONFIG_PATH}/context.yaml" ]] && install -v -m 644 -D ./config/context.yaml "${CROWDSEC_CONSOLE_DIR}" > /dev/null || exit - DATA=${CROWDSEC_DATA_DIR} CFG=${CROWDSEC_CONFIG_PATH} envsubst '$CFG $DATA' < ./config/user.yaml > ${CROWDSEC_CONFIG_PATH}"/user.yaml" || log_fatal "unable to generate user configuration file" - if [[ ${DOCKER_MODE} == "false" ]]; then - CFG=${CROWDSEC_CONFIG_PATH} BIN=${CROWDSEC_BIN_INSTALLED} envsubst '$CFG $BIN' < ./config/crowdsec.service > "${SYSTEMD_PATH_FILE}" || log_fatal "unable to crowdsec systemd file" - fi install_bins if [[ ${DOCKER_MODE} == "false" ]]; then @@ -465,23 +450,12 @@ update_full() { log_err "Cscli binary '$CSCLI_BIN' not found. Please build it with 'make build'" && exit fi - log_info "Backing up existing configuration" - ${CSCLI_BIN_INSTALLED} config backup ${BACKUP_DIR} - log_info "Saving default database content if exist" - if [[ -f "/var/lib/crowdsec/data/crowdsec.db" ]]; then - cp /var/lib/crowdsec/data/crowdsec.db ${BACKUP_DIR}/crowdsec.db - fi - log_info "Cleanup existing crowdsec configuration" + log_info "Removing old binaries" uninstall_crowdsec log_info "Installing crowdsec" install_crowdsec - log_info "Restoring configuration" + log_info "Updating hub" ${CSCLI_BIN_INSTALLED} hub update - ${CSCLI_BIN_INSTALLED} config restore ${BACKUP_DIR} - log_info "Restoring saved database if exist" - if [[ -f "${BACKUP_DIR}/crowdsec.db" ]]; then - cp ${BACKUP_DIR}/crowdsec.db /var/lib/crowdsec/data/crowdsec.db - fi log_info "Finished, restarting" systemctl restart crowdsec || log_fatal "Failed to restart crowdsec" } @@ -559,15 +533,6 @@ uninstall_crowdsec() { ${CSCLI_BIN} dashboard remove -f -y >/dev/null delete_bins - # tmp - rm -rf /tmp/data/ - ## end tmp - - find /etc/crowdsec -maxdepth 1 -mindepth 1 | grep -v "bouncer" | xargs rm -rf || echo "" - rm -f ${CROWDSEC_LOG_FILE} || echo "" - rm -f ${LAPI_LOG_FILE} || echo "" - rm -f ${CROWDSEC_DB_PATH} || echo "" - rm -rf ${CROWDSEC_LIB_DIR} || echo "" rm -rf ${CROWDSEC_USR_DIR} || echo "" rm -f ${SYSTEMD_PATH_FILE} || echo "" log_info "crowdsec successfully uninstalled" @@ -759,12 +724,11 @@ usage() { echo " ./wizard.sh --unattended Install in unattended mode, no question will be asked and defaults will be followed" echo " ./wizard.sh --docker-mode Will install crowdsec without systemd and generate random machine-id" echo " ./wizard.sh -n|--noop Do nothing" - - exit 0 } if [[ $# -eq 0 ]]; then -usage + usage + exit 0 fi while [[ $# -gt 0 ]]