def download_azure_blob(account_name, account_key, file_uri, download_dir): (blob_name, container_name) = parse_blob_uri(file_uri) host_base = get_host_base_from_uri(file_uri) download_path = os.path.join(download_dir, blob_name) blob_service = BlobService(account_name, account_key, host_base=host_base) max_retry = 3 for retry in range(1, max_retry + 1): try: blob_service.get_blob_to_path(container_name, blob_name, download_path) except Exception: hutil.error('Failed to download Azure blob, retry = ' + str(retry) + ', max_retry = ' + str(max_retry)) if retry != max_retry: hutil.log('Sleep 10 seconds') time.sleep(10) else: waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.Download, isSuccess=False, message="(03303)Failed to download file from Azure Storage") raise Exception('Failed to download azure blob: ' + blob_name) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.Download, isSuccess=True, message="(03301)Succeeded to download file from Azure Storage") return download_path
def main(): waagent.LoggerInit('/var/log/waagent.log','/dev/stdout') waagent.Log("%s started to handle." %(ExtensionShortName)) global hutil hutil = Util.HandlerUtility(waagent.Log, waagent.Error) hutil.try_parse_context() global public_settings public_settings = hutil.get_public_settings() if not public_settings: waagent.AddExtensionEvent(name=ExtensionShortName, op='MainInProgress', isSuccess=True, message="Public settings are NOT provided.") public_settings = {} global protected_settings protected_settings = hutil.get_protected_settings() if not protected_settings: waagent.AddExtensionEvent(name=ExtensionShortName, op='MainInProgress', isSuccess=True, message="protected settings are NOT provided.") protected_settings = {} global distro_category distro_category = get_distro_category() for a in sys.argv[1:]: if re.match("^([-/]*)(disable)", a): disable() elif re.match("^([-/]*)(uninstall)", a): uninstall() elif re.match("^([-/]*)(install)", a): install() elif re.match("^([-/]*)(enable)", a): enable() elif re.match("^([-/]*)(update)", a): update()
def download_files_with_retry(hutil, retry_count, wait): hutil.log( ("Will try to download files, " "number of retries = {0}, " "wait SECONDS between retrievals = {1}s").format(retry_count, wait)) for download_retry_count in range(0, retry_count + 1): try: download_files(hutil) break except Exception as e: error_msg = "{0}, retry = {1}, maxRetry = {2}.".format( e, download_retry_count, retry_count) hutil.error(error_msg) if download_retry_count < retry_count: hutil.log("Sleep {0} seconds".format(wait)) time.sleep(wait) else: waagent.AddExtensionEvent( name=ExtensionShortName, op=DownloadOp, isSuccess=False, version=hutil.get_extension_version(), message="(01100)" + error_msg) raise msg = ("Succeeded to download files, " "retry count = {0}").format(download_retry_count) hutil.log(msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=DownloadOp, isSuccess=True, version=hutil.get_extension_version(), message="(01303)" + msg) return retry_count - download_retry_count
def send_heart_beat_msg_to_agent_service(status_event_type): response = None try: retry_count = 0 canRetry = True while retry_count <= 5 and canRetry: waagent.AddExtensionEvent(name=ExtensionShortName, op='HeartBeatInProgress', isSuccess=True, message="In send_heart_beat_msg_to_agent_service method") code,output = run_cmd("python /opt/microsoft/dsc/Scripts/GetDscLocalConfigurationManager.py") if code == 0 and "RefreshMode=Pull" in output: waagent.AddExtensionEvent(name=ExtensionShortName, op='HeartBeatInProgress', isSuccess=True, message="sends heartbeat message in pullmode") m = re.search("ServerURL=([^\n]+)", output) if not m: return registration_url = m.group(1) agent_id = get_nodeid(nodeid_path) node_extended_properties_url = registration_url + "/Nodes(AgentId='" + agent_id + "')/ExtendedProperties" waagent.AddExtensionEvent(name=ExtensionShortName, op='HeartBeatInProgress', isSuccess=True, message="Url is " + node_extended_properties_url) headers = {'Content-Type': "application/json; charset=utf-8", 'Accept': "application/json", "ProtocolVersion" : "2.0"} data = construct_node_extension_properties(output, status_event_type) http_client_factory = httpclientfactory.HttpClientFactory("/etc/opt/omi/ssl/oaas.crt", "/etc/opt/omi/ssl/oaas.key") http_client = http_client_factory.create_http_client(sys.version_info) response = http_client.post(node_extended_properties_url, headers=headers, data=data) waagent.AddExtensionEvent(name=ExtensionShortName, op='HeartBeatInProgress', isSuccess=True, message="response code is " + str(response.status_code)) if response.status_code >=500 and response.status_code < 600: canRetry = True time.sleep(10) else: canRetry = False retry_count += 1 except Exception as e: waagent.AddExtensionEvent(name=ExtensionShortName, op='HeartBeatInProgress', isSuccess=True, message="Failed to send heartbeat message to DSC agent service: {0}, stacktrace: {1} ".format(str(e), traceback.format_exc())) hutil.error('Failed to send heartbeat message to DSC agent service: %s, stack trace: %s' %(str(e), traceback.format_exc())) return response
def check_idns_with_retry(hutil, retry_count, wait): is_idns_ready = False for check_idns_retry_count in range(0, retry_count + 1): is_idns_ready = check_idns() if is_idns_ready: break else: if check_idns_retry_count < retry_count: hutil.error("Internal DNS is not ready, retry to check.") hutil.log("Sleep {0} seconds".format(wait)) time.sleep(wait) if is_idns_ready: msg = ("Internal DNS is ready, " "retry count = {0}").format(check_idns_retry_count) hutil.log(msg) waagent.AddExtensionEvent(name=ExtensionShortName, op="CheckIDNS", isSuccess=True, version=hutil.get_extension_version(), message="(01306)" + msg) else: error_msg = ( "Internal DNS is not ready, " "retry count = {0}, ignore it.").format(check_idns_retry_count) hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op="CheckIDNS", isSuccess=False, version=hutil.get_extension_version(), message="(01306)" + error_msg)
def get_nodeid(file_path): id = None try: if os.path.exists(file_path): with open(file_path) as f: id = f.readline().strip() except Exception as e: error_msg = 'get_nodeid() failed: Unable to open id file {0}'.format( file_path) hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=False, message=error_msg) return None if not id: error_msg = 'get_nodeid() failed: Empty content in id file {0}'.format( file_path) hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=False, message=error_msg) return None return id
def update_statusfile(status_filepath, node_id, vmuuid): waagent.AddExtensionEvent( name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message="updating the status file " + '[statusfile={0}][vmuuid={1}][node_id={2}]'.format( status_filepath, vmuuid, node_id)) if status_filepath is None: error_msg = "Unable to locate a status file" hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=False, message=error_msg) return None status_data = None if os.path.exists(status_filepath): jsonData = open(status_filepath) status_data = json.load(jsonData) jsonData.close() metadatastatus = [{ "status": "success", "code": "0", "name": "metadata", "formattedMessage": { "lang": "en-US", "message": "AgentID=" + node_id + ";VMUUID=" + vmuuid } }] with open(status_filepath, "w") as fp: status_file_content = [{ "status": { "status": "success", "formattedMessage": { "lang": "en-US", "message": "Enable Succeeded" }, "operation": "Enable", "code": "0", "name": "Microsoft.OSTCExtensions.DSCForLinux", "substatus": metadatastatus }, "version": "1.0", "timestampUTC": time.strftime(date_time_format, time.gmtime()) }] json.dump(status_file_content, fp) waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message="successfully written nodeid and vmuuid") waagent.AddExtensionEvent( name=ExtensionName, op="Enable", isSuccess=True, message="successfully executed enable functionality")
def deb_install_pkg(package_path, package_name, major_version, minor_version, build, release, install_options): version = deb_get_pkg_version(package_name) if version is not None and compare_pkg_version( version, major_version, minor_version, build, release) == 1: # package is already installed hutil.log(package_name + ' version ' + version + ' is already installed') waagent.AddExtensionEvent(name=ExtensionShortName, op='InstallInProgress', isSuccess=True, message="dsc package with version: " + version + "is already installed.") return else: cmd = 'dpkg -i ' + install_options + ' ' + package_path code, output = run_cmd(cmd) if code == 0: hutil.log(package_name + ' version ' + str(major_version) + '.' + str(minor_version) + '.' + str(build) + '.' + str(release) + ' is installed successfully') else: waagent.AddExtensionEvent( name=ExtensionShortName, op='InstallInProgress', isSuccess=False, message="Failed to install debian package :" + package_path) raise Exception('Failed to install package {0}: {1}'.format( package_name, output))
def install(): hutil.do_parse_context('Install') try: waagent.AddExtensionEvent(name=ExtensionShortName, op='InstallInProgress', isSuccess=True, message="Installing DSCForLinux extension") remove_old_dsc_packages() install_dsc_packages() waagent.AddExtensionEvent( name=ExtensionShortName, op='InstallInProgress', isSuccess=True, message="successfully installed DSCForLinux extension") hutil.do_exit(0, 'Install', 'success', '0', 'Install Succeeded.') except Exception as e: waagent.AddExtensionEvent( name=ExtensionShortName, op='InstallInProgress', isSuccess=True, message= "failed to install an extension with error: {0} and stacktrace: {1}" .format(str(e), traceback.format_exc())) hutil.error( "Failed to install the extension with error: %s, stack trace: %s" % (str(e), traceback.format_exc())) hutil.do_exit(1, 'Install', 'error', '1', 'Install Failed.')
def download_file(): waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message="Downloading file") download_dir = prepare_download_dir(hutil.get_seq_no()) storage_account_name = get_config('StorageAccountName') storage_account_key = get_config('StorageAccountKey') file_uri = get_config('FileUri') if not file_uri: error_msg = 'Missing FileUri configuration' waagent.AddExtensionEvent( name=ExtensionShortName, op=Operation.Download, isSuccess=False, message="(03000)Argument error, invalid file location") hutil.do_exit(51, 'Enable', 'error', '51', '(03000)Argument error, invalid file location') if storage_account_name and storage_account_key: hutil.log('Downloading file from azure storage...') path = download_azure_blob(storage_account_name, storage_account_key, file_uri, download_dir) return path else: hutil.log('Downloading file from external link...') waagent.AddExtensionEvent( name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message="Downloading file from external link...") path = download_external_file(file_uri, download_dir) return path
def download_external_file(file_uri, download_dir): waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message="Downloading from external file") path = get_path_from_uri(file_uri) file_name = path.split('/')[-1] file_path = os.path.join(download_dir, file_name) max_retry = 3 for retry in range(1, max_retry + 1): try: download_and_save_file(file_uri, file_path) waagent.AddExtensionEvent( name=ExtensionShortName, op=Operation.Download, isSuccess=True, message="(03302)Succeeded to download file from public URI") return file_path except Exception: hutil.error('Failed to download public file, retry = ' + str(retry) + ', max_retry = ' + str(max_retry)) if retry != max_retry: hutil.log('Sleep 10 seconds') time.sleep(10) else: waagent.AddExtensionEvent( name=ExtensionShortName, op=Operation.Download, isSuccess=False, message= '(03304)Failed to download file from public URI, error : %s, stack trace: %s' % (str(e), traceback.format_exc())) raise Exception('Failed to download public file: ' + file_name)
def get_statusfile_path(): seq_no = hutil.get_seq_no() waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message="sequence number is :" + seq_no) status_file = None handlerEnvironment = None handler_env_path = os.path.join(os.getcwd(), 'HandlerEnvironment.json') try: with open(handler_env_path, 'r') as handler_env_file: handler_env_txt = handler_env_file.read() handler_env = json.loads(handler_env_txt) if type(handler_env) == list: handler_env = handler_env[0] handlerEnvironment = handler_env except Exception as e: hutil.error(e.message) waagent.AddExtensionEvent( name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message= 'exception in retrieving status_dir error : %s, stack trace: %s' % (str(e), traceback.format_exc())) status_dir = handlerEnvironment['handlerEnvironment']['statusFolder'] status_file = status_dir + '/' + seq_no + '.status' waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message="status file path: " + status_file) return status_file
def construct_node_extension_properties(lcmconfig, status_event_type): waagent.AddExtensionEvent(name=ExtensionShortName, op='HeartBeatInProgress', isSuccess=True, message="Getting properties") OMSCLOUD_ID = get_omscloudid() distro_info = platform.dist() if len(distro_info[1].split('.')) == 1: major_version = distro_info[1].split('.')[0] minor_version = 0 if len(distro_info[1].split('.')) >= 2: major_version = distro_info[1].split('.')[0] minor_version = distro_info[1].split('.')[1] VMUUID = get_vmuuid() node_config_names = get_lcm_config_setting('ConfigurationNames', lcmconfig) configuration_mode = get_lcm_config_setting("ConfigurationMode", lcmconfig) configuration_mode_frequency = get_lcm_config_setting( "ConfigurationModeFrequencyMins", lcmconfig) refresh_frequency_mins = get_lcm_config_setting("RefreshFrequencyMins", lcmconfig) reboot_node = get_lcm_config_setting("RebootNodeIfNeeded", lcmconfig) action_after_reboot = get_lcm_config_setting("ActionAfterReboot", lcmconfig) allow_module_overwrite = get_lcm_config_setting("AllowModuleOverwrite", lcmconfig) waagent.AddExtensionEvent(name=ExtensionShortName, op='HeartBeatInProgress', isSuccess=True, message="Constructing properties data") properties_data = { "OMSCloudId": OMSCLOUD_ID, "TimeStamp": time.strftime(date_time_format, time.gmtime()), "VMResourceId": "", "ExtensionStatusEvent": status_event_type, "ExtensionInformation": { "Name": "Microsoft.OSTCExtensions.DSCForLinux", "Version": extension_handler_version }, "OSProfile": { "Name": distro_info[0], "Type": "Linux", "MinorVersion": minor_version, "MajorVersion": major_version, "VMUUID": VMUUID }, "RegistrationMetaData": { "NodeConfigurationName": node_config_names, "ConfigurationMode": configuration_mode, "ConfigurationModeFrequencyMins": configuration_mode_frequency, "RefreshFrequencyMins": refresh_frequency_mins, "RebootNodeIfNeeded": reboot_node, "ActionAfterReboot": action_after_reboot, "AllowModuleOverwrite": allow_module_overwrite } } return properties_data
def enable(): hutil.do_parse_context('Enable') hutil.exit_if_enabled() try: start_omiservice() mode = get_config('Mode') if mode == '': mode = Mode.push else: mode = mode.lower() if not hasattr(Mode, mode): waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.Enable, isSuccess=False, message="(03001)Argument error, invalid mode") hutil.do_exit(1, 'Enable', 'error', '1', 'Enable failed, unknown mode: ' + mode) if mode == Mode.remove: remove_module() elif mode == Mode.register: register_automation() else: file_path = download_file() if mode == Mode.pull: current_config = apply_dsc_meta_configuration(file_path) elif mode == Mode.push: current_config = apply_dsc_configuration(file_path) else: install_module(file_path) if mode == Mode.push or mode == Mode.pull: if check_dsc_configuration(current_config): if mode == Mode.push: waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.ApplyMof, isSuccess=True, message="(03104)Succeeded to apply MOF configuration through Push Mode") else: waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.ApplyMetaMof, isSuccess=True, message="(03106)Succeeded to apply meta MOF configuration through Pull Mode") hutil.do_exit(0, 'Enable', 'success', '0', 'Enable Succeeded. Current Configuration: ' + current_config) else: if mode == Mode.push: waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.ApplyMof, isSuccess=False, message="(03105)Failed to apply MOF configuration through Push Mode") else: waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.ApplyMetaMof, isSuccess=False, message="(03107)Failed to apply meta MOF configuration through Pull Mode") hutil.do_exit(1, 'Enable', 'error', '1', 'Enable failed. ' + current_config) hutil.do_exit(0, 'Enable', 'success', '0', 'Enable Succeeded') except Exception, e: hutil.error('Failed to enable the extension with error: %s, stack trace: %s' %(str(e), traceback.format_exc())) hutil.do_exit(1, 'Enable', 'error', '1', 'Enable failed: {0}'.format(e))
def download_azure_blob(account_name, account_key, file_uri, download_dir): waagent.AddExtensionEvent(name=ExtensionShortName, op="EnableInProgress", isSuccess=True, message="Downloading from azure blob") try: (blob_name, container_name) = parse_blob_uri(file_uri) host_base = get_host_base_from_uri(file_uri) blob_parent_path = os.path.join(download_dir, os.path.dirname(blob_name)) if not os.path.exists(blob_parent_path): os.makedirs(blob_parent_path) download_path = os.path.join(download_dir, blob_name) blob_service = BlobService(account_name, account_key, host_base=host_base) except Exception as e: waagent.AddExtensionEvent( name=ExtensionShortName, op='DownloadInProgress', isSuccess=True, message= 'Enable failed with the azure storage error : {0}, stack trace: {1}' .format(str(e), traceback.format_exc())) hutil.error( 'Failed to enable the extension with error: %s, stack trace: %s' % (str(e), traceback.format_exc())) hutil.do_exit(1, 'Enable', 'error', '1', 'Enable failed: {0}'.format(e)) max_retry = 3 for retry in range(1, max_retry + 1): try: blob_service.get_blob_to_path(container_name, blob_name, download_path) except Exception: hutil.error('Failed to download Azure blob, retry = ' + str(retry) + ', max_retry = ' + str(max_retry)) if retry != max_retry: hutil.log('Sleep 10 seconds') time.sleep(10) else: waagent.AddExtensionEvent( name=ExtensionShortName, op=Operation.Download, isSuccess=False, message="(03303)Failed to download file from Azure Storage" ) raise Exception('Failed to download azure blob: ' + blob_name) waagent.AddExtensionEvent( name=ExtensionShortName, op=Operation.Download, isSuccess=True, message="(03301)Succeeded to download file from Azure Storage") return download_path
def register_automation(registration_key, registation_url, node_configuration_name, refresh_freq, configuration_mode_freq, configuration_mode): if (registration_key == '' or registation_url == ''): err_msg = "Either the Registration Key or Registration URL is NOT provided" hutil.error(err_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op='RegisterInProgress', isSuccess=True, message=err_msg) return 51, err_msg if configuration_mode != '' and not ( configuration_mode == 'applyandmonitor' or configuration_mode == 'applyandautocorrect' or configuration_mode == 'applyonly'): err_msg = "ConfigurationMode: " + configuration_mode + " is not valid." hutil.error( err_msg + "It should be one of the values : (ApplyAndMonitor | ApplyAndAutoCorrect | ApplyOnly)" ) waagent.AddExtensionEvent(name=ExtensionShortName, op='RegisterInProgress', isSuccess=True, message=err_msg) return 51, err_msg cmd = '/opt/microsoft/dsc/Scripts/Register.py' + ' --RegistrationKey '+ registration_key \ + ' --ServerURL '+ registation_url optional_parameters = "" if node_configuration_name != '': optional_parameters += ' --ConfigurationName ' + node_configuration_name if refresh_freq != '': optional_parameters += ' --RefreshFrequencyMins ' + refresh_freq if configuration_mode_freq != '': optional_parameters += ' --ConfigurationModeFrequencyMins ' + configuration_mode_freq if configuration_mode != '': optional_parameters += ' --ConfigurationMode ' + configuration_mode waagent.AddExtensionEvent(name=ExtensionShortName, op="RegisterInProgress", isSuccess=True, message="Registration URL " + registation_url + "Optional parameters to Registration" + optional_parameters) code, output = run_cmd(cmd + optional_parameters) if not code == 0: error_msg = 'Failed to register with Azure Automation DSC: {0}'.format( output) hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.Register, isSuccess=True, message="(03109)" + error_msg) return 1, err_msg waagent.AddExtensionEvent( name=ExtensionShortName, op=Operation.Register, isSuccess=True, message="(03108)Succeeded to register with Azure Automation DSC") return 0, ''
def download_file(mode): download_dir = prepare_download_dir(hutil.get_seq_no()) storage_account_name = get_config('StorageAccountName') storage_account_key = get_config('StorageAccountKey') container_name = get_config('ContainerName') mof_blob_name = get_config('MofFileName') mof_file_uri = get_config('MofFileUri') resource_file_name = get_config('ResourceZipFileName') resource_file_uri = get_config('ResourceZipFileUri') if mode == 'push' or mode == 'pull': if storage_account_name and storage_account_key and container_name and mof_blob_name: hutil.log('Downloading the MOF file ' + mof_blob_name + ' from azure storage') download_path = os.path.join(download_dir, mof_blob_name) download_azure_blob(storage_account_name, storage_account_key, container_name, mof_blob_name, download_path) return download_path elif mof_file_uri: hutil.log('Downloading the MOF file from external link') file_path = download_external_file(mof_file_uri, download_dir) return file_path else: error_msg = 'Missing configurations of MOF file' waagent.AddExtensionEvent( name=ExtensionShortName, op=DownloadOp, isSuccess=False, message="(03000)Argument error, invalid file location") elif mode == 'install': if storage_account_name and storage_account_key and container_name and resource_file_name: hutil.log('Downloading the resource zip file ' + resource_file_name + ' from azure storage') download_path = os.path.join(download_dir, resource_file_name) download_azure_blob(storage_account_name, storage_account_key, container_name, resource_file_name, download_path) return download_path elif resource_file_uri: hutil.log('Downloading the resource zip file from external link') file_path = download_external_file(resource_file_uri, download_dir) return file_path else: error_msg = 'Missing configurations of resource zip file' waagent.AddExtensionEvent( name=ExtensionShortName, op=DownloadOp, isSuccess=False, message="(03000)Argument error, invalid file location") else: error_msg = 'Invalid mode: ' + mode hutil.error(error_msg) raise Exception(error_msg)
def apply_dsc_configuration(config_file_path): cmd = '/opt/microsoft/dsc/Scripts/StartDscConfiguration.py -configurationmof ' + config_file_path waagent.AddExtensionEvent(name=ExtensionShortName, op='EnableInProgress', isSuccess=True, message='running the cmd: ' + cmd) code,output = run_cmd(cmd) if code == 0: code,output = run_cmd('/opt/microsoft/dsc/Scripts/GetDscConfiguration.py') return output else: error_msg = 'Failed to apply MOF configuration: {0}'.format(output) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.ApplyMof, isSuccess=True, message=error_msg) hutil.error(error_msg) raise Exception(error_msg)
def download_files(hutil): public_settings = hutil.get_public_settings() if public_settings is None: raise ValueError("Public configuration couldn't be None.") cmd = get_command_to_execute(hutil) blob_uris = public_settings.get('fileUris') protected_settings = hutil.get_protected_settings() storage_account_name = None storage_account_key = None if protected_settings: storage_account_name = protected_settings.get("storageAccountName") storage_account_key = protected_settings.get("storageAccountKey") if storage_account_name is not None: storage_account_name = storage_account_name.strip() if storage_account_key is not None: storage_account_key = storage_account_key.strip() if (not blob_uris or not isinstance(blob_uris, list) or len(blob_uris) == 0): error_msg = "fileUris value provided is empty or invalid." hutil.log(error_msg + " Continue with executing command...") waagent.AddExtensionEvent(name=ExtensionShortName, op=DownloadOp, isSuccess=False, version=Version, message="(01001)"+error_msg) return hutil.do_status_report('Downloading','transitioning', '0', 'Downloading files...') if storage_account_name and storage_account_key: hutil.log("Downloading scripts from azure storage...") download_blobs(storage_account_name, storage_account_key, blob_uris, cmd, hutil) elif not(storage_account_name or storage_account_key): hutil.log("No azure storage account and key specified in protected " "settings. Downloading scripts from external links...") download_external_files(blob_uris, cmd, hutil) else: #Storage account and key should appear in pairs error_msg = "Azure storage account and key should appear in pairs." hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=DownloadOp, isSuccess=False, version=Version, message="(01000)"+error_msg) raise ValueError(error_msg)
def install_module(file_path): install_package('unzip') code,output = run_cmd('/opt/microsoft/dsc/Scripts/InstallModule.py ' + file_path) if not code == 0: error_msg = 'Failed to install DSC Module ' + file_path + ':{0}'.format(output) hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.InstallModule, isSuccess=False, message="(03100)" + error_msg) raise Exception(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.InstallModule, isSuccess=True, message="(03101)Succeeded to install DSC Module")
def remove_module(): module_name = get_config('ResourceName') code,output = run_cmd('/opt/microsoft/dsc/Scripts/RemoveModule.py ' + module_name) if not code == 0: error_msg = 'Failed to remove DSC Module ' + module_name + ': {0}'.format(output) hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.RemoveModule, isSuccess=False, message="(03102)" + error_msg) raise Exception(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.RemoveModule, isSuccess=True, message="(03103)Succeeded to remove DSC Module")
def reboot_if_required(self): self.check_reboot() self.check_needs_restart() msg = '' if self.reboot_after_patch == 'notrequired' and self.reboot_required: msg += 'Pending Reboot' if self.needs_restart: msg += ': ' + ' '.join(self.needs_restart) waagent.AddExtensionEvent(name=self.hutil.get_name(), op="Reboot", isSuccess=False, version=Version, message=" ".join([ self.reboot_after_patch, msg, len(self.needs_restart), "packages need to restart" ])) self.hutil.do_exit(0, 'Enable', 'success', '0', msg) if self.reboot_after_patch == 'required': msg += "System going to reboot(Required)" elif self.reboot_after_patch == 'auto' and self.reboot_required: msg += "System going to reboot(Auto)" elif self.reboot_after_patch == 'rebootifneed': if (self.reboot_required or self.needs_restart): msg += "System going to reboot(RebootIfNeed)" if msg: if self.needs_restart: msg += ': ' + ' '.join(self.needs_restart) self.hutil.log_and_syslog(logging.INFO, msg) waagent.AddExtensionEvent(name=self.hutil.get_name(), op="Reboot", isSuccess=True, version=Version, message="Reboot") retcode = waagent.Run('reboot') if retcode != 0: self.hutil.log_and_syslog(logging.ERROR, "Failed to reboot") waagent.AddExtensionEvent(name=self.hutil.get_name(), op="Reboot", isSuccess=False, version=Version, message="Failed to reboot") else: waagent.AddExtensionEvent(name=self.hutil.get_name(), op="Reboot", isSuccess=False, version=Version, message="Not reboot")
def rpm_check_pkg_exists(package_name, major_version, minor_version, build, release): code, output = run_cmd('rpm -q --queryformat "%{VERSION}.%{RELEASE}" ' + package_name) waagent.AddExtensionEvent(name=ExtensionShortName, op='InstallInProgress', isSuccess=True, message="package name: " + package_name + "; existing package version:" + output) hutil.log("package name: " + package_name + "; existing package version:" + output) if code == 0: return compare_pkg_version(output, major_version, minor_version, build, release)
def uninstall_package(package_name): waagent.AddExtensionEvent(name=ExtensionShortName, op='InstallInProgress', isSuccess=True, message="uninstalling the package" + package_name) if distro_category == DistroCategory.debian: deb_uninstall_package(package_name) elif distro_category == DistroCategory.redhat or distro_category == DistroCategory.suse: rpm_uninstall_package(package_name)
def install_dsc_packages(): openssl_version = get_openssl_version() omi_package_path = omi_package_prefix + openssl_version dsc_package_path = dsc_package_prefix + openssl_version waagent.AddExtensionEvent(name=ExtensionShortName, op='InstallInProgress', isSuccess=True, message="Installing omipackage version: " + omi_package_path + "; dsc package version: " + dsc_package_path) if distro_category == DistroCategory.debian: deb_install_pkg( omi_package_path + '.x64.deb', 'omi', omi_major_version, omi_minor_version, omi_build, omi_release, ' --force-confold --force-confdef --refuse-downgrade ') deb_install_pkg(dsc_package_path + '.x64.deb', 'dsc', dsc_major_version, dsc_minor_version, dsc_build, dsc_release, '') elif distro_category == DistroCategory.redhat or distro_category == DistroCategory.suse: rpm_install_pkg(omi_package_path + '.x64.rpm', 'omi', omi_major_version, omi_minor_version, omi_build, omi_release) rpm_install_pkg(dsc_package_path + '.x64.rpm', 'dsc', dsc_major_version, dsc_minor_version, dsc_build, dsc_release)
def register_automation(): registration_key = get_config('RegistrationKey') registation_url = get_config('RegistrationUrl') code,output = run_cmd('/opt/microsoft/dsc/Scripts/Register.py ' + registration_key + ' ' + registation_url) if not code == 0: error_msg = 'Failed to register with Azure Automation DSC: {0}'.format(output) hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.Register, isSuccess=False, message="(03109)" + error_msg) raise Exception(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=Operation.Register, isSuccess=True, message="(03108)Succeeded to register with Azure Automation DSC")
def download(self): # Read the latest configuration for scheduled task settings = json.loads( waagent.GetFileContents(self.scheduled_configs_file)) self.parse_settings(settings) self.provide_vm_status_test(StatusTest["Scheduled"]) if not self.check_vm_idle(StatusTest["Scheduled"]): return if self.exists_stop_flag(): self.hutil.log_and_syslog( logging.INFO, "Downloading patches is stopped/canceled") return waagent.SetFileContents(self.package_downloaded_path, '') waagent.SetFileContents(self.package_patched_path, '') start_download_time = time.time() # Installing security patches is mandatory self._download(self.category_required) if self.category == self.category_all: self._download(self.category_all) end_download_time = time.time() waagent.AddExtensionEvent( name=self.hutil.get_name(), op=waagent.WALAEventOperation.Download, isSuccess=True, version=Version, message=" ".join([ "Real downloading time is", str(round(end_download_time - start_download_time, 3)), "s" ]))
def check_for_supported_waagent_and_distro_version(): """ Checks & returns if the installed waagent and the Linux distro/version are supported by this LAD. :rtype: bool :return: True iff so. """ for notsupport in ('WALinuxAgent-2.0.5', 'WALinuxAgent-2.0.4', 'WALinuxAgent-1'): code, str_ret = RunGetOutput("grep 'GuestAgentVersion.*" + notsupport + "' /usr/sbin/waagent", should_log=False) if code == 0 and str_ret.find(notsupport) > -1: hutil.log("cannot run this extension on " + notsupport) hutil.do_status_report( g_ext_op_type, "error", '1', "cannot run this extension on " + notsupport) return False if g_dist_config is None: msg = ( "LAD does not support distro/version ({0}); not installed. This extension install/enable operation is " "still considered a success as it's an external error.").format( str(platform.dist())) hutil.log(msg) hutil.do_status_report(g_ext_op_type, "success", '0', msg) waagent.AddExtensionEvent(name=hutil.get_name(), op=g_ext_op_type, isSuccess=True, version=hutil.get_extension_version(), message="Can't be installed on this OS " + str(platform.dist())) return False return True
def start_daemon(hutil): cmd = get_command_to_execute(hutil) if cmd: hutil.log("Command to execute:" + cmd) args = [os.path.join(os.getcwd(), __file__), "-daemon"] # This process will start a new background process by calling # customscript.py -daemon # to run the script and will exit itself immediatelly. # Redirect stdout and stderr to /dev/null. Otherwise daemon process # will throw Broke pipe exeception when parent process exit. devnull = open(os.devnull, 'w') child = subprocess.Popen(args, stdout=devnull, stderr=devnull) hutil.do_exit(0, 'Enable', 'transitioning', '0', 'Launching the script...') else: error_msg = "CommandToExecute is empty or invalid" hutil.error(error_msg) waagent.AddExtensionEvent(name=ExtensionShortName, op=RunScriptOp, isSuccess=False, version=Version, message="(01002)"+error_msg) raise ValueError(error_msg)
def enable(hutil): """ Ensure the same configuration is executed only once If the previous enable failed, we do not have retry logic here, since the custom script may not work in an intermediate state. But if download_files fails, we will retry it for maxRetry times. """ hutil.exit_if_enabled() prepare_download_dir(hutil.get_seq_no()) maxRetry = 2 for retry in range(0, maxRetry + 1): try: download_files(hutil) break except Exception, e: hutil.error(("Failed to download files, " "retry={0}, maxRetry={1}").format(retry, maxRetry)) if retry != maxRetry: hutil.log("Sleep 10 seconds") time.sleep(10) else: error_msg = "Failed to download files" waagent.AddExtensionEvent(name=ExtensionShortName, op=DownloadOp, isSuccess=False, version=Version, message="(01100)" + error_msg) raise