From e1aa98ff64338f87290efbe41c79488a40e07ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= Date: Thu, 14 Nov 2024 01:45:54 -0500 Subject: [PATCH] incusd/instances/publish: Fix base metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #1371 Signed-off-by: Stéphane Graber --- .../server/instance/drivers/driver_lxc.go | 177 ++++++----------- .../server/instance/drivers/driver_qemu.go | 178 ++++++------------ 2 files changed, 123 insertions(+), 232 deletions(-) diff --git a/internal/server/instance/drivers/driver_lxc.go b/internal/server/instance/drivers/driver_lxc.go index 05336264d0c..dafe432e30a 100644 --- a/internal/server/instance/drivers/driver_lxc.go +++ b/internal/server/instance/drivers/driver_lxc.go @@ -5186,85 +5186,35 @@ func (d *lxc) Export(w io.Writer, properties map[string]string, expiration time. return nil } - // Look for metadata.yaml. - meta := api.ImageMetadata{} - - fnam := filepath.Join(cDir, "metadata.yaml") - if !util.PathExists(fnam) { - // Generate a new metadata.yaml. - tempDir, err := os.MkdirTemp("", "incus_metadata_") + // Get the instance's architecture. + var arch string + if d.IsSnapshot() { + parentName, _, _ := api.GetParentAndSnapshotName(d.name) + parent, err := instance.LoadByProjectAndName(d.state, d.project.Name, parentName) if err != nil { _ = tarWriter.Close() d.logger.Error("Failed exporting instance", ctxMap) return nil, err } - defer func() { _ = os.RemoveAll(tempDir) }() - - // Get the instance's architecture. - var arch string - if d.IsSnapshot() { - parentName, _, _ := api.GetParentAndSnapshotName(d.name) - parent, err := instance.LoadByProjectAndName(d.state, d.project.Name, parentName) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return meta, err - } - - arch, _ = osarch.ArchitectureName(parent.Architecture()) - } else { - arch, _ = osarch.ArchitectureName(d.architecture) - } - - if arch == "" { - arch, err = osarch.ArchitectureName(d.state.OS.Architectures[0]) - if err != nil { - d.logger.Error("Failed exporting instance", ctxMap) - return meta, err - } - } - - // Fill in the metadata. - meta.Architecture = arch - meta.CreationDate = time.Now().UTC().Unix() - meta.Properties = properties - if !expiration.IsZero() { - meta.ExpiryDate = expiration.UTC().Unix() - } - - data, err := yaml.Marshal(&meta) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + arch, _ = osarch.ArchitectureName(parent.Architecture()) + } else { + arch, _ = osarch.ArchitectureName(d.architecture) + } - // Write the actual file. - fnam = filepath.Join(tempDir, "metadata.yaml") - err = os.WriteFile(fnam, data, 0644) + if arch == "" { + arch, err = osarch.ArchitectureName(d.state.OS.Architectures[0]) if err != nil { - _ = tarWriter.Close() d.logger.Error("Failed exporting instance", ctxMap) return nil, err } + } - fi, err := os.Lstat(fnam) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + // Generate metadata.yaml. + meta := api.ImageMetadata{} + fnam := filepath.Join(cDir, "metadata.yaml") - tmpOffset := len(path.Dir(fnam)) + 1 - err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false) - if err != nil { - _ = tarWriter.Close() - d.logger.Debug("Error writing to tarfile", logger.Ctx{"err": err}) - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } - } else { + if util.PathExists(fnam) { // Parse the metadata. content, err := os.ReadFile(fnam) if err != nil { @@ -5279,65 +5229,60 @@ func (d *lxc) Export(w io.Writer, properties map[string]string, expiration time. d.logger.Error("Failed exporting instance", ctxMap) return nil, err } + } - if !expiration.IsZero() { - meta.ExpiryDate = expiration.UTC().Unix() - } + // Fill in the metadata. + meta.Architecture = arch + meta.CreationDate = time.Now().UTC().Unix() - if properties != nil { - meta.Properties = properties - } + if meta.Properties != nil { + meta.Properties = properties + } - if properties != nil || !expiration.IsZero() { - // Generate a new metadata.yaml. - tempDir, err := os.MkdirTemp("", "incus_metadata_") - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + if !expiration.IsZero() { + meta.ExpiryDate = expiration.UTC().Unix() + } - defer func() { _ = os.RemoveAll(tempDir) }() + // Write the new metadata.yaml. + tempDir, err := os.MkdirTemp("", "incus_metadata_") + if err != nil { + _ = tarWriter.Close() + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err + } - data, err := yaml.Marshal(&meta) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + defer func() { _ = os.RemoveAll(tempDir) }() - // Write the actual file. - fnam = filepath.Join(tempDir, "metadata.yaml") - err = os.WriteFile(fnam, data, 0644) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } - } + data, err := yaml.Marshal(&meta) + if err != nil { + _ = tarWriter.Close() + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err + } - // Include metadata.yaml in the tarball. - fi, err := os.Lstat(fnam) - if err != nil { - _ = tarWriter.Close() - d.logger.Debug("Error statting during export", logger.Ctx{"fileName": fnam}) - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + fnam = filepath.Join(tempDir, "metadata.yaml") + err = os.WriteFile(fnam, data, 0644) + if err != nil { + _ = tarWriter.Close() + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err + } - if properties != nil || !expiration.IsZero() { - tmpOffset := len(path.Dir(fnam)) + 1 - err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false) - } else { - err = tarWriter.WriteFile(fnam[offset:], fnam, fi, false) - } + // Add metadata.yaml to the tarball. + fi, err := os.Lstat(fnam) + if err != nil { + _ = tarWriter.Close() + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err + } - if err != nil { - _ = tarWriter.Close() - d.logger.Debug("Error writing to tarfile", logger.Ctx{"err": err}) - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + tmpOffset := len(filepath.Dir(fnam)) + 1 + err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false) + if err != nil { + _ = tarWriter.Close() + d.logger.Debug("Error writing to tarfile", logger.Ctx{"err": err}) + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err } // Include all the rootfs files. diff --git a/internal/server/instance/drivers/driver_qemu.go b/internal/server/instance/drivers/driver_qemu.go index f202c3092d4..fac8cac6003 100644 --- a/internal/server/instance/drivers/driver_qemu.go +++ b/internal/server/instance/drivers/driver_qemu.go @@ -6376,84 +6376,35 @@ func (d *qemu) Export(w io.Writer, properties map[string]string, expiration time return nil } - // Look for metadata.yaml. - meta := api.ImageMetadata{} - - fnam := filepath.Join(cDir, "metadata.yaml") - if !util.PathExists(fnam) { - // Generate a new metadata.yaml. - tempDir, err := os.MkdirTemp("", "incus_metadata_") + // Get the instance's architecture. + var arch string + if d.IsSnapshot() { + parentName, _, _ := api.GetParentAndSnapshotName(d.name) + parent, err := instance.LoadByProjectAndName(d.state, d.project.Name, parentName) if err != nil { _ = tarWriter.Close() d.logger.Error("Failed exporting instance", ctxMap) return nil, err } - defer func() { _ = os.RemoveAll(tempDir) }() - - // Get the instance's architecture. - var arch string - if d.IsSnapshot() { - parentName, _, _ := api.GetParentAndSnapshotName(d.name) - parent, err := instance.LoadByProjectAndName(d.state, d.project.Name, parentName) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return meta, err - } - - arch, _ = osarch.ArchitectureName(parent.Architecture()) - } else { - arch, _ = osarch.ArchitectureName(d.architecture) - } - - if arch == "" { - arch, err = osarch.ArchitectureName(d.state.OS.Architectures[0]) - if err != nil { - d.logger.Error("Failed exporting instance", ctxMap) - return meta, err - } - } - - // Fill in the metadata. - meta.Architecture = arch - meta.CreationDate = time.Now().UTC().Unix() - meta.Properties = properties - if !expiration.IsZero() { - meta.ExpiryDate = expiration.UTC().Unix() - } - - data, err := yaml.Marshal(&meta) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + arch, _ = osarch.ArchitectureName(parent.Architecture()) + } else { + arch, _ = osarch.ArchitectureName(d.architecture) + } - // Write the actual file. - fnam = filepath.Join(tempDir, "metadata.yaml") - err = os.WriteFile(fnam, data, 0644) + if arch == "" { + arch, err = osarch.ArchitectureName(d.state.OS.Architectures[0]) if err != nil { - _ = tarWriter.Close() d.logger.Error("Failed exporting instance", ctxMap) return nil, err } + } - fi, err := os.Lstat(fnam) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + // Generate metadata.yaml. + meta := api.ImageMetadata{} + fnam := filepath.Join(cDir, "metadata.yaml") - tmpOffset := len(filepath.Dir(fnam)) + 1 - err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } - } else { + if util.PathExists(fnam) { // Parse the metadata. content, err := os.ReadFile(fnam) if err != nil { @@ -6468,65 +6419,60 @@ func (d *qemu) Export(w io.Writer, properties map[string]string, expiration time d.logger.Error("Failed exporting instance", ctxMap) return nil, err } + } - if !expiration.IsZero() { - meta.ExpiryDate = expiration.UTC().Unix() - } + // Fill in the metadata. + meta.Architecture = arch + meta.CreationDate = time.Now().UTC().Unix() - if properties != nil { - meta.Properties = properties - } + if meta.Properties != nil { + meta.Properties = properties + } - if properties != nil || !expiration.IsZero() { - // Generate a new metadata.yaml. - tempDir, err := os.MkdirTemp("", "incus_metadata_") - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + if !expiration.IsZero() { + meta.ExpiryDate = expiration.UTC().Unix() + } - defer func() { _ = os.RemoveAll(tempDir) }() + // Write the new metadata.yaml. + tempDir, err := os.MkdirTemp("", "incus_metadata_") + if err != nil { + _ = tarWriter.Close() + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err + } - data, err := yaml.Marshal(&meta) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + defer func() { _ = os.RemoveAll(tempDir) }() - // Write the actual file. - fnam = filepath.Join(tempDir, "metadata.yaml") - err = os.WriteFile(fnam, data, 0644) - if err != nil { - _ = tarWriter.Close() - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } - } + data, err := yaml.Marshal(&meta) + if err != nil { + _ = tarWriter.Close() + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err + } - // Include metadata.yaml in the tarball. - fi, err := os.Lstat(fnam) - if err != nil { - _ = tarWriter.Close() - d.logger.Debug("Error statting during export", logger.Ctx{"fileName": fnam}) - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + fnam = filepath.Join(tempDir, "metadata.yaml") + err = os.WriteFile(fnam, data, 0644) + if err != nil { + _ = tarWriter.Close() + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err + } - if properties != nil || !expiration.IsZero() { - tmpOffset := len(filepath.Dir(fnam)) + 1 - err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false) - } else { - err = tarWriter.WriteFile(fnam[offset:], fnam, fi, false) - } + // Add metadata.yaml to the tarball. + fi, err := os.Lstat(fnam) + if err != nil { + _ = tarWriter.Close() + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err + } - if err != nil { - _ = tarWriter.Close() - d.logger.Debug("Error writing to tarfile", logger.Ctx{"err": err}) - d.logger.Error("Failed exporting instance", ctxMap) - return nil, err - } + tmpOffset := len(filepath.Dir(fnam)) + 1 + err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false) + if err != nil { + _ = tarWriter.Close() + d.logger.Debug("Error writing to tarfile", logger.Ctx{"err": err}) + d.logger.Error("Failed exporting instance", ctxMap) + return nil, err } // Convert from raw to qcow2 and add to tarball. @@ -6575,7 +6521,7 @@ func (d *qemu) Export(w io.Writer, properties map[string]string, expiration time } // Read converted file info and write file to tarball. - fi, err := os.Lstat(fPath) + fi, err = os.Lstat(fPath) if err != nil { return nil, err }