Esempio n. 1
0
def install(rootdir, archive, vmname,size,ram,vcpus=1,root_password=None,verbose=False,copy_pubkey=False):
    if archive[1] == "tar":
        with process_for_output(["tar",get_tar_decompression_option(archive[0]) + ("xvpf" if verbose else "xpf"),"-","--xattrs","--xattrs-include=*","-C",rootdir]) as tar:
            copy_archive(archive[0], tar)
        setup_vm_info(rootdir, vmname, ram, vcpus, root_password, copy_pubkey)
    elif archive[1] == "squashfs":
        ro_layer = "system"
        rw_layer = "rw"
        ro_file = os.path.join(rootdir, ro_layer)
        rw_dir = os.path.join(rootdir, rw_layer)
        work_dir = os.path.join(rootdir, "work")
        os.makedirs(rw_dir)
        os.makedirs(work_dir)
        with open(ro_file, "w") as f:
            copy_archive(archive[0], f)
        os.makedirs(os.path.join(rootdir, "boot/grub"))
        with open(os.path.join(rootdir, "boot/grub/grub.cfg"),"w") as f:
            f.write("set WALBRIX_RO_LAYER=/%s\n" % ro_layer)
            f.write("set WALBRIX_RW_LAYER=/%s\n" % rw_layer)
            f.write("loopback loop ${WALBRIX_RO_LAYER}\n")
            f.write("set root=loop\n")
            f.write("normal /boot/grub/grub.cfg")

        with util.tempmount(ro_file, "loop,ro", "squashfs") as tmpdir1:
            with util.tempmount("overlay", "lowerdir=%s,upperdir=%s,workdir=%s" % (tmpdir1, rw_dir, work_dir), "overlay") as tmpdir2:
                setup_vm_info(tmpdir2, vmname, ram, vcpus, root_password, copy_pubkey)
    else:
        raise Exception("Unknown archive type:%s" % archive[1])
Esempio n. 2
0
def mount_vm(name, readonly=False, options=None):
    mount_options = []
    if readonly:
        mount_options.append("ro")
    if options is not None:
        mount_options.append(options)
    device, name = get_device_and_vmname(name)
    make_sure_device_is_not_being_used(device)
    with util.tempmount(device, ",".join(mount_options)) as tempdir:
        overlay_params = get_overlay_params(tempdir)
        if overlay_params is not None:
            ro_layer, rw_layer = overlay_params
            work_dir = os.path.join(tempdir, "work")
            if not readonly:
                if os.path.exists(work_dir):
                    shutil.rmtree(work_dir)
                os.makedirs(work_dir)
            with util.tempmount(os.path.join(tempdir, ro_layer.strip("/")), "loop,ro", "squashfs") as ro_dir:
                rw_dir = os.path.join(tempdir, rw_layer.strip("/"))
                overlay_options = (
                    ["lowerdir=%s:%s" % (rw_dir, ro_dir)]
                    if readonly
                    else ["lowerdir=%s,upperdir=%s,workdir=%s" % (ro_dir, rw_dir, work_dir)]
                )
                if readonly:
                    overlay_options.append("ro")
                with util.tempmount("overlay", ",".join(overlay_options), "overlay") as overlay_root:
                    yield overlay_root
        else:
            yield tempdir
Esempio n. 3
0
def is_vm(device):
    with util.tempmount(device, "ro") as tempdir:
        return any(
            map(
                lambda x: os.path.isfile(os.path.join(tempdir, x)),
                ["boot/grub/menu.lst", "boot/grub/grub.cfg", "sbin/init"],
            )
        )
Esempio n. 4
0
def run(url, vg, name,size,btrfs,ram,vcpus=1,root_password=None,verbose=False,copy_pubkey=False):
    archive = None

    if is_tarball(url): archive = (url, "tar")
    elif is_squashfs(url): archive = (url, "squashfs")
    else:
        vainfo, origin = load_json(url)
        id = vainfo.get("id")
        name = name or id
        if name is None: raise Exception("'id' field not found from VA info")
        minimum_ram = vainfo.get("minimum_ram")
        minimum_hd = vainfo.get("minimum_hd")
        ram = ram or minimum_ram
        if ram is None: raise Exception("'minimum_ram' field not found from VA info")
        size = size or minimum_hd
        if size is None: raise Exception("'minimum_hd' field not found from VA info")
        if "squashfs" in vainfo: # detect squashfs first
            archive = (resolve_relative_path(origin, vainfo["squashfs"]), "squashfs")
        elif "tarball" in vainfo:
            archive = (resolve_relative_path(origin, vainfo["tarball"]), "tar")

    if archive is None: raise Exception("Archive file couldn't be determined")

    if name is None:
        basename = os.path.basename(archive[0])
        if '-' not in basename: raise Exception("Could not determine VA name from tar filename '%s'" % basename)
        name = basename.split('-')[0]

    vmname = get_available_vm_name(name)
    if verbose: print "VM name: %s, Source archive: %s" % (vmname, archive[0])
    if archive[0].startswith("http://") or archive[0].startswith("https://"):
        pass # TODO: check if resource exists
    else:
        if not os.path.isfile(archive[0]): raise Exception("Archive file '%s' does not exist" % archive[0])

    vg = vg or select_vg(size)
    if vg == None:
        print "Cancelled."
        return

    subprocess.check_call(["lvcreate","--yes","--addtag=@wbvm","-n",vmname,"-L","%dG" % size,vg], close_fds=True)
    device = "/dev/%s/%s" % (vg, vmname)
    print "Logical volume %s created." % device
    success = False
    try:
        if btrfs:
            subprocess.check_call(["mkfs.btrfs",device])
        else:
            metadata_opts = ["-m","crc=0"] if "-i686" in archive[0] and archive[1] == "tar" else [] # because grub1 cannot recognize crc
            subprocess.check_call(["mkfs.xfs","-f"] + metadata_opts + [device])
        with util.tempmount(device, None if btrfs else "inode32", "btrfs" if btrfs else "xfs") as tmpdir:
            install(tmpdir, archive, vmname, size, ram, vcpus, root_password,verbose,copy_pubkey)
        success = True
    finally:
        if not success:
            for i in range(5):
                if subprocess.call(["lvremove", "-f", device],close_fds=True) == 0: break
                time.sleep(1)