Optional run 2-3 args + -c flag

This commit is contained in:
AlexSSD7 2023-09-27 15:37:28 +01:00
commit 2a2cf158fd
4 changed files with 69 additions and 23 deletions

View file

@ -33,10 +33,33 @@ import (
var runCmd = &cobra.Command{ var runCmd = &cobra.Command{
Use: "run", Use: "run",
Short: "Start a VM and expose an FTP file share.", Short: "Start a VM and expose an FTP file share.",
Args: cobra.ExactArgs(3), Args: cobra.RangeArgs(1, 3),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
vmMountDevName := args[1] var luksContainerDevice string
fsType := args[2]
vmMountDevName := "vdb"
if luksContainerFlag != "" {
if luksContainerEntireDriveFlag {
slog.Error("--luks-container and --luks-container-entire-drive (-c) cannot be both specified at once")
os.Exit(1)
}
luksContainerDevice = luksContainerFlag
} else if luksContainerEntireDriveFlag {
luksContainerDevice = vmMountDevName
}
if len(args) > 1 {
vmMountDevName = args[1]
} else if luksContainerDevice != "" {
slog.Error("Cannot use the default (entire) device with a LUKS container. Please specify the in-VM device name to mount as a second positional argument.")
}
var fsTypeOverride string
if len(args) > 2 {
fsTypeOverride = args[2]
}
newBackendFunc := share.GetBackend(shareBackendFlag) newBackendFunc := share.GetBackend(shareBackendFlag)
if newBackendFunc == nil { if newBackendFunc == nil {
@ -61,7 +84,7 @@ var runCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
if (luksFlag || luksContainerFlag != "") && !allowLUKSLowMemoryFlag { if (luksFlag || luksContainerDevice != "") && !allowLUKSLowMemoryFlag {
if vmMemAllocFlag < defaultMemAllocLUKS { if vmMemAllocFlag < defaultMemAllocLUKS {
if vmMemAllocFlag != defaultMemAlloc { if vmMemAllocFlag != defaultMemAlloc {
slog.Warn("Enforcing minimum LUKS memory allocation. Please add --allow-luks-low-memory to disable this.", "min", vmMemAllocFlag, "specified", vmMemAllocFlag) slog.Warn("Enforcing minimum LUKS memory allocation. Please add --allow-luks-low-memory to disable this.", "min", vmMemAllocFlag, "specified", vmMemAllocFlag)
@ -72,12 +95,17 @@ var runCmd = &cobra.Command{
} }
os.Exit(runVM(args[0], func(ctx context.Context, i *vm.VM, fm *vm.FileManager, tapCtx *share.NetTapRuntimeContext) int { os.Exit(runVM(args[0], func(ctx context.Context, i *vm.VM, fm *vm.FileManager, tapCtx *share.NetTapRuntimeContext) int {
slog.Info("Mounting the device", "dev", vmMountDevName, "fs", fsType, "luks", luksFlag) fsToLog := "<auto>"
if fsTypeOverride != "" {
fsToLog = fsTypeOverride
}
slog.Info("Mounting the device", "dev", vmMountDevName, "fs", fsToLog, "luks", luksFlag)
err := fm.Mount(vmMountDevName, vm.MountOptions{ err := fm.Mount(vmMountDevName, vm.MountOptions{
LUKSContainerPreopen: luksContainerFlag, LUKSContainerPreopen: luksContainerDevice,
FSType: fsType, FSTypeOverride: fsTypeOverride,
LUKS: luksFlag, LUKS: luksFlag,
}) })
if err != nil { if err != nil {
@ -131,6 +159,7 @@ var runCmd = &cobra.Command{
var ( var (
luksFlag bool luksFlag bool
luksContainerFlag string luksContainerFlag string
luksContainerEntireDriveFlag bool
allowLUKSLowMemoryFlag bool allowLUKSLowMemoryFlag bool
shareListenIPFlag string shareListenIPFlag string
ftpExtIPFlag string ftpExtIPFlag string
@ -142,6 +171,7 @@ var (
func init() { func init() {
runCmd.Flags().BoolVarP(&luksFlag, "luks", "l", false, "Use cryptsetup to open a LUKS volume (password will be prompted).") runCmd.Flags().BoolVarP(&luksFlag, "luks", "l", false, "Use cryptsetup to open a LUKS volume (password will be prompted).")
runCmd.Flags().StringVar(&luksContainerFlag, "luks-container", "", `Specifies a device path (without "dev/" prefix) to preopen as a LUKS container (password will be prompted). Useful for accessing LVM partitions behind LUKS.`) runCmd.Flags().StringVar(&luksContainerFlag, "luks-container", "", `Specifies a device path (without "dev/" prefix) to preopen as a LUKS container (password will be prompted). Useful for accessing LVM partitions behind LUKS.`)
runCmd.Flags().BoolVarP(&luksContainerEntireDriveFlag, "luks-container-entire-drive", "c", false, `Similar to --luks-container, but this assumes that the entire passed-through volume is a LUKS container (password will be prompted).`)
runCmd.Flags().BoolVar(&allowLUKSLowMemoryFlag, "allow-luks-low-memory", false, "Allow VM memory allocation lower than 2048 MiB when LUKS is enabled.") runCmd.Flags().BoolVar(&allowLUKSLowMemoryFlag, "allow-luks-low-memory", false, "Allow VM memory allocation lower than 2048 MiB when LUKS is enabled.")
runCmd.Flags().BoolVar(&debugShellFlag, "debug-shell", false, "Start a VM shell when the network file share is active.") runCmd.Flags().BoolVar(&debugShellFlag, "debug-shell", false, "Start a VM shell when the network file share is active.")

View file

@ -286,8 +286,6 @@ func getDevicePassthroughConfig(val string) (*vm.PassthroughConfig, error) {
slog.Warn("RISK WARNING: Skipping device block size detection and using the default of 512 bytes. Please use this ONLY to recover data from disks with filesystem that were locked to emulated 512-byte block size.") slog.Warn("RISK WARNING: Skipping device block size detection and using the default of 512 bytes. Please use this ONLY to recover data from disks with filesystem that were locked to emulated 512-byte block size.")
// TODO: Remove the need to specify the FS type manually.
devPath := filepath.Clean(valSplit[1]) devPath := filepath.Clean(valSplit[1])
err := osspecifics.CheckValidDevicePath(devPath) err := osspecifics.CheckValidDevicePath(devPath)

View file

@ -37,6 +37,12 @@ func ClearUnprintableChars(s string, allowNewlines bool) string {
}, s) }, s)
} }
var fsTypeRegex = regexp.MustCompile(`^[a-z0-9]+$`)
func ValidateFsType(s string) bool {
return fsTypeRegex.MatchString(s)
}
var devNameRegexp = regexp.MustCompile(`^[0-9a-z_-]+$`) var devNameRegexp = regexp.MustCompile(`^[0-9a-z_-]+$`)
func ValidateDevName(s string) bool { func ValidateDevName(s string) bool {

View file

@ -85,7 +85,7 @@ func (fm *FileManager) Lsblk() ([]byte, error) {
type MountOptions struct { type MountOptions struct {
LUKSContainerPreopen string LUKSContainerPreopen string
FSType string FSTypeOverride string
LUKS bool LUKS bool
} }
@ -186,8 +186,14 @@ func (fm *FileManager) Mount(devName string, mo MountOptions) error {
// Windows, but we're targeting a Linux VM.) // Windows, but we're targeting a Linux VM.)
fullDevPath := "/dev/" + devName fullDevPath := "/dev/" + devName
if mo.FSType == "" { var fsOverride string
return fmt.Errorf("fs type is empty")
if mo.FSTypeOverride != "" {
if !utils.ValidateFsType(mo.FSTypeOverride) {
return fmt.Errorf("bad fs type override (contains illegal characters)")
}
fsOverride = mo.FSTypeOverride
} }
sc, err := fm.vm.DialSSH() sc, err := fm.vm.DialSSH()
@ -228,7 +234,13 @@ func (fm *FileManager) Mount(devName string, mo MountOptions) error {
fullDevPath = "/dev/mapper/" + luksDMName fullDevPath = "/dev/mapper/" + luksDMName
} }
_, err = sshutil.RunSSHCmd(fm.vm.ctx, sc, "mount -t "+shellescape.Quote(mo.FSType)+" "+shellescape.Quote(fullDevPath)+" /mnt") cmd := "mount "
if fsOverride != "" {
cmd += "-t " + shellescape.Quote(fsOverride) + " "
}
cmd += shellescape.Quote(fullDevPath) + " /mnt"
_, err = sshutil.RunSSHCmd(fm.vm.ctx, sc, cmd)
if err != nil { if err != nil {
return errors.Wrap(err, "run mount cmd") return errors.Wrap(err, "run mount cmd")
} }