Skip to content

Commit 9c0e304

Browse files
authored
Merge pull request #545 from dwc0011/add-manual-mount-command-option
Add manual mount command option
2 parents b321cdd + b2a5dcc commit 9c0e304

File tree

5 files changed

+68
-37
lines changed

5 files changed

+68
-37
lines changed

.web-docs/components/builder/chroot/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ information.
122122
a command with sudo or so on. This is a configuration template where the `.Command` variable
123123
is replaced with the command to be run. Defaults to `{{.Command}}`.
124124

125+
- `manual_mount_command` (string) - Manual Mount Command that is executed to manually mount the
126+
root device and before the post mount commands. The device and
127+
mount path are provided by `{{.Device}}` and `{{.MountPath}}`.
128+
125129
- `pre_mount_commands` ([]string) - A series of commands to execute after attaching the root volume and before mounting the chroot.
126130
This is not required unless using `from_scratch`. If so, this should include any partitioning
127131
and filesystem creation commands. The path to the device is provided by `{{.Device}}`.

builder/azure/chroot/builder.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ type Config struct {
6161
// a command with sudo or so on. This is a configuration template where the `.Command` variable
6262
// is replaced with the command to be run. Defaults to `{{.Command}}`.
6363
CommandWrapper string `mapstructure:"command_wrapper"`
64+
// Manual Mount Command that is executed to manually mount the
65+
// root device and before the post mount commands. The device and
66+
// mount path are provided by `{{.Device}}` and `{{.MountPath}}`.
67+
ManualMountCommand string `mapstructure:"manual_mount_command" required:"false"`
6468
// A series of commands to execute after attaching the root volume and before mounting the chroot.
6569
// This is not required unless using `from_scratch`. If so, this should include any partitioning
6670
// and filesystem creation commands. The path to the device is provided by `{{.Device}}`.
@@ -169,6 +173,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
169173
"command_wrapper",
170174
"post_mount_commands",
171175
"pre_mount_commands",
176+
"manual_mount_command",
172177
"mount_path",
173178
},
174179
},
@@ -613,6 +618,7 @@ func buildsteps(
613618
},
614619
&StepMountDevice{
615620
MountOptions: config.MountOptions,
621+
Command: config.ManualMountCommand,
616622
MountPartition: config.MountPartition,
617623
MountPath: config.MountPath,
618624
},

builder/azure/chroot/builder.hcl2spec.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builder/azure/chroot/step_mount_device.go

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"context"
1111
"fmt"
1212
"os"
13+
"os/exec"
1314
"path/filepath"
1415
"runtime"
1516
"strings"
@@ -25,19 +26,20 @@ import (
2526
var _ multistep.Step = &StepMountDevice{}
2627

2728
type StepMountDevice struct {
29+
Command string
2830
MountOptions []string
2931
MountPartition string
3032
MountPath string
3133

32-
mountPath string
34+
mountPath string
35+
isManualMount bool
3336
}
3437

3538
func (s *StepMountDevice) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
3639
ui := state.Get("ui").(packersdk.Ui)
3740
device := state.Get("device").(string)
3841
config := state.Get("config").(*Config)
39-
wrappedCommand := state.Get("wrappedCommand").(common.CommandWrapper)
40-
42+
isManualMount := s.Command != ""
4143
ictx := config.ctx
4244

4345
ictx.Data = &struct{ Device string }{Device: filepath.Base(device)}
@@ -59,12 +61,13 @@ func (s *StepMountDevice) Run(ctx context.Context, state multistep.StateBag) mul
5961
}
6062

6163
log.Printf("Mount path: %s", mountPath)
62-
63-
if err := os.MkdirAll(mountPath, 0755); err != nil {
64-
err := fmt.Errorf("error creating mount directory: %s", err)
65-
state.Put("error", err)
66-
ui.Error(err.Error())
67-
return multistep.ActionHalt
64+
if !isManualMount {
65+
if err := os.MkdirAll(mountPath, 0755); err != nil {
66+
err := fmt.Errorf("error creating mount directory: %s", err)
67+
state.Put("error", err)
68+
ui.Error(err.Error())
69+
return multistep.ActionHalt
70+
}
6871
}
6972

7073
var deviceMount string
@@ -79,23 +82,31 @@ func (s *StepMountDevice) Run(ctx context.Context, state multistep.StateBag) mul
7982

8083
ui.Say("Mounting the root device...")
8184
stderr := new(bytes.Buffer)
82-
83-
// build mount options from mount_options config, useful for nouuid options
84-
// or other specific device type settings for mount
85-
opts := ""
86-
if len(s.MountOptions) > 0 {
87-
opts = "-o " + strings.Join(s.MountOptions, " -o ")
88-
}
89-
mountCommand, err := wrappedCommand(
90-
fmt.Sprintf("mount %s %s %s", opts, deviceMount, mountPath))
91-
if err != nil {
92-
err := fmt.Errorf("error creating mount command: %s", err)
93-
state.Put("error", err)
94-
ui.Error(err.Error())
95-
return multistep.ActionHalt
85+
var cmd *exec.Cmd
86+
if !isManualMount {
87+
// build mount options from mount_options config, useful for nouuid options
88+
// or other specific device type settings for mount
89+
opts := ""
90+
if len(s.MountOptions) > 0 {
91+
opts = "-o " + strings.Join(s.MountOptions, " -o ")
92+
}
93+
wrappedCommand := state.Get("wrappedCommand").(common.CommandWrapper)
94+
mountCommand, err := wrappedCommand(
95+
fmt.Sprintf("mount %s %s %s", opts, deviceMount, mountPath))
96+
if err != nil {
97+
err := fmt.Errorf("error creating mount command: %s", err)
98+
state.Put("error", err)
99+
ui.Error(err.Error())
100+
return multistep.ActionHalt
101+
}
102+
log.Printf("[DEBUG] (step mount) mount command is %s", mountCommand)
103+
cmd = common.ShellCommand(mountCommand)
104+
105+
} else {
106+
log.Printf("[DEBUG] (step mount) mount command is %s", s.Command)
107+
cmd = common.ShellCommand(fmt.Sprintf("%s %s", s.Command, mountPath))
96108
}
97-
log.Printf("[DEBUG] (step mount) mount command is %s", mountCommand)
98-
cmd := common.ShellCommand(mountCommand)
109+
99110
cmd.Stderr = stderr
100111
if err := cmd.Run(); err != nil {
101112
err := fmt.Errorf(
@@ -107,6 +118,7 @@ func (s *StepMountDevice) Run(ctx context.Context, state multistep.StateBag) mul
107118

108119
// Set the mount path so we remember to unmount it later
109120
s.mountPath = mountPath
121+
s.isManualMount = isManualMount
110122
state.Put("mount_path", s.mountPath)
111123
state.Put("mount_device_cleanup", s)
112124

@@ -126,19 +138,22 @@ func (s *StepMountDevice) CleanupFunc(state multistep.StateBag) error {
126138
}
127139

128140
ui := state.Get("ui").(packersdk.Ui)
129-
wrappedCommand := state.Get("wrappedCommand").(common.CommandWrapper)
130-
131-
ui.Say("Unmounting the root device...")
132-
unmountCommand, err := wrappedCommand(fmt.Sprintf("umount -R %s", s.mountPath))
133-
if err != nil {
134-
return fmt.Errorf("error creating unmount command: %s", err)
141+
if !s.isManualMount {
142+
wrappedCommand := state.Get("wrappedCommand").(common.CommandWrapper)
143+
144+
ui.Say("Unmounting the root device...")
145+
unmountCommand, err := wrappedCommand(fmt.Sprintf("umount -R %s", s.mountPath))
146+
if err != nil {
147+
return fmt.Errorf("error creating unmount command: %s", err)
148+
}
149+
150+
cmd := common.ShellCommand(unmountCommand)
151+
if err := cmd.Run(); err != nil {
152+
return fmt.Errorf("error unmounting root device: %s", err)
153+
}
154+
} else {
155+
ui.Say("Skipping Unmounting the root device, it is manually unmounted via manual mount command script...")
135156
}
136-
137-
cmd := common.ShellCommand(unmountCommand)
138-
if err := cmd.Run(); err != nil {
139-
return fmt.Errorf("error unmounting root device: %s", err)
140-
}
141-
142157
s.mountPath = ""
143158
return nil
144159
}

docs-partials/builder/azure/chroot/Config-not-required.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
a command with sudo or so on. This is a configuration template where the `.Command` variable
77
is replaced with the command to be run. Defaults to `{{.Command}}`.
88

9+
- `manual_mount_command` (string) - Manual Mount Command that is executed to manually mount the
10+
root device and before the post mount commands. The device and
11+
mount path are provided by `{{.Device}}` and `{{.MountPath}}`.
12+
913
- `pre_mount_commands` ([]string) - A series of commands to execute after attaching the root volume and before mounting the chroot.
1014
This is not required unless using `from_scratch`. If so, this should include any partitioning
1115
and filesystem creation commands. The path to the device is provided by `{{.Device}}`.

0 commit comments

Comments
 (0)