mirror of
https://github.com/linka-cloud/d2vm.git
synced 2024-11-25 09:06:24 +00:00
luks: implements support for Alpine
Signed-off-by: Adphi <philippe.adrien.nousse@gmail.com>
This commit is contained in:
parent
cab7d8badd
commit
3ec9bdfb01
@ -38,6 +38,7 @@ RUN apt-get update && \
|
|||||||
mount \
|
mount \
|
||||||
tar \
|
tar \
|
||||||
extlinux \
|
extlinux \
|
||||||
|
cryptsetup \
|
||||||
qemu-utils && \
|
qemu-utils && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
115
builder.go
115
builder.go
@ -23,6 +23,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/c2h5oh/datasize"
|
"github.com/c2h5oh/datasize"
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
@ -129,19 +130,34 @@ type builder struct {
|
|||||||
|
|
||||||
mbrPath string
|
mbrPath string
|
||||||
|
|
||||||
loDevice string
|
loDevice string
|
||||||
bootPart string
|
bootPart string
|
||||||
rootPart string
|
rootPart string
|
||||||
bootUUID string
|
cryptPart string
|
||||||
rootUUID string
|
cryptRoot string
|
||||||
|
mappedCryptRoot string
|
||||||
|
bootUUID string
|
||||||
|
rootUUID string
|
||||||
|
cryptUUID string
|
||||||
|
|
||||||
|
luksPassword string
|
||||||
|
|
||||||
cmdLineExtra string
|
cmdLineExtra string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBuilder(ctx context.Context, workdir, imgTag, disk string, size uint64, osRelease OSRelease, format string, cmdLineExtra string, splitBoot bool, bootSize uint64) (Builder, error) {
|
func NewBuilder(ctx context.Context, workdir, imgTag, disk string, size uint64, osRelease OSRelease, format string, cmdLineExtra string, splitBoot bool, bootSize uint64, luksPassword string) (Builder, error) {
|
||||||
if err := checkDependencies(); err != nil {
|
if err := checkDependencies(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if luksPassword != "" {
|
||||||
|
// TODO(adphi): remove this check when we support luks encryption on other distros
|
||||||
|
if osRelease.ID != ReleaseAlpine {
|
||||||
|
return nil, fmt.Errorf("luks encryption is only supported on alpine")
|
||||||
|
}
|
||||||
|
if !splitBoot {
|
||||||
|
return nil, fmt.Errorf("luks encryption requires split boot")
|
||||||
|
}
|
||||||
|
}
|
||||||
f := strings.ToLower(format)
|
f := strings.ToLower(format)
|
||||||
valid := false
|
valid := false
|
||||||
for _, v := range formats {
|
for _, v := range formats {
|
||||||
@ -202,6 +218,7 @@ func NewBuilder(ctx context.Context, workdir, imgTag, disk string, size uint64,
|
|||||||
cmdLineExtra: cmdLineExtra,
|
cmdLineExtra: cmdLineExtra,
|
||||||
splitBoot: splitBoot,
|
splitBoot: splitBoot,
|
||||||
bootSize: bootSize,
|
bootSize: bootSize,
|
||||||
|
luksPassword: luksPassword,
|
||||||
}
|
}
|
||||||
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
|
||||||
@ -302,12 +319,44 @@ func (b *builder) mountImg(ctx context.Context) error {
|
|||||||
} else {
|
} else {
|
||||||
b.rootPart = b.bootPart
|
b.rootPart = b.bootPart
|
||||||
}
|
}
|
||||||
logrus.Infof("creating raw image file system")
|
if b.isLuksEnabled() {
|
||||||
if err := exec.Run(ctx, "mkfs.ext4", b.rootPart); err != nil {
|
logrus.Infof("encrypting root partition")
|
||||||
return err
|
f, err := os.CreateTemp("", "key")
|
||||||
}
|
if err != nil {
|
||||||
if err := exec.Run(ctx, "mount", b.rootPart, b.mntPoint); err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
|
defer f.Close()
|
||||||
|
defer os.Remove(f.Name())
|
||||||
|
if _, err := f.WriteString(b.luksPassword); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// cryptsetup luksFormat --batch-mode --verify-passphrase --type luks2 $ROOT_DEVICE $KEY_FILE
|
||||||
|
if err := exec.Run(ctx, "cryptsetup", "luksFormat", "--batch-mode", "--type", "luks2", b.rootPart, f.Name()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.cryptRoot = fmt.Sprintf("d2vm-%s-root", uuid.New().String())
|
||||||
|
// cryptsetup open -d $KEY_FILE $ROOT_DEVICE $ROOT_LABEL
|
||||||
|
if err := exec.Run(ctx, "cryptsetup", "open", "--key-file", f.Name(), b.rootPart, b.cryptRoot); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.cryptPart = b.rootPart
|
||||||
|
b.rootPart = "/dev/mapper/root"
|
||||||
|
b.mappedCryptRoot = filepath.Join("/dev/mapper", b.cryptRoot)
|
||||||
|
logrus.Infof("creating raw image file system")
|
||||||
|
if err := exec.Run(ctx, "mkfs.ext4", b.mappedCryptRoot); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := exec.Run(ctx, "mount", b.mappedCryptRoot, b.mntPoint); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logrus.Infof("creating raw image file system")
|
||||||
|
if err := exec.Run(ctx, "mkfs.ext4", b.rootPart); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := exec.Run(ctx, "mount", b.rootPart, b.mntPoint); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !b.splitBoot {
|
if !b.splitBoot {
|
||||||
return nil
|
return nil
|
||||||
@ -328,20 +377,17 @@ func (b *builder) unmountImg(ctx context.Context) error {
|
|||||||
logrus.Infof("unmounting raw image")
|
logrus.Infof("unmounting raw image")
|
||||||
var merr error
|
var merr error
|
||||||
if b.splitBoot {
|
if b.splitBoot {
|
||||||
if err := exec.Run(ctx, "umount", filepath.Join(b.mntPoint, "boot")); err != nil {
|
merr = multierr.Append(merr, exec.Run(ctx, "umount", filepath.Join(b.mntPoint, "boot")))
|
||||||
merr = multierr.Append(merr, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err := exec.Run(ctx, "umount", b.mntPoint); err != nil {
|
merr = multierr.Append(merr, exec.Run(ctx, "umount", b.mntPoint))
|
||||||
merr = multierr.Append(merr, err)
|
if b.isLuksEnabled() {
|
||||||
|
merr = multierr.Append(merr, exec.Run(ctx, "cryptsetup", "close", b.cryptRoot))
|
||||||
}
|
}
|
||||||
if err := exec.Run(ctx, "kpartx", "-d", b.loDevice); err != nil {
|
return multierr.Combine(
|
||||||
merr = multierr.Append(merr, err)
|
merr,
|
||||||
}
|
exec.Run(ctx, "kpartx", "-d", b.loDevice),
|
||||||
if err := exec.Run(ctx, "losetup", "-d", b.loDevice); err != nil {
|
exec.Run(ctx, "losetup", "-d", b.loDevice),
|
||||||
merr = multierr.Append(merr, err)
|
)
|
||||||
}
|
|
||||||
return merr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *builder) copyRootFS(ctx context.Context) error {
|
func (b *builder) copyRootFS(ctx context.Context) error {
|
||||||
@ -369,6 +415,12 @@ func (b *builder) setupRootFS(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if b.isLuksEnabled() {
|
||||||
|
b.cryptUUID, err = diskUUID(ctx, b.cryptPart)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
fstab = fmt.Sprintf("UUID=%s / ext4 errors=remount-ro 0 1\nUUID=%s /boot ext4 errors=remount-ro 0 2\n", b.rootUUID, b.bootUUID)
|
fstab = fmt.Sprintf("UUID=%s / ext4 errors=remount-ro 0 1\nUUID=%s /boot ext4 errors=remount-ro 0 2\n", b.rootUUID, b.bootUUID)
|
||||||
} else {
|
} else {
|
||||||
b.bootUUID = b.rootUUID
|
b.bootUUID = b.rootUUID
|
||||||
@ -449,7 +501,14 @@ func (b *builder) installKernel(ctx context.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := b.chWriteFile("/boot/syslinux.cfg", fmt.Sprintf(sysconfig, b.rootUUID, b.cmdLineExtra), perm); err != nil {
|
var cfg string
|
||||||
|
if b.isLuksEnabled() {
|
||||||
|
cfg = fmt.Sprintf(sysconfig, b.rootUUID, fmt.Sprintf("%s root=/dev/mapper/root cryptdm=root", b.cmdLineExtra))
|
||||||
|
cfg = strings.Replace(cfg, "root=UUID="+b.rootUUID, "cryptroot=UUID="+b.cryptUUID, 1)
|
||||||
|
} else {
|
||||||
|
cfg = fmt.Sprintf(sysconfig, b.rootUUID, b.cmdLineExtra)
|
||||||
|
}
|
||||||
|
if err := b.chWriteFile("/boot/syslinux.cfg", cfg, perm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -483,6 +542,10 @@ func (b *builder) chPath(path string) string {
|
|||||||
return fmt.Sprintf("%s%s", b.mntPoint, path)
|
return fmt.Sprintf("%s%s", b.mntPoint, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *builder) isLuksEnabled() bool {
|
||||||
|
return b.luksPassword != ""
|
||||||
|
}
|
||||||
|
|
||||||
func (b *builder) Close() error {
|
func (b *builder) Close() error {
|
||||||
return b.img.Close()
|
return b.img.Close()
|
||||||
}
|
}
|
||||||
@ -498,7 +561,7 @@ func block(path string, size uint64) error {
|
|||||||
|
|
||||||
func checkDependencies() error {
|
func checkDependencies() error {
|
||||||
var merr error
|
var merr error
|
||||||
for _, v := range []string{"mount", "blkid", "tar", "losetup", "parted", "partprobe", "qemu-img", "extlinux", "dd", "mkfs"} {
|
for _, v := range []string{"mount", "blkid", "tar", "losetup", "parted", "kpartx", "qemu-img", "extlinux", "dd", "mkfs.ext4", "cryptsetup"} {
|
||||||
if _, err := exec2.LookPath(v); err != nil {
|
if _, err := exec2.LookPath(v); err != nil {
|
||||||
merr = multierr.Append(merr, err)
|
merr = multierr.Append(merr, err)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ func testSysconfig(t *testing.T, ctx context.Context, img, sysconf, kernel, init
|
|||||||
sys, err := sysconfig(r)
|
sys, err := sysconfig(r)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, sysconf, sys)
|
assert.Equal(t, sysconf, sys)
|
||||||
d, err := NewDockerfile(r, img, "root", "")
|
d, err := NewDockerfile(r, img, "root", "", false)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
logrus.Infof("docker image based on %s", d.Release.Name)
|
logrus.Infof("docker image based on %s", d.Release.Name)
|
||||||
p := filepath.Join(tmpPath, docker.FormatImgName(img))
|
p := filepath.Join(tmpPath, docker.FormatImgName(img))
|
||||||
|
@ -79,6 +79,10 @@ var (
|
|||||||
}
|
}
|
||||||
return docker.RunD2VM(cmd.Context(), d2vm.Image, d2vm.Version, in, out, cmd.Name(), os.Args[2:]...)
|
return docker.RunD2VM(cmd.Context(), d2vm.Image, d2vm.Version, in, out, cmd.Name(), os.Args[2:]...)
|
||||||
}
|
}
|
||||||
|
if luksPassword != "" && !splitBoot {
|
||||||
|
logrus.Warnf("luks password is set: enabling split boot")
|
||||||
|
splitBoot = true
|
||||||
|
}
|
||||||
size, err := parseSize(size)
|
size, err := parseSize(size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -109,6 +113,7 @@ var (
|
|||||||
d2vm.WithRaw(raw),
|
d2vm.WithRaw(raw),
|
||||||
d2vm.WithSplitBoot(splitBoot),
|
d2vm.WithSplitBoot(splitBoot),
|
||||||
d2vm.WithBootSize(bootSize),
|
d2vm.WithBootSize(bootSize),
|
||||||
|
d2vm.WithLuksPassword(luksPassword),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,10 @@ var (
|
|||||||
}
|
}
|
||||||
return docker.RunD2VM(cmd.Context(), d2vm.Image, d2vm.Version, out, out, cmd.Name(), dargs...)
|
return docker.RunD2VM(cmd.Context(), d2vm.Image, d2vm.Version, out, out, cmd.Name(), dargs...)
|
||||||
}
|
}
|
||||||
|
if luksPassword != "" && !splitBoot {
|
||||||
|
logrus.Warnf("luks password is set: enabling split boot")
|
||||||
|
splitBoot = true
|
||||||
|
}
|
||||||
img := args[0]
|
img := args[0]
|
||||||
tag := "latest"
|
tag := "latest"
|
||||||
if parts := strings.Split(img, ":"); len(parts) > 1 {
|
if parts := strings.Split(img, ":"); len(parts) > 1 {
|
||||||
@ -97,6 +101,7 @@ var (
|
|||||||
d2vm.WithRaw(raw),
|
d2vm.WithRaw(raw),
|
||||||
d2vm.WithSplitBoot(splitBoot),
|
d2vm.WithSplitBoot(splitBoot),
|
||||||
d2vm.WithBootSize(bootSize),
|
d2vm.WithBootSize(bootSize),
|
||||||
|
d2vm.WithLuksPassword(luksPassword),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ var (
|
|||||||
networkManager string
|
networkManager string
|
||||||
splitBoot bool
|
splitBoot bool
|
||||||
bootSize uint64
|
bootSize uint64
|
||||||
|
luksPassword string
|
||||||
)
|
)
|
||||||
|
|
||||||
func buildFlags() *pflag.FlagSet {
|
func buildFlags() *pflag.FlagSet {
|
||||||
@ -50,5 +51,6 @@ func buildFlags() *pflag.FlagSet {
|
|||||||
flags.BoolVar(&push, "push", false, "Push the container disk image to the registry")
|
flags.BoolVar(&push, "push", false, "Push the container disk image to the registry")
|
||||||
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(&luksPassword, "luks-password", "", "Password to use for the LUKS encrypted root partition. If not set, the root partition will not be encrypted")
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ func Convert(ctx context.Context, img string, opts ...ConvertOption) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !o.raw {
|
if !o.raw {
|
||||||
d, err := NewDockerfile(r, img, o.password, o.networkManager)
|
d, err := NewDockerfile(r, img, o.password, o.networkManager, o.luksPassword != "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -79,7 +79,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.bootSize)
|
b, err := NewBuilder(ctx, tmpPath, imgUUID, "", o.size, r, format, o.cmdLineExtra, o.splitBoot, o.bootSize, o.luksPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ type convertOptions struct {
|
|||||||
|
|
||||||
splitBoot bool
|
splitBoot bool
|
||||||
bootSize uint64
|
bootSize uint64
|
||||||
|
|
||||||
|
luksPassword string
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithSize(size uint64) ConvertOption {
|
func WithSize(size uint64) ConvertOption {
|
||||||
@ -75,3 +77,9 @@ func WithBootSize(bootSize uint64) ConvertOption {
|
|||||||
o.bootSize = bootSize
|
o.bootSize = bootSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithLuksPassword(password string) ConvertOption {
|
||||||
|
return func(o *convertOptions) {
|
||||||
|
o.luksPassword = password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -64,6 +64,7 @@ type Dockerfile struct {
|
|||||||
Password string
|
Password string
|
||||||
Release OSRelease
|
Release OSRelease
|
||||||
NetworkManager NetworkManager
|
NetworkManager NetworkManager
|
||||||
|
Luks bool
|
||||||
tmpl *template.Template
|
tmpl *template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +72,8 @@ func (d Dockerfile) Render(w io.Writer) error {
|
|||||||
return d.tmpl.Execute(w, d)
|
return d.tmpl.Execute(w, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDockerfile(release OSRelease, img, password string, networkManager NetworkManager) (Dockerfile, error) {
|
func NewDockerfile(release OSRelease, img, password string, networkManager NetworkManager, luks bool) (Dockerfile, error) {
|
||||||
d := Dockerfile{Release: release, Image: img, Password: password, NetworkManager: networkManager}
|
d := Dockerfile{Release: release, Image: img, Password: password, NetworkManager: networkManager, Luks: luks}
|
||||||
var net NetworkManager
|
var net NetworkManager
|
||||||
switch release.ID {
|
switch release.ID {
|
||||||
case ReleaseDebian:
|
case ReleaseDebian:
|
||||||
|
@ -15,6 +15,7 @@ d2vm build [context directory] [flags]
|
|||||||
-f, --file string Name of the Dockerfile
|
-f, --file string Name of the Dockerfile
|
||||||
--force Override output qcow2 image
|
--force Override output qcow2 image
|
||||||
-h, --help help for build
|
-h, --help help for build
|
||||||
|
--luks-password string Password to use for the LUKS encrypted root partition. If not set, the root partition will not be encrypted
|
||||||
--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
|
||||||
|
@ -13,6 +13,7 @@ d2vm convert [docker image] [flags]
|
|||||||
--boot-size uint Size of the boot partition in MB (default 100)
|
--boot-size uint Size of the boot partition in MB (default 100)
|
||||||
--force Override output qcow2 image
|
--force Override output qcow2 image
|
||||||
-h, --help help for convert
|
-h, --help help for convert
|
||||||
|
--luks-password string Password to use for the LUKS encrypted root partition. If not set, the root partition will not be encrypted
|
||||||
--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
|
||||||
|
@ -6,6 +6,9 @@ RUN apk update --no-cache && \
|
|||||||
apk add \
|
apk add \
|
||||||
util-linux \
|
util-linux \
|
||||||
linux-virt \
|
linux-virt \
|
||||||
|
{{- if .Luks }}
|
||||||
|
cryptsetup \
|
||||||
|
{{- end }}
|
||||||
{{- if ge .Release.VersionID "3.17" }}
|
{{- if ge .Release.VersionID "3.17" }}
|
||||||
busybox-openrc \
|
busybox-openrc \
|
||||||
busybox-mdev-openrc \
|
busybox-mdev-openrc \
|
||||||
@ -29,3 +32,9 @@ allow-hotplug eth0\n\
|
|||||||
iface eth0 inet dhcp\n\
|
iface eth0 inet dhcp\n\
|
||||||
' > /etc/network/interfaces
|
' > /etc/network/interfaces
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if .Luks }}
|
||||||
|
RUN source /etc/mkinitfs/mkinitfs.conf && \
|
||||||
|
echo "features=\"${features} cryptsetup\"" > /etc/mkinitfs/mkinitfs.conf && \
|
||||||
|
mkinitfs $(ls /lib/modules)
|
||||||
|
{{- end }}
|
||||||
|
@ -4,6 +4,9 @@ USER root
|
|||||||
|
|
||||||
RUN apt-get -y update && \
|
RUN apt-get -y update && \
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \
|
DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \
|
||||||
|
{{- if .Luks }}
|
||||||
|
cryptsetup \
|
||||||
|
{{- end }}
|
||||||
linux-image-amd64
|
linux-image-amd64
|
||||||
|
|
||||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
@ -6,6 +6,9 @@ RUN apt-get update -y && \
|
|||||||
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 \
|
||||||
|
{{- if .Luks }}
|
||||||
|
cryptsetup \
|
||||||
|
{{- end }}
|
||||||
systemd-sysv \
|
systemd-sysv \
|
||||||
systemd \
|
systemd \
|
||||||
dbus \
|
dbus \
|
||||||
|
Loading…
Reference in New Issue
Block a user