mirror of
https://github.com/linka-cloud/d2vm.git
synced 2024-11-24 16:46:24 +00:00
arm64 support with grub-efi
* build / convert: add `--platform` flag to support linux/amd64 & linux/arm64 * build: add `--pull` flag * run/hetzner: add `--type` flag to select server type * run/hetzner: add `--location` flag to select server location Signed-off-by: Adphi <philippe.adrien.nousse@gmail.com>
This commit is contained in:
parent
f8fc729486
commit
d54b3f9a2c
2
.gitignore
vendored
2
.gitignore
vendored
@ -17,4 +17,4 @@ images
|
|||||||
docs/build
|
docs/build
|
||||||
docs-src
|
docs-src
|
||||||
/completions
|
/completions
|
||||||
/cmd/d2vm/run/sparsecat-linux-amd64
|
/cmd/d2vm/run/sparsecat-linux-*
|
||||||
|
@ -38,7 +38,7 @@ RUN apt-get update && \
|
|||||||
dosfstools \
|
dosfstools \
|
||||||
mount \
|
mount \
|
||||||
tar \
|
tar \
|
||||||
extlinux \
|
"$([ "$(uname -m)" = "x86_64" ] && echo extlinux)" \
|
||||||
cryptsetup-bin \
|
cryptsetup-bin \
|
||||||
qemu-utils && \
|
qemu-utils && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
|
@ -160,7 +160,7 @@ Flags:
|
|||||||
--append-to-cmdline string Extra kernel cmdline arguments to append to the generated one
|
--append-to-cmdline string Extra kernel cmdline arguments to append to the generated one
|
||||||
--boot-fs string Filesystem to use for the boot partition, ext4 or fat32
|
--boot-fs string Filesystem to use for the boot partition, ext4 or fat32
|
||||||
--boot-size uint Size of the boot partition in MB (default 100)
|
--boot-size uint Size of the boot partition in MB (default 100)
|
||||||
--bootloader string Bootloader to use: syslinux, grub, grub-bios, grub-efi (default "syslinux")
|
--bootloader string Bootloader to use: syslinux, grub, grub-bios, grub-efi, defaults to syslinux on amd64 and grub-efi on arm64
|
||||||
--force Override output qcow2 image
|
--force Override output qcow2 image
|
||||||
-h, --help help for convert
|
-h, --help help for convert
|
||||||
--keep-cache Keep the images after the build
|
--keep-cache Keep the images after the build
|
||||||
@ -168,6 +168,7 @@ Flags:
|
|||||||
--network-manager string Network manager to use for the image: none, netplan, ifupdown
|
--network-manager string Network manager to use for the image: none, netplan, ifupdown
|
||||||
-o, --output string The output image, the extension determine the image format, raw will be used if none. Supported formats: qcow2 qed raw vdi vhd vmdk (default "disk0.qcow2")
|
-o, --output string The output image, the extension determine the image format, raw will be used if none. Supported formats: qcow2 qed raw vdi vhd vmdk (default "disk0.qcow2")
|
||||||
-p, --password string Optional root user password
|
-p, --password string Optional root user password
|
||||||
|
--platform string Platform to use for the container disk image, linux/arm64 and linux/arm64 are supported (default "linux/amd64")
|
||||||
--pull Always pull docker image
|
--pull Always pull docker image
|
||||||
--push Push the container disk image to the registry
|
--push Push the container disk image to the registry
|
||||||
--raw Just convert the container to virtual machine image without installing anything more
|
--raw Just convert the container to virtual machine image without installing anything more
|
||||||
@ -317,7 +318,7 @@ Flags:
|
|||||||
--append-to-cmdline string Extra kernel cmdline arguments to append to the generated one
|
--append-to-cmdline string Extra kernel cmdline arguments to append to the generated one
|
||||||
--boot-fs string Filesystem to use for the boot partition, ext4 or fat32
|
--boot-fs string Filesystem to use for the boot partition, ext4 or fat32
|
||||||
--boot-size uint Size of the boot partition in MB (default 100)
|
--boot-size uint Size of the boot partition in MB (default 100)
|
||||||
--bootloader string Bootloader to use: syslinux, grub, grub-bios, grub-efi (default "syslinux")
|
--bootloader string Bootloader to use: syslinux, grub, grub-bios, grub-efi, defaults to syslinux on amd64 and grub-efi on arm64
|
||||||
--build-arg stringArray Set build-time variables
|
--build-arg stringArray Set build-time variables
|
||||||
-f, --file string Name of the Dockerfile
|
-f, --file string Name of the Dockerfile
|
||||||
--force Override output qcow2 image
|
--force Override output qcow2 image
|
||||||
@ -327,6 +328,8 @@ Flags:
|
|||||||
--network-manager string Network manager to use for the image: none, netplan, ifupdown
|
--network-manager string Network manager to use for the image: none, netplan, ifupdown
|
||||||
-o, --output string The output image, the extension determine the image format, raw will be used if none. Supported formats: qcow2 qed raw vdi vhd vmdk (default "disk0.qcow2")
|
-o, --output string The output image, the extension determine the image format, raw will be used if none. Supported formats: qcow2 qed raw vdi vhd vmdk (default "disk0.qcow2")
|
||||||
-p, --password string Optional root user password
|
-p, --password string Optional root user password
|
||||||
|
--platform string Platform to use for the container disk image, linux/arm64 and linux/arm64 are supported (default "linux/amd64")
|
||||||
|
--pull Always pull docker image
|
||||||
--push Push the container disk image to the registry
|
--push Push the container disk image to the registry
|
||||||
--raw Just convert the container to virtual machine image without installing anything more
|
--raw Just convert the container to virtual machine image without installing anything more
|
||||||
-s, --size string The output image size (default "10G")
|
-s, --size string The output image size (default "10G")
|
||||||
|
@ -33,7 +33,7 @@ func BootloaderByName(name string) (BootloaderProvider, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BootloaderProvider interface {
|
type BootloaderProvider interface {
|
||||||
New(c Config, r OSRelease) (Bootloader, error)
|
New(c Config, r OSRelease, arch string) (Bootloader, error)
|
||||||
Name() string
|
Name() string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
builder.go
27
builder.go
@ -82,11 +82,18 @@ type builder struct {
|
|||||||
luksPassword string
|
luksPassword string
|
||||||
|
|
||||||
cmdLineExtra string
|
cmdLineExtra string
|
||||||
|
arch string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBuilder(ctx context.Context, workdir, imgTag, disk string, size uint64, osRelease OSRelease, format string, cmdLineExtra string, splitBoot bool, bootFS BootFS, bootSize uint64, luksPassword string, bootLoader string) (Builder, error) {
|
func NewBuilder(ctx context.Context, workdir, imgTag, disk string, size uint64, osRelease OSRelease, format string, cmdLineExtra string, splitBoot bool, bootFS BootFS, bootSize uint64, luksPassword string, bootLoader string, platform string) (Builder, error) {
|
||||||
if err := checkDependencies(); err != nil {
|
var arch string
|
||||||
return nil, err
|
switch platform {
|
||||||
|
case "linux/amd64":
|
||||||
|
arch = "x86_64"
|
||||||
|
case "linux/arm64", "linux/aarch64":
|
||||||
|
arch = "arm64"
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unexpected platform: %s, supported platforms: linux/amd64, linux/arm64", platform)
|
||||||
}
|
}
|
||||||
if luksPassword != "" {
|
if luksPassword != "" {
|
||||||
if !splitBoot {
|
if !splitBoot {
|
||||||
@ -141,7 +148,7 @@ func NewBuilder(ctx context.Context, workdir, imgTag, disk string, size uint64,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
bl, err := blp.New(config, osRelease)
|
bl, err := blp.New(config, osRelease, arch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -184,6 +191,10 @@ func NewBuilder(ctx context.Context, workdir, imgTag, disk string, size uint64,
|
|||||||
bootSize: bootSize,
|
bootSize: bootSize,
|
||||||
bootFS: bootFS,
|
bootFS: bootFS,
|
||||||
luksPassword: luksPassword,
|
luksPassword: luksPassword,
|
||||||
|
arch: arch,
|
||||||
|
}
|
||||||
|
if err := b.checkDependencies(); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(b.mntPoint, os.ModePerm); err != nil {
|
if err := os.MkdirAll(b.mntPoint, os.ModePerm); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -490,9 +501,13 @@ func block(path string, size uint64) error {
|
|||||||
return f.Truncate(int64(size))
|
return f.Truncate(int64(size))
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkDependencies() error {
|
func (b *builder) checkDependencies() error {
|
||||||
var merr error
|
var merr error
|
||||||
for _, v := range []string{"mount", "blkid", "tar", "losetup", "parted", "kpartx", "qemu-img", "extlinux", "dd", "mkfs.ext4", "cryptsetup"} {
|
deps := []string{"mount", "blkid", "tar", "losetup", "parted", "kpartx", "qemu-img", "dd", "mkfs.ext4", "cryptsetup"}
|
||||||
|
if _, ok := b.bootloader.(*syslinux); ok {
|
||||||
|
deps = append(deps, "extlinux")
|
||||||
|
}
|
||||||
|
for _, v := range deps {
|
||||||
if _, err := exec2.LookPath(v); err != nil {
|
if _, err := exec2.LookPath(v); err != nil {
|
||||||
merr = multierr.Append(merr, err)
|
merr = multierr.Append(merr, err)
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ var (
|
|||||||
file = filepath.Join(args[0], "Dockerfile")
|
file = filepath.Join(args[0], "Dockerfile")
|
||||||
}
|
}
|
||||||
logrus.Infof("building docker image from %s", file)
|
logrus.Infof("building docker image from %s", file)
|
||||||
if err := docker.Build(cmd.Context(), tag, file, args[0], buildArgs...); err != nil {
|
if err := docker.Build(cmd.Context(), pull, tag, file, args[0], platform, buildArgs...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := d2vm.Convert(
|
if err := d2vm.Convert(
|
||||||
@ -108,6 +108,8 @@ var (
|
|||||||
d2vm.WithBootFS(d2vm.BootFS(bootFS)),
|
d2vm.WithBootFS(d2vm.BootFS(bootFS)),
|
||||||
d2vm.WithLuksPassword(luksPassword),
|
d2vm.WithLuksPassword(luksPassword),
|
||||||
d2vm.WithKeepCache(keepCache),
|
d2vm.WithKeepCache(keepCache),
|
||||||
|
d2vm.WithPlatform(platform),
|
||||||
|
d2vm.WithPull(false),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ func maybeMakeContainerDisk(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
logrus.Infof("creating container disk image %s", containerDiskTag)
|
logrus.Infof("creating container disk image %s", containerDiskTag)
|
||||||
if err := d2vm.MakeContainerDisk(ctx, output, containerDiskTag); err != nil {
|
if err := d2vm.MakeContainerDisk(ctx, output, containerDiskTag, platform); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !push {
|
if !push {
|
||||||
|
@ -70,7 +70,7 @@ var (
|
|||||||
}
|
}
|
||||||
if pull || !found {
|
if pull || !found {
|
||||||
logrus.Infof("pulling image %s", img)
|
logrus.Infof("pulling image %s", img)
|
||||||
if err := docker.Pull(cmd.Context(), img); err != nil {
|
if err := docker.Pull(cmd.Context(), platform, img); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,6 +89,8 @@ var (
|
|||||||
d2vm.WithBootFS(d2vm.BootFS(bootFS)),
|
d2vm.WithBootFS(d2vm.BootFS(bootFS)),
|
||||||
d2vm.WithLuksPassword(luksPassword),
|
d2vm.WithLuksPassword(luksPassword),
|
||||||
d2vm.WithKeepCache(keepCache),
|
d2vm.WithKeepCache(keepCache),
|
||||||
|
d2vm.WithPlatform(platform),
|
||||||
|
d2vm.WithPull(pull),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -112,7 +114,6 @@ func parseSize(s string) (uint64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
convertCmd.Flags().BoolVar(&pull, "pull", false, "Always pull docker image")
|
|
||||||
convertCmd.Flags().AddFlagSet(buildFlags())
|
convertCmd.Flags().AddFlagSet(buildFlags())
|
||||||
rootCmd.AddCommand(convertCmd)
|
rootCmd.AddCommand(convertCmd)
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,26 @@ var (
|
|||||||
luksPassword string
|
luksPassword string
|
||||||
|
|
||||||
keepCache bool
|
keepCache bool
|
||||||
|
platform string
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateFlags() error {
|
func validateFlags() error {
|
||||||
|
switch platform {
|
||||||
|
case "linux/amd64":
|
||||||
|
if bootloader == "" {
|
||||||
|
bootloader = "syslinux"
|
||||||
|
}
|
||||||
|
case "linux/arm64", "linux/aarch64":
|
||||||
|
platform = "linux/arm64"
|
||||||
|
if bootloader == "" {
|
||||||
|
bootloader = "grub-efi"
|
||||||
|
}
|
||||||
|
if bootloader != "grub-efi" {
|
||||||
|
return fmt.Errorf("unsupported bootloader for platform %s: %s, only grub-efi is supported", platform, bootloader)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unexpected platform: %s, supported platforms: linux/amd64, linux/arm64", platform)
|
||||||
|
}
|
||||||
if luksPassword != "" && !splitBoot {
|
if luksPassword != "" && !splitBoot {
|
||||||
logrus.Warnf("luks password is set: enabling split boot")
|
logrus.Warnf("luks password is set: enabling split boot")
|
||||||
splitBoot = true
|
splitBoot = true
|
||||||
@ -94,8 +111,10 @@ func buildFlags() *pflag.FlagSet {
|
|||||||
flags.BoolVar(&splitBoot, "split-boot", false, "Split the boot partition from the root partition")
|
flags.BoolVar(&splitBoot, "split-boot", false, "Split the boot partition from the root partition")
|
||||||
flags.Uint64Var(&bootSize, "boot-size", 100, "Size of the boot partition in MB")
|
flags.Uint64Var(&bootSize, "boot-size", 100, "Size of the boot partition in MB")
|
||||||
flags.StringVar(&bootFS, "boot-fs", "", "Filesystem to use for the boot partition, ext4 or fat32")
|
flags.StringVar(&bootFS, "boot-fs", "", "Filesystem to use for the boot partition, ext4 or fat32")
|
||||||
flags.StringVar(&bootloader, "bootloader", "syslinux", "Bootloader to use: syslinux, grub, grub-bios, grub-efi")
|
flags.StringVar(&bootloader, "bootloader", "", "Bootloader to use: syslinux, grub, grub-bios, grub-efi, defaults to syslinux on amd64 and grub-efi on arm64")
|
||||||
flags.StringVar(&luksPassword, "luks-password", "", "Password to use for the LUKS encrypted root partition. If not set, the root partition will not be encrypted")
|
flags.StringVar(&luksPassword, "luks-password", "", "Password to use for the LUKS encrypted root partition. If not set, the root partition will not be encrypted")
|
||||||
flags.BoolVar(&keepCache, "keep-cache", false, "Keep the images after the build")
|
flags.BoolVar(&keepCache, "keep-cache", false, "Keep the images after the build")
|
||||||
|
flags.StringVar(&platform, "platform", d2vm.Arch, "Platform to use for the container disk image, linux/arm64 and linux/arm64 are supported")
|
||||||
|
flags.BoolVar(&pull, "pull", false, "Always pull docker image")
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,8 @@ func init() {
|
|||||||
HetznerCmd.Flags().StringVarP(&hetznerSSHKeyPath, "ssh-key", "i", "", "d2vm image identity key")
|
HetznerCmd.Flags().StringVarP(&hetznerSSHKeyPath, "ssh-key", "i", "", "d2vm image identity key")
|
||||||
HetznerCmd.Flags().BoolVar(&hetznerRemove, "rm", false, "remove server when done")
|
HetznerCmd.Flags().BoolVar(&hetznerRemove, "rm", false, "remove server when done")
|
||||||
HetznerCmd.Flags().StringVarP(&hetznerServerName, "name", "n", "d2vm", "d2vm server name")
|
HetznerCmd.Flags().StringVarP(&hetznerServerName, "name", "n", "d2vm", "d2vm server name")
|
||||||
|
HetznerCmd.Flags().StringVarP(&hetznerVMType, "type", "t", hetznerVMType, "d2vm server type")
|
||||||
|
HetznerCmd.Flags().StringVarP(&hetznerDatacenter, "location", "l", hetznerDatacenter, "d2vm server location")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Hetzner(cmd *cobra.Command, args []string) {
|
func Hetzner(cmd *cobra.Command, args []string) {
|
||||||
@ -113,10 +115,23 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
img, _, err := c.Image.GetByName(ctx, serverImg)
|
arch := "amd64"
|
||||||
|
harch := hcloud.ArchitectureX86
|
||||||
|
if strings.HasPrefix(strings.ToLower(hetznerVMType), "cax") {
|
||||||
|
harch = hcloud.ArchitectureARM
|
||||||
|
arch = "arm64"
|
||||||
|
}
|
||||||
|
sparsecatBin, err := Sparsecat(arch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
imgs, _, err := c.Image.List(ctx, hcloud.ImageListOpts{Name: serverImg, Architecture: []hcloud.Architecture{harch}})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(imgs) == 0 {
|
||||||
|
return fmt.Errorf("no image found with name %s", serverImg)
|
||||||
|
}
|
||||||
l, _, err := c.Location.Get(ctx, hetznerDatacenter)
|
l, _, err := c.Location.Get(ctx, hetznerDatacenter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -125,9 +140,9 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io.
|
|||||||
sres, _, err := c.Server.Create(ctx, hcloud.ServerCreateOpts{
|
sres, _, err := c.Server.Create(ctx, hcloud.ServerCreateOpts{
|
||||||
Name: hetznerServerName,
|
Name: hetznerServerName,
|
||||||
ServerType: st,
|
ServerType: st,
|
||||||
Image: img,
|
Image: imgs[0],
|
||||||
Location: l,
|
Location: l,
|
||||||
StartAfterCreate: hcloud.Bool(false),
|
StartAfterCreate: hcloud.Ptr(false),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -186,7 +201,7 @@ func runHetzner(ctx context.Context, imgPath string, stdin io.Reader, stderr io.
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
if _, err := io.Copy(f, bytes.NewReader(sparsecatBinary)); err != nil {
|
if _, err := io.Copy(f, bytes.NewReader(sparsecatBin)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := f.Close(); err != nil {
|
if err := f.Close(); err != nil {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//go:generate env GOOS=linux GOARCH=amd64 go build -o sparsecat-linux-amd64 github.com/svenwiltink/sparsecat/cmd/sparsecat
|
//go:generate env GOOS=linux GOARCH=amd64 go build -o sparsecat-linux-amd64 github.com/svenwiltink/sparsecat/cmd/sparsecat
|
||||||
|
//go:generate env GOOS=linux GOARCH=arm64 go build -o sparsecat-linux-arm64 github.com/svenwiltink/sparsecat/cmd/sparsecat
|
||||||
|
|
||||||
// Copyright 2022 Linka Cloud All rights reserved.
|
// Copyright 2022 Linka Cloud All rights reserved.
|
||||||
//
|
//
|
||||||
@ -33,7 +34,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//go:embed sparsecat-linux-amd64
|
//go:embed sparsecat-linux-amd64
|
||||||
var sparsecatBinary []byte
|
var sparsecatAmdBinary []byte
|
||||||
|
|
||||||
|
//go:embed sparsecat-linux-arm64
|
||||||
|
var sparsecatArmBinary []byte
|
||||||
|
|
||||||
|
func Sparsecat(arch string) ([]byte, error) {
|
||||||
|
switch arch {
|
||||||
|
case "amd64":
|
||||||
|
return sparsecatAmdBinary, nil
|
||||||
|
case "arm64":
|
||||||
|
return sparsecatArmBinary, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported architecture: %s", arch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle flags with multiple occurrences
|
// Handle flags with multiple occurrences
|
||||||
type MultipleFlag []string
|
type MultipleFlag []string
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func testConfig(t *testing.T, ctx context.Context, name, img string, config Config, luks, grubBIOS, grubEFI bool) {
|
func testConfig(t *testing.T, ctx context.Context, name, img string, config Config, luks, grubBIOS, grubEFI bool) {
|
||||||
require.NoError(t, docker.Pull(ctx, img))
|
require.NoError(t, docker.Pull(ctx, Arch, img))
|
||||||
tmpPath := filepath.Join(os.TempDir(), "d2vm-tests", strings.NewReplacer(":", "-", ".", "-").Replace(name))
|
tmpPath := filepath.Join(os.TempDir(), "d2vm-tests", strings.NewReplacer(":", "-", ".", "-").Replace(name))
|
||||||
require.NoError(t, os.MkdirAll(tmpPath, 0755))
|
require.NoError(t, os.MkdirAll(tmpPath, 0755))
|
||||||
defer os.RemoveAll(tmpPath)
|
defer os.RemoveAll(tmpPath)
|
||||||
@ -52,7 +52,7 @@ func testConfig(t *testing.T, ctx context.Context, name, img string, config Conf
|
|||||||
require.NoError(t, d.Render(f))
|
require.NoError(t, d.Render(f))
|
||||||
imgUUID := uuid.New().String()
|
imgUUID := uuid.New().String()
|
||||||
logrus.Infof("building kernel enabled image")
|
logrus.Infof("building kernel enabled image")
|
||||||
require.NoError(t, docker.Build(ctx, imgUUID, p, dir))
|
require.NoError(t, docker.Build(ctx, false, imgUUID, p, dir, Arch))
|
||||||
defer docker.Remove(ctx, imgUUID)
|
defer docker.Remove(ctx, imgUUID)
|
||||||
// we don't need to test the kernel location if grub is enabled
|
// we don't need to test the kernel location if grub is enabled
|
||||||
if grubBIOS || grubEFI {
|
if grubBIOS || grubEFI {
|
||||||
|
@ -36,7 +36,7 @@ ADD --chown=%[1]d:%[1]d %[2]s /disk/
|
|||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
func MakeContainerDisk(ctx context.Context, path string, tag string) error {
|
func MakeContainerDisk(ctx context.Context, path string, tag string, platform string) error {
|
||||||
tmpPath := filepath.Join(os.TempDir(), "d2vm", uuid.New().String())
|
tmpPath := filepath.Join(os.TempDir(), "d2vm", uuid.New().String())
|
||||||
if err := os.MkdirAll(tmpPath, os.ModePerm); err != nil {
|
if err := os.MkdirAll(tmpPath, os.ModePerm); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -60,7 +60,7 @@ func MakeContainerDisk(ctx context.Context, path string, tag string) error {
|
|||||||
if err := os.WriteFile(dockerfile, []byte(dockerfileContent), os.ModePerm); err != nil {
|
if err := os.WriteFile(dockerfile, []byte(dockerfileContent), os.ModePerm); err != nil {
|
||||||
return fmt.Errorf("failed to write dockerfile: %w", err)
|
return fmt.Errorf("failed to write dockerfile: %w", err)
|
||||||
}
|
}
|
||||||
if err := docker.Build(ctx, tag, dockerfile, tmpPath); err != nil {
|
if err := docker.Build(ctx, false, tag, dockerfile, tmpPath, platform); err != nil {
|
||||||
return fmt.Errorf("failed to build container disk: %w", err)
|
return fmt.Errorf("failed to build container disk: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -67,7 +67,7 @@ func Convert(ctx context.Context, img string, opts ...ConvertOption) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
logrus.Infof("building kernel enabled image")
|
logrus.Infof("building kernel enabled image")
|
||||||
if err := docker.Build(ctx, imgUUID, p, dir); err != nil {
|
if err := docker.Build(ctx, o.pull, imgUUID, p, dir, o.platform); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !o.keepCache {
|
if !o.keepCache {
|
||||||
@ -88,7 +88,7 @@ func Convert(ctx context.Context, img string, opts ...ConvertOption) error {
|
|||||||
if format == "" {
|
if format == "" {
|
||||||
format = "raw"
|
format = "raw"
|
||||||
}
|
}
|
||||||
b, err := NewBuilder(ctx, tmpPath, imgUUID, "", o.size, r, format, o.cmdLineExtra, o.splitBoot, o.bootFS, o.bootSize, o.luksPassword, o.bootLoader)
|
b, err := NewBuilder(ctx, tmpPath, imgUUID, "", o.size, r, format, o.cmdLineExtra, o.splitBoot, o.bootFS, o.bootSize, o.luksPassword, o.bootLoader, o.platform)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ type convertOptions struct {
|
|||||||
luksPassword string
|
luksPassword string
|
||||||
|
|
||||||
keepCache bool
|
keepCache bool
|
||||||
|
platform string
|
||||||
|
pull bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *convertOptions) hasGrubBIOS() bool {
|
func (o *convertOptions) hasGrubBIOS() bool {
|
||||||
@ -113,3 +115,15 @@ func WithKeepCache(b bool) ConvertOption {
|
|||||||
o.keepCache = b
|
o.keepCache = b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithPlatform(platform string) ConvertOption {
|
||||||
|
return func(o *convertOptions) {
|
||||||
|
o.platform = platform
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithPull(b bool) ConvertOption {
|
||||||
|
return func(o *convertOptions) {
|
||||||
|
o.pull = b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -140,7 +140,7 @@ RUN rm -rf /etc/apk
|
|||||||
require.NoError(t, os.WriteFile(filepath.Join(tmp, "hostname"), []byte("d2vm-flatten-test"), perm))
|
require.NoError(t, os.WriteFile(filepath.Join(tmp, "hostname"), []byte("d2vm-flatten-test"), perm))
|
||||||
require.NoError(t, os.WriteFile(filepath.Join(tmp, "resolv.conf"), []byte("nameserver 8.8.8.8"), perm))
|
require.NoError(t, os.WriteFile(filepath.Join(tmp, "resolv.conf"), []byte("nameserver 8.8.8.8"), perm))
|
||||||
require.NoError(t, os.WriteFile(filepath.Join(tmp, "Dockerfile"), []byte(dockerfile), perm))
|
require.NoError(t, os.WriteFile(filepath.Join(tmp, "Dockerfile"), []byte(dockerfile), perm))
|
||||||
require.NoError(t, docker.Build(ctx, img, "", tmp))
|
require.NoError(t, docker.Build(ctx, false, img, "", tmp, "linux/amd64"))
|
||||||
defer docker.Remove(ctx, img)
|
defer docker.Remove(ctx, img)
|
||||||
|
|
||||||
imgTmp := filepath.Join(tmp, "image")
|
imgTmp := filepath.Join(tmp, "image")
|
||||||
|
@ -12,7 +12,7 @@ d2vm build [context directory] [flags]
|
|||||||
--append-to-cmdline string Extra kernel cmdline arguments to append to the generated one
|
--append-to-cmdline string Extra kernel cmdline arguments to append to the generated one
|
||||||
--boot-fs string Filesystem to use for the boot partition, ext4 or fat32
|
--boot-fs string Filesystem to use for the boot partition, ext4 or fat32
|
||||||
--boot-size uint Size of the boot partition in MB (default 100)
|
--boot-size uint Size of the boot partition in MB (default 100)
|
||||||
--bootloader string Bootloader to use: syslinux, grub, grub-bios, grub-efi (default "syslinux")
|
--bootloader string Bootloader to use: syslinux, grub, grub-bios, grub-efi, defaults to syslinux on amd64 and grub-efi on arm64
|
||||||
--build-arg stringArray Set build-time variables
|
--build-arg stringArray Set build-time variables
|
||||||
-f, --file string Name of the Dockerfile
|
-f, --file string Name of the Dockerfile
|
||||||
--force Override output qcow2 image
|
--force Override output qcow2 image
|
||||||
@ -22,6 +22,8 @@ d2vm build [context directory] [flags]
|
|||||||
--network-manager string Network manager to use for the image: none, netplan, ifupdown
|
--network-manager string Network manager to use for the image: none, netplan, ifupdown
|
||||||
-o, --output string The output image, the extension determine the image format, raw will be used if none. Supported formats: qcow2 qed raw vdi vhd vmdk (default "disk0.qcow2")
|
-o, --output string The output image, the extension determine the image format, raw will be used if none. Supported formats: qcow2 qed raw vdi vhd vmdk (default "disk0.qcow2")
|
||||||
-p, --password string Optional root user password
|
-p, --password string Optional root user password
|
||||||
|
--platform string Platform to use for the container disk image, linux/arm64 and linux/arm64 are supported (default "linux/amd64")
|
||||||
|
--pull Always pull docker image
|
||||||
--push Push the container disk image to the registry
|
--push Push the container disk image to the registry
|
||||||
--raw Just convert the container to virtual machine image without installing anything more
|
--raw Just convert the container to virtual machine image without installing anything more
|
||||||
-s, --size string The output image size (default "10G")
|
-s, --size string The output image size (default "10G")
|
||||||
|
@ -12,7 +12,7 @@ d2vm convert [docker image] [flags]
|
|||||||
--append-to-cmdline string Extra kernel cmdline arguments to append to the generated one
|
--append-to-cmdline string Extra kernel cmdline arguments to append to the generated one
|
||||||
--boot-fs string Filesystem to use for the boot partition, ext4 or fat32
|
--boot-fs string Filesystem to use for the boot partition, ext4 or fat32
|
||||||
--boot-size uint Size of the boot partition in MB (default 100)
|
--boot-size uint Size of the boot partition in MB (default 100)
|
||||||
--bootloader string Bootloader to use: syslinux, grub, grub-bios, grub-efi (default "syslinux")
|
--bootloader string Bootloader to use: syslinux, grub, grub-bios, grub-efi, defaults to syslinux on amd64 and grub-efi on arm64
|
||||||
--force Override output qcow2 image
|
--force Override output qcow2 image
|
||||||
-h, --help help for convert
|
-h, --help help for convert
|
||||||
--keep-cache Keep the images after the build
|
--keep-cache Keep the images after the build
|
||||||
@ -20,6 +20,7 @@ d2vm convert [docker image] [flags]
|
|||||||
--network-manager string Network manager to use for the image: none, netplan, ifupdown
|
--network-manager string Network manager to use for the image: none, netplan, ifupdown
|
||||||
-o, --output string The output image, the extension determine the image format, raw will be used if none. Supported formats: qcow2 qed raw vdi vhd vmdk (default "disk0.qcow2")
|
-o, --output string The output image, the extension determine the image format, raw will be used if none. Supported formats: qcow2 qed raw vdi vhd vmdk (default "disk0.qcow2")
|
||||||
-p, --password string Optional root user password
|
-p, --password string Optional root user password
|
||||||
|
--platform string Platform to use for the container disk image, linux/arm64 and linux/arm64 are supported (default "linux/amd64")
|
||||||
--pull Always pull docker image
|
--pull Always pull docker image
|
||||||
--push Push the container disk image to the registry
|
--push Push the container disk image to the registry
|
||||||
--raw Just convert the container to virtual machine image without installing anything more
|
--raw Just convert the container to virtual machine image without installing anything more
|
||||||
|
@ -9,12 +9,14 @@ d2vm run hetzner [options] image-path [flags]
|
|||||||
### Options
|
### Options
|
||||||
|
|
||||||
```
|
```
|
||||||
-h, --help help for hetzner
|
-h, --help help for hetzner
|
||||||
-n, --name string d2vm server name (default "d2vm")
|
-l, --location string d2vm server location (default "hel1-dc2")
|
||||||
--rm remove server when done
|
-n, --name string d2vm server name (default "d2vm")
|
||||||
-i, --ssh-key string d2vm image identity key
|
--rm remove server when done
|
||||||
--token string Hetzner Cloud API token [$HETZNER_TOKEN]
|
-i, --ssh-key string d2vm image identity key
|
||||||
-u, --user string d2vm image ssh user (default "root")
|
--token string Hetzner Cloud API token [$HETZNER_TOKEN]
|
||||||
|
-t, --type string d2vm server type (default "cx11")
|
||||||
|
-u, --user string d2vm image ssh user (default "root")
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options inherited from parent commands
|
### Options inherited from parent commands
|
||||||
|
28
go.mod
28
go.mod
@ -8,24 +8,24 @@ require (
|
|||||||
github.com/fatih/color v1.13.0
|
github.com/fatih/color v1.13.0
|
||||||
github.com/google/go-containerregistry v0.14.0
|
github.com/google/go-containerregistry v0.14.0
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/hetznercloud/hcloud-go v1.35.2
|
github.com/hetznercloud/hcloud-go v1.50.0
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/pkg/sftp v1.10.1
|
github.com/pkg/sftp v1.10.1
|
||||||
github.com/sirupsen/logrus v1.9.0
|
github.com/sirupsen/logrus v1.9.0
|
||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.8.1
|
github.com/stretchr/testify v1.8.4
|
||||||
github.com/svenwiltink/sparsecat v1.0.0
|
github.com/svenwiltink/sparsecat v1.0.0
|
||||||
go.linka.cloud/console v0.0.0-20220910100646-48f9f2b8843b
|
go.linka.cloud/console v0.0.0-20220910100646-48f9f2b8843b
|
||||||
go.uber.org/multierr v1.11.0
|
go.uber.org/multierr v1.11.0
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
golang.org/x/crypto v0.11.0
|
||||||
golang.org/x/sys v0.7.0
|
golang.org/x/sys v0.10.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||||
github.com/creack/pty v1.1.15 // indirect
|
github.com/creack/pty v1.1.15 // indirect
|
||||||
@ -42,23 +42,23 @@ require (
|
|||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
|
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
|
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_golang v1.11.0 // indirect
|
github.com/prometheus/client_golang v1.16.0 // indirect
|
||||||
github.com/prometheus/client_model v0.2.0 // indirect
|
github.com/prometheus/client_model v0.3.0 // indirect
|
||||||
github.com/prometheus/common v0.26.0 // indirect
|
github.com/prometheus/common v0.42.0 // indirect
|
||||||
github.com/prometheus/procfs v0.6.0 // indirect
|
github.com/prometheus/procfs v0.10.1 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/vbatts/tar-split v0.11.3 // indirect
|
github.com/vbatts/tar-split v0.11.3 // indirect
|
||||||
golang.org/x/net v0.8.0 // indirect
|
golang.org/x/net v0.12.0 // indirect
|
||||||
golang.org/x/sync v0.1.0 // indirect
|
golang.org/x/sync v0.2.0 // indirect
|
||||||
golang.org/x/text v0.8.0 // indirect
|
golang.org/x/text v0.11.0 // indirect
|
||||||
google.golang.org/protobuf v1.29.0 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
43
go.sum
43
go.sum
@ -8,8 +8,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
|
|||||||
github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b h1:6+ZFm0flnudZzdSE0JxlhR2hKnGPcNB35BjQf4RYQDY=
|
github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b h1:6+ZFm0flnudZzdSE0JxlhR2hKnGPcNB35BjQf4RYQDY=
|
||||||
github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
|
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
|
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||||
@ -37,6 +37,7 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
|
|||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
@ -53,8 +54,8 @@ github.com/google/go-containerregistry v0.14.0/go.mod h1:aiJ2fp/SXvkWgmYHioXnbMd
|
|||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hetznercloud/hcloud-go v1.35.2 h1:eEDtmDiI2plZ2UQmj4YpiYse5XbtpXOUBpAdIOLxzgE=
|
github.com/hetznercloud/hcloud-go v1.50.0 h1:vS9tJvmSRwgDpMLmPnThGN87Rz8OMP3D4M3rWm8QHEQ=
|
||||||
github.com/hetznercloud/hcloud-go v1.35.2/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzSY9xWL1e9dyxXpgA=
|
github.com/hetznercloud/hcloud-go v1.50.0/go.mod h1:VzDWThl47lOnZXY0q5/LPFD+M62pfe/52TV+mOrpp9Q=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
@ -78,8 +79,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
|||||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
|
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
|
||||||
@ -101,12 +102,15 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s=
|
github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s=
|
||||||
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
|
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||||
|
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||||
|
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
|
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||||
|
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
@ -128,8 +132,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
|||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/svenwiltink/sparsecat v1.0.0 h1:SBDEIImxhD//8MskqodFR9VcixWKkZAPAW35nmA4vcw=
|
github.com/svenwiltink/sparsecat v1.0.0 h1:SBDEIImxhD//8MskqodFR9VcixWKkZAPAW35nmA4vcw=
|
||||||
github.com/svenwiltink/sparsecat v1.0.0/go.mod h1:TdtvJbeTZcd+3cMQpttW6MJl/iPGZT0GHmckep0hoxU=
|
github.com/svenwiltink/sparsecat v1.0.0/go.mod h1:TdtvJbeTZcd+3cMQpttW6MJl/iPGZT0GHmckep0hoxU=
|
||||||
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
|
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
|
||||||
@ -147,15 +152,15 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
|
|||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -171,15 +176,15 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||||
|
5
grub.go
5
grub.go
@ -57,7 +57,10 @@ type grubProvider struct {
|
|||||||
config Config
|
config Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g grubProvider) New(c Config, r OSRelease) (Bootloader, error) {
|
func (g grubProvider) New(c Config, r OSRelease, arch string) (Bootloader, error) {
|
||||||
|
if arch != "x86_64" {
|
||||||
|
return nil, fmt.Errorf("grub is only supported for amd64")
|
||||||
|
}
|
||||||
if r.ID == ReleaseCentOS {
|
if r.ID == ReleaseCentOS {
|
||||||
return nil, fmt.Errorf("grub (efi) is not supported for CentOS, use grub-bios instead")
|
return nil, fmt.Errorf("grub (efi) is not supported for CentOS, use grub-bios instead")
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ package d2vm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -48,7 +49,10 @@ type grubBiosProvider struct {
|
|||||||
config Config
|
config Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g grubBiosProvider) New(c Config, r OSRelease) (Bootloader, error) {
|
func (g grubBiosProvider) New(c Config, r OSRelease, arch string) (Bootloader, error) {
|
||||||
|
if arch != "x86_64" {
|
||||||
|
return nil, fmt.Errorf("grub-bios is only supported for amd64")
|
||||||
|
}
|
||||||
return grubBios{grubCommon: newGrubCommon(c, r)}, nil
|
return grubBios{grubCommon: newGrubCommon(c, r)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
type grubEFI struct {
|
type grubEFI struct {
|
||||||
*grubCommon
|
*grubCommon
|
||||||
|
arch string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g grubEFI) Validate(fs BootFS) error {
|
func (g grubEFI) Validate(fs BootFS) error {
|
||||||
@ -41,7 +42,7 @@ func (g grubEFI) Setup(ctx context.Context, dev, root string, cmdline string) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer clean()
|
defer clean()
|
||||||
if err := g.install(ctx, "--target=x86_64-efi", "--efi-directory=/boot", "--no-nvram", "--removable", "--no-floppy"); err != nil {
|
if err := g.install(ctx, "--target="+g.arch+"-efi", "--efi-directory=/boot", "--no-nvram", "--removable", "--no-floppy"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := g.mkconfig(ctx); err != nil {
|
if err := g.mkconfig(ctx); err != nil {
|
||||||
@ -54,11 +55,11 @@ type grubEFIProvider struct {
|
|||||||
config Config
|
config Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g grubEFIProvider) New(c Config, r OSRelease) (Bootloader, error) {
|
func (g grubEFIProvider) New(c Config, r OSRelease, arch string) (Bootloader, error) {
|
||||||
if r.ID == ReleaseCentOS {
|
if r.ID == ReleaseCentOS {
|
||||||
return nil, fmt.Errorf("grub-efi is not supported for CentOS, use grub-bios instead")
|
return nil, fmt.Errorf("grub-efi is not supported for CentOS, use grub-bios instead")
|
||||||
}
|
}
|
||||||
return grubEFI{grubCommon: newGrubCommon(c, r)}, nil
|
return grubEFI{grubCommon: newGrubCommon(c, r), arch: arch}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g grubEFIProvider) Name() string {
|
func (g grubEFIProvider) Name() string {
|
||||||
|
@ -50,11 +50,14 @@ func CmdOut(ctx context.Context, args ...string) (string, string, error) {
|
|||||||
return exec.RunOut(ctx, "docker", args...)
|
return exec.RunOut(ctx, "docker", args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Build(ctx context.Context, tag, dockerfile, dir string, buildArgs ...string) error {
|
func Build(ctx context.Context, pull bool, tag, dockerfile, dir, platform string, buildArgs ...string) error {
|
||||||
if dockerfile == "" {
|
if dockerfile == "" {
|
||||||
dockerfile = filepath.Join(dir, "Dockerfile")
|
dockerfile = filepath.Join(dir, "Dockerfile")
|
||||||
}
|
}
|
||||||
args := []string{"image", "build", "-t", tag, "-f", dockerfile}
|
args := []string{"image", "build", "-t", tag, "-f", dockerfile, "--platform", platform}
|
||||||
|
if pull {
|
||||||
|
args = append(args, "--pull")
|
||||||
|
}
|
||||||
for _, v := range buildArgs {
|
for _, v := range buildArgs {
|
||||||
args = append(args, "--build-arg", v)
|
args = append(args, "--build-arg", v)
|
||||||
}
|
}
|
||||||
@ -96,8 +99,8 @@ func ImageSave(ctx context.Context, tag, file string) error {
|
|||||||
return Cmd(ctx, "image", "save", "-o", file, tag)
|
return Cmd(ctx, "image", "save", "-o", file, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pull(ctx context.Context, tag string) error {
|
func Pull(ctx context.Context, platform, tag string) error {
|
||||||
return Cmd(ctx, "image", "pull", tag)
|
return Cmd(ctx, "image", "pull", "--platform", platform, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Push(ctx context.Context, tag string) error {
|
func Push(ctx context.Context, tag string) error {
|
||||||
|
@ -71,7 +71,10 @@ func (s syslinux) Setup(ctx context.Context, dev, root string, cmdline string) e
|
|||||||
|
|
||||||
type syslinuxProvider struct{}
|
type syslinuxProvider struct{}
|
||||||
|
|
||||||
func (s syslinuxProvider) New(c Config, _ OSRelease) (Bootloader, error) {
|
func (s syslinuxProvider) New(c Config, _ OSRelease, arch string) (Bootloader, error) {
|
||||||
|
if arch != "x86_64" {
|
||||||
|
return nil, fmt.Errorf("syslinux is only supported for amd64")
|
||||||
|
}
|
||||||
mbrBin := ""
|
mbrBin := ""
|
||||||
for _, v := range mbrPaths {
|
for _, v := range mbrPaths {
|
||||||
if _, err := os.Stat(v); err == nil {
|
if _, err := os.Stat(v); err == nil {
|
||||||
|
@ -15,7 +15,8 @@ RUN apt-get update && \
|
|||||||
linux-image-amd64 && \
|
linux-image-amd64 && \
|
||||||
find /boot -type l -exec rm {} \;
|
find /boot -type l -exec rm {} \;
|
||||||
|
|
||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
RUN ARCH="$([ "$(uname -m)" = "x86_64" ] && echo amd64 || echo arm64)"; \
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
systemd-sysv \
|
systemd-sysv \
|
||||||
systemd \
|
systemd \
|
||||||
{{- if .Grub }}
|
{{- if .Grub }}
|
||||||
@ -26,7 +27,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
|||||||
grub-pc-bin \
|
grub-pc-bin \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if .GrubEFI }}
|
{{- if .GrubEFI }}
|
||||||
grub-efi-amd64-bin \
|
grub-efi-${ARCH}-bin \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
dbus \
|
dbus \
|
||||||
iproute2 \
|
iproute2 \
|
||||||
|
@ -2,7 +2,8 @@ FROM {{ .Image }}
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN ARCH="$([ "$(uname -m)" = "x86_64" ] && echo amd64 || echo arm64)"; \
|
||||||
|
apt-get update && \
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \
|
DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \
|
||||||
linux-image-virtual \
|
linux-image-virtual \
|
||||||
initramfs-tools \
|
initramfs-tools \
|
||||||
@ -16,7 +17,7 @@ RUN apt-get update && \
|
|||||||
grub-pc-bin \
|
grub-pc-bin \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if .GrubEFI }}
|
{{- if .GrubEFI }}
|
||||||
grub-efi-amd64-bin \
|
grub-efi-${ARCH}-bin \
|
||||||
{{- end }}
|
{{- end }}
|
||||||
dbus \
|
dbus \
|
||||||
isc-dhcp-client \
|
isc-dhcp-client \
|
||||||
|
@ -15,10 +15,14 @@
|
|||||||
package d2vm
|
package d2vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"go.linka.cloud/d2vm/pkg/qemu_img"
|
"go.linka.cloud/d2vm/pkg/qemu_img"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
Arch = fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
Version = ""
|
Version = ""
|
||||||
BuildDate = ""
|
BuildDate = ""
|
||||||
Image = "linkacloud/d2vm"
|
Image = "linkacloud/d2vm"
|
||||||
|
Loading…
Reference in New Issue
Block a user