예제 #1
0
def main(factory: str, sha: str, targets_json: str, machines: [],
         platforms: [], app_root_dir: str, publish_tool: str,
         apps_version: str, target_tag: str, target_version: str,
         new_targets_file: str):
    convert_docker_apps()
    status('Searching for Compose Apps in {}'.format(app_root_dir))
    apps = ComposeApps(app_root_dir)
    status('Found Compose Apps: {}'.format(apps.str))

    status('Validating Compose Apps')
    apps.validate()
    status('Compose Apps has been validated: {}'.format(apps.str))

    apps_to_add_to_target = AppsPublisher(factory, publish_tool).publish(
        apps, apps_version)

    status(
        'Creating Targets that refer to the published Apps; tag: {}, version: {}, machines: {}, platforms: {} '
        .format(target_tag, target_version,
                ','.join(machines) if machines else '[]',
                ','.join(platforms) if platforms else '[]'))
    new_targets = create_target(targets_json, apps_to_add_to_target,
                                target_tag, sha, machines, platforms,
                                target_version, new_targets_file)
    if len(new_targets) == 0:
        logger.error('Failed to create Targets for the published Apps')
        return 1

    return 0
예제 #2
0
def convert_docker_apps():
    """Loop through all the .dockerapp files in a directory and convert them
       to directory-based docker-compose.yml friendly representations.
    """
    for p in os.listdir():
        if not p.endswith('.dockerapp'):
            continue
        if os.path.isfile(p):
            status('Converting .dockerapp file for: ' + p)
            convert_docker_app(p)
예제 #3
0
def main(factory: str,
         tag: str,
         ota_lite_tag: str,
         platforms: str,
         sha: str,
         version: str,
         targets_json: str,
         app_preload_flag: str,
         app_dir=None):
    convert_docker_apps()
    apps = {}

    cur_work_dir = os.path.abspath(os.getcwd())
    if app_dir:
        os.chdir(app_dir)

    status('Searching for apps in {}'.format(os.path.abspath(os.getcwd())))
    for app in os.listdir():
        if app.endswith('.disabled'):
            continue
        if os.path.exists(os.path.join(app, 'docker-compose.yml')):
            status('Validating compose file for: ' + app)
            cmd('docker-compose', 'config', cwd=app)
            status('Publishing compose app for: ' + app)
            uri = publish(factory, tag, app)
            apps[app] = {'uri': uri}

    create_target(targets_json, version, apps, ota_lite_tag, sha)

    if app_preload_flag == '1':
        # ------ Dumping container images of all apps -----
        app_images_dir = '/var/cache/bitbake/app-images/' + sha
        if os.path.exists(app_images_dir):
            shutil.rmtree(app_images_dir, ignore_errors=True)

        os.makedirs(app_images_dir)

        status('Dumping container images of the published compose apps to ' +
               app_images_dir)

        prefixed_platforms = platforms.split(',')
        archs = []
        for platform in prefixed_platforms:
            archs.append(platform.split('/')[1])

        with tempfile.TemporaryDirectory() as tmp_dst_dir:
            dump_app_images(os.path.abspath(os.getcwd()), archs, tmp_dst_dir)
            for arch in archs:
                subprocess.check_call([
                    'tar', '-cf',
                    os.path.join(app_images_dir,
                                 '{}-{}.tar'.format(sha, arch)), '-C',
                    os.path.join(tmp_dst_dir, arch), '.'
                ])

        # ------------------------------------------------

    if app_dir:
        os.chdir(cur_work_dir)
예제 #4
0
def publish(factory: str, tag: str, app_name: str) -> str:
    base = 'hub.foundries.io/' + factory + '/'
    app = base + app_name
    tagged = app + ':app-' + tag

    changed = False
    with open(os.path.join(app_name, 'docker-compose.yml')) as f:
        compose = yaml.safe_load(f)
        for name, svc in compose['services'].items():
            img = svc['image']
            if img.startswith(base):
                # this should be a container defined in this factory and
                # in its containers.git, so it should get pinned to ${TAG}
                # to work as expected
                parts = img.split(':')
                if len(parts) == 1:
                    status('Image pinned to latest: %s, updating to %s' %
                           (img, tag))
                    svc['image'] = img + ':' + tag
                    changed = True
                elif len(parts) == 2:
                    allowed = ['${TAG}', 'latest', tag]
                    if factory == 'lmp':
                        # the lmp containers repo pulls in fiotest which sets
                        # its tag to "postmerge" which is okay based on how
                        # we do tagging for that repo.
                        allowed.append('postmerge')
                    if parts[1] not in allowed:
                        sys.exit('Image pinned to %s should be ${TAG} or %s' %
                                 (parts[1], tag))
                    svc['image'] = parts[0] + ':' + tag
                    changed = True
                else:
                    sys.exit('Unexpected image value: ' + img)
    if changed:
        with open(os.path.join(app_name, 'docker-compose.yml'), 'w') as f:
            yaml.dump(compose, f)

    out = cmd('compose-publish', tagged, cwd=app_name, capture=True)
    # The publish command produces output like:
    # = Publishing app...
    # |-> app:  sha256:fc73321368c7a805b0f697a0a845470bc022b6bdd45a8b34
    # |-> manifest:  sha256:e15e3824fc21ce13815aecb0490d60b3a32
    # We need the manifest sha so we can pin it properly in targets.json
    needle = b'|-> manifest:  sha256:'
    sha = out[out.find(needle) + len(needle):].strip()
    return app + '@sha256:' + sha.decode()
예제 #5
0
def change_password(token):
    data = request.json

    if len(data['newPassword']) <= 7:
        return error_status(400, 'Password too short.')
    if dh.change_password(token, data['oldPassword'], data['newPassword']):
        return status('')
    return error_status(401, 'Wrong password.')
예제 #6
0
def get_user_data_by_email(_):
    email = request.args['email']
    data = dh.get_user_data_by_email(email)
    if data:
        dh.add_viewer(email)
        notify_all_sockets()
        return status(data)

    return error_status(400, 'User not found')
예제 #7
0
def sign_in():
    data = request.json
    email = data['email']
    token = dh.login(email, data['password'])

    if token:
        return status({'token': token}, "Successfully signed in.")
    else:
        return error_status(400, "Wrong username or password.")
예제 #8
0
def sign_up():
    data = request.json

    if len(data['password']) <= 7:
        return error_status(400, 'Password too short.')

    if dh.sign_up(data['email'], data['password'], data['firstname'], data['familyname'], data['gender'], data['city'], data['country']):
        return status('')
    else:
        return error_status(400, 'Email already exsits')
예제 #9
0
def convert_docker_app(path: str):
    """Take a .dockerapp file to directory format.
       The file format isn't supported by docker-app 0.8 and beyond. Just
       split a 3 sectioned yaml file into its pieces
    """
    with open(path) as f:
        _, compose, params = yaml.safe_load_all(f)
    if params is None:
        params = {}
    os.unlink(path)
    path, _ = os.path.splitext(path)
    try:
        # this directory might already exist. ie the user has:
        # shellhttpd.dockerapp
        # shellhttpd/Dockerfile...
        os.rename(path, path + '.orig')  # just move out of the way
    except FileNotFoundError:
        pass
    os.mkdir(path)
    # We need to try and convert docker-app style parameters to parameters
    # that are compatible with docker-compose
    params = normalize_keyvals(params)
    compose_str = yaml.dump(compose)
    for k, v in params.items():
        # there are two things we have to replace:
        # 1) Things with no defaults - ie ports: 8080:${PORT}
        #    We need to make this ${PORT-<default>} if we can
        compose_str = compose_str.replace('${%s}' % k, '${%s-%s}' % (k, v))
        # 2) Things that are nested - ie foo.bar=12
        #    We have to make this foo_bar so compose will accept it
        if '.' in k:
            safek = k.replace('.', '_')
            status('Replacing parameter "%s" with "%s" for compatibility' %
                   (k, safek))
            compose_str = compose_str.replace('${' + k, '${' + safek)
    with open(os.path.join(path, 'docker-compose.yml'), 'w') as f:
        f.write(compose_str)
    status('Converted docker-compose for %s\n' % compose_str)
예제 #10
0
def sign_in():
    data = request.json
    email = data['email']
    token = dh.login(email, data['password'])

    if token:
        if email in opensockets:
            for socket in opensockets[email]:
                if not socket.closed:
                    socket.send('msg')
            opensockets[email] = []
        return status({'token': token}, "Successfully signed in.")
    else:
        return error_status(400, "Wrong username or password.")
예제 #11
0
def post_message(token):
    email = request.json['email']
    message = request.json['message']
    dh.post_message(token, email, message)
    return status('', 'Post posted.', 201)
예제 #12
0
def get_user_data_by_email(_):
    data = dh.get_user_data_by_email(request.args['email'])
    if data:
        return status(data)

    return error_status(400, 'User not found')
예제 #13
0
                        help="comment for the test case",
                        type=str)
    args = parser.parse_args()

    return args


if __name__ == '__main__':
    case = helpers.cases.TestRail()
    args = menu()

    #  If there is less than 10 args, call usage().
    if len(sys.argv) < 10:
        print "usage: %s" % (usage())

    #  We check status first, if it doesn't match we don't call the API
    #  and exit(1).
    status = status(args.status)

    comment = args.comment
    project_id = case.get_project_id(args.project)
    suite_id = case.get_project_suite_id(args.suite, project_id)
    section_id = case.get_project_section_id(args.suite, project_id)
    run_id = case.get_test_run_id(args.run, project_id)
    case_id = case.get_case_id(args.case, section_id, suite_id, project_id)

    #  Update the test case.
    update_case = case.set_test_case_result(run_id, case_id, status, comment)
    if len(update_case) > 0:
        print("[Case ID: %s] updated." % (case_id))
예제 #14
0
def validate_token(_):
    return status(None)