Check-in [6c894d8ca6]
Not logged in
Overview
Comment:Set permissions on VM files. Fixes [067fea7873]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6c894d8ca638bf0e681fce593ba03dbf822aa62c
User & Date: vitus on 2016-04-14 14:35:09
Other Links: manifest | tags
Context
2016-04-14
19:56
Added display of privare/public status and spice url to vws list command. Fixes 96cc307ed7 check-in: d72aaf8da4 user: vitus tags: trunk
14:35
Set permissions on VM files. Fixes [067fea7873] check-in: 6c894d8ca6 user: vitus tags: trunk
2016-04-07
13:53
Written autostart command check-in: 1d444062a8 user: vitus tags: trunk
Changes

Modified vws from [b585fb76c1] to [ab478f8f41].

380
381
382
383
384
385
386

387
388
389
390
391
392
393
        if os.path.exists(newnames[i]):
            print >>sys.stderr, "Snapshot %s already exists", options.snapname
            return 1
    for i in drives:
        os.rename(i, newnames[i])
        os.system("qemu-img create -f qcow2 -b \"%s\" \"%s\"" %
                  (newnames[i], i))

    return 0

def cmd_snapshots(options):
    """ vws snapshots - list existing snapshots """
    os.chdir(options.dir)
    drives = get_drives(options.dir)
    lst = []







>







380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
        if os.path.exists(newnames[i]):
            print >>sys.stderr, "Snapshot %s already exists", options.snapname
            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.chmod(i,0664)
    return 0

def cmd_snapshots(options):
    """ vws snapshots - list existing snapshots """
    os.chdir(options.dir)
    drives = get_drives(options.dir)
    lst = []
433
434
435
436
437
438
439

440
441
442
443
444
445
446
        if not backing:
            print >>sys.stderr, "Drive %s has no snapshots" % drive
            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))


def cmd_commit(options):
    """
    Commits last snapshot changes into it's backing file
    There would be one snapshot less for virtual machine
    """
    if options.stopped:







>







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
        if not backing:
            print >>sys.stderr, "Drive %s has no snapshots" % drive
            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.chmod(drive,0664)

def cmd_commit(options):
    """
    Commits last snapshot changes into it's backing file
    There would be one snapshot less for virtual machine
    """
    if options.stopped:
517
518
519
520
521
522
523
524

525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
fi
SPICE_PORT=$(find_free_port 5900)
if [ "$1" = '-cdrom' ]; then
	shift
	CDROM=",file=$1"
	shift
fi


{qemubinary} -name $NAME {accel} \\
-m {memory} \\
{drive} \\
{cdrom}$CDROM \\
{net} \\
{usb} \\
{sound} \\
-chardev socket,server,nowait,path=monitor,id=monitor \\
-mon chardev=monitor,mode=readline \\
-vga {vga} \\
-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 \\
-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \\
-daemonize -pidfile pid

"""

def cmd_create(parsed_args):
    """ vws create - create new VM """
    BADSIZE = "Invalid size of %s specifed %s. Should have K, M or G suffix"
    global TEMPLATE
    if not parsed_args.image and not validate_size(parsed_args.size):







|
>


















>







519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
fi
SPICE_PORT=$(find_free_port 5900)
if [ "$1" = '-cdrom' ]; then
	shift
	CDROM=",file=$1"
	shift
fi
#set umask to make machine group-accessable
umask 002
{qemubinary} -name $NAME {accel} \\
-m {memory} \\
{drive} \\
{cdrom}$CDROM \\
{net} \\
{usb} \\
{sound} \\
-chardev socket,server,nowait,path=monitor,id=monitor \\
-mon chardev=monitor,mode=readline \\
-vga {vga} \\
-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 \\
-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \\
-daemonize -pidfile pid
chmod 0660 monitor pid
"""

def cmd_create(parsed_args):
    """ vws create - create new VM """
    BADSIZE = "Invalid size of %s specifed %s. Should have K, M or G suffix"
    global TEMPLATE
    if not parsed_args.image and not validate_size(parsed_args.size):
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
               "cdrom":"-drive media=cdrom,index=2,if=ide",
               "sound":"-soundhw hda",
               "usb":"-usb"}
    macaddr = ":".join(["%02x" % ord(x) for x in  chr(0x52) + os.urandom(5)])
    if parsed_args.shared:
        machinedir = os.path.join(config.get("directories", "SharedVMs"),
                                  parsed_args.machine)
        dirmode = 0755
    else:
        machinedir = os.path.join(os.environ["HOME"], "VWs",
                                  parsed_args.machine)
        dirmode = 0775

    if parsed_args.net != 'user':
        bridges = list_bridges()







|







565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
               "cdrom":"-drive media=cdrom,index=2,if=ide",
               "sound":"-soundhw hda",
               "usb":"-usb"}
    macaddr = ":".join(["%02x" % ord(x) for x in  chr(0x52) + os.urandom(5)])
    if parsed_args.shared:
        machinedir = os.path.join(config.get("directories", "SharedVMs"),
                                  parsed_args.machine)
        dirmode = 0775
    else:
        machinedir = os.path.join(os.environ["HOME"], "VWs",
                                  parsed_args.machine)
        dirmode = 0775

    if parsed_args.net != 'user':
        bridges = list_bridges()
607
608
609
610
611
612
613







614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
                                  parsed_args.machine)
        else:
            print >> sys.stderr, ("Cannot create VW directory, " +
                                  "something on the way")
        sys.exit(1)
    #  Creating directory for VM
    os.makedirs(machinedir, dirmode)







    driveopts = {"interface":parsed_args.diskif, "image":drivename}
    if parsed_args.install:
        install_image = os.path.abspath(parsed_args.install)

    if parsed_args.image:
        # Copying image file
        print >>sys.stderr, ("Copying %s to %s" %
                             (parsed_args.image,
                              os.path.join(machinedir, drivename)))
        os.system("qemu-img convert -O qcow2 -p %s %s" %
                  (parsed_args.image,
                   os.path.join(machinedir, drivename)))
        os.chdir(machinedir)
    else:
        print >>sys.stderr, "Creating new image file of %s" % parsed_args.size
        os.chdir(machinedir)
        os.system("qemu-img create -f qcow2 %s %s" %
                  (drivename, parsed_args.size))

    # pylint: disable=star-args
    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") as script:
        script.write(TEMPLATE.format(**options))







>
>
>
>
>
>
>


















|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
                                  parsed_args.machine)
        else:
            print >> sys.stderr, ("Cannot create VW directory, " +
                                  "something on the way")
        sys.exit(1)
    #  Creating directory for VM
    os.makedirs(machinedir, dirmode)
    if parsed_args.shared:
        import grp
        gid=grp.getgrnam(config.get("permissions","vm_group")).gr_gid
        uid=os.getuid() 
        os.chown(machinedir,uid,gid)
        if config.getboolean("permissions","setgid_vm"):  
            os.chmod(machinedir,02775)
    driveopts = {"interface":parsed_args.diskif, "image":drivename}
    if parsed_args.install:
        install_image = os.path.abspath(parsed_args.install)

    if parsed_args.image:
        # Copying image file
        print >>sys.stderr, ("Copying %s to %s" %
                             (parsed_args.image,
                              os.path.join(machinedir, drivename)))
        os.system("qemu-img convert -O qcow2 -p %s %s" %
                  (parsed_args.image,
                   os.path.join(machinedir, drivename)))
        os.chdir(machinedir)
    else:
        print >>sys.stderr, "Creating new image file of %s" % parsed_args.size
        os.chdir(machinedir)
        os.system("qemu-img create -f qcow2 %s %s" %
                  (drivename, parsed_args.size))
    os.chmod(drivename,0664)
    # pylint: disable=star-args
    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") as script:
        script.write(TEMPLATE.format(**options))
678
679
680
681
682
683
684




685
686
687
688
689
690
691
                      ('diskif', 'virtio'), ('sound', 'hda'), ('arch', arch),
                      ('vga', 'qxl')]:
    config.set('create options', option, value)
config.add_section('tools')
config.set('tools', 'viewer', 'remote-viewer %s')
config.set('tools', 'bridge_list', '/sbin/brctl show')
config.set('tools', 'lsusb', 'lsusb')




# Read configration files
config.read(['/etc/vws.conf', os.environ['HOME'] + '/.vwsrc'])
# Parse argument
args = ArgumentParser(description="Manage Virtual Workstations")
cmds = args.add_subparsers(dest='command', help="sub-command help")
p = cmds.add_parser("list", help="List existing VWs",
                    description="List existing VWs")







>
>
>
>







689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
                      ('diskif', 'virtio'), ('sound', 'hda'), ('arch', arch),
                      ('vga', 'qxl')]:
    config.set('create options', option, value)
config.add_section('tools')
config.set('tools', 'viewer', 'remote-viewer %s')
config.set('tools', 'bridge_list', '/sbin/brctl show')
config.set('tools', 'lsusb', 'lsusb')
config.add_section('permissions')
config.set('permissions','vm_group','kvm')
config.set('permissions','autostart_user','root')
config.set('permissions','setgid_vm','yes')
# Read configration files
config.read(['/etc/vws.conf', os.environ['HOME'] + '/.vwsrc'])
# Parse argument
args = ArgumentParser(description="Manage Virtual Workstations")
cmds = args.add_subparsers(dest='command', help="sub-command help")
p = cmds.add_parser("list", help="List existing VWs",
                    description="List existing VWs")
788
789
790
791
792
793
794

795
796
797
798
799
800
801
               help='ISO image to install OS from', default=None)
# Miscellenia
p = new_command(cmds, 'monitor', help='connect stdin/stdout to monitor of VM')
p = new_command(cmds, 'spiceuri', help='Output spice URI of machine')

parsed_args = args.parse_args(sys.argv[1:])


# Create command is totally different, so it is handled separately
if parsed_args.command == 'create':
    cmd_create(parsed_args)
    sys.exit(0)

funcname = "cmd_" + parsed_args.command
if hasattr(parsed_args, "subcommand"):







>







803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
               help='ISO image to install OS from', default=None)
# Miscellenia
p = new_command(cmds, 'monitor', help='connect stdin/stdout to monitor of VM')
p = new_command(cmds, 'spiceuri', help='Output spice URI of machine')

parsed_args = args.parse_args(sys.argv[1:])

os.umask(002)
# Create command is totally different, so it is handled separately
if parsed_args.command == 'create':
    cmd_create(parsed_args)
    sys.exit(0)

funcname = "cmd_" + parsed_args.command
if hasattr(parsed_args, "subcommand"):
814
815
816
817
818
819
820

821
822
823
824
825
826
827
    if parsed_args.sock is None:
        if not parsed_args.command in stopped_vm_commands:
            print >>sys.stderr, ("Virtual machine %s is not running." %
                                 parsed_args.machine)
            sys.exit(1)
        else:
            parsed_args.stopped = True

try:
    func(parsed_args)
finally:
    if hasattr(parsed_args, 'sock') and parsed_args.sock is not None:
        parsed_args.sock.shutdown(socket.SHUT_RDWR)
        parsed_args.sock.close()








>







830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
    if parsed_args.sock is None:
        if not parsed_args.command in stopped_vm_commands:
            print >>sys.stderr, ("Virtual machine %s is not running." %
                                 parsed_args.machine)
            sys.exit(1)
        else:
            parsed_args.stopped = True

try:
    func(parsed_args)
finally:
    if hasattr(parsed_args, 'sock') and parsed_args.sock is not None:
        parsed_args.sock.shutdown(socket.SHUT_RDWR)
        parsed_args.sock.close()

Modified vws.conf from [696381eb23] to [9d477542e2].

1
2
3
4
5
6
7













8
9
10
11
12
13
14
15
16
[directories]
SharedVMs=/home/virtual/vws/shared
AutostartVMs=/home/virtual/vws/autostart
[tools]
viewer=remote-viewer %s
bridge_list=/sbin/brigectl show
lsusbh=lsusb













[create options]
net=user
size=20G
mem=1G
# vws would compute default arch for at least i385, x86_64 and arm
# arch=i386
sound=hda
vga=qxl
diskif=virtio






|
>
>
>
>
>
>
>
>
>
>
>
>
>




|




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[directories]
SharedVMs=/home/virtual/vws/shared
AutostartVMs=/home/virtual/vws/autostart
[tools]
viewer=remote-viewer %s
bridge_list=/sbin/brigectl show
lsusb=lsusb
[permissions]
# User name of user which owns processes of autostart VM
# Should be member of group which is able to access KVM device.
autostart_user = kvm
# Group all shared VM belongs to. Probably should be same group which
# owns kvm device. Note that shutdown command knows how to stop private vms of
# members of these groups
vm_group = kvm
# True (yes, on) if directories of new shared VMs should be created setgid.
# This normally would make snapshots and other auxillary files owned by
# shared_vm_group and accessable for all users. Set to false if your
# file system has another sematics of setgid bit on directories.
setgid_vm = yes
[create options]
net=user
size=20G
mem=1G
# vws would compute default arch for at least i386, x86_64 and arm
# arch=i386
sound=hda
vga=qxl
diskif=virtio