Skip to content

Commit e019bb2

Browse files
authored
Merge pull request #1374 from stgraber/publish
incusd/instances/publish: Fix base metadata
2 parents ccaa4de + 4abcc7e commit e019bb2

File tree

5 files changed

+166
-267
lines changed

5 files changed

+166
-267
lines changed

cmd/incus/top.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func (c *cmdTop) Run(cmd *cobra.Command, args []string) error {
191191

192192
// These variables can be changed by the UI
193193
refreshInterval := time.Duration(c.flagRefresh) * time.Second
194-
sortingMethod := alphabetical // default is alphabetical, could change this to a flag
194+
sortingMethod := alphabetical // default is alphabetical, could change this to a flag
195195

196196
// Start the ticker for periodic updates
197197
ticker := time.NewTicker(refreshInterval)

cmd/incusd/images.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -346,16 +346,11 @@ func imgPostInstanceInfo(ctx context.Context, s *state.State, r *http.Request, r
346346
}
347347

348348
// Export instance to writer.
349-
var meta api.ImageMetadata
349+
var meta *api.ImageMetadata
350350

351351
writer = internalIO.NewQuotaWriter(writer, budget)
352352
meta, err = c.Export(writer, req.Properties, req.ExpiresAt, tracker)
353353

354-
// Get ExpiresAt
355-
if meta.ExpiryDate != 0 {
356-
info.ExpiresAt = time.Unix(meta.ExpiryDate, 0)
357-
}
358-
359354
// Clean up file handles.
360355
// When compression is used, Close on imageProgressWriter/tarWriter is required for compressFile/gzip to
361356
// know it is finished. Otherwise it is equivalent to imageFile.Close.
@@ -373,6 +368,11 @@ func imgPostInstanceInfo(ctx context.Context, s *state.State, r *http.Request, r
373368
return nil, err
374369
}
375370

371+
// Get ExpiresAt
372+
if meta.ExpiryDate != 0 {
373+
info.ExpiresAt = time.Unix(meta.ExpiryDate, 0)
374+
}
375+
376376
fi, err := os.Stat(imageFile.Name())
377377
if err != nil {
378378
return nil, err

internal/server/instance/drivers/driver_lxc.go

Lines changed: 77 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -5135,16 +5135,14 @@ func (d *lxc) Update(args db.InstanceArgs, userRequested bool) error {
51355135
}
51365136

51375137
// Export backs up the instance.
5138-
func (d *lxc) Export(w io.Writer, properties map[string]string, expiration time.Time, tracker *ioprogress.ProgressTracker) (api.ImageMetadata, error) {
5138+
func (d *lxc) Export(w io.Writer, properties map[string]string, expiration time.Time, tracker *ioprogress.ProgressTracker) (*api.ImageMetadata, error) {
51395139
ctxMap := logger.Ctx{
51405140
"created": d.creationDate,
51415141
"ephemeral": d.ephemeral,
51425142
"used": d.lastUsedDate}
51435143

5144-
meta := api.ImageMetadata{}
5145-
51465144
if d.IsRunning() {
5147-
return meta, fmt.Errorf("Cannot export a running instance as an image")
5145+
return nil, fmt.Errorf("Cannot export a running instance as an image")
51485146
}
51495147

51505148
d.logger.Info("Exporting instance", ctxMap)
@@ -5153,7 +5151,7 @@ func (d *lxc) Export(w io.Writer, properties map[string]string, expiration time.
51535151
_, err := d.mount()
51545152
if err != nil {
51555153
d.logger.Error("Failed exporting instance", ctxMap)
5156-
return meta, err
5154+
return nil, err
51575155
}
51585156

51595157
defer func() { _ = d.unmount() }()
@@ -5162,7 +5160,7 @@ func (d *lxc) Export(w io.Writer, properties map[string]string, expiration time.
51625160
idmap, err := d.DiskIdmap()
51635161
if err != nil {
51645162
d.logger.Error("Failed exporting instance", ctxMap)
5165-
return meta, err
5163+
return nil, err
51665164
}
51675165

51685166
// Create the tarball.
@@ -5188,164 +5186,115 @@ func (d *lxc) Export(w io.Writer, properties map[string]string, expiration time.
51885186
return nil
51895187
}
51905188

5191-
// Look for metadata.yaml.
5192-
fnam := filepath.Join(cDir, "metadata.yaml")
5193-
if !util.PathExists(fnam) {
5194-
// Generate a new metadata.yaml.
5195-
tempDir, err := os.MkdirTemp("", "incus_metadata_")
5189+
// Get the instance's architecture.
5190+
var arch string
5191+
if d.IsSnapshot() {
5192+
parentName, _, _ := api.GetParentAndSnapshotName(d.name)
5193+
parent, err := instance.LoadByProjectAndName(d.state, d.project.Name, parentName)
51965194
if err != nil {
51975195
_ = tarWriter.Close()
51985196
d.logger.Error("Failed exporting instance", ctxMap)
5199-
return meta, err
5200-
}
5201-
5202-
defer func() { _ = os.RemoveAll(tempDir) }()
5203-
5204-
// Get the instance's architecture.
5205-
var arch string
5206-
if d.IsSnapshot() {
5207-
parentName, _, _ := api.GetParentAndSnapshotName(d.name)
5208-
parent, err := instance.LoadByProjectAndName(d.state, d.project.Name, parentName)
5209-
if err != nil {
5210-
_ = tarWriter.Close()
5211-
d.logger.Error("Failed exporting instance", ctxMap)
5212-
return meta, err
5213-
}
5214-
5215-
arch, _ = osarch.ArchitectureName(parent.Architecture())
5216-
} else {
5217-
arch, _ = osarch.ArchitectureName(d.architecture)
5218-
}
5219-
5220-
if arch == "" {
5221-
arch, err = osarch.ArchitectureName(d.state.OS.Architectures[0])
5222-
if err != nil {
5223-
d.logger.Error("Failed exporting instance", ctxMap)
5224-
return meta, err
5225-
}
5226-
}
5227-
5228-
// Fill in the metadata.
5229-
meta.Architecture = arch
5230-
meta.CreationDate = time.Now().UTC().Unix()
5231-
meta.Properties = properties
5232-
if !expiration.IsZero() {
5233-
meta.ExpiryDate = expiration.UTC().Unix()
5197+
return nil, err
52345198
}
52355199

5236-
data, err := yaml.Marshal(&meta)
5237-
if err != nil {
5238-
_ = tarWriter.Close()
5239-
d.logger.Error("Failed exporting instance", ctxMap)
5240-
return meta, err
5241-
}
5200+
arch, _ = osarch.ArchitectureName(parent.Architecture())
5201+
} else {
5202+
arch, _ = osarch.ArchitectureName(d.architecture)
5203+
}
52425204

5243-
// Write the actual file.
5244-
fnam = filepath.Join(tempDir, "metadata.yaml")
5245-
err = os.WriteFile(fnam, data, 0644)
5205+
if arch == "" {
5206+
arch, err = osarch.ArchitectureName(d.state.OS.Architectures[0])
52465207
if err != nil {
5247-
_ = tarWriter.Close()
52485208
d.logger.Error("Failed exporting instance", ctxMap)
5249-
return meta, err
5209+
return nil, err
52505210
}
5211+
}
52515212

5252-
fi, err := os.Lstat(fnam)
5253-
if err != nil {
5254-
_ = tarWriter.Close()
5255-
d.logger.Error("Failed exporting instance", ctxMap)
5256-
return meta, err
5257-
}
5213+
// Generate metadata.yaml.
5214+
meta := api.ImageMetadata{}
5215+
fnam := filepath.Join(cDir, "metadata.yaml")
52585216

5259-
tmpOffset := len(path.Dir(fnam)) + 1
5260-
err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false)
5261-
if err != nil {
5262-
_ = tarWriter.Close()
5263-
d.logger.Debug("Error writing to tarfile", logger.Ctx{"err": err})
5264-
d.logger.Error("Failed exporting instance", ctxMap)
5265-
return meta, err
5266-
}
5267-
} else {
5217+
if util.PathExists(fnam) {
52685218
// Parse the metadata.
52695219
content, err := os.ReadFile(fnam)
52705220
if err != nil {
52715221
_ = tarWriter.Close()
52725222
d.logger.Error("Failed exporting instance", ctxMap)
5273-
return meta, err
5223+
return nil, err
52745224
}
52755225

52765226
err = yaml.Unmarshal(content, &meta)
52775227
if err != nil {
52785228
_ = tarWriter.Close()
52795229
d.logger.Error("Failed exporting instance", ctxMap)
5280-
return meta, err
5230+
return nil, err
52815231
}
5232+
}
52825233

5283-
if !expiration.IsZero() {
5284-
meta.ExpiryDate = expiration.UTC().Unix()
5285-
}
5234+
// Fill in the metadata.
5235+
meta.Architecture = arch
5236+
meta.CreationDate = time.Now().UTC().Unix()
52865237

5287-
if properties != nil {
5288-
meta.Properties = properties
5289-
}
5238+
if meta.Properties == nil {
5239+
meta.Properties = map[string]string{}
5240+
}
52905241

5291-
if properties != nil || !expiration.IsZero() {
5292-
// Generate a new metadata.yaml.
5293-
tempDir, err := os.MkdirTemp("", "incus_metadata_")
5294-
if err != nil {
5295-
_ = tarWriter.Close()
5296-
d.logger.Error("Failed exporting instance", ctxMap)
5297-
return meta, err
5298-
}
5242+
for k, v := range properties {
5243+
meta.Properties[k] = v
5244+
}
52995245

5300-
defer func() { _ = os.RemoveAll(tempDir) }()
5246+
if !expiration.IsZero() {
5247+
meta.ExpiryDate = expiration.UTC().Unix()
5248+
}
53015249

5302-
data, err := yaml.Marshal(&meta)
5303-
if err != nil {
5304-
_ = tarWriter.Close()
5305-
d.logger.Error("Failed exporting instance", ctxMap)
5306-
return meta, err
5307-
}
5250+
// Write the new metadata.yaml.
5251+
tempDir, err := os.MkdirTemp("", "incus_metadata_")
5252+
if err != nil {
5253+
_ = tarWriter.Close()
5254+
d.logger.Error("Failed exporting instance", ctxMap)
5255+
return nil, err
5256+
}
53085257

5309-
// Write the actual file.
5310-
fnam = filepath.Join(tempDir, "metadata.yaml")
5311-
err = os.WriteFile(fnam, data, 0644)
5312-
if err != nil {
5313-
_ = tarWriter.Close()
5314-
d.logger.Error("Failed exporting instance", ctxMap)
5315-
return meta, err
5316-
}
5317-
}
5258+
defer func() { _ = os.RemoveAll(tempDir) }()
53185259

5319-
// Include metadata.yaml in the tarball.
5320-
fi, err := os.Lstat(fnam)
5321-
if err != nil {
5322-
_ = tarWriter.Close()
5323-
d.logger.Debug("Error statting during export", logger.Ctx{"fileName": fnam})
5324-
d.logger.Error("Failed exporting instance", ctxMap)
5325-
return meta, err
5326-
}
5260+
data, err := yaml.Marshal(&meta)
5261+
if err != nil {
5262+
_ = tarWriter.Close()
5263+
d.logger.Error("Failed exporting instance", ctxMap)
5264+
return nil, err
5265+
}
53275266

5328-
if properties != nil || !expiration.IsZero() {
5329-
tmpOffset := len(path.Dir(fnam)) + 1
5330-
err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false)
5331-
} else {
5332-
err = tarWriter.WriteFile(fnam[offset:], fnam, fi, false)
5333-
}
5267+
fnam = filepath.Join(tempDir, "metadata.yaml")
5268+
err = os.WriteFile(fnam, data, 0644)
5269+
if err != nil {
5270+
_ = tarWriter.Close()
5271+
d.logger.Error("Failed exporting instance", ctxMap)
5272+
return nil, err
5273+
}
53345274

5335-
if err != nil {
5336-
_ = tarWriter.Close()
5337-
d.logger.Debug("Error writing to tarfile", logger.Ctx{"err": err})
5338-
d.logger.Error("Failed exporting instance", ctxMap)
5339-
return meta, err
5340-
}
5275+
// Add metadata.yaml to the tarball.
5276+
fi, err := os.Lstat(fnam)
5277+
if err != nil {
5278+
_ = tarWriter.Close()
5279+
d.logger.Error("Failed exporting instance", ctxMap)
5280+
return nil, err
5281+
}
5282+
5283+
tmpOffset := len(filepath.Dir(fnam)) + 1
5284+
err = tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false)
5285+
if err != nil {
5286+
_ = tarWriter.Close()
5287+
d.logger.Debug("Error writing to tarfile", logger.Ctx{"err": err})
5288+
d.logger.Error("Failed exporting instance", ctxMap)
5289+
return nil, err
53415290
}
53425291

53435292
// Include all the rootfs files.
53445293
fnam = d.RootfsPath()
53455294
err = filepath.Walk(fnam, writeToTar)
53465295
if err != nil {
53475296
d.logger.Error("Failed exporting instance", ctxMap)
5348-
return meta, err
5297+
return nil, err
53495298
}
53505299

53515300
// Include all the templates.
@@ -5354,18 +5303,18 @@ func (d *lxc) Export(w io.Writer, properties map[string]string, expiration time.
53545303
err = filepath.Walk(fnam, writeToTar)
53555304
if err != nil {
53565305
d.logger.Error("Failed exporting instance", ctxMap)
5357-
return meta, err
5306+
return nil, err
53585307
}
53595308
}
53605309

53615310
err = tarWriter.Close()
53625311
if err != nil {
53635312
d.logger.Error("Failed exporting instance", ctxMap)
5364-
return meta, err
5313+
return nil, err
53655314
}
53665315

53675316
d.logger.Info("Exported instance", ctxMap)
5368-
return meta, nil
5317+
return &meta, nil
53695318
}
53705319

53715320
func collectCRIULogFile(d instance.Instance, imagesDir string, function string, method string) error {

0 commit comments

Comments
 (0)