diff --git a/README.md b/README.md index 719fe5082..6a5eed857 100644 --- a/README.md +++ b/README.md @@ -120,19 +120,23 @@ that command. ### Docker image +Thanks to [ApiVer methodology](#apiver-cli-versions-b2-vs-b2v3-b2v4-etc), +you should be perfectly fine using `b2:latest` version even in long-term support scripts, +but make sure to explicitly use `b2v3` command from the docker image as shown below. + #### Authorization User can either authorize on each command (`list-buckets` is just a example here) ```bash -B2_APPLICATION_KEY= B2_APPLICATION_KEY_ID= docker run --rm -e B2_APPLICATION_KEY -e B2_APPLICATION_KEY_ID backblazeit/b2:latest list-buckets +B2_APPLICATION_KEY= B2_APPLICATION_KEY_ID= docker run --rm -e B2_APPLICATION_KEY -e B2_APPLICATION_KEY_ID backblazeit/b2:latest b2v3 list-buckets ``` or authorize once and keep the credentials persisted: ```bash -docker run --rm -it -v b2:/root backblazeit/b2:latest authorize-account -docker run --rm -v b2:/root backblazeit/b2:latest list-buckets # remember to include `-v` - authorization details are there +docker run --rm -it -v b2:/root backblazeit/b2:latest b2v3 authorize-account +docker run --rm -v b2:/root backblazeit/b2:latest b2v3 list-buckets # remember to include `-v` - authorization details are there ``` #### Downloading and uploading @@ -140,35 +144,41 @@ docker run --rm -v b2:/root backblazeit/b2:latest list-buckets # remember to in When uploading a single file, data can be passed to the container via a pipe: ```bash -cat source_file.txt | docker run -i --rm -v b2:/root backblazeit/b2:latest upload-unbound-stream bucket_name - target_file_name +cat source_file.txt | docker run -i --rm -v b2:/root backblazeit/b2:latest b2v3 upload-unbound-stream bucket_name - target_file_name ``` or by mounting local files in the docker container: ```bash -docker run --rm -v b2:/root -v /home/user/path/to/data:/data backblazeit/b2:latest upload-file bucket_name /data/source_file.txt target_file_name +docker run --rm -v b2:/root -v /home/user/path/to/data:/data backblazeit/b2:latest b2v3 upload-file bucket_name /data/source_file.txt target_file_name ``` -## Versions +## ApiVer CLI versions (`b2` vs `b2v3`, `b2v4`, etc.) + +Summary: + +* in terminal, for best UX, use the latest apiver interface provided by `b2` command +* for long-term support, i.e. in scripts, use `b2v3` command -When you start working with `b2`, you might notice that more than one script is available to you. -This is by design - we use the `ApiVer` methodology to provide all the commands to all the versions -while also providing all the bugfixes to all the old versions. +Explanation: -If you use the `b2` command, you're working with the latest stable version. +We use the `ApiVer` methodology so we can continue to evolve the `b2` command line tool, +while also providing all the bugfixes to the old interface versions. + +If you use the `b2` command, you're working with the latest stable interface. It provides all the bells and whistles, latest features, and the best performance. -While it's a great version to work with, if you're willing to write a reliable, long-running script, -you might find out that after some time it will break. -New commands will appear, older will deprecate and be removed, parameters will change. -Backblaze service evolves and the `b2` CLI evolves with it. - -However, now you have a way around this problem. -Instead of using the `b2` command, you can use a version-bound interface e.g.: `b2v3`. -This command will always provide the same interface that the `ApiVer` version `3` provided. -Even if the `b2` command goes into the `ApiVer` version `4`, `6` or even `10` with some major changes, -`b2v3` will still provide the same interface, same commands, and same parameters. +While it's a great version to work with directly, but when writing a reliable, long-running script, +you want to ensure that your script won't break when we release a new version of the `b2` command. + +In that case instead of using the `b2` command, you should use a version-bound interface e.g.: `b2v3`. +This command will always provide the same ApiVer 3 interface, regardless of the semantic version of the `b2` command. +Even if the `b2` command goes into the ApiVer `4`, `6` or even `10` with some major changes, +`b2v3` will still provide the same interface, same commands, and same parameters, with all the security and bug fixes. Over time, it might get slower as we may need to emulate some older behaviors, but we'll ensure that it won't break. +You may find the next interface under `_b2v4`, but please note, as suggested by `_` prefix, +it is not yet stable and is not yet covered by guarantees listed above. + ## Contrib ### Detailed logs diff --git a/changelog.d/+docker_apiver.added.md b/changelog.d/+docker_apiver.added.md new file mode 100644 index 000000000..5ca078fc4 --- /dev/null +++ b/changelog.d/+docker_apiver.added.md @@ -0,0 +1 @@ +Allow `b2v3` to be run in official Docker image without the need to change entrypoint. diff --git a/Dockerfile.template b/docker/Dockerfile.template similarity index 92% rename from Dockerfile.template rename to docker/Dockerfile.template index 88055c969..f93ae8252 100644 --- a/Dockerfile.template +++ b/docker/Dockerfile.template @@ -24,9 +24,10 @@ LABEL vcs-ref="${vcs_ref}" LABEL build-date-iso8601="${build_date}" ENV PYTHONPATH=/opt/b2 +COPY ./docker/entrypoint.sh /entrypoint.sh COPY --from=builder /b2/__pypackages__/${python_version}/lib /opt/b2 COPY --from=builder /b2/__pypackages__/${python_version}/bin/* /bin/ WORKDIR /root -ENTRYPOINT ["b2"] +ENTRYPOINT ["/entrypoint.sh"] CMD ["--help"] diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100755 index 000000000..8324c4949 --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,11 @@ +#!/usr/bin/bash +set -euo pipefail + +if [[ "$1" =~ ^_?b2(v[0-9]+)?$ ]]; then + B2_COMMAND="$1" + shift +else + B2_COMMAND="b2" +fi + +exec "$B2_COMMAND" "$@" diff --git a/noxfile.py b/noxfile.py index 35b959b9c..31d30c669 100644 --- a/noxfile.py +++ b/noxfile.py @@ -61,7 +61,7 @@ def _detect_python_nox_id() -> str: PY_PATHS = ['b2', 'test', 'noxfile.py'] -DOCKER_TEMPLATE = pathlib.Path('./Dockerfile.template') +DOCKER_TEMPLATE = pathlib.Path('docker/Dockerfile.template') SYSTEM = platform.system().lower() @@ -278,7 +278,11 @@ def build(session): # otherwise glob won't find files on windows in action-gh-release. github_output('asset_path', 'dist/*') - version = os.environ['GITHUB_REF'].replace('refs/tags/v', '') + if CI: + version = os.environ['GITHUB_REF'].replace('refs/tags/v', '') + else: + version = subprocess.check_output(['git', 'describe', '--tags']).decode().strip() + github_output('version', version) @@ -590,7 +594,7 @@ def run_docker_tests(session, image_tag): run_integration_test( session, [ "--sut", - f"{docker_run_cmd} --entrypoint {binary_name} {image_tag}", + f"{docker_run_cmd} {image_tag} {binary_name}", "--env-file-cmd-placeholder", "ENVFILE", ]