diff --git a/builder/amazon/chroot/builder.go b/builder/amazon/chroot/builder.go index 02923ce31..a8b20276a 100644 --- a/builder/amazon/chroot/builder.go +++ b/builder/amazon/chroot/builder.go @@ -33,6 +33,7 @@ type Config struct { CommandWrapper string `mapstructure:"command_wrapper"` CopyFiles []string `mapstructure:"copy_files"` DevicePath string `mapstructure:"device_path"` + NVMEDevicePath string `mapstructure:"nvme_device_path"` FromScratch bool `mapstructure:"from_scratch"` MountOptions []string `mapstructure:"mount_options"` MountPartition string `mapstructure:"mount_partition"` diff --git a/builder/amazon/chroot/step_mount_device.go b/builder/amazon/chroot/step_mount_device.go index c05ae2e77..38ec62164 100644 --- a/builder/amazon/chroot/step_mount_device.go +++ b/builder/amazon/chroot/step_mount_device.go @@ -35,6 +35,10 @@ func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multi config := state.Get("config").(*Config) ui := state.Get("ui").(packer.Ui) device := state.Get("device").(string) + if config.NVMEDevicePath != "" { + // customizable device path for mounting NVME block devices on c5 and m5 HVM + device = config.NVMEDevicePath + } wrappedCommand := state.Get("wrappedCommand").(CommandWrapper) var virtualizationType string @@ -47,6 +51,7 @@ func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multi } ctx := config.ctx + ctx.Data = &mountPathData{Device: filepath.Base(device)} mountPath, err := interpolate.Render(config.MountPath, &ctx) @@ -98,7 +103,7 @@ func (s *StepMountDevice) Run(_ context.Context, state multistep.StateBag) multi ui.Error(err.Error()) return multistep.ActionHalt } - + log.Printf("[DEBUG] (step mount) mount command is %s", mountCommand) cmd := ShellCommand(mountCommand) cmd.Stderr = stderr if err := cmd.Run(); err != nil { diff --git a/website/source/docs/builders/amazon-chroot.html.md b/website/source/docs/builders/amazon-chroot.html.md index da1752144..9c16fc320 100644 --- a/website/source/docs/builders/amazon-chroot.html.md +++ b/website/source/docs/builders/amazon-chroot.html.md @@ -225,6 +225,14 @@ each category, the available configuration keys are alphabetized. command](http://linuxcommand.org/man_pages/mount8.html) for valid file system specific options +- `nvme_device_path` (string) - When we call the mount command (by default + `mount -o device dir`), the string provided in `nvme_mount_path` will + replace `device` in that command. When this option is not set, `device` in + that command will be something like `/dev/sdf1`, mirroring the attached + device name. This assumption works for most instances but will fail with c5 + and m5 instances. In order to use the chroot builder with c5 and m5 + instances, you must manually set `nvme_device_path` and `device_path`. + - `pre_mount_commands` (array of strings) - A series of commands to execute after attaching the root volume and before mounting the chroot. This is not required unless using `from_scratch`. If so, this should include any @@ -370,6 +378,7 @@ its internals such as finding an available device. ## Gotchas +### Unmounting the Filesystem One of the difficulties with using the chroot builder is that your provisioning scripts must not leave any processes running or packer will be unable to unmount the filesystem. @@ -399,6 +408,53 @@ services: } ``` +### Using Instances with NVMe block devices. +In C5, C5d, M5, and i3.metal instances, EBS volumes are exposed as NVMe block +devices [reference](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html). +In order to correctly mount these devices, you have to do some extra legwork, +involving the `nvme_device_path` option above. Read that for more information. + +A working example for mounting an NVMe device is below: + +``` +{ + "variables": { + "region" : "us-east-2" + }, + "builders": [ + { + "type": "amazon-chroot", + "region": "{{user `region`}}", + "source_ami_filter": { + "filters": { + "virtualization-type": "hvm", + "name": "amzn-ami-hvm-*", + "root-device-type": "ebs" + }, + "owners": ["137112412989"], + "most_recent": true + }, + "ena_support": true, + "ami_name": "amazon-chroot-test-{{timestamp}}", + "nvme_device_path": "/dev/nvme1n1p", + "device_path": "/dev/sdf" + } + ], + + "provisioners": [ + { + "type": "shell", + "inline": ["echo Test > /tmp/test.txt"] + } + ] +} +``` + +Note that in the `nvme_device_path` you must end with the `p`; if you try to +define the partition in this path (e.g. "nvme_device_path": `/dev/nvme1n1p1`) +and haven't also set the `"mount_partition": 0`, a `1` will be appended to the +`nvme_device_path` and Packer will fail. + ## Building From Scratch This example demonstrates the essentials of building an image from scratch. A