mirror of
https://github.com/lxc/incus.git
synced 2026-10-12 02:18:30 +00:00
+28
-47
@@ -163,10 +163,10 @@ func backupCreate(s *state.State, args db.InstanceBackup, sourceInst instance.In
|
||||
tarWriter := instancewriter.NewInstanceTarWriter(tarPipeWriter, idmapSet)
|
||||
|
||||
// Setup tar writer go routine, with optional compression.
|
||||
tarWriterRes := make(chan error)
|
||||
var compressErr error
|
||||
tarWriterRes := make(chan error, 1)
|
||||
|
||||
backupProgressWriter := &ioprogress.ProgressWriter{
|
||||
WriteCloser: tarFileWriter,
|
||||
Tracker: &ioprogress.ProgressTracker{
|
||||
Handler: func(value, speed int64) {
|
||||
_ = op.ExtendMetadata(map[string]any{"create_backup_progress": fmt.Sprintf("%s (%s/s)", units.GetByteSizeString(value, 2), units.GetByteSizeString(speed, 2))})
|
||||
@@ -177,32 +177,25 @@ func backupCreate(s *state.State, args db.InstanceBackup, sourceInst instance.In
|
||||
go func(resCh chan<- error) {
|
||||
l.Debug("Started backup tarball writer")
|
||||
defer l.Debug("Finished backup tarball writer")
|
||||
if compress != "none" {
|
||||
backupProgressWriter.WriteCloser = tarFileWriter
|
||||
compressErr = compressFile(compress, tarPipeReader, backupProgressWriter)
|
||||
|
||||
// If a compression error occurred, close the tarPipeWriter to end the export.
|
||||
if compressErr != nil {
|
||||
_ = tarPipeWriter.Close()
|
||||
}
|
||||
var err error
|
||||
if compress != "none" {
|
||||
err = compressFile(compress, tarPipeReader, backupProgressWriter)
|
||||
} else {
|
||||
backupProgressWriter.WriteCloser = tarFileWriter
|
||||
_, err = util.SafeCopy(backupProgressWriter, tarPipeReader)
|
||||
}
|
||||
|
||||
// On failure, fail any further tarball writes to end the export.
|
||||
if err != nil {
|
||||
_ = tarPipeReader.CloseWithError(err)
|
||||
}
|
||||
|
||||
resCh <- err
|
||||
}(tarWriterRes)
|
||||
|
||||
// Write index file.
|
||||
l.Debug("Adding backup index file")
|
||||
err = backupWriteIndex(sourceInst, pool, b.OptimizedStorage(), !b.InstanceOnly(), !b.RootOnly(), tarWriter)
|
||||
|
||||
// Check compression errors.
|
||||
if compressErr != nil {
|
||||
return compressErr
|
||||
}
|
||||
|
||||
// Check backupWriteIndex for errors.
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error writing backup index file: %w", err)
|
||||
}
|
||||
@@ -522,36 +515,30 @@ func volumeBackupCreate(s *state.State, args db.StoragePoolVolumeBackup, project
|
||||
tarWriter := instancewriter.NewInstanceTarWriter(tarPipeWriter, nil)
|
||||
|
||||
// Setup tar writer go routine, with optional compression.
|
||||
tarWriterRes := make(chan error)
|
||||
var compressErr error
|
||||
tarWriterRes := make(chan error, 1)
|
||||
|
||||
go func(resCh chan<- error) {
|
||||
l.Debug("Started backup tarball writer")
|
||||
defer l.Debug("Finished backup tarball writer")
|
||||
if compress != "none" {
|
||||
compressErr = compressFile(compress, tarPipeReader, fileWriter)
|
||||
|
||||
// If a compression error occurred, close the tarPipeWriter to end the export.
|
||||
if compressErr != nil {
|
||||
_ = tarPipeWriter.Close()
|
||||
}
|
||||
var err error
|
||||
if compress != "none" {
|
||||
err = compressFile(compress, tarPipeReader, fileWriter)
|
||||
} else {
|
||||
_, err = util.SafeCopy(fileWriter, tarPipeReader)
|
||||
}
|
||||
|
||||
// On failure, fail any further tarball writes to end the export.
|
||||
if err != nil {
|
||||
_ = tarPipeReader.CloseWithError(err)
|
||||
}
|
||||
|
||||
resCh <- err
|
||||
}(tarWriterRes)
|
||||
|
||||
// Write index file.
|
||||
l.Debug("Adding backup index file")
|
||||
err = volumeBackupWriteIndex(projectName, volumeName, pool, backupRow.OptimizedStorage, !backupRow.VolumeOnly, tarWriter)
|
||||
|
||||
// Check compression errors.
|
||||
if compressErr != nil {
|
||||
return compressErr
|
||||
}
|
||||
|
||||
// Check backupWriteIndex for errors.
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error writing backup index file: %w", err)
|
||||
}
|
||||
@@ -781,36 +768,30 @@ func bucketBackupCreate(s *state.State, args db.StoragePoolBucketBackup, project
|
||||
tarWriter := instancewriter.NewInstanceTarWriter(tarPipeWriter, nil)
|
||||
|
||||
// Setup tar writer go routine, with optional compression.
|
||||
tarWriterRes := make(chan error)
|
||||
var compressErr error
|
||||
tarWriterRes := make(chan error, 1)
|
||||
|
||||
go func(resCh chan<- error) {
|
||||
l.Debug("Started backup tarball writer")
|
||||
defer l.Debug("Finished backup tarball writer")
|
||||
if compress != "none" {
|
||||
compressErr = compressFile(compress, tarPipeReader, tarFileWriter)
|
||||
|
||||
// If a compression error occurred, close the tarPipeWriter to end the export.
|
||||
if compressErr != nil {
|
||||
_ = tarPipeWriter.Close()
|
||||
}
|
||||
var err error
|
||||
if compress != "none" {
|
||||
err = compressFile(compress, tarPipeReader, tarFileWriter)
|
||||
} else {
|
||||
_, err = util.SafeCopy(tarFileWriter, tarPipeReader)
|
||||
}
|
||||
|
||||
// On failure, fail any further tarball writes to end the export.
|
||||
if err != nil {
|
||||
_ = tarPipeReader.CloseWithError(err)
|
||||
}
|
||||
|
||||
resCh <- err
|
||||
}(tarWriterRes)
|
||||
|
||||
// Write index file.
|
||||
l.Debug("Adding backup index file")
|
||||
err = bucketBackupWriteIndex(projectName, bucketName, pool, tarWriter)
|
||||
|
||||
// Check compression errors.
|
||||
if compressErr != nil {
|
||||
return compressErr
|
||||
}
|
||||
|
||||
// Check backupWriteIndex for errors.
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error writing backup index file: %w", err)
|
||||
}
|
||||
|
||||
@@ -11097,8 +11097,19 @@ func (d *qemu) DeviceEventHandler(runConf *deviceConfig.RunConfig) error {
|
||||
}
|
||||
|
||||
if mount.Size > 0 {
|
||||
// Resize the active node, which is the top overlay when the disk has snapshots.
|
||||
nodeName := d.blockNodeName(linux.PathNameEncode(mount.DevName))
|
||||
blockDevs, err := d.fetchBlockDeviceChain(m, nodeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(blockDevs) > 0 {
|
||||
nodeName = blockDevs[len(blockDevs)-1]
|
||||
}
|
||||
|
||||
// Update the size.
|
||||
err = m.UpdateBlockSize(d.blockNodeName(linux.PathNameEncode(mount.DevName)), mount.Size)
|
||||
err = m.UpdateBlockSize(nodeName, mount.Size)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed updating disk size %q: %w", mount.DevName, err)
|
||||
}
|
||||
|
||||
@@ -498,6 +498,10 @@ func ovnAddReferencedACLs(info *api.NetworkACL, referencedACLNames map[string]st
|
||||
continue // Skip if the subject is an IP address, IP CIDR or IP range.
|
||||
}
|
||||
|
||||
if strings.HasPrefix(subject, "$") {
|
||||
continue // Skip address set references.
|
||||
}
|
||||
|
||||
// Anything else must be a referenced ACL name.
|
||||
// Record newly seen referenced ACL into authoritative list.
|
||||
referencedACLNames[subject] = struct{}{}
|
||||
|
||||
@@ -8185,11 +8185,25 @@ func (n *ovn) LoadBalancerUpdate(listenAddress string, req api.NetworkLoadBalanc
|
||||
reverter.Add(func() {
|
||||
// Apply old settings to OVN on failure.
|
||||
portMaps, err := n.loadBalancerValidate(net.ParseIP(curLoadBalancer.ListenAddress), &curLoadBalancer.NetworkLoadBalancerPut)
|
||||
if err == nil {
|
||||
vips := n.loadBalancerFlattenVIPs(net.ParseIP(curLoadBalancer.ListenAddress), portMaps)
|
||||
_ = n.ovnnb.CreateLoadBalancer(context.TODO(), n.getLoadBalancerName(curLoadBalancer.ListenAddress), n.getRouterName(), n.getIntSwitchName(), vips...)
|
||||
_ = n.forwardBGPSetupPrefixes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
vips := n.loadBalancerFlattenVIPs(net.ParseIP(curLoadBalancer.ListenAddress), portMaps)
|
||||
|
||||
healthCheck, err := n.getHealthCheck(curLoadBalancer.NetworkLoadBalancerPut)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if healthCheck != nil {
|
||||
for i := range vips {
|
||||
vips[i].HealthCheck = healthCheck
|
||||
}
|
||||
}
|
||||
|
||||
_ = n.ovnnb.CreateLoadBalancer(context.TODO(), n.getLoadBalancerName(curLoadBalancer.ListenAddress), n.getRouterName(), n.getIntSwitchName(), vips...)
|
||||
_ = n.forwardBGPSetupPrefixes()
|
||||
})
|
||||
|
||||
err = n.state.DB.Cluster.Transaction(context.TODO(), func(ctx context.Context, tx *db.ClusterTx) error {
|
||||
|
||||
@@ -9261,6 +9261,23 @@ func (b *backend) qcow2Resize(inst instance.Instance, vol drivers.Volume, size s
|
||||
return err
|
||||
}
|
||||
|
||||
// Move the GPT alt header to the end of the guest disk.
|
||||
if vol.IsVMBlock() {
|
||||
nbdPath, err := drivers.ConnectQemuNbd(volDiskPath, "qcow2", "", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = drivers.DisconnectQemuNbdWait(nbdPath)
|
||||
}()
|
||||
|
||||
err = drivers.MoveGPTAltHeader(b.logger, nbdPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -293,9 +293,14 @@ func (d *common) ApplyPatch(name string) error {
|
||||
// header where possible so that the backup header is where it is expected in case of any corruption with the
|
||||
// primary header.
|
||||
func (d *common) moveGPTAltHeader(devPath string) error {
|
||||
return MoveGPTAltHeader(d.logger, devPath)
|
||||
}
|
||||
|
||||
// MoveGPTAltHeader moves the GPT alternative header to the end of the disk device supplied.
|
||||
func MoveGPTAltHeader(l logger.Logger, devPath string) error {
|
||||
path, err := exec.LookPath("sgdisk")
|
||||
if err != nil {
|
||||
d.logger.Warn("Skipped moving GPT alternative header to end of disk as sgdisk command not found", logger.Ctx{"dev": devPath})
|
||||
l.Warn("Skipped moving GPT alternative header to end of disk as sgdisk command not found", logger.Ctx{"dev": devPath})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -321,7 +326,7 @@ func (d *common) moveGPTAltHeader(devPath string) error {
|
||||
|
||||
_, err = subprocess.RunCommand(path, "--move-second-header", devPath)
|
||||
if err == nil {
|
||||
d.logger.Debug("Moved GPT alternative header to end of disk", logger.Ctx{"dev": devPath})
|
||||
l.Debug("Moved GPT alternative header to end of disk", logger.Ctx{"dev": devPath})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -131,8 +131,8 @@ func (d *lvm) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Oper
|
||||
}
|
||||
}
|
||||
|
||||
// Move the GPT alt header to end of disk if needed.
|
||||
if vol.IsVMBlock() {
|
||||
// Move the GPT alt header to end of disk if needed (the device holds a qcow2 container when qcow2).
|
||||
if vol.IsVMBlock() && !IsQcow2Block(vol) {
|
||||
err = d.moveGPTAltHeader(devPath)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -919,7 +919,8 @@ func (d *lvm) SetVolumeQuota(vol Volume, size string, allowUnsafeResize bool, op
|
||||
|
||||
// Move the VM GPT alt header to end of disk if needed (not needed in unsafe resize mode as it is
|
||||
// expected the caller will do all necessary post resize actions themselves).
|
||||
if vol.IsVMBlock() && !allowUnsafeResize {
|
||||
// The device holds a qcow2 container when qcow2, not the guest disk.
|
||||
if vol.IsVMBlock() && !allowUnsafeResize && !IsQcow2Block(vol) {
|
||||
// Activate the volume for resizing.
|
||||
activated, err := d.activateVolume(vol)
|
||||
if err != nil {
|
||||
|
||||
@@ -2073,6 +2073,17 @@ test_network_ovn_acl() {
|
||||
incus network acl rule add ingress-ping ingress action=allow protocol=icmp4 destination=10.10.10.1-10.10.11.1
|
||||
! incus exec c2 -- ping -c1 -w5 -4 10.10.11.2 || false
|
||||
|
||||
# Test address set subjects aren't treated as referenced ACLs.
|
||||
incus network address-set create pingset
|
||||
incus network address-set add pingset 10.10.11.2
|
||||
# shellcheck disable=2016
|
||||
incus network acl rule add ingress-ping ingress action=allow protocol=icmp4 destination='\$pingset'
|
||||
incus exec c2 -- ping -c1 -w5 -4 10.10.11.2
|
||||
! ovn-nbctl --bare --column=name --format=csv find port_group | grep -q incus_acl0_ || false
|
||||
# shellcheck disable=2016
|
||||
incus network acl rule remove ingress-ping ingress action=allow protocol=icmp4 destination='\$pingset'
|
||||
incus network address-set delete pingset
|
||||
|
||||
# Test ACL rule referencing our own ACL name as source in rule.
|
||||
incus network acl rule remove ingress-ping ingress action=allow protocol=icmp4 destination=10.10.10.1-10.10.11.1
|
||||
incus network acl rule add ingress-ping ingress action=allow protocol=icmp4 source=ingress-ping
|
||||
|
||||
Reference in New Issue
Block a user