Esempio n. 1
0
    def commit(self, request, body):
        """
        Commit specified container to named image.
        if image repository is provided, use the provided repository
        as the new image's repository, otherwise get the image name
        by `image_id` for the repoistory.
        """
        repository = body.pop('repository')
        tag = body.pop('tag')
        image_id = body.pop('id')
        project_id = body.pop('project_id')
        container_id = body.pop('container_id')

        project = self.db.get_project(project_id)
        if not project:
            LOG.error("no such project %s" % project_id)
            return Response(404)

        container_instance = self.db.get_container(container_id)
        if not container_instance:
            LOG.error("no such container %s" % container_id)
            return Response(404)
        container_uuid = container_instance.uuid

        image_instance = self.db.get_image(image_id)
        if not image_instance:
            LOG.error("no such image %s" % image_id)
            return Response(404)
        """If repository is None, use the image's name as repository."""
        if not repository:
            repository = image_instance.name

        new_image_id = uuid.uuid4().hex
        self.db.add_image(dict(id=new_image_id,
                               name=repository,
                               tag=tag,
                               desc=image_instance.desc,
                               repos=image_instance.repos,
                               branch=image_instance.branch,
                               user_id=image_instance.user_id,
                               status='building'),
                          project=project)
        #eventlet.spawn_n(self._manager.commit,
        #             new_image_id,
        #             repository,
        #             tag,
        #             container_uuid)

        self._process_task(self._manager.commit, new_image_id, repository, tag,
                           container_uuid)
        #NOTE(nmg):there may be a bug here.
        return ResponseObject({"id": new_image_id})
Esempio n. 2
0
    def refresh(self, request, id):
        """Refresh code in container."""
        query = self.db.get_container(id)
        if not query:
            LOG.info("container %s not found" % id)
            return Response(404)
        # FIXME(nmg)
        try:
            self._process_task(self._manager.refresh, id)
        except:
            raise

        return Response(204)
Esempio n. 3
0
    def stop(self, request, id):
        """
        Send stop `request` to container node for stoping container.

        This method contains the following two steps:
            - find the host where the container run on
            - send stop request to that host
        If no host found, the request will be droped.
        
        :params request: `wsgi.Request`
        :params id     : container id
        """
        container = self.db.get_container(id)
        if not container:
            LOG.error("nu such container %s" % id)
            return webob.exc.HTTPNotFound()

        host_id = container.host_id
        host = self.db.get_host(host_id)
        if not host:
            LOG.error("no such host")
            return webob.exc.HTTPNotFound()

        host, port = host.host, host.port
        response = self.http.post("http://%s:%s/v1/containers/%s/stop" \
        % (host,port,id))

        return Response(response.status_code)
Esempio n. 4
0
    def delete(self, request, id):
        """
        Send delete `request` to container node for deleting.
        if failed,excepiton will be occured.

        This method contains the following two steps:
            - find the host where the container run on
            - send delete request to that host
        If no host found, the request will be droped.

        :param request: `wsgi.Request`
        :param id     : container idenfier
        """
        container = self.db.get_container(id)
        if not container:
            return webob.exc.HTTPOk()

        host_id = container.host_id
        host = self.db.get_host(host_id)
        if not host:
            LOG.error("no such host %s" % host_id)
            return webob.exc.HTTPNotFound()

        host, port = host.host, host.port
        # FIXME: try to catch exceptions and dealing with it.
        response = self.http.delete("http://%s:%s/v1/containers/%s" \
   %(host,port,id))
        return Response(response.status_code)
Esempio n. 5
0
    def create(self, request, body):
        """Create new container and start it."""
        # FIXME(nmg): try to do this with a pythonic way.

        id = body.pop('db_id')
        name = body.pop('name')
        image_id = body.pop('image_id')

        query = self.db.get_image(image_id)
        if not query:
            msg = "image id is invalid"
            raise exception.ImageNotFound(msg)

        image_uuid = query.uuid
        repository = query.name
        tag = query.tag

        env = body.pop('env')
        project_id = body.pop('project_id')
        repos = body.pop('repos')
        branch = body.pop('branch')
        app_type = body.pop('app_type')
        user_id = body.pop('user_id')
        user_key = body.pop('user_key')
        fixed_ip = body.pop('fixed_ip')

        try:
            self._process_task(self._manager.create, id, name, image_id,
                               image_uuid, repository, tag, repos, branch,
                               app_type, env, user_key, fixed_ip, user_id)
        except:
            raise

        return Response(201)
Esempio n. 6
0
    def start(self, request, id):
        """
        Start container according container id. 
      
        :params request: `wsgi.Request`
        :params      id: the container id

        returns: if start succeed, 204 will be returned.
        """
        query = self.db.get_container(id)
        if query.status == states.RUNNING:
            LOG.info("already running,ignore...")
            return Response(204)
    # FIXME(nmg)
        try:
            self._process_task(self._manager.start, id)
        except:
            raise

        return Response(204)
Esempio n. 7
0
    def commit(self, request, body):
        """Commit container to image."""
        # FIXME(nmg)
        repo = body.pop('repo')
        tag = body.pop('tag')
        try:
            self._process_task(self._manager.commit(repo, tag))
        except:
            raise

        return Response(200)
Esempio n. 8
0
 def delete(self, request, id):
     """
     Delete project identified by `id`.
     """
     LOG.info("DELETE +job delete %s" % id)
     try:
         self.db.delete_project(id)
     except IntegrityError, err:
         LOG.error(err)
         LOG.info("DELETE -job delete = ERR")
         return Response(500)
Esempio n. 9
0
    def delete(self, request, id):
        """
        Delete image by id.
        
        :param request: `wsgi.Request` object
        :param id     : image id
        """

        #eventlet.spawn_n(self._manager.delete,id)
        self._process_task(self._manager.delete, id)

        return Response(200)
Esempio n. 10
0
    def destroy(self, request, name):
        """
	Destroy a temporary container by a given name.

        :params name: the temporary container name
	"""
        # FIXME(nmg)
        try:
            self._process_task(self._manager.destroy, name)
        except:
            raise

        return Response(200)
Esempio n. 11
0
 def save_to_db(self, db_id, name, env, project_id, repos, branch, image_id,
                user_id, host_id):
     """Creating db entry for creation"""
     project = self.db.get_project(project_id)
     if not project:
         LOG.error("no such project %s" % project_id)
         return Response(404)
     self.db.add_container(dict(id=db_id,
                                name=name,
                                env=env,
                                repos=repos,
                                branch=branch,
                                image_id=image_id,
                                user_id=user_id,
                                host_id=host_id,
                                status="building"),
                           project=project)
Esempio n. 12
0
    def delete(self, request, id):
        """
	Delete container by container id.
        
        :params request: `wsgi.Request`
        :params id     : container id
	"""
        query = self.db.get_container(id)
        if not query:
            LOG.error("no such container")
            return webob.exc.HttpNotFound()

        try:
            self._process_task(self._manager.delete, id)
        except:
            raise

        return Response(200)
Esempio n. 13
0
    def refresh(self, request, id):
        """
        Refresh code in container. `refresh request` will be 
        send to remote container server for refreshing.
        if send request failed,exception will occured.
        Is it necessary to catch the exception? I don't
        know. 

        :param request: `wsgi.Request` object
        :param id     : container idenfier
        """
        """
        Check if this container is really exists,
        otherwise return 404 not found.
        """
        container = self.db.get_container(id)
        if not container:
            LOG.error("nu such container %s" % id)
            return webob.exc.HTTPNotFound()
        """
        Get host id from container info,
        if host id is None,return 404.
        """
        host_id = container.host_id
        if not host_id:
            LOG.error("container %s has no host_id" % id)
            return webob.exc.HTTPNotFound()
        """
        Get host instance by `host_id`,
        if host instance is None,return 404.
        """
        host = self.db.get_host(host_id)
        if not host:
            LOG.error("no such host")
            return webob.exc.HTTPNotFound()
        """Get ip address and port for host instance."""
        host, port = host.host, host.port
        """send `refresh request` to the host where container on."""
        #FIXME: exception shoud be catched?
        response = self.http.post("http://%s:%s/v1/containers/%s/refresh" \
        % (host,port,id))

        return Response(response.status_code)
Esempio n. 14
0
    def create(self, request, body):
        """create image."""
        name = body.get('name').lower()
        desc = body.get('desc')
        project_id = body.get('project_id')
        repos = body.get('repos')
        branch = body.get('branch')
        user_id = body.get('user_id')
        id = uuid.uuid4().hex

        project = self.db.get_project(project_id)
        if not project:
            LOG.error("no such project %s" % project_id)
            return Response(404)
        """add db entry first."""
        self.db.add_image(dict(id=id,
                               name=name,
                               tag="latest",
                               desc=desc,
                               repos=repos,
                               branch=branch,
                               user_id=user_id,
                               status='building'),
                          project=project)

        #eventlet.spawn_n(self._manager.create,
        #                 id,
        #                 name,
        #                 desc,
        #                 repos,
        #                 branch,
        #                 user_id)

        self._process_task(self._manager.create, id, name, desc, repos, branch,
                           user_id)
        return ResponseObject({"id": id})
Esempio n. 15
0
    def destroy(self, request, id):
        """destroy temporary container for image edit."""
        #eventlet.spawn_n(self._manager.destroy,id)
        self._process_task(self._manager.destroy, id)

        return Response(200)
Esempio n. 16
0
class Controller(Base):
    def __init__(self):
        super(Controller, self).__init__()

        self.http = client.HTTPClient()

    def index(self, request):
        """
        List all images accorind to `project_id`.
        This method returns a dictionary list and each dict contains the following keys:
            - id
            - uuid
            - name
            - tag
            - desc
            - project_id
            - created
            - user_id
            - status
        If no images found, empty list will be returned.
        """
        images = []
        project_id = request.GET.get('project_id')
        if not project_id:
            LOG.error("project_id cannot be None")
            return webob.exc.HTTPNotFound()
        project_instance = self.db.get_project(project_id)
        if project_instance is None:
            LOG.error("no such project %s" % project_id)
            return webob.exc.HTTPNotFound()
        for image_instance in project_instance.images:
            image = {
                'id': image_instance.id,
                'uuid': image_instance.uuid,
                'name': image_instance.name,
                'tag': image_instance.tag,
                'desc': image_instance.desc,
                'project_id': image_instance.project_id,
                'created': isotime(image_instance.created),
                'user_id': image_instance.user_id,
                'status': image_instance.status
            }
            images.append(image)

        return ResponseObject(images)

    def show(self, request, id):
        """
        Show the image detail according to `id`.

        :parmas id: the image id

        This method returns a dictionary with the following keys:
            - id
            - uuid
            - name
            - repos
            - tag 
            - desc
            - project_id
            - created
            - user_id
            - status
        If no image found, empty dictionary will be returned.    
        """
        image = {}
        query = self.db.get_image(id)
        if query is not None:
            image = {
                'id': query.id,
                'uuid': query.uuid,
                'name': query.name,
                'repos': query.repos,
                'tag': query.tag,
                'desc': query.desc,
                'project_id': query.project_id,
                'created': isotime(query.created),
                'user_id': query.user_id,
                'status': query.status
            }

        return ResponseObject(image)

    def create(self, request, body=None):
        """
        For creating image, body should not be None and
        should contains the following params:
            - project_id  the project's id which the image belong to
            - name        the image name
            -desc        the image description
            - repos       the repos contains `Dockerfile`
            - branch      the branch
            - user_id     the user who created the image
        All the above params are not optional and have no default value.
        """
        """This schema is used for data validate"""
        schema = {
            "type":
            "object",
            "properties": {
                "project_id": {
                    "type": "string",
                    "minLength": 32,
                    "maxLength": 64,
                    "pattern": "^[a-zA-Z0-9]*$",
                },
                "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                },
                "desc": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                },
                "repos": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                },
                "branch": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                },
                "user_id": {
                    "type": "string",
                    "minLength": 32,
                    "maxLength": 64,
                    "pattern": "^[a-zA-Z0-9]*$",
                },
            },
            "required":
            ["project_id", "name", "desc", "repos", "branch", "user_id"]
        }
        try:
            self.validator(body, schema)
        except (SchemaError, ValidationError) as ex:
            LOG.error(ex)
            return webob.exc.HTTPBadRequest(explanation="Bad Paramaters")


#if not body:
#    LOG.error('body cannot be empty!')
#    return webob.exc.HTTPBadRequest()

#project_id = body.get('project_id')
#if not project_id:
#    LOG.error('project_id cannot be None!')
#    return webob.exc.HTTPBadRequest()

        limit = QUOTAS.images or _IMAGE_LIMIT
        query = self.db.get_images(project_id)
        if len(query) >= limit:
            LOG.error("images limit exceed,can not created anymore...")
            return webob.exc.HTTPMethodNotAllowed()

        #name = body.get('name',utils.random_str())
        #desc = body.get('desc','')

        #repos = body.get('repos')
        #if not repos:
        #    LOG.error('repos cannot be None!')
        #    return webob.exc.HTTPBadRequest()

        #branch = body.get('branch')
        #if not branch:
        #    LOG.error("branch cannot be None!")
        #    return webob.exc.HTTPBadRequest()

        #user_id = body.get('user_id')
        #if not user_id:
        #    LOG.error('user_id cannot be None!')
        #    return webob.exc.HTTPBadRequest()
        image_service_endpoint = CONF.image_service_endpoint
        if not image_service_endpoint:
            LOG.error("image service endpoint not found!")
            return webob.exc.HTTPNotFound()
        try:
            image = self.http.post(image_service_endpoint, \
      headers={'Content-Type':'application/json'}, \
      data=json.dumps(body))
        except exceptions.ConnectionError as ex:
            LOG.error("Connect to remote server Error %s" % ex)
            return webob.exc.HTTPInternalServerError()
        except exceptions.ConnectTimeout as ex:
            LOG.error("Connect to remote server Timeout. %s " % ex)
            return webob.exc.HTTPRequestTimeout()
        except exceptions.MissingSchema as ex:
            LOG.error("The URL schema (e.g. http or https) is missing. %s" %
                      ex)
            return webob.exc.HTTPBadRequest()
        except exceptions.InvalidSchema as ex:
            LOG.error("The URL schema is invalid. %s" % ex)
            return webob.exc.HTTPBadRequest()

        return ResponseObject(image.json())

    def delete(self, request, id):
        """
        Delete image from db and registry.
        This method contains the following three steps:
           1. delete db entry
           2. delete image from private image registry
           3. delete local image
        """
        image_instance = self.db.get_image(id)
        if not image_instance:
            LOG.warning("no such image %s" % id)
            return webob.exc.HTTPNotFound()
        """Delete image from database"""
        self.db.delete_image(id)
        """Delete image from image registry"""
        image_service_endpoint = CONF.image_service_endpoint
        if not image_service_endpoint:
            LOG.error("no image service endpoint found!")
            return webob.exc.HTTPNotFound()

        if not image_service_endpoint.startswith("http://"):
            image_service_endpoint += "http://"

        try:
            response = self.http.delete("%s/%s" % \
   (image_service_endpoint,id))
        except ConnectionError, err:
            LOG.error(err)
            return webob.exc.HTTPInternalServerError()

        return Response(response.status_code)