Skip to content

Commit

Permalink
Added rbd configure cmd
Browse files Browse the repository at this point in the history
Signed-off-by: Utkarsh Bhatt <[email protected]>
  • Loading branch information
UtkarshBhatthere committed Sep 5, 2024
1 parent 31c08da commit acf4b68
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 5 deletions.
108 changes: 107 additions & 1 deletion microceph/ceph/rbd_mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const (
RbdMirrorEnableCommand RbdMirrorCommand = "enable"
)

type imageSnapshotSchedule struct {
Schedule string `json:"interval" yaml:"interval"`
StartTime string `json:"start_time" yaml:"start_time"`
}

// Ceph Commands

// GetRbdMirrorPoolInfo fetches the mirroring info for the requested pool
Expand Down Expand Up @@ -94,6 +99,9 @@ func GetRbdMirrorVerbosePoolStatus(pool string, cluster string, client string) (
return RbdReplicationVerbosePoolStatus{Summary: RbdReplicationPoolStatus{State: StateDisabledReplication}}, nil
}

// TODO: Make this print debug.
logger.Infof("REPRBD: Raw Pool Verbose Status: %s", output)

err = yaml.Unmarshal([]byte(output), &response)
if err != nil {
ne := fmt.Errorf("cannot unmarshal rbd response: %v", err)
Expand Down Expand Up @@ -259,7 +267,11 @@ func configurePoolMirroring(pool string, mode types.RbdResourceType, localName s
}

// configureImageMirroring disables or enables image mirroring in requested mode.
func configureImageMirroring(pool string, image string, mode types.RbdReplicationType) error {
func configureImageMirroring(req types.RbdReplicationRequest) error {
pool := req.SourcePool
image := req.SourceImage
mode := req.ReplicationType
schedule := req.Schedule
var args []string

if mode == types.RbdReplicationDisabled {
Expand All @@ -273,6 +285,100 @@ func configureImageMirroring(pool string, image string, mode types.RbdReplicatio
return fmt.Errorf("failed to configure rbd image feature: %v", err)
}

if mode == types.RbdReplicationSnapshot {
err = createSnapshot(pool, image)
if err != nil {
return fmt.Errorf("failed to create image(%s/%s) snapshot : %v", pool, image, err)
}

err = configureSnapshotSchedule(pool, image, schedule, "")
if err != nil {
return fmt.Errorf("failed to create image(%s/%s) snapshot schedule(%s) : %v", pool, image, schedule, err)
}
}

return nil
}

func getSnapshotSchedule(pool string, image string) (imageSnapshotSchedule, error) {
if len(pool) == 0 || len(image) == 0 {
return imageSnapshotSchedule{}, fmt.Errorf("ImageName(%s/%s) not complete", pool, image)
}

output, err := listSnapshotSchedule(pool, image)
if err != nil {
return imageSnapshotSchedule{}, err
}

ret := []imageSnapshotSchedule{}
err = json.Unmarshal(output, &ret)
if err != nil {
return imageSnapshotSchedule{}, nil
}

return ret[0], nil
}

func listSnapshotSchedule(pool string, image string) ([]byte, error) {
args := []string{"mirror", "snapshot", "schedule", "list"}

if len(pool) != 0 {
args = append(args, "--pool")
args = append(args, pool)
}

if len(image) != 0 {
args = append(args, "--image")
args = append(args, image)
}

output, err := processExec.RunCommand("rbd", args...)
if err != nil {
return []byte(""), err
}

return []byte(output), nil
}

func configureSnapshotSchedule(pool string, image string, schedule string, startTime string) error {
var args []string
if len(schedule) == 0 {
args = []string{"mirror", "snapshot", "schedule", "rm", "--pool", pool}
} else {
args = []string{"mirror", "snapshot", "schedule", "add", "--pool", pool}
}

if len(image) != 0 {
args = append(args, "--image")
args = append(args, image)
}

if len(schedule) != 0 {
args = append(args, schedule)

// Also add start-time param if provided.
if len(startTime) != 0 {
args = append(args, startTime)
}
}

_, err := processExec.RunCommand("rbd", args...)
if err != nil {
return err
}

return nil
}

// createSnapshot creates a snapshot of the requested image
func createSnapshot(pool string, image string) error {
args := []string{"mirror", "image", "snapshot", fmt.Sprintf("%s/%s", pool, image)}

_, err := processExec.RunCommand("rbd", args...)
if err != nil {
return err
}

return nil
}

Expand Down
28 changes: 25 additions & 3 deletions microceph/ceph/replication_rbd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/canonical/lxd/shared/logger"
"github.com/canonical/microceph/microceph/api/types"
"github.com/canonical/microceph/microceph/constants"
"github.com/canonical/microceph/microceph/database"
"github.com/canonical/microceph/microceph/interfaces"
)
Expand Down Expand Up @@ -152,7 +153,20 @@ func (rh *RbdReplicationHandler) DisableHandler(ctx context.Context, args ...any

// ConfigureHandler configures replication properties for requested rbd pool/image.
func (rh *RbdReplicationHandler) ConfigureHandler(ctx context.Context, args ...any) error {
// TODO: Implement Configure Handler
if rh.Request.Schedule == constants.DisableSnapshotSchedule {
return configureSnapshotSchedule(rh.Request.SourcePool, rh.Request.SourceImage, "", "")
}

schedule, err := getSnapshotSchedule(rh.Request.SourcePool, rh.Request.SourceImage)
if err != nil {
return err
}

if rh.Request.Schedule != schedule.Schedule {
return configureSnapshotSchedule(rh.Request.SourcePool, rh.Request.SourceImage, rh.Request.Schedule, "")
}

// no change
return nil
}

Expand All @@ -161,6 +175,9 @@ func (rh *RbdReplicationHandler) ListHandler(ctx context.Context, args ...any) e
// fetch all ceph pools
pools := ListPools()

// TODO: make this print debug
logger.Infof("REPRBD: Scan active pools %v", pools)

// fetch verbose pool status for each pool
statusList := []RbdReplicationVerbosePoolStatus{}
for _, pool := range pools {
Expand All @@ -180,6 +197,9 @@ func (rh *RbdReplicationHandler) ListHandler(ctx context.Context, args ...any) e
statusList = append(statusList, poolStatus)
}

// TODO: Make this print debug.
logger.Infof("REPRBD: List Verbose Pool status: %v", statusList)

resp, err := json.Marshal(statusList)
if err != nil {
return fmt.Errorf("failed to marshal response(%v): %v", statusList, err)
Expand Down Expand Up @@ -241,7 +261,7 @@ func handleImageEnablement(rh *RbdReplicationHandler, localSite string, remoteSi
}

// pool in Image mode, Enable Image in requested mode.
return configureImageMirroring(rh.Request.SourcePool, rh.Request.SourceImage, rh.Request.ReplicationType)
return configureImageMirroring(rh.Request)
}

// Disable handler for pool resource.
Expand Down Expand Up @@ -283,5 +303,7 @@ func handleImageDisablement(rh *RbdReplicationHandler) error {
return configureImageFeatures(rh.Request.SourcePool, rh.Request.SourceImage, "disable", "journaling")
}

return configureImageMirroring(rh.Request.SourcePool, rh.Request.SourceImage, types.RbdReplicationDisabled)
// patch replication type
rh.Request.ReplicationType = types.RbdReplicationDisabled
return configureImageMirroring(rh.Request)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (c *cmdRemoteReplicationConfigureRbd) Command() *cobra.Command {
cmd.Flags().StringVar(&c.poolName, "pool", "", "RBD pool name")
cmd.MarkFlagRequired("pool")
cmd.Flags().StringVar(&c.imageName, "image", "", "RBD image name")
cmd.Flags().StringVar(&c.schedule, "snapshot-schedule", "", "snapshot schedule in days, hours, or minutes using d, h, m suffix respectively")
cmd.Flags().StringVar(&c.schedule, "schedule", "", "snapshot schedule in days, hours, or minutes using d, h, m suffix respectively")
return cmd
}

Expand Down
3 changes: 3 additions & 0 deletions microceph/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ func GetPathFileMode() PathFileMode {
// Regexes
const ClusterNameRegex = "^[a-z0-9]+$"

// Snapshot schedule special constants
const DisableSnapshotSchedule = "\\0"

// Replication Events
const EventEnableReplication = "enable_replication"
const EventDisableReplication = "disable_replication"
Expand Down

0 comments on commit acf4b68

Please sign in to comment.