Beispiel #1
0
class Tiny_Core_Linux:

    def __init__(self):
        self.url_core_iso  = 'https://distro.ibiblio.org/tinycorelinux/11.x/x86/release/Core-current.iso'
        self.path_core_iso = '/tmp/core-currenet.iso'
        self.vm_name       = 'tiny-core-linux'
        self.sdk           = Sdk()

    def create_vm(self):
        self.sdk.content()
        print('-----')
        vm = self.sdk.vm(self.vm_name)
        print('-----')
        #if vm is None:
        #    print('need to create vm')
        #print(f"VM: {vm}")
        pass

    def download_iso(self):
        if file_not_exists(self.path_core_iso):
            Http.GET_bytes_to_file(self.url_core_iso, self.path_core_iso)
        return self.path_core_iso
Beispiel #2
0
class VM_Process:
    def __init__(self, vm):
        self.sdk = Sdk()
        self.vm = vm
        self.vm_account = Config().vm_account()
        self.server_details = Config().vsphere_server_details()
        self.vm_user_name = self.vm_account['username']
        self.vm_password = self.vm_account['password']
        self.ip_server = self.server_details['host']

    def exec(self, program_path, arguments=""):
        return self.start_process_return_stdout(program_path, arguments)

    def set_vm_account(self, username, password):
        self.vm_user_name = username
        self.vm_password = password

    def set_vm_account_from_env(self, env_prefix):
        self.vm_account['username'] = environ.get(f'{env_prefix}_USERNAME')
        self.vm_account['password'] = environ.get(f'{env_prefix}_PASSWORD')
        return self

    def start_process_return_stdout(self, program_path, arguments=""):
        content = self.sdk.content()
        # assert self.vm.guest().toolsStatus == 'toolsOk'

        file_stdout = f"/tmp/_vm_exec_{random_string()}"
        arguments += f" > {file_stdout}"  # capture stdout in a file
        creds = pyVmomi.vim.vm.guest.NamePasswordAuthentication(
            username=self.vm_user_name, password=self.vm_password)
        pm = content.guestOperationsManager.processManager
        ps = pyVmomi.vim.vm.guest.ProcessManager.ProgramSpec(
            programPath=program_path, arguments=arguments)
        res = pm.StartProgramInGuest(self.vm.vm, creds, ps)
        file_transfer = content.guestOperationsManager.fileManager.InitiateFileTransferFromGuest(
            self.vm.vm, creds, file_stdout)
        file_url = file_transfer.url.replace("*:443", self.ip_server)
        resp = requests.get(file_url, verify=False)
        return resp.text

    # helper commands

    def curl(self, target='-h'):
        return self.exec('/usr/bin/curl', target)

    def ls(self, path=""):
        return self.exec('/bin/ls', path)
Beispiel #3
0
class Datastore:

    def __init__(self, name="datastore1", datacenter='ha-datacenter'):
        self.name       = name
        self.datacenter = datacenter
        self.sdk  = Sdk()

    def datastore(self):
        return self.sdk.get_object(pyVmomi.vim.Datastore, self.name)

    def delete(self, target):
        item_path = f'[{self.name}]/{target}'.replace('//','/')
        return self.delete_path(item_path)

    def delete_path(self, item_path):
        content = self.sdk.content()
        datacenter = self.sdk.datacenter()
        try:
            task = content.fileManager.DeleteDatastoreFile_Task(item_path, datacenter)
            Task().wait_for_task(task)
            if task.info.state == "success":
                return True
        except Exception as error:
            print(f"[Error][delete] {error.msg}")  # todo: add global error handler and use it here
        return False

    def info(self):
        info = self.datastore().info
        vmfs = info.vmfs
        data = {
                    "Capacity": self.sizeof_fmt(vmfs.capacity)   ,
                    "Name"    : info.name       ,
                    "Type"    : vmfs.type       ,
                    "SSD"     : vmfs.ssd        ,
                    "UUID"    : vmfs.uuid       ,
               }
        return data

    def add_query_details_to_search_spec(self,search_spec):
        query_details       = pyVmomi.vim.host.DatastoreBrowser.FileInfo.Details(fileOwner    = True,
                                                                                 fileSize     = True,
                                                                                 fileType     = True,
                                                                                 modification = True)
        search_spec.details = query_details
        return self

    def execute_search_task(self, search_function, search_spec):
        self.add_query_details_to_search_spec(search_spec)
        task  = search_function("[%s]" % self.name, search_spec)
        Task().wait_for_task(task)
        return task.info.result

    def get_search_data__for_files(self, search_results):
        data = []
        for item in  search_results:
            #print(item)
            for file in item.file:
                data.append({
                                "Folder_path": item.folderPath               ,
                                "Modified"   : str(file.modification)        ,
                                "Owner"      : file.owner                    ,
                                "FileName"   : file.path                     ,
                                "Size"       : self.sizeof_fmt(file.fileSize),
                                "Type"       : type(file).__name__.replace('vim.host.DatastoreBrowser.','')
                             })
        return data

    def get_search_data__for_folders(self, search_results):
        data = []
        for item in  search_results:
            data.append({
                            "Modified"  : str(item.modification)        ,
                            "Owner"     : item.owner                    ,
                            "FolderName": item.path                     ,
                            "Size"      : self.sizeof_fmt(item.fileSize)
                         })
        return data

    def file_delete(self, folder_name, file_name):
        file_path = f"{folder_name}/{file_name}"
        return self.delete(file_path)

    @index_by
    @group_by
    def files(self, match_pattern="*"):
        search_function          = self.datastore().browser.SearchDatastoreSubFolders_Task
        search_spec              = pyVmomi.vim.HostDatastoreBrowserSearchSpec()
        search_spec.matchPattern = match_pattern
        search_results           = self.execute_search_task(search_function, search_spec)
        return self.get_search_data__for_files(search_results)

    def files_names(self, match_pattern="*"):
        return sorted(list(set(self.files(match_pattern, index_by='FileName'))))

    def files_paths(self, match_pattern="*"):
        files = self.files(match_pattern)
        paths = []
        for file in files:
            path = f"{file['Folder_path']}/{file['FileName']}"
            #path = path.replace(f'[{self.name}] ', "")          # remove datastore from path
            paths.append(path)

        return sorted(paths)

    # note the content.fileManager.MakeDirectory doesn't return a Task so need to keep an eye on this for side effect
    # it might be that these legacy methods do the folder creation in a sync way (vs a task)
    def folder_create(self, folder_name):
        folder_path = f'[{self.name}]/{folder_name}'
        content = self.sdk.content()
        datacenter = self.sdk.datacenter()
        content.fileManager.MakeDirectory(name=folder_path, datacenter=datacenter, createParentDirectories=True) # this method doesn't return a task
        #Task().wait_for_task(task)
        return True

    def folder_delete(self, folder_name):
        return self.delete(folder_name)

    @index_by
    @group_by
    def folders(self, match_pattern="*"):
        search_function = self.datastore().browser.SearchSubFolders

        query_folder    = pyVmomi.vim.host.DatastoreBrowser.FolderQuery()
        search_spec     = pyVmomi.vim.host.DatastoreBrowser.SearchSpec(query=[query_folder])
        search_spec.matchPattern = match_pattern
        search_results = self.execute_search_task(search_function, search_spec)
        return self.get_search_data__for_folders(search_results[0].file)

    def folders_names(self, match_pattern="*"):
        return sorted(list(set(self.folders(match_pattern, index_by="FolderName"))))

    def sizeof_fmt(self, num):
        """
        Returns the human readable version of a file size
        :param num:
        :return:
        """
        for item in ['bytes', 'KB', 'MB', 'GB']:
            if num < 1024.0:
                return "%3.1f %s" % (num, item)
            num /= 1024.0
        return "%3.1f %s" % (num, 'TB')