From d4bad2742d0ca17af8af0179f8f312215f66fa81 Mon Sep 17 00:00:00 2001 From: Troy Partridge Date: Tue, 26 Nov 2024 06:40:27 -0800 Subject: [PATCH] core: fix purge_osd command for multiple OSD IDs Updating the command pre run to parse the comma separated list of OSD IDs Signed-off-by: Troy Partridge --- cmd/commands/rook.go | 23 +++++++++++++---------- docs/rook.md | 4 ++-- pkg/rook/purge_osd.go | 6 +++--- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/cmd/commands/rook.go b/cmd/commands/rook.go index 894a0c75..aead3314 100644 --- a/cmd/commands/rook.go +++ b/cmd/commands/rook.go @@ -19,6 +19,7 @@ package command import ( "fmt" "strconv" + "strings" "github.com/rook/kubectl-rook-ceph/pkg/exec" "github.com/rook/kubectl-rook-ceph/pkg/logging" @@ -47,8 +48,8 @@ var versionCmd = &cobra.Command{ var purgeCmd = &cobra.Command{ Use: "purge-osd", - Short: "Permanently remove an OSD from the cluster. Multiple OSDs can be removed with a comma-separated list of IDs, for example, purge-osd 0,1", - PreRunE: validateOsdID, + Short: "Permanently remove an OSD from the cluster. Multiple OSDs can be removed in a single command with a comma-separated list of IDs, for example, purge-osd 0,1", + PreRunE: validateOsdIDs, Args: cobra.ExactArgs(1), Example: "kubectl rook-ceph rook purge-osd ", PreRun: func(cmd *cobra.Command, args []string) { @@ -56,8 +57,8 @@ var purgeCmd = &cobra.Command{ }, Run: func(cmd *cobra.Command, args []string) { forceflagValue := cmd.Flag("force").Value.String() - osdID := args[0] - rook.PurgeOsd(cmd.Context(), clientSets, operatorNamespace, cephClusterNamespace, osdID, forceflagValue) + osdIDs := args[0] + rook.PurgeOsds(cmd.Context(), clientSets, operatorNamespace, cephClusterNamespace, osdIDs, forceflagValue) }, } @@ -76,14 +77,16 @@ func init() { RookCmd.AddCommand(statusCmd) RookCmd.AddCommand(purgeCmd) statusCmd.PersistentFlags().Bool("json", false, "print status in json format") - purgeCmd.PersistentFlags().Bool("force", false, "force deletion of an OSD if the OSD still contains data") + purgeCmd.PersistentFlags().Bool("force", false, "force deletion of OSD(s) with the risk that they could still contains data") } -func validateOsdID(cmd *cobra.Command, args []string) error { - osdID := args[0] - _, err := strconv.Atoi(osdID) - if err != nil { - return fmt.Errorf("invalid ID %s, the OSD ID must be an integer. %v", osdID, err) +func validateOsdIDs(cmd *cobra.Command, args []string) error { + osdIDs := strings.Split(args[0], ",") + for _, osdID := range osdIDs { + _, err := strconv.Atoi(osdID) + if err != nil { + return fmt.Errorf("invalid ID %s, the OSD ID must be an integer. %v", osdID, err) + } } return nil diff --git a/docs/rook.md b/docs/rook.md index 5384843b..25a17563 100644 --- a/docs/rook.md +++ b/docs/rook.md @@ -8,9 +8,9 @@ The `rook` command supports the following sub-commands: 4. `status all`: [status all](#status-all) print the phase and conditions of all CRs 5. `status `: [status cr](#status-cr-name) print the phase and conditions of CRs of a specific type, such as 'cephobjectstore', 'cephfilesystem', etc -## Purge an OSD +## Purge OSDs -Permanently remove an OSD from the cluster. +Permanently remove OSD(s) from the cluster. !!! warning Data loss is possible when passing the --force flag if the PGs are not healthy on other OSDs. diff --git a/pkg/rook/purge_osd.go b/pkg/rook/purge_osd.go index 391b1287..596417f0 100644 --- a/pkg/rook/purge_osd.go +++ b/pkg/rook/purge_osd.go @@ -28,7 +28,7 @@ import ( v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func PurgeOsd(ctx context.Context, clientsets *k8sutil.Clientsets, operatorNamespace, clusterNamespace, osdId, flag string) { +func PurgeOsds(ctx context.Context, clientsets *k8sutil.Clientsets, operatorNamespace, clusterNamespace, osdIds, flag string) { monCm, err := clientsets.Kube.CoreV1().ConfigMaps(clusterNamespace).Get(ctx, mons.MonConfigMap, v1.GetOptions{}) if err != nil { logging.Fatal(fmt.Errorf("failed to get mon configmap %s %v", mons.MonConfigMap, err)) @@ -47,12 +47,12 @@ func PurgeOsd(ctx context.Context, clientsets *k8sutil.Clientsets, operatorNames cmd := "/bin/sh" args := []string{ "-c", - fmt.Sprintf("export ROOK_MON_ENDPOINTS=%s ROOK_CEPH_USERNAME=client.admin ROOK_CEPH_SECRET=%s ROOK_CONFIG_DIR=/var/lib/rook && rook ceph osd remove --osd-ids=%s --force-osd-removal=%s", monEndPoint, adminKey, osdId, flag), + fmt.Sprintf("export ROOK_MON_ENDPOINTS=%s ROOK_CEPH_USERNAME=client.admin ROOK_CEPH_SECRET=%s ROOK_CONFIG_DIR=/var/lib/rook && rook ceph osd remove --osd-ids=%s --force-osd-removal=%s", monEndPoint, adminKey, osdIds, flag), } logging.Info("Running purge osd command") _, err = exec.RunCommandInOperatorPod(ctx, clientsets, cmd, args, operatorNamespace, clusterNamespace, false) if err != nil { - logging.Fatal(err, "failed to remove osd %s", osdId) + logging.Fatal(err, "failed to remove osd %s", osdIds) } }