Optional run 2-3 args + -c flag
This commit is contained in:
parent
4d504f70d1
commit
2a2cf158fd
4 changed files with 69 additions and 23 deletions
62
cmd/run.go
62
cmd/run.go
|
|
@ -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.")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue