def create_container(self, image, command, environment, detach, network_disabled): # Note: There is no 'docker run' in the docker-pyhton api, it uses a derivative of # 'docker create' and 'docker run' - we can use 'docker run' to create what we need cmd = ['docker', 'run'] if len(environment) > 0: for env in environment: cmd.append('-e') cmd.append(env) if detach: cmd.append('-d') # MAKE SURE THIS SHIT WORKS IN LATER DOCKER VERSIONS (MAY HAVE CHANGED TO --network) if network_disabled: cmd.append('--net=none') cmd.append(image) cmd.append(command) r = subp(cmd) if r.return_code != 0: raise DockerError('Unable to create docker image %s' % image) # return the id of the new container return r.stdout.strip()
def inspect(self, obj_id): # returns dict representation of "docker inspect ID" cmd = ['docker', 'inspect', obj_id] r = subp(cmd) if r.return_code != 0: raise Exception('Unable to inspect object: %s' % obj_id) return json.loads(r.stdout)[0]
def _mount_overlay(self, identifier): """ OverlayFS mount backend. """ cid = self._identifier_as_cid(identifier) cinfo = self.client.inspect(cid) ld, ud, wd = '', '', '' try: ld = cinfo['GraphDriver']['Data']['lowerDir'] ud = cinfo['GraphDriver']['Data']['upperDir'] wd = cinfo['GraphDriver']['Data']['workDir'] except: ld, ud, wd = DockerMount._no_gd_api_overlay(cid) options = ['ro', 'lowerdir=' + ld, 'upperdir=' + ud, 'workdir=' + wd] optstring = ','.join(options) cmd = ['mount', '-t', 'overlay', '-o', optstring, 'overlay', self.mountpoint] status = subp(cmd) if status.return_code != 0: self._cleanup_container(cinfo) raise MountError('Failed to mount OverlayFS device.\n%s' % status.stderr.decode(sys.getdefaultencoding())) return cid
def getDmsetupLs(): cmd = ['dmsetup', 'ls'] r = subp(cmd) if r.return_code != 0: print r.stderr return -1 return r.stdout
def _get_fs(thin_pathname): """ Returns the file system type (xfs, ext4) of a given device """ cmd = ['lsblk', '-o', 'FSTYPE', '-n', thin_pathname] fs_return = subp(cmd) return fs_return.stdout.strip()
def remove_image(self, iid, noprune=False): # removes image iid cmd = ['docker', 'rmi', iid] if noprune: cmd.append('--no-prune') r = subp(cmd) if r.return_code != 0: raise DockerError('Unable to remove docker image %s' % iid)
def unmount_path(path, force=False): """ Unmounts the directory specified by path. """ r = subp(['umount', path]) if not force: if r.return_code != 0: raise ValueError(r.stderr)
def remove_thin_device(name, force=False): """ Destroys a thin device via subprocess call. """ cmd = ['dmsetup', 'remove', '--retry', name] r = subp(cmd) if not force: if r.return_code != 0: raise MountError('Could not remove thin device:\n%s' % r.stderr.decode(sys.getdefaultencoding()).split("\n")[0])
def _is_device_active(device): """ Checks dmsetup to see if a device is already active """ cmd = ['dmsetup', 'info', device] dmsetup_info = subp(cmd) for dm_line in dmsetup_info.stdout.split("\n"): line = dm_line.split(':') if ('State' in line[0].strip()) and ('ACTIVE' in line[1].strip()): return True return False
def _activate_thin_device(name, dm_id, size, pool): """ Provisions an LVM device-mapper thin device reflecting, DM device id 'dm_id' in the docker pool. """ table = '0 %d thin /dev/mapper/%s %s' % (int(size) // 512, pool, dm_id) cmd = ['dmsetup', 'create', name, '--table', table] r = subp(cmd) if r.return_code != 0: raise MountError('Failed to create thin device: %s' % r.stderr.decode(sys.getdefaultencoding()))
def get_dev_at_mountpoint(mntpoint): """ Retrieves the device mounted at mntpoint, or raises MountError if none. """ results = subp(['findmnt', '-o', 'SOURCE', mntpoint]) if results.return_code != 0: raise MountError('No device mounted at %s' % mntpoint) stdout = results.stdout.decode(sys.getdefaultencoding()) return stdout.replace('SOURCE\n', '').strip().split('\n')[-1]
def dm_pool(self): # ONLY FOR DEVICEMAPPER # returns the docker-pool docker is using cmd = ['docker', 'info'] r = subp(cmd) if r.return_code != 0: raise Exception('Unable to get docker info') for line in r.stdout.strip().split('\n'): if line.strip().startswith('Pool Name'): pre, _, post = line.partition(':') return post.strip() raise Exception('Unable to get docker pool name')
def driver(self): # returns the storage driver docker is using cmd = ['docker', 'info'] r = subp(cmd) if r.return_code != 0: raise Exception('Unable to get docker info') for line in r.stdout.strip().split('\n'): if line.startswith('Storage Driver'): pre, _, post = line.partition(':') return post.strip() raise Exception('Unable to get docker storage driver')
def commit(self, cid): cmd = ['docker', 'commit'] cmd.append('-c') cmd.append('LABEL \'io.projectatomic.Temporary\': \'true\'') cmd.append(cid) r = subp(cmd) if r.return_code != 0: raise DockerError('Unable to commit docker container %s' % cid) # return newly created image id return r.stdout.strip()
def mount_path(source, target, bind=False): """ Subprocess call to mount dev at path. """ cmd = ['mount'] if bind: cmd.append('--bind') cmd.append(source) cmd.append(target) r = subp(cmd) if r.return_code != 0: raise MountError('Could not mount docker container:\n' + ' '.join(cmd) + '\n%s' % r.stderr.decode(sys.getdefaultencoding()))
def containers(self, all=False, quiet=False): # returns a list of dicts, each dict is an containers's information # except when quiet is used - which returns a list of container ids # dict keys: # Status # Created # Image # Labels # NetworkSettings # HostConfig # ImageID # Command # Names # Id # Ports cmd = ['docker', 'ps', '-q'] if all: cmd.append("-a") r = subp(cmd) if r.return_code != 0: raise Exception('Unable to get docker containers') containers = r.stdout.strip().split('\n') if quiet: return containers else: conts = [] for i in containers: inspec = self.inspect(i) dic = {} dic['Status'] = inspec['State']['Status'] dic['Created'] = inspec['Created'] dic['Image'] = inspec['Config']['Image'] dic['Labels'] = inspec['Config']['Labels'] dic['NetworkSettings'] = inspec['NetworkSettings'] dic['HostConfig'] = inspec['HostConfig'] dic['ImageID'] = inspec['Image'] dic['Command'] = inspec['Config']['Cmd'] dic['Names'] = inspec['Name'] dic['Id'] = inspec['Id'] dic['Ports'] = inspec['NetworkSettings']['Ports'] conts.append(dic) return conts
def images(self, all=False, quiet=False): # returns a list of dicts, each dict is an image's information # except when quiet is used - which returns a list of image ids # dict keys: # Created # Labels # VirtualSize # ParentId # RepoTags # RepoDigests # Id # Size # Adding --no-trunc to ensure we get full ID's if any quiet is True cmd = ['docker', 'images', '-q', '--no-trunc'] if all: cmd.append("-a") r = subp(cmd) if r.return_code != 0: raise Exception('Unable to get docker images') images = r.stdout.strip().split('\n') if quiet: return images else: ims = [] for i in images: inspec = self.inspect(i) dic = {} dic['Created'] = inspec['Created'] if inspec['Config']: dic['Labels'] = inspec['Config']['Labels'] else: dic['Labels'] = {} dic['VirtualSize'] = inspec['VirtualSize'] dic['ParentId'] = inspec['Parent'] dic['RepoTags'] = inspec['RepoTags'] dic['RepoDigests'] = inspec['RepoDigests'] dic['Id'] = inspec['Id'] dic['Size'] = inspec['Size'] ims.append(dic) return ims
def remove_container(self, cid): # removes container cid cmd = ['docker', 'rm', cid] r = subp(cmd) if r.return_code != 0: raise DockerError('Unable to remove docker container %s' % cid)
def __init__(self): cmd = ['docker', '-v'] r = subp(cmd) if r.return_code != 0: raise Exception('Unable to communicate with the docker server')