From ed599a5ce9bba08888dd2170a5220c515592bbd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20B=C3=BChler?= Date: Sat, 21 Jan 2023 09:45:26 +0100 Subject: [PATCH] Add rosetta support for Linux guest VMs. (#42) This requires tart 0.3.5. --- builder/tart/builder.go | 1 + builder/tart/builder.hcl2spec.go | 2 ++ builder/tart/step_create_linux_vm.go | 7 ++++-- docs/builders/tart.mdx | 1 + example/install_rosetta.sh | 8 +++++++ example/ubuntu-22.04-rosetta.pkr.hcl | 34 ++++++++++++++++++++++++++++ version/version.go | 2 +- 7 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 example/install_rosetta.sh create mode 100644 example/ubuntu-22.04-rosetta.pkr.hcl diff --git a/builder/tart/builder.go b/builder/tart/builder.go index 3eebf17..1f5f505 100644 --- a/builder/tart/builder.go +++ b/builder/tart/builder.go @@ -27,6 +27,7 @@ type Config struct { VMName string `mapstructure:"vm_name" required:"true"` VMBaseName string `mapstructure:"vm_base_name" required:"true"` Recovery bool `mapstructure:"recovery" required:"false"` + Rosetta string `mapstructure:"rosetta" required:"false"` CpuCount uint8 `mapstructure:"cpu_count" required:"false"` MemoryGb uint16 `mapstructure:"memory_gb" required:"false"` Display string `mapstructure:"display" required:"false"` diff --git a/builder/tart/builder.hcl2spec.go b/builder/tart/builder.hcl2spec.go index 1ff5939..1d5ad03 100644 --- a/builder/tart/builder.hcl2spec.go +++ b/builder/tart/builder.hcl2spec.go @@ -28,6 +28,7 @@ type FlatConfig struct { VMName *string `mapstructure:"vm_name" required:"true" cty:"vm_name" hcl:"vm_name"` VMBaseName *string `mapstructure:"vm_base_name" required:"true" cty:"vm_base_name" hcl:"vm_base_name"` Recovery *bool `mapstructure:"recovery" required:"false" cty:"recovery" hcl:"recovery"` + Rosetta *string `mapstructure:"rosetta" required:"false" cty:"rosetta" hcl:"rosetta"` CpuCount *uint8 `mapstructure:"cpu_count" required:"false" cty:"cpu_count" hcl:"cpu_count"` MemoryGb *uint16 `mapstructure:"memory_gb" required:"false" cty:"memory_gb" hcl:"memory_gb"` Display *string `mapstructure:"display" required:"false" cty:"display" hcl:"display"` @@ -115,6 +116,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { "vm_name": &hcldec.AttrSpec{Name: "vm_name", Type: cty.String, Required: false}, "vm_base_name": &hcldec.AttrSpec{Name: "vm_base_name", Type: cty.String, Required: false}, "recovery": &hcldec.AttrSpec{Name: "recovery", Type: cty.Bool, Required: false}, + "rosetta": &hcldec.AttrSpec{Name: "rosetta", Type: cty.String, Required: false}, "cpu_count": &hcldec.AttrSpec{Name: "cpu_count", Type: cty.Number, Required: false}, "memory_gb": &hcldec.AttrSpec{Name: "memory_gb", Type: cty.Number, Required: false}, "display": &hcldec.AttrSpec{Name: "display", Type: cty.String, Required: false}, diff --git a/builder/tart/step_create_linux_vm.go b/builder/tart/step_create_linux_vm.go index d9012d3..55eef3f 100644 --- a/builder/tart/step_create_linux_vm.go +++ b/builder/tart/step_create_linux_vm.go @@ -20,7 +20,7 @@ func (s *stepCreateLinuxVM) Run(ctx context.Context, state multistep.StateBag) m ui.Say("Creating virtual machine...") createArguments := []string{ - "create", "--linux", + "create", "--linux", } if config.DiskSizeGb > 0 { @@ -60,12 +60,15 @@ func (s *stepCreateLinuxVM) RunInstaller(ctx context.Context, state multistep.St ui := state.Get("ui").(packersdk.Ui) ui.Say("Starting the virtual machine for installation...") - runArgs := []string{"run", config.VMName, } + runArgs := []string{"run", config.VMName} if config.Headless { runArgs = append(runArgs, "--no-graphics") } else { runArgs = append(runArgs, "--graphics") } + if config.Rosetta != "" { + runArgs = append(runArgs, fmt.Sprintf("--rosetta=%s", config.Rosetta)) + } if !config.DisableVNC { runArgs = append(runArgs, "--vnc-experimental") } diff --git a/docs/builders/tart.mdx b/docs/builders/tart.mdx index 4375887..799819c 100644 --- a/docs/builders/tart.mdx +++ b/docs/builders/tart.mdx @@ -45,6 +45,7 @@ Below we'll go through available options of this Packer plugin - `ssh_username` (string) - Username to use for the communication over SSH to run provision steps. - `ssh_password` (string) - Password to use for the communication over SSH to run provision steps. - `headless` (boolean) - Whether to show graphics interface of a VM. Useful for debugging `boot_command`. +- `rosetta` (string) - Whether to enable Rosetta support of a Linux guest VM. Useful for running non arm64 programs in the guest VM. A common used value is `rosetta`. For further details and explanation run `tart run --help` - `boot_command` (array of strings) - This is an array of commands to type when the virtual machine is first booted. The goal of these commands should be to type just enough to initialize the operating system installer. ### Example Usage diff --git a/example/install_rosetta.sh b/example/install_rosetta.sh new file mode 100644 index 0000000..6991cd7 --- /dev/null +++ b/example/install_rosetta.sh @@ -0,0 +1,8 @@ +#!/bin/sh -x + +sudo mkdir /var/run/rosetta +sudo mount -t virtiofs rosetta /var/run/rosetta +sudo /usr/sbin/update-binfmts --install rosetta /var/run/rosetta/rosetta \ + --magic "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00" \ + --mask "\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" \ + --credentials yes --preserve no --fix-binary yes diff --git a/example/ubuntu-22.04-rosetta.pkr.hcl b/example/ubuntu-22.04-rosetta.pkr.hcl new file mode 100644 index 0000000..09e8100 --- /dev/null +++ b/example/ubuntu-22.04-rosetta.pkr.hcl @@ -0,0 +1,34 @@ +packer { + required_plugins { + tart = { + version = ">= 0.6.2" + source = "github.com/cirruslabs/tart" + } + } +} + +source "tart-cli" "tart" { + vm_base_name = "ubuntu-22.04-vanilla" + vm_name = "ubuntu-22.04-rosetta" + headless = true + disable_vnc = true + rosetta = "rosetta" + ssh_password = "ubuntu" + ssh_username = "ubuntu" + ssh_timeout = "120s" +} + +build { + sources = ["source.tart-cli.tart"] + + provisioner "shell" { + inline = [ + "sudo apt update && sudo apt-get install -y binfmt-support", + ] + } + + provisioner "shell" { + script = "install_rosetta.sh" + remote_path = "/tmp/install_rosetta.sh" + } +} diff --git a/version/version.go b/version/version.go index a5b0551..8ff0d6a 100644 --- a/version/version.go +++ b/version/version.go @@ -6,7 +6,7 @@ import ( var ( // Version is the main version number that is being run at the moment. - Version = "0.3.0" + Version = "0.6.2" // VersionPrerelease is A pre-release marker for the Version. If this is "" // (empty string) then it means that it is a final release. Otherwise, this