コード例 #1
0
ファイル: dockerapp.py プロジェクト: shaoguangleo/dfms
    def initialize(self, **kwargs):
        BarrierAppDROP.initialize(self, **kwargs)

        self._image = self._getArg(kwargs, "image", None)
        if not self._image:
            raise Exception("No docker image specified, cannot create DockerApp")

        if ":" not in self._image:
            logger.warn("%r: Image %s is too generic since it doesn't specify a tag" % (self, self._image))

        self._command = self._getArg(kwargs, "command", None)
        if not self._command:
            raise Exception("No command specified, cannot create DockerApp")

        # The user used to run the process in the docker container
        # By default docker containers run as root, but we don't want to run
        # a process using a different user because otherwise anything that that
        # process writes to the filesystem
        self._user = self._getArg(kwargs, "user", None)

        # In some cases we want to make sure the command in the container runs
        # as a certain user, so we wrap up the command line in a small script
        # that will create the user if missing and switch to it
        self._ensureUserAndSwitch = self._getArg(kwargs, "ensureUserAndSwitch", self._user is None)

        # By default containers are removed from the filesystem, but people
        # might want to preserve them.
        # TODO: This might be something that the data lifecycle manager could
        # handle, but for the time being we do it here
        self._removeContainer = self._getArg(kwargs, "removeContainer", True)

        # Additional volume bindings can be specified for existing files/dirs
        # on the host system.
        self._additionalBindings = {}
        for binding in self._getArg(kwargs, "additionalBindings", []):
            if binding.find(":") == -1:
                host_path = container_path = binding
            else:
                host_path, container_path = binding.split(":")
            if not os.path.exists(host_path):
                raise ValueError("'Path %s doesn't exist, cannot use as additional volume binding" % (host_path,))
            self._additionalBindings[host_path] = container_path

        if logger.isEnabledFor(logging.INFO):
            logger.info("%r with image '%s' and command '%s' created" % (self, self._image, self._command))

        # Check if we have the image; otherwise pull it.
        extra_kwargs = self._kwargs_from_env()
        c = AutoVersionClient(**extra_kwargs)
        found = reduce(lambda a, b: a or self._image in b["RepoTags"], c.images(), False)

        if not found:
            if logger.isEnabledFor(logging.DEBUG):
                logger.debug("Image '%s' not found, pulling it" % (self._image))
            start = time.time()
            c.pull(self._image)
            end = time.time()
            if logger.isEnabledFor(logging.DEBUG):
                logger.debug("Took %.2f [s] to pull image '%s'" % ((end - start), self._image))
        else:
            if logger.isEnabledFor(logging.DEBUG):
                logger.debug("Image '%s' found, no need to pull it" % (self._image))

        self._containerIp = None
        self._containerId = None
        self._waiters = []