Esempio n. 1
0
    def on_put(self, req, resp, name):
        """
        Handles PUT (or "initiate") requests for a Cluster upgrade.

        :param req: Request instance that will be passed through.
        :type req: falcon.Request
        :param resp: Response instance that will be passed through.
        :type resp: falcon.Response
        :param name: The name of the Cluster being upgraded.
        :type name: str
        """
        data = req.stream.read().decode()
        try:
            args = json.loads(data)
            upgrade_to = args['upgrade_to']
        except (KeyError, ValueError):
            resp.status = falcon.HTTP_400
            return
        # FIXME: How do I pass 'upgrade_to'?
        POOLS['clusterexecpool'].spawn(
            clusterexec.clusterexec, name, 'upgrade', self.store)
        key = '/commissaire/cluster/{0}/upgrade'.format(name)
        cluster_upgrade_default = {
            'status': 'in_process',
            'upgrade_to': upgrade_to,
            'upgraded': [],
            'in_process': [],
            'started_at': datetime.datetime.utcnow().isoformat(),
            'finished_at': None
        }
        cluster_upgrade = ClusterUpgrade(**cluster_upgrade_default)
        self.store.set(key, cluster_upgrade.to_json())
        resp.status = falcon.HTTP_201
        req.context['model'] = cluster_upgrade
Esempio n. 2
0
    def on_put(self, req, resp, name):
        """
        Handles PUT (or "initiate") requests for a Cluster upgrade.

        :param req: Request instance that will be passed through.
        :type req: falcon.Request
        :param resp: Response instance that will be passed through.
        :type resp: falcon.Response
        :param name: The name of the Cluster being upgraded.
        :type name: str
        """
        data = req.stream.read().decode()
        try:
            args = json.loads(data)
            upgrade_to = args['upgrade_to']
        except (KeyError, ValueError):
            resp.status = falcon.HTTP_400
            return

        # Make sure the cluster name is valid.
        if not util.etcd_cluster_exists(self.store, name):
            self.logger.info(
                'Upgrade PUT requested for nonexistent cluster {0}'.format(
                    name))
            resp.status = falcon.HTTP_404
            return

        # If the operation is already in progress and the requested version
        # matches, return the current status with response code 200 OK.
        # If the requested version conflicts with the operation in progress,
        # return the current status with response code 409 Conflict.
        key = '/commissaire/cluster/{0}/upgrade'.format(name)
        try:
            etcd_resp = self.store.get(key)
            self.logger.debug('Etcd Response: {0}'.format(etcd_resp))
            cluster_upgrade = ClusterUpgrade(**json.loads(etcd_resp.value))
            if not cluster_upgrade.finished_at:
                if cluster_upgrade.upgrade_to == upgrade_to:
                    self.logger.debug(
                        'Cluster {0} upgrade to {1} already in progress'.
                        format(name, upgrade_to))
                    resp.status = falcon.HTTP_200
                else:
                    self.logger.debug(
                        'Cluster upgrade to {0} requested while '
                        'upgrade to {1} was already in progress'.
                        format(upgrade_to, cluster_upgrade.upgrade_to))
                    resp.status = falcon.HTTP_409
                req.context['model'] = cluster_upgrade
                return
        except etcd.EtcdKeyNotFound:
            pass

        # FIXME: How do I pass 'upgrade_to'?
        POOLS['clusterexecpool'].spawn(
            clusterexec.clusterexec, name, 'upgrade', self.store)
        self.logger.debug('Started upgrade in clusterexecpool for {0}'.format(
            name))
        cluster_upgrade_default = {
            'status': 'in_process',
            'upgrade_to': upgrade_to,
            'upgraded': [],
            'in_process': [],
            'started_at': datetime.datetime.utcnow().isoformat(),
            'finished_at': None
        }
        cluster_upgrade = ClusterUpgrade(**cluster_upgrade_default)
        self.store.set(key, cluster_upgrade.to_json())
        resp.status = falcon.HTTP_201
        req.context['model'] = cluster_upgrade
Esempio n. 3
0
    def on_put(self, req, resp, name):
        """
        Handles PUT (or "initiate") requests for a Cluster upgrade.

        :param req: Request instance that will be passed through.
        :type req: falcon.Request
        :param resp: Response instance that will be passed through.
        :type resp: falcon.Response
        :param name: The name of the Cluster being upgraded.
        :type name: str
        """
        data = req.stream.read().decode()
        try:
            args = json.loads(data)
            upgrade_to = args['upgrade_to']
        except (KeyError, ValueError):
            resp.status = falcon.HTTP_400
            return

        # Make sure the cluster name is valid.
        if not util.etcd_cluster_exists(name):
            self.logger.info(
                'Upgrade PUT requested for nonexistent cluster {0}'.format(
                    name))
            resp.status = falcon.HTTP_404
            return

        # If the operation is already in progress and the requested version
        # matches, return the current status with response code 200 OK.
        # If the requested version conflicts with the operation in progress,
        # return the current status with response code 409 Conflict.
        key = '/commissaire/cluster/{0}/upgrade'.format(name)
        etcd_resp, error = cherrypy.engine.publish('store-get', key)[0]
        self.logger.debug('Etcd Response: {0}'.format(etcd_resp))
        if not error:
            cluster_upgrade = ClusterUpgrade(**json.loads(etcd_resp.value))
            if not cluster_upgrade.finished_at:
                if cluster_upgrade.upgrade_to == upgrade_to:
                    self.logger.debug(
                        'Cluster {0} upgrade to {1} already in progress'.
                        format(name, upgrade_to))
                    resp.status = falcon.HTTP_200
                else:
                    self.logger.debug(
                        'Cluster upgrade to {0} requested while '
                        'upgrade to {1} was already in progress'.format(
                            upgrade_to, cluster_upgrade.upgrade_to))
                    resp.status = falcon.HTTP_409
                req.context['model'] = cluster_upgrade
                return

        # FIXME: How do I pass 'upgrade_to'?
        p = Process(target=clusterexec, args=(name, 'upgrade'))
        p.start()
        self.logger.debug(
            'Started upgrade in clusterexecpool for {0}'.format(name))
        cluster_upgrade_default = {
            'status': 'in_process',
            'upgrade_to': upgrade_to,
            'upgraded': [],
            'in_process': [],
            'started_at': datetime.datetime.utcnow().isoformat(),
            'finished_at': None
        }
        cluster_upgrade = ClusterUpgrade(**cluster_upgrade_default)
        cherrypy.engine.publish('store-save', key, cluster_upgrade.to_json())
        resp.status = falcon.HTTP_201
        req.context['model'] = cluster_upgrade