mirror of
https://github.com/mudler/luet.git
synced 2025-09-09 11:10:07 +00:00
54 lines
1.3 KiB
Go
54 lines
1.3 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/containerd/containerd/images/archive"
|
|
"github.com/docker/distribution/reference"
|
|
)
|
|
|
|
// SaveImage exports an image as a tarball which can then be imported by docker.
|
|
func (c *Client) SaveImage(ctx context.Context, image, format string, writer io.WriteCloser) error {
|
|
// Parse the image name and tag.
|
|
named, err := reference.ParseNormalizedNamed(image)
|
|
if err != nil {
|
|
return fmt.Errorf("parsing image name %q failed: %v", image, err)
|
|
}
|
|
// Add the latest lag if they did not provide one.
|
|
named = reference.TagNameOnly(named)
|
|
image = named.String()
|
|
|
|
// Create the worker opts.
|
|
opt, err := c.createWorkerOpt(false)
|
|
if err != nil {
|
|
return fmt.Errorf("creating worker opt failed: %v", err)
|
|
}
|
|
|
|
if opt.ImageStore == nil {
|
|
return errors.New("image store is nil")
|
|
}
|
|
|
|
exportOpts := []archive.ExportOpt{
|
|
archive.WithImage(opt.ImageStore, image),
|
|
}
|
|
|
|
switch format {
|
|
case "docker":
|
|
|
|
case "oci":
|
|
exportOpts = append(exportOpts, archive.WithSkipDockerManifest())
|
|
|
|
default:
|
|
return fmt.Errorf("%q is not a valid format", format)
|
|
}
|
|
|
|
if err := archive.Export(ctx, opt.ContentStore, writer, exportOpts...); err != nil {
|
|
return fmt.Errorf("exporting image %s failed: %v", image, err)
|
|
}
|
|
|
|
return writer.Close()
|
|
}
|