def index(self, request): """ List all repos by `project_id`. This method returns a dictionary list and each dict contains the following keys: - id - repo_path - created If no repos was found, a empty list will be returned. """ repos = [] project_id = request.GET.get('project_id') project = self.db.get_project(project_id) if not project: LOG.error("no such project %s" % project_id) return webob.exc.HTTPNotFound() for item in project.repos: repo = { 'id': item.id, 'repo_path': item.repo_path, 'created': isotime(item.created), } repos.append(repo) return ResponseObject(repos)
def index(self, request): """ List all users according to `project_id`. This method returns a dictionary list and each dict contains the following keys: - id the unique 64 bytes uuid - name the user name - email user's email address - role_id user's role_id - created when user be added If no use found, empty list will be returned. """ users = [] project_id = request.GET.get('project_id') project = self.db.get_project(project_id) for item in project.users: user = { 'id': item.id, 'name': item.name, 'email': item.email, 'role_id': item.role_id, 'created': isotime(item.created), } users.append(user) return ResponseObject(users)
def commit(self, request): """Commit container to a New image.""" repo = request.GET.pop('repo') tag = request.GET.pop('tag') ctn = request.GET.pop('ctn') id = request.GET.pop('id') project_id = request.GET.pop('proj_id') 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() 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: data = { "repository": repo, "tag": tag, "container_id": ctn, "id": id, "project_id": project_id } response = self.http.post( "%s/commit" % image_service_endpoint, headers={'Content-Type': 'application/json'}, data=json.dumps(data)) except: raise return ResponseObject(response.json())
def show(self, request, id): """ Show the use detail according to user `id`. :params id: the user id This method returns a dictionary with the following keys: - id unique 64 bytes uuid - name user's name - email user's email address - role_id user's role_id, which identified the current user as super-user or normal-user. - projects the project lists the user belong to - created when the user be added If no user found, empty dictionary will be returned. """ query = self.db.get_user(id) if query is None: LOG.error("no such user %s" % id) return ResponseObject({'projects': []}) projects_list = [] project_instances = query.projects for project in project_instances: project = { "id": project.id, "name": project.name, "desc": project.desc, "created": isotime(project.created) } projects_list.append(project) user = { 'id': query.id, 'name': query.name, 'email': query.email, 'role_id': query.role_id, 'projects': projects_list, 'created': isotime(query.created) } return ResponseObject(user)
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})
def baseimage(self, request): """ This method used for getting the baseimage """ base_image_list = [] image_instances = self.db.get_base_images() for instance in image_instances: image = { "id": instance.id, "repository": instance.repository, "tag": instance.tag } base_image_list.append(image) return ResponseObject(base_image_list)
def destroy(self, request, id): """Destroy temporary containers for image online edit.""" 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.post("%s/%s/destroy" % (image_service_endpoint, id)) except: raise return ResponseObject(response.json())
def edit(self, request, id): """ Edit image online. This method not used any more. """ 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.get("%s/%s/edit" % (image_service_endpoint, id)) except: raise return ResponseObject(response.json())
def index(self, request): """ List all containers on all container nodes according to `project_id` and `user_id`. This method returns a dictionary list and each dict contains the following keys: - id - name - repos - branch - image - network - created - status If no container found, empty list will be returned. """ containers = [] project_id = request.GET.get('project_id') user_id = request.GET.get('user_id') query = self.db.get_containers(project_id, user_id) for item in query: container = { 'id': item.id, 'name': item.name, 'repos': item.repos, 'branch': item.branch, 'image_id': item.image_id, 'network': item.fixed_ip, 'created': timeutils.isotime(item.created), 'status': item.status, } container.setdefault("image", "") """Get the image name and tag by the `image_id`. if the image not found, use the default.""" image_id = item.image_id image_instance = self.db.get_image(image_id) if image_instance: image = "%s:%s" % (image_instance.name, image_instance.tag) container.update({"image": image}) containers.append(container) return ResponseObject(containers)
def show(self, request, id): """ Show the container info according by container's id `id`. This method returns a dictionary with following keys: - id - name - uuid - env - project_id - repos - branch - image_id - network - created - user_id - host_id - status If no container found, empty dictionary will returned. """ container = {} query = self.db.get_container(id) if query is not None: container = { 'id': query.id, 'name': query.name, 'uuid': query.uuid, 'env': query.env, 'project_id': query.project_id, 'repos': query.repos, 'branch': query.branch, 'image_id': query.image_id, 'network': query.fixed_ip, 'created': timeutils.isotime(query.created), 'user_id': query.user_id, 'host_id': query.host_id, 'status': query.status, } return ResponseObject(container)
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 repo detail according repo `id`. This method returns a dictionary with following keys: - id - repo_path - project_id - created If no repos was found, a empty dictionary will be returned. """ query = self.db.get_repo(id) if query is None: return {} repo = { 'id': query.id, 'repo_path': query.repo_path, 'project_id': query.project_id, 'created': isotime(query.created) } return ResponseObject(repo)
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 index(self, request): """ List all projects. This method returns a dictionary list and each dict containers the following keys: - id - name - desc - created If no projects found, empty list will be returned. """ projects = [] project_instances = self.db.get_projects() if project_instances: for instance in project_instances: project = { 'id': instance.id, 'name': instance.name, 'desc': instance.desc, 'created': isotime(instance.created) } projects.append(project) return ResponseObject(projects)
def edit(self, request, id): """edit image online. this method is not very correct,change this if you can.""" """if HTTP_HOST is localhost,this will be failed,so use CONF.host instead. http_host=request.environ['HTTP_HOST'].rpartition(":")[0] """ http_host = CONF.host name = utils.random_str() port = 17698 image_instance = self.db.get_image(id) if image_instance: image_uuid = image_instance.uuid kwargs = {"Image": image_uuid} """this method should not be ina greenthread cause it is beatter to prepare edit before client to connect. TODO: change this if you can. self._manager.edit(kwargs, http_host, name, port) """ #eventlet.spawn_n(self._manager.edit, # kwargs, # http_host, # name, # port) self._process_task(self._manager.edit, kwargs, http_host, name, port) response = {"url":"http://%s:%s" % \ (http_host,port), "name": name} return ResponseObject(response)
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})
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 create(self, request, body=None): """ For creating container, body should not be None and should contains the following params: - project_id the project's id which the containers belong to - image_id the image's id which used for creation - user_id the user which the container belong to - repos the repos which will be tested - branch the branch which will be tested - env the envrionment which the container belong to(eg.DEV/QA/STAG/PUB/PROD) - user_key the user's public key which will be inject to container - zone_id the zone's id which the container belong to(eg.BJ/CD) All the above parmas 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]*$", }, "image_id": { "type": "string", "minLength": 32, "maxLength": 64, "pattern": "^[a-zA-Z0-9]*$", }, "user_id": { "type": "string", "minLength": 32, "maxLength": 64, "pattern": "^[a-zA-Z0-9]*$", }, "repos": { "type": "string", "minLength": 1, "maxLength": 255, }, "branch": { "type": "string", "minLength": 1, "maxLength": 255, }, "env": { "type": "string", "minLength": 1, "maxLength": 255, }, "user_key": { "type": "string", "minLength": 1, "maxLength": 255, }, "zone_id": { "type": "string", "minLength": 1, "maxLength": 255, }, }, "required": [ "project_id", "image_id", "user_id", "repos", "branch", "env", "user_key", "zone_id" ] } try: self.validator(body, schema) except (SchemaError, ValidationError) as ex: LOG.error(ex) return webob.exc.HTTPBadRequest(explanation="Bad Paramaters") """Limit check""" limit = QUOTAS.containers or _CONTAINER_LIMIT query = self.db.get_containers(project_id, user_id) if len(query) >= limit: msg = 'container limit exceeded!!!' LOG.error(msg) return webob.exc.HTTPForbidden(explanation=msg) """Call the scheduler to decide which host the container will be run on. """ # TODO(nmg): This should be modified to use rpc call not function call. try: instance = self._scheduler.run_instance(project_id, user_id, image_id, repos, branch, env, user_key, zone_id) except exception.NoValidHost: raise return ResponseObject(instance)
def show(self, request, id): """ Show project detail according to project `id`. This method returns a dictionary with following keys: - id - name - desc - created - users - repos - images - containers If no project found, empty dictionary will be returned. """ project_instance = self.db.get_project(id) if project_instance is None: return {} """get project user list.""" user_list = [] for user_instance in project_instance.users: user = { "id": user_instance.id, "name": user_instance.name, "email": user_instance.email, "role_id": user_instance.role_id, "created": isotime(user_instance.created) } user_list.append(user) """"get project repo list.""" repo_list = [] for repo_instance in project_instance.repos: repo = { "id": repo_instance.id, "repo_path": repo_instance.repo_path, "created": isotime(repo_instance.created) } repo_list.append(repo) """"get project image list.""" image_list = [] 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 } image_list.append(image) """Get containes list""" container_list = [] for item in project_instance.containers: container = { 'id': item.id, 'name': item.name, 'uuid': item.uuid, 'env': item.env, 'project_id': item.project_id, 'repos': item.repos, 'branch': item.branch, 'image_id': item.image_id, 'network': item.network, 'created': item.created, 'user_id': item.user_id, 'host_id': item.host_id, 'status': item.status } container_list.append(container) project = { "id": project_instance.id, "name": project_instance.name, "desc": project_instance.desc, "created": isotime(project_instance.created), "users": user_list, "repos": repo_list, "images": image_list, "containers": container_list } return ResponseObject(project)