├── awspub ├── tests │ ├── __init__.py │ ├── test_cli.py │ ├── fixtures │ │ ├── config2-mapping.yaml │ │ ├── config1.vmdk │ │ ├── config-minimal.yaml │ │ ├── config-invalid-s3-extra.yaml │ │ ├── config-valid-nonawspub.yaml │ │ ├── config3-duplicate-keys.yaml │ │ ├── config2.yaml │ │ └── config1.yaml │ ├── test_image_marketplace.py │ ├── test_common.py │ ├── test_api.py │ ├── test_s3.py │ ├── test_context.py │ ├── test_snapshot.py │ └── test_sns.py ├── __init__.py ├── exceptions.py ├── common.py ├── sns.py ├── context.py ├── cli │ └── __init__.py ├── image_marketplace.py ├── api.py ├── snapshot.py ├── configmodels.py └── s3.py ├── docs ├── config-samples │ ├── image.vmdk │ ├── config-minimal-sns.yaml.mapping │ ├── config-minimal-ssm.yaml.mapping │ ├── config-with-parameters.yaml.mapping │ ├── config-minimal.yaml │ ├── config-minimal-public.yaml │ ├── config-minimal-tags.yaml │ ├── config-with-parameters.yaml │ ├── config-multiple-images.yaml │ ├── config-minimal-image-tags.yaml │ ├── config-minimal-share.yaml │ ├── config-minimal-groups.yaml │ ├── config-minimal-ssm.yaml │ ├── config-minimal-sns.yaml │ └── config-minimal-marketplace.yaml ├── how_to │ ├── api.rst │ ├── index.rst │ ├── install.rst │ └── publish.rst ├── reference │ ├── logic.rst │ ├── index.rst │ ├── config_models.rst │ └── architecture.rst └── conf.py ├── _static ├── tag.png ├── favicon.png ├── header-nav.js ├── footer.js ├── github_issue_links.css ├── footer.css ├── github_issue_links.js ├── css │ └── cookie-banner.css ├── 404.svg ├── header.css ├── furo_colors.css └── custom.css ├── .sphinx ├── pa11y.json ├── spellingcheck.yaml ├── get_vale_conf.py └── build_requirements.py ├── .custom_wordlist.txt ├── .wokeignore ├── _templates ├── base.html ├── sidebar │ └── search.html ├── 404.html ├── page.html ├── header.html └── footer.html ├── requirements_parser.py ├── .gitignore ├── reuse └── links.txt ├── .github ├── workflows │ ├── automatic-doc-checks.yml │ ├── pr.yaml │ ├── sphinx-python-dependency-build-checks.yml │ └── publish-to-pypi.yaml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── SECURITY.md ├── readme.rst ├── renovate.json ├── .wordlist.txt ├── index.rst ├── .readthedocs.yaml ├── release-management.rst ├── make.bat ├── tox.ini ├── snap └── snapcraft.yaml ├── pyproject.toml ├── Makefile ├── Makefile.sp ├── conf.py └── custom_conf.py /awspub/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /awspub/tests/test_cli.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/config-samples/image.vmdk: -------------------------------------------------------------------------------- 1 | ../../awspub/tests/fixtures/config1.vmdk -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-sns.yaml.mapping: -------------------------------------------------------------------------------- 1 | --- 2 | serial: 20171022 -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-ssm.yaml.mapping: -------------------------------------------------------------------------------- 1 | --- 2 | version: "2.0.0" -------------------------------------------------------------------------------- /_static/tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canonical/awspub/main/_static/tag.png -------------------------------------------------------------------------------- /awspub/tests/fixtures/config2-mapping.yaml: -------------------------------------------------------------------------------- 1 | key1: "value1" 2 | key2: "value$2" 3 | -------------------------------------------------------------------------------- /docs/config-samples/config-with-parameters.yaml.mapping: -------------------------------------------------------------------------------- 1 | --- 2 | serial: 20171022 -------------------------------------------------------------------------------- /_static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canonical/awspub/main/_static/favicon.png -------------------------------------------------------------------------------- /awspub/tests/fixtures/config1.vmdk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canonical/awspub/main/awspub/tests/fixtures/config1.vmdk -------------------------------------------------------------------------------- /awspub/__init__.py: -------------------------------------------------------------------------------- 1 | from awspub.api import cleanup, create, list, publish 2 | 3 | __all__ = ["create", "list", "publish", "cleanup"] 4 | -------------------------------------------------------------------------------- /.sphinx/pa11y.json: -------------------------------------------------------------------------------- 1 | { 2 | "chromeLaunchConfig": { 3 | "args": [ 4 | "--no-sandbox" 5 | ] 6 | }, 7 | "reporter": "cli", 8 | "standard": "WCAG2AA" 9 | } -------------------------------------------------------------------------------- /.custom_wordlist.txt: -------------------------------------------------------------------------------- 1 | AMI 2 | AMIs 3 | ARN 4 | ConfigModel 5 | GPL 6 | SSM 7 | Snapcraft 8 | Snapstore 9 | YAML 10 | awspub 11 | awspub's 12 | config 13 | https 14 | io 15 | readthedocs 16 | vmdk 17 | SNS 18 | -------------------------------------------------------------------------------- /.wokeignore: -------------------------------------------------------------------------------- 1 | # the cheat sheets contain a link to a repository with a block word which we 2 | # cannot avoid for now, ie 3 | # https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html 4 | doc-cheat-sheet* 5 | -------------------------------------------------------------------------------- /docs/config-samples/config-minimal.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "x86_64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image": 9 | boot_mode: "uefi-preferred" 10 | -------------------------------------------------------------------------------- /awspub/tests/fixtures/config-minimal.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | awspub: 3 | source: 4 | path: "config1.vmdk" 5 | architecture: "x86_64" 6 | 7 | s3: 8 | bucket_name: "bucket1" 9 | 10 | images: 11 | "my-custom-image": 12 | boot_mode: "uefi-preferred" 13 | -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-public.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "x86_64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image": 9 | boot_mode: "uefi-preferred" 10 | public: true 11 | -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-tags.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "x86_64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image": 9 | boot_mode: "uefi-preferred" 10 | tags: 11 | tag-key: "tag-value" 12 | -------------------------------------------------------------------------------- /docs/config-samples/config-with-parameters.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "x86_64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image-$serial": 9 | boot_mode: "uefi-preferred" 10 | regions: 11 | - eu-central-1 12 | -------------------------------------------------------------------------------- /_static/header-nav.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $(document).on("click", function () { 3 | $(".more-links-dropdown").hide(); 4 | }); 5 | 6 | $('.nav-more-links').click(function(event) { 7 | $('.more-links-dropdown').toggle(); 8 | event.stopPropagation(); 9 | }); 10 | }) 11 | -------------------------------------------------------------------------------- /_templates/base.html: -------------------------------------------------------------------------------- 1 | {% extends "furo/base.html" %} 2 | 3 | {% block theme_scripts %} 4 | 7 | {% endblock theme_scripts %} 8 | 9 | {# ru-fu: don't include the color variables from the conf.py file, but use a 10 |  separate CSS file to save space #} 11 | {% block theme_styles %} 12 | {% endblock theme_styles %} 13 | -------------------------------------------------------------------------------- /_static/footer.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $(document).on("click", function () { 3 | $(".all-contributors").hide(); 4 | $("#overlay").hide(); 5 | }); 6 | 7 | $('.display-contributors').click(function(event) { 8 | $('.all-contributors').toggle(); 9 | $("#overlay").toggle(); 10 | event.stopPropagation(); 11 | }); 12 | }) 13 | -------------------------------------------------------------------------------- /awspub/tests/fixtures/config-invalid-s3-extra.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | s3: 3 | bucket_name: "bucket1" 4 | invalid_field: "not allowed" # This is an invalid field 5 | source: 6 | path: "config1.vmdk" 7 | architecture: "x86_64" 8 | images: 9 | test-image: 10 | description: "Test Image" 11 | separate_snapshot: "False" 12 | boot_mode: "uefi-preferred" 13 | -------------------------------------------------------------------------------- /docs/how_to/api.rst: -------------------------------------------------------------------------------- 1 | How to use the API 2 | ================== 3 | 4 | `awspub` provides a high-level API which can be used 5 | to create and publish images. 6 | 7 | Assuming there is a configuration file and a configuration file mapping: 8 | 9 | .. code-block:: 10 | 11 | import awspub 12 | awspub.create("config.yaml", "mapping.yaml") 13 | awspub.publish("config.yaml", "mapping.yaml") 14 | -------------------------------------------------------------------------------- /requirements_parser.py: -------------------------------------------------------------------------------- 1 | import tomllib 2 | 3 | LOCK = 'poetry.lock' 4 | 5 | 6 | def _get_requirements() -> list[str]: 7 | c = _read_config() 8 | 9 | deps = set() 10 | 11 | for dep in c["package"]: 12 | deps.add(dep['name']) 13 | 14 | return list(deps) 15 | 16 | 17 | def _read_config() -> dict: 18 | with open(LOCK, 'rb') as f: 19 | config = tomllib.load(f) 20 | return config 21 | -------------------------------------------------------------------------------- /awspub/tests/fixtures/config-valid-nonawspub.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | s3: 3 | bucket_name: "bucket1" 4 | source: 5 | path: "config1.vmdk" 6 | architecture: "x86_64" 7 | images: 8 | test-image: 9 | description: "Test Image" 10 | separate_snapshot: "False" 11 | boot_mode: "uefi-preferred" 12 | notawspub: # to make sure config outside of toplevel `awspub` dict is allowed 13 | foo_bar: "irrelevant" 14 | -------------------------------------------------------------------------------- /_templates/sidebar/search.html: -------------------------------------------------------------------------------- 1 |
7 | 8 | -------------------------------------------------------------------------------- /awspub/tests/fixtures/config3-duplicate-keys.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | s3: 3 | bucket_name: "bucket1" 4 | 5 | source: 6 | path: "config1.vmdk" 7 | architecture: "x86_64" 8 | 9 | images: 10 | "test-image-1": 11 | description: | 12 | A test image 13 | boot_mode: "uefi" 14 | # second image with the same key 15 | "test-image-1": 16 | description: | 17 | A test image 18 | boot_mode: "uefi" 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | *.egg-info/ 3 | .eggs/ 4 | *.pyc 5 | .tox 6 | *~ 7 | *.snap 8 | docs-build/ 9 | config.yaml 10 | .coverage 11 | 12 | # docs 13 | /*env*/ 14 | .sphinx/venv/ 15 | .sphinx/warnings.txt 16 | .sphinx/.wordlist.dic 17 | .sphinx/requirements.txt 18 | .sphinx/.doctrees/ 19 | .sphinx/node_modules/ 20 | package*.json 21 | _build 22 | .DS_Store 23 | __pycache__ 24 | .idea/ 25 | oci/_external/*.rst 26 | .vscode/ 27 | .sphinx/styles/* 28 | .sphinx/vale.ini 29 | -------------------------------------------------------------------------------- /reuse/links.txt: -------------------------------------------------------------------------------- 1 | .. _reStructuredText style guide: https://canonical-documentation-with-sphinx-and-readthedocscom.readthedocs-hosted.com/style-guide/ 2 | .. _Read the Docs at Canonical: https://library.canonical.com/documentation/read-the-docs 3 | .. _How to publish documentation on Read the Docs: https://library.canonical.com/documentation/publish-on-read-the-docs 4 | .. _Example product documentation: https://canonical-example-product-documentation.readthedocs-hosted.com/ 5 | -------------------------------------------------------------------------------- /.github/workflows/automatic-doc-checks.yml: -------------------------------------------------------------------------------- 1 | name: Main Documentation Checks 2 | 3 | on: 4 | - push 5 | - pull_request 6 | - workflow_dispatch 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | documentation-checks: 14 | uses: canonical/documentation-workflows/.github/workflows/documentation-checks.yaml@main 15 | with: 16 | working-directory: '.' 17 | python-version: '3.12' 18 | -------------------------------------------------------------------------------- /docs/config-samples/config-multiple-images.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | awspub: 3 | source: 4 | path: "image.vmdk" 5 | architecture: "x86_64" 6 | 7 | s3: 8 | bucket_name: "awspub-toabctl" 9 | 10 | images: 11 | "my-custom-image": 12 | boot_mode: "uefi-preferred" 13 | regions: 14 | - eu-central-1 15 | "my-custom-image-2": 16 | description: | 17 | Another image 18 | boot_mode: "uefi" 19 | regions: 20 | - eu-central-2 21 | -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-image-tags.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "x86_64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image-1": 9 | boot_mode: "uefi-preferred" 10 | tags: 11 | key1: "value1" 12 | "my-custom-image-2": 13 | boot_mode: "uefi" 14 | tags: 15 | key2: "value2" 16 | tag-key: "another-value" 17 | tags: 18 | tag-key: "tag-value" 19 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting a vulnerability 2 | To report a security issue, file a [Private Security Report](https://github.com/Canonical/awspub/security/advisories/new) 3 | with a description of the issue, the steps you took to create the issue, 4 | affected versions, and, if known, mitigations for the issue. 5 | The [Ubuntu Security disclosure and embargo policy](https://ubuntu.com/security/disclosure-policy) 6 | contains more information about what you can expect when you contact us and what we expect from you. 7 | -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-share.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "x86_64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image": 9 | boot_mode: "uefi-preferred" 10 | share: 11 | - "123456789123" 12 | - "aws-cn:456789012345" 13 | - "arn:aws:organizations::123456789012:organization/o-123example" 14 | - "arn:aws-cn:organizations::334455667788:ou/o-123example/ou-1234-5example" 15 | -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-groups.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "arm64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image-1": 9 | boot_mode: "uefi-preferred" 10 | groups: 11 | - "group1" 12 | regions: 13 | - us-west-1 14 | "my-custom-image-2": 15 | boot_mode: "uefi" 16 | groups: 17 | - "group2" 18 | regions: 19 | - us-east-1 20 | - ca-central-1 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. 16 | 2. 17 | 3. 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Additional context** 23 | Add any other context about the problem here. 24 | -------------------------------------------------------------------------------- /readme.rst: -------------------------------------------------------------------------------- 1 | awspub - image publication for AWS EC2 2 | -------------------------------------- 3 | 4 | `awspub` can publish images (AMIs) based on .VMDK files 5 | to AWS EC2. 6 | 7 | Documentation 8 | ============= 9 | 10 | The documentation can be found under https://canonical-awspub.readthedocs-hosted.com/ . 11 | 12 | Report issues 13 | ============= 14 | 15 | Please use https://github.com/canonical/awspub/issues to report problems or ask 16 | questions. 17 | 18 | License 19 | ======= 20 | 21 | The project uses `GPL-3.0` as license. 22 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "packageRules": [ 7 | { 8 | "groupName": "all non-major dependencies", 9 | "groupSlug": "all-minor-patch", 10 | "matchPackageNames": [ 11 | "*" 12 | ], 13 | "matchUpdateTypes": [ 14 | "minor", 15 | "patch" 16 | ], 17 | "matchCurrentVersion": "!/^0/", 18 | "automerge": true 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-ssm.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "x86_64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image": 9 | boot_mode: "uefi-preferred" 10 | ssm_parameter: 11 | - 12 | name: "/awspub-test/my-custom-image/$version" 13 | description: | 14 | Version $version of my-custom-image 15 | - 16 | name: "/awspub-test/my-custom-image/latest" 17 | allow_overwrite: true 18 | description: | 19 | always latest version of my-custom-image 20 | -------------------------------------------------------------------------------- /_static/github_issue_links.css: -------------------------------------------------------------------------------- 1 | .github-issue-link-container { 2 | padding-right: 0.5rem; 3 | } 4 | .github-issue-link { 5 | font-size: var(--font-size--small); 6 | font-weight: bold; 7 | background-color: #D6410D; 8 | padding: 13px 23px; 9 | text-decoration: none; 10 | } 11 | .github-issue-link:link { 12 | color: #FFFFFF; 13 | } 14 | .github-issue-link:visited { 15 | color: #FFFFFF 16 | } 17 | .muted-link.github-issue-link:hover { 18 | color: #FFFFFF; 19 | text-decoration: underline; 20 | } 21 | .github-issue-link:active { 22 | color: #FFFFFF; 23 | text-decoration: underline; 24 | } 25 | -------------------------------------------------------------------------------- /docs/reference/logic.rst: -------------------------------------------------------------------------------- 1 | Reference for the API 2 | ===================== 3 | 4 | If in doubt, use the high level API. This 5 | should work well for most of the use cases. 6 | 7 | High-level API 8 | ++++++++++++++ 9 | 10 | .. automodule:: awspub 11 | :members: 12 | 13 | 14 | Low-level API 15 | +++++++++++++ 16 | 17 | .. automodule:: awspub.context 18 | :members: 19 | 20 | .. automodule:: awspub.s3 21 | :members: 22 | 23 | .. automodule:: awspub.snapshot 24 | :members: 25 | 26 | .. automodule:: awspub.image 27 | :members: 28 | 29 | .. automodule:: awspub.image_marketplace 30 | :members: 31 | 32 | .. automodule:: awspub.sns 33 | :members: 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | 22 | -------------------------------------------------------------------------------- /docs/config-samples/config-minimal-sns.yaml: -------------------------------------------------------------------------------- 1 | awspub: 2 | source: 3 | path: "image.vmdk" 4 | architecture: "x86_64" 5 | s3: 6 | bucket_name: "awspub-toabctl" 7 | images: 8 | "my-custom-image": 9 | boot_mode: "uefi-preferred" 10 | sns: 11 | - "my-topic1": 12 | subject: "my-topic1-subject" 13 | message: 14 | default: "This is default message" 15 | email: "This is message for email protocols." 16 | - "my-topic2": 17 | subject: "my-topic2-subject" 18 | message: 19 | default: "This is message for email protocols. New image $serial is available" 20 | regions: 21 | - us-east-1 22 | -------------------------------------------------------------------------------- /_templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends "page.html" %} 2 | 3 | {% block content -%} 4 |Sorry, but the documentation page that you are looking for was not found.
\n\nDocumentation changes over time, and pages are moved around. We try to redirect you to the updated content where possible, but unfortunately, that didn\'t work this time (maybe because the content you were looking for does not exist in this version of the documentation).
\nYou can try to use the navigation to locate the content you\'re looking for, or search for a similar page.
\n', 86 | } 87 | 88 | # Default image for OGP (to prevent font errors, see 89 | # https://github.com/canonical/sphinx-docs-starter-pack/pull/54 ) 90 | if not 'ogp_image' in locals(): 91 | ogp_image = 'https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg' 92 | 93 | ############################################################ 94 | ### General configuration 95 | ############################################################ 96 | 97 | exclude_patterns = [ 98 | '_build', 99 | 'Thumbs.db', 100 | '.DS_Store', 101 | '.sphinx', 102 | '.tox' 103 | ] 104 | exclude_patterns.extend(custom_excludes) 105 | 106 | rst_epilog = ''' 107 | .. include:: /reuse/links.txt 108 | ''' 109 | if 'custom_rst_epilog' in locals(): 110 | rst_epilog = custom_rst_epilog 111 | 112 | source_suffix = { 113 | '.rst': 'restructuredtext', 114 | '.md': 'markdown', 115 | } 116 | 117 | if not 'conf_py_path' in html_context and 'github_folder' in html_context: 118 | html_context['conf_py_path'] = html_context['github_folder'] 119 | 120 | # For ignoring specific links 121 | linkcheck_anchors_ignore_for_url = [ 122 | r'https://github\.com/.*' 123 | ] 124 | linkcheck_anchors_ignore_for_url.extend(custom_linkcheck_anchors_ignore_for_url) 125 | 126 | # Tags cannot be added directly in custom_conf.py, so add them here 127 | for tag in custom_tags: 128 | tags.add(tag) 129 | 130 | # html_context['get_contribs'] is a function and cannot be 131 | # cached (see https://github.com/sphinx-doc/sphinx/issues/12300) 132 | suppress_warnings = ["config.cache"] 133 | 134 | ############################################################ 135 | ### Styling 136 | ############################################################ 137 | 138 | # Find the current builder 139 | builder = 'dirhtml' 140 | if '-b' in sys.argv: 141 | builder = sys.argv[sys.argv.index('-b')+1] 142 | 143 | # Setting templates_path for epub makes the build fail 144 | if builder == 'dirhtml' or builder == 'html': 145 | templates_path = ['_templates'] 146 | notfound_template = '404.html' 147 | 148 | # Theme configuration 149 | html_theme = 'furo' 150 | html_last_updated_fmt = '' 151 | html_permalinks_icon = '¶' 152 | 153 | if html_title == '': 154 | html_theme_options = { 155 | 'sidebar_hide_name': True 156 | } 157 | 158 | ############################################################ 159 | ### Additional files 160 | ############################################################ 161 | 162 | html_static_path = ['_static'] 163 | 164 | html_css_files = [ 165 | 'custom.css', 166 | 'header.css', 167 | 'github_issue_links.css', 168 | 'furo_colors.css', 169 | 'footer.css', 170 | 'css/cookie-banner.css', 171 | ] 172 | html_css_files.extend(custom_html_css_files) 173 | 174 | html_js_files = ['header-nav.js', 'footer.js', 'js/bundle.js'] 175 | if 'github_issues' in html_context and html_context['github_issues'] and not disable_feedback_button: 176 | html_js_files.append('github_issue_links.js') 177 | html_js_files.extend(custom_html_js_files) 178 | 179 | ############################################################# 180 | # Display the contributors 181 | 182 | def get_contributors_for_file(github_url, github_folder, pagename, page_source_suffix, display_contributors_since=None): 183 | filename = f"{pagename}{page_source_suffix}" 184 | paths=html_context['github_folder'][1:] + filename 185 | 186 | try: 187 | repo = Repo(".") 188 | except InvalidGitRepositoryError: 189 | cwd = os.getcwd() 190 | ghfolder = html_context['github_folder'][:-1] 191 | if ghfolder and cwd.endswith(ghfolder): 192 | repo = Repo(cwd.rpartition(ghfolder)[0]) 193 | else: 194 | print("The local Git repository could not be found.") 195 | return 196 | 197 | since = display_contributors_since if display_contributors_since and display_contributors_since.strip() else None 198 | 199 | commits = repo.iter_commits(paths=paths, since=since) 200 | 201 | contributors_dict = {} 202 | for commit in commits: 203 | contributor = commit.author.name 204 | if contributor not in contributors_dict or commit.committed_date > contributors_dict[contributor]['date']: 205 | contributors_dict[contributor] = { 206 | 'date': commit.committed_date, 207 | 'sha': commit.hexsha 208 | } 209 | # The github_page contains the link to the contributor's latest commit. 210 | contributors_list = [{'name': name, 'github_page': f"{github_url}/commit/{data['sha']}"} for name, data in contributors_dict.items()] 211 | sorted_contributors_list = sorted(contributors_list, key=lambda x: x['name']) 212 | return sorted_contributors_list 213 | 214 | html_context['get_contribs'] = get_contributors_for_file 215 | ############################################################# 216 | -------------------------------------------------------------------------------- /custom_conf.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | from requirements_parser import _get_requirements 3 | 4 | # Custom configuration for the Sphinx documentation builder. 5 | # All configuration specific to your project should be done in this file. 6 | # 7 | # The file is included in the common conf.py configuration file. 8 | # You can modify any of the settings below or add any configuration that 9 | # is not covered by the common conf.py file. 10 | # 11 | # For the full list of built-in configuration values, see the documentation: 12 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 13 | # 14 | # If you're not familiar with Sphinx and don't want to use advanced 15 | # features, it is sufficient to update the settings in the "Project 16 | # information" section. 17 | 18 | ############################################################ 19 | ### Project information 20 | ############################################################ 21 | 22 | # Product name 23 | project = 'awspub' 24 | author = 'Canonical Ltd.' 25 | 26 | # The title you want to display for the documentation in the sidebar. 27 | # You might want to include a version number here. 28 | # To not display any title, set this option to an empty string. 29 | html_title = project + ' documentation' 30 | 31 | # The default value uses CC-BY-SA as the license and the current year 32 | # as the copyright year. 33 | # 34 | # If your documentation needs a different copyright license, use that 35 | # instead of 'CC-BY-SA'. Also, if your documentation is included as 36 | # part of the code repository of your project, it'll inherit the license 37 | # of the code. So you'll need to specify that license here (instead of 38 | # 'CC-BY-SA'). 39 | # 40 | # For static works, it is common to provide the year of first publication. 41 | # Another option is to give the first year and the current year 42 | # for documentation that is often changed, e.g. 2022–2023 (note the en-dash). 43 | # 44 | # A way to check a GitHub repo's creation date is to obtain a classic GitHub 45 | # token with 'repo' permissions here: https://github.com/settings/tokens 46 | # Next, use 'curl' and 'jq' to extract the date from the GitHub API's output: 47 | # 48 | # curl -H 'Authorization: token