diff --git a/go.mod b/go.mod index e6789624..90536a05 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,10 @@ require ( github.com/RoaringBitmap/roaring v1.9.3 github.com/golang/protobuf v1.5.4 github.com/gorilla/mux v1.8.1 - github.com/longhorn/backupstore v0.0.0-20240417071544-3bd377eeefeb + github.com/longhorn/backupstore v0.0.0-20240426093637-ac3867f121c0 github.com/longhorn/longhorn-engine v1.6.0-dev-20231217.0.20240418025706-519598108463 - github.com/longhorn/sparse-tools v0.0.0-20240228120902-ce8c4c2e71ca - github.com/longhorn/types v0.0.0-20240417112740-a0d8514936b8 + github.com/longhorn/sparse-tools v0.0.0-20240424162924-2651ad40ad19 + github.com/longhorn/types v0.0.0-20240424162824-4995e1e42438 github.com/pkg/errors v0.9.1 github.com/rancher/go-fibmap v0.0.0-20160418233256-5fc9f8c1ed47 github.com/sirupsen/logrus v1.9.3 diff --git a/go.sum b/go.sum index 9031b9de..4a3772c7 100644 --- a/go.sum +++ b/go.sum @@ -57,14 +57,20 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/longhorn/backupstore v0.0.0-20240417071544-3bd377eeefeb h1:GkAG0P7QI32PYgjLBV6VvaEAM/Z9dKyPohccU1js+Uk= github.com/longhorn/backupstore v0.0.0-20240417071544-3bd377eeefeb/go.mod h1:4cbJWtlrD2cGTQxQLtdlPTYopiJiusXH7CpOBrn/s3k= +github.com/longhorn/backupstore v0.0.0-20240426093637-ac3867f121c0 h1:sb9HK8uWApqrBbpjnxlNSmIB5f4oi3UqfeRHVniPcqo= +github.com/longhorn/backupstore v0.0.0-20240426093637-ac3867f121c0/go.mod h1:NlOHCyQiGjn9TS1HUfQlBESttDPzi9x1Vs38geRV9SU= github.com/longhorn/longhorn-engine v1.6.0-dev-20231217.0.20240418025706-519598108463 h1:KxddgUYC9InOhe8MxfbxzOL5v9q7f5DyThxQGGKvqVw= github.com/longhorn/longhorn-engine v1.6.0-dev-20231217.0.20240418025706-519598108463/go.mod h1:WNiZl2l51I36/c8dewxkyWd0yBA5Anznzki0knKO88U= github.com/longhorn/sparse-tools v0.0.0-20240228120902-ce8c4c2e71ca h1:dECamLpXIlL7GRmiruGseb5xO6hGAWyu2xYm9D46mb8= github.com/longhorn/sparse-tools v0.0.0-20240228120902-ce8c4c2e71ca/go.mod h1:pvlUkVwRGojXhcTkkzksOe4i7GVk59P2PbJjHIB2Yj0= +github.com/longhorn/sparse-tools v0.0.0-20240424162924-2651ad40ad19 h1:/bSLCJxmmtq+alVHtvPl5eDXgMHqBOzOwcCCJxtRts0= +github.com/longhorn/sparse-tools v0.0.0-20240424162924-2651ad40ad19/go.mod h1:pvlUkVwRGojXhcTkkzksOe4i7GVk59P2PbJjHIB2Yj0= github.com/longhorn/types v0.0.0-20240417064442-e7df610ea802 h1:evjIqn8Ta4toYsdcfvUBXOyV64ZEo72CYe+Vfd+3STQ= github.com/longhorn/types v0.0.0-20240417064442-e7df610ea802/go.mod h1:pqT+7B8T+nkyUZYe8tL3CwPDCHjkbe3mHUDY5ntJFyQ= github.com/longhorn/types v0.0.0-20240417112740-a0d8514936b8 h1:M9TQLN379VNN3JsuLuKHDRIy/11jYeIuxYLFuekjcPw= github.com/longhorn/types v0.0.0-20240417112740-a0d8514936b8/go.mod h1:pqT+7B8T+nkyUZYe8tL3CwPDCHjkbe3mHUDY5ntJFyQ= +github.com/longhorn/types v0.0.0-20240424162824-4995e1e42438 h1:nSuJa62e6F9YsP06Js4jnKr0AsvEMGwBRLm9fXTlmns= +github.com/longhorn/types v0.0.0-20240424162824-4995e1e42438/go.mod h1:pqT+7B8T+nkyUZYe8tL3CwPDCHjkbe3mHUDY5ntJFyQ= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= diff --git a/vendor/github.com/longhorn/backupstore/Dockerfile.dapper b/vendor/github.com/longhorn/backupstore/Dockerfile.dapper index ee79381e..a2996791 100644 --- a/vendor/github.com/longhorn/backupstore/Dockerfile.dapper +++ b/vendor/github.com/longhorn/backupstore/Dockerfile.dapper @@ -10,15 +10,15 @@ RUN apt-get update && \ rm -f /bin/sh && ln -s /bin/bash /bin/sh ENV DOCKER_URL_amd64=https://get.docker.com/builds/Linux/x86_64/docker-1.10.3 \ - DOCKER_URL_arm=https://github.com/rancher/docker/releases/download/v1.10.3-ros1/docker-1.10.3_arm \ + DOCKER_URL_arm64=https://github.com/rancher/docker/releases/download/v1.10.3-ros1/docker-1.10.3_arm \ DOCKER_URL=DOCKER_URL_${ARCH} RUN wget -O - ${!DOCKER_URL} > /usr/bin/docker && chmod +x /usr/bin/docker -ENV GOLANG_ARCH_amd64=amd64 GOLANG_ARCH_arm=armv6l GOLANG_ARCH=GOLANG_ARCH_${ARCH} \ +ENV GOLANG_ARCH_amd64=amd64 GOLANG_ARCH_arm64=arm64 GOLANG_ARCH=GOLANG_ARCH_${ARCH} \ GOPATH=/go PATH=/go/bin:/usr/local/go/bin:${PATH} SHELL=/bin/bash -RUN wget -O - https://storage.googleapis.com/golang/go1.17.10.linux-${!GOLANG_ARCH}.tar.gz | tar -xzf - -C /usr/local +RUN wget -O - https://storage.googleapis.com/golang/go1.21.3.linux-${!GOLANG_ARCH}.tar.gz | tar -xzf - -C /usr/local RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.55.2 ENV DAPPER_SOURCE /go/src/github.com/longhorn/backupstore diff --git a/vendor/github.com/longhorn/backupstore/backupbackingimage/backupbackingimage.go b/vendor/github.com/longhorn/backupstore/backupbackingimage/backupbackingimage.go index 672b17ff..c89a9a93 100644 --- a/vendor/github.com/longhorn/backupstore/backupbackingimage/backupbackingimage.go +++ b/vendor/github.com/longhorn/backupstore/backupbackingimage/backupbackingimage.go @@ -95,10 +95,14 @@ func CreateBackingImageBackup(config *BackupConfig, backupBackingImage *BackupBa return err } - defer lock.Unlock() if err := lock.Lock(); err != nil { return err } + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + log.WithError(unlockErr).Warn("Failed to unlock backup backing image") + } + }() exists, err := addBackingImageConfigInBackupStore(bsDriver, backupBackingImage) if err != nil { @@ -123,7 +127,11 @@ func CreateBackingImageBackup(config *BackupConfig, backupBackingImage *BackupBa go func() { defer backupOperation.CloseFile() - defer lock.Unlock() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + log.WithError(unlockErr).Warn("Failed to unlock backup backing image") + } + }() backupOperation.UpdateBackupProgress(string(common.ProgressStateInProgress), 0, "", "") @@ -322,10 +330,14 @@ func RestoreBackingImageBackup(config *RestoreConfig, restoreOperation RestoreOp return err } - defer lock.Unlock() if err := lock.Lock(); err != nil { return err } + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock restore backing image") + } + }() backupBackingImage, err := loadBackingImageConfigInBackupStore(bsDriver, backingImageName) if err != nil { @@ -356,8 +368,16 @@ func RestoreBackingImageBackup(config *RestoreConfig, restoreOperation RestoreOp } go func() { - defer backingImageFile.Close() - defer lock.Unlock() + defer func() { + if closeErr := backingImageFile.Close(); closeErr != nil { + logrus.WithError(closeErr).Warn("Failed to close backing image file") + } + }() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock restore") + } + }() progress := &common.Progress{ TotalBlockCounts: int64(len(backupBackingImage.Blocks)), @@ -416,7 +436,7 @@ func checkBackingImageFile(backingImageFilePath string, backupBackingImage *Back // We want to truncate regular files, but not device if stat.Mode()&os.ModeType == 0 { if err := backingImageFile.Truncate(backupBackingImage.Size); err != nil { - errors.Wrapf(err, "failed to truncate backing image") + err = errors.Wrapf(err, "failed to truncate backing image") return nil, err } } @@ -519,7 +539,11 @@ func RemoveBackingImageBackup(backupURL string) (err error) { if err := lock.Lock(); err != nil { return err } - defer lock.Unlock() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock restore") + } + }() // If we fail to load the backup we still want to proceed with the deletion of the backup file backupBackingImage, err := loadBackingImageConfigInBackupStore(bsDriver, backingImageName) diff --git a/vendor/github.com/longhorn/backupstore/config.go b/vendor/github.com/longhorn/backupstore/config.go index a996ba0d..40d9305f 100644 --- a/vendor/github.com/longhorn/backupstore/config.go +++ b/vendor/github.com/longhorn/backupstore/config.go @@ -220,7 +220,6 @@ func getVolumeNames(jobQueues *workerpool.WorkerPool, driver BackupStoreDriver) Payload: lv2Paths, Err: nil, } - return }) } @@ -258,7 +257,6 @@ func getVolumeNames(jobQueues *workerpool.WorkerPool, driver BackupStoreDriver) Payload: volumeNames, Err: nil, } - return }) } } diff --git a/vendor/github.com/longhorn/backupstore/deltablock.go b/vendor/github.com/longhorn/backupstore/deltablock.go index 7c2ace7b..28f0d062 100644 --- a/vendor/github.com/longhorn/backupstore/deltablock.go +++ b/vendor/github.com/longhorn/backupstore/deltablock.go @@ -138,7 +138,9 @@ func CreateDeltaBlockBackup(backupName string, config *DeltaBackupConfig) (isInc defer func() { if err != nil { log.WithError(err).Error("Failed to create delta block backup") - deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateError), 0, "", err.Error()) + if updateErr := deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateError), 0, "", err.Error()); updateErr != nil { + log.WithError(updateErr).Warn("Failed to update backup status") + } } }() @@ -152,7 +154,11 @@ func CreateDeltaBlockBackup(backupName string, config *DeltaBackupConfig) (isInc return false, err } - defer lock.Unlock() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock") + } + }() if err := lock.Lock(); err != nil { return false, err } @@ -218,13 +224,17 @@ func CreateDeltaBlockBackup(backupName string, config *DeltaBackupConfig) (isInc delta, err := deltaOps.CompareSnapshot(snapshot.Name, backupRequest.getLastSnapshotName(), volume.Name) if err != nil { - deltaOps.CloseSnapshot(snapshot.Name, volume.Name) + if closeErr := deltaOps.CloseSnapshot(snapshot.Name, volume.Name); closeErr != nil { + err = errors.Wrapf(err, "during handling err %+v, close snapshot returns err %+v", err, closeErr) + } return backupRequest.isIncrementalBackup(), err } if delta.BlockSize != DEFAULT_BLOCK_SIZE { - deltaOps.CloseSnapshot(snapshot.Name, volume.Name) - return backupRequest.isIncrementalBackup(), - fmt.Errorf("driver doesn't support block sizes other than %v", DEFAULT_BLOCK_SIZE) + err = fmt.Errorf("driver doesn't support block sizes other than %v", DEFAULT_BLOCK_SIZE) + if closeErr := deltaOps.CloseSnapshot(snapshot.Name, volume.Name); closeErr != nil { + err = errors.Wrapf(err, "during handling err %+v, close snapshot returns err %+v", err, closeErr) + } + return backupRequest.isIncrementalBackup(), err } log.WithFields(logrus.Fields{ LogFieldReason: LogReasonComplete, @@ -258,22 +268,38 @@ func CreateDeltaBlockBackup(backupName string, config *DeltaBackupConfig) (isInc // keep lock alive for async go routine. if err := lock.Lock(); err != nil { - deltaOps.CloseSnapshot(snapshot.Name, volume.Name) + if closeErr := deltaOps.CloseSnapshot(snapshot.Name, volume.Name); closeErr != nil { + err = errors.Wrapf(err, "during handling err %+v, close snapshot returns err %+v", err, closeErr) + } return backupRequest.isIncrementalBackup(), err } go func() { - defer deltaOps.CloseSnapshot(snapshot.Name, volume.Name) - defer lock.Unlock() + defer func() { + if closeErr := deltaOps.CloseSnapshot(snapshot.Name, volume.Name); closeErr != nil { + logrus.WithError(closeErr).Warn("Failed to close snapshot") + } + }() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock") + } + }() - deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateInProgress), 0, "", "") + if updateErr := deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateInProgress), 0, "", ""); updateErr != nil { + logrus.WithError(updateErr).Error("Failed to update backup status") + } log.Info("Performing delta block backup") if progress, backup, err := performBackup(bsDriver, config, delta, deltaBackup, backupRequest.lastBackup); err != nil { logrus.WithError(err).Errorf("Failed to perform backup for volume %v snapshot %v", volume.Name, snapshot.Name) - deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateInProgress), progress, "", err.Error()) + if updateErr := deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateInProgress), progress, "", err.Error()); updateErr != nil { + logrus.WithError(updateErr).Warn("Failed to update backup status") + } } else { - deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateInProgress), progress, backup, "") + if updateErr := deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateInProgress), progress, backup, ""); updateErr != nil { + logrus.WithError(updateErr).Warn("Failed to update backup status") + } } }() return backupRequest.isIncrementalBackup(), nil @@ -369,7 +395,9 @@ func backupBlock(bsDriver BackupStoreDriver, config *DeltaBackupConfig, deltaBackup.Lock() defer deltaBackup.Unlock() updateBlocksAndProgress(deltaBackup, progress, checksum, newBlock) - deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateInProgress), progress.progress, "", "") + if updateErr := deltaOps.UpdateBackupStatus(snapshot.Name, volume.Name, string(types.ProgressStateInProgress), progress.progress, "", ""); updateErr != nil { + logrus.WithError(updateErr).Warn("Failed to update backup status") + } }() blkFile := getBlockFilePath(volume.Name, checksum) @@ -640,7 +668,11 @@ func RestoreDeltaBlockBackup(ctx context.Context, config *DeltaRestoreConfig) er return err } - defer lock.Unlock() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock") + } + }() if err := lock.Lock(); err != nil { return err } @@ -699,7 +731,9 @@ func RestoreDeltaBlockBackup(ctx context.Context, config *DeltaRestoreConfig) er defer func() { _ = deltaOps.CloseVolumeDev(volDev) deltaOps.UpdateRestoreStatus(volDevName, currentProgress, err) - lock.Unlock() + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock") + } }() progress := &progress{ @@ -791,7 +825,11 @@ func RestoreDeltaBlockBackupIncrementally(ctx context.Context, config *DeltaRest if err := lock.Lock(); err != nil { return err } - defer lock.Unlock() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock") + } + }() vol, err := loadVolume(bsDriver, srcVolumeName) if err != nil { @@ -858,7 +896,11 @@ func RestoreDeltaBlockBackupIncrementally(ctx context.Context, config *DeltaRest } go func() { defer volDev.Close() - defer lock.Unlock() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(err).Warn("Failed to unlock") + } + }() // This pre-truncate is to ensure the XFS speculatively // preallocates post-EOF blocks get reclaimed when volDev is @@ -1079,7 +1121,11 @@ func DeleteBackupVolume(volumeName string, destURL string) error { if err := lock.Lock(); err != nil { return err } - defer lock.Unlock() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock") + } + }() return removeVolume(volumeName, bsDriver) } @@ -1100,7 +1146,7 @@ func checkBlockReferenceCount(blockInfos map[string]*BlockInfo, backup *Backup, func getLatestBackup(backup *Backup, lastBackup *Backup) error { if lastBackup.SnapshotCreatedAt == "" { // FIXME - go lint points out that this copies a potentially locked sync.mutex - *lastBackup = *backup + *lastBackup = *backup // nolint:govet return nil } @@ -1116,7 +1162,7 @@ func getLatestBackup(backup *Backup, lastBackup *Backup) error { if backupTime.After(lastBackupTime) { // FIXME - go lint points out that this copies a potentially locked sync.mutex - *lastBackup = *backup + *lastBackup = *backup // nolint:govet } return nil @@ -1144,7 +1190,11 @@ func DeleteDeltaBlockBackup(backupURL string) error { if err := lock.Lock(); err != nil { return err } - defer lock.Unlock() + defer func() { + if unlockErr := lock.Unlock(); unlockErr != nil { + logrus.WithError(unlockErr).Warn("Failed to unlock") + } + }() // If we fail to load the backup we still want to proceed with the deletion of the backup file backupToBeDeleted, err := loadBackup(bsDriver, backupName, volumeName) diff --git a/vendor/github.com/longhorn/backupstore/fsops/fsops.go b/vendor/github.com/longhorn/backupstore/fsops/fsops.go index 157ff9db..e4292726 100644 --- a/vendor/github.com/longhorn/backupstore/fsops/fsops.go +++ b/vendor/github.com/longhorn/backupstore/fsops/fsops.go @@ -10,6 +10,7 @@ import ( "github.com/longhorn/backupstore" "github.com/longhorn/backupstore/util" + "github.com/sirupsen/logrus" ) const ( @@ -127,7 +128,9 @@ func (f *FileSystemOperator) List(path string) ([]string, error) { func (f *FileSystemOperator) Upload(src, dst string) error { tmpDst := dst + ".tmp" + "." + strconv.FormatInt(time.Now().UTC().UnixNano(), 10) if f.FileExists(tmpDst) { - f.Remove(tmpDst) + if err := f.Remove(tmpDst); err != nil { + logrus.WithError(err).Warnf("Failed to remove tmp file %s", tmpDst) + } } if err := f.preparePath(dst); err != nil { return err diff --git a/vendor/github.com/longhorn/backupstore/util/util.go b/vendor/github.com/longhorn/backupstore/util/util.go index 39405011..ff291b22 100644 --- a/vendor/github.com/longhorn/backupstore/util/util.go +++ b/vendor/github.com/longhorn/backupstore/util/util.go @@ -333,7 +333,7 @@ func EnsureMountPoint(Kind, mountPoint string, mounter mount.Interface, log logr } }() - notMounted, err := mount.IsNotMountPoint(mounter, mountPoint) + isMoundPoint, err := mounter.IsMountPoint(mountPoint) if err == fs.ErrNotExist { return false, nil } @@ -352,10 +352,10 @@ func EnsureMountPoint(Kind, mountPoint string, mounter mount.Interface, log logr if mntErr := cleanupMount(mountPoint, mounter, log); mntErr != nil { return true, errors.Wrapf(mntErr, "failed to clean up corrupted mount point %v", mountPoint) } - notMounted = true + isMoundPoint = false } - if notMounted { + if !isMoundPoint { return false, nil } @@ -400,36 +400,30 @@ func MountWithTimeout(mounter mount.Interface, source string, target string, fst // CleanUpMountPoints tries to clean up all existing mount points for existing backup stores func CleanUpMountPoints(mounter mount.Interface, log logrus.FieldLogger) error { - var errs error - - filepath.Walk(MountDir, func(path string, info os.FileInfo, err error) error { + return filepath.Walk(MountDir, func(path string, info os.FileInfo, err error) error { if err != nil { - errs = multierr.Append(errs, errors.Wrapf(err, "failed to get file info of %v", path)) - return nil + return errors.Wrapf(err, "failed to get file info of %v", path) } if !info.IsDir() { return nil } - notMounted, err := mount.IsNotMountPoint(mounter, path) + isMountPoint, err := mounter.IsMountPoint(path) if err != nil { - errs = multierr.Append(errs, errors.Wrapf(err, "failed to check if %s is not mounted", path)) - return nil + return errors.Wrapf(err, "failed to check if %s is not mounted", path) } - if notMounted { + if !isMountPoint { return nil } if err := cleanupMount(path, mounter, log); err != nil { - errs = multierr.Append(errs, errors.Wrapf(err, "failed to clean up mount point %v", path)) + return errors.Wrapf(err, "failed to clean up mount point %v", path) } return nil }) - - return errs } func CheckBackupType(backupTarget string) (string, error) { diff --git a/vendor/modules.txt b/vendor/modules.txt index 5068d254..19ab7136 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -117,7 +117,7 @@ github.com/kr/pretty # github.com/kr/text v0.2.0 ## explicit github.com/kr/text -# github.com/longhorn/backupstore v0.0.0-20240417071544-3bd377eeefeb +# github.com/longhorn/backupstore v0.0.0-20240426093637-ac3867f121c0 ## explicit; go 1.21 github.com/longhorn/backupstore github.com/longhorn/backupstore/azblob @@ -139,13 +139,13 @@ github.com/longhorn/longhorn-engine/pkg/replica/client github.com/longhorn/longhorn-engine/pkg/types github.com/longhorn/longhorn-engine/pkg/util github.com/longhorn/longhorn-engine/pkg/util/disk -# github.com/longhorn/sparse-tools v0.0.0-20240228120902-ce8c4c2e71ca +# github.com/longhorn/sparse-tools v0.0.0-20240424162924-2651ad40ad19 ## explicit; go 1.17 github.com/longhorn/sparse-tools/sparse github.com/longhorn/sparse-tools/sparse/rest github.com/longhorn/sparse-tools/types github.com/longhorn/sparse-tools/util -# github.com/longhorn/types v0.0.0-20240417112740-a0d8514936b8 +# github.com/longhorn/types v0.0.0-20240424162824-4995e1e42438 ## explicit; go 1.21 github.com/longhorn/types/pkg/generated/bimrpc github.com/longhorn/types/pkg/generated/enginerpc