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])
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
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"], ) )
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)