diff --git a/.copier-answers.image-template.yml b/.copier-answers.image-template.yml new file mode 100644 index 00000000..9cd1d907 --- /dev/null +++ b/.copier-answers.image-template.yml @@ -0,0 +1,15 @@ +# Changes here will be overwritten by Copier; do NOT edit manually +_commit: v0.1.3 +_src_path: https://github.com/Tecnativa/image-template.git +dockerhub_image: "" +image_platforms: + - linux/amd64 + - linux/arm64/v8 +main_branches: + - master +project_name: docker-duplicity +project_owner: Tecnativa +push_to_ghcr: true +pytest: true +python_versions: + - "3.9" diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml deleted file mode 100644 index 0994493b..00000000 --- a/.github/workflows/cd.yaml +++ /dev/null @@ -1,221 +0,0 @@ -name: cd - -on: - pull_request: - push: - branches: [master] - workflow_dispatch: - inputs: - pytest_addopts: - description: - Extra options for pytest; use -vv for full details; see - https://docs.pytest.org/en/latest/example/simple.html#how-to-change-command-line-options-defaults - required: false - -env: - DOCKER_BUILDKIT: 1 - PUSH: ${{ toJSON(github.ref == 'refs/heads/master') }} - PLATFORMS: linux/amd64 - LANG: "en_US.utf-8" - LC_ALL: "en_US.utf-8" - PIP_CACHE_DIR: ${{ github.workspace }}/.cache.~/pip - PIPX_HOME: ${{ github.workspace }}/.cache.~/pipx - POETRY_CACHE_DIR: ${{ github.workspace }}/.cache.~/pypoetry - POETRY_VIRTUALENVS_IN_PROJECT: "true" - PYTEST_ADDOPTS: ${{ github.event.inputs.pytest_addopts }} - PYTHONIOENCODING: "UTF-8" - -jobs: - pre-commit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - - uses: pre-commit/action@v2.0.0 - - build-push: - runs-on: ubuntu-latest - needs: pre-commit - env: - DOCKER_REPO: tecnativa/docker-duplicity - DOCKERHUB_REPO: tecnativa/duplicity - steps: - - uses: actions/checkout@v2 - # TODO Use YAML anchors when available - # Get git metadata (see https://github.com/docker/build-push-action#handle-tags-and-labels) - - name: Docker meta - id: docker_meta - uses: crazy-max/ghaction-docker-meta@v1 - with: - images: ${{ env.DOCKER_REPO }} # list of Docker images to use as base name for tags - tag-sha: true # add git short SHA as Docker tag - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - # Build images for testing - - name: Build :docker-s3 - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - # HACK: Build single platform image for testing. See https://github.com/docker/buildx/issues/59 - load: true - push: false - tags: | - docker-duplicity-local:docker-s3 - target: docker-s3 - labels: ${{ steps.docker_meta.outputs.labels }} - - name: Build :postgres-s3 - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - # HACK: Build single platform image for testing. See https://github.com/docker/buildx/issues/59 - load: true - push: false - tags: | - docker-duplicity-local:postgres-s3 - target: postgres-s3 - labels: ${{ steps.docker_meta.outputs.labels }} - - name: Build :docker - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - # HACK: Build single platform image for testing. See https://github.com/docker/buildx/issues/59 - load: true - push: false - tags: | - docker-duplicity-local:docker - target: docker - labels: ${{ steps.docker_meta.outputs.labels }} - - name: Build :postgres - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - # HACK: Build single platform image for testing. See https://github.com/docker/buildx/issues/59 - load: true - push: false - tags: | - docker-duplicity-local:postgres - target: postgres - labels: ${{ steps.docker_meta.outputs.labels }} - - name: Build :latest - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - # HACK: Build single platform image for testing. See https://github.com/docker/buildx/issues/59 - load: true - push: false - tags: | - docker-duplicity-local:latest - target: latest - labels: ${{ steps.docker_meta.outputs.labels }} - # Set up and run tests - - name: Install python - uses: actions/setup-python@v1 - with: - python-version: "3.9" - - name: Generate cache key CACHE - run: - echo "CACHE=${{ secrets.CACHE_DATE }} ${{ runner.os }} $(python -VV | - sha256sum | cut -d' ' -f1) ${{ hashFiles('pyproject.toml') }} ${{ - hashFiles('poetry.lock') }}" >> $GITHUB_ENV - - uses: actions/cache@v2 - with: - path: | - .cache.~ - .venv - ~/.local/bin - key: venv ${{ env.CACHE }} - - run: pip install poetry - - name: Patch $PATH - run: echo "$HOME/.local/bin" >> $GITHUB_PATH - - name: Install dependencies - run: sudo apt install -y gettext librsync-dev - - run: poetry install - - run: poetry run pytest - env: - DOCKER_IMAGE_NAME: docker-duplicity-local - # Build and push stable images to DockerHub and to GHCR - - name: Login to DockerHub - if: ${{ fromJSON(env.PUSH) }} - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - name: Login to GitHub Container Registry - if: ${{ fromJSON(env.PUSH) }} - uses: docker/login-action@v1 - with: - registry: ghcr.io - username: ${{ secrets.BOT_LOGIN }} - password: ${{ secrets.BOT_TOKEN }} - - name: Build and push :docker-s3 - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - platforms: ${{ env.PLATFORMS }} - load: false - push: ${{ fromJSON(env.PUSH) }} - tags: | - ghcr.io/${{ env.DOCKER_REPO }}:docker-s3 - ${{ env.DOCKERHUB_REPO }}:docker-s3 - target: docker-s3 - labels: ${{ steps.docker_meta.outputs.labels }} - - name: Build and push :postgres-s3 - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - platforms: ${{ env.PLATFORMS }} - load: false - push: ${{ fromJSON(env.PUSH) }} - tags: | - ghcr.io/${{ env.DOCKER_REPO }}:postgres-s3 - ${{ env.DOCKERHUB_REPO }}:postgres-s3 - target: postgres-s3 - labels: ${{ steps.docker_meta.outputs.labels }} - - name: Build and push :docker - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - platforms: ${{ env.PLATFORMS }} - load: false - push: ${{ fromJSON(env.PUSH) }} - tags: | - ghcr.io/${{ env.DOCKER_REPO }}:docker - ${{ env.DOCKERHUB_REPO }}:docker - target: docker - labels: ${{ steps.docker_meta.outputs.labels }} - - name: Build and push :postgres - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - platforms: ${{ env.PLATFORMS }} - load: false - push: ${{ fromJSON(env.PUSH) }} - tags: | - ghcr.io/${{ env.DOCKER_REPO }}:postgres - ${{ env.DOCKERHUB_REPO }}:postgres - target: postgres - labels: ${{ steps.docker_meta.outputs.labels }} - - name: Build and push :latest - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - platforms: ${{ env.PLATFORMS }} - load: false - push: ${{ fromJSON(env.PUSH) }} - tags: | - ghcr.io/${{ env.DOCKER_REPO }}:latest - ${{ env.DOCKERHUB_REPO }}:latest - target: latest - labels: ${{ steps.docker_meta.outputs.labels }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..5fe59f72 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,165 @@ +name: Build, Test & Deploy + +"on": + pull_request: + push: + branches: + - master + tags: + - "v*" + workflow_dispatch: + inputs: + pytest_addopts: + description: + Extra options for pytest; use -vv for full details; see + https://docs.pytest.org/en/latest/example/simple.html#how-to-change-command-line-options-defaults + required: false + +env: + LANG: "en_US.utf-8" + LC_ALL: "en_US.utf-8" + PIP_CACHE_DIR: ${{ github.workspace }}/.cache.~/pip + PIPX_HOME: ${{ github.workspace }}/.cache.~/pipx + POETRY_CACHE_DIR: ${{ github.workspace }}/.cache.~/pypoetry + POETRY_VIRTUALENVS_IN_PROJECT: "true" + PYTEST_ADDOPTS: ${{ github.event.inputs.pytest_addopts }} + PYTHONIOENCODING: "UTF-8" + +jobs: + build-test: + runs-on: ubuntu-20.04 + strategy: + matrix: + python: + - 3.9 + steps: + # Prepare environment + - uses: actions/checkout@v2 + # Set up and run tests + - name: Install python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + - name: Generate cache key CACHE + run: + echo "CACHE=${{ secrets.CACHE_DATE }} ${{ runner.os }} $(python -VV | + sha256sum | cut -d' ' -f1) ${{ hashFiles('pyproject.toml') }} ${{ + hashFiles('poetry.lock') }}" >> $GITHUB_ENV + - uses: actions/cache@v2 + with: + path: | + .cache.~ + .venv + ~/.local/bin + key: venv ${{ env.CACHE }} + - run: pip install poetry + - name: Patch $PATH + run: echo "$HOME/.local/bin" >> $GITHUB_PATH + - run: poetry install + # Run tests + - run: poetry run pytest --prebuild + build-push: + runs-on: ubuntu-20.04 + services: + registry: + image: registry:2 + ports: + - 5000:5000 + env: + DOCKER_IMAGE_NAME: ${{ github.repository }} + PUSH: ${{ toJSON(github.event_name != 'pull_request') }} + strategy: + matrix: + target: + - base + - docker + - docker-s3 + - postgres + - postgres-s3 + - s3 + steps: + # Set up Docker Environment + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: | + /tmp/.buildx-cache + key: buildx|${{ secrets.CACHE_DATE }}|${{ runner.os }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + with: + driver-opts: network=host + install: true + # Build and push + - name: Compute image name + id: image_name_compute + run: | + if [ "${{ matrix.target }}" = "base" ]; then + echo "::set-output name=image_name::${{ env.DOCKER_IMAGE_NAME }}" + else + echo "::set-output name=image_name::${{ env.DOCKER_IMAGE_NAME }}-${{ matrix.target }}" + fi + - name: Docker meta for local images + id: docker_meta_local + uses: crazy-max/ghaction-docker-meta@v1 + with: + images: localhost:5000/${{ steps.image_name_compute.outputs.image_name }} + tag-edge: true + tag-semver: | + {{version}} + {{major}} + {{major}}.{{minor}} + - name: Build and push to local (test) registry + uses: docker/build-push-action@v2 + with: + context: . + file: ./Dockerfile + platforms: | + linux/amd64 + linux/arm64/v8 + load: false + push: true + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache,mode=max + labels: ${{ steps.docker_meta_local.outputs.labels }} + tags: ${{ steps.docker_meta_local.outputs.tags }} + target: ${{ matrix.target }} + # Next jobs only happen outside of pull requests and on main branches + - name: Login to GitHub Container Registry + if: ${{ fromJSON(env.PUSH) }} + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ secrets.BOT_LOGIN }} + password: ${{ secrets.BOT_TOKEN }} + - name: Docker meta for public images + if: ${{ fromJSON(env.PUSH) }} + id: docker_meta_public + uses: crazy-max/ghaction-docker-meta@v1 + with: + images: | + ghcr.io/${{ steps.image_name_compute.outputs.image_name }} + tag-edge: true + tag-semver: | + {{version}} + {{major}} + {{major}}.{{minor}} + - name: Build and push to public registry(s) + if: ${{ fromJSON(env.PUSH) }} + uses: docker/build-push-action@v2 + with: + context: . + file: ./Dockerfile + platforms: | + linux/amd64 + linux/arm64/v8 + load: false + push: true + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache,mode=max + labels: ${{ steps.docker_meta_public.outputs.labels }} + tags: ${{ steps.docker_meta_public.outputs.tags }} + target: ${{ matrix.target }} diff --git a/Dockerfile b/Dockerfile index 22e3c1db..2691584f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3-alpine AS latest +FROM python:3-alpine AS base ENV CRONTAB_15MIN='*/15 * * * *' \ CRONTAB_HOURLY='0 * * * *' \ @@ -71,13 +71,13 @@ RUN apk add --no-cache --virtual .build \ COPY bin/* /usr/local/bin/ RUN chmod a+rx /usr/local/bin/* && sync -FROM latest AS latest-s3 +FROM base AS s3 ENV JOB_500_WHAT='dup full $SRC $DST' \ JOB_500_WHEN='weekly' \ OPTIONS_EXTRA='--metadata-sync-mode partial --full-if-older-than 1W --file-prefix-archive archive-$(hostname -f)- --file-prefix-manifest manifest-$(hostname -f)- --file-prefix-signature signature-$(hostname -f)- --s3-european-buckets --s3-multipart-chunk-size 10 --s3-use-new-style' -FROM latest AS docker +FROM base AS docker RUN apk add --no-cache docker-cli @@ -87,7 +87,7 @@ ENV JOB_500_WHAT='dup full $SRC $DST' \ OPTIONS_EXTRA='--metadata-sync-mode partial --full-if-older-than 1W --file-prefix-archive archive-$(hostname -f)- --file-prefix-manifest manifest-$(hostname -f)- --file-prefix-signature signature-$(hostname -f)- --s3-european-buckets --s3-multipart-chunk-size 10 --s3-use-new-style' -FROM latest AS postgres +FROM base AS postgres RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.13/main postgresql-client \ && psql --version \ diff --git a/README.md b/README.md index b5e6c771..4b78793e 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ -# Duplicity Cron Runner +[![Last image-template](https://img.shields.io/badge/last%20template%20update-v0.1.3-informational)](https://github.com/Tecnativa/image-template/tree/v0.1.3) +[![GitHub Container Registry](https://img.shields.io/badge/GitHub%20Container%20Registry-latest-%2324292e)](https://github.com/orgs/Tecnativa/packages/container/package/docker-duplicity) -[![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/tecnativa/duplicity)](https://hub.docker.com/r/tecnativa/duplicity/) -![MicroBadger Layers](https://img.shields.io/microbadger/layers/tecnativa/duplicity) -![GitHub](https://img.shields.io/github/license/tecnativa/docker-duplicity) +# Duplicity Cron Runner
@@ -13,6 +12,8 @@ - [Why?](#why) - [How?](#how) - [Where?](#where) +- [Available images](#available-images) +- [Tags](#tags) - [Environment variables available](#environment-variables-available) - [`CRONTAB_{15MIN,HOURLY,DAILY,WEEKLY,MONTHLY}`](#crontab_15minhourlydailyweeklymonthly) - [`DBS_TO_EXCLUDE`](#dbs_to_exclude) @@ -37,10 +38,13 @@ - [Shortcuts](#shortcuts) - [Testing your configuration](#testing-your-configuration) - [Prebuilt flavors](#prebuilt-flavors) - - [Normal (`latest`)](#normal-latest) - - [PostgreSQL (`postgres`)](#postgresql-postgres) - - [Docker (`docker`)](#docker-docker) + - [Normal (`docker-duplicity`)](#normal-docker-duplicity) + - [PostgreSQL (`docker-duplicity-postgres`)](#postgresql-docker-duplicity-postgres) + - [Docker (`docker-duplicity-docker`)](#docker-docker-duplicity-docker) - [Amazon S3 (`*-s3`)](#amazon-s3--s3) +- [Development](#development) + - [Testing](#testing) + - [Managing packages](#managing-packages)
@@ -65,8 +69,26 @@ and sending an email report automatically. ## Where? - [Source code](https://github.com/Tecnativa/docker-duplicity). -- [Prebuilt images in GitHub package registry](https://github.com/Tecnativa/docker-duplicity/packages/212851). -- [Prebuilt images in Docker Hub](https://hub.docker.com/r/tecnativa/duplicity). +- [Prebuilt images in GitHub package registry](https://github.com/Tecnativa/docker-duplicity/packages/). + +## Available images + +Each of the built-in [flavors][flavors] is separated into a specific docker image: + +- [`docker-duplicity`](https://github.com/orgs/Tecnativa/packages/container/package/docker-duplicity) +- [`docker-duplicity-s3`](https://github.com/orgs/Tecnativa/packages/container/package/docker-duplicity-s3) +- [`docker-duplicity-docker`](https://github.com/orgs/Tecnativa/packages/container/package/docker-duplicity-docker) +- [`docker-duplicity-docker-s3`](https://github.com/orgs/Tecnativa/packages/container/package/docker-duplicity-docker-s3) +- [`docker-duplicity-postgres`](https://github.com/orgs/Tecnativa/packages/container/package/docker-duplicity-postgres) +- [`docker-duplicity-postgres-s3`](https://github.com/orgs/Tecnativa/packages/container/package/docker-duplicity-postgres-s3) + +Check the [section bellow][flavors] to get more info. + +## Tags + +Each of the images mentioned above are tagged with `:latest`, referring to the latest +_tagged_ version in git, and `:egde`, referring to the latest version in the `master` +branch. Each individual git released version is also tagged (e.g. `:0.1.0`) ## Environment variables available @@ -242,7 +264,7 @@ Add jobs through environment variable pairs. The order will be followed. Refer to [Duplicity man page](http://duplicity.nongnu.org/duplicity.1.html), or execute: - docker run -it --rm tecnativa/duplicity duplicity --help + docker run -it --rm ghcr.io/tecnativa/docker-duplicity duplicity --help ### Shortcuts @@ -269,7 +291,7 @@ Replace `daily` by any other periodicity to test it too. Sometimes you need more than just copying a file here, pasting it there. That's why we supply some special flavours of this image. -### Normal (`latest`) +### Normal (`docker-duplicity`) This includes just the most basic packages to boot the cron and use Duplicity with any backend. All other images are built on top of this one, so downloading several flavours @@ -282,7 +304,7 @@ It's [preconfigured][dockerfile] to backup daily: JOB_300_WHEN=daily ``` -### PostgreSQL (`postgres`) +### PostgreSQL (`docker-duplicity-postgres`) If you want to back up a PostgreSQL server, make sure you run this image in a fashion similar to this `docker-compose.yaml` definition: @@ -296,7 +318,7 @@ services: POSTGRES_USER: myuser POSTGRES_DB: mydb backup: - image: tecnativa/duplicity:postgres + image: ghcr.io/tecnativa/docker-duplicity-postgres hostname: my.postgres.backup environment: # Postgres connection @@ -322,7 +344,7 @@ It will make [dumps automatically][dockerfile]: JOB_200_WHEN=daily weekly ``` -### Docker (`docker`) +### Docker (`docker-duplicity-docker`) Imagine you need to run some command in another container to generate a backup file before actually backing it up in a remote place. @@ -351,7 +373,7 @@ services: - data:/var/opt/gitlab:z - logs:/var/log/gitlab:z backup: - image: tecnativa/duplicity:docker + image: ghcr.io/tecnativa/docker-duplicity-docker hostname: backup domainname: gitlab.example.com privileged: true # To speak with host's docker socket @@ -399,3 +421,77 @@ Note, that for `DST` variable you should use `boto3+s3://bucket_name[/prefix]` s [options]: http://duplicity.nongnu.org/vers8/duplicity.1.html#sect5 [postgresql]: https://www.postgresql.org/ [tzdata]: https://pkgs.alpinelinux.org/package/edge/main/aarch64/tzdata + +## Development + +All the dependencies you need to develop this project (apart from Docker itself) are +managed with [poetry](https://python-poetry.org/). + +To set up your development environment, run: + +```bash +pip install pipx # If you don't have pipx installed +pipx install poetry # Install poetry itself +poetry install # Install the python dependencies and setup the development environment +``` + +### Testing + +To run the tests locally, add `--prebuild` to autobuild the image before testing: + +```sh +poetry run pytest --prebuild +``` + +By default, the image that the tests use (and optionally prebuild) is named +`test:docker-duplicity`. If you prefer, you can build it separately before testing, and +remove the `--prebuild` flag, to run the tests with that image you built: + +```sh +docker image build -t test:docker-duplicity . +poetry run pytest +``` + +If you want to use a different image, pass the `--image` command line argument with the +name you want: + +```sh +# To build it automatically +poetry run pytest --prebuild --image my_custom_image + +# To prebuild it separately +docker image build -t my_custom_image . +poetry run pytest --image my_custom_image +``` + +### Managing packages + +The poetry project configuration (in the `pyproject.toml` file) includes a section which +contains the duplicity dependencies themselves. This allows us to manage those more +easily and avoid future conflicts. Those are then exported into a `requirements.txt` +file in this repo, which is the one that is used inside the container. + +So, if you need to add a new duplicity dependency to be used inside the container, the +correct process would be: + +1. Add the dependency to the poetry project with: + + ```bash + poetry add --optional MY_NEW_PACKAGE + ``` + + Note that it should be marked as an **optional** dependency, as it will not be used + in general development _outside_ the container. + + The new optional dependency should then be added to the duplicity list in the + `[tool.poetry.extras]` section of `pyproject.toml` + + ```toml + [tool.poetry.extras] + duplicity = ["b2", "b2sdk", "boto", "boto3", "gdata", "jottalib", "paramiko", "pexpect", "PyDrive", "pyrax", "python", "requests", "duplicity", "dropbox", "python", "mediafire", "MY_NEW_PACKAGE"] + ``` + +1. Export the new poetry-resolved list of packages to the `requirements.txt` file: + ```bash + poetry export -E duplicity -o requirements.txt` + ``` diff --git a/poetry.lock b/poetry.lock index e4f00a04..1fe7418c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -19,7 +19,7 @@ name = "argparse" version = "1.4.0" description = "Python command-line parsing library" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -27,7 +27,7 @@ name = "args" version = "0.1.0" description = "Command Arguments for Humans." category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -35,7 +35,7 @@ name = "arrow" version = "0.17.0" description = "Better dates & times for Python" category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] @@ -68,7 +68,7 @@ name = "b2" version = "2.1.0" description = "Command Line Tool for Backblaze B2" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -84,7 +84,7 @@ name = "b2sdk" version = "1.2.0" description = "Backblaze B2 SDK" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -101,7 +101,7 @@ name = "babel" version = "2.9.0" description = "Internationalization utilities" category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] @@ -112,7 +112,7 @@ name = "bcrypt" version = "3.2.0" description = "Modern password hashing for your software and your servers" category = "main" -optional = false +optional = true python-versions = ">=3.6" [package.dependencies] @@ -150,49 +150,49 @@ name = "boto" version = "2.49.0" description = "Amazon Web Services Library" category = "main" -optional = false +optional = true python-versions = "*" [[package]] name = "boto3" -version = "1.16.28" +version = "1.17.2" description = "The AWS SDK for Python" category = "main" -optional = false -python-versions = "*" +optional = true +python-versions = ">= 2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [package.dependencies] -botocore = ">=1.19.28,<1.20.0" +botocore = ">=1.20.2,<1.21.0" jmespath = ">=0.7.1,<1.0.0" s3transfer = ">=0.3.0,<0.4.0" [[package]] name = "botocore" -version = "1.19.28" +version = "1.20.2" description = "Low-level, data-driven core of boto 3." category = "main" -optional = false -python-versions = "*" +optional = true +python-versions = ">= 2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [package.dependencies] jmespath = ">=0.7.1,<1.0.0" python-dateutil = ">=2.1,<3.0.0" -urllib3 = {version = ">=1.25.4,<1.27", markers = "python_version != \"3.4\""} +urllib3 = ">=1.25.4,<1.27" [[package]] name = "cachetools" -version = "4.1.1" +version = "4.2.1" description = "Extensible memoizing collections and decorators" category = "main" -optional = false +optional = true python-versions = "~=3.5" [[package]] name = "certifi" -version = "2020.11.8" +version = "2020.12.5" description = "Python package for providing Mozilla's CA Bundle." category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -200,7 +200,7 @@ name = "cffi" version = "1.14.4" description = "Foreign Function Interface for Python calling C code." category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -208,11 +208,11 @@ pycparser = "*" [[package]] name = "chardet" -version = "3.0.4" +version = "4.0.0" description = "Universal encoding detector for Python 2 and 3" category = "main" -optional = false -python-versions = "*" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "click" @@ -227,7 +227,7 @@ name = "clint" version = "0.5.1" description = "Python Command Line Interface Tools" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -243,14 +243,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "cryptography" -version = "3.2.1" +version = "3.3.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +optional = true +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" [package.dependencies] -cffi = ">=1.8,<1.11.3 || >1.11.3" +cffi = ">=1.12" six = ">=1.4.1" [package.extras] @@ -265,7 +265,7 @@ name = "debtcollector" version = "1.11.0" description = "A collection of Python deprecation patterns and strategies that help you collect your technical debt in a non-destructive manner." category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -278,7 +278,7 @@ name = "dropbox" version = "8.3.1" description = "Official Dropbox API Client" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -288,10 +288,10 @@ urllib3 = "*" [[package]] name = "duplicity" -version = "0.8.17" +version = "0.8.18" description = "Encrypted backup using rsync algorithm" category = "main" -optional = false +optional = true python-versions = ">2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.dependencies] @@ -300,11 +300,11 @@ future = "*" [[package]] name = "execnet" -version = "1.7.1" +version = "1.8.0" description = "execnet: rapid multi-Python deployment" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] apipkg = ">=1.4" @@ -314,14 +314,13 @@ testing = ["pre-commit"] [[package]] name = "fasteners" -version = "0.15" +version = "0.16" description = "A python package that provides useful locks." category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] -monotonic = ">=0.1" six = "*" [[package]] @@ -342,7 +341,7 @@ name = "funcsigs" version = "1.0.2" description = "Python function signatures from PEP362 for Python 2.6, 2.7 and 3.2+" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -350,7 +349,7 @@ name = "future" version = "0.18.2" description = "Clean single-source support for Python 3 and 2" category = "main" -optional = false +optional = true python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] @@ -358,7 +357,7 @@ name = "gdata" version = "2.0.18" description = "Python client library for Google data APIs" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -366,7 +365,7 @@ name = "google-api-python-client" version = "1.7.12" description = "Google API Client Library for Python" category = "main" -optional = false +optional = true python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" [package.dependencies] @@ -378,16 +377,16 @@ uritemplate = ">=3.0.0,<4dev" [[package]] name = "google-auth" -version = "1.23.0" +version = "1.25.0" description = "Google Authentication Library" category = "main" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +optional = true +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" [package.dependencies] cachetools = ">=2.0.0,<5.0" pyasn1-modules = ">=0.2.1" -rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.5\""} +rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""} six = ">=1.9.0" [package.extras] @@ -398,7 +397,7 @@ name = "google-auth-httplib2" version = "0.0.4" description = "Google Authentication Library: httplib2 transport" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -411,15 +410,15 @@ name = "httplib2" version = "0.18.1" description = "A comprehensive HTTP client library." category = "main" -optional = false +optional = true python-versions = "*" [[package]] name = "humanize" -version = "3.1.0" +version = "3.2.0" description = "Python humanize utilities" category = "main" -optional = false +optional = true python-versions = ">=3.6" [package.extras] @@ -438,7 +437,7 @@ name = "ip-associations-python-novaclient-ext" version = "0.2" description = "Adds Rackspace ip_associations support to python-novaclient" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -449,7 +448,7 @@ name = "iso8601" version = "0.1.13" description = "Simple module to parse ISO 8601 dates" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -457,7 +456,7 @@ name = "jeepney" version = "0.6.0" description = "Low-level, pure Python DBus protocol wrapper." category = "main" -optional = false +optional = true python-versions = ">=3.6" [package.extras] @@ -468,7 +467,7 @@ name = "jmespath" version = "0.10.0" description = "JSON Matching Expressions" category = "main" -optional = false +optional = true python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] @@ -476,7 +475,7 @@ name = "jottalib" version = "0.5.1" description = "A library and tools to access the JottaCloud API" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -498,10 +497,10 @@ scanner = ["xattr"] [[package]] name = "keyring" -version = "21.5.0" +version = "22.0.1" description = "Store and access your passwords safely." category = "main" -optional = false +optional = true python-versions = ">=3.6" [package.dependencies] @@ -510,15 +509,15 @@ pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_ SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} [package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] [[package]] name = "keystoneauth1" version = "2.18.0" description = "Authentication Library for OpenStack Identity" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -540,7 +539,7 @@ name = "logfury" version = "0.1.2" description = "Toolkit for responsible, low-boilerplate logging of library method calls" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -555,7 +554,7 @@ name = "lxml" version = "4.6.2" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" [package.extras] @@ -577,7 +576,7 @@ name = "mediafire" version = "0.6.0" description = "Python MediaFire client library" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -587,23 +586,23 @@ six = ">=1.8.0" [[package]] name = "mock" -version = "4.0.2" +version = "4.0.3" description = "Rolling backport of unittest.mock for all Pythons" category = "main" -optional = false +optional = true python-versions = ">=3.6" [package.extras] build = ["twine", "wheel", "blurb"] docs = ["sphinx"] -test = ["pytest", "pytest-cov"] +test = ["pytest (<5.4)", "pytest-cov"] [[package]] name = "monotonic" version = "1.5" description = "An implementation of time.monotonic() for Python 2 & < 3.3" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -611,7 +610,7 @@ name = "msgpack-python" version = "0.5.6" description = "MessagePack (de)serializer." category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -627,7 +626,7 @@ name = "netaddr" version = "0.8.0" description = "A network address manipulation library for Python" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -635,7 +634,7 @@ name = "netifaces" version = "0.10.9" description = "Portable network interface information." category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -643,7 +642,7 @@ name = "oauth2client" version = "4.1.3" description = "OAuth 2.0 client library" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -658,7 +657,7 @@ name = "oauthlib" version = "3.1.0" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] @@ -671,7 +670,7 @@ name = "os-diskconfig-python-novaclient-ext" version = "0.1.3" description = "Disk Config extension for python-novaclient" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -682,7 +681,7 @@ name = "os-networksv2-python-novaclient-ext" version = "0.26" description = "Adds rackspace networks support to python-novaclient" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -693,7 +692,7 @@ name = "os-virtual-interfacesv2-python-novaclient-ext" version = "0.20" description = "Adds Virtual Interfaces support to python-novaclient" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -704,7 +703,7 @@ name = "oslo.config" version = "4.12.0" description = "Oslo Configuration API" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -721,7 +720,7 @@ name = "oslo.i18n" version = "3.12.0" description = "Oslo i18n library" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -734,7 +733,7 @@ name = "oslo.serialization" version = "2.16.1" description = "Oslo Serialization library" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -749,7 +748,7 @@ name = "oslo.utils" version = "3.22.3" description = "Oslo Utility library" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -766,7 +765,7 @@ six = ">=1.9.0" [[package]] name = "packaging" -version = "20.8" +version = "20.9" description = "Core utilities for Python packages" category = "dev" optional = false @@ -780,7 +779,7 @@ name = "paramiko" version = "2.7.2" description = "SSH2 protocol library" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -807,7 +806,7 @@ name = "pbr" version = "1.10.0" description = "Python Build Reasonableness" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -815,7 +814,7 @@ name = "pexpect" version = "4.8.0" description = "Pexpect allows easy control of interactive console applications." category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -826,7 +825,7 @@ name = "phx-class-registry" version = "3.0.5" description = "Factory+Registry pattern for Python classes." category = "main" -optional = false +optional = true python-versions = "*" [package.extras] @@ -857,7 +856,7 @@ name = "positional" version = "1.2.1" description = "Library to enforce positional or key-word arguments (deprecated/unmaintained)" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -869,15 +868,15 @@ name = "prettytable" version = "0.7.2" description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format." category = "main" -optional = false +optional = true python-versions = "*" [[package]] name = "ptyprocess" -version = "0.6.0" +version = "0.7.0" description = "Run a subprocess in a pseudo terminal" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -893,7 +892,7 @@ name = "pyasn1" version = "0.4.8" description = "ASN.1 types and codecs" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -901,7 +900,7 @@ name = "pyasn1-modules" version = "0.2.8" description = "A collection of ASN.1-based protocols modules." category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -920,7 +919,7 @@ name = "pycparser" version = "2.20" description = "C parser in Python" category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] @@ -928,7 +927,7 @@ name = "pydrive" version = "1.3.1" description = "Google Drive API made easy." category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -949,7 +948,7 @@ name = "pynacl" version = "1.4.0" description = "Python binding to the Networking and Cryptography (NaCl) library" category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] @@ -973,7 +972,7 @@ name = "pyrax" version = "1.9.8" description = "Python language bindings for OpenStack Clouds." category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -986,7 +985,7 @@ six = ">=1.9.0,<2" [[package]] name = "pytest" -version = "6.2.1" +version = "6.2.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -1039,7 +1038,7 @@ name = "python-dateutil" version = "2.8.1" description = "Extensions to the standard Python datetime module" category = "main" -optional = false +optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" [package.dependencies] @@ -1050,7 +1049,7 @@ name = "python-keystoneclient" version = "3.10.0" description = "Client Library for OpenStack Identity" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1071,7 +1070,7 @@ name = "python-novaclient" version = "2.27.0" description = "Client library for OpenStack Compute API" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1090,10 +1089,10 @@ six = ">=1.9.0" [[package]] name = "python-swiftclient" -version = "3.10.1" +version = "3.11.0" description = "OpenStack Object Storage API Client Library" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1102,14 +1101,14 @@ six = ">=1.9.0" [package.extras] keystone = ["python-keystoneclient (>=0.7.0)"] -test = ["coverage (>=4.0,!=4.4)", "hacking (>=1.1.0,<1.2.0)", "keystoneauth1 (>=3.4.0)", "mock (>=1.2.0)", "openstacksdk (>=0.11.0)", "stestr (>=2.0.0,!=3.0.0)"] +test = ["coverage (>=4.0,!=4.4)", "keystoneauth1 (>=3.4.0)", "mock (>=1.2.0)", "openstacksdk (>=0.11.0)", "stestr (>=2.0.0,!=3.0.0)", "hacking (>=1.1.0,<1.2.0)", "hacking (>=3.2.0,<3.3.0)"] [[package]] name = "pytz" -version = "2020.4" +version = "2021.1" description = "World timezone definitions, modern and historical" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -1117,23 +1116,23 @@ name = "pywin32-ctypes" version = "0.2.0" description = "" category = "main" -optional = false +optional = true python-versions = "*" [[package]] name = "pyyaml" -version = "5.3.1" +version = "5.4.1" description = "YAML parser and emitter for Python" category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "rackspace-auth-openstack" version = "1.3" description = "Rackspace Auth Plugin for OpenStack Clients." category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1144,7 +1143,7 @@ name = "rackspace-novaclient" version = "2.1" description = "Metapackage to install python-novaclient and Rackspace extensions" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1162,7 +1161,7 @@ name = "rax-default-network-flags-python-novaclient-ext" version = "0.4.0" description = "Novaclient Extension for Instance Default Network Flags" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1173,7 +1172,7 @@ name = "rax-scheduled-images-python-novaclient-ext" version = "0.3.1" description = "Extends python-novaclient to use RAX-SI, the Rackspace Nova API Scheduled Images extension" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1192,7 +1191,7 @@ name = "requests" version = "2.11.1" description = "Python HTTP for Humans." category = "main" -optional = false +optional = true python-versions = "*" [package.extras] @@ -1204,7 +1203,7 @@ name = "requests-oauthlib" version = "1.3.0" description = "OAuthlib authentication support for Requests." category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] @@ -1219,7 +1218,7 @@ name = "requests-toolbelt" version = "0.9.1" description = "A utility belt for advanced users of python-requests" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1230,7 +1229,7 @@ name = "rfc3986" version = "1.4.0" description = "Validating URI References per RFC 3986" category = "main" -optional = false +optional = true python-versions = "*" [package.extras] @@ -1238,10 +1237,10 @@ idna2008 = ["idna"] [[package]] name = "rsa" -version = "4.6" +version = "4.7" description = "Pure-Python RSA implementation" category = "main" -optional = false +optional = true python-versions = ">=3.5, <4" [package.dependencies] @@ -1249,10 +1248,10 @@ pyasn1 = ">=0.1.3" [[package]] name = "s3transfer" -version = "0.3.3" +version = "0.3.4" description = "An Amazon S3 Transfer Manager" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1263,7 +1262,7 @@ name = "secretstorage" version = "3.3.0" description = "Python bindings to FreeDesktop.org Secret Service API" category = "main" -optional = false +optional = true python-versions = ">=3.6" [package.dependencies] @@ -1275,7 +1274,7 @@ name = "simplejson" version = "3.17.2" description = "Simple, fast, extensible JSON encoder/decoder for Python" category = "main" -optional = false +optional = true python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] @@ -1283,7 +1282,7 @@ name = "six" version = "1.15.0" description = "Python 2 and 3 compatibility utilities" category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] @@ -1291,7 +1290,7 @@ name = "stevedore" version = "1.20.1" description = "Manage dynamic plugins for Python applications" category = "main" -optional = false +optional = true python-versions = "*" [package.dependencies] @@ -1308,14 +1307,15 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tqdm" -version = "4.54.0" +version = "4.56.0" description = "Fast, Extensible Progress Meter" category = "main" -optional = false +optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" [package.extras] -dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown", "wheel"] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +telegram = ["requests"] [[package]] name = "typed-ast" @@ -1338,15 +1338,15 @@ name = "uritemplate" version = "3.0.1" description = "URI templates" category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "urllib3" -version = "1.26.2" +version = "1.26.3" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] @@ -1359,13 +1359,16 @@ name = "wrapt" version = "1.12.1" description = "Module for decorators, wrappers and monkey patching." category = "main" -optional = false +optional = true python-versions = "*" +[extras] +duplicity = ["b2", "b2sdk", "boto", "boto3", "gdata", "jottalib", "paramiko", "pexpect", "PyDrive", "pyrax", "duplicity", "dropbox", "mediafire"] + [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "30c044bde1b7a92d2eeb7861eeaf4a7146c1b40f98e4dfe187b8c7a7e6c51e2c" +content-hash = "7e68e335688f74be39d2f809777268680a8d76af79d22879459421edf1025342" [metadata.files] apipkg = [ @@ -1422,20 +1425,20 @@ boto = [ {file = "boto-2.49.0.tar.gz", hash = "sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a"}, ] boto3 = [ - {file = "boto3-1.16.28-py2.py3-none-any.whl", hash = "sha256:ca62b4517ddb6a81a9b0113cca05b2dba5faab14d2b35b81f402b052955738c5"}, - {file = "boto3-1.16.28.tar.gz", hash = "sha256:7f44988fc605fa264046d7d16f773836ac1e8b3f6721b79ba796b875bbf9ea75"}, + {file = "boto3-1.17.2-py2.py3-none-any.whl", hash = "sha256:6a7f9e2fb631d39bd089cb7e83b4a8ce5e572bdc6545ac51b761bd9ea2ad80c6"}, + {file = "boto3-1.17.2.tar.gz", hash = "sha256:1a282c1cd7d5028cbb3a75d747df32162295253f55d263ac85840e264830963b"}, ] botocore = [ - {file = "botocore-1.19.28-py2.py3-none-any.whl", hash = "sha256:d8dab9b74dc0ad2e5439e5ea3c119e234d2f02952f37f379d9a74adfa305ed75"}, - {file = "botocore-1.19.28.tar.gz", hash = "sha256:97741448e63850895818193c29b93ec6319135587ae4994a6f611ffccb1a978e"}, + {file = "botocore-1.20.2-py2.py3-none-any.whl", hash = "sha256:7442fdbbdc841bfac7f94f92ecb807de070e32ed205743eb72d4ea27c5e8e778"}, + {file = "botocore-1.20.2.tar.gz", hash = "sha256:bf587b044983a91a0124cc133ff167b8528c19fbbc8f0b956d9a1ac256cad7d7"}, ] cachetools = [ - {file = "cachetools-4.1.1-py3-none-any.whl", hash = "sha256:513d4ff98dd27f85743a8dc0e92f55ddb1b49e060c2d5961512855cda2c01a98"}, - {file = "cachetools-4.1.1.tar.gz", hash = "sha256:bbaa39c3dede00175df2dc2b03d0cf18dd2d32a7de7beb68072d13043c9edb20"}, + {file = "cachetools-4.2.1-py3-none-any.whl", hash = "sha256:1d9d5f567be80f7c07d765e21b814326d78c61eb0c3a637dffc0e5d1796cb2e2"}, + {file = "cachetools-4.2.1.tar.gz", hash = "sha256:f469e29e7aa4cff64d8de4aad95ce76de8ea1125a16c68e0d93f65c3c3dc92e9"}, ] certifi = [ - {file = "certifi-2020.11.8-py2.py3-none-any.whl", hash = "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd"}, - {file = "certifi-2020.11.8.tar.gz", hash = "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4"}, + {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, + {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, ] cffi = [ {file = "cffi-1.14.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775"}, @@ -1474,8 +1477,8 @@ cffi = [ {file = "cffi-1.14.4.tar.gz", hash = "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c"}, ] chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, + {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, + {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, @@ -1489,28 +1492,20 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] cryptography = [ - {file = "cryptography-3.2.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:6dc59630ecce8c1f558277ceb212c751d6730bd12c80ea96b4ac65637c4f55e7"}, - {file = "cryptography-3.2.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:75e8e6684cf0034f6bf2a97095cb95f81537b12b36a8fedf06e73050bb171c2d"}, - {file = "cryptography-3.2.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4e7268a0ca14536fecfdf2b00297d4e407da904718658c1ff1961c713f90fd33"}, - {file = "cryptography-3.2.1-cp27-cp27m-win32.whl", hash = "sha256:7117319b44ed1842c617d0a452383a5a052ec6aa726dfbaffa8b94c910444297"}, - {file = "cryptography-3.2.1-cp27-cp27m-win_amd64.whl", hash = "sha256:a733671100cd26d816eed39507e585c156e4498293a907029969234e5e634bc4"}, - {file = "cryptography-3.2.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a75f306a16d9f9afebfbedc41c8c2351d8e61e818ba6b4c40815e2b5740bb6b8"}, - {file = "cryptography-3.2.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:5849d59358547bf789ee7e0d7a9036b2d29e9a4ddf1ce5e06bb45634f995c53e"}, - {file = "cryptography-3.2.1-cp35-abi3-macosx_10_10_x86_64.whl", hash = "sha256:bd717aa029217b8ef94a7d21632a3bb5a4e7218a4513d2521c2a2fd63011e98b"}, - {file = "cryptography-3.2.1-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:efe15aca4f64f3a7ea0c09c87826490e50ed166ce67368a68f315ea0807a20df"}, - {file = "cryptography-3.2.1-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:32434673d8505b42c0de4de86da8c1620651abd24afe91ae0335597683ed1b77"}, - {file = "cryptography-3.2.1-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:7b8d9d8d3a9bd240f453342981f765346c87ade811519f98664519696f8e6ab7"}, - {file = "cryptography-3.2.1-cp35-cp35m-win32.whl", hash = "sha256:d3545829ab42a66b84a9aaabf216a4dce7f16dbc76eb69be5c302ed6b8f4a29b"}, - {file = "cryptography-3.2.1-cp35-cp35m-win_amd64.whl", hash = "sha256:a4e27ed0b2504195f855b52052eadcc9795c59909c9d84314c5408687f933fc7"}, - {file = "cryptography-3.2.1-cp36-abi3-win32.whl", hash = "sha256:13b88a0bd044b4eae1ef40e265d006e34dbcde0c2f1e15eb9896501b2d8f6c6f"}, - {file = "cryptography-3.2.1-cp36-abi3-win_amd64.whl", hash = "sha256:07ca431b788249af92764e3be9a488aa1d39a0bc3be313d826bbec690417e538"}, - {file = "cryptography-3.2.1-cp36-cp36m-win32.whl", hash = "sha256:a035a10686532b0587d58a606004aa20ad895c60c4d029afa245802347fab57b"}, - {file = "cryptography-3.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:d26a2557d8f9122f9bf445fc7034242f4375bd4e95ecda007667540270965b13"}, - {file = "cryptography-3.2.1-cp37-cp37m-win32.whl", hash = "sha256:545a8550782dda68f8cdc75a6e3bf252017aa8f75f19f5a9ca940772fc0cb56e"}, - {file = "cryptography-3.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:55d0b896631412b6f0c7de56e12eb3e261ac347fbaa5d5e705291a9016e5f8cb"}, - {file = "cryptography-3.2.1-cp38-cp38-win32.whl", hash = "sha256:3cd75a683b15576cfc822c7c5742b3276e50b21a06672dc3a800a2d5da4ecd1b"}, - {file = "cryptography-3.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:d25cecbac20713a7c3bc544372d42d8eafa89799f492a43b79e1dfd650484851"}, - {file = "cryptography-3.2.1.tar.gz", hash = "sha256:d3d5e10be0cf2a12214ddee45c6bd203dab435e3d83b4560c03066eda600bfe3"}, + {file = "cryptography-3.3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030"}, + {file = "cryptography-3.3.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9f6b0492d111b43de5f70052e24c1f0951cb9e6022188ebcb1cc3a3d301469b0"}, + {file = "cryptography-3.3.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a69bd3c68b98298f490e84519b954335154917eaab52cf582fa2c5c7efc6e812"}, + {file = "cryptography-3.3.1-cp27-cp27m-win32.whl", hash = "sha256:84ef7a0c10c24a7773163f917f1cb6b4444597efd505a8aed0a22e8c4780f27e"}, + {file = "cryptography-3.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:594a1db4511bc4d960571536abe21b4e5c3003e8750ab8365fafce71c5d86901"}, + {file = "cryptography-3.3.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0003a52a123602e1acee177dc90dd201f9bb1e73f24a070db7d36c588e8f5c7d"}, + {file = "cryptography-3.3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:83d9d2dfec70364a74f4e7c70ad04d3ca2e6a08b703606993407bf46b97868c5"}, + {file = "cryptography-3.3.1-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:dc42f645f8f3a489c3dd416730a514e7a91a59510ddaadc09d04224c098d3302"}, + {file = "cryptography-3.3.1-cp36-abi3-manylinux1_x86_64.whl", hash = "sha256:788a3c9942df5e4371c199d10383f44a105d67d401fb4304178020142f020244"}, + {file = "cryptography-3.3.1-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:69e836c9e5ff4373ce6d3ab311c1a2eed274793083858d3cd4c7d12ce20d5f9c"}, + {file = "cryptography-3.3.1-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:9e21301f7a1e7c03dbea73e8602905a4ebba641547a462b26dd03451e5769e7c"}, + {file = "cryptography-3.3.1-cp36-abi3-win32.whl", hash = "sha256:b4890d5fb9b7a23e3bf8abf5a8a7da8e228f1e97dc96b30b95685df840b6914a"}, + {file = "cryptography-3.3.1-cp36-abi3-win_amd64.whl", hash = "sha256:0e85aaae861d0485eb5a79d33226dd6248d2a9f133b81532c8f5aae37de10ff7"}, + {file = "cryptography-3.3.1.tar.gz", hash = "sha256:7e177e4bea2de937a584b13645cab32f25e3d96fc0bc4a4cf99c27dc77682be6"}, ] debtcollector = [ {file = "debtcollector-1.11.0-py2.py3-none-any.whl", hash = "sha256:a339dd5c5d0516c9d42ff764d41565d5dcc408c9afcaac6f5d277a768f01d2a5"}, @@ -1522,15 +1517,15 @@ dropbox = [ {file = "dropbox-8.3.1.tar.gz", hash = "sha256:51c222871ead15fdad879ea4728c37a44ed1c7a43359bf7bdf8bcbfba2776c24"}, ] duplicity = [ - {file = "duplicity-0.8.17.tar.gz", hash = "sha256:1d1be81c3d4bf0109170dacd5254f91ac8d139a474417de6f100bd7c0a4a4cf8"}, + {file = "duplicity-0.8.18.tar.gz", hash = "sha256:6664424e52f8b9abd94ce1a1ef2a5e373877e23030f515dde91ab424d3d456e1"}, ] execnet = [ - {file = "execnet-1.7.1-py2.py3-none-any.whl", hash = "sha256:d4efd397930c46415f62f8a31388d6be4f27a91d7550eb79bc64a756e0056547"}, - {file = "execnet-1.7.1.tar.gz", hash = "sha256:cacb9df31c9680ec5f95553976c4da484d407e85e41c83cb812aa014f0eddc50"}, + {file = "execnet-1.8.0-py2.py3-none-any.whl", hash = "sha256:7a13113028b1e1cc4c6492b28098b3c6576c9dccc7973bfe47b342afadafb2ac"}, + {file = "execnet-1.8.0.tar.gz", hash = "sha256:b73c5565e517f24b62dea8a5ceac178c661c4309d3aa0c3e420856c072c411b4"}, ] fasteners = [ - {file = "fasteners-0.15-py2.py3-none-any.whl", hash = "sha256:007e4d2b2d4a10093f67e932e5166722d2eab83b77724156e92ad013c6226574"}, - {file = "fasteners-0.15.tar.gz", hash = "sha256:3a176da6b70df9bb88498e1a18a9e4a8579ed5b9141207762368a1017bf8f5ef"}, + {file = "fasteners-0.16-py2.py3-none-any.whl", hash = "sha256:74b6847e0a6bb3b56c8511af8e24c40e4cf7a774dfff5b251c260ed338096a4b"}, + {file = "fasteners-0.16.tar.gz", hash = "sha256:c995d8c26b017c5d6a6de9ad29a0f9cdd57de61ae1113d28fac26622b06a0933"}, ] flake8 = [ {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, @@ -1552,8 +1547,8 @@ google-api-python-client = [ {file = "google_api_python_client-1.7.12-py3-none-any.whl", hash = "sha256:52ee38b5ade3f412a39c7c6c4bdacde73b06512f8b9dadca021021d354aa7fe2"}, ] google-auth = [ - {file = "google-auth-1.23.0.tar.gz", hash = "sha256:5176db85f1e7e837a646cd9cede72c3c404ccf2e3373d9ee14b2db88febad440"}, - {file = "google_auth-1.23.0-py2.py3-none-any.whl", hash = "sha256:b728625ff5dfce8f9e56a499c8a4eb51443a67f20f6d28b67d5774c310ec4b6b"}, + {file = "google-auth-1.25.0.tar.gz", hash = "sha256:514e39f4190ca972200ba33876da5a8857c5665f2b4ccc36c8b8ee21228aae80"}, + {file = "google_auth-1.25.0-py2.py3-none-any.whl", hash = "sha256:008e23ed080674f69f9d2d7d80db4c2591b9bb307d136cea7b3bc129771d211d"}, ] google-auth-httplib2 = [ {file = "google-auth-httplib2-0.0.4.tar.gz", hash = "sha256:8d092cc60fb16517b12057ec0bba9185a96e3b7169d86ae12eae98e645b7bc39"}, @@ -1564,8 +1559,8 @@ httplib2 = [ {file = "httplib2-0.18.1.tar.gz", hash = "sha256:8af66c1c52c7ffe1aa5dc4bcd7c769885254b0756e6e69f953c7f0ab49a70ba3"}, ] humanize = [ - {file = "humanize-3.1.0-py3-none-any.whl", hash = "sha256:6790d9ba139ce09761ae901be9b22bd32a131fa65ecc82cdfc4d86f377f7395d"}, - {file = "humanize-3.1.0.tar.gz", hash = "sha256:fd3eb915310335c63a54d4507289ecc7b3a7454cd2c22ac5086d061a3cbfd592"}, + {file = "humanize-3.2.0-py3-none-any.whl", hash = "sha256:d47d80cd47c1511ed3e49ca5f10c82ed940ea020b45b49ab106ed77fa8bb9d22"}, + {file = "humanize-3.2.0.tar.gz", hash = "sha256:ab69004895689951b79f2ae4fdd6b8127ff0c180aff107856d5d98119a33f026"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -1591,8 +1586,8 @@ jottalib = [ {file = "jottalib-0.5.1.tar.gz", hash = "sha256:015c9a1772f06a2ad496278aff4b20ad41acc660304fa8f8b854932c662bb0a5"}, ] keyring = [ - {file = "keyring-21.5.0-py3-none-any.whl", hash = "sha256:12de23258a95f3b13e5b167f7a641a878e91eab8ef16fafc077720a95e6115bb"}, - {file = "keyring-21.5.0.tar.gz", hash = "sha256:207bd66f2a9881c835dad653da04e196c678bf104f8252141d2d3c4f31051579"}, + {file = "keyring-22.0.1-py3-none-any.whl", hash = "sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0"}, + {file = "keyring-22.0.1.tar.gz", hash = "sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df"}, ] keystoneauth1 = [ {file = "keystoneauth1-2.18.0-py2.py3-none-any.whl", hash = "sha256:ad292a0f78fb88052fd91ab5d59297c24926994f916d0d261bf131800a925e8d"}, @@ -1650,8 +1645,8 @@ mediafire = [ {file = "mediafire-0.6.0.tar.gz", hash = "sha256:d9182785856b858b8d7896740f0dbb012856a81e00132812bffbf0e344884d6b"}, ] mock = [ - {file = "mock-4.0.2-py3-none-any.whl", hash = "sha256:3f9b2c0196c60d21838f307f5825a7b86b678cedc58ab9e50a8988187b4d81e0"}, - {file = "mock-4.0.2.tar.gz", hash = "sha256:dd33eb70232b6118298d516bbcecd26704689c386594f0f3c4f13867b2c56f72"}, + {file = "mock-4.0.3-py3-none-any.whl", hash = "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62"}, + {file = "mock-4.0.3.tar.gz", hash = "sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc"}, ] monotonic = [ {file = "monotonic-1.5-py2.py3-none-any.whl", hash = "sha256:552a91f381532e33cbd07c6a2655a21908088962bb8fa7239ecbcc6ad1140cc7"}, @@ -1727,8 +1722,8 @@ os-virtual-interfacesv2-python-novaclient-ext = [ {file = "oslo.utils-3.22.3.tar.gz", hash = "sha256:70473be975412407d43ef04b0de34c4d21c567bdcab608caeb8f0fcd4138f4f2"}, ] packaging = [ - {file = "packaging-20.8-py2.py3-none-any.whl", hash = "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858"}, - {file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"}, + {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, + {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, ] paramiko = [ {file = "paramiko-2.7.2-py2.py3-none-any.whl", hash = "sha256:4f3e316fef2ac628b05097a637af35685183111d4bc1b5979bd397c2ab7b5898"}, @@ -1767,8 +1762,8 @@ prettytable = [ {file = "prettytable-0.7.2.zip", hash = "sha256:a53da3b43d7a5c229b5e3ca2892ef982c46b7923b51e98f0db49956531211c4f"}, ] ptyprocess = [ - {file = "ptyprocess-0.6.0-py2.py3-none-any.whl", hash = "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f"}, - {file = "ptyprocess-0.6.0.tar.gz", hash = "sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0"}, + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, @@ -1849,8 +1844,8 @@ pyrax = [ {file = "pyrax-1.9.8.tar.gz", hash = "sha256:e9db943447fdf2690046d7f98466fc4743497b74578efe6e400a6edbfd9728f5"}, ] pytest = [ - {file = "pytest-6.2.1-py3-none-any.whl", hash = "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8"}, - {file = "pytest-6.2.1.tar.gz", hash = "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306"}, + {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, + {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, ] pytest-forked = [ {file = "pytest-forked-1.3.0.tar.gz", hash = "sha256:6aa9ac7e00ad1a539c41bec6d21011332de671e938c7637378ec9710204e37ca"}, @@ -1873,31 +1868,39 @@ python-novaclient = [ {file = "python_novaclient-2.27.0-py2.py3-none-any.whl", hash = "sha256:6406a8ced973d6e73115fde9fa4c09e01046415701afd98aaf6f0295ba0bad86"}, ] python-swiftclient = [ - {file = "python-swiftclient-3.10.1.tar.gz", hash = "sha256:0176b17aa14cc2ef82a327dc70b66af670bdb39dcf836896f81269db376932ea"}, - {file = "python_swiftclient-3.10.1-py2.py3-none-any.whl", hash = "sha256:7ec538f52c51285bcbfcbae33c5b1eea210282f035ba7abefd066b7f7ad6f8ee"}, + {file = "python-swiftclient-3.11.0.tar.gz", hash = "sha256:3972f8b1986e60ea786ad01697e6882f331209ae947ef8b795531940f1e0732b"}, + {file = "python_swiftclient-3.11.0-py2.py3-none-any.whl", hash = "sha256:2657e2871691bac476dbfecea3956d0bbde0c74d80a639aa01335a0f2e471b6c"}, ] pytz = [ - {file = "pytz-2020.4-py2.py3-none-any.whl", hash = "sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd"}, - {file = "pytz-2020.4.tar.gz", hash = "sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268"}, + {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, + {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, ] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, ] pyyaml = [ - {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, - {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, - {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, - {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, - {file = "PyYAML-5.3.1-cp39-cp39-win32.whl", hash = "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a"}, - {file = "PyYAML-5.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e"}, - {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] rackspace-auth-openstack = [ {file = "rackspace-auth-openstack-1.3.tar.gz", hash = "sha256:c4c069eeb1924ea492c50144d8a4f5f1eb0ece945e0c0d60157cabcadff651cd"}, @@ -1972,12 +1975,12 @@ rfc3986 = [ {file = "rfc3986-1.4.0.tar.gz", hash = "sha256:112398da31a3344dc25dbf477d8df6cb34f9278a94fee2625d89e4514be8bb9d"}, ] rsa = [ - {file = "rsa-4.6-py3-none-any.whl", hash = "sha256:6166864e23d6b5195a5cfed6cd9fed0fe774e226d8f854fcb23b7bbef0350233"}, - {file = "rsa-4.6.tar.gz", hash = "sha256:109ea5a66744dd859bf16fe904b8d8b627adafb9408753161e766a92e7d681fa"}, + {file = "rsa-4.7-py3-none-any.whl", hash = "sha256:a8774e55b59fd9fc893b0d05e9bfc6f47081f46ff5b46f39ccf24631b7be356b"}, + {file = "rsa-4.7.tar.gz", hash = "sha256:69805d6b69f56eb05b62daea3a7dbd7aa44324ad1306445e05da8060232d00f4"}, ] s3transfer = [ - {file = "s3transfer-0.3.3-py2.py3-none-any.whl", hash = "sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13"}, - {file = "s3transfer-0.3.3.tar.gz", hash = "sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db"}, + {file = "s3transfer-0.3.4-py2.py3-none-any.whl", hash = "sha256:1e28620e5b444652ed752cf87c7e0cb15b0e578972568c6609f0f18212f259ed"}, + {file = "s3transfer-0.3.4.tar.gz", hash = "sha256:7fdddb4f22275cf1d32129e21f056337fd2a80b6ccef1664528145b72c49e6d2"}, ] secretstorage = [ {file = "SecretStorage-3.3.0-py3-none-any.whl", hash = "sha256:5c36f6537a523ec5f969ef9fad61c98eb9e017bc601d811e53aa25bece64892f"}, @@ -2043,8 +2046,8 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tqdm = [ - {file = "tqdm-4.54.0-py2.py3-none-any.whl", hash = "sha256:9e7b8ab0ecbdbf0595adadd5f0ebbb9e69010e0bd48bbb0c15e550bf2a5292df"}, - {file = "tqdm-4.54.0.tar.gz", hash = "sha256:5c0d04e06ccc0da1bd3fa5ae4550effcce42fcad947b4a6cafa77bdc9b09ff22"}, + {file = "tqdm-4.56.0-py2.py3-none-any.whl", hash = "sha256:4621f6823bab46a9cc33d48105753ccbea671b68bab2c50a9f0be23d4065cb5a"}, + {file = "tqdm-4.56.0.tar.gz", hash = "sha256:fe3d08dd00a526850568d542ff9de9bbc2a09a791da3c334f3213d8d0bbbca65"}, ] typed-ast = [ {file = "typed_ast-1.4.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70"}, @@ -2088,8 +2091,8 @@ uritemplate = [ {file = "uritemplate-3.0.1.tar.gz", hash = "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"}, ] urllib3 = [ - {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"}, - {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, + {file = "urllib3-1.26.3-py2.py3-none-any.whl", hash = "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80"}, + {file = "urllib3-1.26.3.tar.gz", hash = "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"}, ] wrapt = [ {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, diff --git a/pyproject.toml b/pyproject.toml index ad700cb4..9ba0c86b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,22 +6,22 @@ authors = ["Tecnativa"] [tool.poetry.dependencies] python = "^3.9" -b2 = "^2.1.0" -b2sdk = "^1.2.0" -boto = "^2.49.0" -boto3 = "^1.16.28" -gdata = "^2.0.18" -jottalib = "^0.5.1" -paramiko = "^2.7.2" -pexpect = "^4.8.0" -PyDrive = "^1.3.1" -pyrax = "^1.9.8" -python-swiftclient = "^3.10.1" -requests-oauthlib = "^1.3.0" -duplicity = "^0.8.17" -dropbox = "^8.0.0" -python-keystoneclient = "3.10.0" -mediafire = "^0.6.0" +b2 = {version = "^2.1.0", optional = true} +b2sdk = {version = "1.2.0", optional = true} +boto = {version = "^2.49.0", optional = true} +boto3 = {version = "^1.16.61", optional = true} +gdata = {version = "^2.0.18", optional = true} +jottalib = {version = "^0.5.1", optional = true} +paramiko = {version = "^2.7.2", optional = true} +pexpect = {version = "^4.8.0", optional = true} +PyDrive = {version = "^1.3.1", optional = true} +pyrax = {version = "^1.9.8", optional = true} +python-swiftclient = {version = "^3.11.0", optional = true} +requests-oauthlib = {version = "^1.3.0", optional = true} +duplicity = {version = "^0.8.18", optional = true} +dropbox = {version = "^8.0.0", optional = true} +python-keystoneclient = {version = "^3.10.0", optional = true} +mediafire = {version = "^0.6.0", optional = true} [tool.poetry.dev-dependencies] pytest = "^6.2.1" @@ -30,6 +30,9 @@ flake8 = "^3.8.4" plumbum = "^1.6.9" pytest-xdist = "^2.2.0" +[tool.poetry.extras] +duplicity = ["b2", "b2sdk", "boto", "boto3", "gdata", "jottalib", "paramiko", "pexpect", "PyDrive", "pyrax", "python", "requests", "duplicity", "dropbox", "python", "mediafire"] + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt index 27b5ca7c..6e0fecd4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,22 +21,22 @@ bcrypt==3.2.0; python_version >= "3.6" \ --hash=sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55 \ --hash=sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34 \ --hash=sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29 -boto3==1.16.28 \ - --hash=sha256:ca62b4517ddb6a81a9b0113cca05b2dba5faab14d2b35b81f402b052955738c5 \ - --hash=sha256:7f44988fc605fa264046d7d16f773836ac1e8b3f6721b79ba796b875bbf9ea75 +boto3==1.17.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") \ + --hash=sha256:6a7f9e2fb631d39bd089cb7e83b4a8ce5e572bdc6545ac51b761bd9ea2ad80c6 \ + --hash=sha256:1a282c1cd7d5028cbb3a75d747df32162295253f55d263ac85840e264830963b boto==2.49.0 \ --hash=sha256:147758d41ae7240dc989f0039f27da8ca0d53734be0eb869ef16e3adcfa462e8 \ --hash=sha256:ea0d3b40a2d852767be77ca343b58a9e3a4b00d9db440efb8da74b4e58025e5a -botocore==1.19.28 \ - --hash=sha256:d8dab9b74dc0ad2e5439e5ea3c119e234d2f02952f37f379d9a74adfa305ed75 \ - --hash=sha256:97741448e63850895818193c29b93ec6319135587ae4994a6f611ffccb1a978e -cachetools==4.1.1; python_version >= "3.5" and python_version < "4.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0") \ - --hash=sha256:513d4ff98dd27f85743a8dc0e92f55ddb1b49e060c2d5961512855cda2c01a98 \ - --hash=sha256:bbaa39c3dede00175df2dc2b03d0cf18dd2d32a7de7beb68072d13043c9edb20 -certifi==2020.11.8 \ - --hash=sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd \ - --hash=sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4 -cffi==1.14.4; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" \ +botocore==1.20.2; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" \ + --hash=sha256:7442fdbbdc841bfac7f94f92ecb807de070e32ed205743eb72d4ea27c5e8e778 \ + --hash=sha256:bf587b044983a91a0124cc133ff167b8528c19fbbc8f0b956d9a1ac256cad7d7 +cachetools==4.2.1; python_version >= "3.5" and python_version < "4.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") \ + --hash=sha256:1d9d5f567be80f7c07d765e21b814326d78c61eb0c3a637dffc0e5d1796cb2e2 \ + --hash=sha256:f469e29e7aa4cff64d8de4aad95ce76de8ea1125a16c68e0d93f65c3c3dc92e9 +certifi==2020.12.5 \ + --hash=sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830 \ + --hash=sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c +cffi==1.14.4; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6" \ --hash=sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775 \ --hash=sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06 \ --hash=sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26 \ @@ -71,34 +71,26 @@ cffi==1.14.4; python_version >= "3.6" and python_full_version < "3.0.0" or pytho --hash=sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3 \ --hash=sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b \ --hash=sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c -chardet==3.0.4 \ - --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 \ - --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae +chardet==4.0.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \ + --hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5 \ + --hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa clint==0.5.1 \ --hash=sha256:05224c32b1075563d0b16d0015faaf9da43aa214e4a2140e51f08789e7a4c5aa -cryptography==3.2.1; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "linux" or sys_platform == "linux" and python_version >= "3.6" and python_full_version >= "3.5.0" \ - --hash=sha256:6dc59630ecce8c1f558277ceb212c751d6730bd12c80ea96b4ac65637c4f55e7 \ - --hash=sha256:75e8e6684cf0034f6bf2a97095cb95f81537b12b36a8fedf06e73050bb171c2d \ - --hash=sha256:4e7268a0ca14536fecfdf2b00297d4e407da904718658c1ff1961c713f90fd33 \ - --hash=sha256:7117319b44ed1842c617d0a452383a5a052ec6aa726dfbaffa8b94c910444297 \ - --hash=sha256:a733671100cd26d816eed39507e585c156e4498293a907029969234e5e634bc4 \ - --hash=sha256:a75f306a16d9f9afebfbedc41c8c2351d8e61e818ba6b4c40815e2b5740bb6b8 \ - --hash=sha256:5849d59358547bf789ee7e0d7a9036b2d29e9a4ddf1ce5e06bb45634f995c53e \ - --hash=sha256:bd717aa029217b8ef94a7d21632a3bb5a4e7218a4513d2521c2a2fd63011e98b \ - --hash=sha256:efe15aca4f64f3a7ea0c09c87826490e50ed166ce67368a68f315ea0807a20df \ - --hash=sha256:32434673d8505b42c0de4de86da8c1620651abd24afe91ae0335597683ed1b77 \ - --hash=sha256:7b8d9d8d3a9bd240f453342981f765346c87ade811519f98664519696f8e6ab7 \ - --hash=sha256:d3545829ab42a66b84a9aaabf216a4dce7f16dbc76eb69be5c302ed6b8f4a29b \ - --hash=sha256:a4e27ed0b2504195f855b52052eadcc9795c59909c9d84314c5408687f933fc7 \ - --hash=sha256:13b88a0bd044b4eae1ef40e265d006e34dbcde0c2f1e15eb9896501b2d8f6c6f \ - --hash=sha256:07ca431b788249af92764e3be9a488aa1d39a0bc3be313d826bbec690417e538 \ - --hash=sha256:a035a10686532b0587d58a606004aa20ad895c60c4d029afa245802347fab57b \ - --hash=sha256:d26a2557d8f9122f9bf445fc7034242f4375bd4e95ecda007667540270965b13 \ - --hash=sha256:545a8550782dda68f8cdc75a6e3bf252017aa8f75f19f5a9ca940772fc0cb56e \ - --hash=sha256:55d0b896631412b6f0c7de56e12eb3e261ac347fbaa5d5e705291a9016e5f8cb \ - --hash=sha256:3cd75a683b15576cfc822c7c5742b3276e50b21a06672dc3a800a2d5da4ecd1b \ - --hash=sha256:d25cecbac20713a7c3bc544372d42d8eafa89799f492a43b79e1dfd650484851 \ - --hash=sha256:d3d5e10be0cf2a12214ddee45c6bd203dab435e3d83b4560c03066eda600bfe3 +cryptography==3.3.1; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "linux" or sys_platform == "linux" and python_version >= "3.6" and python_full_version >= "3.6.0" \ + --hash=sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030 \ + --hash=sha256:9f6b0492d111b43de5f70052e24c1f0951cb9e6022188ebcb1cc3a3d301469b0 \ + --hash=sha256:a69bd3c68b98298f490e84519b954335154917eaab52cf582fa2c5c7efc6e812 \ + --hash=sha256:84ef7a0c10c24a7773163f917f1cb6b4444597efd505a8aed0a22e8c4780f27e \ + --hash=sha256:594a1db4511bc4d960571536abe21b4e5c3003e8750ab8365fafce71c5d86901 \ + --hash=sha256:0003a52a123602e1acee177dc90dd201f9bb1e73f24a070db7d36c588e8f5c7d \ + --hash=sha256:83d9d2dfec70364a74f4e7c70ad04d3ca2e6a08b703606993407bf46b97868c5 \ + --hash=sha256:dc42f645f8f3a489c3dd416730a514e7a91a59510ddaadc09d04224c098d3302 \ + --hash=sha256:788a3c9942df5e4371c199d10383f44a105d67d401fb4304178020142f020244 \ + --hash=sha256:69e836c9e5ff4373ce6d3ab311c1a2eed274793083858d3cd4c7d12ce20d5f9c \ + --hash=sha256:9e21301f7a1e7c03dbea73e8602905a4ebba641547a462b26dd03451e5769e7c \ + --hash=sha256:b4890d5fb9b7a23e3bf8abf5a8a7da8e228f1e97dc96b30b95685df840b6914a \ + --hash=sha256:0e85aaae861d0485eb5a79d33226dd6248d2a9f133b81532c8f5aae37de10ff7 \ + --hash=sha256:7e177e4bea2de937a584b13645cab32f25e3d96fc0bc4a4cf99c27dc77682be6 debtcollector==1.11.0 \ --hash=sha256:a339dd5c5d0516c9d42ff764d41565d5dcc408c9afcaac6f5d277a768f01d2a5 \ --hash=sha256:733afa881c844a40ef4623ab73ce1862e505bc4655635da3a91d8f3482677785 @@ -106,11 +98,11 @@ dropbox==8.3.1 \ --hash=sha256:f3b8190df962f53ce776c168345f441d6fc9aeee983f31dc86853057800b3125 \ --hash=sha256:795dca49a931d28579748d0653646759e2914090362b7a4c26a0ea5572433582 \ --hash=sha256:51c222871ead15fdad879ea4728c37a44ed1c7a43359bf7bdf8bcbfba2776c24 -duplicity==0.8.17; (python_version > "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4") \ - --hash=sha256:1d1be81c3d4bf0109170dacd5254f91ac8d139a474417de6f100bd7c0a4a4cf8 -fasteners==0.15; python_version > "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" \ - --hash=sha256:007e4d2b2d4a10093f67e932e5166722d2eab83b77724156e92ad013c6226574 \ - --hash=sha256:3a176da6b70df9bb88498e1a18a9e4a8579ed5b9141207762368a1017bf8f5ef +duplicity==0.8.18; (python_version > "2.6" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4") \ + --hash=sha256:6664424e52f8b9abd94ce1a1ef2a5e373877e23030f515dde91ab424d3d456e1 +fasteners==0.16; python_version > "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" \ + --hash=sha256:74b6847e0a6bb3b56c8511af8e24c40e4cf7a774dfff5b251c260ed338096a4b \ + --hash=sha256:c995d8c26b017c5d6a6de9ad29a0f9cdd57de61ae1113d28fac26622b06a0933 funcsigs==1.0.2 \ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \ --hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50 @@ -125,15 +117,15 @@ google-api-python-client==1.7.12; python_version >= "2.7" and python_full_versio google-auth-httplib2==0.0.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ --hash=sha256:8d092cc60fb16517b12057ec0bba9185a96e3b7169d86ae12eae98e645b7bc39 \ --hash=sha256:aeaff501738b289717fac1980db9711d77908a6c227f60e4aa1923410b43e2ee -google-auth==1.23.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ - --hash=sha256:5176db85f1e7e837a646cd9cede72c3c404ccf2e3373d9ee14b2db88febad440 \ - --hash=sha256:b728625ff5dfce8f9e56a499c8a4eb51443a67f20f6d28b67d5774c310ec4b6b +google-auth==1.25.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" \ + --hash=sha256:514e39f4190ca972200ba33876da5a8857c5665f2b4ccc36c8b8ee21228aae80 \ + --hash=sha256:008e23ed080674f69f9d2d7d80db4c2591b9bb307d136cea7b3bc129771d211d httplib2==0.18.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ --hash=sha256:ca2914b015b6247791c4866782fa6042f495b94401a0f0bd3e1d6e0ba2236782 \ --hash=sha256:8af66c1c52c7ffe1aa5dc4bcd7c769885254b0756e6e69f953c7f0ab49a70ba3 -humanize==3.1.0; python_version >= "3.6" \ - --hash=sha256:6790d9ba139ce09761ae901be9b22bd32a131fa65ecc82cdfc4d86f377f7395d \ - --hash=sha256:fd3eb915310335c63a54d4507289ecc7b3a7454cd2c22ac5086d061a3cbfd592 +humanize==3.2.0; python_version >= "3.6" \ + --hash=sha256:d47d80cd47c1511ed3e49ca5f10c82ed940ea020b45b49ab106ed77fa8bb9d22 \ + --hash=sha256:ab69004895689951b79f2ae4fdd6b8127ff0c180aff107856d5d98119a33f026 ip-associations-python-novaclient-ext==0.2 \ --hash=sha256:e4576c3ee149bcca7e034507ad9c698cb07dd9fa10f90056756aea0fa59bae37 iso8601==0.1.13 \ @@ -143,14 +135,14 @@ iso8601==0.1.13 \ jeepney==0.6.0; sys_platform == "linux" and python_version >= "3.6" \ --hash=sha256:aec56c0eb1691a841795111e184e13cad504f7703b9a64f63020816afa79a8ae \ --hash=sha256:7d59b6622675ca9e993a6bd38de845051d315f8b0c72cca3aef733a20b648657 -jmespath==0.10.0; python_version >= "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" \ +jmespath==0.10.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" \ --hash=sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f \ --hash=sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9 jottalib==0.5.1 \ --hash=sha256:015c9a1772f06a2ad496278aff4b20ad41acc660304fa8f8b854932c662bb0a5 -keyring==21.5.0; python_version >= "3.6" \ - --hash=sha256:12de23258a95f3b13e5b167f7a641a878e91eab8ef16fafc077720a95e6115bb \ - --hash=sha256:207bd66f2a9881c835dad653da04e196c678bf104f8252141d2d3c4f31051579 +keyring==22.0.1; python_version >= "3.6" \ + --hash=sha256:9f44660a5d4931bdc14c08a1d01ef30b18a7a8147380710d8c9f9531e1f6c3c0 \ + --hash=sha256:9acb3e1452edbb7544822b12fd25459078769e560fa51f418b6d00afaa6178df keystoneauth1==2.18.0 \ --hash=sha256:ad292a0f78fb88052fd91ab5d59297c24926994f916d0d261bf131800a925e8d \ --hash=sha256:075a9ca7a8877c5885fa2487699015e45260c4e6be119683effe0ad2ab1255d2 @@ -198,10 +190,10 @@ lxml==4.6.2; python_version >= "2.7" and python_full_version < "3.0.0" or python mediafire==0.6.0 \ --hash=sha256:b63e5d990cbe6e6fbf4e805a6c48591387ff3c7566077c398a0aa5f66de23751 \ --hash=sha256:d9182785856b858b8d7896740f0dbb012856a81e00132812bffbf0e344884d6b -mock==4.0.2; python_version >= "3.6" \ - --hash=sha256:3f9b2c0196c60d21838f307f5825a7b86b678cedc58ab9e50a8988187b4d81e0 \ - --hash=sha256:dd33eb70232b6118298d516bbcecd26704689c386594f0f3c4f13867b2c56f72 -monotonic==1.5; python_version > "2.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" \ +mock==4.0.3; python_version >= "3.6" \ + --hash=sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62 \ + --hash=sha256:7d3fbbde18228f4ff2f1f119a45cdffa458b4c0dee32eb4d2bb2f82554bac7bc +monotonic==1.5 \ --hash=sha256:552a91f381532e33cbd07c6a2655a21908088962bb8fa7239ecbcc6ad1140cc7 \ --hash=sha256:23953d55076df038541e648a53676fb24980f7a1be290cdda21300b3bc21dfb0 msgpack-python==0.5.6 \ @@ -235,9 +227,6 @@ netifaces==0.10.9 \ oauth2client==4.1.3 \ --hash=sha256:b8a81cc5d60e2d364f0b1b98f958dbd472887acaf1a5b05e21c28c31a2d6d3ac \ --hash=sha256:d486741e451287f69568a4d26d70d9acd73a2bbfa275746c535b4209891cccc6 -oauthlib==3.1.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ - --hash=sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea \ - --hash=sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889 os-diskconfig-python-novaclient-ext==0.1.3 \ --hash=sha256:f668665a5765648ec47fbd80f9a8e5f37498b6ea3fb2d0d570b7da7d96146be9 \ --hash=sha256:e7d19233a7b73c70244d2527d162d8176555698e7c621b41f689be496df15e75 @@ -275,10 +264,10 @@ prettytable==0.7.2 \ --hash=sha256:853c116513625c738dc3ce1aee148b5b5757a86727e67eff6502c7ca59d43c36 \ --hash=sha256:2d5460dc9db74a32bcc8f9f67de68b2c4f4d2f01fa3bd518764c69156d9cacd9 \ --hash=sha256:a53da3b43d7a5c229b5e3ca2892ef982c46b7923b51e98f0db49956531211c4f -ptyprocess==0.6.0 \ - --hash=sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f \ - --hash=sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0 -pyasn1-modules==0.2.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ +ptyprocess==0.7.0 \ + --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \ + --hash=sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220 +pyasn1-modules==0.2.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" \ --hash=sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e \ --hash=sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199 \ --hash=sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405 \ @@ -337,7 +326,7 @@ pyparsing==2.4.7; python_version >= "2.6" and python_full_version < "3.0.0" or p pyrax==1.9.8 \ --hash=sha256:23873829b286183b56fdb94b515118e3332bfcb12b7532dc0582e78bd002c0ae \ --hash=sha256:e9db943447fdf2690046d7f98466fc4743497b74578efe6e400a6edbfd9728f5 -python-dateutil==2.8.1; python_version > "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version > "3.5" \ +python-dateutil==2.8.1; python_version > "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version > "3.5" \ --hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \ --hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a python-keystoneclient==3.10.0 \ @@ -346,29 +335,34 @@ python-keystoneclient==3.10.0 \ python-novaclient==2.27.0 \ --hash=sha256:d1279d5c2857cf8c56cb953639b36225bc1fec7fa30ee632940823506a7638ef \ --hash=sha256:6406a8ced973d6e73115fde9fa4c09e01046415701afd98aaf6f0295ba0bad86 -python-swiftclient==3.10.1 \ - --hash=sha256:0176b17aa14cc2ef82a327dc70b66af670bdb39dcf836896f81269db376932ea \ - --hash=sha256:7ec538f52c51285bcbfcbae33c5b1eea210282f035ba7abefd066b7f7ad6f8ee -pytz==2020.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ - --hash=sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd \ - --hash=sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268 +pytz==2021.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ + --hash=sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798 \ + --hash=sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da pywin32-ctypes==0.2.0; sys_platform == "win32" and python_version >= "3.6" \ --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \ --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 -pyyaml==5.3.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" \ - --hash=sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f \ - --hash=sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76 \ - --hash=sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2 \ - --hash=sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c \ - --hash=sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2 \ - --hash=sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648 \ - --hash=sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a \ - --hash=sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf \ - --hash=sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97 \ - --hash=sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee \ - --hash=sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a \ - --hash=sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e \ - --hash=sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d +pyyaml==5.4.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" \ + --hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \ + --hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \ + --hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \ + --hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \ + --hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \ + --hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \ + --hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \ + --hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \ + --hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \ + --hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \ + --hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \ + --hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \ + --hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \ + --hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \ + --hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \ + --hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \ + --hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \ + --hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \ + --hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \ + --hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \ + --hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e rackspace-auth-openstack==1.3 \ --hash=sha256:c4c069eeb1924ea492c50144d8a4f5f1eb0ece945e0c0d60157cabcadff651cd rackspace-novaclient==2.1 \ @@ -377,25 +371,21 @@ rax-default-network-flags-python-novaclient-ext==0.4.0 \ --hash=sha256:852bf49d90e7a1bc16aa0b25b46a45ba5654069f7321a363c8d94c5496666001 rax-scheduled-images-python-novaclient-ext==0.3.1 \ --hash=sha256:f170cf97b20bdc8a1784cc0b85b70df5eb9b88c3230dab8e68e1863bf3937cdb -requests-oauthlib==1.3.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \ - --hash=sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a \ - --hash=sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d \ - --hash=sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc requests-toolbelt==0.9.1 \ --hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0 \ --hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f -requests==2.11.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ +requests==2.11.1 \ --hash=sha256:545c4855cd9d7c12671444326337013766f4eea6068c3f0307fb2dc2696d580e \ --hash=sha256:5acf980358283faba0b897c73959cecf8b841205bb4b2ad3ef545f46eae1a133 rfc3986==1.4.0 \ --hash=sha256:af9147e9aceda37c91a05f4deb128d4b4b49d6b199775fd2d2927768abdc8f50 \ --hash=sha256:112398da31a3344dc25dbf477d8df6cb34f9278a94fee2625d89e4514be8bb9d -rsa==4.6; python_version >= "3.5" and python_version < "4" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5") \ - --hash=sha256:6166864e23d6b5195a5cfed6cd9fed0fe774e226d8f854fcb23b7bbef0350233 \ - --hash=sha256:109ea5a66744dd859bf16fe904b8d8b627adafb9408753161e766a92e7d681fa -s3transfer==0.3.3 \ - --hash=sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13 \ - --hash=sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db +rsa==4.7; python_version >= "3.5" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") \ + --hash=sha256:a8774e55b59fd9fc893b0d05e9bfc6f47081f46ff5b46f39ccf24631b7be356b \ + --hash=sha256:69805d6b69f56eb05b62daea3a7dbd7aa44324ad1306445e05da8060232d00f4 +s3transfer==0.3.4; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" \ + --hash=sha256:1e28620e5b444652ed752cf87c7e0cb15b0e578972568c6609f0f18212f259ed \ + --hash=sha256:7fdddb4f22275cf1d32129e21f056337fd2a80b6ccef1664528145b72c49e6d2 secretstorage==3.3.0; sys_platform == "linux" and python_version >= "3.6" \ --hash=sha256:5c36f6537a523ec5f969ef9fad61c98eb9e017bc601d811e53aa25bece64892f \ --hash=sha256:30cfdef28829dad64d6ea1ed08f8eff6aa115a77068926bcc9f5225d5a3246aa @@ -445,20 +435,20 @@ simplejson==3.17.2; python_version >= "2.5" and python_full_version < "3.0.0" or --hash=sha256:d0b64409df09edb4c365d95004775c988259efe9be39697d7315c42b7a5e7e94 \ --hash=sha256:55d65f9cc1b733d85ef95ab11f559cce55c7649a2160da2ac7a078534da676c8 \ --hash=sha256:75ecc79f26d99222a084fbdd1ce5aad3ac3a8bd535cd9059528452da38b68841 -six==1.15.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6" and python_version < "4" \ +six==1.15.0; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6" and python_version < "4" \ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \ --hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 stevedore==1.20.1 \ --hash=sha256:edc26850d33770ce0b961b10b4a20c0b366bf89e316bbc9fa200dfd7ca2b5e57 \ --hash=sha256:046200a915780b58bf1c84436e86701b741d664893aefa84d8aceadd15ed4734 -tqdm==4.54.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ - --hash=sha256:9e7b8ab0ecbdbf0595adadd5f0ebbb9e69010e0bd48bbb0c15e550bf2a5292df \ - --hash=sha256:5c0d04e06ccc0da1bd3fa5ae4550effcce42fcad947b4a6cafa77bdc9b09ff22 +tqdm==4.56.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ + --hash=sha256:4621f6823bab46a9cc33d48105753ccbea671b68bab2c50a9f0be23d4065cb5a \ + --hash=sha256:fe3d08dd00a526850568d542ff9de9bbc2a09a791da3c334f3213d8d0bbbca65 uritemplate==3.0.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" \ --hash=sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f \ --hash=sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae -urllib3==1.26.2; python_version >= "2.7" and python_full_version < "3.0.0" and python_version != "3.4" or python_full_version >= "3.5.0" and python_version < "4" and python_version != "3.4" \ - --hash=sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473 \ - --hash=sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08 +urllib3==1.26.3; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" \ + --hash=sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80 \ + --hash=sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73 wrapt==1.12.1 \ --hash=sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7 diff --git a/tests/conftest.py b/tests/conftest.py index 89f3fec5..27c708c0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,58 +1,88 @@ -import os +import logging from contextlib import contextmanager -from logging import info from pathlib import Path import pytest from plumbum import local from plumbum.cmd import docker -DOCKER_IMAGE_NAME = os.environ.get("DOCKER_IMAGE_NAME", "docker-duplicity-local") +_logger = logging.getLogger(__name__) def pytest_addoption(parser): """Allow prebuilding image for local testing.""" - parser.addoption("--prebuild", action="store_const", const=True) + parser.addoption( + "--prebuild", + action="store_true", + help="Build local image before testing", + ) + parser.addoption( + "--image", + action="store", + default="test:docker-duplicity", + help="Specify testing image name", + ) -@pytest.fixture(autouse=True, scope="session") -def prebuild_docker_image(request): - """Build local docker image once before starting test suite.""" +@pytest.fixture(scope="session") +def image(request): + """Get image name. Builds it if needed.""" + image = request.config.getoption("--image") + images = [] if request.config.getoption("--prebuild"): - for tag in ["docker-s3", "postgres-s3", "docker", "postgres", "latest"]: - docker_image_name = f"{DOCKER_IMAGE_NAME}:{tag}" - info(f"Building {docker_image_name}...") - docker( + for tag in ["docker-s3", "postgres-s3", "docker", "postgres", "s3", "base"]: + image_name = f"{image}-{tag}" + images.append(image_name) + build = docker[ + "image", "build", "-t", - docker_image_name, + image_name, "--target", tag, - str(Path(__file__).parent.parent), + Path(__file__).parent.parent, + ] + retcode, stdout, stderr = build.run() + _logger.log( + # Pytest prints warnings if a test fails, so this is a warning if + # the build succeeded, to allow debugging the build logs + logging.ERROR if retcode else logging.WARNING, + "Build logs for COMMAND: %s\nEXIT CODE:%d\nSTDOUT:%s\nSTDERR:%s", + build.bound_command(), + retcode, + stdout, + stderr, ) + assert not retcode, "Image build failed" + return image -@contextmanager -def container(tag_name): +@pytest.fixture(scope="session") +def container_factory(image): """A context manager that starts the docker container.""" - container_id = None - docker_image_name = f"{DOCKER_IMAGE_NAME}:{tag_name}" - info(f"Starting {docker_image_name} container") - try: - container_id = docker( - "container", - "run", - "--detach", - docker_image_name, - ).strip() - with local.env(): - yield container_id - finally: - if container_id: - info(f"Removing {container_id}...") - docker( + + @contextmanager + def _container(tag_name): + container_id = None + image_name = f"{image}-{tag_name}" + _logger.info(f"Starting {image_name} container") + try: + container_id = docker( "container", - "rm", - "-f", - container_id, - ) + "run", + "--detach", + image_name, + ).strip() + with local.env(): + yield container_id + finally: + if container_id: + _logger.info(f"Removing {container_id}...") + docker( + "container", + "rm", + "-f", + container_id, + ) + + return _container diff --git a/tests/test_requirements.py b/tests/test_requirements.py new file mode 100644 index 00000000..8e744583 --- /dev/null +++ b/tests/test_requirements.py @@ -0,0 +1,18 @@ +import filecmp +import tempfile +from pathlib import Path + +from plumbum.cmd import poetry + + +def test_requirements_file_up_to_date(): + cur_path = Path.cwd() + # Generate new requirements.txt from lock file + assert (cur_path / "poetry.lock").exists() + with tempfile.NamedTemporaryFile(suffix=".txt", prefix="requirements") as f: + new_file = f.name + poetry("export", "-E", "duplicity", "-o", new_file) + # Compare new file with old one + assert filecmp.cmp( + new_file, cur_path / "requirements.txt" + ), "Requirements file not up-to-date!" diff --git a/tests/test_service.py b/tests/test_service.py index 0292153c..e717e960 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -1,12 +1,13 @@ -from conftest import container +import logging + from plumbum.cmd import docker MIN_PG = 13.0 -def test_containers_start(): - for tag in ["docker-s3", "postgres-s3", "docker", "postgres", "latest"]: - with container(tag) as test_container: +def test_containers_start(container_factory): + for tag in ["docker-s3", "postgres-s3", "docker", "postgres", "s3", "base"]: + with container_factory(tag) as test_container: docker( "exec", test_container, @@ -15,9 +16,9 @@ def test_containers_start(): ) -def test_docker_bin(): +def test_docker_bin(container_factory): for tag in ["docker-s3", "docker"]: - with container(tag) as test_container: + with container_factory(tag) as test_container: docker( "exec", test_container, @@ -26,9 +27,9 @@ def test_docker_bin(): ) -def test_postgres_bin(): +def test_postgres_bin(container_factory): for tag in ["postgres-s3", "postgres"]: - with container(tag) as test_container: + with container_factory(tag) as test_container: for app in ("psql", "pg_dump"): binary_name, product, version = docker( "exec",