Beispiel #1
0
    def __init__(self, path=None, pkg=None, host=None):
        self.pkg = pkg
        self.host = host
        version = None
        if path is not None:
            m = AGENT_DIR_PATTERN.match(path)
            if m == None:
                raise UpdateError(u"Illegal agent directory: {0}".format(path))
            version = m.group(1)
        elif self.pkg is not None:
            version = pkg.version

        if version == None:
            raise UpdateError(u"Illegal agent version: {0}".format(version))
        self.version = FlexibleVersion(version)

        location = u"disk" if path is not None else u"package"
        logger.verbose(u"Instantiating Agent {0} from {1}", self.name,
                       location)

        self.error = None
        self.supported = None

        self._load_error()
        self._load_supported()

        self._ensure_downloaded()
        return
Beispiel #2
0
    def _unpack(self):
        try:
            if os.path.isdir(self.get_agent_dir()):
                shutil.rmtree(self.get_agent_dir())

            zipfile.ZipFile(self.get_agent_pkg_path()).extractall(
                self.get_agent_dir())

        except Exception as e:
            fileutil.clean_ioerror(
                e, paths=[self.get_agent_dir(),
                          self.get_agent_pkg_path()])

            msg = u"Exception unpacking Agent {0} from {1}: {2}".format(
                self.name, self.get_agent_pkg_path(), ustr(e))
            raise UpdateError(msg)

        if not os.path.isdir(self.get_agent_dir()):
            msg = u"Unpacking Agent {0} failed to create directory {1}".format(
                self.name, self.get_agent_dir())
            raise UpdateError(msg)

        logger.verbose(u"Agent {0} unpacked successfully to {1}", self.name,
                       self.get_agent_dir())
        return
Beispiel #3
0
    def __init__(self, path=None, pkg=None, host=None):
        self.pkg = pkg
        self.host = host
        version = None
        if path is not None:
            m = AGENT_DIR_PATTERN.match(path)
            if m == None:
                raise UpdateError(u"Illegal agent directory: {0}".format(path))
            version = m.group(1)
        elif self.pkg is not None:
            version = pkg.version

        if version == None:
            raise UpdateError(u"Illegal agent version: {0}".format(version))
        self.version = FlexibleVersion(version)

        location = u"disk" if path is not None else u"package"
        logger.verbose(u"Loading Agent {0} from {1}", self.name, location)

        self.error = GuestAgentError(self.get_agent_error_file())
        self.error.load()

        try:
            self._ensure_downloaded()
            self._ensure_loaded()
        except Exception as e:
            if isinstance(e, ResourceGoneError):
                raise

            # The agent was improperly blacklisting versions due to a timeout
            # encountered while downloading a later version. Errors of type
            # socket.error are IOError, so this should provide sufficient
            # protection against a large class of I/O operation failures.
            if isinstance(e, IOError):
                raise

            # Note the failure, blacklist the agent if the package downloaded
            # - An exception with a downloaded package indicates the package
            #   is corrupt (e.g., missing the HandlerManifest.json file)
            self.mark_failure(
                is_fatal=os.path.isfile(self.get_agent_pkg_path()))

            msg = u"Agent {0} install failed with exception: {1}".format(
                self.name, ustr(e))
            detailed_msg = '{0} {1}'.format(
                msg, traceback.extract_tb(get_traceback(e)))
            add_event(AGENT_NAME,
                      version=self.version,
                      op=WALAEventOperation.Install,
                      is_success=False,
                      message=detailed_msg)
Beispiel #4
0
    def _download(self):
        package = None

        for uri in self.pkg.uris:
            try:
                resp = restutil.http_get(uri.uri, chk_proxy=True)
                if resp.status == restutil.httpclient.OK:
                    package = resp.read()
                    fileutil.write_file(self.get_agent_pkg_path(),
                                        bytearray(package),
                                        asbin=True)
                    logger.info(u"Agent {0} downloaded from {1}", self.name,
                                uri.uri)
                    break
            except restutil.HttpError as e:
                logger.warn(u"Agent {0} download from {1} failed", self.name,
                            uri.uri)

        if not os.path.isfile(self.get_agent_pkg_path()):
            msg = u"Unable to download Agent {0} from any URI".format(
                self.name)
            add_event(AGENT_NAME,
                      op=WALAEventOperation.Download,
                      version=CURRENT_VERSION,
                      is_success=False,
                      message=msg)
            raise UpdateError(msg)
        return
Beispiel #5
0
    def __init__(self, path):
        if path is None:
            raise UpdateError(u"GuestAgentError requires a path")
        self.path = path

        self.clear()
        return
Beispiel #6
0
    def __init__(self, path):
        if path is None:
            raise UpdateError(u"Supported requires a path")
        self.path = path

        self._load()
        return
Beispiel #7
0
    def _download(self):
        for uri in self.pkg.uris:
            if not HostPluginProtocol.is_default_channel() and self._fetch(
                    uri.uri):
                break
            elif self.host is not None and self.host.ensure_initialized():
                if not HostPluginProtocol.is_default_channel():
                    logger.warn(
                        "Download unsuccessful, falling back to host plugin")
                else:
                    logger.verbose("Using host plugin as default channel")

                uri, headers = self.host.get_artifact_request(
                    uri.uri, self.host.manifest_uri)
                if self._fetch(uri, headers=headers):
                    if not HostPluginProtocol.is_default_channel():
                        logger.verbose(
                            "Setting host plugin as default channel")
                        HostPluginProtocol.set_default_channel(True)
                    break
                else:
                    logger.warn("Host plugin download unsuccessful")
            else:
                logger.error("No download channels available")

        if not os.path.isfile(self.get_agent_pkg_path()):
            msg = u"Unable to download Agent {0} from any URI".format(
                self.name)
            add_event(AGENT_NAME,
                      op=WALAEventOperation.Download,
                      version=CURRENT_VERSION,
                      is_success=False,
                      message=msg)
            raise UpdateError(msg)
        return
Beispiel #8
0
    def _ensure_downloaded(self):
        logger.verbose(u"Ensuring Agent {0} is downloaded", self.name)

        if self.is_downloaded:
            logger.verbose(
                u"Agent {0} was previously downloaded - skipping download",
                self.name)
            return

        if self.pkg is None:
            raise UpdateError(
                u"Agent {0} is missing package and download URIs".format(
                    self.name))

        self._download()
        self._unpack()

        msg = u"Agent {0} downloaded successfully".format(self.name)
        logger.verbose(msg)
        add_event(AGENT_NAME,
                  version=self.version,
                  op=WALAEventOperation.Install,
                  is_success=True,
                  message=msg)
        return
Beispiel #9
0
    def _download(self):
        for uri in self.pkg.uris:
            if self._fetch(uri.uri):
                break
            else:
                if self.host is not None and self.host.ensure_initialized():
                    logger.warn(
                        "Download unsuccessful, falling back to host plugin")
                    uri, headers = self.host.get_artifact_request(
                        uri.uri, self.host.manifest_uri)
                    if uri is not None \
                            and headers is not None \
                            and self._fetch(uri, headers=headers):
                        break
                else:
                    logger.warn(
                        "Download unsuccessful, host plugin not available")

        if not os.path.isfile(self.get_agent_pkg_path()):
            msg = u"Unable to download Agent {0} from any URI".format(
                self.name)
            add_event(AGENT_NAME,
                      op=WALAEventOperation.Download,
                      version=CURRENT_VERSION,
                      is_success=False,
                      message=msg)
            raise UpdateError(msg)
        return
Beispiel #10
0
    def __init__(self, path):  # pylint: disable=R1711
        if path is None:
            raise UpdateError(u"GuestAgentError requires a path")
        self.path = path

        self.clear()
        return
Beispiel #11
0
    def __init__(self, path=None, pkg=None, host=None):
        self.pkg = pkg
        self.host = host
        version = None
        if path is not None:
            m = AGENT_DIR_PATTERN.match(path)
            if m == None:
                raise UpdateError(u"Illegal agent directory: {0}".format(path))
            version = m.group(1)
        elif self.pkg is not None:
            version = pkg.version

        if version == None:
            raise UpdateError(u"Illegal agent version: {0}".format(version))
        self.version = FlexibleVersion(version)

        location = u"disk" if path is not None else u"package"
        logger.verbose(u"Loading Agent {0} from {1}", self.name, location)

        self.error = GuestAgentError(self.get_agent_error_file())
        self.error.load()
        self.safe_deploy = safedeploy.SafeDeploy()

        try:
            self._ensure_downloaded()
            self._ensure_loaded()
        except Exception as e:
            if isinstance(e, ResourceGoneError):
                raise

            # Note the failure, blacklist the agent if the package downloaded
            # - An exception with a downloaded package indicates the package
            #   is corrupt (e.g., missing the HandlerManifest.json file)
            self.mark_failure(
                is_fatal=os.path.isfile(self.get_agent_pkg_path()))

            msg = u"Agent {0} install failed with exception: {1}".format(
                self.name, ustr(e))
            logger.warn(msg)
            add_event(AGENT_NAME,
                      version=self.version,
                      op=WALAEventOperation.Install,
                      is_success=False,
                      message=msg)
Beispiel #12
0
    def _load_manifest(self):
        path = self.get_agent_manifest_path()
        if not os.path.isfile(path):
            msg = u"Agent {0} is missing the {1} file".format(self.name, AGENT_MANIFEST_FILE)
            raise UpdateError(msg)

        with open(path, "r") as manifest_file:
            try:
                manifests = json.load(manifest_file)
            except Exception as e:
                msg = u"Agent {0} has a malformed {1}".format(self.name, AGENT_MANIFEST_FILE)
                raise UpdateError(msg)
            if type(manifests) is list:
                if len(manifests) <= 0:
                    msg = u"Agent {0} has an empty {1}".format(self.name, AGENT_MANIFEST_FILE)
                    raise UpdateError(msg)
                manifest = manifests[0]
            else:
                manifest = manifests

        try:
            self.manifest = HandlerManifest(manifest)
            if len(self.manifest.get_enable_command()) <= 0:
                raise Exception(u"Manifest is missing the enable command")
        except Exception as e:
            msg = u"Agent {0} has an illegal {1}: {2}".format(
                self.name,
                AGENT_MANIFEST_FILE,
                ustr(e))
            raise UpdateError(msg)

        logger.info(
            u"Agent {0} loaded manifest from {1}",
            self.name,
            self.get_agent_manifest_path())
        logger.verbose(u"Successfully loaded Agent {0} {1}: {2}",
            self.name,
            AGENT_MANIFEST_FILE,
            ustr(self.manifest.data))
        return
Beispiel #13
0
    def _ensure_downloaded(self):
        try:
            logger.verbose(u"Ensuring Agent {0} is downloaded", self.name)

            if self.is_blacklisted:
                logger.info(u"Agent {0} is blacklisted - skipping download",
                            self.name)
                return

            if self.is_downloaded:
                logger.verbose(
                    u"Agent {0} was previously downloaded - skipping download",
                    self.name)
                self._load_manifest()
                return

            if self.pkg is None:
                raise UpdateError(
                    u"Agent {0} is missing package and download URIs".format(
                        self.name))

            self._download()
            self._unpack()
            self._load_manifest()
            self._load_error()
            self._load_supported()

            msg = u"Agent {0} downloaded successfully".format(self.name)
            logger.verbose(msg)
            add_event(AGENT_NAME,
                      version=self.version,
                      op=WALAEventOperation.Install,
                      is_success=True,
                      message=msg)

        except Exception as e:
            # Note the failure, blacklist the agent if the package downloaded
            # - An exception with a downloaded package indicates the package
            #   is corrupt (e.g., missing the HandlerManifest.json file)
            self.mark_failure(
                is_fatal=os.path.isfile(self.get_agent_pkg_path()))

            msg = u"Agent {0} download failed with exception: {1}".format(
                self.name, ustr(e))
            logger.warn(msg)
            add_event(AGENT_NAME,
                      version=self.version,
                      op=WALAEventOperation.Install,
                      is_success=False,
                      message=msg)
        return
Beispiel #14
0
    def _download(self):
        uris_shuffled = self.pkg.uris
        random.shuffle(uris_shuffled)
        for uri in uris_shuffled:
            if not HostPluginProtocol.is_default_channel() and self._fetch(
                    uri.uri):
                break

            elif self.host is not None and self.host.ensure_initialized():
                if not HostPluginProtocol.is_default_channel():
                    logger.warn("Download failed, switching to host plugin")
                else:
                    logger.verbose("Using host plugin as default channel")

                uri, headers = self.host.get_artifact_request(
                    uri.uri, self.host.manifest_uri)
                try:
                    if self._fetch(uri, headers=headers, use_proxy=False):
                        if not HostPluginProtocol.is_default_channel():
                            logger.verbose(
                                "Setting host plugin as default channel")
                            HostPluginProtocol.set_default_channel(True)
                        break
                    else:
                        logger.warn("Host plugin download failed")

                # If the HostPlugin rejects the request,
                # let the error continue, but set to use the HostPlugin
                except ResourceGoneError:
                    HostPluginProtocol.set_default_channel(True)
                    raise

            else:
                logger.error("No download channels available")

        if not os.path.isfile(self.get_agent_pkg_path()):
            msg = u"Unable to download Agent {0} from any URI".format(
                self.name)
            add_event(AGENT_NAME,
                      op=WALAEventOperation.Download,
                      version=CURRENT_VERSION,
                      is_success=False,
                      message=msg)
            raise UpdateError(msg)
Beispiel #15
0
    def __init__(self, s):
        if s is None or not isinstance(s, dict):
            raise UpdateError(u"SupportedDisribution requires a dictionary")

        self.slice = s['slice']
        self.versions = s['versions']
Beispiel #16
0
 def __init__(self, path):
     if path is None:
         raise UpdateError(u"Supported requires a path")
     self.path = path
     self.distributions = {}
     return