mirror of
https://github.com/certbot/certbot.git
synced 2026-06-06 15:22:38 -04:00
Merge branch 'master' into remove-setuptools-test
This commit is contained in:
commit
e2377f129e
17 changed files with 196 additions and 59 deletions
|
|
@ -61,6 +61,7 @@ Authors
|
|||
* [Daniel Albers](https://github.com/AID)
|
||||
* [Daniel Aleksandersen](https://github.com/da2x)
|
||||
* [Daniel Convissor](https://github.com/convissor)
|
||||
* [Daniel "Drex" Drexler](https://github.com/aeturnum)
|
||||
* [Daniel Huang](https://github.com/dhuang)
|
||||
* [Dave Guarino](https://github.com/daguar)
|
||||
* [David cz](https://github.com/dave-cz)
|
||||
|
|
|
|||
|
|
@ -315,6 +315,9 @@ class Registration(ResourceBody):
|
|||
# on new-reg key server ignores 'key' and populates it based on
|
||||
# JWS.signature.combined.jwk
|
||||
key = jose.Field('key', omitempty=True, decoder=jose.JWK.from_json)
|
||||
# Contact field implements special behavior to allow messages that clear existing
|
||||
# contacts while not expecting the `contact` field when loading from json.
|
||||
# This is implemented in the constructor and *_json methods.
|
||||
contact = jose.Field('contact', omitempty=True, default=())
|
||||
agreement = jose.Field('agreement', omitempty=True)
|
||||
status = jose.Field('status', omitempty=True)
|
||||
|
|
@ -327,24 +330,73 @@ class Registration(ResourceBody):
|
|||
|
||||
@classmethod
|
||||
def from_data(cls, phone=None, email=None, external_account_binding=None, **kwargs):
|
||||
"""Create registration resource from contact details."""
|
||||
"""
|
||||
Create registration resource from contact details.
|
||||
|
||||
The `contact` keyword being passed to a Registration object is meaningful, so
|
||||
this function represents empty iterables in its kwargs by passing on an empty
|
||||
`tuple`.
|
||||
"""
|
||||
|
||||
# Note if `contact` was in kwargs.
|
||||
contact_provided = 'contact' in kwargs
|
||||
|
||||
# Pop `contact` from kwargs and add formatted email or phone numbers
|
||||
details = list(kwargs.pop('contact', ()))
|
||||
if phone is not None:
|
||||
details.append(cls.phone_prefix + phone)
|
||||
if email is not None:
|
||||
details.extend([cls.email_prefix + mail for mail in email.split(',')])
|
||||
kwargs['contact'] = tuple(details)
|
||||
|
||||
# Insert formatted contact information back into kwargs
|
||||
# or insert an empty tuple if `contact` provided.
|
||||
if details or contact_provided:
|
||||
kwargs['contact'] = tuple(details)
|
||||
|
||||
if external_account_binding:
|
||||
kwargs['external_account_binding'] = external_account_binding
|
||||
|
||||
return cls(**kwargs)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""Note if the user provides a value for the `contact` member."""
|
||||
if 'contact' in kwargs:
|
||||
# Avoid the __setattr__ used by jose.TypedJSONObjectWithFields
|
||||
object.__setattr__(self, '_add_contact', True)
|
||||
super(Registration, self).__init__(**kwargs)
|
||||
|
||||
def _filter_contact(self, prefix):
|
||||
return tuple(
|
||||
detail[len(prefix):] for detail in self.contact # pylint: disable=not-an-iterable
|
||||
if detail.startswith(prefix))
|
||||
|
||||
def _add_contact_if_appropriate(self, jobj):
|
||||
"""
|
||||
The `contact` member of Registration objects should not be required when
|
||||
de-serializing (as it would be if the Fields' `omitempty` flag were `False`), but
|
||||
it should be included in serializations if it was provided.
|
||||
|
||||
:param jobj: Dictionary containing this Registrations' data
|
||||
:type jobj: dict
|
||||
|
||||
:returns: Dictionary containing Registrations data to transmit to the server
|
||||
:rtype: dict
|
||||
"""
|
||||
if getattr(self, '_add_contact', False):
|
||||
jobj['contact'] = self.encode('contact')
|
||||
|
||||
return jobj
|
||||
|
||||
def to_partial_json(self):
|
||||
"""Modify josepy.JSONDeserializable.to_partial_json()"""
|
||||
jobj = super(Registration, self).to_partial_json()
|
||||
return self._add_contact_if_appropriate(jobj)
|
||||
|
||||
def fields_to_partial_json(self):
|
||||
"""Modify josepy.JSONObjectWithFields.fields_to_partial_json()"""
|
||||
jobj = super(Registration, self).fields_to_partial_json()
|
||||
return self._add_contact_if_appropriate(jobj)
|
||||
|
||||
@property
|
||||
def phones(self):
|
||||
"""All phones found in the ``contact`` field."""
|
||||
|
|
|
|||
|
|
@ -254,6 +254,19 @@ class RegistrationTest(unittest.TestCase):
|
|||
from acme.messages import Registration
|
||||
hash(Registration.from_json(self.jobj_from))
|
||||
|
||||
def test_default_not_transmitted(self):
|
||||
from acme.messages import NewRegistration
|
||||
empty_new_reg = NewRegistration()
|
||||
new_reg_with_contact = NewRegistration(contact=())
|
||||
|
||||
self.assertEqual(empty_new_reg.contact, ())
|
||||
self.assertEqual(new_reg_with_contact.contact, ())
|
||||
|
||||
self.assertTrue('contact' not in empty_new_reg.to_partial_json())
|
||||
self.assertTrue('contact' not in empty_new_reg.fields_to_partial_json())
|
||||
self.assertTrue('contact' in new_reg_with_contact.to_partial_json())
|
||||
self.assertTrue('contact' in new_reg_with_contact.fields_to_partial_json())
|
||||
|
||||
|
||||
class UpdateRegistrationTest(unittest.TestCase):
|
||||
"""Tests for acme.messages.UpdateRegistration."""
|
||||
|
|
|
|||
|
|
@ -1,16 +1,35 @@
|
|||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
set -e
|
||||
join() {
|
||||
sep=$1
|
||||
first=$2
|
||||
if [ "$first" != "" ]; then
|
||||
shift 2
|
||||
echo -n "${first}"
|
||||
for item in "$@"; do echo -n "${sep}${item}"; done
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
paths=$(for plugin_snap in $(snap connections certbot|sed -n '2,$p'|awk '$1=="content[certbot-1]"{print $3}'|cut -d: -f1); do echo /snap/$plugin_snap/current/lib/python3.8/site-packages; done)
|
||||
export CERTBOT_PLUGIN_PATH=$(join : $paths)
|
||||
# This code is based on snapcraft's own patch to work around this problem at
|
||||
# https://github.com/snapcore/snapcraft/blob/a97fb5c7ea553a1bd20f4887a7c3393e75761890/patches/ctypes_init.diff.
|
||||
# We may not build the Certbot snap for all of these architectures (and as of
|
||||
# writing this we do not), but we keep the code for them to avoid having to
|
||||
# solve this problem again in the future if we add support for new
|
||||
# architectures.
|
||||
case "${SNAP_ARCH}" in
|
||||
'arm64')
|
||||
ARCH_TRIPLET='aarch64-linux-gnu';;
|
||||
'armhf')
|
||||
ARCH_TRIPLET='arm-linux-gnueabihf';;
|
||||
'i386')
|
||||
ARCH_TRIPLET='i386-linux-gnu';;
|
||||
'ppc64el')
|
||||
ARCH_TRIPLET='powerpc64le-linux-gnu';;
|
||||
'powerpc')
|
||||
ARCH_TRIPLET='powerpc-linux-gnu';;
|
||||
'amd64')
|
||||
ARCH_TRIPLET='x86_64-linux-gnu';;
|
||||
's390x')
|
||||
ARCH_TRIPLET='s390x-linux-gnu';;
|
||||
*)
|
||||
echo "Unrecongized value of SNAP_ARCH: ${SNAP_ARCH}" >&2
|
||||
exit 1
|
||||
esac
|
||||
|
||||
export CERTBOT_AUGEAS_PATH="${SNAP}/usr/lib/${ARCH_TRIPLET}/libaugeas.so.0"
|
||||
|
||||
CERTBOT_PLUGIN_PATH="$(snap connections certbot | gawk 'BEGIN {ORS=""} NR>1 { if ($1 == "content[certbot-1]") { split($3,a,":"); PLUGINS=PLUGINS":/snap/"a[1]"/current/lib/python3.8/site-packages/"; next; } } END { print substr(PLUGINS, 2) }')"
|
||||
export CERTBOT_PLUGIN_PATH
|
||||
|
||||
exec certbot "$@"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
|
|||
|
||||
### Added
|
||||
|
||||
*
|
||||
* Added the ability to remove email and phone contact information from an account
|
||||
using `update_account --register-unsafely-without-email`
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
@ -14,7 +15,11 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
|
|||
|
||||
### Fixed
|
||||
|
||||
*
|
||||
* The problem causing the Apache plugin in the Certbot snap on ARM systems to
|
||||
fail to load the Augeas library it depends on has been fixed.
|
||||
* The `acme` library can now tell the ACME server to clear contact information by passing an empty
|
||||
`tuple` to the `contact` field of a `Registration` message.
|
||||
* Fixed the `*** stack smashing detected ***` error in the Certbot snap on some systems.
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
|
|
@ -36,7 +41,6 @@ More details about these changes can be found on our GitHub repo.
|
|||
|
||||
### Fixed
|
||||
|
||||
*
|
||||
|
||||
More details about these changes can be found on our GitHub repo.
|
||||
|
||||
|
|
|
|||
|
|
@ -171,13 +171,10 @@ def prepare_and_parse_args(plugins, args, detect_defaults=False):
|
|||
["register", "automation"], "--register-unsafely-without-email", action="store_true",
|
||||
default=flag_default("register_unsafely_without_email"),
|
||||
help="Specifying this flag enables registering an account with no "
|
||||
"email address. This is strongly discouraged, because in the "
|
||||
"event of key loss or account compromise you will irrevocably "
|
||||
"lose access to your account. You will also be unable to receive "
|
||||
"notice about impending expiration or revocation of your "
|
||||
"certificates. Updates to the Subscriber Agreement will still "
|
||||
"affect you, and will be effective 14 days after posting an "
|
||||
"update to the web site.")
|
||||
"email address. This is strongly discouraged, because you will be "
|
||||
"unable to receive notice about impending expiration or "
|
||||
"revocation of your certificates or problems with your Certbot "
|
||||
"installation that will lead to failure to renew.")
|
||||
helpful.add(
|
||||
["register", "update_account", "unregister", "automation"], "-m", "--email",
|
||||
default=flag_default("email"),
|
||||
|
|
|
|||
|
|
@ -319,6 +319,9 @@ def post_arg_parse_except_hook(exc_type, exc_value, trace, debug, log_path):
|
|||
# logger.DEBUG should be used
|
||||
if debug or not issubclass(exc_type, Exception):
|
||||
assert constants.QUIET_LOGGING_LEVEL <= logging.ERROR
|
||||
if exc_type is KeyboardInterrupt:
|
||||
logger.error('Exiting due to user request.')
|
||||
sys.exit(1)
|
||||
logger.error('Exiting abnormally:', exc_info=exc_info)
|
||||
else:
|
||||
logger.debug('Exiting abnormally:', exc_info=exc_info)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import josepy as jose
|
|||
import zope.component
|
||||
|
||||
from acme import errors as acme_errors
|
||||
from acme.magic_typing import Union
|
||||
from acme.magic_typing import Union, Iterable, Optional # pylint: disable=unused-import
|
||||
import certbot
|
||||
from certbot import crypto_util
|
||||
from certbot import errors
|
||||
|
|
@ -590,7 +590,7 @@ def _init_le_client(config, authenticator, installer):
|
|||
:type config: interfaces.IConfig
|
||||
|
||||
:param authenticator: Acme authentication handler
|
||||
:type authenticator: interfaces.IAuthenticator
|
||||
:type authenticator: Optional[interfaces.IAuthenticator]
|
||||
:param installer: Installer object
|
||||
:type installer: interfaces.IInstaller
|
||||
|
||||
|
|
@ -703,17 +703,17 @@ def update_account(config, unused_plugins):
|
|||
|
||||
if not accounts:
|
||||
return "Could not find an existing account to update."
|
||||
if config.email is None:
|
||||
if config.register_unsafely_without_email:
|
||||
return ("--register-unsafely-without-email provided, however, a "
|
||||
"new e-mail address must\ncurrently be provided when "
|
||||
"updating a registration.")
|
||||
if config.email is None and not config.register_unsafely_without_email:
|
||||
config.email = display_ops.get_email(optional=False)
|
||||
|
||||
acc, acme = _determine_account(config)
|
||||
cb_client = client.Client(config, acc, None, None, acme=acme)
|
||||
# Empty list of contacts in case the user is removing all emails
|
||||
|
||||
acc_contacts = () # type: Iterable[str]
|
||||
if config.email:
|
||||
acc_contacts = ['mailto:' + email for email in config.email.split(',')]
|
||||
# We rely on an exception to interrupt this process if it didn't work.
|
||||
acc_contacts = ['mailto:' + email for email in config.email.split(',')]
|
||||
prev_regr_uri = acc.regr.uri
|
||||
acc.regr = cb_client.acme.update_registration(acc.regr.update(
|
||||
body=acc.regr.body.update(contact=acc_contacts)))
|
||||
|
|
@ -722,8 +722,13 @@ def update_account(config, unused_plugins):
|
|||
# so that we can also continue to use the account object with acmev1.
|
||||
acc.regr = acc.regr.update(uri=prev_regr_uri)
|
||||
account_storage.update_regr(acc, cb_client.acme)
|
||||
eff.prepare_subscription(config, acc)
|
||||
add_msg("Your e-mail address was updated to {0}.".format(config.email))
|
||||
|
||||
if config.email is None:
|
||||
add_msg("Any contact information associated with this account has been removed.")
|
||||
else:
|
||||
eff.prepare_subscription(config, acc)
|
||||
add_msg("Your e-mail address was updated to {0}.".format(config.email))
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import zope.component
|
|||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot import util
|
||||
from certbot.compat import misc
|
||||
from certbot.compat import os
|
||||
from certbot.display import util as display_util
|
||||
|
||||
|
|
@ -33,9 +32,10 @@ def get_email(invalid=False, optional=True):
|
|||
msg = "Enter email address (used for urgent renewal and security notices)\n"
|
||||
unsafe_suggestion = ("\n\nIf you really want to skip this, you can run "
|
||||
"the client with --register-unsafely-without-email "
|
||||
"but make sure you then backup your account key from "
|
||||
"{0}\n\n".format(os.path.join(
|
||||
misc.get_default_folder('config'), 'accounts')))
|
||||
"but you will then be unable to receive notice about "
|
||||
"impending expiration or revocation of your "
|
||||
"certificates or problems with your Certbot "
|
||||
"installation that will lead to failure to renew.\n\n")
|
||||
if optional:
|
||||
if invalid:
|
||||
msg += unsafe_suggestion
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ class PostArgParseExceptHookTest(unittest.TestCase):
|
|||
self.log_path = 'foo.log'
|
||||
|
||||
def test_base_exception(self):
|
||||
exc_type = KeyboardInterrupt
|
||||
exc_type = BaseException
|
||||
mock_logger, output = self._test_common(exc_type, debug=False)
|
||||
self._assert_exception_logged(mock_logger.error, exc_type)
|
||||
self._assert_logfile_output(output)
|
||||
|
|
@ -342,6 +342,11 @@ class PostArgParseExceptHookTest(unittest.TestCase):
|
|||
self._assert_exception_logged(mock_logger.debug, exc_type)
|
||||
self._assert_quiet_output(mock_logger, output)
|
||||
|
||||
def test_keyboardinterrupt(self):
|
||||
exc_type = KeyboardInterrupt
|
||||
mock_logger, output = self._test_common(exc_type, debug=False)
|
||||
mock_logger.error.assert_called_once_with('Exiting due to user request.')
|
||||
|
||||
def _test_common(self, error_type, debug):
|
||||
"""Returns the mocked logger and stderr output."""
|
||||
mock_err = six.StringIO()
|
||||
|
|
|
|||
|
|
@ -1404,6 +1404,43 @@ class MainTest(test_util.ConfigTestCase):
|
|||
"user@example.org"])
|
||||
self.assertTrue("Could not find an existing account" in x[0])
|
||||
|
||||
@mock.patch('certbot._internal.main._determine_account')
|
||||
@mock.patch('certbot._internal.eff.prepare_subscription')
|
||||
@mock.patch('certbot._internal.main.account')
|
||||
def test_update_account_remove_email(self, mocked_account_module, mock_prepare, mock_det_acc):
|
||||
# Mock account storage and the account object returned
|
||||
mocked_storage = mock.MagicMock()
|
||||
mocked_account = mock.MagicMock()
|
||||
|
||||
mocked_account_module.AccountFileStorage.return_value = mocked_storage
|
||||
mocked_storage.find_all.return_value = [mocked_account]
|
||||
mock_det_acc.return_value = (mocked_account, "foo")
|
||||
|
||||
# Mock registration body to verify calls are made
|
||||
mock_regr_body = mock.MagicMock()
|
||||
|
||||
# mocked_account.regr is overwritten in update, requiring an odd mock setup
|
||||
mocked_account.regr.body = mock_regr_body
|
||||
|
||||
x = self._call(
|
||||
["update_account", "--register-unsafely-without-email"])
|
||||
|
||||
|
||||
# When update succeeds, the return value of update_account() is None
|
||||
self.assertTrue(x[0] is None)
|
||||
# and we got supposedly did update the registration from
|
||||
# the server
|
||||
client_mock = x[3]
|
||||
self.assertTrue(client_mock.Client().acme.update_registration.called)
|
||||
|
||||
self.assertTrue(mock_regr_body.update.called)
|
||||
self.assertTrue('contact' in mock_regr_body.update.call_args[1])
|
||||
self.assertEqual(mock_regr_body.update.call_args[1]['contact'], ())
|
||||
# and we saved the updated registration on disk
|
||||
self.assertTrue(mocked_storage.update_regr.called)
|
||||
# ensure we didn't try to subscribe (no email to subscribe with)
|
||||
self.assertFalse(mock_prepare.called)
|
||||
|
||||
@mock.patch('certbot._internal.main.display_ops.get_email')
|
||||
@test_util.patch_get_utility()
|
||||
def test_update_account_with_email(self, mock_utility, mock_email):
|
||||
|
|
|
|||
2
snap/hooks/configure
vendored
2
snap/hooks/configure
vendored
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/bash -e
|
||||
#!/bin/sh -e
|
||||
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash -e
|
||||
#!/bin/sh -e
|
||||
|
||||
if [ "$(snapctl get trust-plugin-with-root)" = "ok" ]; then
|
||||
# allow the connection, but reset config to allow for other slots to go through this auth flow
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ apps:
|
|||
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"
|
||||
LD_LIBRARY_PATH: "$SNAP/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH"
|
||||
CERTBOT_SNAPPED: "True"
|
||||
renew:
|
||||
command: certbot.wrapper -q renew
|
||||
|
|
@ -32,7 +31,6 @@ apps:
|
|||
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
|
||||
LD_LIBRARY_PATH: "$SNAP/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH"
|
||||
CERTBOT_SNAPPED: "True"
|
||||
# Run approximately twice a day with randomization
|
||||
timer: 00:00~24:00/2
|
||||
|
|
@ -44,7 +42,7 @@ parts:
|
|||
source: .
|
||||
constraints: [$SNAPCRAFT_PART_SRC/snap-constraints.txt]
|
||||
python-packages:
|
||||
- git+https://github.com/basak/python-augeas.git@snap
|
||||
- git+https://github.com/certbot/python-augeas.git@certbot-patched
|
||||
- ./acme
|
||||
- ./certbot
|
||||
- ./certbot-apache
|
||||
|
|
@ -54,7 +52,7 @@ parts:
|
|||
# Old versions of this file used to unstage
|
||||
# lib/python3.8/site-packages/augeas.py to avoid conflicts between
|
||||
# python-augeas 0.5.0 which was pinned in snap-constraints.txt and
|
||||
# Robie's python-augeas fork which creates an auto-generated cffi file at
|
||||
# our python-augeas fork which creates an auto-generated cffi file at
|
||||
# the same path. Since we've combined things in one part and removed the
|
||||
# python-augeas pinning, unstaging this file had a different, unintended
|
||||
# effect so we now stage the file to keep the auto-generated cffi file.
|
||||
|
|
@ -73,10 +71,13 @@ parts:
|
|||
- python3-distutils
|
||||
- python3-pkg-resources
|
||||
- python3.8-minimal
|
||||
# added for certbot.wrapper script:
|
||||
- gawk
|
||||
# To build cryptography and cffi if needed
|
||||
build-packages: [gcc, libffi-dev, libssl-dev, git, libaugeas-dev, python3-dev]
|
||||
build-environment:
|
||||
- SNAPCRAFT_PYTHON_VENV_ARGS: --system-site-packages
|
||||
- PIP_NO_BUILD_ISOLATION: "no"
|
||||
override-pull: |
|
||||
snapcraftctl pull
|
||||
cd $SNAPCRAFT_PART_SRC
|
||||
|
|
|
|||
|
|
@ -8,12 +8,6 @@ targets:
|
|||
type: ubuntu
|
||||
virt: hvm
|
||||
user: ubuntu
|
||||
- ami: ami-008680ee60f23c94b
|
||||
name: ubuntu20.04_arm64
|
||||
type: ubuntu
|
||||
virt: hvm
|
||||
user: ubuntu
|
||||
machine_type: a1.medium
|
||||
- ami: ami-0545f7036167eb3aa
|
||||
name: ubuntu19.10
|
||||
type: ubuntu
|
||||
|
|
@ -36,6 +30,12 @@ targets:
|
|||
type: ubuntu
|
||||
virt: hvm
|
||||
user: admin
|
||||
- ami: ami-0dcd54b7d2fff584f
|
||||
name: debian10_arm64
|
||||
type: ubuntu
|
||||
virt: hvm
|
||||
user: admin
|
||||
machine_type: a1.medium
|
||||
- ami: ami-003f19e0e687de1cd
|
||||
name: debian9
|
||||
type: ubuntu
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ then
|
|||
# For apache 2.4, set up ServerName
|
||||
sudo sed -i '/ServerName/ s/#ServerName/ServerName/' $CONFFILE
|
||||
sudo sed -i '/ServerName/ s/www.example.com/'$PUBLIC_HOSTNAME'/' $CONFFILE
|
||||
if [ $(python3 -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//') -ne 38 ]
|
||||
if [ $(python3 -V 2>&1 | cut -d" " -f 2 | cut -d. -f1,2 | sed 's/\.//') -lt 36 ]
|
||||
then
|
||||
# Upgrade python version using pyenv because py3.5 is deprecated
|
||||
# Don't upgrade if it's already 3.8 because pyenv doesn't work great on arm, and
|
||||
|
|
|
|||
|
|
@ -8,12 +8,6 @@ targets:
|
|||
type: ubuntu
|
||||
virt: hvm
|
||||
user: ubuntu
|
||||
- ami: ami-008680ee60f23c94b
|
||||
name: ubuntu20.04_arm64
|
||||
type: ubuntu
|
||||
virt: hvm
|
||||
user: ubuntu
|
||||
machine_type: a1.medium
|
||||
- ami: ami-0545f7036167eb3aa
|
||||
name: ubuntu19.10
|
||||
type: ubuntu
|
||||
|
|
@ -31,6 +25,12 @@ targets:
|
|||
type: ubuntu
|
||||
virt: hvm
|
||||
user: admin
|
||||
- ami: ami-0dcd54b7d2fff584f
|
||||
name: debian10_arm64
|
||||
type: ubuntu
|
||||
virt: hvm
|
||||
user: admin
|
||||
machine_type: a1.medium
|
||||
#-----------------------------------------------------------------------------
|
||||
# Other Redhat Distros
|
||||
- ami: ami-0916c408cb02e310b
|
||||
|
|
|
|||
Loading…
Reference in a new issue