mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 11:00:25 +00:00
rbd: Add new methods to generate spec strings
Refactor lots of string concatenation using the Stringer implementation for each type. Signed-off-by: Mehdy Khoshnoody <mehdy.khoshnoody@gmail.com>
This commit is contained in:
parent
ed30fa19d4
commit
c0361c47d6
@ -231,10 +231,10 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
|
|||||||
err = rbdVol.ensureEncryptionMetadataSet(rbdImageRequiresEncryption)
|
err = rbdVol.ensureEncryptionMetadataSet(rbdImageRequiresEncryption)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to save encryption status, deleting image %s: %s"),
|
klog.Errorf(util.Log(ctx, "failed to save encryption status, deleting image %s: %s"),
|
||||||
rbdVol.RbdImageName, err)
|
rbdVol, err)
|
||||||
if deleteErr := deleteImage(ctx, rbdVol, cr); deleteErr != nil {
|
if deleteErr := deleteImage(ctx, rbdVol, cr); deleteErr != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s/%s with error: %v"),
|
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s with error: %v"),
|
||||||
rbdVol.Pool, rbdVol.RbdImageName, deleteErr)
|
rbdVol, deleteErr)
|
||||||
return nil, deleteErr
|
return nil, deleteErr
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -452,8 +452,8 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
|
|||||||
// Deleting rbd image
|
// Deleting rbd image
|
||||||
klog.V(4).Infof(util.Log(ctx, "deleting image %s"), rbdVol.RbdImageName)
|
klog.V(4).Infof(util.Log(ctx, "deleting image %s"), rbdVol.RbdImageName)
|
||||||
if err = deleteImage(ctx, rbdVol, cr); err != nil {
|
if err = deleteImage(ctx, rbdVol, cr); err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s/%s with error: %v"),
|
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s with error: %v"),
|
||||||
rbdVol.Pool, rbdVol.RbdImageName, err)
|
rbdVol, err)
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,16 +740,15 @@ func (cs *ControllerServer) DeleteSnapshot(ctx context.Context, req *csi.DeleteS
|
|||||||
err = unprotectSnapshot(ctx, rbdSnap, cr)
|
err = unprotectSnapshot(ctx, rbdSnap, cr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.FailedPrecondition,
|
return nil, status.Errorf(codes.FailedPrecondition,
|
||||||
"failed to unprotect snapshot: %s/%s with error: %v",
|
"failed to unprotect snapshot: %s with error: %v",
|
||||||
rbdSnap.Pool, rbdSnap.RbdSnapName, err)
|
rbdSnap, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deleting snapshot
|
// Deleting snapshot
|
||||||
klog.V(4).Infof(util.Log(ctx, "deleting Snaphot %s"), rbdSnap.RbdSnapName)
|
klog.V(4).Infof(util.Log(ctx, "deleting Snaphot %s"), rbdSnap)
|
||||||
if err := deleteSnapshot(ctx, rbdSnap, cr); err != nil {
|
if err := deleteSnapshot(ctx, rbdSnap, cr); err != nil {
|
||||||
return nil, status.Errorf(codes.FailedPrecondition,
|
return nil, status.Errorf(codes.FailedPrecondition,
|
||||||
"failed to delete snapshot: %s/%s with error: %v",
|
"failed to delete snapshot: %s with error: %v", rbdSnap, err)
|
||||||
rbdSnap.Pool, rbdSnap.RbdSnapName, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &csi.DeleteSnapshotResponse{}, nil
|
return &csi.DeleteSnapshotResponse{}, nil
|
||||||
@ -801,8 +800,8 @@ func (cs *ControllerServer) ControllerExpandVolume(ctx context.Context, req *csi
|
|||||||
defer rbdVol.Destroy()
|
defer rbdVol.Destroy()
|
||||||
|
|
||||||
if rbdVol.Encrypted {
|
if rbdVol.Encrypted {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "encrypted volumes do not support resize (%s/%s)",
|
return nil, status.Errorf(codes.InvalidArgument, "encrypted volumes do not support resize (%s)",
|
||||||
rbdVol.Pool, rbdVol.RbdImageName)
|
rbdVol)
|
||||||
}
|
}
|
||||||
|
|
||||||
// always round up the request size in bytes to the nearest MiB/GiB
|
// always round up the request size in bytes to the nearest MiB/GiB
|
||||||
@ -811,12 +810,12 @@ func (cs *ControllerServer) ControllerExpandVolume(ctx context.Context, req *csi
|
|||||||
// resize volume if required
|
// resize volume if required
|
||||||
nodeExpansion := false
|
nodeExpansion := false
|
||||||
if rbdVol.VolSize < volSize {
|
if rbdVol.VolSize < volSize {
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd volume %s/%s size is %v,resizing to %v"), rbdVol.Pool, rbdVol.RbdImageName, rbdVol.VolSize, volSize)
|
klog.V(4).Infof(util.Log(ctx, "rbd volume %s size is %v,resizing to %v"), rbdVol, rbdVol.VolSize, volSize)
|
||||||
rbdVol.VolSize = volSize
|
rbdVol.VolSize = volSize
|
||||||
nodeExpansion = true
|
nodeExpansion = true
|
||||||
err = resizeRBDImage(rbdVol, cr)
|
err = resizeRBDImage(rbdVol, cr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to resize rbd image: %s/%s with error: %v"), rbdVol.Pool, rbdVol.RbdImageName, err)
|
klog.Errorf(util.Log(ctx, "failed to resize rbd image: %s with error: %v"), rbdVol, err)
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,7 +623,7 @@ func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unmapping rbd device
|
// Unmapping rbd device
|
||||||
imageSpec := imgInfo.Pool + "/" + imgInfo.ImageName
|
imageSpec := imgInfo.String()
|
||||||
if err = detachRBDImageOrDeviceSpec(ctx, imageSpec, true, imgInfo.NbdAccess, imgInfo.Encrypted, req.GetVolumeId()); err != nil {
|
if err = detachRBDImageOrDeviceSpec(ctx, imageSpec, true, imgInfo.NbdAccess, imgInfo.Encrypted, req.GetVolumeId()); err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "error unmapping volume (%s) from staging path (%s): (%v)"), req.GetVolumeId(), stagingTargetPath, err)
|
klog.Errorf(util.Log(ctx, "error unmapping volume (%s) from staging path (%s): (%v)"), req.GetVolumeId(), stagingTargetPath, err)
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
@ -730,7 +730,7 @@ func (ns *NodeServer) NodeGetCapabilities(ctx context.Context, req *csi.NodeGetC
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NodeServer) processEncryptedDevice(ctx context.Context, volOptions *rbdVolume, devicePath string) (string, error) {
|
func (ns *NodeServer) processEncryptedDevice(ctx context.Context, volOptions *rbdVolume, devicePath string) (string, error) {
|
||||||
imageSpec := volOptions.Pool + "/" + volOptions.RbdImageName
|
imageSpec := volOptions.String()
|
||||||
encrypted, err := volOptions.checkRbdImageEncrypted(ctx)
|
encrypted, err := volOptions.checkRbdImageEncrypted(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to get encryption status for rbd image %s: %v"),
|
klog.Errorf(util.Log(ctx, "failed to get encryption status for rbd image %s: %v"),
|
||||||
@ -780,13 +780,13 @@ func (ns *NodeServer) processEncryptedDevice(ctx context.Context, volOptions *rb
|
|||||||
func encryptDevice(ctx context.Context, rbdVol *rbdVolume, devicePath string) error {
|
func encryptDevice(ctx context.Context, rbdVol *rbdVolume, devicePath string) error {
|
||||||
passphrase, err := util.GetCryptoPassphrase(ctx, rbdVol.VolID, rbdVol.KMS)
|
passphrase, err := util.GetCryptoPassphrase(ctx, rbdVol.VolID, rbdVol.KMS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to get crypto passphrase for %s/%s: %v"),
|
klog.Errorf(util.Log(ctx, "failed to get crypto passphrase for %s: %v"),
|
||||||
rbdVol.Pool, rbdVol.RbdImageName, err)
|
rbdVol, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = util.EncryptVolume(ctx, devicePath, passphrase); err != nil {
|
if err = util.EncryptVolume(ctx, devicePath, passphrase); err != nil {
|
||||||
err = fmt.Errorf("failed to encrypt volume %s/%s: %v", rbdVol.Pool, rbdVol.RbdImageName, err)
|
err = fmt.Errorf("failed to encrypt volume %s: %v", rbdVol, err)
|
||||||
klog.Errorf(util.Log(ctx, err.Error()))
|
klog.Errorf(util.Log(ctx, err.Error()))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -803,8 +803,8 @@ func encryptDevice(ctx context.Context, rbdVol *rbdVolume, devicePath string) er
|
|||||||
func openEncryptedDevice(ctx context.Context, volOptions *rbdVolume, devicePath string) (string, error) {
|
func openEncryptedDevice(ctx context.Context, volOptions *rbdVolume, devicePath string) (string, error) {
|
||||||
passphrase, err := util.GetCryptoPassphrase(ctx, volOptions.VolID, volOptions.KMS)
|
passphrase, err := util.GetCryptoPassphrase(ctx, volOptions.VolID, volOptions.KMS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to get passphrase for encrypted device %s/%s: %v"),
|
klog.Errorf(util.Log(ctx, "failed to get passphrase for encrypted device %s: %v"),
|
||||||
volOptions.Pool, volOptions.RbdImageName, err)
|
volOptions, err)
|
||||||
return "", status.Error(codes.Internal, err.Error())
|
return "", status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,8 +820,8 @@ func openEncryptedDevice(ctx context.Context, volOptions *rbdVolume, devicePath
|
|||||||
} else {
|
} else {
|
||||||
err = util.OpenEncryptedVolume(ctx, devicePath, mapperFile, passphrase)
|
err = util.OpenEncryptedVolume(ctx, devicePath, mapperFile, passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to open device %s/%s: %v"),
|
klog.Errorf(util.Log(ctx, "failed to open device %s: %v"),
|
||||||
volOptions.Pool, volOptions.RbdImageName, err)
|
volOptions, err)
|
||||||
return devicePath, err
|
return devicePath, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,8 +202,7 @@ func attachRBDImage(ctx context.Context, volOptions *rbdVolume, cr *util.Credent
|
|||||||
|
|
||||||
func createPath(ctx context.Context, volOpt *rbdVolume, cr *util.Credentials) (string, error) {
|
func createPath(ctx context.Context, volOpt *rbdVolume, cr *util.Credentials) (string, error) {
|
||||||
isNbd := false
|
isNbd := false
|
||||||
image := volOpt.RbdImageName
|
imagePath := volOpt.String()
|
||||||
imagePath := fmt.Sprintf("%s/%s", volOpt.Pool, image)
|
|
||||||
|
|
||||||
klog.V(5).Infof(util.Log(ctx, "rbd: map mon %s"), volOpt.Monitors)
|
klog.V(5).Infof(util.Log(ctx, "rbd: map mon %s"), volOpt.Monitors)
|
||||||
|
|
||||||
@ -244,8 +243,7 @@ func createPath(ctx context.Context, volOpt *rbdVolume, cr *util.Credentials) (s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func waitForrbdImage(ctx context.Context, backoff wait.Backoff, volOptions *rbdVolume, cr *util.Credentials) error {
|
func waitForrbdImage(ctx context.Context, backoff wait.Backoff, volOptions *rbdVolume, cr *util.Credentials) error {
|
||||||
image := volOptions.RbdImageName
|
imagePath := volOptions.String()
|
||||||
imagePath := fmt.Sprintf("%s/%s", volOptions.Pool, image)
|
|
||||||
|
|
||||||
err := wait.ExponentialBackoff(backoff, func() (bool, error) {
|
err := wait.ExponentialBackoff(backoff, func() (bool, error) {
|
||||||
used, rbdOutput, err := rbdStatus(ctx, volOptions, cr)
|
used, rbdOutput, err := rbdStatus(ctx, volOptions, cr)
|
||||||
|
@ -156,21 +156,36 @@ func (rv *rbdVolume) Destroy() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String returns the image-spec (pool/image) format of the image
|
||||||
|
func (rv *rbdVolume) String() string {
|
||||||
|
return fmt.Sprintf("%s/%s", rv.Pool, rv.RbdImageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the snap-spec (pool/image@snap) format of the snapshot
|
||||||
|
func (rs *rbdSnapshot) String() string {
|
||||||
|
return fmt.Sprintf("%s/%s@%s", rs.Pool, rs.RbdImageName, rs.RbdSnapName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// imageSpec returns the image-spec (pool/image) format of the snapshot
|
||||||
|
func (rs *rbdSnapshot) imageSpec() string {
|
||||||
|
return fmt.Sprintf("%s/%s", rs.Pool, rs.RbdImageName)
|
||||||
|
}
|
||||||
|
|
||||||
// createImage creates a new ceph image with provision and volume options.
|
// createImage creates a new ceph image with provision and volume options.
|
||||||
func createImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) error {
|
func createImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) error {
|
||||||
volSzMiB := fmt.Sprintf("%dM", util.RoundOffVolSize(pOpts.VolSize))
|
volSzMiB := fmt.Sprintf("%dM", util.RoundOffVolSize(pOpts.VolSize))
|
||||||
options := librbd.NewRbdImageOptions()
|
options := librbd.NewRbdImageOptions()
|
||||||
|
|
||||||
logMsg := "rbd: create %s size %s (features: %s) using mon %s, pool %s "
|
logMsg := "rbd: create %s size %s (features: %s) using mon %s"
|
||||||
if pOpts.DataPool != "" {
|
if pOpts.DataPool != "" {
|
||||||
logMsg += fmt.Sprintf("data pool %s", pOpts.DataPool)
|
logMsg += fmt.Sprintf(", data pool %s", pOpts.DataPool)
|
||||||
err := options.SetString(librbd.RbdImageOptionDataPool, pOpts.DataPool)
|
err := options.SetString(librbd.RbdImageOptionDataPool, pOpts.DataPool)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to set data pool")
|
return errors.Wrapf(err, "failed to set data pool")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
klog.V(4).Infof(util.Log(ctx, logMsg),
|
klog.V(4).Infof(util.Log(ctx, logMsg),
|
||||||
pOpts.RbdImageName, volSzMiB, pOpts.ImageFeatures, pOpts.Monitors, pOpts.Pool)
|
pOpts, volSzMiB, pOpts.ImageFeatures, pOpts.Monitors)
|
||||||
|
|
||||||
if pOpts.ImageFeatures != "" {
|
if pOpts.ImageFeatures != "" {
|
||||||
features := imageFeaturesToUint64(ctx, pOpts.ImageFeatures)
|
features := imageFeaturesToUint64(ctx, pOpts.ImageFeatures)
|
||||||
@ -227,10 +242,8 @@ func rbdStatus(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) (boo
|
|||||||
var output string
|
var output string
|
||||||
var cmd []byte
|
var cmd []byte
|
||||||
|
|
||||||
image := pOpts.RbdImageName
|
klog.V(4).Infof(util.Log(ctx, "rbd: status %s using mon %s"), pOpts, pOpts.Monitors)
|
||||||
|
args := []string{"status", pOpts.String(), "-m", pOpts.Monitors, "--id", cr.ID, "--keyfile=" + cr.KeyFile}
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd: status %s using mon %s, pool %s"), image, pOpts.Monitors, pOpts.Pool)
|
|
||||||
args := []string{"status", image, "--pool", pOpts.Pool, "-m", pOpts.Monitors, "--id", cr.ID, "--keyfile=" + cr.KeyFile}
|
|
||||||
cmd, err := execCommand("rbd", args)
|
cmd, err := execCommand("rbd", args)
|
||||||
output = string(cmd)
|
output = string(cmd)
|
||||||
|
|
||||||
@ -248,10 +261,10 @@ func rbdStatus(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) (boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(output, imageWatcherStr) {
|
if strings.Contains(output, imageWatcherStr) {
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd: watchers on %s: %s"), image, output)
|
klog.V(4).Infof(util.Log(ctx, "rbd: watchers on %s: %s"), pOpts, output)
|
||||||
return true, output, nil
|
return true, output, nil
|
||||||
}
|
}
|
||||||
klog.Warningf(util.Log(ctx, "rbd: no watchers on %s"), image)
|
klog.Warningf(util.Log(ctx, "rbd: no watchers on %s"), pOpts)
|
||||||
return false, output, nil
|
return false, output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +274,7 @@ func rbdManagerTaskDeleteImage(ctx context.Context, pOpts *rbdVolume, cr *util.C
|
|||||||
var output []byte
|
var output []byte
|
||||||
|
|
||||||
args := []string{"rbd", "task", "add", "remove",
|
args := []string{"rbd", "task", "add", "remove",
|
||||||
pOpts.Pool + "/" + pOpts.RbdImageName,
|
pOpts.String(),
|
||||||
"--id", cr.ID,
|
"--id", cr.ID,
|
||||||
"--keyfile=" + cr.KeyFile,
|
"--keyfile=" + cr.KeyFile,
|
||||||
"-m", pOpts.Monitors,
|
"-m", pOpts.Monitors,
|
||||||
@ -294,16 +307,16 @@ func deleteImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if found {
|
if found {
|
||||||
klog.Errorf(util.Log(ctx, "rbd is still being used "), image)
|
klog.Errorf(util.Log(ctx, "rbd %s is still being used"), pOpts)
|
||||||
return fmt.Errorf("rbd %s is still being used", image)
|
return fmt.Errorf("rbd %s is still being used", pOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd: rm %s using mon %s, pool %s"), image, pOpts.Monitors, pOpts.Pool)
|
klog.V(4).Infof(util.Log(ctx, "rbd: rm %s using mon %s"), pOpts, pOpts.Monitors)
|
||||||
|
|
||||||
// attempt to use Ceph manager based deletion support if available
|
// attempt to use Ceph manager based deletion support if available
|
||||||
rbdCephMgrSupported, err := rbdManagerTaskDeleteImage(ctx, pOpts, cr)
|
rbdCephMgrSupported, err := rbdManagerTaskDeleteImage(ctx, pOpts, cr)
|
||||||
if rbdCephMgrSupported && err != nil {
|
if rbdCephMgrSupported && err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to add task to delete rbd image: %s/%s, %v"), pOpts.Pool, image, err)
|
klog.Errorf(util.Log(ctx, "failed to add task to delete rbd image: %s, %v"), pOpts, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +331,7 @@ func deleteImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er
|
|||||||
rbdImage := librbd.GetImage(ioctx, image)
|
rbdImage := librbd.GetImage(ioctx, image)
|
||||||
err = rbdImage.Remove()
|
err = rbdImage.Remove()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s/%s, error: %v"), pOpts.Pool, image, err)
|
klog.Errorf(util.Log(ctx, "failed to delete rbd image: %s, error: %v"), pOpts, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,8 +341,7 @@ func deleteImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er
|
|||||||
// updateSnapWithImageInfo updates provided rbdSnapshot with information from on-disk data
|
// updateSnapWithImageInfo updates provided rbdSnapshot with information from on-disk data
|
||||||
// regarding the same
|
// regarding the same
|
||||||
func updateSnapWithImageInfo(ctx context.Context, rbdSnap *rbdSnapshot, cr *util.Credentials) error {
|
func updateSnapWithImageInfo(ctx context.Context, rbdSnap *rbdSnapshot, cr *util.Credentials) error {
|
||||||
snapInfo, err := getSnapInfo(ctx, rbdSnap.Monitors, cr, rbdSnap.Pool,
|
snapInfo, err := rbdSnap.getSnapInfo(ctx, rbdSnap.Monitors, cr)
|
||||||
rbdSnap.RbdImageName, rbdSnap.RbdSnapName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -349,7 +361,7 @@ func updateSnapWithImageInfo(ctx context.Context, rbdSnap *rbdSnapshot, cr *util
|
|||||||
// updateVolWithImageInfo updates provided rbdVolume with information from on-disk data
|
// updateVolWithImageInfo updates provided rbdVolume with information from on-disk data
|
||||||
// regarding the same
|
// regarding the same
|
||||||
func updateVolWithImageInfo(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error {
|
func updateVolWithImageInfo(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error {
|
||||||
imageInfo, err := getImageInfo(ctx, rbdVol.Monitors, cr, rbdVol.Pool, rbdVol.RbdImageName)
|
imageInfo, err := rbdVol.getImageInfo(ctx, rbdVol.Monitors, cr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -702,12 +714,8 @@ func imageFeaturesToUint64(ctx context.Context, imageFeatures string) uint64 {
|
|||||||
func protectSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentials) error {
|
func protectSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentials) error {
|
||||||
var output []byte
|
var output []byte
|
||||||
|
|
||||||
image := pOpts.RbdImageName
|
klog.V(4).Infof(util.Log(ctx, "rbd: snap protect %s using mon %s"), pOpts, pOpts.Monitors)
|
||||||
snapName := pOpts.RbdSnapName
|
args := []string{"snap", "protect", pOpts.String(), "--id", cr.ID, "-m", pOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
||||||
|
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd: snap protect %s using mon %s, pool %s "), image, pOpts.Monitors, pOpts.Pool)
|
|
||||||
args := []string{"snap", "protect", "--pool", pOpts.Pool, "--snap", snapName, image, "--id",
|
|
||||||
cr.ID, "-m", pOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
|
||||||
|
|
||||||
output, err := execCommand("rbd", args)
|
output, err := execCommand("rbd", args)
|
||||||
|
|
||||||
@ -721,12 +729,8 @@ func protectSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentia
|
|||||||
func createSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentials) error {
|
func createSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentials) error {
|
||||||
var output []byte
|
var output []byte
|
||||||
|
|
||||||
image := pOpts.RbdImageName
|
klog.V(4).Infof(util.Log(ctx, "rbd: snap create %s using mon %s"), pOpts, pOpts.Monitors)
|
||||||
snapName := pOpts.RbdSnapName
|
args := []string{"snap", "create", pOpts.String(), "--id", cr.ID, "-m", pOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
||||||
|
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd: snap create %s using mon %s, pool %s"), image, pOpts.Monitors, pOpts.Pool)
|
|
||||||
args := []string{"snap", "create", "--pool", pOpts.Pool, "--snap", snapName, image,
|
|
||||||
"--id", cr.ID, "-m", pOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
|
||||||
|
|
||||||
output, err := execCommand("rbd", args)
|
output, err := execCommand("rbd", args)
|
||||||
|
|
||||||
@ -740,12 +744,8 @@ func createSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credential
|
|||||||
func unprotectSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentials) error {
|
func unprotectSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentials) error {
|
||||||
var output []byte
|
var output []byte
|
||||||
|
|
||||||
image := pOpts.RbdImageName
|
klog.V(4).Infof(util.Log(ctx, "rbd: snap unprotect %s using mon %s"), pOpts, pOpts.Monitors)
|
||||||
snapName := pOpts.RbdSnapName
|
args := []string{"snap", "unprotect", pOpts.String(), "--id", cr.ID, "-m", pOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
||||||
|
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd: snap unprotect %s using mon %s, pool %s"), image, pOpts.Monitors, pOpts.Pool)
|
|
||||||
args := []string{"snap", "unprotect", "--pool", pOpts.Pool, "--snap", snapName, image, "--id",
|
|
||||||
cr.ID, "-m", pOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
|
||||||
|
|
||||||
output, err := execCommand("rbd", args)
|
output, err := execCommand("rbd", args)
|
||||||
|
|
||||||
@ -759,12 +759,8 @@ func unprotectSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credent
|
|||||||
func deleteSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentials) error {
|
func deleteSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credentials) error {
|
||||||
var output []byte
|
var output []byte
|
||||||
|
|
||||||
image := pOpts.RbdImageName
|
klog.V(4).Infof(util.Log(ctx, "rbd: snap rm %s using mon %s"), pOpts, pOpts.Monitors)
|
||||||
snapName := pOpts.RbdSnapName
|
args := []string{"snap", "rm", pOpts.String(), "--id", cr.ID, "-m", pOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
||||||
|
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd: snap rm %s using mon %s, pool %s"), image, pOpts.Monitors, pOpts.Pool)
|
|
||||||
args := []string{"snap", "rm", "--pool", pOpts.Pool, "--snap", snapName, image, "--id",
|
|
||||||
cr.ID, "-m", pOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
|
||||||
|
|
||||||
output, err := execCommand("rbd", args)
|
output, err := execCommand("rbd", args)
|
||||||
|
|
||||||
@ -773,22 +769,20 @@ func deleteSnapshot(ctx context.Context, pOpts *rbdSnapshot, cr *util.Credential
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := undoSnapReservation(ctx, pOpts, cr); err != nil {
|
if err := undoSnapReservation(ctx, pOpts, cr); err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to remove reservation for snapname (%s) with backing snap (%s) on image (%s) (%s)"),
|
klog.Errorf(util.Log(ctx, "failed to remove reservation for snapname (%s) with backing snap (%s): %s"),
|
||||||
pOpts.RequestName, pOpts.RbdSnapName, pOpts.RbdImageName, err)
|
pOpts.RequestName, pOpts, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint: interfacer
|
||||||
func restoreSnapshot(ctx context.Context, pVolOpts *rbdVolume, pSnapOpts *rbdSnapshot, cr *util.Credentials) error {
|
func restoreSnapshot(ctx context.Context, pVolOpts *rbdVolume, pSnapOpts *rbdSnapshot, cr *util.Credentials) error {
|
||||||
var output []byte
|
var output []byte
|
||||||
|
|
||||||
image := pVolOpts.RbdImageName
|
klog.V(4).Infof(util.Log(ctx, "rbd: clone %s using mon %s"), pVolOpts, pVolOpts.Monitors)
|
||||||
snapName := pSnapOpts.RbdSnapName
|
args := []string{"clone", pSnapOpts.String(), pVolOpts.String(),
|
||||||
|
"--id", cr.ID, "-m", pVolOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
||||||
klog.V(4).Infof(util.Log(ctx, "rbd: clone %s using mon %s, pool %s"), image, pVolOpts.Monitors, pVolOpts.Pool)
|
|
||||||
args := []string{"clone", pSnapOpts.Pool + "/" + pSnapOpts.RbdImageName + "@" + snapName,
|
|
||||||
pVolOpts.Pool + "/" + image, "--id", cr.ID, "-m", pVolOpts.Monitors, "--keyfile=" + cr.KeyFile}
|
|
||||||
|
|
||||||
output, err := execCommand("rbd", args)
|
output, err := execCommand("rbd", args)
|
||||||
|
|
||||||
@ -802,10 +796,7 @@ func restoreSnapshot(ctx context.Context, pVolOpts *rbdVolume, pSnapOpts *rbdSna
|
|||||||
// getSnapshotMetadata fetches on-disk metadata about the snapshot and populates the passed in
|
// getSnapshotMetadata fetches on-disk metadata about the snapshot and populates the passed in
|
||||||
// rbdSnapshot structure
|
// rbdSnapshot structure
|
||||||
func getSnapshotMetadata(ctx context.Context, pSnapOpts *rbdSnapshot, cr *util.Credentials) error {
|
func getSnapshotMetadata(ctx context.Context, pSnapOpts *rbdSnapshot, cr *util.Credentials) error {
|
||||||
imageName := pSnapOpts.RbdImageName
|
snapInfo, err := pSnapOpts.getSnapInfo(ctx, pSnapOpts.Monitors, cr)
|
||||||
snapName := pSnapOpts.RbdSnapName
|
|
||||||
|
|
||||||
snapInfo, err := getSnapInfo(ctx, pSnapOpts.Monitors, cr, pSnapOpts.Pool, imageName, snapName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -835,7 +826,7 @@ type imageInfo struct {
|
|||||||
|
|
||||||
// getImageInfo queries rbd about the given image and returns its metadata, and returns
|
// getImageInfo queries rbd about the given image and returns its metadata, and returns
|
||||||
// ErrImageNotFound if provided image is not found
|
// ErrImageNotFound if provided image is not found
|
||||||
func getImageInfo(ctx context.Context, monitors string, cr *util.Credentials, poolName, imageName string) (imageInfo, error) {
|
func (rv *rbdVolume) getImageInfo(ctx context.Context, monitors string, cr *util.Credentials) (imageInfo, error) {
|
||||||
// rbd --format=json info [image-spec | snap-spec]
|
// rbd --format=json info [image-spec | snap-spec]
|
||||||
|
|
||||||
var imgInfo imageInfo
|
var imgInfo imageInfo
|
||||||
@ -847,22 +838,20 @@ func getImageInfo(ctx context.Context, monitors string, cr *util.Credentials, po
|
|||||||
"--keyfile="+cr.KeyFile,
|
"--keyfile="+cr.KeyFile,
|
||||||
"-c", util.CephConfigPath,
|
"-c", util.CephConfigPath,
|
||||||
"--format="+"json",
|
"--format="+"json",
|
||||||
"info", poolName+"/"+imageName)
|
"info", rv.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed getting information for image (%s): (%s)"), poolName+"/"+imageName, err)
|
klog.Errorf(util.Log(ctx, "failed getting information for image (%s): (%s)"), rv, err)
|
||||||
if strings.Contains(string(stderr), "rbd: error opening image "+imageName+
|
if strings.Contains(string(stderr), "rbd: error opening image "+rv.RbdImageName+
|
||||||
": (2) No such file or directory") {
|
": (2) No such file or directory") {
|
||||||
return imgInfo, ErrImageNotFound{imageName, err}
|
return imgInfo, ErrImageNotFound{rv.String(), err}
|
||||||
}
|
}
|
||||||
return imgInfo, err
|
return imgInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(stdout, &imgInfo)
|
err = json.Unmarshal(stdout, &imgInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to parse JSON output of image info (%s): (%s)"),
|
klog.Errorf(util.Log(ctx, "failed to parse JSON output of image info (%s): (%s)"), rv, err)
|
||||||
poolName+"/"+imageName, err)
|
return imgInfo, fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s", err, string(stdout))
|
||||||
return imgInfo, fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s",
|
|
||||||
err, string(stdout))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return imgInfo, nil
|
return imgInfo, nil
|
||||||
@ -881,7 +870,7 @@ getSnapInfo queries rbd about the snapshots of the given image and returns its m
|
|||||||
returns ErrImageNotFound if provided image is not found, and ErrSnapNotFound if provided snap
|
returns ErrImageNotFound if provided image is not found, and ErrSnapNotFound if provided snap
|
||||||
is not found in the images snapshot list
|
is not found in the images snapshot list
|
||||||
*/
|
*/
|
||||||
func getSnapInfo(ctx context.Context, monitors string, cr *util.Credentials, poolName, imageName, snapName string) (snapInfo, error) {
|
func (rs *rbdSnapshot) getSnapInfo(ctx context.Context, monitors string, cr *util.Credentials) (snapInfo, error) {
|
||||||
// rbd --format=json snap ls [image-spec]
|
// rbd --format=json snap ls [image-spec]
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -896,33 +885,30 @@ func getSnapInfo(ctx context.Context, monitors string, cr *util.Credentials, poo
|
|||||||
"--keyfile="+cr.KeyFile,
|
"--keyfile="+cr.KeyFile,
|
||||||
"-c", util.CephConfigPath,
|
"-c", util.CephConfigPath,
|
||||||
"--format="+"json",
|
"--format="+"json",
|
||||||
"snap", "ls", poolName+"/"+imageName)
|
"snap", "ls", rs.imageSpec())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed getting snap (%s) information from image (%s): (%s)"),
|
klog.Errorf(util.Log(ctx, "failed getting snap (%s) information from image (%s): (%s)"),
|
||||||
snapName, poolName+"/"+imageName, err)
|
rs.RbdSnapName, rs.imageSpec(), err)
|
||||||
if strings.Contains(string(stderr), "rbd: error opening image "+imageName+
|
if strings.Contains(string(stderr), "rbd: error opening image "+rs.RbdImageName+
|
||||||
": (2) No such file or directory") {
|
": (2) No such file or directory") {
|
||||||
return snpInfo, ErrImageNotFound{imageName, err}
|
return snpInfo, ErrImageNotFound{rs.imageSpec(), err}
|
||||||
}
|
}
|
||||||
return snpInfo, err
|
return snpInfo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(stdout, &snaps)
|
err = json.Unmarshal(stdout, &snaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "failed to parse JSON output of image snap list (%s): (%s)"),
|
klog.Errorf(util.Log(ctx, "failed to parse JSON output of image snap list (%s): (%s)"), rs.imageSpec(), err)
|
||||||
poolName+"/"+imageName, err)
|
return snpInfo, fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s", err, string(stdout))
|
||||||
return snpInfo, fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s",
|
|
||||||
err, string(stdout))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, snap := range snaps {
|
for _, snap := range snaps {
|
||||||
if snap.Name == snapName {
|
if snap.Name == rs.RbdSnapName {
|
||||||
return snap, nil
|
return snap, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return snpInfo, ErrSnapNotFound{snapName, fmt.Errorf("snap (%s) for image (%s) not found",
|
return snpInfo, ErrSnapNotFound{rs.String(), fmt.Errorf("snap (%s) not found", rs)}
|
||||||
snapName, poolName+"/"+imageName)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rbdImageMetadataStash strongly typed JSON spec for stashed RBD image metadata
|
// rbdImageMetadataStash strongly typed JSON spec for stashed RBD image metadata
|
||||||
@ -937,6 +923,11 @@ type rbdImageMetadataStash struct {
|
|||||||
// file name in which image metadata is stashed
|
// file name in which image metadata is stashed
|
||||||
const stashFileName = "image-meta.json"
|
const stashFileName = "image-meta.json"
|
||||||
|
|
||||||
|
// spec returns the image-spec (pool/image) format of the image
|
||||||
|
func (ri *rbdImageMetadataStash) String() string {
|
||||||
|
return fmt.Sprintf("%s/%s", ri.Pool, ri.ImageName)
|
||||||
|
}
|
||||||
|
|
||||||
// stashRBDImageMetadata stashes required fields into the stashFileName at the passed in path, in
|
// stashRBDImageMetadata stashes required fields into the stashFileName at the passed in path, in
|
||||||
// JSON format
|
// JSON format
|
||||||
func stashRBDImageMetadata(volOptions *rbdVolume, path string) error {
|
func stashRBDImageMetadata(volOptions *rbdVolume, path string) error {
|
||||||
@ -954,15 +945,13 @@ func stashRBDImageMetadata(volOptions *rbdVolume, path string) error {
|
|||||||
|
|
||||||
encodedBytes, err := json.Marshal(imgMeta)
|
encodedBytes, err := json.Marshal(imgMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshall JSON image metadata for image (%s) in pool (%s): (%v)",
|
return fmt.Errorf("failed to marshall JSON image metadata for image (%s): (%v)", volOptions, err)
|
||||||
volOptions.RbdImageName, volOptions.Pool, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fPath := filepath.Join(path, stashFileName)
|
fPath := filepath.Join(path, stashFileName)
|
||||||
err = ioutil.WriteFile(fPath, encodedBytes, 0600)
|
err = ioutil.WriteFile(fPath, encodedBytes, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to stash JSON image metadata for image (%s) in pool (%s) at path (%s): (%v)",
|
return fmt.Errorf("failed to stash JSON image metadata for image (%s) at path (%s): (%v)", volOptions, fPath, err)
|
||||||
volOptions.RbdImageName, volOptions.Pool, fPath, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -1005,10 +994,9 @@ func resizeRBDImage(rbdVol *rbdVolume, cr *util.Credentials) error {
|
|||||||
var output []byte
|
var output []byte
|
||||||
|
|
||||||
mon := rbdVol.Monitors
|
mon := rbdVol.Monitors
|
||||||
image := rbdVol.RbdImageName
|
|
||||||
volSzMiB := fmt.Sprintf("%dM", util.RoundOffVolSize(rbdVol.VolSize))
|
volSzMiB := fmt.Sprintf("%dM", util.RoundOffVolSize(rbdVol.VolSize))
|
||||||
|
|
||||||
args := []string{"resize", image, "--size", volSzMiB, "--pool", rbdVol.Pool, "--id", cr.ID, "-m", mon, "--keyfile=" + cr.KeyFile}
|
args := []string{"resize", rbdVol.String(), "--size", volSzMiB, "--id", cr.ID, "-m", mon, "--keyfile=" + cr.KeyFile}
|
||||||
output, err := execCommand("rbd", args)
|
output, err := execCommand("rbd", args)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1042,19 +1030,19 @@ func (rv *rbdVolume) SetMetadata(key, value string) error {
|
|||||||
func (rv *rbdVolume) checkRbdImageEncrypted(ctx context.Context) (string, error) {
|
func (rv *rbdVolume) checkRbdImageEncrypted(ctx context.Context) (string, error) {
|
||||||
value, err := rv.GetMetadata(encryptionMetaKey)
|
value, err := rv.GetMetadata(encryptionMetaKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf(util.Log(ctx, "checking image %s encrypted state metadata failed: %s"), rv.RbdImageName, err)
|
klog.Errorf(util.Log(ctx, "checking image %s encrypted state metadata failed: %s"), rv, err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
encrypted := strings.TrimSpace(value)
|
encrypted := strings.TrimSpace(value)
|
||||||
klog.V(4).Infof(util.Log(ctx, "image %s encrypted state metadata reports %q"), rv.RbdImageName, encrypted)
|
klog.V(4).Infof(util.Log(ctx, "image %s encrypted state metadata reports %q"), rv, encrypted)
|
||||||
return encrypted, nil
|
return encrypted, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rv *rbdVolume) ensureEncryptionMetadataSet(status string) error {
|
func (rv *rbdVolume) ensureEncryptionMetadataSet(status string) error {
|
||||||
err := rv.SetMetadata(encryptionMetaKey, status)
|
err := rv.SetMetadata(encryptionMetaKey, status)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to save encryption status for %s: %v", rv.RbdImageName, err)
|
return fmt.Errorf("failed to save encryption status for %s: %v", rv, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user