mirror of
				https://github.com/linka-cloud/d2vm.git
				synced 2025-10-31 01:22:27 +00:00 
			
		
		
		
	luks: implements support for centos
Signed-off-by: Adphi <philippe.adrien.nousse@gmail.com>
This commit is contained in:
		
							
								
								
									
										33
									
								
								builder.go
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								builder.go
									
									
									
									
									
								
							| @@ -150,10 +150,6 @@ func NewBuilder(ctx context.Context, workdir, imgTag, disk string, size uint64, | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if luksPassword != "" { | ||||
| 		// TODO(adphi): remove this check when we support luks encryption on other distros | ||||
| 		if osRelease.ID == ReleaseCentOS { | ||||
| 			return nil, fmt.Errorf("luks encryption is not supported on centos") | ||||
| 		} | ||||
| 		if !splitBoot { | ||||
| 			return nil, fmt.Errorf("luks encryption requires split boot") | ||||
| 		} | ||||
| @@ -314,11 +310,7 @@ func (b *builder) mountImg(ctx context.Context) error { | ||||
| 		return err | ||||
| 	} | ||||
| 	b.bootPart = fmt.Sprintf("/dev/mapper/%sp1", filepath.Base(b.loDevice)) | ||||
| 	if b.splitBoot { | ||||
| 		b.rootPart = fmt.Sprintf("/dev/mapper/%sp2", filepath.Base(b.loDevice)) | ||||
| 	} else { | ||||
| 		b.rootPart = b.bootPart | ||||
| 	} | ||||
| 	b.rootPart = ifElse(b.splitBoot, fmt.Sprintf("/dev/mapper/%sp2", filepath.Base(b.loDevice)), b.bootPart) | ||||
| 	if b.isLuksEnabled() { | ||||
| 		logrus.Infof("encrypting root partition") | ||||
| 		f, err := os.CreateTemp("", "key") | ||||
| @@ -408,7 +400,10 @@ func diskUUID(ctx context.Context, disk string) (string, error) { | ||||
|  | ||||
| func (b *builder) setupRootFS(ctx context.Context) (err error) { | ||||
| 	logrus.Infof("setting up rootfs") | ||||
| 	b.rootUUID, err = diskUUID(ctx, b.rootPart) | ||||
| 	b.rootUUID, err = diskUUID(ctx, ifElse(b.isLuksEnabled(), b.mappedCryptRoot, b.rootPart)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	var fstab string | ||||
| 	if b.splitBoot { | ||||
| 		b.bootUUID, err = diskUUID(ctx, b.bootPart) | ||||
| @@ -503,12 +498,15 @@ func (b *builder) installKernel(ctx context.Context) error { | ||||
| 	} | ||||
| 	var cfg string | ||||
| 	if b.isLuksEnabled() { | ||||
| 		if b.osRelease.ID != ReleaseAlpine { | ||||
| 			cfg = fmt.Sprintf(sysconfig, b.rootUUID, fmt.Sprintf("%s root=/dev/mapper/root cryptopts=target=root,source=UUID=%s", b.cmdLineExtra, b.cryptUUID)) | ||||
| 			cfg = strings.Replace(cfg, "root=UUID="+b.rootUUID, "", 1) | ||||
| 		} else { | ||||
| 		switch b.osRelease.ID { | ||||
| 		case ReleaseAlpine: | ||||
| 			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) | ||||
| 		case ReleaseCentOS: | ||||
| 			cfg = fmt.Sprintf(sysconfig, b.rootUUID, fmt.Sprintf("%s rd.luks.name=UUID=%s rd.luks.uuid=%s rd.luks.crypttab=0", b.cmdLineExtra, b.rootUUID, b.cryptUUID)) | ||||
| 		default: | ||||
| 			cfg = fmt.Sprintf(sysconfig, b.rootUUID, fmt.Sprintf("%s root=/dev/mapper/root cryptopts=target=root,source=UUID=%s", b.cmdLineExtra, b.cryptUUID)) | ||||
| 			cfg = strings.Replace(cfg, "root=UUID="+b.rootUUID, "", 1) | ||||
| 		} | ||||
| 	} else { | ||||
| 		cfg = fmt.Sprintf(sysconfig, b.rootUUID, b.cmdLineExtra) | ||||
| @@ -577,3 +575,10 @@ func checkDependencies() error { | ||||
| func OutputFormats() []string { | ||||
| 	return formats[:] | ||||
| } | ||||
|  | ||||
| func ifElse(v bool, t string, f string) string { | ||||
| 	if v { | ||||
| 		return t | ||||
| 	} | ||||
| 	return f | ||||
| } | ||||
|   | ||||
| @@ -38,11 +38,16 @@ type test struct { | ||||
| 	args []string | ||||
| } | ||||
|  | ||||
| var images = []string{ | ||||
| 	"alpine:3.17", | ||||
| 	"ubuntu:20.04", | ||||
| 	"debian:11", | ||||
| 	"centos:8", | ||||
| type img struct { | ||||
| 	name string | ||||
| 	luks string | ||||
| } | ||||
|  | ||||
| var images = []img{ | ||||
| 	{name: "alpine:3.17", luks: "Enter passphrase for /dev/sda2:"}, | ||||
| 	{name: "ubuntu:20.04", luks: "Please unlock disk root:"}, | ||||
| 	{name: "debian:11", luks: "Please unlock disk root:"}, | ||||
| 	{name: "centos:8", luks: "Please enter passphrase for disk"}, | ||||
| } | ||||
|  | ||||
| func TestConvert(t *testing.T) { | ||||
| @@ -55,6 +60,10 @@ func TestConvert(t *testing.T) { | ||||
| 			name: "split-boot", | ||||
| 			args: []string{"--split-boot"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "luks", | ||||
| 			args: []string{"--luks-password=root"}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tt := range tests { | ||||
| @@ -64,21 +73,21 @@ func TestConvert(t *testing.T) { | ||||
| 			require.NoError(os.MkdirAll(dir, os.ModePerm)) | ||||
|  | ||||
| 			defer os.RemoveAll(dir) | ||||
| 			for _, i := range images { | ||||
| 				t.Run(i, func(t *testing.T) { | ||||
| 			for _, img := range images { | ||||
| 				t.Run(img.name, func(t *testing.T) { | ||||
| 					ctx, cancel := context.WithCancel(context.Background()) | ||||
| 					defer cancel() | ||||
|  | ||||
| 					// t.Parallel() | ||||
| 					require := require2.New(t) | ||||
|  | ||||
| 					out := filepath.Join(dir, strings.NewReplacer(":", "-", ".", "-").Replace(i)+".qcow2") | ||||
| 					out := filepath.Join(dir, strings.NewReplacer(":", "-", ".", "-").Replace(img.name)+".qcow2") | ||||
|  | ||||
| 					if _, err := os.Stat(out); err == nil { | ||||
| 						require.NoError(os.Remove(out)) | ||||
| 					} | ||||
|  | ||||
| 					require.NoError(docker.RunD2VM(ctx, d2vm.Image, d2vm.Version, dir, dir, "convert", append([]string{"-p", "root", "-o", "/out/" + filepath.Base(out), "-v", i}, tt.args...)...)) | ||||
| 					 | ||||
| 					require.NoError(docker.RunD2VM(ctx, d2vm.Image, d2vm.Version, dir, dir, "convert", append([]string{"-p", "root", "-o", "/out/" + filepath.Base(out), "-v", "--keep-cache", img.name}, tt.args...)...)) | ||||
|  | ||||
| 					inr, inw := io.Pipe() | ||||
| 					defer inr.Close() | ||||
| @@ -93,6 +102,9 @@ func TestConvert(t *testing.T) { | ||||
| 						password := []byte("Password:") | ||||
| 						s := bufio.NewScanner(outr) | ||||
| 						s.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) { | ||||
| 							if i := bytes.Index(data, []byte(img.luks)); i >= 0 { | ||||
| 								return i + len(img.luks), []byte(img.luks), nil | ||||
| 							} | ||||
| 							if i := bytes.Index(data, login); i >= 0 { | ||||
| 								return i + len(login), login, nil | ||||
| 							} | ||||
| @@ -106,8 +118,14 @@ func TestConvert(t *testing.T) { | ||||
| 						}) | ||||
| 						for s.Scan() { | ||||
| 							b := s.Bytes() | ||||
| 							if bytes.Contains(b, []byte(img.luks)) { | ||||
| 								t.Logf("sending luks password") | ||||
| 								if _, err := inw.Write([]byte("root\n")); err != nil { | ||||
| 									t.Logf("failed to write luks password: %v", err) | ||||
| 									cancel() | ||||
| 								} | ||||
| 							} | ||||
| 							if bytes.Contains(b, login) { | ||||
| 								t.Logf("vm ready") | ||||
| 								t.Logf("sending login") | ||||
| 								if _, err := inw.Write([]byte("root\n")); err != nil { | ||||
| 									t.Logf("failed to write login: %v", err) | ||||
| @@ -134,7 +152,7 @@ func TestConvert(t *testing.T) { | ||||
| 							cancel() | ||||
| 						} | ||||
| 					}() | ||||
| 					if err := qemu.Run(ctx, out, qemu.WithStdin(inr), qemu.WithStdout(io.MultiWriter(outw, os.Stdout)), qemu.WithStderr(io.Discard)); err != nil && !success.Load() { | ||||
| 					if err := qemu.Run(ctx, out, qemu.WithStdin(inr), qemu.WithStdout(io.MultiWriter(outw, os.Stdout)), qemu.WithStderr(io.Discard), qemu.WithMemory(2048)); err != nil && !success.Load() { | ||||
| 						t.Fatalf("failed to run qemu: %v", err) | ||||
| 					} | ||||
| 				}) | ||||
|   | ||||
| @@ -7,12 +7,20 @@ RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* && \ | ||||
|  | ||||
| RUN yum update -y | ||||
|  | ||||
| RUN yum install -y kernel systemd NetworkManager e2fsprogs sudo && \ | ||||
| RUN yum install -y \ | ||||
|     kernel \ | ||||
|     systemd \ | ||||
|     NetworkManager \ | ||||
|     e2fsprogs \ | ||||
|     {{- if .Luks }} | ||||
|     cryptsetup \ | ||||
|     {{- end }} | ||||
|     sudo && \ | ||||
|     systemctl enable NetworkManager && \ | ||||
|     systemctl unmask systemd-remount-fs.service && \ | ||||
|     systemctl unmask getty.target | ||||
|  | ||||
| RUN dracut --no-hostonly --regenerate-all --force && \ | ||||
| RUN dracut --no-hostonly --regenerate-all --force {{ if .Luks }}--install="/usr/sbin/cryptsetup"{{ end }}&& \ | ||||
|     cd /boot && \ | ||||
|     ln -s $(find . -name 'vmlinuz-*') vmlinuz && \ | ||||
|     ln -s $(find . -name 'initramfs-*.img') initrd.img | ||||
|   | ||||
		Reference in New Issue
	
	Block a user