Compare commits

...

29 Commits

Author SHA1 Message Date
Brad Warren
b973de36d5 build amd64 certbot snap only 2024-11-12 13:05:33 -08:00
Brad Warren
8143f80478 try using python3-dbg 2024-11-12 13:05:29 -08:00
ohemorange
38fc7fcc48 escape backslashes in format string in finish_release.py (#10043) 2024-11-05 23:42:59 +00:00
ohemorange
0e225dcba2 Fix release script main replacement (#10042)
* restore incorrect regex changes to CHANGELOG.md

* Update _release.sh regex to switch only first instance of main in changelog
2024-11-05 14:55:23 -08:00
Brad Warren
4ff5719a65 Merge pull request #10039 from certbot/candidate-3.0.0
Candidate 3.0.0
2024-11-05 12:52:47 -08:00
Will Greenberg
798a61622c Bump version to 3.1.0 2024-11-05 10:55:20 -08:00
Will Greenberg
b20d01e032 Add contents to certbot/CHANGELOG.md for next version 2024-11-05 10:55:20 -08:00
Will Greenberg
990352e371 Remove built packages from git 2024-11-05 10:55:20 -08:00
Will Greenberg
c5a5d6f9a1 Release 3.0.0 2024-11-05 10:55:19 -08:00
Will Greenberg
d4850399c5 Update changelog for 3.0.0 release 2024-11-05 10:54:15 -08:00
Brad Warren
c4be440853 update dependencies (#10036)
this fixes the current [dependabot alert](https://github.com/certbot/certbot/security/dependabot)
2024-11-01 10:04:10 -07:00
Will Greenberg
165c3e32b0 snap: fix generated postrefreshhook script (#9994)
Fixes #9990

If the python oneliner to check certbot's version succeeded, exit_code
would never be set, which would cause our exit_code check to fail. Use
a check that handles unset exit_code
2024-11-01 08:03:57 -07:00
Will Greenberg
2660a2017b Certbot 3.0 outdated plugin warning (#10031)
* Print an error if outdated snap plugins detected

With Certbot 3.0 comes a bump to Python 3.12, so if any snap plugins
are still located in a python3.8 directory, print an error informing
the user.

* tox nitpicks

* personal nitpick

* review fixups

* Update certbot/certbot/_internal/snap_config.py

Co-authored-by: ohemorange <ebportnoy@gmail.com>

* Use LOGGER.warn instead of error

* warn-->warning

* warn-->warning

---------

Co-authored-by: ohemorange <ebportnoy@gmail.com>
2024-11-01 07:52:48 -07:00
ohemorange
6a6544fd90 Update azure standard tests to use macOS-15 and python3.12 (#10032)
macOS-12 is [being deprecated](https://github.com/actions/runner-images/issues/10721) on Azure, so update to the latest available version.

* Upgrade macOS azure tests to use macOS-15

* switch standard azure tests to using python 3.12

* restore mac and linux cover tests to oldest and newest version style, and add explanation that that's what we're doing.
2024-11-01 07:34:16 -07:00
Brad Warren
320cf92944 depecate py38 support (#10034) 2024-10-31 15:48:57 -07:00
Brad Warren
3078c2f3db remove reference to "good first issue" label (#10018) 2024-10-25 11:43:44 -07:00
Brad Warren
c54f99e35b mattermost/action-mattermost-notify still uses master (#10021) 2024-10-04 14:08:25 -07:00
Brad Warren
c81dbb2582 Make Docker builds more verbose (#10022)
* use consistent casing to fix warnings

* don't truncate docker build logs

* make docker build output verbose
2024-10-04 13:54:56 -07:00
Will Greenberg
742f97e11a docs: fix logo url (#10019) 2024-09-26 15:10:06 -07:00
Will Greenberg
84c8dbc52a Migrate master branch to main
We're a few years behind the curve on this one, but using "master" as a
programming term is a callous practice that explicitly uses the
historical institution of slavery as a cheap, racist metaphor. Switch to
using "main", as it's the new default in git and GitHub.
2024-09-26 14:48:10 -07:00
Brad Warren
4b51e3004c remove certbot_dns_route53.authenticator (#10014)
This is another and very minor piece of https://github.com/certbot/certbot/issues/9988.

We've done nothing to warn/migrate installations using the old `certbot-route53:auth` plugin name and installations like that still exist according to https://gist.github.com/bmw/aceb69020dceee50ba827ec17b22e08a. We could try to warn/migrate these users for a future release or decide it's niche enough that we'll just let it break, but I think it's easy enough to keep the simple shim around.

This PR just moves the code raising a deprecation warning into `_internal` as part of cleaning up all deprecation warnings I found in https://github.com/certbot/certbot/issues/9988. I manually tested this with a Certbot config using the `certbot-route53:auth` plugin name and renewal worked just fine.
2024-09-18 14:07:35 -07:00
ohemorange
018800c5cc specify channel in weekly mm message (#10013) 2024-09-16 12:31:52 -07:00
Brad Warren
2eb4154169 allow manually triggering GH actions (#10015) 2024-09-16 12:16:51 -07:00
Brad Warren
becc2c3fee Remove deprecated --dns-route53-propagation-seconds (#10010)
* remove dns-route53-prop-secs

* document design difference
2024-09-13 12:14:49 -07:00
ldlb
cb5382d4d5 Remove deprecated features:--manual-public-ip-logging-ok (#9991)
* Remove parameter '--manual-public-ip-logging-ok'

* Update changelog with removal of '--manual-public-ip-logging-ok' flag
2024-09-12 07:21:55 -07:00
ohemorange
6975e32998 Fix weekly mattermost notifier (#10009) 2024-09-11 11:11:47 -07:00
Brad Warren
62962357c5 add parenthesis (#10008) 2024-09-10 13:06:48 -07:00
ohemorange
343b540970 Use new mattermost action workflow (#10007) 2024-09-10 12:53:21 -07:00
ohemorange
089b7efacd Update syntax for mattermost webhooks (#10006) 2024-09-10 12:16:53 -07:00
56 changed files with 313 additions and 314 deletions

View File

@@ -1,8 +1,8 @@
# Configuring Azure Pipelines with Certbot
Let's begin. All pipelines are defined in `.azure-pipelines`. Currently there are two:
* `.azure-pipelines/main.yml` is the main one, executed on PRs for master, and pushes to master,
* `.azure-pipelines/advanced.yml` add installer testing on top of the main pipeline, and is executed for `test-*` branches, release branches, and nightly run for master.
* `.azure-pipelines/main.yml` is the main one, executed on PRs for main, and pushes to main,
* `.azure-pipelines/advanced.yml` add installer testing on top of the main pipeline, and is executed for `test-*` branches, release branches, and nightly run for main.
Several templates are defined in `.azure-pipelines/templates`. These YAML files aggregate common jobs configuration that can be reused in several pipelines.
@@ -64,7 +64,7 @@ Azure Pipeline needs RW on code, RO on metadata, RW on checks, commit statuses,
RW access here is required to allow update of the pipelines YAML files from Azure DevOps interface, and to
update the status of builds and PRs on GitHub side when Azure Pipelines are triggered.
Note however that no admin access is defined here: this means that Azure Pipelines cannot do anything with
protected branches, like master, and cannot modify the security context around this on GitHub.
protected branches, like main, and cannot modify the security context around this on GitHub.
Access can be defined for all or only selected repositories, which is nice.
```
@@ -91,11 +91,11 @@ grant permissions from Azure Pipelines to GitHub in order to setup a GitHub OAut
then are way too large (admin level on almost everything), while the classic approach does not add any more
permissions, and works perfectly well.__
- Select GitHub in "Select your repository section", choose certbot/certbot in Repository, master in default branch.
- Select GitHub in "Select your repository section", choose certbot/certbot in Repository, main in default branch.
- Click on YAML option for "Select a template"
- Choose a name for the pipeline (eg. test-pipeline), and browse to the actual pipeline YAML definition in the
"YAML file path" input (eg. `.azure-pipelines/test-pipeline.yml`)
- Click "Save & queue", choose the master branch to build the first pipeline, and click "Save and run" button.
- Click "Save & queue", choose the main branch to build the first pipeline, and click "Save and run" button.
_Done. Pipeline is operational. Repeat to add more pipelines from existing YAML files in `.azure-pipelines`._

View File

@@ -1,9 +1,9 @@
# We run the test suite on commits to master so codecov gets coverage data
# about the master branch and can use it to track coverage changes.
# We run the test suite on commits to main so codecov gets coverage data
# about the main branch and can use it to track coverage changes.
trigger:
- master
- main
pr:
- master
- main
- '*.x'
variables:

View File

@@ -1,4 +1,4 @@
# Nightly pipeline running each day for master.
# Nightly pipeline running each day for main.
trigger: none
pr: none
schedules:
@@ -6,7 +6,7 @@ schedules:
displayName: Nightly build
branches:
include:
- master
- main
always: true
variables:

View File

@@ -25,8 +25,9 @@ jobs:
linux-integration-nginx-oldest:
PYTHON_VERSION: 3.8
TOXENV: integration-nginx-oldest
# python 3.8 integration tests are not run here because they're run as
# part of the standard test suite
linux-py38-integration:
PYTHON_VERSION: 3.8
TOXENV: integration
linux-py39-integration:
PYTHON_VERSION: 3.9
TOXENV: integration
@@ -36,20 +37,19 @@ jobs:
linux-py311-integration:
PYTHON_VERSION: 3.11
TOXENV: integration
linux-py312-integration:
PYTHON_VERSION: 3.12
TOXENV: integration
# python 3.12 integration tests are not run here because they're run as
# part of the standard test suite
nginx-compat:
TOXENV: nginx_compat
linux-integration-rfc2136:
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.8
PYTHON_VERSION: 3.12
TOXENV: integration-dns-rfc2136
le-modification:
IMAGE_NAME: ubuntu-22.04
TOXENV: modification
farmtest-apache2:
PYTHON_VERSION: 3.8
PYTHON_VERSION: 3.12
TOXENV: test-farm-apache2
pool:
vmImage: $(IMAGE_NAME)

View File

@@ -1,60 +1,4 @@
jobs:
- job: docker_build
pool:
vmImage: ubuntu-22.04
strategy:
matrix:
arm32v6:
DOCKER_ARCH: arm32v6
arm64v8:
DOCKER_ARCH: arm64v8
amd64:
DOCKER_ARCH: amd64
# The default timeout of 60 minutes is a little low for compiling
# cryptography on ARM architectures.
timeoutInMinutes: 180
steps:
- bash: set -e && tools/docker/build.sh $(dockerTag) $DOCKER_ARCH
displayName: Build the Docker images
# We don't filter for the Docker Hub organization to continue to allow
# easy testing of these scripts on forks.
- bash: |
set -e
DOCKER_IMAGES=$(docker images --filter reference='*/certbot' --filter reference='*/dns-*' --format '{{.Repository}}')
docker save --output images.tar $DOCKER_IMAGES
displayName: Save the Docker images
# If the name of the tar file or artifact changes, the deploy stage will
# also need to be updated.
- bash: set -e && mv images.tar $(Build.ArtifactStagingDirectory)
displayName: Prepare Docker artifact
- task: PublishPipelineArtifact@1
inputs:
path: $(Build.ArtifactStagingDirectory)
artifact: docker_$(DOCKER_ARCH)
displayName: Store Docker artifact
- job: docker_test
dependsOn: docker_build
pool:
vmImage: ubuntu-22.04
strategy:
matrix:
arm32v6:
DOCKER_ARCH: arm32v6
arm64v8:
DOCKER_ARCH: arm64v8
amd64:
DOCKER_ARCH: amd64
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifact: docker_$(DOCKER_ARCH)
path: $(Build.SourcesDirectory)
displayName: Retrieve Docker images
- bash: set -e && docker load --input $(Build.SourcesDirectory)/images.tar
displayName: Load Docker images
- bash: |
set -e && tools/docker/test.sh $(dockerTag) $DOCKER_ARCH
displayName: Run integration tests for Docker images
- job: snaps_build
pool:
vmImage: ubuntu-22.04
@@ -62,10 +6,6 @@ jobs:
matrix:
amd64:
SNAP_ARCH: amd64
armhf:
SNAP_ARCH: armhf
arm64:
SNAP_ARCH: arm64
timeoutInMinutes: 0
steps:
- script: |
@@ -88,12 +28,11 @@ jobs:
git config --global user.name "$(Build.RequestedFor)"
mkdir -p ~/.local/share/snapcraft/provider/launchpad
cp $(credentials.secureFilePath) ~/.local/share/snapcraft/provider/launchpad/credentials
python3 tools/snap/build_remote.py ALL --archs ${SNAP_ARCH} --timeout $(snapBuildTimeout)
python3 tools/snap/build_remote.py certbot --archs ${SNAP_ARCH} --timeout $(snapBuildTimeout)
displayName: Build snaps
- script: |
set -e
mv *.snap $(Build.ArtifactStagingDirectory)
mv certbot-dns-*/*.snap $(Build.ArtifactStagingDirectory)
displayName: Prepare artifacts
- task: PublishPipelineArtifact@1
inputs:
@@ -129,31 +68,3 @@ jobs:
set -e
venv/bin/python -m tox run -e integration-external,apacheconftest-external-with-pebble
displayName: Run tox
- job: snap_dns_run
dependsOn: snaps_build
pool:
vmImage: ubuntu-22.04
steps:
- script: |
set -e
sudo apt-get update
sudo apt-get install -y --no-install-recommends snapd
displayName: Install dependencies
- task: UsePythonVersion@0
inputs:
versionSpec: 3.12
addToPath: true
- task: DownloadPipelineArtifact@2
inputs:
artifact: snaps_amd64
path: $(Build.SourcesDirectory)/snap
displayName: Retrieve Certbot snaps
- script: |
set -e
python3 -m venv venv
venv/bin/python tools/pip_install.py -e certbot-ci
displayName: Prepare Certbot-CI
- script: |
set -e
sudo -E venv/bin/pytest certbot-ci/snap_integration_tests/dns_tests --allow-persistent-changes --snap-folder $(Build.SourcesDirectory)/snap --snap-arch amd64
displayName: Test DNS plugins snaps

View File

@@ -5,14 +5,16 @@ jobs:
strategy:
matrix:
macos-py38-cover:
IMAGE_NAME: macOS-12
# mac unit+cover tests with the oldest python we support
IMAGE_NAME: macOS-15
PYTHON_VERSION: 3.8
TOXENV: cover
# As of pip 23.1.0, builds started failing on macOS unless this flag was set.
# See https://github.com/certbot/certbot/pull/9717#issuecomment-1610861794.
PIP_USE_PEP517: "true"
macos-cover:
IMAGE_NAME: macOS-13
# mac unit+cover tests with the newest python we support
IMAGE_NAME: macOS-15
TOXENV: cover
# See explanation under macos-py38-cover.
PIP_USE_PEP517: "true"
@@ -21,10 +23,12 @@ jobs:
PYTHON_VERSION: 3.8
TOXENV: oldest
linux-py38:
# linux unit tests with the oldest python we support
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.8
TOXENV: py38
linux-cover:
# linux unit+cover tests with the newest python we support
IMAGE_NAME: ubuntu-22.04
TOXENV: cover
linux-lint:
@@ -35,7 +39,6 @@ jobs:
TOXENV: mypy
linux-integration:
IMAGE_NAME: ubuntu-22.04
PYTHON_VERSION: 3.8
TOXENV: integration
apache-compat:
IMAGE_NAME: ubuntu-22.04

View File

@@ -1,6 +1,4 @@
stages:
- stage: TestAndPackage
jobs:
- template: ../jobs/standard-tests-jobs.yml
- template: ../jobs/extended-tests-jobs.yml
- template: ../jobs/packaging-jobs.yml

View File

@@ -1,6 +1,6 @@
## Pull Request Checklist
- [ ] The Certbot team has recently expressed interest in reviewing a PR for this. If not, this PR may be closed due our limited resources and need to prioritize how we spend them.
- [ ] If the change being made is to a [distributed component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), edit the `master` section of `certbot/CHANGELOG.md` to include a description of the change being made.
- [ ] If the change being made is to a [distributed component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), edit the `main` section of `certbot/CHANGELOG.md` to include a description of the change being made.
- [ ] Add or update any documentation as needed to support the changes in this PR.
- [ ] Include your name in `AUTHORS.md` if you like.

View File

@@ -8,25 +8,14 @@ on:
jobs:
if_merged:
# Forked repos can not access Mattermost secret.
if: github.event.pull_request.merged == true && !github.event.pull_request.head.repo.fork
if: github.event.pull_request.merged == true && !github.event.pull_request.head.repo.fork
runs-on: ubuntu-latest
steps:
- name: Create Mattermost Message
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#example-of-a-script-injection-attack
env:
NUMBER: ${{ github.event.number }}
PR_URL: https://github.com/${{ github.repository }}/pull/${{ github.event.number }}
REPO: ${{ github.repository }}
USER: ${{ github.actor }}
TITLE: ${{ github.event.pull_request.title }}
run: |
jq --null-input \
--arg number "$NUMBER" \
--arg pr_url "$PR_URL" \
--arg repo "$REPO" \
--arg user "$USER" \
--arg title "$TITLE" \
'{ "text": "[\($repo)] | [\($title) #\($number)](\($pr_url)) was merged into master by \($user)" }' > mattermost.json
- uses: mattermost/action-mattermost-notify@master
env:
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_MERGE_WEBHOOK }}
TEXT: >
[${{ github.repository }}] |
[${{ github.event.pull_request.title }}
#${{ github.event.number }}](https://github.com/${{ github.repository }}/pull/${{ github.event.number }})
was merged into main by ${{ github.actor }}

View File

@@ -4,6 +4,7 @@ on:
schedule:
# Every week on Thursday @ 13:00
- cron: "0 13 * * 4"
workflow_dispatch:
jobs:
send-mattermost-message:
runs-on: ubuntu-latest
@@ -11,15 +12,16 @@ jobs:
steps:
- name: Create Mattermost Message
run: |
DATE=$(date --date="7 days ago" +"%Y-%m-%d")
MERGED_URL="https://github.com/pulls?q=merged%3A%3E${DATE}+org%3Acertbot"
UPDATED_URL="https://github.com/pulls?q=updated%3A%3E${DATE}+org%3Acertbot"
echo "{\"text\":\"## Updates Across Certbot Repos\n\n
- Certbot team members SHOULD look at: [link]($MERGED_URL)\n\n
- Certbot team members MAY also want to look at: [link]($UPDATED_URL)\n\n
- Want to Discuss something today? Place it [here](https://docs.google.com/document/d/17YMUbtC1yg6MfiTMwT8zVm9LmO-cuGVBom0qFn8XJBM/edit?usp=sharing) and we can meet today on Zoom.\n\n
- The key words SHOULD and MAY in this message are to be interpreted as described in [RFC 8147](https://www.rfc-editor.org/rfc/rfc8174). \"
}" > mattermost.json
DATE=$(date --date="7 days ago" +"%Y-%m-%d")
echo "MERGED_URL=https://github.com/pulls?q=merged%3A%3E${DATE}+org%3Acertbot" >> $GITHUB_ENV
echo "UPDATED_URL=https://github.com/pulls?q=updated%3A%3E${DATE}+org%3Acertbot" >> $GITHUB_ENV
- uses: mattermost/action-mattermost-notify@master
env:
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }}
MATTERMOST_CHANNEL: private-certbot
TEXT: |
## Updates Across Certbot Repos
- Certbot team members SHOULD look at: [link](${{ env.MERGED_URL }})
- Certbot team members MAY also want to look at: [link](${{ env.UPDATED_URL }})
- Want to Discuss something today? Place it [here](https://docs.google.com/document/d/17YMUbtC1yg6MfiTMwT8zVm9LmO-cuGVBom0qFn8XJBM/edit?usp=sharing) and we can meet today on Zoom.
- The key words SHOULD and MAY in this message are to be interpreted as described in [RFC 8147](https://www.rfc-editor.org/rfc/rfc8174).

View File

@@ -3,6 +3,7 @@ on:
schedule:
# Run 1:24AM every night
- cron: '24 1 * * *'
workflow_dispatch:
permissions:
issues: write
jobs:

View File

@@ -6,6 +6,7 @@ This module is an implementation of the `ACME protocol`_.
"""
import sys
import warnings
# This code exists to keep backwards compatibility with people using acme.jose
# before it became the standalone josepy package.
@@ -19,3 +20,10 @@ for mod in list(sys.modules):
# preserved (acme.jose.* is josepy.*)
if mod == 'josepy' or mod.startswith('josepy.'):
sys.modules['acme.' + mod.replace('josepy', 'jose', 1)] = sys.modules[mod]
if sys.version_info[:2] == (3, 8):
warnings.warn(
"Python 3.8 support will be dropped in the next planned release of "
"acme. Please upgrade your Python version.",
PendingDeprecationWarning,
) # pragma: no cover

View File

@@ -3,7 +3,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'cryptography>=3.2.1',

View File

@@ -1,7 +1,7 @@
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
# We specify the minimum acme and certbot version as the current plugin

View File

@@ -96,7 +96,6 @@ def _prepare_args_env(certbot_args: List[str], directory_url: str, http_01_port:
'--no-verify-ssl',
'--http-01-port', str(http_01_port),
'--https-port', str(tls_alpn_01_port),
'--manual-public-ip-logging-ok',
'--config-dir', config_dir,
'--work-dir', os.path.join(workspace, 'work'),
'--logs-dir', os.path.join(workspace, 'logs'),

View File

@@ -1,7 +1,7 @@
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'certbot',

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
# for now, do not upgrade to cloudflare>=2.20 to avoid deprecation warnings and the breaking

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'python-digitalocean>=1.11', # 1.15.0 or newer is recommended for TTL support

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
# This version of lexicon is required to address the problem described in

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'dns-lexicon>=3.14.1',

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'dns-lexicon>=3.14.1',

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'google-api-python-client>=1.6.5',

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'dns-lexicon>=3.14.1',

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'dns-lexicon>=3.14.1',

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'dns-lexicon>=3.14.1',

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'dns-lexicon>=3.15.1',

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'dnspython>=1.15.0',

View File

@@ -101,13 +101,4 @@ Examples
--dns-route53 \\
-d example.com \\
-d www.example.com
.. code-block:: bash
:caption: To acquire a certificate for ``example.com``, waiting 30 seconds
for DNS propagation
certbot certonly \\
--dns-route53 \\
--dns-route53-propagation-seconds 30 \\
-d example.com
"""

View File

@@ -6,18 +6,20 @@ from typing import Any
from typing import Callable
from typing import DefaultDict
from typing import Dict
from typing import Iterable
from typing import List
from typing import Type
import boto3
from botocore.exceptions import ClientError
from botocore.exceptions import NoCredentialsError
from acme.challenges import ChallengeResponse
from acme import challenges
from certbot import achallenges
from certbot import errors
from certbot import interfaces
from certbot.achallenges import AnnotatedChallenge
from certbot.plugins import dns_common
from certbot.util import add_deprecated_argument
from certbot.plugins import common
logger = logging.getLogger(__name__)
@@ -27,7 +29,7 @@ INSTRUCTIONS = (
"and add the necessary permissions for Route53 access.")
class Authenticator(dns_common.DNSAuthenticator):
class Authenticator(common.Plugin, interfaces.Authenticator):
"""Route53 Authenticator
This authenticator solves a DNS01 challenge by uploading the answer to AWS
@@ -41,6 +43,7 @@ class Authenticator(dns_common.DNSAuthenticator):
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.r53 = boto3.client("route53")
self._attempt_cleanup = False
self._resource_records: DefaultDict[str, List[Dict[str, str]]] = \
collections.defaultdict(list)
@@ -48,9 +51,9 @@ class Authenticator(dns_common.DNSAuthenticator):
return "Solve a DNS01 challenge using AWS Route53"
@classmethod
def add_parser_arguments(cls, add: Callable[..., None], # pylint: disable=arguments-differ
default_propagation_seconds: int = 10) -> None:
add_deprecated_argument(add, 'propagation-seconds', 1)
def add_parser_arguments(cls, add: Callable[..., None]) -> None:
# This authenticator currently adds no extra arguments.
pass
def auth_hint(self, failed_achalls: List[achallenges.AnnotatedChallenge]) -> str:
return (
@@ -58,13 +61,13 @@ class Authenticator(dns_common.DNSAuthenticator):
'--dns-route53. Ensure the above domains have their DNS hosted by AWS Route53.'
)
def _setup_credentials(self) -> None:
def prepare(self) -> None:
pass
def _perform(self, domain: str, validation_name: str, validation: str) -> None:
pass
def get_chall_pref(self, unused_domain: str) -> Iterable[Type[challenges.Challenge]]:
return [challenges.DNS01]
def perform(self, achalls: List[AnnotatedChallenge]) -> List[ChallengeResponse]:
def perform(self, achalls: List[AnnotatedChallenge]) -> List[challenges.ChallengeResponse]:
self._attempt_cleanup = True
try:
@@ -82,7 +85,16 @@ class Authenticator(dns_common.DNSAuthenticator):
raise errors.PluginError("\n".join([str(e), INSTRUCTIONS]))
return [achall.response(achall.account_key) for achall in achalls]
def _cleanup(self, domain: str, validation_name: str, validation: str) -> None:
def cleanup(self, achalls: List[achallenges.AnnotatedChallenge]) -> None:
if self._attempt_cleanup:
for achall in achalls:
domain = achall.domain
validation_domain_name = achall.validation_domain_name(domain)
validation = achall.validation(achall.account_key)
self._cleanup(validation_domain_name, validation)
def _cleanup(self, validation_name: str, validation: str) -> None:
try:
self._change_txt_record("DELETE", validation_name, validation)
except (NoCredentialsError, ClientError) as e:
@@ -166,3 +178,13 @@ class Authenticator(dns_common.DNSAuthenticator):
raise errors.PluginError(
"Timed out waiting for Route53 change. Current status: %s" %
response["ChangeInfo"]["Status"])
# Our route53 plugin was initially a 3rd party plugin named `certbot-route53:auth` as described at
# https://github.com/certbot/certbot/issues/4688. This shim exists to allow installations using the
# old plugin name of `certbot-route53:auth` to continue to work without cluttering things like
# Certbot's help output with two route53 plugins.
class HiddenAuthenticator(Authenticator):
"""A hidden shim around certbot-dns-route53 for backwards compatibility."""
hidden = True

View File

@@ -6,17 +6,27 @@ from unittest import mock
from botocore.exceptions import ClientError
from botocore.exceptions import NoCredentialsError
import josepy as jose
import pytest
from acme import challenges
from certbot import achallenges
from certbot import errors
from certbot.compat import os
from certbot.plugins import dns_test_common
from certbot.plugins.dns_test_common import DOMAIN
from certbot.tests import acme_util
from certbot.tests import util as test_util
DOMAIN = 'example.com'
KEY = jose.JWKRSA.load(test_util.load_vector("rsa512_key.pem"))
class AuthenticatorTest(unittest.TestCase, dns_test_common.BaseAuthenticatorTest):
class AuthenticatorTest(unittest.TestCase):
# pylint: disable=protected-access
achall = achallenges.KeyAuthorizationAnnotatedChallenge(
challb=acme_util.DNS01, domain=DOMAIN, account_key=KEY)
def setUp(self):
from certbot_dns_route53._internal.dns_route53 import Authenticator
@@ -35,6 +45,12 @@ class AuthenticatorTest(unittest.TestCase, dns_test_common.BaseAuthenticatorTest
del os.environ["AWS_ACCESS_KEY_ID"]
del os.environ["AWS_SECRET_ACCESS_KEY"]
def test_more_info(self) -> None:
self.assertTrue(isinstance(self.auth.more_info(), str))
def test_get_chall_pref(self) -> None:
self.assertEqual(self.auth.get_chall_pref("example.org"), [challenges.DNS01])
def test_perform(self):
self.auth._change_txt_record = mock.MagicMock()
self.auth._wait_for_change = mock.MagicMock()
@@ -85,13 +101,6 @@ class AuthenticatorTest(unittest.TestCase, dns_test_common.BaseAuthenticatorTest
self.auth.cleanup([self.achall])
def test_parser_arguments(self) -> None:
from certbot.util import DeprecatedArgumentAction
m = mock.MagicMock()
self.auth.add_parser_arguments(m) # pylint: disable=no-member
m.assert_any_call('propagation-seconds', action=DeprecatedArgumentAction,
help=mock.ANY, nargs=1)
class ClientTest(unittest.TestCase):
# pylint: disable=protected-access

View File

@@ -1,17 +0,0 @@
"""Shim around `~certbot_dns_route53._internal.dns_route53` for backwards compatibility."""
from typing import Any
import warnings
from certbot_dns_route53._internal import dns_route53
class Authenticator(dns_route53.Authenticator):
"""Shim around `~certbot_dns_route53._internal.dns_route53.Authenticator`
for backwards compatibility."""
hidden = True
def __init__(self, *args: Any, **kwargs: Any) -> None:
warnings.warn("The 'authenticator' module was renamed 'dns_route53'",
DeprecationWarning)
super().__init__(*args, **kwargs)

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'boto3>=1.15.15',
@@ -71,7 +71,7 @@ setup(
entry_points={
'certbot.plugins': [
'dns-route53 = certbot_dns_route53._internal.dns_route53:Authenticator',
'certbot-route53:auth = certbot_dns_route53.authenticator:Authenticator'
'certbot-route53:auth = certbot_dns_route53._internal.dns_route53:HiddenAuthenticator',
],
},
)

View File

@@ -4,7 +4,7 @@ import sys
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
'dns-lexicon>=3.14.1',

View File

@@ -1,7 +1,7 @@
from setuptools import find_packages
from setuptools import setup
version = '2.12.0.dev0'
version = '3.1.0.dev0'
install_requires = [
# We specify the minimum acme and certbot version as the current plugin

View File

@@ -1,8 +1,25 @@
# Certbot change log
Certbot adheres to [Semantic Versioning](https://semver.org/).
## 3.0.0 - master
## 3.1.0 - main
### Added
*
### Changed
*
### Fixed
*
More details about these changes can be found on our GitHub repo.
## 3.0.0 - 2024-11-05
### Added
@@ -13,6 +30,13 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
* The update_symlinks command was removed.
* The `csr_dir` and `key_dir` attributes on
`certbot.configuration.NamespaceConfig` were removed.
* The `--manual-public-ip-logging-ok` command line flag was removed.
* The `--dns-route53-propagation-seconds` command line flag was removed.
* The `certbot_dns_route53.authenticator` module has been removed. This should
not affect any users of the plugin and instead would only affect developers
trying to develop on top of the old code.
* Support for Python 3.8 was deprecated and will be removed in our next planned
release.
### Fixed

View File

@@ -2,10 +2,10 @@
|build-status|
.. |build-status| image:: https://img.shields.io/azure-devops/build/certbot/ba534f81-a483-4b9b-9b4e-a60bec8fee72/5/master
.. |build-status| image:: https://img.shields.io/azure-devops/build/certbot/ba534f81-a483-4b9b-9b4e-a60bec8fee72/5/main
:target: https://dev.azure.com/certbot/certbot/_build?definitionId=5
:alt: Azure Pipelines CI status
.. image:: https://raw.githubusercontent.com/EFForg/design/master/logos/eff-certbot-lockup.png
:width: 200
:alt: EFF Certbot Logo
@@ -39,7 +39,7 @@ Documentation: https://certbot.eff.org/docs
Software project: https://github.com/certbot/certbot
Changelog: https://github.com/certbot/certbot/blob/master/certbot/CHANGELOG.md
Changelog: https://github.com/certbot/certbot/blob/main/certbot/CHANGELOG.md
For Contributors: https://certbot.eff.org/docs/contributing.html

View File

@@ -1,4 +1,13 @@
"""Certbot client."""
import sys
import warnings
# version number like 1.2.3a0, must have at least 2 parts, like 1.2
__version__ = '2.12.0.dev0'
__version__ = '3.1.0.dev0'
if sys.version_info[:2] == (3, 8):
warnings.warn(
"Python 3.8 support will be dropped in the next planned release of "
"certbot. Please upgrade your Python version.",
PendingDeprecationWarning,
) # pragma: no cover

View File

@@ -1866,6 +1866,10 @@ def main(cli_args: Optional[List[str]] = None) -> Optional[Union[str, int]]:
if config.func != plugins_cmd: # pylint: disable=comparison-with-callable
raise
if sys.version_info[:2] == (3, 8):
logger.warning("Python 3.8 support will be dropped in the next planned release "
"of Certbot - please upgrade your Python version.")
with make_displayer(config) as displayer:
display_obj.set_display(displayer)

View File

@@ -108,7 +108,6 @@ permitted by DNS standards.)
help='Path or command to execute for the authentication script')
add('cleanup-hook',
help='Path or command to execute for the cleanup script')
util.add_deprecated_argument(add, 'public-ip-logging-ok', 0)
def prepare(self) -> None: # pylint: disable=missing-function-docstring
if self.config.noninteractive_mode and not self.conf('auth-hook'):

View File

@@ -33,6 +33,7 @@ _ARCH_TRIPLET_MAP = {
'amd64': 'x86_64-linux-gnu',
's390x': 's390x-linux-gnu',
}
CURRENT_PYTHON_VERSION_STRING = 'python3.12'
LOGGER = logging.getLogger(__name__)
@@ -71,10 +72,35 @@ def prepare_env(cli_args: List[str]) -> List[str]:
raise e
data = response.json()
connections = ['/snap/{0}/current/lib/python3.12/site-packages/'.format(item['slot']['snap'])
for item in data.get('result', {}).get('established', [])
if item.get('plug', {}).get('plug') == 'plugin'
and item.get('plug-attrs', {}).get('content') == 'certbot-1']
connections = []
outdated_plugins = []
for plugin in data.get('result', {}).get('established', []):
plug: str = plugin.get('plug', {}).get('plug')
plug_content: str = plugin.get('plug-attrs', {}).get('content')
if plug == 'plugin' and plug_content == 'certbot-1':
plugin_name: str = plugin['slot']['snap']
# First, check that the plugin is using our expected python version,
# i.e. its "read" slot is something like
# "$SNAP/lib/python3.12/site-packages". If not, skip it and print an
# error.
slot_read: str = plugin.get('slot-attrs', {}).get('read', [])
if len(slot_read) != 0 and CURRENT_PYTHON_VERSION_STRING not in slot_read[0]:
outdated_plugins.append(plugin_name)
continue
connections.append('/snap/{0}/current/lib/{1}/site-packages/'.format(
plugin_name,
CURRENT_PYTHON_VERSION_STRING
))
if outdated_plugins:
LOGGER.warning('The following plugins are using an outdated python version and must be '
'updated to be compatible with Certbot 3.0. Please see '
'https://community.letsencrypt.org/t/'
'certbot-3-0-could-have-potential-third-party-snap-breakages/226940 '
'for more information:')
plugin_list = '\n'.join(' * {}'.format(plugin) for plugin in outdated_plugins)
LOGGER.warning(plugin_list)
os.environ['CERTBOT_PLUGIN_PATH'] = ':'.join(connections)

View File

@@ -594,7 +594,7 @@ class ParseTest(unittest.TestCase):
assert_set_by_user_with_value(namespace, 'text_mode', True)
assert_set_by_user_with_value(namespace, 'verbose_count', 1)
assert_set_by_user_with_value(namespace, 'email', 'foo@example.com')
def test_arg_with_contained_spaces(self):
# This can happen if a user specifies an arg like "-d foo.com" enclosed
# in double quotes, or as its own line in a docker-compose.yml file (as

View File

@@ -25,6 +25,10 @@ from certbot.plugins import common
logger = logging.getLogger(__name__)
# As of writing this, the only one of our plugins that does not inherit from this class (either
# directly or indirectly through certbot.plugins.dns_common_lexicon.LexiconDNSAuthenticator) is
# certbot-dns-route53. If you are attempting to make changes to all of our DNS plugins, please keep
# this difference in mind.
class DNSAuthenticator(common.Plugin, interfaces.Authenticator, metaclass=abc.ABCMeta):
"""Base class for DNS Authenticators"""

View File

@@ -122,7 +122,7 @@ options:
case, and to know when to deprecate support for past
Python versions and flags. If you wish to hide this
information from the Let's Encrypt server, set this to
"". (default: CertbotACMEClient/2.11.0 (certbot;
"". (default: CertbotACMEClient/3.0.0 (certbot;
OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY
(SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel).
The flags encoded in the user agent are: --duplicate,

View File

@@ -96,17 +96,15 @@ found in the `virtualenv docs`_.
Find issues to work on
----------------------
You can find the open issues in the `github issue tracker`_. Comparatively
easy ones are marked `good first issue`_. If you're starting work on
something, post a comment to let others know and seek feedback on your plan
where appropriate.
You can find the open issues in the `github issue tracker`_. If you're starting
work on something, post a comment to let others know and seek feedback on your
plan where appropriate.
Once you've got a working branch, you can open a pull request. All changes in
your pull request must have thorough unit test coverage, pass our
tests, and be compliant with the :ref:`coding style <coding-style>`.
.. _github issue tracker: https://github.com/certbot/certbot/issues
.. _good first issue: https://github.com/certbot/certbot/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22
.. _testing:
@@ -258,8 +256,8 @@ certificate once it is issued. Some plugins, like the built-in Apache and Nginx
plugins, implement both interfaces and perform both tasks. Others, like the
built-in Standalone authenticator, implement just one interface.
.. _interfaces.py: https://github.com/certbot/certbot/blob/master/certbot/certbot/interfaces.py
.. _plugins/common.py: https://github.com/certbot/certbot/blob/master/certbot/certbot/plugins/common.py#L45
.. _interfaces.py: https://github.com/certbot/certbot/blob/main/certbot/certbot/interfaces.py
.. _plugins/common.py: https://github.com/certbot/certbot/blob/main/certbot/certbot/plugins/common.py#L45
Authenticators
@@ -389,7 +387,7 @@ identifier ``metadata-1``.
The script used to generate the snapcraft.yaml files for our own externally
snapped plugins can be found at
https://github.com/certbot/certbot/blob/master/tools/snap/generate_dnsplugins_snapcraft.sh.
https://github.com/certbot/certbot/blob/main/tools/snap/generate_dnsplugins_snapcraft.sh.
For more information on building externally snapped plugins, see the section on
:ref:`Building snaps`.
@@ -562,7 +560,7 @@ Building the Certbot and DNS plugin snaps
Instructions for how to manually build and run the Certbot snap and the externally
snapped DNS plugins that the Certbot project supplies are located in the README
file at https://github.com/certbot/certbot/tree/master/tools/snap.
file at https://github.com/certbot/certbot/tree/main/tools/snap.
Updating the documentation
==========================

View File

@@ -25,7 +25,7 @@ We release packages and upload them to PyPI (wheels and source tarballs).
The following scripts are used in the process:
- https://github.com/certbot/certbot/blob/master/tools/release.sh
- https://github.com/certbot/certbot/blob/main/tools/release.sh
We use git tags to identify releases, using `Semantic Versioning`_. For
example: `v0.11.1`.
@@ -50,7 +50,7 @@ key servers.
Notes for package maintainers
=============================
0. Please use our tagged releases, not ``master``!
0. Please use our tagged releases, not ``main``!
1. Do not package ``certbot-compatibility-test`` as it's only used internally.

View File

@@ -99,7 +99,7 @@ Apache
------
The Apache plugin currently `supports
<https://github.com/certbot/certbot/blob/master/certbot-apache/certbot_apache/_internal/entrypoint.py>`_
<https://github.com/certbot/certbot/blob/main/certbot-apache/certbot_apache/_internal/entrypoint.py>`_
modern OSes based on Debian, Fedora, SUSE, Gentoo, CentOS and Darwin.
This automates both obtaining *and* installing certificates on an Apache
webserver. To specify this plugin on the command line, simply include

View File

@@ -66,9 +66,9 @@ parser.add_argument('--branch',
parser.add_argument('--pull_request',
default='~',
help='certbot/certbot pull request to trial')
parser.add_argument('--merge_master',
parser.add_argument('--merge_main',
action='store_true',
help="if set merges PR into master branch of certbot/certbot")
help="if set merges PR into main branch of certbot/certbot")
parser.add_argument('--saveinstances',
action='store_true',
help="don't kill EC2 instances after run, useful for debugging")
@@ -207,7 +207,7 @@ def block_until_instance_ready(booting_instance, extra_wait_time=20):
# Fabric Routines
#-------------------------------------------------------------------------------
def local_git_clone(local_cxn, repo_url, log_dir):
"""clones master of repo_url"""
"""clones main of repo_url"""
local_cxn.local('cd %s && if [ -d letsencrypt ]; then rm -rf letsencrypt; fi' % log_dir)
local_cxn.local('cd %s && git clone %s letsencrypt'% (log_dir, repo_url))
local_cxn.local('cd %s && tar czf le.tar.gz letsencrypt'% log_dir)
@@ -219,17 +219,17 @@ def local_git_branch(local_cxn, repo_url, branch_name, log_dir):
(log_dir, repo_url, branch_name))
local_cxn.local('cd %s && tar czf le.tar.gz letsencrypt' % log_dir)
def local_git_PR(local_cxn, repo_url, PRnumstr, log_dir, merge_master=True):
"""clones specified pull request from repo_url and optionally merges into master"""
def local_git_PR(local_cxn, repo_url, PRnumstr, log_dir, merge_main=True):
"""clones specified pull request from repo_url and optionally merges into main"""
local_cxn.local('cd %s && if [ -d letsencrypt ]; then rm -rf letsencrypt; fi' % log_dir)
local_cxn.local('cd %s && git clone %s letsencrypt' % (log_dir, repo_url))
local_cxn.local('cd %s && cd letsencrypt && '
'git fetch origin pull/%s/head:lePRtest' % (log_dir, PRnumstr))
local_cxn.local('cd %s && cd letsencrypt && git checkout lePRtest' % log_dir)
if merge_master:
if merge_main:
local_cxn.local('cd %s && cd letsencrypt && git remote update origin' % log_dir)
local_cxn.local('cd %s && cd letsencrypt && '
'git merge origin/master -m "testmerge"' % log_dir)
'git merge origin/main -m "testmerge"' % log_dir)
local_cxn.local('cd %s && tar czf le.tar.gz letsencrypt' % log_dir)
def local_repo_to_remote(cxn, log_dir):
@@ -382,9 +382,9 @@ def main():
print("Making local git repo")
if cl_args.pull_request != '~':
print('Testing PR %s ' % cl_args.pull_request,
"MERGING into master" if cl_args.merge_master else "")
"MERGING into main" if cl_args.merge_main else "")
local_git_PR(local_cxn, cl_args.repo, cl_args.pull_request, log_dir,
cl_args.merge_master)
cl_args.merge_main)
elif cl_args.branch != '~':
print('Testing branch %s of %s' % (cl_args.branch, cl_args.repo))
local_git_branch(local_cxn, cl_args.repo, cl_args.branch, log_dir)

View File

@@ -25,6 +25,7 @@
# dependencies) until https://github.com/certbot/certbot/issues/9828 is resolved.
# 6) Similarly to 6), CSR support is deprecated in pyOpenSSL since 24.2, we silence
# the warning until https://github.com/certbot/certbot/issues/9992 is resolved.
# 7) Ignore our own PendingDeprecationWarning about Python 3.8 soon to be dropped.
filterwarnings =
error
ignore:decodestring\(\) is a deprecated alias:DeprecationWarning:dns
@@ -33,3 +34,4 @@ filterwarnings =
ignore:.*datetime.utcfromtimestamp\(\) is deprecated:DeprecationWarning:dateutil
ignore:X509Extension support in pyOpenSSL is deprecated:DeprecationWarning
ignore:CSR support in pyOpenSSL is deprecated:DeprecationWarning
ignore:Python 3.8 support will be dropped:PendingDeprecationWarning

View File

@@ -23,7 +23,7 @@ environment:
apps:
certbot:
command: bin/python3 -s $SNAP/bin/certbot
command: bin/python3-dbg -s $SNAP/bin/certbot
environment:
PATH: "$SNAP/bin:$SNAP/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
AUGEAS_LENS_LIB: "$SNAP/usr/share/augeas/lenses/dist"
@@ -72,7 +72,9 @@ parts:
- python3-minimal
- python3-pkg-resources
- python3.12-minimal
# To build cryptography and cffi if needed
- libpython3-all-dbg
- python3-dbg
- python3.12-dbg
build-packages:
- gcc
- git
@@ -80,7 +82,9 @@ parts:
- build-essential
- libssl-dev
- libffi-dev
- python3-dev
- libpython3-all-dbg
- python3-dbg
- python3-venv
- cargo
- pkg-config
build-environment:
@@ -95,9 +99,10 @@ parts:
# build, but also on any isolated build that pip could trigger when building wheels for
# dependencies. See https://github.com/certbot/certbot/pull/8443 for more info.
- PIP_CONSTRAINT: $CRAFT_PART_SRC/snap-constraints.txt
- PARTS_PYTHON_INTERPRETER: "python3-dbg"
override-build: |
python3 -m venv "${CRAFT_PART_INSTALL}"
"${CRAFT_PART_INSTALL}/bin/python3" "${CRAFT_PART_SRC}/tools/pipstrap.py"
python3-dbg -m venv "${CRAFT_PART_INSTALL}"
"${CRAFT_PART_INSTALL}/bin/python3-dbg" "${CRAFT_PART_SRC}/tools/pipstrap.py"
craftctl default
override-pull: |
craftctl default

View File

@@ -1,4 +1,4 @@
## nextversion - master
## nextversion - main
### Added

View File

@@ -97,7 +97,7 @@ fi
git checkout "$RELEASE_BRANCH"
# Update changelog
sed -i "s/master/$(date +'%Y-%m-%d')/" certbot/CHANGELOG.md
sed -i "0,/main/ s/main/$(date +'%Y-%m-%d')/" certbot/CHANGELOG.md
git add certbot/CHANGELOG.md
git commit -m "Update changelog for $version release"
@@ -205,7 +205,7 @@ git tag --local-user "$RELEASE_GPG_KEY" --sign --message "Release $version" "$ta
git rm --cached -r "$built_package_dir"
git commit -m "Remove built packages from git"
# Add master section to CHANGELOG.md
# Add main section to CHANGELOG.md
header=$(head -n 4 certbot/CHANGELOG.md)
body=$(sed s/nextversion/$nextversion/ tools/_changelog_top.txt)
footer=$(tail -n +5 certbot/CHANGELOG.md)

View File

@@ -1,5 +1,5 @@
#base image
FROM python:3.12-alpine3.18 as certbot
FROM python:3.12-alpine3.18 AS certbot
ENTRYPOINT [ "certbot" ]
EXPOSE 80 443
@@ -25,6 +25,12 @@ RUN apk add --no-cache --virtual .certbot-deps \
# cryptography library
ARG CARGO_NET_GIT_FETCH_WITH_CLI=true
# Install certbot from sources
#
# For some reason, setting the CARGO_LOG and CARGO_TERM_VERBOSE environment
# variables and -v/--verbose flags on pip seems to help cryptography builds not
# hang when building Docker images for other architectures using QEMU. See
# https://github.com/certbot/certbot/issues/10020. This may hopefully also help
# us to get more information about the problem to aid further debugging.
RUN apk add --no-cache --virtual .build-deps \
gcc \
linux-headers \
@@ -35,7 +41,8 @@ RUN apk add --no-cache --virtual .build-deps \
cargo \
git \
pkgconfig \
&& python tools/pip_install.py --no-cache-dir \
&& CARGO_LOG=trace CARGO_TERM_VERBOSE=true python tools/pip_install.py \
--no-cache-dir -vvv \
--editable src/acme \
--editable src/certbot \
&& apk del .build-deps \
@@ -44,6 +51,6 @@ RUN apk add --no-cache --virtual .build-deps \
#static definition for making a plugin, but beware that
#using this layer definition will cause collisions if you make
#extensive use of the cache.
FROM certbot as certbot-plugin
FROM certbot AS certbot-plugin
COPY --from=plugin-src . /opt/certbot/src/plugin
RUN python tools/pip_install.py --no-cache-dir --editable /opt/certbot/src/plugin

View File

@@ -70,7 +70,7 @@ ParseArgs() {
local IFS=","
# Handle the special value "all"
if [[ "${ARCH_LIST}" == "all" ]]; then
# Replace with comma separated
# Replace with comma separated
ARCH_LIST="${ALL_TARGET_ARCH[*]}"
fi
@@ -88,7 +88,7 @@ ParseArgs() {
}
# Function for use with trap in the primary scripts to remove the
# Function for use with trap in the primary scripts to remove the
# docker builder and restore the original directory
Cleanup() {
docker buildx rm certbot_builder || true
@@ -106,5 +106,11 @@ CreateBuilder() {
# just incase the env is not perfectly clean, remove any old instance of the builder
docker buildx rm certbot_builder || true
# create the builder instance
docker buildx create --name certbot_builder --driver docker-container --driver-opt=network=host --bootstrap
}
#
# BUILDKIT_STEP_LOG_MAX_* environment variables are set to prevent docker
# from truncating build logs that can be useful during debugging. See
# https://github.com/docker/buildx/issues/484#issuecomment-749352728
docker buildx create --name certbot_builder --driver docker-container \
--driver-opt=network=host --driver-opt env.BUILDKIT_STEP_LOG_MAX_SIZE=-1 \
--driver-opt env.BUILDKIT_STEP_LOG_MAX_SPEED=-1 --bootstrap
}

View File

@@ -111,7 +111,7 @@ def get_snap_revisions(snap, channel, version):
print('Getting revision numbers for', snap, version)
cmd = ['snapcraft', 'status', snap]
process = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, universal_newlines=True)
pattern = f'^\s+{channel}\s+{version}\s+(\d+)\s*'
pattern = f'^\\s+{channel}\\s+{version}\\s+(\\d+)\\s*'
revisions = re.findall(pattern, process.stdout, re.MULTILINE)
assert len(revisions) == SNAP_ARCH_COUNT, f'Unexpected number of snaps found for {channel} {snap} {version} (expected {SNAP_ARCH_COUNT}, found {len(revisions)})'
return revisions

View File

@@ -11,34 +11,34 @@ appnope==0.1.4 ; python_version >= "3.8" and python_version < "4.0" and sys_plat
astroid==3.0.3 ; python_version >= "3.8" and python_version < "4.0"
asttokens==2.4.1 ; python_version >= "3.8" and python_version < "4.0"
attrs==24.2.0 ; python_version >= "3.8" and python_version < "4.0"
azure-core==1.30.2 ; python_version >= "3.8" and python_version < "4.0"
azure-core==1.32.0 ; python_version >= "3.8" and python_version < "4.0"
azure-devops==7.1.0b4 ; python_version >= "3.8" and python_version < "4.0"
babel==2.16.0 ; python_version >= "3.8" and python_version < "4.0"
backcall==0.2.0 ; python_version >= "3.8" and python_version < "4.0"
bcrypt==4.2.0 ; python_version >= "3.8" and python_version < "4.0"
beautifulsoup4==4.12.3 ; python_version >= "3.8" and python_version < "4.0"
boto3==1.35.6 ; python_version >= "3.8" and python_version < "4.0"
botocore==1.35.6 ; python_version >= "3.8" and python_version < "4.0"
build==1.2.1 ; python_version >= "3.8" and python_version < "4.0"
boto3==1.35.53 ; python_version >= "3.8" and python_version < "4.0"
botocore==1.35.53 ; python_version >= "3.8" and python_version < "4.0"
build==1.2.2.post1 ; python_version >= "3.8" and python_version < "4.0"
cachecontrol==0.14.0 ; python_version >= "3.8" and python_version < "4.0"
cachetools==5.5.0 ; python_version >= "3.8" and python_version < "4.0"
certifi==2024.7.4 ; python_version >= "3.8" and python_version < "4.0"
cffi==1.17.0 ; python_version >= "3.8" and python_version < "4.0"
certifi==2024.8.30 ; python_version >= "3.8" and python_version < "4.0"
cffi==1.17.1 ; python_version >= "3.8" and python_version < "4.0"
chardet==5.2.0 ; python_version >= "3.8" and python_version < "4.0"
charset-normalizer==3.3.2 ; python_version >= "3.8" and python_version < "4.0"
charset-normalizer==3.4.0 ; python_version >= "3.8" and python_version < "4.0"
cleo==2.1.0 ; python_version >= "3.8" and python_version < "4.0"
cloudflare==2.19.4 ; python_version >= "3.8" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.8" and python_version < "4.0"
configargparse==1.7 ; python_version >= "3.8" and python_version < "4.0"
configobj==5.0.8 ; python_version >= "3.8" and python_version < "4.0"
configobj==5.0.9 ; python_version >= "3.8" and python_version < "4.0"
coverage==7.6.1 ; python_version >= "3.8" and python_version < "4.0"
crashtest==0.4.1 ; python_version >= "3.8" and python_version < "4.0"
cryptography==43.0.0 ; python_version >= "3.8" and python_version < "4.0"
cryptography==43.0.3 ; python_version >= "3.8" and python_version < "4.0"
cython==0.29.37 ; python_version >= "3.8" and python_version < "4.0"
decorator==5.1.1 ; python_version >= "3.8" and python_version < "4.0"
deprecated==1.2.14 ; python_version >= "3.8" and python_version < "4.0"
dill==0.3.8 ; python_version >= "3.8" and python_version < "4.0"
distlib==0.3.8 ; python_version >= "3.8" and python_version < "4.0"
dill==0.3.9 ; python_version >= "3.8" and python_version < "4.0"
distlib==0.3.9 ; python_version >= "3.8" and python_version < "4.0"
distro==1.9.0 ; python_version >= "3.8" and python_version < "4.0"
dns-lexicon==3.18.0 ; python_version >= "3.8" and python_version < "4.0"
dnspython==2.6.1 ; python_version >= "3.8" and python_version < "4.0"
@@ -46,26 +46,26 @@ docutils==0.20.1 ; python_version >= "3.8" and python_version < "4.0"
dulwich==0.21.7 ; python_version >= "3.8" and python_version < "4.0"
exceptiongroup==1.2.2 ; python_version >= "3.8" and python_version < "3.11"
execnet==2.1.1 ; python_version >= "3.8" and python_version < "4.0"
executing==2.0.1 ; python_version >= "3.8" and python_version < "4.0"
executing==2.1.0 ; python_version >= "3.8" and python_version < "4.0"
fabric==3.2.2 ; python_version >= "3.8" and python_version < "4.0"
fastjsonschema==2.20.0 ; python_version >= "3.8" and python_version < "4.0"
filelock==3.15.4 ; python_version >= "3.8" and python_version < "4.0"
google-api-core==2.19.1 ; python_version >= "3.8" and python_version < "4.0"
google-api-python-client==2.142.0 ; python_version >= "3.8" and python_version < "4.0"
filelock==3.16.1 ; python_version >= "3.8" and python_version < "4.0"
google-api-core==2.22.0 ; python_version >= "3.8" and python_version < "4.0"
google-api-python-client==2.151.0 ; python_version >= "3.8" and python_version < "4.0"
google-auth-httplib2==0.2.0 ; python_version >= "3.8" and python_version < "4.0"
google-auth==2.34.0 ; python_version >= "3.8" and python_version < "4.0"
googleapis-common-protos==1.64.0 ; python_version >= "3.8" and python_version < "4.0"
google-auth==2.35.0 ; python_version >= "3.8" and python_version < "4.0"
googleapis-common-protos==1.65.0 ; python_version >= "3.8" and python_version < "4.0"
httplib2==0.22.0 ; python_version >= "3.8" and python_version < "4.0"
idna==3.8 ; python_version >= "3.8" and python_version < "4.0"
idna==3.10 ; python_version >= "3.8" and python_version < "4.0"
imagesize==1.4.1 ; python_version >= "3.8" and python_version < "4.0"
importlib-metadata==8.4.0 ; python_version >= "3.8" and python_version < "4.0"
importlib-resources==6.4.4 ; python_version >= "3.8" and python_version < "4.0"
importlib-metadata==8.5.0 ; python_version >= "3.8" and python_version < "4.0"
importlib-resources==6.4.5 ; python_version >= "3.8" and python_version < "4.0"
iniconfig==2.0.0 ; python_version >= "3.8" and python_version < "4.0"
installer==0.7.0 ; python_version >= "3.8" and python_version < "4.0"
invoke==2.2.0 ; python_version >= "3.8" and python_version < "4.0"
ipdb==0.13.13 ; python_version >= "3.8" and python_version < "4.0"
ipython==8.12.3 ; python_version >= "3.8" and python_version < "4.0"
isodate==0.6.1 ; python_version >= "3.8" and python_version < "4.0"
isodate==0.7.2 ; python_version >= "3.8" and python_version < "4.0"
isort==5.13.2 ; python_version >= "3.8" and python_version < "4.0"
jaraco-classes==3.4.0 ; python_version >= "3.8" and python_version < "4.0"
jedi==0.19.1 ; python_version >= "3.8" and python_version < "4.0"
@@ -74,41 +74,41 @@ jinja2==3.1.4 ; python_version >= "3.8" and python_version < "4.0"
jmespath==1.0.1 ; python_version >= "3.8" and python_version < "4.0"
josepy==1.14.0 ; python_version >= "3.8" and python_version < "4.0"
jsonlines==4.0.0 ; python_version >= "3.8" and python_version < "4.0"
jsonpickle==3.2.2 ; python_version >= "3.8" and python_version < "4.0"
jsonpickle==3.3.0 ; python_version >= "3.8" and python_version < "4.0"
keyring==24.3.1 ; python_version >= "3.8" and python_version < "4.0"
markdown-it-py==3.0.0 ; python_version >= "3.8" and python_version < "4.0"
markupsafe==2.1.5 ; python_version >= "3.8" and python_version < "4.0"
matplotlib-inline==0.1.7 ; python_version >= "3.8" and python_version < "4.0"
mccabe==0.7.0 ; python_version >= "3.8" and python_version < "4.0"
mdurl==0.1.2 ; python_version >= "3.8" and python_version < "4.0"
more-itertools==10.4.0 ; python_version >= "3.8" and python_version < "4.0"
msgpack==1.0.8 ; python_version >= "3.8" and python_version < "4.0"
more-itertools==10.5.0 ; python_version >= "3.8" and python_version < "4.0"
msgpack==1.1.0 ; python_version >= "3.8" and python_version < "4.0"
msrest==0.7.1 ; python_version >= "3.8" and python_version < "4.0"
mypy-extensions==1.0.0 ; python_version >= "3.8" and python_version < "4.0"
mypy==1.9.0 ; python_version >= "3.8" and python_version < "4.0"
nh3==0.2.18 ; python_version >= "3.8" and python_version < "4.0"
oauthlib==3.2.2 ; python_version >= "3.8" and python_version < "4.0"
packaging==24.1 ; python_version >= "3.8" and python_version < "4.0"
paramiko==3.4.1 ; python_version >= "3.8" and python_version < "4.0"
paramiko==3.5.0 ; python_version >= "3.8" and python_version < "4.0"
parsedatetime==2.6 ; python_version >= "3.8" and python_version < "4.0"
parso==0.8.4 ; python_version >= "3.8" and python_version < "4.0"
pexpect==4.9.0 ; python_version >= "3.8" and python_version < "4.0"
pickleshare==0.7.5 ; python_version >= "3.8" and python_version < "4.0"
pip==24.2 ; python_version >= "3.8" and python_version < "4.0"
pip==24.3.1 ; python_version >= "3.8" and python_version < "4.0"
pkginfo==1.10.0 ; python_version >= "3.8" and python_version < "4.0"
platformdirs==4.2.2 ; python_version >= "3.8" and python_version < "4.0"
platformdirs==4.3.6 ; python_version >= "3.8" and python_version < "4.0"
pluggy==1.5.0 ; python_version >= "3.8" and python_version < "4.0"
ply==3.11 ; python_version >= "3.8" and python_version < "4.0"
poetry-core==1.9.0 ; python_version >= "3.8" and python_version < "4.0"
poetry-core==1.9.1 ; python_version >= "3.8" and python_version < "4.0"
poetry-plugin-export==1.8.0 ; python_version >= "3.8" and python_version < "4.0"
poetry==1.8.3 ; python_version >= "3.8" and python_version < "4.0"
prompt-toolkit==3.0.47 ; python_version >= "3.8" and python_version < "4.0"
proto-plus==1.24.0 ; python_version >= "3.8" and python_version < "4.0"
protobuf==5.27.3 ; python_version >= "3.8" and python_version < "4.0"
poetry==1.8.4 ; python_version >= "3.8" and python_version < "4.0"
prompt-toolkit==3.0.48 ; python_version >= "3.8" and python_version < "4.0"
proto-plus==1.25.0 ; python_version >= "3.8" and python_version < "4.0"
protobuf==5.28.3 ; python_version >= "3.8" and python_version < "4.0"
ptyprocess==0.7.0 ; python_version >= "3.8" and python_version < "4.0"
pure-eval==0.2.3 ; python_version >= "3.8" and python_version < "4.0"
pyasn1-modules==0.4.0 ; python_version >= "3.8" and python_version < "4.0"
pyasn1==0.6.0 ; python_version >= "3.8" and python_version < "4.0"
pyasn1-modules==0.4.1 ; python_version >= "3.8" and python_version < "4.0"
pyasn1==0.6.1 ; python_version >= "3.8" and python_version < "4.0"
pycparser==2.22 ; python_version >= "3.8" and python_version < "4.0"
pygments==2.18.0 ; python_version >= "3.8" and python_version < "4.0"
pylint==3.0.2 ; python_version >= "3.8" and python_version < "4.0"
@@ -117,20 +117,20 @@ pynsist==2.7 ; python_version >= "3.8" and python_version < "4.0"
pyopenssl==24.2.1 ; python_version >= "3.8" and python_version < "4.0"
pyotp==2.9.0 ; python_version >= "3.8" and python_version < "4.0"
pyparsing==3.1.4 ; python_version >= "3.8" and python_version < "4.0"
pyproject-api==1.7.1 ; python_version >= "3.8" and python_version < "4.0"
pyproject-hooks==1.1.0 ; python_version >= "3.8" and python_version < "4.0"
pyproject-api==1.8.0 ; python_version >= "3.8" and python_version < "4.0"
pyproject-hooks==1.2.0 ; python_version >= "3.8" and python_version < "4.0"
pyrfc3339==1.1 ; python_version >= "3.8" and python_version < "4.0"
pytest-cov==5.0.0 ; python_version >= "3.8" and python_version < "4.0"
pytest-xdist==3.6.1 ; python_version >= "3.8" and python_version < "4.0"
pytest==8.3.2 ; python_version >= "3.8" and python_version < "4.0"
pytest==8.3.3 ; python_version >= "3.8" and python_version < "4.0"
python-augeas==1.1.0 ; python_version >= "3.8" and python_version < "4.0"
python-dateutil==2.9.0.post0 ; python_version >= "3.8" and python_version < "4.0"
python-digitalocean==1.17.0 ; python_version >= "3.8" and python_version < "4.0"
pytz==2024.1 ; python_version >= "3.8" and python_version < "4.0"
pytz==2024.2 ; python_version >= "3.8" and python_version < "4.0"
pywin32-ctypes==0.2.3 ; python_version >= "3.8" and python_version < "4.0" and sys_platform == "win32"
pywin32==306 ; python_version >= "3.8" and python_version < "4.0" and sys_platform == "win32"
pywin32==308 ; python_version >= "3.8" and python_version < "4.0" and sys_platform == "win32"
pyyaml==6.0.2 ; python_version >= "3.8" and python_version < "4.0"
rapidfuzz==3.9.6 ; python_version >= "3.8" and python_version < "4.0"
rapidfuzz==3.9.7 ; python_version >= "3.8" and python_version < "4.0"
readme-renderer==43.0 ; python_version >= "3.8" and python_version < "4.0"
requests-download==0.1.2 ; python_version >= "3.8" and python_version < "4.0"
requests-file==2.1.0 ; python_version >= "3.8" and python_version < "4.0"
@@ -138,18 +138,18 @@ requests-oauthlib==2.0.0 ; python_version >= "3.8" and python_version < "4.0"
requests-toolbelt==1.0.0 ; python_version >= "3.8" and python_version < "4.0"
requests==2.32.3 ; python_version >= "3.8" and python_version < "4.0"
rfc3986==2.0.0 ; python_version >= "3.8" and python_version < "4.0"
rich==13.8.0 ; python_version >= "3.8" and python_version < "4.0"
rich==13.9.3 ; python_version >= "3.8" and python_version < "4.0"
rsa==4.9 ; python_version >= "3.8" and python_version < "4"
s3transfer==0.10.2 ; python_version >= "3.8" and python_version < "4.0"
s3transfer==0.10.3 ; python_version >= "3.8" and python_version < "4.0"
secretstorage==3.3.3 ; python_version >= "3.8" and python_version < "4.0" and sys_platform == "linux"
semantic-version==2.10.0 ; python_version >= "3.8" and python_version < "4.0"
setuptools-rust==1.10.1 ; python_version >= "3.8" and python_version < "4.0"
setuptools==73.0.1 ; python_version >= "3.8" and python_version < "4.0"
setuptools-rust==1.10.2 ; python_version >= "3.8" and python_version < "4.0"
setuptools==75.3.0 ; python_version >= "3.8" and python_version < "4.0"
shellingham==1.5.4 ; python_version >= "3.8" and python_version < "4.0"
six==1.16.0 ; python_version >= "3.8" and python_version < "4.0"
snowballstemmer==2.2.0 ; python_version >= "3.8" and python_version < "4.0"
soupsieve==2.6 ; python_version >= "3.8" and python_version < "4.0"
sphinx-rtd-theme==2.0.0 ; python_version >= "3.8" and python_version < "4.0"
sphinx-rtd-theme==3.0.1 ; python_version >= "3.8" and python_version < "4.0"
sphinx==7.1.2 ; python_version >= "3.8" and python_version < "4.0"
sphinxcontrib-applehelp==1.0.4 ; python_version >= "3.8" and python_version < "4.0"
sphinxcontrib-devhelp==1.0.2 ; python_version >= "3.8" and python_version < "4.0"
@@ -160,30 +160,29 @@ sphinxcontrib-qthelp==1.0.3 ; python_version >= "3.8" and python_version < "4.0"
sphinxcontrib-serializinghtml==1.1.5 ; python_version >= "3.8" and python_version < "4.0"
stack-data==0.6.3 ; python_version >= "3.8" and python_version < "4.0"
tldextract==5.1.2 ; python_version >= "3.8" and python_version < "4.0"
tomli==2.0.1 ; python_version >= "3.8" and python_full_version <= "3.11.0a6"
tomli==2.0.2 ; python_version >= "3.8" and python_full_version <= "3.11.0a6"
tomlkit==0.13.2 ; python_version >= "3.8" and python_version < "4.0"
tox==4.18.0 ; python_version >= "3.8" and python_version < "4.0"
tox==4.23.2 ; python_version >= "3.8" and python_version < "4.0"
traitlets==5.14.3 ; python_version >= "3.8" and python_version < "4.0"
trove-classifiers==2024.7.2 ; python_version >= "3.8" and python_version < "4.0"
trove-classifiers==2024.10.21.16 ; python_version >= "3.8" and python_version < "4.0"
twine==5.1.1 ; python_version >= "3.8" and python_version < "4.0"
types-cffi==1.16.0.20240331 ; python_version >= "3.8" and python_version < "4.0"
types-httplib2==0.22.0.20240310 ; python_version >= "3.8" and python_version < "4.0"
types-pyopenssl==24.1.0.20240722 ; python_version >= "3.8" and python_version < "4.0"
types-pyrfc3339==1.1.1.5 ; python_version >= "3.8" and python_version < "4.0"
types-python-dateutil==2.9.0.20240821 ; python_version >= "3.8" and python_version < "4.0"
types-pytz==2024.1.0.20240417 ; python_version >= "3.8" and python_version < "4.0"
types-pywin32==306.0.0.20240822 ; python_version >= "3.8" and python_version < "4.0"
types-python-dateutil==2.9.0.20241003 ; python_version >= "3.8" and python_version < "4.0"
types-pytz==2024.2.0.20241003 ; python_version >= "3.8" and python_version < "4.0"
types-pywin32==308.0.0.20241029 ; python_version >= "3.8" and python_version < "4.0"
types-requests==2.31.0.6 ; python_version >= "3.8" and python_version < "4.0"
types-setuptools==73.0.0.20240822 ; python_version >= "3.8" and python_version < "4.0"
types-six==1.16.21.20240513 ; python_version >= "3.8" and python_version < "4.0"
types-setuptools==75.2.0.20241025 ; python_version >= "3.8" and python_version < "4.0"
types-urllib3==1.26.25.14 ; python_version >= "3.8" and python_version < "4.0"
typing-extensions==4.12.2 ; python_version >= "3.8" and python_version < "4.0"
uritemplate==4.1.1 ; python_version >= "3.8" and python_version < "4.0"
urllib3==1.26.19 ; python_version >= "3.8" and python_version < "4.0"
virtualenv==20.26.3 ; python_version >= "3.8" and python_version < "4.0"
urllib3==1.26.20 ; python_version >= "3.8" and python_version < "4.0"
virtualenv==20.27.1 ; python_version >= "3.8" and python_version < "4.0"
wcwidth==0.2.13 ; python_version >= "3.8" and python_version < "4.0"
wheel==0.44.0 ; python_version >= "3.8" and python_version < "4.0"
wrapt==1.16.0 ; python_version >= "3.8" and python_version < "4.0"
xattr==1.1.0 ; python_version >= "3.8" and python_version < "4.0" and sys_platform == "darwin"
yarg==0.1.10 ; python_version >= "3.8" and python_version < "4.0"
zipp==3.20.1 ; python_version >= "3.8" and python_version < "4.0"
zipp==3.20.2 ; python_version >= "3.8" and python_version < "4.0"

View File

@@ -25,7 +25,7 @@ cb_required=\$(grep -oP "version = '\K.*(?=')" \$SNAP/setup.py)
\$SNAP/bin/python3 -c "import sys; from packaging import version; sys.exit(1) if\
version.parse('\$cb_installed') < version.parse('\$cb_required') else sys.exit(0)" || exit_code=\$?
if [ "\$exit_code" -eq 1 ]; then
if [ "\$exit_code" = "1" ]; then
echo "Certbot is version \$cb_installed but needs to be at least \$cb_required before" \\
"this plugin can be updated; will try again on next refresh."
exit 1