Example #1
0
def get_repo_info(repo=None, logged_in=False):
    if repo is None:
        abort(500)
    rinfo_key = 'cache:repo_info:%s' % repo
    repo_info_cache = db.exists(rinfo_key)
    pkg_list = {}
    p, a, rev_pending = get_build_info(1, repo, logged_in)

    # logger.info('@@-antbs.py-@@ 293 | GET_REPO_INFO - FIRED')
    if not repo_info_cache:
        logger.info('@@-antbs.py-@@ 295 | GET_REPO_INFO - CACHE CHECK FAILED. WE ARE NOT USING CACHED INFO')
        all_packages = glob.glob('/srv/antergos.info/repo/%s/x86_64/***.pkg.tar.xz' % repo)

        if all_packages is not None:
            for item in all_packages:
                # logger.info(item)
                item = item.split('/')[-1]
                item = re.search('^([a-z]|[0-9]|-|_)+(?=-\d|r|v)', item)

                item = item.group(0) or ''
                if not item or item == '':
                    continue
                logger.info(item)
                pkg = package.Package(item)
                builds = pkg.builds
                try:
                    bnum = builds[0]
                except Exception:
                    bnum = ''
                review_stat = db.get('build_log:%s:review_stat' % bnum) or 'n/a'
                review_stat = db.get('review_stat:%s:string' % review_stat) or 'n/a'
                review_dev = db.get('build_log:%s:review_dev' % bnum) or 'n/a'
                review_date = db.get('build_log:%s:review_date' % bnum) or 'n/a'
                all_info = dict(bnum=bnum, name=pkg.name, version=pkg.version, review_dev=review_dev,
                                review_stat=review_stat, review_date=review_date, pkgid=pkg.pkgid)

                db.hmset('%s:%s' % (rinfo_key, pkg.pkgid), all_info)
                db.expire('%s:%s' % (rinfo_key, pkg.pkgid), 901)
                db.rpush(rinfo_key, pkg.pkgid)
                db.expire(rinfo_key, 900)
                pkg_list[pkg.pkgid] = all_info

    else:
        logger.info('@@-antbs.py-@@ 318 | GET_REPO_INFO - CACHE CHECK PASSED. WE ARE USING CACHED INFO')
        rindex = db.lrange(rinfo_key, 0, -1)
        for i in rindex:
            h = db.hgetall('%s:%s' % (rinfo_key, i))
            pkg_list[i] = h
            # logger.info('@@-antbs.py-@@ 320 | GET_REPO_INFO - pkg_list hash is %s' % str(pkg_list))

    return pkg_list, rev_pending
Example #2
0
def handle_worker_exception(job, exc_type, exc_value, traceback):
    # TODO: This needs some thought on how to recover instead of bailing on entire build queue
    """

    :param job:
    :param exc_type:
    :param exc_value:
    :param traceback:
    :return:
    """
    doc = docker.Client(base_url='unix://var/run/docker.sock', timeout=10)
    if job['origin'] == 'build_queue':
        container = db.get('container')
    elif job['origin'] == 'repo_queue':
        container = db.get('repo_container')
    else:
        container = ''
    queue = status.queue
    now_building = status.now_building
    try:
        doc.kill(container)
        doc.remove_container(container)
    except Exception:
        logger.error('Unable to kill container')
    if job['origin'] == 'build_queue':
        db.set('%s:result' % now_building['key'], 'failed')
        db.rpush('failed', now_building['build_id'])

        if not queue or len(queue) == 0 or queue == []:
            repo = os.path.join("/tmp", "staging")
            cache = os.path.join("/tmp", "pkg_cache")

            remove(repo)
            remove(cache)
            remove('/opt/antergos-packages')

            # db.set('idle', "True")
            status.idle = True
            # db.set('building', 'Idle')
            status.current_status = 'Idle'
            # db.hset('now_building', 'pkg', '')
            # db.set('container', '')
            # db.set('building_num', '')
            # db.set('building_start', '')

    logger.error('Caught Build Exception: %s', traceback)

    return True
Example #3
0
def get_live_build_output():
    """


    """

    psub = db.pubsub()
    psub.subscribe('build-output')
    first_run = True
    keep_alive = 0
    while True:
        message = psub.get_message()
        if message:
            if first_run and (message['data'] == '1' or message['data'] == 1):
                message['data'] = db.get('build_log_last_line')
                first_run = False
            elif message['data'] == '1' or message['data'] == 1:
                message['data'] = '...'

            yield 'event: build_output\ndata: %s\n\n' % message['data']
        elif keep_alive > 600:
            keep_alive = 0
            yield ':'

        keep_alive += 1
        gevent.sleep(.05)

    psub.close()
Example #4
0
def check_github_repo(project=None, repo=None):
    """

    :param project:
    :param repo:
    :return:
    """
    new_items = []
    gh = login(token=GITHUB_TOKEN)
    key = "antbs:monitor:github:%s:%s" % (project, repo)
    last_id = db.get(key) or ""
    gh_repo = gh.repository(project, repo)
    commits = gh_repo.commits()
    latest = None
    try:
        commit = commits.next()
        latest = commit.sha
    except StopIteration:
        pass

    if latest != last_id:
        if "pamac" == repo:
            repo = "pamac-dev"
        db.set(key, latest)
        new_items.append([repo])

    return new_items
Example #5
0
    def process_cnchi(self):
        a_b_test = db.get("CNCHI_A_B_TEST")

        if a_b_test == "A":
            db.set("CNCHI_A_B_TEST", "B")
        elif a_b_test == "B":
            db.set("CNCHI_A_B_TEST", "A")

        self.result = json.dumps({"msg": a_b_test})
Example #6
0
    def is_from_authorized_sender(self):
        # Determine if the request sender is authorized to send us webhooks.
        if self.is_monitor is True:
            return True
        manual = int(self.request.args.get("phab", "0"))
        gitlab = self.request.headers.get("X-Gitlab-Event") or ""
        cnchi = self.request.args.get("cnchi", False)
        if manual and manual > 0 and self.request.args.get("token") == db.get("ANTBS_MANUAL_TOKEN"):
            self.is_manual = True
        elif cnchi and cnchi == db.get("CNCHI_TOKEN"):
            self.is_cnchi = True
        elif cnchi and cnchi != db.get("CNCHI_TOKEN"):
            logger.error("CNCHI_A_B_TEST: " + cnchi)
        elif "" != gitlab and "Push Hook" == gitlab:
            self.is_gitlab = True
            self.repo = "antergos-packages"
            self.full_name = "Antergos/antergos-packages"
            self.changes = [["numix-icon-theme-square", "numix-icon-theme-square-kde"]]
        else:
            # Store the IP address blocks that github uses for hook requests.
            hook_blocks = requests.get("https://api.github.com/meta").json()["hooks"]
            for block in hook_blocks:
                ip = ipaddress.ip_address(u"%s" % self.request.remote_addr)
                if ipaddress.ip_address(ip) in ipaddress.ip_network(block):
                    # the remote_addr is within the network range of github
                    self.is_github = True
                    break
            else:
                return False

            if self.request.headers.get("X-GitHub-Event") == "ping":
                self.result = json.dumps({"msg": "Hi!"})
                return False
            elif self.request.headers.get("X-GitHub-Event") != "push":
                self.result = json.dumps({"msg": "wrong event type"})
                return False

        return True
Example #7
0
def check_for_new_items():
    db.set('FEED_CHECKED', 'True')
    db.expire('FEED_CHECKED', 900)
    new_items = []
    gh = login(token=GITHUB_TOKEN)
    last_id = db.get('ANTBS_GITHUB_LAST_EVENT') or ''
    repo = gh.repository('numixproject', "numix-icon-theme")
    commits = repo.commits()
    latest = None
    try:
        commit = commits.next()
        latest = commit.sha
    except StopIteration:
        pass

    if latest != last_id:
        db.set('ANTBS_GITHUB_LAST_EVENT', latest)
        new_items.append(['numix-icon-theme'])

    gl = Gitlab('https://gitlab.com', GITLAB_TOKEN)
    gl.auth()
    nxsq = gl.Project(id='61284')
    last_updated = db.get('ANTBS_GITLAB_LAST_UPDATED')
    events = nxsq.Event()

    for event in events:
        if event.action_name == 'pushed to':
            if event.created_at != last_updated:
                db.set('ANTBS_GITLAB_LAST_UPDATED', event.created_at)
                new_items.append(['numix-icon-theme-square'])
                new_items.append(['numix-icon-theme-square-kde'])

            break

    if len(new_items) > 0:
        add_to_build_queue(new_items)
Example #8
0
def get_live_build_ouput():
    psub = db.pubsub()
    psub.subscribe('build-output')
    first_run = True
    while True:
        message = psub.get_message()
        if message:
            if first_run and (message['data'] == '1' or message['data'] == 1):
                message['data'] = db.get('build_log_last_line')
                first_run = False
            elif message['data'] == '1' or message['data'] == 1:
                message['data'] = '...'

            yield 'data: %s\n\n' % message['data']

        gevent.sleep(.05)

    psub.close()
Example #9
0
def check_gitlab_repo(project_id=None):
    """

    :param project_id:
    :return:
    """
    new_items = []
    gl = Gitlab("https://gitlab.com", GITLAB_TOKEN)
    gl.auth()
    nxsq = gl.Project(id=project_id)
    key = "antbs:monitor:gitlab:%s" % project_id
    last_updated = db.get(key)
    events = nxsq.Event()

    for event in events:
        if event.action_name == "pushed to":
            if event.created_at != last_updated:
                db.set(key, event.created_at)
                new_items.append(["numix-icon-theme-square"])
                new_items.append(["numix-icon-theme-square-kde"])

            break

    return new_items
Example #10
0
def build_iso(pkg_obj=None):
    """

    :param pkg_obj:
    :return:
    """
    status.iso_building = True

    in_dir_last = len([name for name in os.listdir('/srv/antergos.info/repo/iso/testing')])
    if in_dir_last is None:
        in_dir_last = "0"
    db.set('pkg_count_iso', in_dir_last)

    bld_obj = process_and_save_build_metadata(pkg_obj=pkg_obj)
    build_id = bld_obj.bnum

    fetch_and_compile_translations(translations_for=["cnchi_updater", "antergos-gfxboot"])

    flag = '/srv/antergos.info/repo/iso/testing/.ISO32'
    minimal = '/srv/antergos.info/repo/iso/testing/.MINIMAL'

    if 'i686' in pkg_obj.name:
        if not os.path.exists(flag):
            open(flag, 'a').close()
    else:
        if os.path.exists(flag):
            os.remove(flag)

    if 'minimal' in pkg_obj.name:
        out_dir = '/out'
        if not os.path.exists(minimal):
            open(minimal, 'a').close()
    else:
        out_dir = '/out'
        if os.path.exists(minimal):
            os.remove(minimal)

    # Create docker host config dict
    hconfig = create_host_config(privileged=True, cap_add=['ALL'],
                                 binds={
                                     '/opt/archlinux-mkarchiso':
                                         {
                                             'bind': '/start',
                                             'ro': False
                                         },
                                     '/run/dbus':
                                         {
                                             'bind': '/var/run/dbus',
                                             'ro': False
                                         },
                                     '/srv/antergos.info/repo/iso/testing':
                                         {
                                             'bind': out_dir,
                                             'ro': False
                                         }},
                                 restart_policy={
                                     "MaximumRetryCount": 2,
                                     "Name": "on-failure"})
    iso_container = {}
    try:
        iso_container = doc.create_container("antergos/mkarchiso", command='/start/run.sh',
                                             name=pkg_obj.name, host_config=hconfig, cpuset='0-3')
        if iso_container.get('Warnings') and iso_container.get('Warnings') != '':
            logger.error(iso_container.get('Warnings'))
    except Exception as err:
        logger.error('Create container failed. Error Msg: %s' % err)
        bld_obj.failed = True
        return False

    bld_obj.container = iso_container.get('Id')
    status.container = bld_obj.container

    try:
        doc.start(bld_obj.container)
        cont = bld_obj.container
        stream_process = Process(target=publish_build_ouput, kwargs=dict(container=cont, bld_obj=bld_obj, is_iso=True))
        stream_process.start()
        result = doc.wait(cont)
        if result != 0:
            bld_obj.failed = True
            logger.error('[CONTAINER EXIT CODE] Container %s exited. Return code was %s' % (pkg_obj.name, result))
            return False
        else:
            bld_obj.completed = True
            logger.info('[CONTAINER EXIT CODE] Container %s exited. Return code was %s' % (pkg_obj.name, result))
    except Exception as err:
        logger.error('Start container failed. Error Msg: %s' % err)
        bld_obj.failed = True
        return False

    stream_process.join()
    in_dir = len([name for name in os.listdir('/srv/antergos.info/repo/iso/testing')])
    last_count = int(db.get('pkg_count_iso'))
    if in_dir > last_count:
        bld_obj.completed = True
        tlmsg = 'Build <a href="/build/%s">%s</a> for <strong>%s</strong> was successful.' % (
            build_id, build_id, pkg_obj.name)
        Timeline(msg=tlmsg, tl_type=4)
        completed = status.completed
        completed.rpush(bld_obj.bnum)
    else:
        bld_obj.failed = True
        bld_obj.completed = False
        tlmsg = 'Build <a href="/build/%s">%s</a> for <strong>%s</strong> failed.' % (build_id, build_id, pkg_obj.name)
        Timeline(msg=tlmsg, tl_type=5)
        failed = status.failed
        failed.rpush(build_id)

    bld_obj.end_str = datetime.datetime.now().strftime("%m/%d/%Y %I:%M%p")

    if not bld_obj.failed:
        remove('/opt/archlinux-mkarchiso/antergos-iso')
        run_docker_clean(pkg_obj.name)
        db.set('antbs:misc:cache_buster:flag', True)
        return True
    return False
Example #11
0
def build_iso():
    iso_arch = ['x86_64', 'i686']
    in_dir_last = len([name for name in os.listdir('/srv/antergos.info/repo/iso/testing')])
    if in_dir_last is None:
        in_dir_last = "0"
    db.set('pkg_count_iso', in_dir_last)
    is_minimal = db.get('isoMinimal')
    if is_minimal == 'True':
        iso_name = 'antergos-iso-minimal-'
    else:
        iso_name = 'antergos-iso-'
    for arch in iso_arch:
        if db.exists('iso:one:arch') and arch == 'x86_64':
            continue
        pkgobj = package.get_pkg_object(iso_name + arch)
        failed = False
        db.incr('build_number')
        dt = datetime.datetime.now().strftime("%m/%d/%Y %I:%M%p")
        build_id = db.get('build_number')
        pkgobj.save_to_db('builds', build_id, 'list')
        this_log = 'build_log:%s' % build_id
        db.set('%s:start' % this_log, dt)
        db.set('building_num', build_id)
        db.hset('now_building', 'build_id', build_id)
        db.hset('now_building', 'key', this_log)
        db.hset('now_building', 'pkg', pkgobj.name)
        db.set(this_log, True)
        db.set('building_start', dt)
        logger.info('Building %s' % pkgobj.name)
        db.set('building', 'Building: %s' % pkgobj.name)
        db.lrem('queue', 0, pkgobj.name)
        db.set('%s:pkg' % this_log, pkgobj.name)
        db.set('%s:version' % this_log, pkgobj.version)

        flag = '/srv/antergos.info/repo/iso/testing/.ISO32'
        minimal = '/srv/antergos.info/repo/iso/testing/.MINIMAL'
        if arch is 'i686':
            if not os.path.exists(flag):
                open(flag, 'a').close()
        else:
            if os.path.exists(flag):
                os.remove(flag)
        if is_minimal == "True":
            out_dir = '/out'
            if not os.path.exists(minimal):
                open(minimal, 'a').close()
        else:
            out_dir = '/out'
            if os.path.exists(minimal):
                os.remove(minimal)
        # Get and compile translations for updater script
        # TODO: Move this into its own method.
        trans_dir = "/opt/antergos-iso-translations/"
        trans_files_dir = os.path.join(trans_dir, "translations/antergos.cnchi_updaterpot")
        dest_dir = '/srv/antergos.info/repo/iso/testing/trans'
        if not os.path.exists(dest_dir):
            os.mkdir(dest_dir)
        try:
            subprocess.check_call(['tx', 'pull', '-a', '-r', 'antergos.cnchi_updaterpot', '--minimum-perc=50'],
                                  cwd=trans_dir)
            for r, d, f in os.walk(trans_files_dir):
                for tfile in f:
                    logger.info('tfile is %s' % tfile)
                    logger.info('tfile cut is %s' % tfile[:-2])
                    mofile = tfile[:-2] + 'mo'
                    logger.info('mofile is %s' % mofile)
                    subprocess.check_call(['msgfmt', '-v', tfile, '-o', mofile], cwd=trans_files_dir)
                    os.rename(os.path.join(trans_files_dir, mofile), os.path.join(dest_dir, mofile))
        except subprocess.CalledProcessError as err:
            logger.error(err.output)
        except Exception as err:
            logger.error(err)

        nm = iso_name + arch
        # Initiate communication with docker daemon
        run_docker_clean(nm)
        hconfig = create_host_config(privileged=True, cap_add=['ALL'],
                                     binds={
                                         '/opt/archlinux-mkarchiso':
                                             {
                                                 'bind': '/start',
                                                 'ro': False
                                             },
                                         '/run/dbus':
                                             {
                                                 'bind': '/var/run/dbus',
                                                 'ro': False
                                             },
                                         '/srv/antergos.info/repo/iso/testing':
                                             {
                                                 'bind': out_dir,
                                                 'ro': False
                                             }},
                                     restart_policy={
                                         "MaximumRetryCount": 2,
                                         "Name": "on-failure"})
        try:
            iso_container = doc.create_container("antergos/mkarchiso", command='/start/run.sh', tty=True,
                                                 name=nm, host_config=hconfig, cpuset='0-3')
            db.set('container', iso_container.get('Id'))
        except Exception as err:
            logger.error("Cant connect to Docker daemon. Error msg: %s", err)
            failed = True
            break

        try:
            doc.start(iso_container, privileged=True, cap_add=['ALL'], binds={
                '/opt/archlinux-mkarchiso':
                    {
                        'bind': '/start',
                        'ro': False
                    },
                '/run/dbus':
                    {
                        'bind': '/var/run/dbus',
                        'ro': False
                    },
                '/srv/antergos.info/repo/iso/testing':
                    {
                        'bind': out_dir,
                        'ro': False
                    },
            })

            cont = db.get('container')
            stream_process = Process(target=publish_build_ouput, args=(cont, this_log))
            stream_process.start()
            result = doc.wait(cont)
            result2 = None
            if result is not 0:
                doc.restart(cont)
                stream_process2 = Process(target=publish_build_ouput, args=(cont, this_log))
                stream_process2.start()
                result2 = doc.wait(cont)
                if result2 is not 0:
                    # failed = True
                    # db.set('build_failed', "True")
                    logger.error('[CONTAINER EXIT CODE] Container %s exited. Return code was %s' % (nm, result))
            if result is 0 or (result2 and result2 is 0):
                logger.info('[CONTAINER EXIT CODE] Container %s exited. Return code was %s' % (nm, result))
                db.set('build_failed', "False")

        except Exception as err:
            logger.error("Cant start container. Error msg: %s", err)
            break

        db.publish('build-output', 'ENDOFLOG')
        db.set('%s:end' % this_log, datetime.datetime.now().strftime("%m/%d/%Y %I:%M%p"))

        in_dir = len([name for name in os.listdir('/srv/antergos.info/repo/iso/testing')])
        last_count = int(db.get('pkg_count_iso'))
        if in_dir > last_count:
            db.incr('pkg_count_iso', (in_dir - last_count))
            db.rpush('completed', build_id)
            db.set('%s:result' % this_log, 'completed')
            # db.set('%s:review_stat' % this_log, '1')
        else:
            logger.error('%s not found after container exit.' % iso_name + arch)
            failed = True
            db.set('%s:result' % this_log, 'failed')
            db.rpush('failed', build_id)
        remove('/opt/archlinux-mkarchiso/antergos-iso')
        doc.remove_container(cont, v=True)
Example #12
0
def update_main_repo(pkg=None, rev_result=None, this_log=None):
    if pkg and rev_result:
        repo = 'antergos'
        repodir = 'main'
        if rev_result == 'skip':
            rev_result = None
            repo = 'antergos-staging'
            repodir = 'staging'
        result = '/tmp/result'
        if os.path.exists(result):
            shutil.rmtree(result)
        os.mkdir(result, 0o777)
        command = "/makepkg/build.sh"
        pkgenv = ["_PKGNAME=%s" % pkg, "_RESULT=%s" % rev_result, "_UPDREPO=True", "_REPO=%s" % repo,
                  "_REPO_DIR=%s" % repodir]
        building_saved = False
        if not status.idle:
            building_saved = status.current_status
        else:
            status.idle = False
        status.current_status = 'Updating repo database.'
        container = None
        run_docker_clean("update_repo")
        try:
            container = doc.create_container("antergos/makepkg", command=command,
                                             name="update_repo", environment=pkgenv,
                                             volumes=['/makepkg', '/root/.gnupg', '/main', '/result', '/staging'])
            db.set('update_repo_container', container.get('Id'))
            doc.start(container, binds={
                DOC_DIR:
                    {
                        'bind': '/makepkg',
                        'ro': True
                    },
                '/srv/antergos.info/repo/antergos':
                    {
                        'bind': '/main',
                        'ro': False
                    },
                '/srv/antergos.info/repo/iso/testing/uefi/antergos-staging/':
                    {
                        'bind': '/staging',
                        'ro': False
                    },
                '/root/.gnupg':
                    {
                        'bind': '/root/.gnupg',
                        'ro': False
                    },
                '/tmp/result':
                    {
                        'bind': '/result',
                        'ro': False
                    }
            }, privileged=True)
            if this_log is None:
                this_log = 'repo_update_log'
                upd_repo = False
            else:
                upd_repo = True
            cont = db.get('update_repo_container')
            stream_process = Process(target=publish_build_ouput, args=(cont, this_log, upd_repo))
            stream_process.start()
            doc.wait(container)
            db.set('antbs:misc:cache_buster:flag', True)
        except Exception as err:
            logger.error('Start container failed. Error Msg: %s' % err)

        doc.remove_container(container, v=True)

        if not status.idle:
            if building_saved:
                status.current_status = building_saved
            else:
                status.idle = True
                status.current_status = 'Idle'
Example #13
0
def handle_hook(first=False, last=False):
    status.idle = False
    pull_from = 'antergos'
    packages = status.queue()

    if os.path.exists(REPO_DIR):
        remove(REPO_DIR)
    try:
        subprocess.check_call(
            ['git', 'clone', 'http://github.com/antergos/antergos-packages.git'],
            cwd='/opt')
        subprocess.check_call(['chmod', '-R', 'a+rw', REPO_DIR], cwd='/opt')
    except subprocess.CalledProcessError as err:
        logger.error(err)

    if status.iso_flag:
        status.iso_flag = False
        status.current_status = 'Building docker image.'
        status.iso_building = True
        image = docker_utils.maybe_build_mkarchiso()
        db.lrem('queue', 0, 'antergos-iso')
        db.lrem('queue', 0, 'antergos-iso.openbox')
        if image:
            archs = ['x86_64', 'i686']
            if db.get('isoMinimal') == 'True':
                iso_name = 'antergos-iso-minimal-'
            else:
                iso_name = 'antergos-iso-'
            for arch in archs:
                db.rpush('queue', iso_name + arch)
                version = datetime.datetime.now().strftime('%Y.%m.%d')
                pkgobj = package.get_pkg_object(iso_name + arch)
                pkgobj.save_to_db('version', version)
            build_iso()
        db.set('isoBuilding', 'False')
        db.set('isoMinimal', 'False')
        db.set('idle', "True")
        return True

    elif first and not status.iso_flag:
        status.current_status = 'Building docker image.'
        image = docker_utils.maybe_build_base_devel()
        if not image:
            return False

        logger.info('Checking database for packages.')
        status.current_status = 'Checking database for queued packages'

        all_deps = process_package_queue(packages)

        logger.info('All queued packages are in the database, checking deps to determine build order.')
        status.current_status = 'Determining build order by sorting package depends'
        if len(all_deps) > 1:
            topsort = check_deps(all_deps)
            check = []
            packages.delete()
            for p in topsort:
                # TODO: What if there is already a group of packages in queue prior to the current group?
                packages.append(p)

        logger.info('Check deps complete. Starting build_pkgs')
        logger.debug((packages, status.iso_flag))
        status.current_status = 'Check deps complete. Starting build container.'

    if not status.iso_flag and len(packages) > 0:
        pack = status.queue().lpop()
        if pack and pack is not None and pack != '':
            pkgobj = package.get_pkg_object(name=pack)
        else:
            return False

        rqjob = get_current_job(db)
        rqjob.meta['is_first'] = first
        rqjob.meta['is_last'] = last
        rqjob.meta['package'] = pkgobj.name
        rqjob.save()

        status.now_building = pkgobj.name
        built = build_pkgs(last, pkgobj)
        # TODO: Move this into its own method
        if built:
            completed = status.completed()
            failed = status.failed()
            blds = pkgobj.builds()
            total = len(blds)
            if total > 0:
                success = len([x for x in pkgobj.blds if x in completed])
                failure = len([x for x in pkgobj.blds if x in failed])
                if success > 0:
                    success = 100 * success / total
                else:
                    success = 0
                if failure > 0:
                    failure = 100 * failure / total
                else:
                    failure = 0
                pkgobj.success_rate = success
                pkgobj.failure_rate = failure
    if last:
        remove('/opt/antergos-packages')
        status.idle = True
        status.building = 'Idle'
        status.now_building = 'Idle'
        status.container = ''
        status.building_num = ''
        status.building_start = ''
        logger.info('All builds completed.')