add WithPlatform in bundle unpack (#486)

* add WithPlatform in bundle unpack

Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com>

* fix OCIImageExtractor

Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com>

* add unit test and fix comments

Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com>

---------

Signed-off-by: Nianyu Shen <xiaoyu9964@gmail.com>
This commit is contained in:
Nianyu Shen 2024-08-30 16:36:14 -07:00 committed by GitHub
parent 2f6a3fc39e
commit dc46baf6e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 3 deletions

View File

@ -1,10 +1,13 @@
package bundles_test
import (
"debug/elf"
"fmt"
"io"
"os"
"path"
"path/filepath"
"runtime"
. "github.com/kairos-io/kairos-sdk/bundles"
. "github.com/onsi/ginkgo/v2"
@ -29,7 +32,29 @@ var _ = Describe("Bundle", func() {
defer os.RemoveAll(dir)
err = RunBundles([]BundleOption{WithDBPath(dir), WithRootFS(dir), WithTarget("container://quay.io/mocaccino/extra:edgevpn-utils-0.15.0")})
Expect(err).ToNot(HaveOccurred())
Expect(filepath.Join(dir, "usr", "bin", "edgevpn")).To(BeARegularFile())
binPath := filepath.Join(dir, "usr", "bin", "edgevpn")
Expect(binPath).To(BeARegularFile())
expectBinaryArch(binPath, runtime.GOARCH)
})
When("platform is specified", func() {
for _, arch := range []string{"amd64", "arm64", "arm/v7"} {
It(fmt.Sprintf("install with %s", arch), func() {
dir, err := os.MkdirTemp("", "test")
Expect(err).ToNot(HaveOccurred())
defer os.RemoveAll(dir)
err = RunBundles([]BundleOption{
WithDBPath(dir),
WithRootFS(dir),
WithTarget("container://quay.io/luet/base:0.35.5"),
WithPlatform(fmt.Sprintf("linux/%s", arch)),
})
Expect(err).ToNot(HaveOccurred())
binPath := filepath.Join(dir, "usr", "bin", "luet")
Expect(binPath).To(BeARegularFile())
expectBinaryArch(binPath, arch)
})
}
})
When("local is true", func() {
@ -205,3 +230,18 @@ func expectInstalled(installer BundleInstaller, config *BundleConfig) {
_, err = os.Stat("/etc/cos/grub.cfg")
Expect(err).ToNot(HaveOccurred())
}
func expectBinaryArch(path string, arch string) {
f, err := elf.Open(path)
Expect(err).ToNot(HaveOccurred())
switch arch {
case "amd64":
Expect(f.Machine.String()).To(Equal(elf.EM_X86_64.String()))
case "arm64":
Expect(f.Machine.String()).To(Equal(elf.EM_AARCH64.String()))
case "arm/v7":
Expect(f.Machine.String()).To(Equal(elf.EM_ARM.String()))
default:
Fail(fmt.Sprintf("unsupported arch: %s", arch))
}
}

View File

@ -27,6 +27,7 @@ type BundleConfig struct {
LocalFile bool
Auth *registrytypes.AuthConfig
Transport http.RoundTripper
Platform string
}
// BundleOption defines a configuration option for a bundle.
@ -93,6 +94,13 @@ func WithTransport(t http.RoundTripper) BundleOption {
}
}
func WithPlatform(p string) BundleOption {
return func(bc *BundleConfig) error {
bc.Platform = p
return nil
}
}
func (bc *BundleConfig) extractRepo() (string, string, error) {
s := strings.Split(bc.Repository, "://")
if len(s) != 2 {
@ -204,10 +212,11 @@ func (e OCIImageExtractor) Install(config *BundleConfig) error {
if err != nil {
return err
}
if e.Local {
img, err = tarball.ImageFromPath(target, nil)
} else {
img, err = utils.GetImage(target, utils.GetCurrentPlatform(), config.Auth, config.Transport)
img, err = utils.GetImage(target, config.Platform, config.Auth, config.Transport)
}
if err != nil {
return err
@ -233,10 +242,11 @@ func (e OCIImageRunner) Install(config *BundleConfig) error {
if err != nil {
return err
}
if e.Local {
img, err = tarball.ImageFromPath(target, nil)
} else {
img, err = utils.GetImage(target, utils.GetCurrentPlatform(), config.Auth, config.Transport)
img, err = utils.GetImage(target, config.Platform, config.Auth, config.Transport)
}
if err != nil {
return err