Skip to content

Commit

Permalink
PVC create should be max of three size sources.
Browse files Browse the repository at this point in the history
controller defined size
qcow2 virtual and actual size
Also fix a yetus missing comment

Signed-off-by: Andrew Durbin <[email protected]>
  • Loading branch information
andrewd-zededa committed Feb 18, 2025
1 parent 5aff6b5 commit c137365
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
5 changes: 5 additions & 0 deletions pkg/pillar/diskmetrics/diskmetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const qemuExecLongTimeout = 1000 * time.Second
// qemuExecUltraLongTimeout is a long timeout for command executions in separate worker thread that take especially long
const qemuExecUltraLongTimeout = 120 * time.Hour

// GetImgInfo returns the ImgInfo structure from qemu-img info
func GetImgInfo(log *base.LogObject, diskfile string) (*types.ImgInfo, error) {
var imgInfo types.ImgInfo

Expand All @@ -45,6 +46,8 @@ func GetImgInfo(log *base.LogObject, diskfile string) (*types.ImgInfo, error) {
}

// GetDiskActualSize - returns ActualSize of the image
// following github.com/qemu/qemu/docs/tools/qemu-img.rst:
// "How much space the image file occupies on the host file system" (current size possibly thin)
func GetDiskActualSize(log *base.LogObject, diskfile string) (uint64, error) {
imgInfo, err := GetImgInfo(log, diskfile)
if err != nil {
Expand All @@ -54,6 +57,8 @@ func GetDiskActualSize(log *base.LogObject, diskfile string) (uint64, error) {
}

// GetDiskVirtualSize - returns VirtualSize of the image
// following github.com/qemu/qemu/docs/tools/qemu-img.rst:
// "The size of the guest disk" (max size)
func GetDiskVirtualSize(log *base.LogObject, diskfile string) (uint64, error) {
imgInfo, err := GetImgInfo(log, diskfile)
if err != nil {
Expand Down
42 changes: 39 additions & 3 deletions pkg/pillar/kubeapi/vitoapiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

zconfig "github.com/lf-edge/eve-api/go/config"
"github.com/lf-edge/eve/pkg/pillar/base"
"github.com/lf-edge/eve/pkg/pillar/diskmetrics"
"github.com/lf-edge/eve/pkg/pillar/types"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -242,6 +243,38 @@ func RolloutDiskToPVC(ctx context.Context, log *base.LogObject, exists bool,
uploadproxyURL := "https://" + clusterIP + ":443"
log.Noticef("RolloutDiskToPVC diskfile %s pvc %s URL %s", diskfile, pvcName, uploadproxyURL)

imgVirtBytes, err := diskmetrics.GetDiskVirtualSize(log, diskfile)
if err != nil {
err = fmt.Errorf("failed to get virtual size of disk %s: %v", diskfile, err)
log.Error(err)
return err
}
if pvcSize < imgVirtBytes {
log.Noticef("Image file: %s has virtual size %d", diskfile, imgVirtBytes)
pvcSize = imgVirtBytes
}
// ActualSize can be larger (by a very small amount) than VirtualSize for fully-allocated/not-thin QCOW2 files
imgActualBytes, err := diskmetrics.GetDiskActualSize(log, diskfile)
if err != nil {
err = fmt.Errorf("failed to get actual size of disk %s: %v", diskfile, err)
log.Error(err)
return err
}
if pvcSize < imgActualBytes {
pvcSize = imgActualBytes
}

// Create PVC and then copy data. We create PVC to set the designated node id label.
if !exists {
err = CreatePVC(pvcName, pvcSize, log)
if err != nil {
err = fmt.Errorf("Error creating PVC %s", pvcName)
log.Error(err)
return err
}
exists = true
}

// Sample virtctl command
// virtctl image-upload -n eve-kube-app pvc pvcname --no-create --storage-class longhorn --image-path=<diskfile>
// --insecure --uploadproxy-url https://10.43.31.180:8443 --access-mode RWO --block-volume --size 1000M
Expand Down Expand Up @@ -291,24 +324,27 @@ func RolloutDiskToPVC(ctx context.Context, log *base.LogObject, exists bool,
WithContext(ctx).WithUnlimitedTimeout(timeout * time.Second).CombinedOutput()

uploadDuration := time.Since(startTimeThisUpload)
if err != nil {
if err != nil && !strings.Contains(string(output), "already successfully imported") {
err = fmt.Errorf("RolloutDiskToPVC: Failed after %f seconds to convert qcow to PVC %s: %v", uploadDuration.Seconds(), output, err)
log.Error(err)
time.Sleep(5)
time.Sleep(30 * time.Second) // 30 secs with 10 tries, 5 mins should be good enough even if k3s server restarts
continue
}

// Eventually the command should return something like:
// PVC 688b9728-6f21-4bb6-b2f7-4928813fefdc-pvc-0 already successfully imported/cloned/updated
overallDuration := time.Since(startTimeOverall)
log.Noticef("RolloutDiskToPVC image upload completed on try:%d after %f seconds, total elapsed time %f seconds", uploadTry, uploadDuration.Seconds(), overallDuration.Seconds())
log.Functionf("RolloutDiskToPVC image upload completed on try:%d after %f seconds, total elapsed time %f seconds", uploadTry, uploadDuration.Seconds(), overallDuration.Seconds())
err = waitForPVCUploadComplete(ctx, pvcName, log)
if err != nil {
err = fmt.Errorf("RolloutDiskToPVC: error wait for PVC %v", err)
log.Error(err)
return err
}
log.Noticef("RolloutDiskToPVC image upload completed on try:%d after %f seconds, total elapsed time %f seconds", uploadTry, uploadDuration.Seconds(), overallDuration.Seconds())
return nil
}

return fmt.Errorf("RolloutDiskToPVC attempts to upload image failed")
}

Expand Down

0 comments on commit c137365

Please sign in to comment.