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