Skip to content

Commit

Permalink
Fixed hardcoded root partition device name sda2
Browse files Browse the repository at this point in the history
The root partition may not be /dev/sda2, for example if set the boot disk as the
second disk, the root partition device name will be /dev/sdb2. It may be
/dev/vda2 if not using san disk. The fix figured out the root partition device
UUID and set the UUID as the root, the root partition device UUID keeps no
change.

Signed-off-by: JUN JIE NAN <[email protected]>
  • Loading branch information
nanjj committed Apr 3, 2024
1 parent a49adf1 commit 8603c91
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
8 changes: 8 additions & 0 deletions distrobuilder/main_incus.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"context"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -352,6 +353,13 @@ func (c *cmdIncus) run(cmd *cobra.Command, args []string, overlayDir string) err
return fmt.Errorf("Failed to mount UEFI partition: %w", err)
}

rootfsDevUUID, err := vm.findRootfsDevUUID()
if err != nil {
return fmt.Errorf("Failed to find rootfs device UUID: %w", err)
}

c.global.ctx = context.WithValue(c.global.ctx, shared.ContextKeyEnviron,
[]string{fmt.Sprintf("ROOTFS_DEVICE_UUID=%s", rootfsDevUUID)})
// We cannot use Incus' rsync package as that uses the --delete flag which
// causes an issue due to the boot/efi directory being present.
err = shared.RsyncLocal(c.global.ctx, overlayDir+"/", vmDir)
Expand Down
29 changes: 29 additions & 0 deletions distrobuilder/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,35 @@ func (v *vm) getUEFIDevFile() string {
return fmt.Sprintf("%sp1", v.loopDevice)
}

func (v *vm) findRootfsDevUUID() (rootUUID string, err error) {
rootfsDevFile := v.getRootfsDevFile()
if rootfsDevFile == "" {
err = fmt.Errorf("Failed to get rootfs device name.")
return
}

var out strings.Builder
if err = shared.RunCommand(v.ctx, nil, &out, "blkid", "-o", "export", rootfsDevFile); err != nil {
err = fmt.Errorf("Failed to get rootfs device UUID: %w", err)
return
}

fields := strings.Fields(out.String())
for _, field := range fields {
if strings.HasPrefix(field, "UUID=") {
rootUUID = field
break
}
}

if rootUUID == "" {
err = fmt.Errorf("No rootfs device UUID found")
return
}

return
}

func (v *vm) createEmptyDiskImage() error {
f, err := os.Create(v.imageFile)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions shared/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
yaml "gopkg.in/yaml.v2"
)

const ContextKeyEnviron = ContextKey("environ")

// EnvVariable represents a environment variable.
type EnvVariable struct {
Value string
Expand All @@ -27,6 +29,9 @@ type EnvVariable struct {
// Environment represents a set of environment variables.
type Environment map[string]EnvVariable

// ContextKey type.
type ContextKey string

// Copy copies a file.
func Copy(src, dest string) error {
var err error
Expand Down Expand Up @@ -56,6 +61,10 @@ func Copy(src, dest string) error {
// RunCommand runs a command. Stdout is written to the given io.Writer. If nil, it's written to the real stdout. Stderr is always written to the real stderr.
func RunCommand(ctx context.Context, stdin io.Reader, stdout io.Writer, name string, arg ...string) error {
cmd := exec.CommandContext(ctx, name, arg...)
env, ok := ctx.Value(ContextKeyEnviron).([]string)
if ok && len(env) > 0 {
cmd.Env = append(os.Environ(), env...)
}

if stdin != nil {
cmd.Stdin = stdin
Expand Down

0 comments on commit 8603c91

Please sign in to comment.