Exemplo n.º 1
0
 def remove(self, force=False, recursive=False):
     """Delete files or directories"""
     if not os.path.lexists(self.filename):
         pass
     elif self.filename.count("/") < 2:
         Msg().err("Error: delete pathname too short: ", self.filename)
         return False
     elif self.uid() != HostInfo.uid:
         Msg().err("Error: delete not owner: ", self.filename)
         return False
     elif (not force) and (not self._is_safe_prefix(self.filename)):
         Msg().err("Error: delete outside of directory tree: ",
                   self.filename)
         return False
     elif os.path.isfile(self.filename) or os.path.islink(self.filename):
         try:
             os.remove(self.filename)
         except (IOError, OSError):
             Msg().err("Error: deleting file: ", self.filename)
             return False
     elif os.path.isdir(self.filename):
         if recursive:
             status = self._removedir()
         else:
             status = self.rmdir()
         if not status:
             Msg().err("Error: deleting directory: ", self.filename)
             return False
     if self.filename in dict(FileUtil.tmptrash):
         del FileUtil.tmptrash[self.filename]
     return True
Exemplo n.º 2
0
 def _check_exposed_ports(self):
     """TCP/UDP ports < 1024 in ExposedPorts JSON metadata
     The exposed ports format is  ExposedPorts:{ "80/tcp":{}, }
     """
     mapped_ports = self._get_portsmap()
     exposes_priv = False
     exposes_port = False
     for port in self.opt["portsexp"]:
         try:
             port_number = int(port.split("/")[0])
             exposes_port = True
         except (ValueError, TypeError):
             pass
         else:
             if port_number < 1024:
                 if port_number in list(mapped_ports.keys()):
                     if mapped_ports[port_number] >= 1024:
                         continue
                 exposes_priv = True
     if exposes_priv and HostInfo.uid != 0:
         Msg().err("Error: this container exposes privileged TCP/IP ports")
         return False
     if exposes_port:
         Msg().out("Warning: this container exposes TCP/IP ports", l=Msg.WAR)
     return True
Exemplo n.º 3
0
 def load(self, imagefile, imagerepo=None):
     """Generic load of image tags to a file"""
     if not os.path.exists(imagefile) and imagefile != '-':
         Msg().err("Error: image file does not exist:", imagefile)
         return False
     tmp_imagedir = FileUtil("load").mktmp()
     try:
         os.makedirs(tmp_imagedir)
     except (IOError, OSError):
         return False
     if not self._untar_saved_container(imagefile, tmp_imagedir):
         Msg().err("Error: failed to extract container:", imagefile)
         FileUtil(tmp_imagedir).remove(recursive=True)
         return False
     imagetype = self._get_imagedir_type(tmp_imagedir)
     if imagetype == "Docker":
         repositories = DockerLocalFileAPI(self.localrepo).load(
             tmp_imagedir, imagerepo)
     elif imagetype == "OCI":
         repositories = OciLocalFileAPI(self.localrepo).load(
             tmp_imagedir, imagerepo)
     else:
         repositories = []
     FileUtil(tmp_imagedir).remove(recursive=True)
     return repositories
Exemplo n.º 4
0
    def _check_executable(self):
        """Check if executable exists and has execute permissions"""
        if self.opt["entryp"] and is_genstr(self.opt["entryp"]):
            self.opt["entryp"] = self.opt["entryp"].strip().split(' ')
        if isinstance(self.opt["entryp"], list):
            if self.opt["cmd"]:                                     # and cmd
                cmd_args = self.opt["cmd"]
                self.opt["cmd"] = self.opt["entryp"]
                self.opt["cmd"].extend(cmd_args)   # cmd=args entryp
            else:
                self.opt["cmd"] = self.opt["entryp"]
        if not self.opt["cmd"]:
            self.opt["cmd"] = Config.conf['cmd']
            Msg().err("Warning: no command assuming:", self.opt["cmd"],
                      l=Msg.WAR)
        exec_name = self.opt["cmd"][0]            # exec pathname without args
        if exec_name.startswith("./") or exec_name.startswith("../"):
            exec_name = self.opt["cwd"] + '/' + exec_name

        path = self.opt["env"].getenv("PATH")
        # DEBUG
        exec_name = FileUtil(exec_name).find_exec(path, self.container_root,
                                                  self.opt["vol"],
                                                  self.opt["cwd"])
        if exec_name:
            return self.container_root + '/' + exec_name
        Msg().err("Error: command not found or has no execute bit set: ",
                  self.opt["cmd"])
        return ""
Exemplo n.º 5
0
 def verify_image(self):
     """Verify the structure of an image repository"""
     Msg().out("Info: loading structure", l=Msg.INF)
     structure = self._load_structure(self.cur_tagdir)
     if not structure:
         Msg().err("Error: load of image tag structure failed")
         return False
     Msg().out("Info: verifying layers", l=Msg.INF)
     status = True
     if "ancestry" in structure and "has_json_f" in structure:
         status = self._verify_image_v1(structure)
     elif "manifest" in structure:
         if "fsLayers" in structure["manifest"]:
             status = self._verify_image_v2_s1(structure)
         elif "layers" in structure["manifest"]:
             status = self._verify_image_v2_s2(structure)
     for layer_id in structure["repolayers"]:
         if "layer_f" not in structure["repolayers"][layer_id]:
             Msg().err("Error: layer file not found in structure", layer_id)
             status = False
             continue
         layer_status = self._verify_layer_file(structure, layer_id)
         if not layer_status:
             status = False
             continue
         Msg().out("Info: layer ok:", layer_id, l=Msg.INF)
     return status
Exemplo n.º 6
0
 def get_v2(self, imagerepo, tag):
     """Pull container with v2 API"""
     files = []
     (hdr_data, manifest) = self.get_v2_image_manifest(imagerepo, tag)
     status = self.curl.get_status_code(hdr_data["X-ND-HTTPSTATUS"])
     if status == 401:
         Msg().err("Error: manifest not found or not authorized")
         return []
     if status != 200:
         Msg().err("Error: pulling manifest:")
         return []
     try:
         if not (self.localrepo.setup_tag(tag)
                 and self.localrepo.set_version("v2")):
             Msg().err("Error: setting localrepo v2 tag and version")
             return []
         self.localrepo.save_json("manifest", manifest)
         Msg().out("Info: v2 layers: %s" % (imagerepo), l=Msg.DBG)
         if "fsLayers" in manifest:
             files = self.get_v2_layers_all(imagerepo, manifest["fsLayers"])
         elif "layers" in manifest:
             if "config" in manifest:
                 manifest["layers"].append(manifest["config"])
             files = self.get_v2_layers_all(imagerepo, manifest["layers"])
         else:
             Msg().err("Error: layers section missing in manifest")
     except (KeyError, AttributeError, IndexError, ValueError, TypeError):
         pass
     return files
Exemplo n.º 7
0
 def test_04_err(self, mock_stderr):
     """Test04 Msg.err()."""
     msg = Msg(Msg.ERR)
     msg.err("111", "222", "333", 444, ('555'))
     self.assertEqual("111 222 333 444 555\n", mock_stderr.getvalue())
     sys.stdout = STDOUT
     sys.stderr = STDERR
Exemplo n.º 8
0
    def clone(self):
        """Clone a container by creating a complete copy
        """
        source_container_dir = self.localrepo.cd_container(self.container_id)
        if not source_container_dir:
            Msg().err("Error: source container not found:", self.container_id)
            return False

        dest_container_id = Unique().uuid(os.path.basename(self.imagerepo))
        dest_container_dir = self.localrepo.setup_container(
            "CLONING", "inprogress", dest_container_id)
        if not dest_container_dir:
            Msg().err("Error: create destination container: setting up")
            return False

        status = FileUtil(source_container_dir).copydir(dest_container_dir)
        if not status:
            Msg().err("Error: creating container:", dest_container_id)
            return False

        if not self._chk_container_root(dest_container_id):
            Msg().out("Warning: check container content:",
                      dest_container_id,
                      l=Msg.WAR)

        return dest_container_id
Exemplo n.º 9
0
 def _load_image_step2(self, structure, imagerepo, tag):
     """Load a container image into a repository mimic docker load"""
     imagetag = imagerepo + ':' + tag
     (json_config_file, layers) = \
             self._get_from_manifest(structure, imagetag)
     if json_config_file:
         layer_id = json_config_file.replace(".json", "")
         json_file = structure["repoconfigs"][json_config_file]["json_f"]
         self._move_layer_to_v1repo(json_file, layer_id, "container.json")
     top_layer_id = self._find_top_layer_id(structure)
     layers = self._sorted_layers(structure, top_layer_id)
     for layer_id in layers:
         Msg().out("Info: adding layer:", layer_id, l=Msg.INF)
         if str(structure["repolayers"][layer_id]["VERSION"]) != "1.0":
             Msg().err("Error: layer version unknown")
             return []
         for layer_item in ("json_f", "layer_f"):
             filename = str(structure["repolayers"][layer_id][layer_item])
             if not self._move_layer_to_v1repo(filename, layer_id):
                 Msg().err("Error: copying %s file %s" %
                           (layer_item[:-2], filename),
                           l=Msg.VER)
                 return []
     self.localrepo.save_json("ancestry", layers)
     if self._imagerepo:
         imagetag = self._imagerepo + ':' + tag
     return [imagetag]
Exemplo n.º 10
0
 def save(self, imagetag_list, imagefile):
     """Save a set of image tags to a file similarly to docker save
     """
     tmp_imagedir = FileUtil("save").mktmp()
     try:
         os.makedirs(tmp_imagedir)
     except (IOError, OSError):
         return False
     structure = dict()
     structure["manifest"] = []
     structure["repositories"] = dict()
     status = False
     for (imagerepo, tag) in imagetag_list:
         status = self._save_image(imagerepo, tag, structure, tmp_imagedir)
         if not status:
             Msg().err("Error: save image failed:", imagerepo + ':' + tag)
             break
     if status:
         self.localrepo.save_json(tmp_imagedir + "/manifest.json",
                                  structure["manifest"])
         self.localrepo.save_json(tmp_imagedir + "/repositories",
                                  structure["repositories"])
         if not FileUtil(tmp_imagedir).tar(imagefile):
             Msg().err("Error: save image failed in writing tar", imagefile)
             status = False
     else:
         Msg().err("Error: no images specified")
     FileUtil(tmp_imagedir).remove(recursive=True)
     return status
Exemplo n.º 11
0
 def _add_device_spec(self, dev_path, mode="rwm"):
     """Add device to the configuration"""
     if not (os.path.exists(dev_path) and dev_path.startswith("/dev/")):
         Msg().err("Error: device not found", dev_path)
         return False
     dev_stat = os.stat(dev_path)
     if stat.S_ISBLK(dev_stat.st_mode):
         dev_type = 'b'
     elif stat.S_ISCHR(dev_stat.st_mode):
         dev_type = 'c'
     else:
         Msg().err("Error: not a device", dev_path)
         return False
     filemode = 0
     if 'r' in mode.lower():
         filemode += 0o444
     if 'w' in mode.lower():
         filemode += 0o222
     if not filemode:
         filemode = 0o666
     if "devices" not in self._container_specjson["linux"]:
         self._container_specjson["linux"]["devices"] = []
     device = {
         "path": dev_path,
         "type": dev_type,
         "major": os.major(dev_stat.st_dev),
         "minor": os.minor(dev_stat.st_dev),
         "fileMode": filemode,
         "uid": HostInfo.uid,
         "gid": HostInfo.gid,
     }
     self._container_specjson["linux"]["devices"].append(device)
     return True
Exemplo n.º 12
0
 def _setup_container_user_noroot(self, user):
     """ Setup user for engines without root support.
     Equivalent to _setup_container_user() for engines without root support.
     """
     host_auth = NixAuthentication()
     (passwd, group) = self._select_auth_files()
     container_auth = NixAuthentication(passwd, group)
     if not user:
         user = HostInfo().username()
     (valid_user, user_id) = self._user_from_str(user,
                                                 host_auth, container_auth)
     if not valid_user:
         Msg().err("Error: invalid syntax for user", user)
         return False
     if self.opt["user"] == "root":
         self.opt["user"] = HostInfo().username()
         self.opt["uid"] = str(HostInfo.uid)
         self.opt["gid"] = str(HostInfo.gid)
     if (self._is_mountpoint("/etc/passwd") or
             self._is_mountpoint("/etc/group")):
         self.opt["hostauth"] = self.opt["containerauth"] = False
         return True
     if self.opt["user"]:
         self.opt["uid"] = str(HostInfo.uid)
         self.opt["gid"] = str(HostInfo.gid)
     else:
         if self.opt["hostauth"] or self.opt["containerauth"]:
             Msg().err("Error: user not found on host")
             return False
         self.opt["user"] = user_id["user"] if "user" in user_id else user
         self.opt["uid"] = user_id["uid"] if "uid" in user_id else ""
         self.opt["gid"] = user_id["gid"] if "gid" in user_id else ""
     self._create_user(container_auth, host_auth)
     return True
Exemplo n.º 13
0
    def create_fromlayer(self, imagerepo, tag, layer_file, container_json):
        """Create a container from a layer file exported by Docker.
        """
        self.imagerepo = imagerepo
        self.tag = tag
        if not self.container_id:
            self.container_id = Unique().uuid(os.path.basename(self.imagerepo))

        if not container_json:
            Msg().err("Error: create container: getting json")
            return False

        container_dir = self.localrepo.setup_container(self.imagerepo,
                                                       self.tag,
                                                       self.container_id)
        if not container_dir:
            Msg().err("Error: create container: setting up")
            return False

        fjson = container_dir + "/container.json"
        self.localrepo.save_json(fjson, container_json)
        status = self._untar_layers([
            layer_file,
        ], container_dir + "/ROOT")
        if not status:
            Msg().err("Error: creating container:", self.container_id)
        elif not self._chk_container_root():
            Msg().out("Warning: check container content:",
                      self.container_id,
                      l=Msg.WAR)

        return self.container_id
Exemplo n.º 14
0
 def set_mode(self, force=False):
     """Set nvidia mode"""
     if not self.container_dir:
         Msg().err("Error: nvidia set mode container dir not found")
         return False
     nvi_host_dir_list = self._find_host_dir()
     nvi_cont_dir = self._find_cont_dir()
     if not nvi_host_dir_list:
         Msg().err("Error: host nvidia libraries not found")
         return False
     if not nvi_cont_dir:
         Msg().err("Error: destination dir for nvidia libs not found")
         return False
     if (not force) and self._installation_exists(nvi_host_dir_list,
                                                  nvi_cont_dir):
         Msg().err("Error: nvidia installation already exists"
                   ", use --force to overwrite")
         return False
     for nvi_host_dir in nvi_host_dir_list:
         lib_list = self._get_nvidia_libs(nvi_host_dir)
         self._copy_files(nvi_host_dir, nvi_cont_dir, lib_list, force)
     self._copy_files('/etc', '/etc', Config.conf['nvi_etc_list'], force)
     self._copy_files('/usr/bin', '/usr/bin', Config.conf['nvi_bin_list'],
                      force)
     FileUtil(self._container_nvidia_set).putdata("", 'w')
     Msg().out("Info: nvidia mode set")
     return True
Exemplo n.º 15
0
 def test_03_out(self, mock_stdout):
     """Test03 Msg.out()."""
     msg = Msg(Msg.MSG)
     msg.out("111", "222", "333", 444, ('555'))
     self.assertEqual("111 222 333 444 555\n", mock_stdout.getvalue())
     sys.stdout = STDOUT
     sys.stderr = STDERR
Exemplo n.º 16
0
 def _run_invalid_options(self):
     """check -p --publish -P --publish-all --net-coop"""
     if self.opt["portsmap"]:
         Msg().out("Warning: this execution mode does not support "
                   "-p --publish", l=Msg.WAR)
     if self.opt["netcoop"]:
         Msg().out("Warning: this execution mode does not support "
                   "-P --netcoop --publish-all", l=Msg.WAR)
Exemplo n.º 17
0
    def run(self, container_id):
        """Execute a Docker container using Fakechroot. This is the main
        method invoked to run the a container with Fakechroot.
          * argument: container_id or name
          * options:  many via self.opt see the help
        """

        # warning root execution not supported
        self._uid_check()

        # setup execution
        exec_path = self._run_init(container_id)
        if not exec_path:
            return 2

        self._run_invalid_options()

        # execution mode and get patcher
        xmode = self.exec_mode.get_mode()
        self._elfpatcher = ElfPatcher(self.localrepo, self.container_id)

        # verify if container pathnames are correct for this mode
        if not self._elfpatcher.check_container_path():
            Msg().out("Warning: container path mismatch, use setup to convert",
                      l=Msg.WAR)

        # set basic environment variables
        self._run_env_set()
        self._fakechroot_env_set()

        # if not --hostenv clean the environment
        self._run_env_cleanup_list()

        # build the actual command
        cmd_l = self._set_cpu_affinity()
        cmd_l.extend([
            "env",
            "-i",
        ])
        cmd_l.extend(self.opt["env"].list())
        if xmode in ("F1", "F2"):
            container_loader = self._elfpatcher.get_container_loader()
            if container_loader:
                cmd_l.append(container_loader)
        cmd_l.extend(self._run_add_script_support(exec_path))
        cmd_l.extend(self.opt["cmd"])
        Msg().out("CMD =", cmd_l, l=Msg.VER)

        # execute
        self._run_banner(self.opt["cmd"][0], '#')
        cwd = FileUtil(self.container_root).cont2host(self.opt["cwd"],
                                                      self.opt["vol"])
        status = subprocess.call(cmd_l, shell=False, close_fds=True, cwd=cwd)
        return status
Exemplo n.º 18
0
 def setup(self):
     """Prepare container for FileBind"""
     if not os.path.isdir(self.container_orig_dir):
         if not FileUtil(self.container_orig_dir).mkdir():
             Msg().err("Error: creating dir:", self.container_orig_dir)
             return False
     if not os.path.isdir(self.container_bind_dir):
         if not FileUtil(self.container_bind_dir).mkdir():
             Msg().err("Error: creating dir:", self.container_bind_dir)
             return False
     return True
Exemplo n.º 19
0
 def _untar_layers(self, tarfiles, destdir):
     """Untar all container layers. Each layer is extracted
     and permissions are changed to avoid file permission
     issues when extracting the next layer.
     """
     if not (tarfiles and destdir):
         return False
     status = True
     gid = str(HostInfo.gid)
     optional_flags = [
         "--wildcards",
         "--delay-directory-restore",
     ]
     for option in optional_flags:
         if not HostInfo().cmd_has_option("tar", option):
             optional_flags.remove(option)
     for tarf in tarfiles:
         if tarf != '-':
             self._apply_whiteouts(tarf, destdir)
         verbose = ''
         if Msg.level >= Msg.VER:
             verbose = 'v'
             Msg().out("Info: extracting:", tarf, l=Msg.INF)
         cmd = [
             "tar",
             "-C",
             destdir,
             "-x" + verbose,
             "--one-file-system",
             "--no-same-owner",
             "--overwrite",
             "--exclude=dev/*",
             "--exclude=etc/udev/devices/*",
             "--no-same-permissions",
             r"--exclude=.wh.*",
         ] + optional_flags + ["-f", tarf]
         if subprocess.call(cmd, stderr=Msg.chlderr, close_fds=True):
             Msg().err("Error: while extracting image layer")
             status = False
         cmd = [
             "find", destdir, "(", "-type", "d", "!", "-perm", "-u=x",
             "-exec", "chmod", "u+x", "{}", ";", ")", ",", "(", "!",
             "-perm", "-u=w", "-exec", "chmod", "u+w", "{}", ";", ")", ",",
             "(", "!", "-perm", "-u=r", "-exec", "chmod", "u+r", "{}", ";",
             ")", ",", "(", "!", "-gid", gid, "-exec", "chgrp", gid, "{}",
             ";", ")", ",", "(", "-name", ".wh.*", "-exec", "rm", "-f",
             "--preserve-root", "{}", ";", ")"
         ]
         if subprocess.call(cmd, stderr=Msg.chlderr, close_fds=True):
             status = False
             Msg().err("Error: while modifying attributes of image layer")
     return status
Exemplo n.º 20
0
    def restore_ld(self):
        """Restore ld.so"""
        elf_loader = self.get_container_loader()
        futil_ldso = FileUtil(self._container_ld_so_orig)
        if futil_ldso.size() <= 0:
            Msg().err("Error: original loader not found or empty")
            return False

        if not futil_ldso.copyto(elf_loader):
            Msg().err("Error: in loader copy or file locked by other process")
            return False

        return True
Exemplo n.º 21
0
 def get_installinfo(self):
     """Get json containing installation info"""
     Msg().out("Info: searching for messages:", l=Msg.VER)
     for url in self._get_mirrors(self._installinfo):
         infofile = self._get_file(url)
         try:
             with open(infofile, 'r') as filep:
                 self._install_json = json.load(filep)
             for msg in self._install_json["messages"]:
                 Msg().out("Info:", msg)
         except (KeyError, AttributeError, ValueError, OSError, IOError):
             Msg().out("Info: no messages:", infofile, url, l=Msg.VER)
         return self._install_json
Exemplo n.º 22
0
    def _copy_files(self, host_src_dir, cont_dst_dir, files_list, force=False):
        """copy or link file to destination creating directories as needed"""
        Msg().out("Source (host) dir ", host_src_dir, l=Msg.DBG)
        Msg().out("Destination (container) dir ", cont_dst_dir, l=Msg.DBG)
        for fname in files_list:
            srcname = host_src_dir + '/' + fname
            dstname = self.container_root + '/' + cont_dst_dir + '/' + fname
            if os.path.isfile(dstname) or os.path.islink(dstname):
                if force:
                    try:
                        os.remove(dstname)
                    except OSError:
                        Msg().err("Error: deleting nvidia file", dstname)
                else:
                    Msg().out("Info: nvidia file already exists",
                              dstname,
                              ", use --force to overwrite",
                              l=Msg.INF)
                    return False

            srcdir = os.path.dirname(srcname)
            dstdir = os.path.dirname(dstname)
            if not os.path.isdir(dstdir):
                try:
                    os.makedirs(dstdir)
                    os.chmod(
                        dstdir,
                        stat.S_IMODE(os.stat(srcdir).st_mode) | stat.S_IRWXU)
                except OSError:
                    Msg().err("Error: creating nvidia dir", dstdir)

            if os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
                Msg().out("Info: is link", srcname, "to", dstname, l=Msg.DBG)
            elif os.path.isfile(srcname):
                shutil.copy2(srcname, dstname)
                Msg().out("Info: is file", srcname, "to", dstname, l=Msg.DBG)
                try:
                    mask = stat.S_IMODE(os.stat(srcname).st_mode) | \
                                        stat.S_IWUSR | stat.S_IRUSR
                    if os.access(srcname, os.X_OK):
                        mask = mask | stat.S_IXUSR
                    os.chmod(dstname, mask)
                except (IOError, OSError) as error:
                    Msg().err("Error: change mask of nvidia file", error)
            else:
                Msg().err("Warn: nvidia file in config not found", srcname)

        Msg().out("Info: nvidia copied", srcname, "to", dstname, l=Msg.DBG)
        return True
Exemplo n.º 23
0
    def export_tofile(self, clone_file):
        """Export a container creating a tar file of the rootfs
        """
        cont_dir = self.localrepo.cd_container(self.container_id)
        if not cont_dir:
            Msg().err("Error: container not found:", self.container_id)
            return False

        status = FileUtil(cont_dir + "/ROOT").tar(clone_file)
        if not status:
            Msg().err("Error: exporting container file system:",
                      self.container_id)

        return self.container_id
Exemplo n.º 24
0
    def clone_tofile(self, clone_file):
        """Create a cloned container tar file containing both the rootfs
        and all udocker control files. This is udocker specific.
        """
        container_dir = self.localrepo.cd_container(self.container_id)
        if not container_dir:
            Msg().err("Error: container not found:", self.container_id)
            return False

        status = FileUtil(container_dir).tar(clone_file)
        if not status:
            Msg().err("Error: export container as clone:", self.container_id)

        return self.container_id
Exemplo n.º 25
0
 def get_v1(self, imagerepo, tag):
     """Pull container with v1 API"""
     Msg().out("Info: v1 image id: %s" % (imagerepo), l=Msg.DBG)
     (hdr_data, images_array) = self.get_v1_repo(imagerepo)
     status = self.curl.get_status_code(hdr_data["X-ND-HTTPSTATUS"])
     if status == 401 or not images_array:
         Msg().err("Error: image not found or not authorized")
         return []
     try:
         endpoint = "http://" + hdr_data["x-docker-endpoints"]
     except KeyError:
         endpoint = self.index_url
     (tags_array) = self.get_v1_image_tags(endpoint, imagerepo)
     image_id = self._get_v1_id_from_tags(tags_array, tag)
     if not image_id:
         Msg().err("Error: image tag not found")
         return []
     if len(image_id) <= 8:
         image_id = self._get_v1_id_from_images(images_array, image_id)
         if not image_id:
             Msg().err("Error: image id not found")
             return []
     if not (self.localrepo.setup_tag(tag)
             and self.localrepo.set_version("v1")):
         Msg().err("Error: setting localrepo v1 tag and version")
         return []
     Msg().out("Info: v1 ancestry", image_id, l=Msg.DBG)
     (dummy, ancestry) = self.get_v1_image_ancestry(endpoint, image_id)
     if not ancestry:
         Msg().err("Error: ancestry not found")
         return []
     self.localrepo.save_json("ancestry", ancestry)
     Msg().out("Info: v1 layers", image_id, l=Msg.DBG)
     files = self.get_v1_layers_all(endpoint, ancestry)
     return files
Exemplo n.º 26
0
 def _select_implementation(self):
     """Select which implementation to use"""
     if GetURLpyCurl().is_available() and not self._curl_exec:
         self._geturl = GetURLpyCurl()
         self.cache_support = True
         Msg().out("Info: using pycurl", l=Msg.DBG)
     elif GetURLexeCurl().is_available():
         self._geturl = GetURLexeCurl()
         Msg().out("Info: using curl executable",
                   self._geturl._curl_exec,
                   l=Msg.DBG)
     else:
         Msg().err("Error: need curl or pycurl to perform downloads")
         raise NameError('need curl or pycurl')
Exemplo n.º 27
0
 def _download(self, url):
     """Download a file """
     download_file = FileUtil("udockertools").mktmp()
     if Msg.level <= Msg.DEF:
         Msg().setlevel(Msg.NIL)
     (hdr, dummy) = self.curl.get(url, ofile=download_file, follow=True)
     if Msg.level == Msg.NIL:
         Msg().setlevel()
     try:
         if "200" in hdr.data["X-ND-HTTPSTATUS"]:
             return download_file
     except (KeyError, TypeError, AttributeError):
         pass
     FileUtil(download_file).remove()
     return ""
Exemplo n.º 28
0
    def unshare(self, flags):
        """Python implementation of unshare"""
        try:
            _unshare = ctypes.CDLL("libc.so.6").unshare
        except OSError:
            Msg().err("Error: in unshare: mapping libc")
            return False

        _unshare.restype = ctypes.c_int
        _unshare.argtypes = (ctypes.c_int, )

        if _unshare(flags) == -1:
            Msg().err("Error: in unshare:", os.strerror(-1))
            return False
        return True
Exemplo n.º 29
0
 def _get_url(self, *args, **kwargs):
     """Encapsulates the call to GetURL.get() so that authentication
     for v1 and v2 repositories can be treated differently.
     Example:
          _get_url(url, ctimeout=5, timeout=5, header=[]):
     """
     url = str(args[0])
     if "RETRY" not in kwargs:
         kwargs["RETRY"] = 3
     if "FOLLOW" not in kwargs:
         kwargs["FOLLOW"] = 3
     kwargs["RETRY"] -= 1
     (hdr, buf) = self.curl.get(*args, **kwargs)
     Msg().out("Info: header: %s" % (hdr.data), l=Msg.DBG)
     Msg().out("Info: buffer: %s" % (buf.getvalue()), l=Msg.DBG)
     status_code = self.curl.get_status_code(hdr.data["X-ND-HTTPSTATUS"])
     if status_code == 200:
         return (hdr, buf)
     if not kwargs["RETRY"]:
         hdr.data["X-ND-CURLSTATUS"] = 13  # Permission denied
         return (hdr, buf)
     auth_kwargs = kwargs.copy()
     if "location" not in hdr.data:
         kwargs["FOLLOW"] = 3
     if "location" in hdr.data and hdr.data['location']:
         if not kwargs["FOLLOW"]:
             hdr.data["X-ND-CURLSTATUS"] = 13
             return (hdr, buf)
         kwargs["FOLLOW"] -= 1
         args = [hdr.data['location']]
         if "header" in auth_kwargs:
             del auth_kwargs["header"]
     elif status_code == 401:
         if "www-authenticate" in hdr.data:
             www_authenticate = hdr.data["www-authenticate"]
             if not "realm" in www_authenticate:
                 return (hdr, buf)
             if 'error="insufficient_scope"' in www_authenticate:
                 return (hdr, buf)
             auth_header = ""
             if "/v2/" in url:
                 auth_header = self._get_v2_auth(www_authenticate,
                                                 kwargs["RETRY"])
             if "/v1/" in url:
                 auth_header = self._get_v1_auth(www_authenticate)
             auth_kwargs.update({"header": [auth_header]})
     (hdr, buf) = self._get_url(*args, **auth_kwargs)
     return (hdr, buf)
Exemplo n.º 30
0
 def get_tags(self, imagerepo):
     """List tags from a v2 or v1 repositories"""
     Msg().out("Info: get tags", imagerepo, l=Msg.DBG)
     (dummy, remoterepo) = self._parse_imagerepo(imagerepo)
     if self.is_v2():
         return self.get_v2_image_tags(remoterepo, True)  # try v2
     return self.get_v1_image_tags(remoterepo, True)  # try v1