def do_command_add(self, line): records = line.split(' ') if len(records) != 2: raise DockerfileParseException( 'Use ADD <file> <dir_or_file> instead of ADD %s' % line) file_name = records[0] dir_name = records[1] file_path = self.context_path.joinpath(file_name) target_path = pathlib.Path(dir_name) if not file_path.is_file(): log.error('File (%s) not found' % file_path) exit(-1) if len(self.layers) == 0: top_layer = None else: top_layer = self.layers[-1] filesystem = Driver().create_filesystem(top_layer) image_target_path = filesystem.path.joinpath( target_path.relative_to('/')) if file_path.suffix == '.tar': untar(image_target_path, tar_file_path=file_path) else: cp(file_path, image_target_path) layer = Driver().create_layer(filesystem) config_add_diff(self.config, layer.diff_digest, 'ADD file:%s in /' % file_name) self.layers.append(layer)
def remove_layers(self): log.debug('Start removing image (%s) layers' % self.id) if self.layers is None: raise OCIError('Image (%s) has no layers' % self.id) for layer in reversed(self.layers): try: Driver().remove_image_reference(layer, self.id) Driver().remove_layer(layer) except LayerInUseException as e: log.debug(e.args[0]) self.layers = None log.debug('Finish removing image (%s) layers' % self.id)
def __init__(self, options): log.debug('Start importing (%s)' % options.file) layer = None with tempfile.TemporaryDirectory() as temp_dir_name: if options.file == '-': input_file = os.fdopen(sys.stdin.fileno(), 'rb') else: try: input_file = urlopen(options.file) except ValueError: input_file = open(options.file, 'rb') rootfs_tar_path = pathlib.Path(temp_dir_name, 'rootfs.tar') with rootfs_tar_path.open('wb') as output_file: log.debug('Start copying (%s) to (%s)', options.file, str(rootfs_tar_path)) shutil.copyfileobj(input_file, output_file) log.debug('Finish copying (%s) to (%s)', options.file, str(rootfs_tar_path)) if rootfs_tar_path.is_file(): filesystem = Driver().create_filesystem() untar(filesystem.path, tar_file=input_file) layer = Driver().create_layer(filesystem) if layer is None: log.error('Could not create layer') exit(-1) try: distribution = Distribution() history = '/bin/sh -c #(nop) IMPORTED file:%s in / ' % options.file image = Distribution().create_image(layer=layer, history=history) if options.runc_config is not None: config_file_path = pathlib.Path(options.runc_config) if not config_file_path.is_file(): OCIError('Runc config file (%s) does not exist' % str(config_file_path)) spec = Spec.from_file(config_file_path) process = spec.get('Process') command = process.get('Args') if command is not None: image.set_command(command) environment = process.get('Env') if environment is not None: image.set_environment(environment) working_dir = process.get('Cwd') if working_dir is not None: image.set_working_dir(working_dir) if options.tag is not None: for tag in options.tag: Distribution().add_tag(self.image, tag) except Exception as e: log.error(e.args[0]) exit(-1) log.debug('Finish importing (%s)' % options.file)
def destroy(self): if self.id is None: raise OCIError('Can not destroy image (%s)' % self.id) if len(Driver().get_child_filesystems(self.top_layer())) != 0: raise ImageInUseException() for tag in self.tags: self.remove_tag(tag) self.tags = None self.destroy_manifest()
def create(cls, image, name, command=None, workdir=None): log.debug('Start creating container named (%s) from image (%s)' % (name, image.id)) create_time = datetime.utcnow() os = image.config.get('OS') if os != operating_system(): raise OCIError('Image (%s) operating system (%s) is not supported' % (image.id, os)) arch = image.config.get('Architecture') if arch != architecture(): raise OCIError('Image (%s) operating system (%s) is not supported' % (image.id, os)) while True: container_id = generate_random_sha256() runc_id = container_id[:12] if check_free_runc_id(runc_id): break image_config_config = image.config.get('Config') args = command or image_config_config.get('Cmd') or ['/bin/sh'] env = image_config_config.get('Env') or [] cwd = workdir or image_config_config.get('WorkingDir') or '/' layer = image.top_layer() container_path = pathlib.Path(oci_config['global']['path'], 'containers', container_id) if not container_path.is_dir(): container_path.mkdir(parents=True) rootfs_path = container_path.joinpath('rootfs') root_path = rootfs_path solaris = None if os == 'SunOS': solaris = Solaris(anet=[SolarisAnet()]) root_path = rootfs_path.joinpath('root') filesystem = Driver().create_filesystem(layer) Driver().mount_filesystem(filesystem, container_id, root_path) config = Spec( platform=Platform(os=os, arch=arch), hostname=runc_id, process=Process(terminal=True, user=User(uid=0, gid=0), args=args, env=env, cwd=cwd), root=Root(path=str(rootfs_path), readonly=False), solaris=solaris ) config_file_path = container_path.joinpath('config.json') config.save(config_file_path) runc_create(runc_id, container_path) log.debug('Finish creating container named (%s) from image (%s)' % (name, image.id)) return cls(container_id, name, create_time)
def create(cls, config, layers): image_config = config.get('Config') config.add('Created', datetime.utcnow()) if len(layers) == 0: raise OCIError('Images must have at least one layer') manifest = create_manifest(config, layers) manifest_desciptor = save_manifest(manifest) image_id = manifest_desciptor.get('Digest').encoded() for layer in layers: Driver().add_image_reference(layer, image_id) return cls(image_id, [])
def load_layers(self, path=None): log.debug('Start loading image (%s) layers' % self.id) if self.config is None: raise OCIError('Image (%s) has no config' % self.id) if self.manifest is None: raise OCIError('Image (%s) has no manifest' % self.id) root_fs = self.config.get('RootFS') self.layers = [] for layer_descriptor in self.manifest.get('Layers'): layer_id = layer_descriptor.get('Digest').encoded() log.debug('Loading image (%s) layer (%s)' % (self.id, layer_id)) layer = Driver().get_layer(layer_id) self.layers.append(layer) log.debug('Finish loading image (%s) layers' % self.id)
def destroy(self, remove_filesystem=True): container_id = self.id log.debug('Start destroying container (%s)' % container_id) container_status = self.status() if container_status != 'exited': self.delete_container() Driver().unmount_filesystem(self.id, remove=remove_filesystem) container_path = pathlib.Path(oci_config['global']['path'], 'containers', self.id) rm(container_path.joinpath('config.json')) rootfs_path = pathlib.Path(self.config.get('Root').get('Path')) if self.config.get('Platform').get('OS') == 'SunOS': rm(rootfs_path.joinpath('root')) rm(rootfs_path) rm(container_path) self.config = None self.id = None self.name = None self.create_time = None log.debug('Finish destroying container (%s)' % container_id)