Check-in [df1b3337bc]
Not logged in
Overview
Comment:Fix byte/string issues in send_command
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: df1b3337bc7cbac2e13f451df17bccea547a52a5
User & Date: vitus on 2019-09-21 17:02:27
Other Links: manifest | tags
Context
2019-10-01
19:29
Made debian package ver 0.8. Removed lintian warining. Converted find_free_port to python3 check-in: 5bd9419845 user: vitus tags: trunk
2019-09-21
17:02
Fix byte/string issues in send_command check-in: df1b3337bc user: vitus tags: trunk
2019-09-20
21:40
Converted to python3 check-in: 0141f28d64 user: vitus tags: trunk
Changes

Modified vws from [d2f776edc6] to [6a51b18933].

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
        # There can be stray (qemu) prompt in the socket. Try to drain
        # it
        try:
            sock.recv(64, socket.MSG_DONTWAIT)
        except socket.error as ex:
            if ex.errno != errno.EAGAIN and ex.errno != errno.EWOULDBLOCK:
                raise ex
        sock.send(command + "\n")
        answer = ""
        while not answer.endswith("(qemu) "):
            chunk = sock.recv(1024)
            if chunk == '':
                raise IOError("Unexpected EOF from monitor")
            answer += chunk
    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")







|



|

|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
        # There can be stray (qemu) prompt in the socket. Try to drain
        # it
        try:
            sock.recv(64, socket.MSG_DONTWAIT)
        except socket.error as ex:
            if ex.errno != errno.EAGAIN and ex.errno != errno.EWOULDBLOCK:
                raise ex
        sock.send((command + "\n").encode("utf-8"))
        answer = ""
        while not answer.endswith("(qemu) "):
            chunk = sock.recv(1024)
            if chunk == b'':
                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")
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    return lst

def parse_arp(iface):
    """
    Returns map which maps mac addresses to IPs for specified interface"
    """
    addr_map = {}
    pipe = os.popen("%s -n -u %s" % (config.get("tools", "arp"), iface), "r")
    for line in pipe:
        data = line.split()
        mac = data[2]
        if mac == "HWAddress":
            continue
        if mac == iface:
            # Foind line with (incomplete) entry







|







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    return lst

def parse_arp(iface):
    """
    Returns map which maps mac addresses to IPs for specified interface"
    """
    addr_map = {}
    pipe = os.popen("%s -n -i %s" % (config.get("tools", "arp"), iface), "r")
    for line in pipe:
        data = line.split()
        mac = data[2]
        if mac == "HWAddress":
            continue
        if mac == iface:
            # Foind line with (incomplete) entry
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    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") as f:
        for line in f:
            match = re.search("-net nic,macaddr=(\\S+) -net ([^, ]+)", line)
            if match:
                f = {"mac":match.group(1)}
                if match.group(2) == "user":
                    f["iface"] = "user"
                elif match.group(2) == "bridge":
                    f["iface"] = re.search("br=(\\S+)", line).group(1)
                else:







|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
    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") as f:
        for line in f:
            match = re.search("-net nic,(?:\S*,)?macaddr=(\\S+) -net ([^, ]+)", line)
            if match:
                f = {"mac":match.group(1)}
                if match.group(2) == "user":
                    f["iface"] = "user"
                elif match.group(2) == "bridge":
                    f["iface"] = re.search("br=(\\S+)", line).group(1)
                else:
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479
480






481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
            f["uri"] = uri[uri.rindex(":")+1:]
            f.update(get_netinfo(sock))
            sock.shutdown(socket.SHUT_RDWR)
            sock.close()
            f["state"] = "running"
    return f

def matches(name, patterns):
    """ checks if name matches one of patterns """
    import fnmatch
    for pattern in patterns:
        if fnmatch.fnmatch(name, pattern):
            return True
    return False

def add_ip_address(listing):
    """ Adds IP addresses from ARP into VM listing """
    bridges = set()
    for vminfo in listing:
        if "ip" not in vminfo:
            bridges.add(vminfo["iface"])
    arp_data = {}
    for bridge in bridges:
        arp_data.update(parse_arp(bridge))
    for vminfo in listing:
        if "mac" in vminfo and not "ip" in vminfo:
            if vminfo["mac"] in arp_data:
                vminfo["ip"] = arp_data[vminfo["mac"]]
            else:
                vminfo["ip"] = "-"
def all_vms():
    """
    Returns list of tuples  vmname, vmtype, directory
    for all vms
    """

    search_path = [("private", os.path.join(pwd.getpwuid(os.getuid()).pw_dir,
                                            "VWs")),
                   ("shared", config.get("directories", "SharedVMs")),
                   ("autostart", config.get("directories", "AutostartVMs"))]
    vmlist = []
    for (vmtype, dirname) in search_path:
        if not os.access(dirname, os.X_OK):
            continue
        for vmname in os.listdir(dirname):
            if not os.access(os.path.join(dirname, vmname, "start"), os.X_OK):
                continue






            vmlist.append((vmname, vmtype, os.path.join(dirname, vmname)))
    return vmlist
def cmd_list(options):
    """ vws list """
    count = 0
    maxlen = 0
    vms = []
    for vmname, vmtype, dirname in all_vms():
        if not matches(vmname, options.pattern):
            continue
        count += 1
        if maxlen < len(vmname):
            maxlen = len(vmname)
        if options.state:
            vms.append(make_vm_listing(vmname, dirname, vmtype))
        else:
            vms.append({"name":vmname})







<
<
<
<
<
<
<
















|




>











>
>
>
>
>
>
|






|
<
<







435
436
437
438
439
440
441







442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488


489
490
491
492
493
494
495
            f["uri"] = uri[uri.rindex(":")+1:]
            f.update(get_netinfo(sock))
            sock.shutdown(socket.SHUT_RDWR)
            sock.close()
            f["state"] = "running"
    return f









def add_ip_address(listing):
    """ Adds IP addresses from ARP into VM listing """
    bridges = set()
    for vminfo in listing:
        if "ip" not in vminfo:
            bridges.add(vminfo["iface"])
    arp_data = {}
    for bridge in bridges:
        arp_data.update(parse_arp(bridge))
    for vminfo in listing:
        if "mac" in vminfo and not "ip" in vminfo:
            if vminfo["mac"] in arp_data:
                vminfo["ip"] = arp_data[vminfo["mac"]]
            else:
                vminfo["ip"] = "-"
def all_vms(patterns=["*"]):
    """
    Returns list of tuples  vmname, vmtype, directory
    for all vms
    """
    import fnmatch
    search_path = [("private", os.path.join(pwd.getpwuid(os.getuid()).pw_dir,
                                            "VWs")),
                   ("shared", config.get("directories", "SharedVMs")),
                   ("autostart", config.get("directories", "AutostartVMs"))]
    vmlist = []
    for (vmtype, dirname) in search_path:
        if not os.access(dirname, os.X_OK):
            continue
        for vmname in os.listdir(dirname):
            if not os.access(os.path.join(dirname, vmname, "start"), os.X_OK):
                continue
            matches = False
            for pattern in patterns:
                if fnmatch.fnmatch(vmname, pattern):
                    matches = True
                    break
            if matches:
                vmlist.append((vmname, vmtype, os.path.join(dirname, vmname)))
    return vmlist
def cmd_list(options):
    """ vws list """
    count = 0
    maxlen = 0
    vms = []
    for vmname, vmtype, dirname in all_vms(options.pattern):


        count += 1
        if maxlen < len(vmname):
            maxlen = len(vmname)
        if options.state:
            vms.append(make_vm_listing(vmname, dirname, vmtype))
        else:
            vms.append({"name":vmname})
558
559
560
561
562
563
564



565
566
567
568
569
570
571
572
573
574
575
576
577

578
579
580
581
582
583
584
585
        os.system("qemu-img create -f qcow2 -b \"%s\" \"%s\"" %
                  (newnames[i], i))
        os.chmod(i, 0o664)
    return 0

def cmd_snapshots(options):
    """ vws snapshots - list existing snapshots """



    os.chdir(options.dir)
    drives = get_drives(options.dir)
    lst = []
    info = {}
    with os.popen("qemu-img info --backing-chain " + drives[0], "r") as f:
        for line in f:
            if line.find(": ") != -1:
                var, val = line.strip().split(": ")
                if val != "":
                    info[var] = val
            elif line[0] == '\n':
                lst.append(info)
                info = {}

        lst.append(info)
    for snap in lst:
        print("%-30s  %+8s  %+8s" % (snap["image"], snap["virtual size"],
                                     snap["disk size"]))


def get_backing(drive):
    """ find if partucular virtual drive has backing file and returns







>
>
>













>
|







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
        os.system("qemu-img create -f qcow2 -b \"%s\" \"%s\"" %
                  (newnames[i], i))
        os.chmod(i, 0o664)
    return 0

def cmd_snapshots(options):
    """ vws snapshots - list existing snapshots """
    if not options.stopped:
        print("Cannot list snapshots of running VW", file=sys.stderr)
        sys.exit(1)
    os.chdir(options.dir)
    drives = get_drives(options.dir)
    lst = []
    info = {}
    with os.popen("qemu-img info --backing-chain " + drives[0], "r") as f:
        for line in f:
            if line.find(": ") != -1:
                var, val = line.strip().split(": ")
                if val != "":
                    info[var] = val
            elif line[0] == '\n':
                lst.append(info)
                info = {}
        if info:
            lst.append(info)
    for snap in lst:
        print("%-30s  %+8s  %+8s" % (snap["image"], snap["virtual size"],
                                     snap["disk size"]))


def get_backing(drive):
    """ find if partucular virtual drive has backing file and returns