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")
|
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.
|
// Get some temporary storage.
|
||||||
ociPath, err := os.MkdirTemp("", "incus-oci-")
|
ociPath, err := os.MkdirTemp("", "incus-oci-")
|
||||||
if err != nil {
|
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"})
|
req.ProgressHandler(ioprogress.ProgressData{Text: "Retrieving OCI image from registry"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageTag := "latest"
|
||||||
|
|
||||||
stdout, _, err := subprocess.RunCommandSplit(
|
stdout, _, err := subprocess.RunCommandSplit(
|
||||||
ctx,
|
ctx,
|
||||||
env,
|
env,
|
||||||
@@ -192,7 +189,7 @@ func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*I
|
|||||||
"copy",
|
"copy",
|
||||||
"--remove-signatures",
|
"--remove-signatures",
|
||||||
fmt.Sprintf("%s/%s", strings.Replace(r.httpHost, "https://", "docker://", 1), info.Alias),
|
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 {
|
if err != nil {
|
||||||
logger.Debug("Error copying remote image to local", logger.Ctx{"image": info.Alias, "stdout": stdout, "stderr": err})
|
logger.Debug("Error copying remote image to local", logger.Ctx{"image": info.Alias, "stdout": stdout, "stderr": err})
|
||||||
return nil, 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"})
|
req.ProgressHandler(ioprogress.ProgressData{Text: "Unpacking the OCI image"})
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, err = subprocess.RunCommand(
|
err = unpackOCIImage(filepath.Join(ociPath, "oci"), imageTag, filepath.Join(ociPath, "image"))
|
||||||
"umoci",
|
|
||||||
"unpack",
|
|
||||||
"--keep-dirlinks",
|
|
||||||
"--image", filepath.Join(ociPath, "oci"),
|
|
||||||
filepath.Join(ociPath, "image"))
|
|
||||||
if err != nil {
|
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
|
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