Пример #1
0
    def initialize(cls, name):
        client = connect()

        try:
            instance = cls.get_by_name(name)
            logger.info('running %s for %s', instance.container_id, name)
        except NotFound:
            data = settings.bots[name]

            # mmmhhhh.
            from meuh.distro import Distro
            distro = Distro.initialize(data['distro'], force=False)

            container_id = client.create_container(image=distro.tag,
                                                   command=['/bin/bash'],
                                                   name=name,
                                                   hostname=name,
                                                   detach=True,
                                                   tty=True,
                                                   stdin_open=True,
                                                   volumes=[
                                                       '/meuh/build',
                                                       '/meuh/publish'
                                                   ])
            logger.info('created %s from %s for %s',
                        container_id,
                        distro.tag,
                        name)
            instance = cls(name, container_id=container_id)
        instance.start()
        return instance
Пример #2
0
 def get_by_name(cls, name):
     client = connect()
     container_name = '/%s' % name
     for container in client.containers(all=True):
         if container_name in container['Names']:
             return cls(name, container_id=container['Id'])
     raise NotFound('bot %s was not found' % name)
Пример #3
0
 def destroy(self, force=False):
     """Destroy the bot"""
     client = connect()
     client.stop(self.container_id)
     client.remove_container(self.container_id, v=True, force=force)
     logger.info('destroyed %s for %s', self.container_id, self.name)
     self.container_id = None
Пример #4
0
 def cleanup(self, dest):
     """Cleanup bot files"""
     dest = os.path.join('/meuh/build', dest)
     cmd = ['rm', '-rf', dest]
     client = connect()
     logger.info('execute %s', cmd)
     for res in client.execute(self.container_id, cmd=cmd, stream=True):
         print(res)
Пример #5
0
    def build(self, src_name, src_dir, env=None):
        # copy files into shared volume
        shared_dir = os.path.join(self.settings['build-dir'], src_name)
        host.execute('mkdir -p %s' % shared_dir)
        src_dir = os.path.abspath(src_dir)
        parent_dir, src = os.path.dirname(src_dir), os.path.basename(src_dir)
        args = [
            "rsync --delete-excluded --recursive",
            "--include='%s'" % src,
            "--include='%s/*'" % src,
            "--include='%s/**/*'" % src,
            "--include='%s_*.orig.*'" % src_name,
            "--include='%s.orig.*'" % src_name,
            "--exclude='*'",
            "%s/" % parent_dir,
            "%s/" % shared_dir,
        ]
        host.execute(' '.join(args))

        # build packages

        client = connect()

        work_dir = os.path.join('/meuh/build', src_name, src)
        env = ctx.inline(env or {})

        for cmd in self.settings['publish-commands']:
            formatted = ['/bin/sh', '-c', '%s' % cmd]
            logger.info('execute %s', cmd)
            for res in client.execute(self.container_id,
                                      cmd=formatted,
                                      stream=True):
                print(res, end='')

        for cmd in self.settings['build-commands']:
            formatted = ['/bin/sh',
                         '-c',
                         'cd %s && %s %s' % (work_dir, env, cmd)]
            logger.info('execute %s', 'cd %s && %s %s' % (work_dir, env, cmd))
            for res in client.execute(self.container_id,
                                      cmd=formatted,
                                      stream=True):
                print(res, end='')

        # publish results
        args = [
            "rsync --recursive",
            "--include='*.deb'",
            "--include='*.udeb'",
            "--include='*.dsc'",
            "--include='*.changes'",
            "--exclude='*'",
            "%s/" % os.path.join('/meuh/build', src_name),
            '/meuh/publish'
        ]
        self.execute(' '.join(args))
        logger.info('artifacts are published into /meuh/publish')
Пример #6
0
 def _exec(self, cmd):
     client = connect()
     formatted = ['/bin/sh', '-c', cmd]
     for res in client.execute(self.container_id,
                               cmd=formatted,
                               stream=True,
                               stdout=True,
                               stderr=True):
         print(res, end='')
Пример #7
0
 def execute(self, cmd):
     """Execute a command into the bot"""
     client = connect()
     formatted = ['/bin/sh', '-c', cmd]
     logger.info('execute %s', cmd)
     for res in client.execute(self.container_id,
                               cmd=formatted,
                               stream=True):
         print(res, end='')
Пример #8
0
    def download(self, src, dest, extract_here=False):
        client = connect()

        with SpooledTemporaryFile() as file:
            file.write(client.copy(self.container_id, src).read())
            file.seek(0)
            tfile = TarFile(fileobj=file)
            if extract_here:
                base = len(os.path.basename(src)) + 1
                for member in tfile.getmembers():
                    member.name = member.name[base:]
            tfile.extractall(path=dest)
Пример #9
0
    def publish(self):
        """publish artefacts"""
        client = connect()

        patterns = ['*.deb', '*.dsc', '*.tar.gz', '*.tar.xz', '*.changes']
        batch = []
        for pattern in patterns:
            batch.append('cp -r /meuh/build/%s /meuh/publish' % pattern)
        cmd = ['/bin/sh', '-c', '; '.join(batch)]
        for res in client.execute(self.container_id, cmd=cmd, stream=True):
            logger.info('RES %s', res)
        logger.info('artifacts are published into /meuh/publish')
Пример #10
0
def distributions():
    distributions = defaultdict(lambda: {
        'defined': False,
        'created': False,
    })
    client = connect()

    for name in settings.distros.keys():
        distributions[name]['defined'] = True

    for data in client.images():
        for tag in data['RepoTags']:
            if tag.startswith('meuh/distro:'):
                distributions[tag[12:]]['created'] = True
    return distributions
Пример #11
0
    def start(self):
        client = connect()

        inspect = client.inspect_container(self.container_id)
        if not inspect['State']['Running']:
            if not ensure_dir(self.settings['build-dir']):
                logger.info("bind %s:/meuh:rw", self.settings['build-dir'])
            if not ensure_dir(self.settings['publish-dir']):
                logger.info("bind %s:/meuh:rw", self.settings['publish-dir'])
            client.start(self.container_id,
                         binds={
                             self.settings['build-dir']: '/meuh/build',
                             self.settings['publish-dir']: '/meuh/publish',
                         })
            logger.info('start %s', self.container_id)

            for cmd in self.settings['prereqs']:
                res = client.execute(self.container_id, cmd)
                logger.info('EXEC %s', cmd)
                logger.info('RES %s', res)
            return True
        return False
Пример #12
0
    def build2(self, src, env=None):
        client = connect()
        src_dir = os.path.join('/meuh/build', src)
        env = ctx.inline(env or {})

        for cmd in self.settings['publish-commands']:
            formatted = ['/bin/sh', '-c', '%s' % cmd]
            logger.info('execute %s', cmd)
            for res in client.execute(self.container_id,
                                      cmd=formatted,
                                      stream=True):
                print(res, end='')

        for cmd in self.settings['build-commands']:
            formatted = ['/bin/sh',
                         '-c',
                         'cd %s && %s %s' % (src_dir, env, cmd)]
            logger.info('execute %s', 'cd %s && %s %s' % (src_dir, env, cmd))
            for res in client.execute(self.container_id,
                                      cmd=formatted,
                                      stream=True):
                print(res, end='')
Пример #13
0
 def arch(self):
     """architecture of the inner distro"""
     client = connect()
     resp = client.execute(self.container_id,
                           'dpkg-architecture -qDEB_HOST_ARCH')
     return resp.strip() or None