mirror of
https://github.com/lxc/incus.git
synced 2026-02-05 09:46:19 +01:00
client: Use the umoci Go package instead of the command
Signed-off-by: Piotr Resztak <piotr.resztak@futurfusion.io>
This commit is contained in:
committed by
Stéphane Graber
parent
341d4252f4
commit
727041a1c2
@@ -155,11 +155,6 @@ func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*I
|
||||
return nil, fmt.Errorf("OCI image export currently requires root access")
|
||||
}
|
||||
|
||||
_, err = exec.LookPath("umoci")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("OCI container handling requires \"umoci\" be present on the system")
|
||||
}
|
||||
|
||||
// Get some temporary storage.
|
||||
ociPath, err := os.MkdirTemp("", "incus-oci-")
|
||||
if err != nil {
|
||||
@@ -183,6 +178,8 @@ func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*I
|
||||
req.ProgressHandler(ioprogress.ProgressData{Text: "Retrieving OCI image from registry"})
|
||||
}
|
||||
|
||||
imageTag := "latest"
|
||||
|
||||
stdout, _, err := subprocess.RunCommandSplit(
|
||||
ctx,
|
||||
env,
|
||||
@@ -192,7 +189,7 @@ func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*I
|
||||
"copy",
|
||||
"--remove-signatures",
|
||||
fmt.Sprintf("%s/%s", strings.Replace(r.httpHost, "https://", "docker://", 1), info.Alias),
|
||||
fmt.Sprintf("oci:%s:latest", filepath.Join(ociPath, "oci")))
|
||||
fmt.Sprintf("oci:%s:%s", filepath.Join(ociPath, "oci"), imageTag))
|
||||
if err != nil {
|
||||
logger.Debug("Error copying remote image to local", logger.Ctx{"image": info.Alias, "stdout": stdout, "stderr": err})
|
||||
return nil, err
|
||||
@@ -203,14 +200,9 @@ func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*I
|
||||
req.ProgressHandler(ioprogress.ProgressData{Text: "Unpacking the OCI image"})
|
||||
}
|
||||
|
||||
stdout, err = subprocess.RunCommand(
|
||||
"umoci",
|
||||
"unpack",
|
||||
"--keep-dirlinks",
|
||||
"--image", filepath.Join(ociPath, "oci"),
|
||||
filepath.Join(ociPath, "image"))
|
||||
err = unpackOCIImage(filepath.Join(ociPath, "oci"), imageTag, filepath.Join(ociPath, "image"))
|
||||
if err != nil {
|
||||
logger.Debug("Error unpacking OCI image", logger.Ctx{"image": filepath.Join(ociPath, "oci"), "stdout": stdout, "stderr": err})
|
||||
logger.Debug("Error unpacking OCI image", logger.Ctx{"image": filepath.Join(ociPath, "oci"), "err": err})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
11
client/oci_util.go
Normal file
11
client/oci_util.go
Normal file
@@ -0,0 +1,11 @@
|
||||
//go:build !linux
|
||||
|
||||
package incus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func unpackOCIImage(imagePath string, imageTag string, bundlePath string) error {
|
||||
return fmt.Errorf("Platform isn't supported")
|
||||
}
|
||||
60
client/oci_util_linux.go
Normal file
60
client/oci_util_linux.go
Normal file
@@ -0,0 +1,60 @@
|
||||
//go:build linux
|
||||
|
||||
package incus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/opencontainers/umoci"
|
||||
"github.com/opencontainers/umoci/oci/cas/dir"
|
||||
"github.com/opencontainers/umoci/oci/casext"
|
||||
"github.com/opencontainers/umoci/oci/layer"
|
||||
|
||||
"github.com/lxc/incus/v6/shared/logger"
|
||||
)
|
||||
|
||||
// Custom handler to intercept logs.
|
||||
type umociLogHandler struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
// HandleLog implements a proxy between apex/log and our logger.
|
||||
func (h *umociLogHandler) HandleLog(e *log.Entry) error {
|
||||
switch e.Level {
|
||||
case log.DebugLevel:
|
||||
logger.Debug(h.Message, logger.Ctx{"log": e.Message})
|
||||
case log.InfoLevel:
|
||||
logger.Info(h.Message, logger.Ctx{"log": e.Message})
|
||||
case log.WarnLevel:
|
||||
logger.Warn(h.Message, logger.Ctx{"log": e.Message})
|
||||
case log.ErrorLevel:
|
||||
logger.Error(h.Message, logger.Ctx{"log": e.Message})
|
||||
case log.FatalLevel:
|
||||
logger.Panic(h.Message, logger.Ctx{"log": e.Message})
|
||||
default:
|
||||
logger.Error("Unknown umoci log level", logger.Ctx{"log": e.Message})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func unpackOCIImage(imagePath string, imageTag string, bundlePath string) error {
|
||||
// Set the custom handler
|
||||
log.SetHandler(&umociLogHandler{Message: "Unpacking OCI image"})
|
||||
defer log.SetHandler(nil)
|
||||
|
||||
var unpackOptions layer.UnpackOptions
|
||||
unpackOptions.KeepDirlinks = true
|
||||
|
||||
// Get a reference to the CAS.
|
||||
engine, err := dir.Open(imagePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Open CAS: %w", err)
|
||||
}
|
||||
|
||||
engineExt := casext.NewEngine(engine)
|
||||
defer func() { _ = engine.Close() }()
|
||||
|
||||
return umoci.Unpack(engineExt, imageTag, bundlePath, unpackOptions)
|
||||
}
|
||||
Reference in New Issue
Block a user