def create(self, id, name, desc, repos, branch, user_id): """create new image.""" LOG.info("BUILD +job build %s" % name) repo_name = os.path.basename(repos) #user_home = os.path.join("/home",user_id) user_home = os.path.join(os.path.expandvars('$HOME'), user_id) if not os.path.exists(user_home): os.mkdir(user_home) if utils.repo_exist(user_id, repo_name): try: self.mercurial.pull(user_home, repos) except: LOG.error("pull %s failed!" % repos) self.db.update_image(id, status="error") raise else: try: self.mercurial.clone(user_home, repos) except: LOG.error("clone %s failed!" % repos) self.db.update_image(id, status="error") raise self.mercurial.update(user_home, repos, branch) tar_path = utils.make_zip_tar(os.path.join(user_home, repo_name)) with open(tar_path, 'rb') as data: status = self.driver.build(name, data) if status == 404: LOG.error("request URL not Found!") LOG.info("BUILD -job build %s = ERR" % name) return if status == 200: LOG.info("BUILD -job build %s = OK" % name) """update db entry if successful build.""" status, json = self.driver.inspect(name) uuid = json.get('Id') self.db.update_image(id, uuid=uuid) """ tag image into repositories if successful build.""" LOG.info("TAG +job tag %s" % id) tag_status, tag = self.driver.tag(name) LOG.info("TAG -job tag %s" % id) if tag_status == 201: """push image into repositories if successful tag.""" LOG.info("PUSH +job push %s" % tag) push_status = self.driver.push(tag) if push_status == 200: LOG.info("PUSH -job push %s = OK" % tag) """update db entry if successful push.""" self.db.update_image(id, status="ok") else: self.db.update_image(id, status="error") LOG.info("PUSH -job push %s = ERR" % tag) if status == 500: self.db.update_image(id, status="error") LOG.error("image {} create failed!".format(name)) LOG.info("BUILD -job build %s = ERR" % name)
def create(self, id, name, image_id, image_uuid, repository, tag, repos, branch, app_type, app_env, ssh_key, fixed_ip, user_id): """Create new container and start it. There are three steps to do this: 1. Pull image from docker registry. 2. Create container use the specified image. 3. Start container. """ LOG.info("CREATE +job create %s" % id) """Pull Specified Imag From Docker Registry.""" LOG.info("pull image %s from registry..." % image_id) status = self.driver.pull_image(repository, tag) if status == 404: LOG.error("pull failed,no registry found!") self.db.update_container(id, status="error") return webob.exc.HTTPNotFound() if status == 500: LOG.error("pull failed,internal server error!") self.db.update_container(id, status="error") return webob.exc.HTTPInternalServerError() """Check if the image was pulled successful.""" resp = self.driver.inspect_image(image_uuid) if resp.status_code == 404: msg = "pull image failed!" LOG.error(msg) return webob.exc.HTTPNotFound(explanation=msg) LOG.info("pull image succeed!") """ Generate arguments for container creation. """ port = resp.json()['Config']['ExposedPorts'] kwargs = { 'Hostname': '', 'User': '', 'Memory': '', 'MemorySwap': '', 'AttachStdin': False, 'AttachStdout': False, 'AttachStderr': False, 'PortSpecs': [], 'Tty': True, 'OpenStdin': True, 'StdinOnce': False, 'Env': ["REPO_PATH=%s" % repos, "BRANCH=%s" % branch, "APP_TYPE=%s" % app_type, "APP_ENV=%s" % app_env, "SSH_KEY=%s" % ssh_key], 'Cmd': ["/opt/start.sh"], 'Dns': None, 'Image': image_uuid, 'Volumes': {}, 'VolumesFrom': '', 'ExposedPorts': port, "RestartPolicy": {"Name": "always"} } """Invork docker remote api to create container.""" resp = self.driver.create(name, kwargs) if resp.status_code == 201: """Update container status to ``created``""" uuid = resp.json()['Id'] self.db.update_container(id, uuid=uuid, status="created") """ Clone or Pull code before container start. This method contains the following two steps: 1. Create code and logs directory for each container. 2. Clone or Pull the specified code and update to the specified branch. """ self.db.update_container(id, uuid=uuid, status="init") short_uuid = uuid[:12] root_path = utils.create_root_path(user_id, short_uuid) log_path = utils.create_log_path(root_path) repo_name = os.path.basename(repos) if utils.repo_exist(root_path, repo_name): try: self.mercurial.pull(root_path, repos) except: raise else: try: self.mercurial.clone(root_path, repos) except: raise try: self.mercurial.update(root_path, repos, branch) except: raise www_path = ["/home/www", "/home/jm/www"] log_pathes = ["/home/jm/logs", "/home/logs"] kwargs = { 'Binds': ['%s:%s' % (root_path, www_path[0]), '%s:%s' % (root_path, www_path[1]), '%s:%s' % (log_path, log_pathes[0]), '%s:%s' % (log_path, log_pathes[1]), ], 'Dns': [CONF.dns], } """ Start container and update db status. """ status = self.driver.start(uuid, kwargs) if status == 204: """If start container succeed, inject fixed ip addr to container""" network = self.network.get_fixed_ip() """ Add db entry immediately to prevent this fixed ip be used again. """ self.db.add_network(dict(container_id=id, fixed_ip=network)) """Set fixed ip to container""" try: nwutils.set_fixed_ip(uuid, network) except: LOG.error("Set fixed ip %s to container %s failed" % (network, uuid)) """Cleanup db entry for ip reuse""" self.db.delete_network(id) raise """Update container's network""" self.db.update_container(id, fixed_ip=network) """Update container's status""" self.db.update_container(id, status="running") if status == 500: LOG.error("start container %s error" % uuid) self.db.update_container(id, status="error") if resp.status_code == 500: self.db.update_container(id, status='error') raise web.exc.HTTPInternalServerError() if resp.status_code == 404: LOG.error("no such image %s" % image_uuid) return if resp.status_code == 409: self.db.update_container(id, status='error') LOG.error("CONFLICT!!!") return LOG.info("CREATE -job create %s = OK" % id)
def create(self, id, name, image_id, image_uuid, repository, tag, repos, branch, app_type, app_env, ssh_key, fixed_ip, user_id): """Create new container and start it. There are three steps to do this: 1. Pull image from docker registry. 2. Create container use the specified image. 3. Start container. """ LOG.info("CREATE +job create %s" % id) """Pull Specified Imag From Docker Registry.""" LOG.info("pull image %s from registry..." % image_id) status = self.driver.pull_image(repository, tag) if status == 404: LOG.error("pull failed,no registry found!") self.db.update_container(id, status="error") return webob.exc.HTTPNotFound() if status == 500: LOG.error("pull failed,internal server error!") self.db.update_container(id, status="error") return webob.exc.HTTPInternalServerError() """Check if the image was pulled successful.""" resp = self.driver.inspect_image(image_uuid) if resp.status_code == 404: msg = "pull image failed!" LOG.error(msg) return webob.exc.HTTPNotFound(explanation=msg) LOG.info("pull image succeed!") """ Generate arguments for container creation. """ port = resp.json()['Config']['ExposedPorts'] kwargs = { 'Hostname': '', 'User': '', 'Memory': '', 'MemorySwap': '', 'AttachStdin': False, 'AttachStdout': False, 'AttachStderr': False, 'PortSpecs': [], 'Tty': True, 'OpenStdin': True, 'StdinOnce': False, 'Env': [ "REPO_PATH=%s" % repos, "BRANCH=%s" % branch, "APP_TYPE=%s" % app_type, "APP_ENV=%s" % app_env, "SSH_KEY=%s" % ssh_key ], 'Cmd': ["/opt/start.sh"], 'Dns': None, 'Image': image_uuid, 'Volumes': {}, 'VolumesFrom': '', 'ExposedPorts': port, "RestartPolicy": { "Name": "always" } } """Invork docker remote api to create container.""" resp = self.driver.create(name, kwargs) if resp.status_code == 201: """Update container status to ``created``""" uuid = resp.json()['Id'] self.db.update_container(id, uuid=uuid, status="created") """ Clone or Pull code before container start. This method contains the following two steps: 1. Create code and logs directory for each container. 2. Clone or Pull the specified code and update to the specified branch. """ self.db.update_container(id, uuid=uuid, status="init") short_uuid = uuid[:12] root_path = utils.create_root_path(user_id, short_uuid) log_path = utils.create_log_path(root_path) repo_name = os.path.basename(repos) if utils.repo_exist(root_path, repo_name): try: self.mercurial.pull(root_path, repos) except: raise else: try: self.mercurial.clone(root_path, repos) except: raise try: self.mercurial.update(root_path, repos, branch) except: raise www_path = ["/home/www", "/home/jm/www"] log_pathes = ["/home/jm/logs", "/home/logs"] kwargs = { 'Binds': [ '%s:%s' % (root_path, www_path[0]), '%s:%s' % (root_path, www_path[1]), '%s:%s' % (log_path, log_pathes[0]), '%s:%s' % (log_path, log_pathes[1]), ], 'Dns': [CONF.dns], } """ Start container and update db status. """ status = self.driver.start(uuid, kwargs) if status == 204: """If start container succeed, inject fixed ip addr to container""" network = self.network.get_fixed_ip() """ Add db entry immediately to prevent this fixed ip be used again. """ self.db.add_network(dict(container_id=id, fixed_ip=network)) """Set fixed ip to container""" try: nwutils.set_fixed_ip(uuid, network) except: LOG.error("Set fixed ip %s to container %s failed" % (network, uuid)) """Cleanup db entry for ip reuse""" self.db.delete_network(id) raise """Update container's network""" self.db.update_container(id, fixed_ip=network) """Update container's status""" self.db.update_container(id, status="running") if status == 500: LOG.error("start container %s error" % uuid) self.db.update_container(id, status="error") if resp.status_code == 500: self.db.update_container(id, status='error') raise web.exc.HTTPInternalServerError() if resp.status_code == 404: LOG.error("no such image %s" % image_uuid) return if resp.status_code == 409: self.db.update_container(id, status='error') LOG.error("CONFLICT!!!") return LOG.info("CREATE -job create %s = OK" % id)