Пример #1
0
 def test_03_uuid(self):
     """Test03 Unique.uuid()."""
     uniq = Unique()
     rand = uniq.uuid("zxcvbnm")
     self.assertEqual(len(rand), 36)
     rand = uniq.uuid(789)
     self.assertEqual(len(rand), 36)
Пример #2
0
 def test_07_filename(self):
     """Test07 Unique.filename()."""
     uniq = Unique()
     rand = uniq.filename("zxcvbnmasdf")
     self.assertTrue(rand.endswith("zxcvbnmasdf"))
     self.assertTrue(rand.startswith("udocker"))
     self.assertGreater(len(rand.strip()), 56)
     rand = uniq.filename(12345)
     self.assertTrue(rand.endswith("12345"))
     self.assertTrue(rand.startswith("udocker"))
     self.assertGreater(len(rand.strip()), 50)
Пример #3
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
Пример #4
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
Пример #5
0
 def mktmp(self):
     """Generate a temporary filename"""
     while True:
         tmp_file = self._tmpdir + '/' + \
             Unique().filename(self.basename)
         if not os.path.exists(tmp_file):
             FileUtil.tmptrash[tmp_file] = True
             self.filename = tmp_file
             return tmp_file
Пример #6
0
 def load(self, tmp_imagedir, imagerepo=None):
     """Load a Docker file created with docker save, mimic Docker
     load. The file is a tarball containing several layers, each
     layer has metadata and data content (directory tree) stored
     as a tar file.
     """
     self._imagerepo = imagerepo
     structure = self._load_structure(tmp_imagedir)
     if not structure:
         Msg().err("Error: failed to load image structure")
         return []
     if "repositories" in structure and structure["repositories"]:
         repositories = self._load_repositories(structure)
     else:
         if not imagerepo:
             imagerepo = Unique().imagename()
         tag = Unique().imagetag()
         repositories = self._load_image(structure, imagerepo, tag)
     return repositories
Пример #7
0
 def _load_manifest(self, structure, manifest):
     """Load OCI manifest"""
     try:
         tag = manifest["annotations"]["org.opencontainers.image.ref.name"]
     except KeyError:
         tag = Unique().imagetag()
     if '/' in tag and ':' in tag:
         (imagerepo, tag) = tag.split(':', 1)
     else:
         imagerepo = Unique().imagename()
     if self._imagerepo:
         imagerepo = self._imagerepo
     imagetag = imagerepo + ':' + tag
     structure["manifest"][imagetag] = dict()
     structure["manifest"][imagetag]["json"] = \
             self.localrepo.load_json(structure["repolayers"]\
             [manifest["digest"]]["layer_f"])
     structure["manifest"][imagetag]["json_f"] = \
             structure["repolayers"][manifest["digest"]]["layer_f"]
     return self._load_image(structure, imagerepo, tag)
Пример #8
0
    def create_fromimage(self, imagerepo, tag):
        """Create a container from an image in the repository.
        Since images are stored as layers in tar files, this
        step consists in extracting those layers into a ROOT
        directory in the appropriate sequence.
        first argument: imagerepo
        second argument: image tag in that repo
        """
        self.imagerepo = imagerepo
        self.tag = tag
        image_dir = self.localrepo.cd_imagerepo(self.imagerepo, self.tag)
        if not image_dir:
            Msg().err("Error: create container: imagerepo is invalid")
            return False

        (container_json, layer_files) = self.localrepo.get_image_attributes()
        if not container_json:
            Msg().err("Error: create container: getting layers or json")
            return False

        if not self.container_id:
            self.container_id = Unique().uuid(os.path.basename(self.imagerepo))

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

        self.localrepo.save_json(container_dir + "/container.json",
                                 container_json)
        status = self._untar_layers(layer_files, 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
Пример #9
0
 def import_tocontainer(self, tarfile, imagerepo, tag, container_name):
     """Import a tar file containing a simple directory tree possibly
     created with Docker export and create local container ready to use"""
     if not imagerepo:
         imagerepo = "IMPORTED"
         tag = "latest"
     if not os.path.exists(tarfile) and tarfile != '-':
         Msg().err("Error: tar file does not exist:", tarfile)
         return False
     if container_name:
         if self.localrepo.get_container_id(container_name):
             Msg().err("Error: container name already exists:",
                       container_name)
             return False
     layer_id = Unique().layer_v1()
     container_json = self.create_container_meta(layer_id)
     container_id = ContainerStructure(self.localrepo).create_fromlayer(
         imagerepo, tag, tarfile, container_json)
     if container_name:
         self.localrepo.set_container_name(container_id, container_name)
     return container_id
Пример #10
0
 def import_toimage(self, tarfile, imagerepo, tag, move_tarball=True):
     """Import a tar file containing a simple directory tree possibly
     created with Docker export and create local image"""
     if not os.path.exists(tarfile) and tarfile != '-':
         Msg().err("Error: tar file does not exist: ", tarfile)
         return False
     self.localrepo.setup_imagerepo(imagerepo)
     tag_dir = self.localrepo.cd_imagerepo(imagerepo, tag)
     if tag_dir:
         Msg().err("Error: tag already exists in repo:", tag)
         return False
     tag_dir = self.localrepo.setup_tag(tag)
     if not tag_dir:
         Msg().err("Error: creating repo and tag")
         return False
     if not self.localrepo.set_version("v1"):
         Msg().err("Error: setting repository version")
         return False
     layer_id = Unique().layer_v1()
     layer_file = self.localrepo.layersdir + '/' + layer_id + ".layer"
     json_file = self.localrepo.layersdir + '/' + layer_id + ".json"
     if move_tarball:
         try:
             os.rename(tarfile, layer_file)
         except (IOError, OSError):
             pass
     if not os.path.exists(layer_file):
         if not FileUtil(tarfile).copyto(layer_file):
             Msg().err("Error: in move/copy file", tarfile)
             return False
     self.localrepo.add_image_layer(layer_file)
     self.localrepo.save_json("ancestry", [layer_id])
     container_json = self.create_container_meta(layer_id)
     self.localrepo.save_json(json_file, container_json)
     self.localrepo.add_image_layer(json_file)
     Msg().out("Info: added layer", layer_id, l=Msg.INF)
     return layer_id
Пример #11
0
    def clone_fromfile(self, clone_file):
        """Create a cloned container from a file containing a cloned container
        exported by udocker.
        """
        if not self.container_id:
            self.container_id = Unique().uuid(os.path.basename(self.imagerepo))

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

        status = self._untar_layers([
            clone_file,
        ], container_dir)
        if not status:
            Msg().err("Error: creating container clone:", 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
Пример #12
0
 def test_05_imagetag(self):
     """Test05 Unique.imagetag()."""
     uniq = Unique()
     rand = uniq.imagetag()
     self.assertEqual(len(rand), 10)
Пример #13
0
    def run(self, container_id):
        """Execute a Docker container using singularity.
        This is the main method invoked to run a container with singularity.
          * argument: container_id or name
          * options:  many via self.opt see the help
        """

        if os.path.isdir(
                FileBind(self.localrepo, container_id).container_orig_dir):
            FileBind(self.localrepo, container_id).restore() # legacy 1.1.3

        Config.conf['sysdirs_list'] = (
            # "/dev", "/proc", "/sys",
            "/etc/resolv.conf", "/etc/host.conf",
            "/lib/modules",
        )

        # setup execution
        exec_path = self._run_init(container_id)
        if not exec_path:
            return 2
        self.opt["cmd"][0] = exec_path.replace(self.container_root + "/", "")

        self._run_invalid_options()

        self._make_container_directories()

        self.select_singularity()

        self._run_as_root()

        # set environment variables
        self._run_env_set()

        if Msg.level >= Msg.DBG:
            singularity_debug = ["--debug", "-v", ]
        elif self._has_option("--silent"):
            singularity_debug = ["--silent", ]
        elif self._has_option("--quiet"):
            singularity_debug = ["--quiet", ]
        else:
            singularity_debug = []

        if self.executable.startswith(self.localrepo.bindir):
            Config.conf['singularity_options'].extend(["-u", ])

        #if FileUtil("nvidia-smi").find_exec():
        #    Config.conf['singularity_options'].extend(["--nv", ])

        singularity_vol_list = self._get_volume_bindings()

        # build the actual command
        self.execution_id = Unique().uuid(self.container_id)
        cmd_l = self._set_cpu_affinity()
        cmd_l.append(self.executable)
        cmd_l.extend(singularity_debug)
        cmd_l.append("exec")
        cmd_l.extend(Config.conf['singularity_options'])
        if self.opt["cwd"]:
            cmd_l.extend(["--pwd", self.opt["cwd"], ])
        cmd_l.extend(singularity_vol_list)
        cmd_l.append(self.container_root)
        cmd_l.extend(self.opt["cmd"])
        Msg().out("CMD =", cmd_l, l=Msg.VER)

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

        # execute
        self._run_banner(self.opt["cmd"][0], '/')
        status = subprocess.call(cmd_l, shell=False, close_fds=True, \
            env=os.environ.update(self._singularity_env_get()))
        return status
Пример #14
0
    def run(self, container_id):
        """Execute a Docker container using runc. This is the main method
        invoked to run the a container with runc.
          * argument: container_id or name
          * options:  many via self.opt see the help
        """

        Config.conf['sysdirs_list'] = (
            "/etc/resolv.conf",
            "/etc/host.conf",
            # "/etc/passwd", "/etc/group",
        )

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

        self._run_invalid_options()

        self._container_specfile = "config.json"
        if self.container_dir:
            if self.localrepo.iswriteable_container(container_id):
                self._container_specdir = self.container_dir
            else:
                self._container_specdir = FileUtil("SPECDIR").mktmpdir()
                FileUtil(self._container_specdir).register_prefix()
            self._container_specfile = \
                    self._container_specdir + '/' + self._container_specfile

        self._filebind = FileBind(self.localrepo, container_id)
        self._filebind.setup()
        self.select_runc()

        # create new OCI spec file
        if not self._load_spec(new=True):
            return 4

        self._uid_check()

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

        # set environment variables
        self._run_env_set()
        self._set_spec()
        if (Config.conf['runc_nomqueue']
                or (Config.conf['runc_nomqueue'] is None
                    and not HostInfo().oskernel_isgreater([4, 8, 0]))):
            self._del_mount_spec("mqueue", "/dev/mqueue")

        self._del_mount_spec("cgroup", "/sys/fs/cgroup")
        self._del_namespace_spec("network")
        self._set_id_mappings()
        self._add_volume_bindings()
        self._add_devices()
        self._add_capabilities_spec()
        self._mod_mount_spec("shm", "/dev/shm", {"options": ["size=2g"]})
        self._proot_overlay()
        self._save_spec()
        if Msg.level >= Msg.DBG:
            runc_debug = [
                "--debug",
            ]
            Msg().out(
                json.dumps(self._container_specjson, indent=4, sort_keys=True))
        else:
            runc_debug = []

    # build the actual command
        self.execution_id = Unique().uuid(self.container_id)
        cmd_l = self._set_cpu_affinity()
        cmd_l.append(self.executable)
        cmd_l.extend(runc_debug)
        cmd_l.extend(["--root", self._container_specdir, "run"])
        cmd_l.extend(["--bundle", self._container_specdir, self.execution_id])
        Msg().err("CMD =", cmd_l, l=Msg.VER)
        self._run_banner(self.opt["cmd"][0], '%')
        if sys.stdout.isatty():
            return self.run_pty(cmd_l)

        return self.run_nopty(cmd_l)
Пример #15
0
 def test_01_init(self):
     """Test01 Unique() constructor."""
     uniq = Unique()
     self.assertEqual(uniq.def_name, "udocker")
Пример #16
0
 def test_06_layer_v1(self):
     """Test06 Unique.layer_v1()."""
     uniq = Unique()
     rand = uniq.layer_v1()
     self.assertEqual(len(rand), 64)
Пример #17
0
 def test_02__rnd(self):
     """Test02 Unique._rnd()."""
     uniq = Unique()
     rand = uniq._rnd(64)
     self.assertIsInstance(rand, str)
     self.assertEqual(len(rand), 64)
Пример #18
0
 def test_04_imagename(self):
     """Test04 Unique.imagename()."""
     uniq = Unique()
     rand = uniq.imagename()
     self.assertEqual(len(rand), 16)