Index: vws ================================================================== --- vws +++ vws @@ -57,11 +57,10 @@ readfd, _, _ = select.select([sock], [], [], 0.1) if sock in readfd: _ = sock.recv(1024) return sock - def send_command(sock, command): """Sends monitor command to given socket and returns answer""" if sock is None: raise RuntimeError("None socket is passed to send_command") fcntl.flock(sock, fcntl.LOCK_EX) @@ -81,11 +80,10 @@ raise IOError("Unexpected EOF from monitor") answer += chunk.decode("utf-8") finally: fcntl.flock(sock, fcntl.LOCK_UN) return answer - def spiceurl(sock): """Returns spice URI for given (as set of parsed args) VM""" output = send_command(sock, "info spice") url = None @@ -139,11 +137,11 @@ return addr_map def validate_size(size): """Checks if size argument has proper format""" - return re.match("\\d+[KMG]", size) is not None + return re.match("[0-9]+[KMG]", size) is not None def get_drives(vm_dir): """Return list of drive files in the VW directory""" result = [] @@ -153,17 +151,15 @@ match = re.search("file=([^,\\s]*)", line) if match: result.append(match.group(1)) return result - def snapshot_mode(sock): """Returns True if VM is running in snapshot mode""" print("Entering snapshot_mode", file=sys.stderr) answer = send_command(sock, "info block") return re.search(": /tmp", answer) is not None - def read_netinfo(filename): """Reads network information from start script""" with open(filename, "r", encoding="utf-8") as f: for line in f: @@ -176,12 +172,10 @@ f["iface"] = re.search("br=(\\S+)", line).group(1) else: f["iface"] = "unknown" return f return {"iface": "unknown", "mac": "?", "ip": "?"} - - def get_netinfo(sock): """Gets network information from the running VM""" answer = send_command(sock, "info network") match = re.search("bridge\\.0:.*,br=(\\S+).*macaddr=(\\S+)", answer, re.S) if match: @@ -194,21 +188,17 @@ ) if match: return {"iface": match.group(1), "mac": match.group(2)} print(answer, file=sys.stderr) return {"iface": "unknown", "ip": "?", "mac": "?", "card": "?"} - - # # command implementation # - def cmd_spiceuri(options): """vws spiceuri""" print(spiceurl(options.sock)) - def fix_bridge_name(filename): """ Checks if bridge listed in network configuration exists on this machine, and replaces it with default one @@ -252,11 +242,10 @@ nxt = 0 snapshot_id = line[: line.index(" ")] return snapshot_id return None - def make_start_cmdline(options): """ Append options passed from vws commandline to start script commandline """ @@ -271,12 +260,10 @@ if options.password: os.environ["SPICE_PASSWORD"] = options.password[0] if arg: return shlex.join(arg) return "" - - def cmd_start(options): """vws start""" if "DISPLAY" not in os.environ: # If cannot start GUI just don't do it. options.gui = False @@ -293,11 +280,11 @@ os.stat("monitor") except FileNotFoundError: # We cannot find monitor socket. So this machine might be # never run on this host fix_bridge_name("start") - os.system("./start%s" % arg) + os.system("./start %s" % arg) os.chdir(cwd) time.sleep(2) options.sock = connect_vm(options.dir) if options.sock is None: print("VM start failed", file=sys.stderr) @@ -318,11 +305,10 @@ if options.gui: os.system((config.get("tools", "viewer") + "&") % uri) elif not options.stopped: print("VM already running use uri %s" % uri, file=sys.stderr) - def cmd_stop(options): """vws stop""" print("entering cmd_stop", file=sys.stderr) if options.hard or snapshot_mode(options.sock): try: @@ -333,11 +319,10 @@ print("monitor socket closed") else: raise ex else: print(send_command(options.sock, "system_powerdown")) - def cmd_monitor(options): """vws monitor""" eol = False try: @@ -367,12 +352,10 @@ print("") eol = True print("Keyboard interrupt") if not eol: print("") - - def cmd_reset(options): """vws reset""" print(send_command(options.sock, "system_reset")) @@ -383,11 +366,10 @@ print(answer, file=sys.stderr) sys.exit(1) else: options.hard = True cmd_stop(options) - def cmd_cdrom(options): """vws cdrom""" if options.id is None: # Search for devices which could be interpreted as CDROM @@ -407,15 +389,15 @@ options.id = dev_id break if options.id is None: print("No CDROM device found among:\n" + devlist, file=sys.stderr) return 1 - if options.file == "": + if options.eject: + answer = send_command(options.sock, "eject " + options.id) + elif options.file == "": print("Please specify either --eject or iso image", file=sys.stderr) return 1 - if options.file is None: - answer = send_command(options.sock, "eject " + options.id) else: answer = send_command( options.sock, "change %s %s" % (options.id, os.path.abspath(options.file)) ) @@ -427,16 +409,16 @@ """Search for pattern or address given in options in the given list of devices. List should be produced by get_host_devices() or get_vm_devices() """ - if hasattr("pattern", options): + if hasattr(options, "pattern"): for dev in devices: if re.search(options.pattern, dev[1]): options.address = dev[0] break - elif not hasattr("address", options): + elif not hasattr(options, "address"): print( "Address or search pattern for device " + "is not specified", file=sys.stderr, ) options.sock.close() @@ -571,12 +553,11 @@ count = 0 maxlen = 0 vms = [] for vmname, vmtype, dirname in all_vms(options.pattern): count += 1 - if maxlen < len(vmname): - maxlen = len(vmname) + maxlen = max(maxlen,len(vmname)) if options.state: vms.append(make_vm_listing(vmname, dirname, vmtype)) else: vms.append({"name": vmname}) if options.state: @@ -647,11 +628,11 @@ if os.path.exists(newnames[i]): print("Snapshot %s already exists", options.snapname, file=sys.stderr) return 1 for i in drives: os.rename(i, newnames[i]) - os.system('qemu-img create -f qcow2 -b "%s" "%s"' % (newnames[i], i)) + os.system('qemu-img create -f qcow2 -b "%s" -F qcow2 "%s"' % (newnames[i], i)) os.chmod(i, 0o664) return 0 def cmd_snapshots(options): @@ -706,11 +687,11 @@ print("Drive %s has no snapshots" % drive, file=sys.stderr) continue # Unlink current image os.unlink(drive) # create new image with same backing file - os.system('qemu-img create -f qcow2 -b "%s" "%s"' % (backing, drive)) + os.system('qemu-img create -f qcow2 -b "%s" -F qcow2 "%s"' % (backing, drive)) os.chmod(drive, 0o664) def cmd_commit(options): """ @@ -830,18 +811,20 @@ TEMPLATE = """#!/bin/sh # Get machine name from current directory name NAME=$(basename $(pwd)) -# if remote access is enabled, then there should be -# SPICE_PASSWORD=password +# to enable remote access, create in the vm directory file named +# password with cleartext password QEMU_AUDIO_DRV=spice export QEMU_AUDIO_DRV -if [ -n "$SPICE_PASSWORD" ]; then - SPICE_AUTH="password=$SPICE_PASSWORD" +if [ -f "password" ]; then + PASSWORD_SECRET="-object secret id=password,forma=raw,file=password " + SPICE_AUTH="password-secret=password" else - SPICE_AUTH="disable-ticketing,addr=127.0.0.1" + PASSWORD_SECRET="" + SPICE_AUTH="disable-ticketing=on,addr=127.0.0.1" fi SPICE_PORT=$(find_free_port 5900) if [ "$1" = '-cdrom' ]; then shift CDROM=",file=$1" @@ -857,11 +840,11 @@ {usb} \\ {sound} \\ -chardev socket,server=on,wait=off,path=monitor,id=monitor \\ -mon chardev=monitor,mode=readline \\ -vga {vga} \\ --spice port=$SPICE_PORT,$SPICE_AUTH \\ +${{PASSWORD_SECRET}} -spice port=$SPICE_PORT,$SPICE_AUTH \\ -device virtio-serial -chardev spicevmc,id=vdagent,name=vdagent \\ -device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \\ -device ich9-usb-ehci1,id=usb \\ -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on \\ -chardev spicevmc,name=usbredir,id=usbredirchardev1 \\ @@ -888,11 +871,11 @@ "accel": "-enable-kvm", "memory": "1024M", "vga": "qxl", "drive": "-drive media=disk,index=0,if={interface},file={image}", "cdrom": "-drive media=cdrom,index=2,if=ide", - "sound": "-audio spice,id=au0,model=hda", + "sound": "-audio driver=spice,id=au0,model=hda", "group": config.get("permissions", "vm_group"), "usb": "-usb", "rtc": "", "extraargs": '${1:+"$@"}', } @@ -933,11 +916,11 @@ options["usb"] = "" if not parsed_args.sound: options["sound"] = "" else: - options["sound"] = "-soundhw " + parsed_args.sound + options["sound"] = "-audio driver=spice,model=" + parsed_args.sound options["memory"] = parsed_args.mem if parsed_args.localtime: options["rtc"] = "-rtc base=localtime,clock=host \\\n" @@ -976,11 +959,10 @@ print("Creating new image file of %s" % parsed_args.size, file=sys.stderr) os.chdir(machinedir) os.system("qemu-img create -f qcow2 %s %s" % (drivename, parsed_args.size)) os.chmod(drivename, 0o664) options["drive"] = options["drive"].format(**driveopts) - if hasattr(parsed_args, "debug") and parsed_args.debug: print(repr(driveopts), repr(options["drive"])) print(repr(options)) with open("start", "w", encoding="utf-8") as script: script.write(TEMPLATE.format(**options)) @@ -1037,11 +1019,11 @@ "create options": { "net": "user", "size": "20G", "mem": "1G", "diskif": "virtio", - "sound": "hda", + "sound": "virtio", "arch": arch, "vga": "qxl", }, "tools": { "viewer": "remote-viewer %s", @@ -1208,11 +1190,12 @@ "file", nargs="?", default="", help="ISO image or special file to connect to drive", ) - p.add_argument("--eject", dest="file", action="store_const", const=None) + p.add_argument("--eject", dest="eject", action="store_const", + const=True, default=False) usb = cmds.add_parser("usb", help="manage USB devices").add_subparsers( dest="subcommand", help="manage USB devices" ) p = new_command(usb, "insert", help="attach device to the virtual machine") p.add_argument("pattern", help="Pattern of device name to look up in lsusb")