From 7ba6718263fc9f9ec6ff4b74454d0a6339eebaea Mon Sep 17 00:00:00 2001 From: BarkovBG Date: Thu, 15 Aug 2024 20:09:58 +0300 Subject: [PATCH] [Disk Manager] add release base disk cmd to admin tool (#1799) * add release base disk cmd to admin tool * resolve issues * fix build * fix issues --- .../internal/api/private_service.proto | 6 ++ .../internal/pkg/client/client.go | 13 ++++ .../internal/pkg/facade/private_service.go | 21 ++++++ cloud/disk_manager/pkg/admin/common.go | 4 +- cloud/disk_manager/pkg/admin/disks.go | 2 +- cloud/disk_manager/pkg/admin/filesystem.go | 2 +- cloud/disk_manager/pkg/admin/images.go | 2 +- cloud/disk_manager/pkg/admin/private.go | 74 +++++++++++++++++++ cloud/disk_manager/pkg/admin/snapshots.go | 2 +- 9 files changed, 120 insertions(+), 6 deletions(-) diff --git a/cloud/disk_manager/internal/api/private_service.proto b/cloud/disk_manager/internal/api/private_service.proto index 64a83e4a322..bff5cf402ad 100644 --- a/cloud/disk_manager/internal/api/private_service.proto +++ b/cloud/disk_manager/internal/api/private_service.proto @@ -13,6 +13,8 @@ service PrivateService { // Schedules blank (no op) operation, used for testing. rpc ScheduleBlankOperation(google.protobuf.Empty) returns (cloud.disk_manager.Operation); + rpc ReleaseBaseDisk(ReleaseBaseDiskRequest) returns (cloud.disk_manager.Operation); + rpc RebaseOverlayDisk(RebaseOverlayDiskRequest) returns (cloud.disk_manager.Operation); rpc RetireBaseDisk(RetireBaseDiskRequest) returns (cloud.disk_manager.Operation); @@ -50,6 +52,10 @@ service PrivateService { rpc GetAliveNodes(google.protobuf.Empty) returns (GetAliveNodesResponse); } +message ReleaseBaseDiskRequest { + cloud.disk_manager.DiskId disk_id = 1; +} + message RebaseOverlayDiskRequest { cloud.disk_manager.DiskId disk_id = 1; string base_disk_id = 4; diff --git a/cloud/disk_manager/internal/pkg/client/client.go b/cloud/disk_manager/internal/pkg/client/client.go index d907c3cdfa8..3ece160b298 100644 --- a/cloud/disk_manager/internal/pkg/client/client.go +++ b/cloud/disk_manager/internal/pkg/client/client.go @@ -163,6 +163,11 @@ type PrivateClient interface { // Used for testing. ScheduleBlankOperation(ctx context.Context) (*disk_manager.Operation, error) + ReleaseBaseDisk( + ctx context.Context, + req *api.ReleaseBaseDiskRequest, + ) (*disk_manager.Operation, error) + RebaseOverlayDisk( ctx context.Context, req *api.RebaseOverlayDiskRequest, @@ -269,6 +274,14 @@ func (c *privateClient) ScheduleBlankOperation( return c.privateServiceClient.ScheduleBlankOperation(ctx, &empty.Empty{}) } +func (c *privateClient) ReleaseBaseDisk( + ctx context.Context, + req *api.ReleaseBaseDiskRequest, +) (*disk_manager.Operation, error) { + + return c.privateServiceClient.ReleaseBaseDisk(ctx, req) +} + func (c *privateClient) RebaseOverlayDisk( ctx context.Context, req *api.RebaseOverlayDiskRequest, diff --git a/cloud/disk_manager/internal/pkg/facade/private_service.go b/cloud/disk_manager/internal/pkg/facade/private_service.go index 76a08984fc7..475338c2f57 100644 --- a/cloud/disk_manager/internal/pkg/facade/private_service.go +++ b/cloud/disk_manager/internal/pkg/facade/private_service.go @@ -42,6 +42,27 @@ func (s *privateService) ScheduleBlankOperation( return getOperation(ctx, s.taskScheduler, taskID) } +func (s *privateService) ReleaseBaseDisk( + ctx context.Context, + req *api.ReleaseBaseDiskRequest, +) (*disk_manager.Operation, error) { + + taskID, err := s.poolService.ReleaseBaseDisk( + ctx, + &pools_protos.ReleaseBaseDiskRequest{ + OverlayDisk: &types.Disk{ + ZoneId: req.DiskId.ZoneId, + DiskId: req.DiskId.DiskId, + }, + }, + ) + if err != nil { + return nil, err + } + + return getOperation(ctx, s.taskScheduler, taskID) +} + func (s *privateService) RebaseOverlayDisk( ctx context.Context, req *api.RebaseOverlayDiskRequest, diff --git a/cloud/disk_manager/pkg/admin/common.go b/cloud/disk_manager/pkg/admin/common.go index 787c5fa18d9..921cf59df8f 100644 --- a/cloud/disk_manager/pkg/admin/common.go +++ b/cloud/disk_manager/pkg/admin/common.go @@ -67,8 +67,8 @@ func getRequestContext(ctx context.Context) context.Context { return ctx } -func requestDeletionConfirmation(objectType string, objectID string) error { - log.Printf("confirm destruction by typing %s id to stdin", objectType) +func requestConfirmation(objectType string, objectID string) error { + log.Printf("confirm command by typing %s id to stdin", objectType) scanner := bufio.NewScanner(os.Stdin) scanner.Scan() if scanner.Text() != objectID { diff --git a/cloud/disk_manager/pkg/admin/disks.go b/cloud/disk_manager/pkg/admin/disks.go index b0e330f6e3b..592c6a95ac7 100644 --- a/cloud/disk_manager/pkg/admin/disks.go +++ b/cloud/disk_manager/pkg/admin/disks.go @@ -328,7 +328,7 @@ type deleteDisk struct { func (c *deleteDisk) run() error { ctx := newContext(c.clientConfig) - err := requestDeletionConfirmation("disk", c.diskID) + err := requestConfirmation("disk", c.diskID) if err != nil { return err } diff --git a/cloud/disk_manager/pkg/admin/filesystem.go b/cloud/disk_manager/pkg/admin/filesystem.go index 43d4564d038..5b69180485c 100644 --- a/cloud/disk_manager/pkg/admin/filesystem.go +++ b/cloud/disk_manager/pkg/admin/filesystem.go @@ -219,7 +219,7 @@ type deleteFilesystem struct { func (c *deleteFilesystem) run() error { ctx := newContext(c.clientConfig) - err := requestDeletionConfirmation("filesystem", c.filesystemID) + err := requestConfirmation("filesystem", c.filesystemID) if err != nil { return err } diff --git a/cloud/disk_manager/pkg/admin/images.go b/cloud/disk_manager/pkg/admin/images.go index 2d8935ae748..fe09080e7c1 100644 --- a/cloud/disk_manager/pkg/admin/images.go +++ b/cloud/disk_manager/pkg/admin/images.go @@ -231,7 +231,7 @@ type deleteImage struct { func (c *deleteImage) run() error { ctx := newContext(c.clientConfig) - err := requestDeletionConfirmation("image", c.imageID) + err := requestConfirmation("image", c.imageID) if err != nil { return err } diff --git a/cloud/disk_manager/pkg/admin/private.go b/cloud/disk_manager/pkg/admin/private.go index a0afad0537c..322c60ed282 100644 --- a/cloud/disk_manager/pkg/admin/private.go +++ b/cloud/disk_manager/pkg/admin/private.go @@ -106,6 +106,80 @@ func newRebaseOverlayDiskCmd(config *client_config.ClientConfig) *cobra.Command //////////////////////////////////////////////////////////////////////////////// +type releaseBaseDisk struct { + config *client_config.ClientConfig + zoneID string + overlayDiskID string +} + +func (c *releaseBaseDisk) run() error { + ctx := newContext(c.config) + + err := requestConfirmation("overlay disk", c.overlayDiskID) + if err != nil { + return err + } + + client, err := internal_client.NewPrivateClientForCLI(ctx, c.config) + if err != nil { + return fmt.Errorf("failed to create client: %w", err) + } + defer client.Close() + + req := &api.ReleaseBaseDiskRequest{ + DiskId: &disk_manager.DiskId{ + ZoneId: c.zoneID, + DiskId: c.overlayDiskID, + }, + } + + resp, err := client.ReleaseBaseDisk(getRequestContext(ctx), req) + if err != nil { + return err + } + + fmt.Printf("Operation: %v\n", resp.Id) + + return internal_client.WaitOperation(ctx, client, resp.Id) +} + +func newReleaseBaseDiskCmd(config *client_config.ClientConfig) *cobra.Command { + c := &releaseBaseDisk{ + config: config, + } + + cmd := &cobra.Command{ + Use: "release_base_disk", + RunE: func(cmd *cobra.Command, args []string) error { + return c.run() + }, + } + + cmd.Flags().StringVar( + &c.zoneID, + "zone-id", + "", + "overlay disk zone ID where disk is located; required", + ) + if err := cmd.MarkFlagRequired("zone-id"); err != nil { + log.Fatalf("Error setting flag zone-id as required: %v", err) + } + + cmd.Flags().StringVar( + &c.overlayDiskID, + "overlay-disk-id", + "", + "overlay disk ID; required", + ) + if err := cmd.MarkFlagRequired("overlay-disk-id"); err != nil { + log.Fatalf("Error setting flag overlay-disk-id as required: %v", err) + } + + return cmd +} + +//////////////////////////////////////////////////////////////////////////////// + type retireBaseDisk struct { config *client_config.ClientConfig baseDiskID string diff --git a/cloud/disk_manager/pkg/admin/snapshots.go b/cloud/disk_manager/pkg/admin/snapshots.go index c0b925c4027..e65c43cb68b 100644 --- a/cloud/disk_manager/pkg/admin/snapshots.go +++ b/cloud/disk_manager/pkg/admin/snapshots.go @@ -207,7 +207,7 @@ type deleteSnapshot struct { func (c *deleteSnapshot) run() error { ctx := newContext(c.clientConfig) - err := requestDeletionConfirmation("snapshot", c.snapshotID) + err := requestConfirmation("snapshot", c.snapshotID) if err != nil { return err }