def test_echo_docker_api_result_push_no_access(): push_stream = [ { 'status': 'The push refers to repository [docker.io/library/asdf]' }, { 'status': 'Preparing', 'progressDetail': {}, 'id': '2e280b8a5f3e' }, { 'status': 'Preparing', 'progressDetail': {}, 'id': 'd0b7e1b96cc1' }, { 'status': 'Preparing', 'progressDetail': {}, 'id': 'fcd8d39597dd' }, { 'status': 'Waiting', 'progressDetail': {}, 'id': '2e280b8a5f3e' }, { 'status': 'Waiting', 'progressDetail': {}, 'id': 'd0b7e1b96cc1' }, { 'status': 'Waiting', 'progressDetail': {}, 'id': 'fcd8d39597dd' }, { 'errorDetail': { 'message': 'denied: requested access to the resource is denied' }, 'error': 'denied: requested access to the resource is denied', }, ] with pytest.raises(BentoMLException) as e: _ = [line for line in echo_docker_api_result(push_stream)] assert str(e.value) == 'denied: requested access to the resource is denied'
def test_echo_docker_api_result_build(): build_stream = [ { 'stream': 'Step 1/2 : FROM bentoml/model-server:0.8.1' }, { 'stream': '\n' }, { 'stream': ' ---> f034fa23264c\n' }, { 'stream': 'Step 2/2 : COPY . /bento' }, { 'stream': '\n' }, { 'stream': ' ---> Using cache\n' }, { 'aux': { 'ID': 'sha256:garbagehash' } }, { 'stream': 'Successfully built 9d9918e008dd\n' }, { 'stream': 'Successfully tagged personal/test:latest\n' }, ] expected = [ "Step 1/2 : FROM bentoml/model-server:0.8.1", " ---> f034fa23264c", "Step 2/2 : COPY . /bento", " ---> Using cache", "Successfully built 9d9918e008dd", "Successfully tagged personal/test:latest", ] res = [line for line in echo_docker_api_result(build_stream)] assert_equal_lists(res, expected)
def test_echo_docker_api_result_push(): push_stream = [ {'status': 'The push refers to repository [docker.io/personal/test]'}, {'status': 'Preparing', 'progressDetail': {}, 'id': '2e280b8a5f3e'}, {'status': 'Preparing', 'progressDetail': {}, 'id': '03613b6b1004'}, {'status': 'Waiting', 'progressDetail': {}, 'id': 'cb2960c4c4d1'}, { 'status': 'Pushing', 'progressDetail': {'current': 5632, 'total': 532223}, 'progress': '[=> ]', 'id': '03613b6b1004', }, { 'status': 'Pushing', 'progressDetail': {'current': 512, 'total': 699}, 'progress': '[=====> ]', 'id': '2e280b8a5f3e', }, { 'status': 'Pushing', 'progressDetail': {'current': 128512, 'total': 532223}, 'progress': '[==> ]', 'id': '03613b6b1004', }, {'status': 'Pushed', 'progressDetail': {}, 'id': '2e280b8a5f3e'}, {'status': 'latest: digest: sha256:garbagehash size: 2214'}, { 'progressDetail': {}, 'aux': {'Tag': 'latest', 'Digest': 'sha256:garbagehash', 'Size': 2214}, }, ] expected = [ f"Pushed {format_size(5632)} / {format_size(532223)}", f"Pushed {format_size(5632 + 512)} / {format_size(532223 + 699)}", f"Pushed {format_size(128512 + 512)} / {format_size(532223 + 699)}", ] res = [line for line in echo_docker_api_result(push_stream)] assert_equal_lists(res, expected)
def containerize(bento, push, tag, build_arg, username, password): """Containerize specified BentoService. BENTO is the target BentoService to be containerized, referenced by its name and version in format of name:version. For example: "iris_classifier:v1.2.0" `bentoml containerize` command also supports the use of the `latest` tag which will automatically use the last built version of your Bento. You can provide a tag for the image built by Bento using the `--docker-image-tag` flag. Additionally, you can provide a `--push` flag, which will push the built image to the Docker repository specified by the image tag. You can also prefixing the tag with a hostname for the repository you wish to push to. e.g. `bentoml containerize IrisClassifier:latest --push --tag username/iris` would build a Docker image called `username/iris:latest` and push that to Docker Hub. By default, the `containerize` command will use the credentials provided by Docker. You may provide your own through `--username` and `--password`. """ saved_bundle_path = resolve_bundle_path(bento, pip_installed_bundle_path) _echo(f"Found Bento: {saved_bundle_path}") bento_metadata = load_bento_service_metadata(saved_bundle_path) name = to_valid_docker_image_name(bento_metadata.name) version = to_valid_docker_image_version(bento_metadata.version) if not tag: _echo("Tag not specified, using tag parsed from " f"BentoService: '{name}:{version}'") tag = f"{name}:{version}" if ":" not in tag: _echo( "Image version not specified, using version parsed " f"from BentoService: '{version}'", CLI_COLOR_WARNING, ) tag = f"{tag}:{version}" docker_build_args = {} if build_arg: for arg in build_arg: key, value = arg.split("=") docker_build_args[key] = value import docker docker_api = docker.APIClient() try: with Spinner(f"Building Docker image {tag} from {bento} \n"): for line in echo_docker_api_result( docker_api.build( path=saved_bundle_path, tag=tag, decode=True, buildargs=docker_build_args, )): _echo(line) except docker.errors.APIError as error: raise CLIException(f'Could not build Docker image: {error}') _echo( f'Finished building {tag} from {bento}', CLI_COLOR_SUCCESS, ) if push: auth_config_payload = ({ "username": username, "password": password } if username or password else None) try: with Spinner(f"Pushing docker image to {tag}\n"): for line in echo_docker_api_result( docker_api.push( repository=tag, stream=True, decode=True, auth_config=auth_config_payload, )): _echo(line) _echo( f'Pushed {tag} to {name}', CLI_COLOR_SUCCESS, ) except (docker.errors.APIError, BentoMLException) as error: raise CLIException(f'Could not push Docker image: {error}')