diff --git a/README.md b/README.md index 49ecb2b79..1d5aaf13a 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,20 @@ This creates a new archive, uploads it to S3 and updates the Lambda function to #### Docker Workflows -In [version 0.53.0](https://github.com/zappa/Zappa/blob/master/CHANGELOG.md), support was added to deploy & update Lambda functions using Docker. Refer to [the blog post](https://ianwhitestone.work/zappa-serverless-docker/) for more details about how to leverage this functionality, and when you may want to. +In [version 0.53.0](https://github.com/zappa/Zappa/blob/master/CHANGELOG.md), support was added to deploy & update Lambda functions using Docker. + +You can specify an ECR image using the `--docker-image-uri` option to the zappa command on `deploy` and `update`. +Zappa expects that the image is built and pushed to a Amazon ECR repository. + +Deploy Example: + + $ zappa deploy --docker-image-uri {AWS ACCOUNT ID}.dkr.ecr.{REGION}.amazonaws.com/{REPOSITORY NAME}:latest + +Update Example: + + $ zappa update --docker-image-uri {AWS ACCOUNT ID}.dkr.ecr.{REGION}.amazonaws.com/{REPOSITORY NAME}:latest + +Refer to [the blog post](https://ianwhitestone.work/zappa-serverless-docker/) for more details about how to leverage this functionality, and when you may want to. ### Rollback diff --git a/setup.py b/setup.py index af89dea10..88fd418c0 100755 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ version=__version__, packages=["zappa"], install_requires=required, - python_requires=">=3.7, <3.10", + python_requires=">=3.7", tests_require=test_required, test_suite="nose.collector", include_package_data=True, diff --git a/tests/tests.py b/tests/tests.py index 563e158f5..0fa347048 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -13,6 +13,7 @@ import unittest import uuid import zipfile +from functools import partial from io import BytesIO from subprocess import check_output @@ -40,7 +41,7 @@ ) from zappa.wsgi import common_log, create_wsgi_request -from .utils import get_unsupported_sys_versioninfo +from .utils import get_sys_versioninfo def random_string(length): @@ -2553,7 +2554,7 @@ def test_delete_lambda_concurrency(self, client): FunctionName="abc", ) - @mock.patch("sys.version_info", new_callable=get_unsupported_sys_versioninfo) + @mock.patch("sys.version_info", new_callable=get_sys_versioninfo) def test_unsupported_version_error(self, *_): from importlib import reload @@ -2562,6 +2563,28 @@ def test_unsupported_version_error(self, *_): reload(zappa) + @mock.patch("pathlib.Path.read_text", return_value="/docker/") + @mock.patch("sys.version_info", new_callable=partial(get_sys_versioninfo, 6)) + def test_minor_version_only_check_when_in_docker(self, *_): + from importlib import reload + + with self.assertRaises(RuntimeError): + import zappa + + reload(zappa) + + @mock.patch("pathlib.Path.read_text", return_value="/docker/") + @mock.patch("sys.version_info", new_callable=partial(get_sys_versioninfo, 7)) + def test_no_runtimeerror_when_in_docker(self, *_): + from importlib import reload + + try: + import zappa + + reload(zappa) + except RuntimeError: + self.fail() + def test_wsgi_query_string_unquoted(self): event = { "body": {}, diff --git a/tests/tests_docs.py b/tests/tests_docs.py index 7c45156ad..0473a465b 100644 --- a/tests/tests_docs.py +++ b/tests/tests_docs.py @@ -80,10 +80,11 @@ def test_readmetoc(self): ) if environ.get("ZAPPA_TEST_SAVE_README_NEW"): - with open(path.join(path.dirname(DIR), "README.test.md"), "w") as f: + readme_test_output_filepath = path.join(path.dirname(DIR), "README.test.md") + with open(readme_test_output_filepath, "w") as f: f.write(new_readme) - msg = "README.test.md written so you can manually compare." + msg = f"{readme_test_output_filepath} written so you can manually compare." else: msg = "You can set environ[ZAPPA_TEST_SAVE_README_NEW]=1 to generate\n" " README.test.md to manually compare." diff --git a/tests/utils.py b/tests/utils.py index 725947c84..fc2a09d71 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -80,7 +80,7 @@ def is_base64(test_string: str) -> bool: return False -def get_unsupported_sys_versioninfo() -> tuple: - """Mock used to test the python unsupported version testcase""" +def get_sys_versioninfo(minor_version: int = 6) -> tuple: + """Mock used to test the python version check testcases""" invalid_versioninfo = namedtuple("version_info", ["major", "minor", "micro", "releaselevel", "serial"]) - return invalid_versioninfo(3, 6, 1, "final", 0) + return invalid_versioninfo(3, minor_version, 1, "final", 0) diff --git a/zappa/__init__.py b/zappa/__init__.py index 0513a377f..6aa5f3f8b 100644 --- a/zappa/__init__.py +++ b/zappa/__init__.py @@ -1,12 +1,36 @@ import sys +from pathlib import Path + + +def running_in_docker() -> bool: + """ + Determine if zappa is running in docker. + - When docker is used allow usage of any python version + """ + # https://stackoverflow.com/a/20012536/24718 + cgroup_content = Path("/proc/1/cgroup").read_text() + in_docker = "/docker/" in cgroup_content or "/lxc/" in cgroup_content + return in_docker + SUPPORTED_VERSIONS = [(3, 7), (3, 8), (3, 9)] +MINIMUM_SUPPORTED_MINOR_VERSION = 7 -if sys.version_info[:2] not in SUPPORTED_VERSIONS: +if not running_in_docker() and sys.version_info[:2] not in SUPPORTED_VERSIONS: + print(running_in_docker()) formatted_supported_versions = ["{}.{}".format(*version) for version in SUPPORTED_VERSIONS] - err_msg = "This version of Python ({}.{}) is not supported!\n".format( - *sys.version_info - ) + "Zappa (and AWS Lambda) support the following versions of Python: {}".format(formatted_supported_versions) + err_msg = ( + f"This version of Python ({sys.version_info.major}.{sys.version_info.minor}) is not supported!\n" + f"Zappa (and AWS Lambda) support the following versions of Python: {formatted_supported_versions}" + ) raise RuntimeError(err_msg) +elif running_in_docker() and sys.version_info.minor < MINIMUM_SUPPORTED_MINOR_VERSION: + # when running in docker enforce minimum version only + err_msg = ( + f"This version of Python ({sys.version_info.major}.{sys.version_info.minor}) is not supported!\n" + f"Zappa requires a minimum version of 3.{MINIMUM_SUPPORTED_MINOR_VERSION}" + ) + raise RuntimeError(err_msg) + __version__ = "0.55.0"