예제 #1
0
def get_image_tags(image, prefix='v', proxies=None):
    """Retrieve tags from dockerhub of an image.

    :param image: image name, organisation/repository.
    :param prefix: prefix by which to filter images.

    :returns: sorted list of tags, newest first, ordered by semver.
        Or the list [None] if an error occurs fetching tag meta information.
    """
    try:
        tags_data = _get_image_meta(image, proxies=proxies)
    except Exception as e:
        logger = labslauncher.get_named_logger("ImageMeta")
        logger.warning(e)
        logger.warning("Failed to fetch image information from dockerhub.")
        return [None]
    tags = list()
    for t in tags_data:
        name = t['name']
        if name[0] != prefix:
            continue
        try:
            semver.parse(name[1:])
        except ValueError:
            continue
        else:
            tags.append(name[1:])
    ordered_tags = [
        '{}{}'.format(prefix, x) for x in sorted(
            tags, reverse=True, key=functools.cmp_to_key(semver.compare))
    ]
    return ordered_tags
예제 #2
0
    def __init__(self, settings, app):
        """Initialize a launcher."""
        self.settings = settings
        self.app = app
        self.version = labslauncher.__version__
        self.logger = labslauncher.get_named_logger("Launcher")
        self.releases = labslauncher.app_releases(
            repository=self.settings['github_repo'],
            user=self.settings['github_user'],
            token=self.settings['github_token'])
        self.server_name = "{}-{}".format(self.settings["server_name"],
                                          getpass.getuser())

        self.fixed_tag = self.settings["fixed_tag"]
        if self.fixed_tag == "":
            self.fixed_tag = None
        self.proxy = None
        for protocol in ('ftp', 'http', 'https'):
            value = self.settings["{}_proxy".format(protocol)]
            if value != "":
                if self.proxy is None:
                    self.proxy = dict()
                self.proxy[protocol] = value

        self.ping_timer = QTimer()
        self.pinger = ping.Pingu()
예제 #3
0
 def __init__(self,
              image_name,
              server_name,
              data_bind,
              container_cmd,
              host_only,
              fixed_tag=None,
              registry='docker.io',
              proxies=None):
     """Initialize the client."""
     self.image_name = image_name
     self.server_name = server_name
     self.data_bind = data_bind
     self.container_cmd = container_cmd
     self.host_only = host_only
     self.fixed_tag = fixed_tag
     self.registry = registry
     self.proxies = proxies
     # TODO: plumb in registry
     self.logger = labslauncher.get_named_logger("DckrClnt")
     # throttle connection errors to once every 5 minutes
     spam = [
         'Could not create docker client', 'Failed to query docker client'
     ]
     self.logger.addFilter(
         RateLimitingFilter(rate=1, per=300, burst=1, match=spam))
     self.logger.info("""Creating docker client with options:
        image name: {}
        server name: {}
        data bind: {}
        command: {}
        host only: {}
        fixed tag: {}
        proxies: {}""".format(image_name, server_name, data_bind,
                              container_cmd, host_only, fixed_tag, proxies))
     self._client = None
     self.total_size = None
     self.final_stats = None
     self.last_failure = "Unknown error"
     self.last_failure_type = None
     self.is_running()  # sets up tag, status, and available
     # docker service heartbeat
     self.dheartbeat = QTimer()
     self.dheartbeat.setInterval(1000 * 5)  # 5 seconds
     self.dheartbeat.start()
     self.dheartbeat.timeout.connect(self.is_running)
     # container status heartbeat
     self.cheartbeat = QTimer()
     self.cheartbeat.setInterval(1000 * 5)  # 5 seconds
     self.cheartbeat.start()
     self.cheartbeat.timeout.connect(self.set_status)
예제 #4
0
    def __init__(self, fn, *args, **kwargs):
        """Initialize the worker.

        :param callback: function callback to run on this worker thread.
        :param args: arguments to pass to the callback function.
        :param kwargs: keyword arguments to pass to the callback function.

        To enable progress indicator the worker should accept a Qt Signal
        as a `progress` keyword argument. To enable stopping of the thread
        the function should accept a threading.Event as a `stopped` keyword
        argument.
        """
        super(Worker, self).__init__()
        self.fn = fn
        self.args = args
        self.kwargs = kwargs
        self.signals = WorkerSignals()
        self.kwargs['progress'] = self.signals.progress
        self.stopped = threading.Event()
        self.kwargs['stopped'] = self.stopped
        self.logger = labslauncher.get_named_logger('Runnabl')
예제 #5
0
    def __init__(self, app, settings):
        """Initialize the main window."""
        super().__init__()
        self.settings = settings
        self.version = labslauncher.__version__
        self.logger = labslauncher.get_named_logger("Launcher")
        self.about = About(self.version)
        releases = labslauncher.app_releases(
            repository=self.settings['github_repo'],
            user=self.settings['github_user'],
            token=self.settings['github_token'])
        self.change_log = ChangeLog(releases)
        self.settings_dlg = SettingsDlg(self.settings, parent=self)

        self.setWindowTitle("EPI2ME Labs Launcher")
        # display in centre of screen and fixed size
        qtRectangle = self.frameGeometry()
        centerPoint = QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())
        self.setFixedSize(400, 400)

        app.aboutToQuit.connect(self.settings.qsettings.sync)

        self.pool = QThreadPool()
        app.aboutToQuit.connect(self.pool.waitForDone)

        fixed_tag = self.settings["fixed_tag"]
        if fixed_tag == "":
            fixed_tag = None
        proxy = None
        for protocol in ('ftp', 'http', 'https'):
            value = self.settings["{}_proxy".format(protocol)]
            if value != "":
                if proxy is None:
                    proxy = dict()
                proxy[protocol] = value
        self.docker = DockerClient(self.settings["image_name"],
                                   self.settings["server_name"],
                                   self.settings["data_bind"],
                                   self.settings["container_cmd"],
                                   host_only=self.settings["docker_restrict"],
                                   fixed_tag=fixed_tag,
                                   proxies=proxy)

        self.ping_timer = QTimer(self)
        self.pinger = ping.Pingu()
        self.docker.status.changed.connect(self.on_status)
        self.on_status(self.docker.status.value, boot=True)

        self.layout = QVBoxLayout()

        self.file_menu = self.menuBar().addMenu("&File")
        self.exit_act = QAction("Exit", self)
        self.exit_act.triggered.connect(self.close)
        self.file_menu.addAction(self.exit_act)
        self.settings_act = QAction("Setting", self)
        self.settings_act.triggered.connect(self.settings_dlg.show)
        self.file_menu.addAction(self.settings_act)
        self.help_menu = self.menuBar().addMenu("&Help")
        self.about_act = QAction('About', self)
        self.about_act.triggered.connect(self.about.show)
        self.help_menu.addAction(self.about_act)
        self.change_log_act = QAction('Change log', self)
        self.change_log_act.triggered.connect(self.change_log.show)
        self.help_menu.addAction(self.change_log_act)
        self.help_act = QAction("Help", self)
        self.help_act.triggered.connect(self.show_help)
        self.help_menu.addAction(self.help_act)

        self.stack = QStackedWidget()
        self.home = HomeScreen(parent=self)
        self.start = StartScreen(parent=self)
        self.update = UpdateScreen(parent=self)
        self.app_update = AppUpdateScreen(parent=self)
        # TODO: several parts of the code use the stack indexes
        self.stack.addWidget(self.home)
        self.stack.addWidget(self.start)
        self.stack.addWidget(self.update)
        self.stack.addWidget(self.app_update)
        self.layout.addWidget(self.stack)

        w = QWidget()
        w.setLayout(self.layout)
        self.setCentralWidget(w)

        self.home.goto_start.connect(self.show_start)
        self.start.goto_home.connect(self.show_home)
        self.update.goto_next.connect(
            functools.partial(self.stack.setCurrentIndex, 1))
        self.app_update.goto_next.connect(
            functools.partial(self.stack.setCurrentIndex, 0))
        self.maybe_show_app_update()
        self.logger.info("Application started.")