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,13 +95,18 @@ 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 {
slog.Error("Failed to mount the disk inside the VM", "error", err.Error()) slog.Error("Failed to mount the disk inside the VM", "error", err.Error())
@ -129,19 +157,21 @@ var runCmd = &cobra.Command{
} }
var ( var (
luksFlag bool luksFlag bool
luksContainerFlag string luksContainerFlag string
allowLUKSLowMemoryFlag bool luksContainerEntireDriveFlag bool
shareListenIPFlag string allowLUKSLowMemoryFlag bool
ftpExtIPFlag string shareListenIPFlag string
shareBackendFlag string ftpExtIPFlag string
smbUseExternAddrFlag bool shareBackendFlag string
debugShellFlag bool smbUseExternAddrFlag bool
debugShellFlag bool
) )
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,8 +85,8 @@ func (fm *FileManager) Lsblk() ([]byte, error) {
type MountOptions struct { type MountOptions struct {
LUKSContainerPreopen string LUKSContainerPreopen string
FSType string FSTypeOverride string
LUKS bool LUKS bool
} }
func (fm *FileManager) luksOpen(sc *ssh.Client, fullDevPath string, luksDMName string) error { func (fm *FileManager) luksOpen(sc *ssh.Client, fullDevPath string, luksDMName string) error {
@ -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")
} }