summaryrefslogtreecommitdiff
path: root/actions/image_partition_action.go
diff options
context:
space:
mode:
Diffstat (limited to 'actions/image_partition_action.go')
-rw-r--r--actions/image_partition_action.go55
1 files changed, 42 insertions, 13 deletions
diff --git a/actions/image_partition_action.go b/actions/image_partition_action.go
index 5054e6d..cd832ac 100644
--- a/actions/image_partition_action.go
+++ b/actions/image_partition_action.go
@@ -116,6 +116,7 @@ import (
"os"
"os/exec"
"path"
+ "path/filepath"
"strings"
"syscall"
@@ -183,19 +184,23 @@ func (i *ImagePartitionAction) generateKernelRoot(context *debos.DebosContext) e
}
func (i ImagePartitionAction) getPartitionDevice(number int, context debos.DebosContext) string {
+ /* Always look up canonical device as udev might not generate the by-id
+ * symlinks while there is an flock on /dev/vda */
+ device, _ := filepath.EvalSymlinks(context.Image)
+
suffix := "p"
/* Check partition naming first: if used 'by-id'i naming convention */
- if strings.Contains(context.Image, "/disk/by-id/") {
+ if strings.Contains(device, "/disk/by-id/") {
suffix = "-part"
}
/* If the iamge device has a digit as the last character, the partition
* suffix is p<number> else it's just <number> */
- last := context.Image[len(context.Image)-1]
+ last := device[len(device)-1]
if last >= '0' && last <= '9' {
- return fmt.Sprintf("%s%s%d", context.Image, suffix, number)
+ return fmt.Sprintf("%s%s%d", device, suffix, number)
} else {
- return fmt.Sprintf("%s%d", context.Image, number)
+ return fmt.Sprintf("%s%d", device, number)
}
}
@@ -247,7 +252,7 @@ func (i ImagePartitionAction) formatPartition(p *Partition, context debos.DebosC
return nil
}
-func (i ImagePartitionAction) PreNoMachine(context *debos.DebosContext) error {
+func (i *ImagePartitionAction) PreNoMachine(context *debos.DebosContext) error {
img, err := os.OpenFile(i.ImageName, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
@@ -274,11 +279,28 @@ func (i ImagePartitionAction) PreNoMachine(context *debos.DebosContext) error {
func (i ImagePartitionAction) Run(context *debos.DebosContext) error {
i.LogStart()
+ /* Exclusively Lock image device file to prevent udev from triggering
+ * partition rescans, which cause confusion as some time asynchronously the
+ * partition device might disappear and reappear due to that! */
+ imageFD, err := os.Open(context.Image)
+ if err != nil {
+ return err
+ }
+ /* Defer will keep the fd open until the function returns, at which points
+ * the filesystems will have been mounted protecting from more udev funnyness
+ */
+ defer imageFD.Close()
+
+ err = syscall.Flock(int(imageFD.Fd()), syscall.LOCK_EX)
+ if err != nil {
+ return err
+ }
+
command := []string{"parted", "-s", context.Image, "mklabel", i.PartitionType}
if len(i.GptGap) > 0 {
command = append(command, i.GptGap)
}
- err := debos.Command{}.Run("parted", command...)
+ err = debos.Command{}.Run("parted", command...)
if err != nil {
return err
}
@@ -317,12 +339,6 @@ func (i ImagePartitionAction) Run(context *debos.DebosContext) error {
}
devicePath := i.getPartitionDevice(p.number, *context)
- // Give a chance for udevd to create proper symlinks
- err = debos.Command{}.Run("udevadm", "udevadm", "settle", "-t", "5",
- "-E", devicePath)
- if err != nil {
- return err
- }
err = i.formatPartition(p, *context)
if err != nil {
@@ -358,7 +374,7 @@ func (i ImagePartitionAction) Run(context *debos.DebosContext) error {
return nil
}
-func (i ImagePartitionAction) Cleanup(context debos.DebosContext) error {
+func (i ImagePartitionAction) Cleanup(context *debos.DebosContext) error {
for idx := len(i.Mountpoints) - 1; idx >= 0; idx-- {
m := i.Mountpoints[idx]
mntpath := path.Join(context.ImageMntDir, m.Mountpoint)
@@ -372,6 +388,19 @@ func (i ImagePartitionAction) Cleanup(context debos.DebosContext) error {
return nil
}
+func (i ImagePartitionAction) PostMachineCleanup(context *debos.DebosContext) error {
+ image := path.Join(context.Artifactdir, i.ImageName)
+ /* Remove the image in case of any action failure */
+ if context.State != debos.Success {
+ if _, err := os.Stat(image); !os.IsNotExist(err) {
+ if err = os.Remove(image); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
func (i *ImagePartitionAction) Verify(context *debos.DebosContext) error {
if len(i.GptGap) > 0 {
log.Println("WARNING: special version of parted is needed for 'gpt_gap' option")