From 580b21bd3840f2d764371f95d8d835179b83e60a Mon Sep 17 00:00:00 2001 From: Peyton Robertson <93797227+peytonr18@users.noreply.github.com> Date: Mon, 2 Feb 2026 20:27:54 -0800 Subject: [PATCH 1/9] fix(azure): round duration field in FinishReportingEvent to four decimal places (#6709) --- cloudinit/reporting/events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudinit/reporting/events.py b/cloudinit/reporting/events.py index 94ab95b7378..fd2d7dceaff 100644 --- a/cloudinit/reporting/events.py +++ b/cloudinit/reporting/events.py @@ -107,7 +107,7 @@ def as_dict(self): """The event represented as json friendly.""" data = super(FinishReportingEvent, self).as_dict() data["result"] = self.result - data["duration"] = self.duration + data["duration"] = round(self.duration, 4) if self.post_files: data["files"] = _collect_file_info(self.post_files) return data From afd0c6c5ebf5bba0385a9c76a1362d55aad022f9 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Tue, 3 Feb 2026 09:22:06 -0700 Subject: [PATCH 2/9] chore: pin full SHA commits for all workflows (#6711) cloud-init project now requires full SHA commits instead of tags for all workflows to utilize a more secure policy for CI runners. Any Github actions lacking full SHA pins in workflows/actions will error due to repo prevention policy. Additionally update SHA pins to latest known workflow releases. --- .github/workflows/_integration_common.yml | 2 +- .github/workflows/ci-check-format.yml | 12 ++++++------ .github/workflows/ci-integration.yml | 6 +++--- .github/workflows/ci-unit-distro.yml | 4 ++-- .github/workflows/ci-unit-python.yml | 4 ++-- .github/workflows/daily-linkcheck.yml | 4 ++-- .github/workflows/daily-unit-lint.yml | 12 ++++++------ .github/workflows/gh-cla.yml | 2 +- .github/workflows/gh-label.yml | 2 +- .github/workflows/gh-stale.yml | 2 +- .github/workflows/packaging-downstream.yml | 2 +- .github/workflows/packaging-lint.yml | 2 +- .github/workflows/packaging-upstream.yml | 2 +- .github/workflows/weekly-tics.yml | 2 +- 14 files changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/workflows/_integration_common.yml b/.github/workflows/_integration_common.yml index e77c36de887..4f2ce595c7d 100644 --- a/.github/workflows/_integration_common.yml +++ b/.github/workflows/_integration_common.yml @@ -61,7 +61,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup LXD uses: canonical/setup-lxd@8c6a87bfb56aa48f3fb9b830baa18562d8bfd4ee # v0.1.2 with: diff --git a/.github/workflows/ci-check-format.yml b/.github/workflows/ci-check-format.yml index c74acfe174c..416dc9454e7 100644 --- a/.github/workflows/ci-check-format.yml +++ b/.github/workflows/ci-check-format.yml @@ -24,7 +24,7 @@ jobs: FORCE_COLOR: 1 steps: - name: Checkout - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Dependencies run: | @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Test format run: | @@ -61,9 +61,9 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install RTD Python Version - uses: actions/setup-python@v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.11.9' - name: Install dependencies @@ -86,7 +86,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install ShellCheck run: | @@ -101,7 +101,7 @@ jobs: name: GitHub Action and Workflow Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: reviewdog/action-actionlint@83e4ed25b168066ad8f62f5afbb29ebd8641d982 # v1.69.1 with: fail_level: any diff --git a/.github/workflows/ci-integration.yml b/.github/workflows/ci-integration.yml index ea4401c4b41..0f07aa1c791 100644 --- a/.github/workflows/ci-integration.yml +++ b/.github/workflows/ci-integration.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Prepare dependencies run: | sudo DEBIAN_FRONTEND=noninteractive apt-get update @@ -45,13 +45,13 @@ jobs: DEB_BUILD_OPTIONS=nocheck ./packages/bddeb -d --release ${{ env.RELEASE }} cp cloud-init_all.deb ${{ runner.temp }} - name: Archive debs as artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: 'cloud-init-${{ env.RELEASE }}-deb' path: '${{ runner.temp }}/cloud-init*.deb' retention-days: 3 - name: Setup LXD - uses: canonical/setup-lxd@v0.1.2 + uses: canonical/setup-lxd@8c6a87bfb56aa48f3fb9b830baa18562d8bfd4ee # v1 with: channel: 6/stable - name: Verify deb package diff --git a/.github/workflows/ci-unit-distro.yml b/.github/workflows/ci-unit-distro.yml index bc02d97f7e9..b996cf394fe 100644 --- a/.github/workflows/ci-unit-distro.yml +++ b/.github/workflows/ci-unit-distro.yml @@ -22,10 +22,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up LXD - uses: canonical/setup-lxd@v0.1.2 + uses: canonical/setup-lxd@8c6a87bfb56aa48f3fb9b830baa18562d8bfd4ee # v1 - name: Create alpine container # the current shell doesn't have lxd as one of the groups diff --git a/.github/workflows/ci-unit-python.yml b/.github/workflows/ci-unit-python.yml index dd08d549147..cd2da58d8d0 100644 --- a/.github/workflows/ci-unit-python.yml +++ b/.github/workflows/ci-unit-python.yml @@ -32,9 +32,9 @@ jobs: continue-on-error: ${{ matrix.experimental }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Python ${{matrix.python-version}} - uses: actions/setup-python@v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{matrix.python-version}} check-latest: ${{matrix.check-latest}} diff --git a/.github/workflows/daily-linkcheck.yml b/.github/workflows/daily-linkcheck.yml index 1113a58cfb0..11114b19d24 100644 --- a/.github/workflows/daily-linkcheck.yml +++ b/.github/workflows/daily-linkcheck.yml @@ -12,10 +12,10 @@ jobs: continue-on-error: ${{ !(github.event_name == 'workflow_dispatch' && github.event.inputs.failOnError == 'true') }} steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: "Install Python 3.10" - uses: actions/setup-python@v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.10.8' diff --git a/.github/workflows/daily-unit-lint.yml b/.github/workflows/daily-unit-lint.yml index cee12694a1a..bfe997e38db 100644 --- a/.github/workflows/daily-unit-lint.yml +++ b/.github/workflows/daily-unit-lint.yml @@ -13,7 +13,7 @@ jobs: FORCE_COLOR: 1 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install dependencies env: DEBIAN_FRONTEND: noninteractive @@ -30,9 +30,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Latest Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: # select latest version here: # https://github.com/actions/python-versions/blob/main/versions-manifest.json @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install dependencies run: | sudo apt-get -qy update @@ -76,9 +76,9 @@ jobs: continue-on-error: ${{ matrix.experimental }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Python ${{matrix.python-version}} - uses: actions/setup-python@v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{matrix.python-version}} check-latest: ${{matrix.check-latest}} diff --git a/.github/workflows/gh-cla.yml b/.github/workflows/gh-cla.yml index a0832cbf2e6..060a38f7fb4 100644 --- a/.github/workflows/gh-cla.yml +++ b/.github/workflows/gh-cla.yml @@ -10,4 +10,4 @@ jobs: runs-on: ubuntu-latest steps: - name: Check if CLA signed - uses: canonical/has-signed-canonical-cla@v2 + uses: canonical/has-signed-canonical-cla@19bae73390fdbfdc1ef9a9bb9408d87a1de755f6 # v2 diff --git a/.github/workflows/gh-label.yml b/.github/workflows/gh-label.yml index 33be8c9eee4..1356aea4fce 100644 --- a/.github/workflows/gh-label.yml +++ b/.github/workflows/gh-label.yml @@ -6,4 +6,4 @@ jobs: labeler: runs-on: ubuntu-latest steps: - - uses: actions/labeler@v5 + - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 diff --git a/.github/workflows/gh-stale.yml b/.github/workflows/gh-stale.yml index 4f3b5d994fd..ef8b8388474 100644 --- a/.github/workflows/gh-stale.yml +++ b/.github/workflows/gh-stale.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v9 + - uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-issue-stale: -1 diff --git a/.github/workflows/packaging-downstream.yml b/.github/workflows/packaging-downstream.yml index 7b925b989f2..0e9daf2a29e 100644 --- a/.github/workflows/packaging-downstream.yml +++ b/.github/workflows/packaging-downstream.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout branch - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install dependencies run: | diff --git a/.github/workflows/packaging-lint.yml b/.github/workflows/packaging-lint.yml index 5926b4db73b..111fd332791 100644 --- a/.github/workflows/packaging-lint.yml +++ b/.github/workflows/packaging-lint.yml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Repository checkout - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Get all matching changed files id: matching-changed-files diff --git a/.github/workflows/packaging-upstream.yml b/.github/workflows/packaging-upstream.yml index a4aab2356f7..574c6872f5c 100644 --- a/.github/workflows/packaging-upstream.yml +++ b/.github/workflows/packaging-upstream.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Setup - checkout branches - uses: actions/checkout@v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # Fetch all history for merging fetch-depth: 0 diff --git a/.github/workflows/weekly-tics.yml b/.github/workflows/weekly-tics.yml index b5f505880a7..52deec952ac 100644 --- a/.github/workflows/weekly-tics.yml +++ b/.github/workflows/weekly-tics.yml @@ -16,7 +16,7 @@ jobs: runs-on: [self-hosted, linux, amd64, tiobe, noble] steps: - name: Checkout the project - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 From 72809f8046f7abb5157e864a903cc5cc3c70ecbb Mon Sep 17 00:00:00 2001 From: drzee99 Date: Thu, 5 Feb 2026 17:00:53 +0100 Subject: [PATCH 3/9] fix: DNS resolution performance regression during local stage (#6707) Fixes DNS queries for IP addresses that cause 2+ minute boot delays with systemd 259+. Moves IP detection earlier in is_resolvable() and removes legacy DNS-dependent metadata URL. Fixes GH-6641 --- cloudinit/sources/DataSourceEc2.py | 1 - cloudinit/util.py | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py index e210e7d61e5..0c56c086d98 100644 --- a/cloudinit/sources/DataSourceEc2.py +++ b/cloudinit/sources/DataSourceEc2.py @@ -77,7 +77,6 @@ class DataSourceEc2(sources.DataSource): metadata_urls = [ "http://169.254.169.254", "http://[fd00:ec2::254]", - "http://instance-data.:8773", ] # The minimum supported metadata_version from the ec2 metadata apis diff --git a/cloudinit/util.py b/cloudinit/util.py index 93c62ad58f4..cac5926f10f 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -1295,6 +1295,12 @@ def is_resolvable(url) -> bool: global _DNS_REDIRECT_IP parsed_url = parse.urlparse(url) name = parsed_url.hostname + + # Early return for IP addresses - no DNS resolution needed + with suppress(ValueError): + if net.is_ip_address(parsed_url.netloc.strip("[]")): + return True + if _DNS_REDIRECT_IP is None: badips = set() badnames = ( @@ -1319,10 +1325,6 @@ def is_resolvable(url) -> bool: LOG.debug("detected dns redirection: %s", badresults) try: - # ip addresses need no resolution - with suppress(ValueError): - if net.is_ip_address(parsed_url.netloc.strip("[]")): - return True result = socket.getaddrinfo(name, None) # check first result's sockaddr field addr = result[0][4][0] From 961fc8490d67fa3ee5a268ffdc5c60261c8e3fb2 Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Thu, 5 Feb 2026 14:14:32 -0700 Subject: [PATCH 4/9] doc: make doc hierarchy more focused (#6694) Various pages in the table of contents documented things that are not useful without some other context. Remove these from the table of contents and link to them from pages that have that context. Introduce new "advanced" pages under the reference and explanation categories to link to pages which are not suitable for the average user. Other pages contained implementation details. Remove the implementation details or move the page to be under the new "advanced" pages. Introduce a new "project status" page to gather project-related info. Delete content and pages containing duplicate information. Don't make security policy recommendations to users. Remove page documenting the performance analysis subcommand, since there are more accurate ways of analyzing performance. File deletions -------------- about-cloud-config.rst performance_analysis.rst File renames ------------ faq.rst -> from reference to explanation user_files.rst -> from reference to explanation module_run_frequency -> from how-to to reference test_unreleased_packages -> from howto to reference foramt.rst -> format/index.rst (and sub-pages) --- doc/man/cloud-id.1 | 5 - doc/rtd/development/internal_files.rst | 19 +- doc/rtd/explanation/about-cloud-config.rst | 141 ------ doc/rtd/explanation/advanced_explanation.rst | 16 + doc/rtd/explanation/analyze.rst | 3 + .../explanation/configuration-priority.rst | 70 +++ doc/rtd/explanation/configuration.rst | 92 +--- doc/rtd/explanation/exported_errors.rst | 2 + doc/rtd/explanation/failure_states.rst | 4 +- doc/rtd/{reference => explanation}/faq.rst | 0 doc/rtd/explanation/format.rst | 405 ------------------ doc/rtd/explanation/format/boothook.rst | 46 ++ .../format/cloud-config-archive.rst | 46 ++ doc/rtd/explanation/format/cloud-config.rst | 38 ++ doc/rtd/explanation/format/gzip.rst | 15 + doc/rtd/explanation/format/include.rst | 20 + doc/rtd/explanation/format/index.rst | 47 ++ doc/rtd/explanation/format/jinja.rst | 42 ++ doc/rtd/explanation/format/mime.rst | 80 ++++ .../explanation/format/user-data-script.rst | 25 ++ doc/rtd/explanation/index.rst | 29 +- doc/rtd/explanation/instancedata.rst | 63 +-- doc/rtd/explanation/kernel-command-line.rst | 2 + doc/rtd/explanation/part_handlers.rst | 30 ++ doc/rtd/explanation/project-status.rst | 11 + doc/rtd/explanation/return_codes.rst | 2 + doc/rtd/explanation/vendordata.rst | 2 + doc/rtd/howto/index.rst | 13 +- doc/rtd/howto/launch_multipass.rst | 5 +- doc/rtd/reference/advanced_reference.rst | 20 + doc/rtd/reference/base_config_reference.rst | 9 +- doc/rtd/reference/cli.rst | 144 +------ doc/rtd/reference/cloud-config.rst | 8 + doc/rtd/reference/config-format-headers.rst | 35 ++ doc/rtd/reference/datasource_dsname_map.rst | 2 + doc/rtd/reference/datasources.rst | 21 +- doc/rtd/reference/datasources/vmware.rst | 34 +- doc/rtd/reference/examples.rst | 5 +- doc/rtd/reference/examples_library.rst | 9 +- doc/rtd/reference/index.rst | 27 +- doc/rtd/reference/merging.rst | 6 +- .../module_run_frequency.rst | 0 doc/rtd/reference/network-config.rst | 8 +- doc/rtd/reference/performance_analysis.rst | 110 ----- .../test_unreleased_packages.rst | 0 doc/rtd/reference/user_files.rst | 73 +--- 46 files changed, 676 insertions(+), 1108 deletions(-) delete mode 100644 doc/rtd/explanation/about-cloud-config.rst create mode 100644 doc/rtd/explanation/advanced_explanation.rst create mode 100644 doc/rtd/explanation/configuration-priority.rst rename doc/rtd/{reference => explanation}/faq.rst (100%) delete mode 100644 doc/rtd/explanation/format.rst create mode 100644 doc/rtd/explanation/format/boothook.rst create mode 100644 doc/rtd/explanation/format/cloud-config-archive.rst create mode 100644 doc/rtd/explanation/format/cloud-config.rst create mode 100644 doc/rtd/explanation/format/gzip.rst create mode 100644 doc/rtd/explanation/format/include.rst create mode 100644 doc/rtd/explanation/format/index.rst create mode 100644 doc/rtd/explanation/format/jinja.rst create mode 100644 doc/rtd/explanation/format/mime.rst create mode 100644 doc/rtd/explanation/format/user-data-script.rst create mode 100644 doc/rtd/explanation/part_handlers.rst create mode 100644 doc/rtd/explanation/project-status.rst create mode 100644 doc/rtd/reference/advanced_reference.rst create mode 100644 doc/rtd/reference/cloud-config.rst create mode 100644 doc/rtd/reference/config-format-headers.rst rename doc/rtd/{howto => reference}/module_run_frequency.rst (100%) delete mode 100644 doc/rtd/reference/performance_analysis.rst rename doc/rtd/{howto => reference}/test_unreleased_packages.rst (100%) diff --git a/doc/man/cloud-id.1 b/doc/man/cloud-id.1 index 6ae9597b5d3..211c0bf7104 100644 --- a/doc/man/cloud-id.1 +++ b/doc/man/cloud-id.1 @@ -28,11 +28,6 @@ Report all standardized cloud-id information as json .B "-l, --long" Report extended cloud-id information as tab-delimited string -.TP -.BR "-i , --instance-data " -Path to instance-data.json file. Default is -/run/cloud-init/instance-data.json - .SH EXIT STATUS .TP 0 diff --git a/doc/rtd/development/internal_files.rst b/doc/rtd/development/internal_files.rst index 27e72360c74..94daac0ee31 100644 --- a/doc/rtd/development/internal_files.rst +++ b/doc/rtd/development/internal_files.rst @@ -9,8 +9,8 @@ unexpected cloud-init failures. .. _data_files: -Data files -========== +/var/ +===== Inside the :file:`/var/lib/cloud/` directory there are two important subdirectories: @@ -44,3 +44,18 @@ previous boot: * :file:`status.json`: JSON file showing the datasource used, a breakdown of all four stages, whether any errors occurred, and the start and stop times of the stages. + + +/run/ +===== + +Cloud-init uses :file:`/run/cloud-init/` for the following files: + +* :file:`/run/cloud-init/instance-data.json`: world-readable JSON containing + standardized keys, sensitive keys redacted. +* :file:`/run/cloud-init/instance-data-sensitive.json`: root-readable + unredacted JSON blob. +* :file:`/run/cloud-init/combined-cloud-config.json`: root-readable + unredacted JSON blob. Any meta-data, vendor-data and user-data overrides + are applied to the :file:`/run/cloud-init/combined-cloud-config.json` config + values. diff --git a/doc/rtd/explanation/about-cloud-config.rst b/doc/rtd/explanation/about-cloud-config.rst deleted file mode 100644 index 23cdfc03207..00000000000 --- a/doc/rtd/explanation/about-cloud-config.rst +++ /dev/null @@ -1,141 +0,0 @@ -.. _about-cloud-config: - -About the cloud-config file -*************************** - -The ``#cloud-config`` file is a type of user-data that cloud-init can consume -to automatically set up various aspects of the system. It is commonly referred -to as **cloud config**. Using cloud config to configure your machine leverages -the best practices encoded into cloud-init's modules in a distribution-agnostic -way. - -Note that networks are not configurable via the ``#cloud-config`` file because -:ref:`network configuration ` comes from the cloud. - -How do I create a cloud-config file? -==================================== - -The cloud-config file uses `YAML version 1.1`_. The file is composed of a -**header** and one or more **modules**. - -* **The header**: - The first line **must start** with ``#cloud-config``. This line identifies - the file to cloud-init and ensures that it will be processed as intended. - -* **The modules**: - After the header, every aspect of the system's configuration is controlled - through specific cloud-init modules. - -Most modules are specified through the use of one or more **top-level keys**, -and the configuration options are set using YAML key-value pairs or list types, -according to the config schema. It follows this general format: - -.. code-block:: yaml - - #cloud-config - top-level-key: - config-key-1: config-value-1 - config-key-2: config-value-2 - list-type: - - list-value-1 - additional-list-value-1 - - list-value-2 - -The order of the top-level keys is unimportant -- they can be written in any -order, and cloud-init handles the order of operations. - -Let us consider a real example using the :ref:`Keyboard ` -module. The top-level key for this module is ``keyboard:``, and beneath that -are the various configuration options for the module shown as key-value pairs: - -.. code-block:: yaml - - #cloud-config - keyboard: - layout: us - model: pc105 - variant: nodeadkeys - options: compose:rwin - -Not all modules require a top-level key, and will run on the system anyway if -certain conditions are met. A full list of modules can be found -:ref:`on our modules page `. This list also shows the valid schema for -every module, and simple YAML examples. - -Checking your cloud-config file -=============================== - -Once you have constructed your cloud-config file, you can check it against -the :ref:`cloud-config validation tool `. This -tool tests the YAML in your file against the cloud-init schema and will warn -you of any errors. - -Example cloud-config file -========================= - -The following code is an example of a complete user-data cloud-config file. -The :ref:`cloud-config example library ` contains further -examples that can be copy/pasted and adapted to your needs. - -.. code-block:: yaml - - #cloud-config - - # Basic system setup - hostname: example-host - fqdn: example-host.example.com - - # User setup configuration - users: - - name: exampleuser - gecos: Example User - sudo: ['ALL=(ALL) NOPASSWD:ALL'] - groups: sudo - homedir: /home/exampleuser - shell: /bin/bash - ssh_authorized_keys: - - ssh-rsa AAAAB3...restofpublickey user@host - - # Change passwords for exampleuser using chpasswd - chpasswd: - expire: false - users: - - {name: exampleuser, password: terriblepassword12345, type: text} - - # Package management - package_update: true - package_upgrade: true - packages: - - git - - nginx - - python3 - - # Commands to run at the end of the cloud-init process - runcmd: - - echo "Hello, world!" > /etc/motd - - systemctl restart nginx - - mkdir -p /var/www/html - - echo "

Welcome to the party, pal!

" > /var/www/html/index.html - - # Write files to the instance - write_files: - - path: /etc/example_config.conf - content: | - [example-config] - key=value - - path: /etc/motd - content: | - Some text that will appear in your MOTD! - - # Final message, shown after cloud-init completes - final_message: "The system is up, after $UPTIME seconds" - - # Reboot the instance after configuration - power_state: - mode: reboot - message: Rebooting after initial setup - timeout: 30 - condition: True - -.. LINKS -.. _YAML version 1.1: https://yaml.org/spec/1.1/current.html diff --git a/doc/rtd/explanation/advanced_explanation.rst b/doc/rtd/explanation/advanced_explanation.rst new file mode 100644 index 00000000000..a698187833f --- /dev/null +++ b/doc/rtd/explanation/advanced_explanation.rst @@ -0,0 +1,16 @@ +Advanced explanation +******************** + +The following guides are not suitable for most users because they document +implementation details which are subject to change. + +----- + +.. toctree:: + :maxdepth: 1 + + Boot and reboot behavior + Events + Serial network output + Debug ds-identify <../howto/identify_datasource.rst> + Custom part handlers diff --git a/doc/rtd/explanation/analyze.rst b/doc/rtd/explanation/analyze.rst index 3257a530fd0..e0c99b9ecda 100644 --- a/doc/rtd/explanation/analyze.rst +++ b/doc/rtd/explanation/analyze.rst @@ -1,5 +1,8 @@ +:orphan: + .. _analyze: + Performance *********** diff --git a/doc/rtd/explanation/configuration-priority.rst b/doc/rtd/explanation/configuration-priority.rst new file mode 100644 index 00000000000..3acc97a5b55 --- /dev/null +++ b/doc/rtd/explanation/configuration-priority.rst @@ -0,0 +1,70 @@ +.. _configuration: + +Configuration priority +********************** + +Configuration settings are prioritized by their source. Settings from a higher +priority source override settings from lower priority sources. In decreasing +priority: + +1. Runtime configuration +2. Image configuration +3. Builtin defaults + +.. _runtime_config: + +Runtime configuration +--------------------- + +Runtime configuration is fetched from the datasource and is defined at instance +launch. Runtime settings use the :ref:`user-data format.`. + +User-provided configurations override settings provided by the platform (called +:ref:`vendor-data`). + +Every platform supporting ``cloud-init`` should provide a method for supplying +user-data. See your cloud provider's documentation for details. The +:ref:`datasource page` for your cloud might have clues for how to +define user-data. + +Once an instance has been initialized, the user-data may not be edited. +It is sourced directly from the cloud, so even if you find a local file +that contains user-data, it will likely be overwritten in the next boot. + + +Image configuration +------------------- + +Image configurations are built into an image before it boots. Image +configurations can define :ref:`user-data` +settings, as well as other :ref:`base configuration` +settings. + +From highest priority to lowest, image configuration sources are: + +- **Runtime config**: Machine-generated :file:`/run/cloud-init/cloud.cfg`. Do + not write to this file. +- **Configuration directory**: Anything defined in :file:`/etc/cloud/cloud.cfg` + and :file:`/etc/cloud/cloud.cfg.d/*.cfg`. +- **Hardcoded config** Config_ that lives within the source of ``cloud-init`` + and cannot be changed. + +.. _upstream-config: + +Builtin defaults +---------------- + +Some settings are part of the source code and may be overridden. + +.. _network: + +Network configuration +===================== + +Cloud-init brings up the network without any configuration required. See +:ref:`network configuration documentation` for more +information. + +.. _Config: https://github.com/canonical/cloud-init/blob/b861ea8a5e1fd0eb33096f60f54eeff42d80d3bd/cloudinit/settings.py#L22 +.. _cloud.cfg template: https://github.com/canonical/cloud-init/blob/main/config/cloud.cfg.tmpl +.. _YAML version 1.1: https://yaml.org/spec/1.1/current.html diff --git a/doc/rtd/explanation/configuration.rst b/doc/rtd/explanation/configuration.rst index 5eb0be1daa2..f4132714dda 100644 --- a/doc/rtd/explanation/configuration.rst +++ b/doc/rtd/explanation/configuration.rst @@ -1,88 +1,8 @@ -.. _configuration: +Configuration +************* -Configuration sources -********************* +.. toctree:: + :maxdepth: 1 -Internally, ``cloud-init`` builds a single configuration that is then -referenced throughout the life of ``cloud-init``. The configuration is built -from multiple sources such that if a key is defined in multiple sources, the -higher priority source overwrites the lower priority source. - -Base configuration -================== - -The base configuration format uses `YAML version 1.1`_, but may be -declared as jinja templates which cloud-init will render at runtime with -:ref:`instance-data ` variables. - -From lowest priority to highest, configuration sources are: - -- **Hardcoded config** Config_ that lives within the source of ``cloud-init`` - and cannot be changed. -- **Configuration directory**: Anything defined in :file:`/etc/cloud/cloud.cfg` - and :file:`/etc/cloud/cloud.cfg.d/*.cfg`. -- **Runtime config**: Anything defined in :file:`/run/cloud-init/cloud.cfg`. -- **Kernel command line**: On the kernel command line, anything found between - ``cc:`` and ``end_cc`` will be interpreted as cloud-config user-data. - -These four sources make up the base configuration. The contents of this -configuration are defined in the -:ref:`base configuration reference page`. - -.. note:: - Base configuration may contain - :ref:`cloud-config` which may be - overridden by vendor-data and user-data. - -Vendor-data and user-data -========================= - -Added to the base configuration are :ref:`vendor-data` and -:ref:`user-data` which are both provided by the datasource. - -These get fetched from the datasource and are defined at instance launch. - -Network configuration -===================== - -Network configuration happens independently from other ``cloud-init`` -configuration. See :ref:`network configuration documentation` -for more information. - -Specifying configuration -========================== - -End users ---------- - -Pass :ref:`user-data` to the cloud provider. -Every platform supporting ``cloud-init`` will provide a method of supplying -user-data. If you're unsure how to do this, reference the documentation -provided by the cloud platform you're on. Additionally, there may be -related ``cloud-init`` documentation in the :ref:`datasource` -section. - -Once an instance has been initialized, the user-data may not be edited. -It is sourced directly from the cloud, so even if you find a local file -that contains user-data, it will likely be overwritten in the next boot. - -Distro providers ----------------- - -Modify the base config. This often involves submitting a PR to modify -the base `cloud.cfg template`_, which is used to customize -:file:`/etc/cloud/cloud.cfg` per distro. Additionally, a file can be added to -:file:`/etc/cloud/cloud.cfg.d` to override a piece of the base configuration. - -Cloud providers ---------------- - -Pass vendor-data. This is the preferred method for clouds to provide -their own customisation. In some cases, it may make sense to modify the -base config in the same manner as distro providers on cloud-supported -images. - - -.. _Config: https://github.com/canonical/cloud-init/blob/b861ea8a5e1fd0eb33096f60f54eeff42d80d3bd/cloudinit/settings.py#L22 -.. _cloud.cfg template: https://github.com/canonical/cloud-init/blob/main/config/cloud.cfg.tmpl -.. _YAML version 1.1: https://yaml.org/spec/1.1/current.html + Configuration priority + Configuration formats diff --git a/doc/rtd/explanation/exported_errors.rst b/doc/rtd/explanation/exported_errors.rst index d1ebc8c3235..3409d6b6547 100644 --- a/doc/rtd/explanation/exported_errors.rst +++ b/doc/rtd/explanation/exported_errors.rst @@ -1,3 +1,5 @@ +:orphan: + .. _exported_errors: Exported errors diff --git a/doc/rtd/explanation/failure_states.rst b/doc/rtd/explanation/failure_states.rst index 21a1c442231..4f8b41a8dc8 100644 --- a/doc/rtd/explanation/failure_states.rst +++ b/doc/rtd/explanation/failure_states.rst @@ -1,7 +1,7 @@ .. _failure_states: -Failure states -============== +Failure modes +============= Cloud-init has multiple modes of failure. This page describes these modes and how to gather information about failures. diff --git a/doc/rtd/reference/faq.rst b/doc/rtd/explanation/faq.rst similarity index 100% rename from doc/rtd/reference/faq.rst rename to doc/rtd/explanation/faq.rst diff --git a/doc/rtd/explanation/format.rst b/doc/rtd/explanation/format.rst deleted file mode 100644 index a0f8e98f02f..00000000000 --- a/doc/rtd/explanation/format.rst +++ /dev/null @@ -1,405 +0,0 @@ -.. _user_data_formats: - -User-data formats -***************** - -User-data is configuration data provided by a user of a cloud platform to an -instance at launch. User-data can be passed to cloud-init in any of many -formats documented here. User-data is combined with the other -:ref:`configuration sources` to create a combined configuration -which modifies an instance. - -Configuration types -=================== - -User-data formats can be categorized into those that directly configure the -instance, and those that serve as a container, template, or means to obtain -or modify another configuration. - -Formats that directly configure the instance: - -- `Cloud config data`_ -- `User-data script`_ -- `Cloud boothook`_ - -Formats that deal with other user-data formats: - -- `Include file`_ -- `Jinja template`_ -- `MIME multi-part archive`_ -- `Cloud config archive`_ -- `Part handler`_ -- `Gzip compressed content`_ - -.. _user_data_formats-cloud_config: - -Cloud config data -================= - -Example -------- - -.. code-block:: yaml - - #cloud-config - password: password - chpasswd: - expire: False - -Explanation ------------ - -Cloud-config can be used to define how an instance should be configured -in a human-friendly format. The cloud config format uses `YAML`_ with -keys which describe desired instance state. - -These things may include: - -- performing package upgrades on first boot -- configuration of different package mirrors or sources -- initial user or group setup -- importing certain SSH keys or host keys -- *and many more...* - -Many modules are available to process cloud-config data. These modules -may run once per instance, every boot, or once ever. See the associated -module to determine the run frequency. - -For more information, see the cloud config -:ref:`example configurations ` or the cloud config -:ref:`modules reference`. - -.. _user_data_script: - -User-data script -================ - -Example -------- - -.. code-block:: shell - - #!/bin/sh - echo "Hello World" > /var/tmp/output.txt - -Explanation ------------ - -A user-data script is a single script to be executed once per instance. -User-data scripts are run relatively late in the boot process, during -cloud-init's :ref:`final stage` as part of the -:ref:`cc_scripts_user` module. - -.. warning:: - Use of ``INSTANCE_ID`` variable within user-data scripts is deprecated. - Use :ref:`jinja templates` with - :ref:`v1.instance_id` instead. - -.. _user_data_formats-cloud_boothook: - -Cloud boothook -============== - -Simple Example --------------- - -.. code-block:: shell - - #cloud-boothook - #!/bin/sh - echo 192.168.1.130 us.archive.ubuntu.com > /etc/hosts - -Example of once-per-instance script ------------------------------------ - -.. code-block:: bash - - #cloud-boothook - #!/bin/sh - - # Early exit 0 when script has already run for this instance-id, - # continue if new instance boot. - cloud-init-per instance do-hosts /bin/false && exit 0 - echo 192.168.1.130 us.archive.ubuntu.com >> /etc/hosts - -Explanation ------------ - -A cloud boothook is similar to a :ref:`user-data script` -in that it is a script run on boot. When run, -the environment variable ``INSTANCE_ID`` is set to the current instance ID -for use within the script. - -The boothook is different in that: - -* It is run very early in boot, during the :ref:`network` stage, - before any cloud-init modules are run. -* It is run on every boot - -.. warning:: - Use of ``INSTANCE_ID`` variable within boothooks is deprecated. - Use :ref:`jinja templates` with - :ref:`v1.instance_id` instead. - -Include file -============ - -Example -------- - -.. code-block:: text - - #include - https://raw.githubusercontent.com/canonical/cloud-init/403f70b930e3ce0f05b9b6f0e1a38d383d058b53/doc/examples/cloud-config-run-cmds.txt - https://raw.githubusercontent.com/canonical/cloud-init/403f70b930e3ce0f05b9b6f0e1a38d383d058b53/doc/examples/cloud-config-boot-cmds.txt - -Explanation ------------ - -An include file contains a list of URLs, one per line. Each of the URLs will -be read and their content can be any kind of user-data format. If an error -occurs reading a file the remaining files will not be read. - -.. _user_data_formats-jinja: - -Jinja template -============== - -.. _jinja-config: - -Example cloud-config --------------------- - -.. code-block:: yaml - - ## template: jinja - #cloud-config - runcmd: - - echo 'Running on {{ v1.cloud_name }}' > /var/tmp/cloud_name - -.. _jinja-script: - -Example user-data script ------------------------- - -.. code-block:: shell - - ## template: jinja - #!/bin/sh - echo 'Current instance id: {{ v1.instance_id }}' > /var/tmp/instance_id - -Explanation ------------ - -`Jinja templating `_ may be used for -cloud-config and user-data scripts. Any -:ref:`instance-data variables` may be used -as jinja template variables. Any jinja templated configuration must contain -the original header along with the new jinja header above it. - -.. note:: - Use of Jinja templates is supported for cloud-config, user-data - scripts, and cloud-boothooks. Jinja templates are not supported for - meta configs. - -.. _user_data_formats-mime_archive: - -MIME multi-part archive -======================= - -Example -------- - -.. code-block:: - - Content-Type: multipart/mixed; boundary="===============2389165605550749110==" - MIME-Version: 1.0 - Number-Attachments: 2 - - --===============2389165605550749110== - Content-Type: text/cloud-boothook; charset="us-ascii" - MIME-Version: 1.0 - Content-Transfer-Encoding: 7bit - Content-Disposition: attachment; filename="part-001" - - #!/bin/sh - echo "this is from a boothook." > /var/tmp/boothook.txt - - --===============2389165605550749110== - Content-Type: text/cloud-config; charset="us-ascii" - MIME-Version: 1.0 - Content-Transfer-Encoding: 7bit - Content-Disposition: attachment; filename="part-002" - - bootcmd: - - echo "this is from a cloud-config." > /var/tmp/bootcmd.txt - --===============2389165605550749110==-- - -Explanation ------------ - -Using a MIME multi-part file, the user can specify more than one type of data. - -For example, both a user-data script and a cloud-config type could be -specified. - -Each part must specify a valid -:ref:`content types`. Supported content-types -may also be listed from the ``cloud-init`` subcommand -:command:`make-mime`: - -.. code-block:: shell-session - - $ cloud-init devel make-mime --list-types - -Helper subcommand to generate MIME messages -------------------------------------------- - -The ``cloud-init`` `make-mime`_ subcommand can also generate MIME multi-part -files. - -The :command:`make-mime` subcommand takes pairs of (filename, "text/" mime -subtype) separated by a colon (e.g., ``config.yaml:cloud-config``) and emits a -MIME multipart message to :file:`stdout`. - -**MIME subcommand Examples** - -Create user-data containing both a cloud-config (:file:`config.yaml`) -and a shell script (:file:`script.sh`) - -.. code-block:: shell-session - - $ cloud-init devel make-mime -a config.yaml:cloud-config -a script.sh:x-shellscript > user-data.mime - -Create user-data containing 3 shell scripts: - -- :file:`always.sh` - run every boot -- :file:`instance.sh` - run once per instance -- :file:`once.sh` - run once - -.. code-block:: shell-session - - $ cloud-init devel make-mime -a always.sh:x-shellscript-per-boot -a instance.sh:x-shellscript-per-instance -a once.sh:x-shellscript-per-once - - -Cloud config archive -==================== - -Example -------- - -.. code-block:: shell - - #cloud-config-archive - - type: "text/cloud-boothook" - content: | - #!/bin/sh - echo "this is from a boothook." > /var/tmp/boothook.txt - - type: "text/cloud-config" - content: | - bootcmd: - - echo "this is from a cloud-config." > /var/tmp/bootcmd.txt - -Explanation ------------ - -A cloud-config-archive is a way to specify more than one type of data -using YAML. Since building a MIME multipart archive can be somewhat unwieldy -to build by hand or requires using a cloud-init helper utility, the -cloud-config-archive provides a simpler alternative to building the MIME -multi-part archive for those that would prefer to use YAML. - -The format is a list of dictionaries. - -Required fields: - -* ``type``: The :ref:`Content-Type` - identifier for the type of user-data in content -* ``content``: The user-data configuration - -Optional fields: - -* ``launch-index``: The EC2 Launch-Index (if applicable) -* ``filename``: This field is only used if using a user-data format that - requires a filename in a MIME part. This is unrelated to any local system - file. - -All other fields will be interpreted as a MIME part header. - -.. _user_data_formats-part_handler: - -Part handler -============ - -Example -------- - -.. literalinclude:: ../../examples/part-handler.txt - :language: python - :linenos: - - -Explanation ------------ - -A part handler contains custom code for either supporting new -mime-types in multi-part user-data or for overriding the existing handlers for -supported mime-types. - -See the :ref:`custom part handler` reference documentation -for details on writing custom handlers along with an annotated example. - -`This blog post`_ offers another example for more advanced usage. - -Gzip compressed content -======================= - -Content found to be gzip compressed will be uncompressed. -The uncompressed data will then be used as if it were not compressed. -This is typically useful because user-data size may be limited based on -cloud platform. - -.. _user_data_formats-content_types: - -Headers and content types -========================= - -In order for cloud-init to recognize which user-data format is being used, -the user-data must contain a header. Additionally, if the user-data -is being passed as a multi-part message, such as MIME, cloud-config-archive, -or part-handler, the content-type for each part must also be set -appropriately. - -The table below lists the headers and content types for each user-data format. -Note that gzip compressed content is not represented here as it gets passed -as binary data and so may be processed automatically. - -+--------------------+-----------------------------+-------------------------+ -|User-data format |Header |Content-Type | -+====================+=============================+=========================+ -|Cloud config data |#cloud-config |text/cloud-config | -+--------------------+-----------------------------+-------------------------+ -|User-data script |#! |text/x-shellscript | -+--------------------+-----------------------------+-------------------------+ -|Cloud boothook |#cloud-boothook |text/cloud-boothook | -+--------------------+-----------------------------+-------------------------+ -|MIME multi-part |Content-Type: multipart/mixed|multipart/mixed | -+--------------------+-----------------------------+-------------------------+ -|Cloud config archive|#cloud-config-archive |text/cloud-config-archive| -+--------------------+-----------------------------+-------------------------+ -|Jinja template |## template: jinja |text/jinja2 | -+--------------------+-----------------------------+-------------------------+ -|Include file |#include |text/x-include-url | -+--------------------+-----------------------------+-------------------------+ -|Part handler |#part-handler |text/part-handler | -+--------------------+-----------------------------+-------------------------+ - -Continued reading -================= - -See the :ref:`configuration sources` documentation for -information about other sources of configuration for cloud-init. - -.. _make-mime: https://github.com/canonical/cloud-init/blob/main/cloudinit/cmd/devel/make_mime.py -.. _YAML: https://yaml.org/spec/1.1/current.html -.. _This blog post: http://foss-boss.blogspot.com/2011/01/advanced-cloud-init-custom-handlers.html diff --git a/doc/rtd/explanation/format/boothook.rst b/doc/rtd/explanation/format/boothook.rst new file mode 100644 index 00000000000..de0d4256a39 --- /dev/null +++ b/doc/rtd/explanation/format/boothook.rst @@ -0,0 +1,46 @@ +.. _user_data_formats-cloud_boothook: + +Cloud boothook +============== + +Simple Example +-------------- + +.. code-block:: shell + + #cloud-boothook + #!/bin/sh + echo 192.168.1.130 us.archive.ubuntu.com > /etc/hosts + +Example of once-per-instance script +----------------------------------- + +.. code-block:: bash + + #cloud-boothook + #!/bin/sh + + # Early exit 0 when script has already run for this instance-id, + # continue if new instance boot. + cloud-init-per instance do-hosts /bin/false && exit 0 + echo 192.168.1.130 us.archive.ubuntu.com >> /etc/hosts + +Explanation +----------- + +A cloud boothook is similar to a :ref:`user-data script` +in that it is a script run on boot. When run, +the environment variable ``INSTANCE_ID`` is set to the current instance ID +for use within the script. + +The boothook is different in that: + +* It is run very early in boot, during the :ref:`network` stage, + before any cloud-init modules are run. +* It runs every boot. + +.. warning:: + Use of ``INSTANCE_ID`` variable within boothooks is deprecated. + Use :ref:`jinja templates` with + :ref:`v1.instance_id` instead. + diff --git a/doc/rtd/explanation/format/cloud-config-archive.rst b/doc/rtd/explanation/format/cloud-config-archive.rst new file mode 100644 index 00000000000..ffe596d3b15 --- /dev/null +++ b/doc/rtd/explanation/format/cloud-config-archive.rst @@ -0,0 +1,46 @@ +.. _cloud-config-archive: + +Cloud config archive +==================== + +Example +------- + +.. code-block:: shell + + #cloud-config-archive + - type: "text/cloud-boothook" + content: | + #!/bin/sh + echo "this is from a boothook." > /var/tmp/boothook.txt + - type: "text/cloud-config" + content: | + bootcmd: + - echo "this is from a cloud-config." > /var/tmp/bootcmd.txt + +Explanation +----------- + +A cloud-config-archive is a way to specify more than one type of data +using YAML. Since building a MIME multipart archive can be somewhat unwieldy +to build by hand or requires using a cloud-init helper utility, the +cloud-config-archive provides a simpler alternative to building the MIME +multi-part archive for those that would prefer to use YAML. + +The format is a list of dictionaries. + +Required fields: + +* ``type``: The :ref:`Content-Type` + identifier for the type of user-data in content +* ``content``: The user-data configuration + +Optional fields: + +* ``launch-index``: The EC2 Launch-Index (if applicable) +* ``filename``: This field is only used if using a user-data format that + requires a filename in a MIME part. This is unrelated to any local system + file. + +All other fields will be interpreted as a MIME part header. + diff --git a/doc/rtd/explanation/format/cloud-config.rst b/doc/rtd/explanation/format/cloud-config.rst new file mode 100644 index 00000000000..73c529d101d --- /dev/null +++ b/doc/rtd/explanation/format/cloud-config.rst @@ -0,0 +1,38 @@ +.. _user_data_formats-cloud_config: + +Cloud config +============ + +Example +------- + +.. code-block:: yaml + + #cloud-config + password: password + chpasswd: + expire: False + +Explanation +----------- + +Cloud-config can be used to define how an instance should be configured +in a human-friendly format. The cloud config format uses `YAML`_ with +keys which describe desired instance state. + +These things may include: + +- performing package upgrades on first boot +- configuration of different package mirrors or sources +- initial user or group setup +- importing certain SSH keys or host keys +- *and many more...* + +Many modules are available to process cloud-config data. These modules +may run once per instance, every boot, or once ever. See the associated +module to determine the run frequency. + +See the :ref:`cloud-config reference` and +:ref:`example configurations ` for more details. + +.. _YAML: https://yaml.org/spec/1.1/current.html diff --git a/doc/rtd/explanation/format/gzip.rst b/doc/rtd/explanation/format/gzip.rst new file mode 100644 index 00000000000..b8dae34cf58 --- /dev/null +++ b/doc/rtd/explanation/format/gzip.rst @@ -0,0 +1,15 @@ +.. _gzip: + +Gzip compressed content +======================= + +Content found to be gzip compressed will be uncompressed. +The uncompressed data will then be used as if it were not compressed. +This may be useful when user-data size may be limited based on +cloud platform. + +Some platforms are known to corrupt binary content, which prevents using +this format. + +.. _user_data_formats-content_types: + diff --git a/doc/rtd/explanation/format/include.rst b/doc/rtd/explanation/format/include.rst new file mode 100644 index 00000000000..304b53596e6 --- /dev/null +++ b/doc/rtd/explanation/format/include.rst @@ -0,0 +1,20 @@ +.. _user_data_formats-include: + +Include file +============ + +Example +------- + +.. code-block:: text + + #include + https://raw.githubusercontent.com/canonical/cloud-init/403f70b930e3ce0f05b9b6f0e1a38d383d058b53/doc/examples/cloud-config-run-cmds.txt + https://raw.githubusercontent.com/canonical/cloud-init/403f70b930e3ce0f05b9b6f0e1a38d383d058b53/doc/examples/cloud-config-boot-cmds.txt + +Explanation +----------- + +An include file contains a list of URLs, one per line. Each of the URLs will +be read and their content can be any kind of user-data format. If an error +occurs reading a file the remaining files will not be read. diff --git a/doc/rtd/explanation/format/index.rst b/doc/rtd/explanation/format/index.rst new file mode 100644 index 00000000000..a658f4f3727 --- /dev/null +++ b/doc/rtd/explanation/format/index.rst @@ -0,0 +1,47 @@ +.. _user_data_formats: + +User-data formats +***************** + +User-data encodes instructions used by cloud-init. User-data has multiple +configuration types. Each type is identified by a +:ref:`unique header `. + +Configuration types +=================== + +User-data formats can be categorized into those that directly configure the +instance, and those that serve as a container, template, or means to obtain +or modify another configuration. + +Formats that directly configure the instance: + +- :ref:`Cloud-config ` +- :ref:`User-data script ` +- :ref:`Boothook ` + +Formats that embed other formats: + +- :ref:`Include ` +- :ref:`Jinja ` +- :ref:`MIME ` +- :ref:`Cloud-config archive ` +- :ref:`Gzip ` + +.. toctree:: + :hidden: + + Cloud-config + Boothook + User-data script + Include + Jinja + Gzip + Cloud-config archive + MIME + +Continued reading +================= + +See the :ref:`configuration sources` documentation for +information about configuration sources and priority. diff --git a/doc/rtd/explanation/format/jinja.rst b/doc/rtd/explanation/format/jinja.rst new file mode 100644 index 00000000000..f83393b10db --- /dev/null +++ b/doc/rtd/explanation/format/jinja.rst @@ -0,0 +1,42 @@ +.. _user_data_formats-jinja: + +Jinja template +============== + +.. _jinja-config: + +Example cloud-config +-------------------- + +.. code-block:: yaml + + ## template: jinja + #cloud-config + runcmd: + - echo 'Running on {{ v1.cloud_name }}' > /var/tmp/cloud_name + +.. _jinja-script: + +Example user-data script +------------------------ + +.. code-block:: shell + + ## template: jinja + #!/bin/sh + echo 'Current instance id: {{ v1.instance_id }}' > /var/tmp/instance_id + +Explanation +----------- + +`Jinja templates `_ may be used for +cloud-config and user-data scripts. Any +:ref:`instance-data variables` may be used +as jinja template variables. Any jinja templated configuration must contain +the original header along with the new jinja header above it. + +.. note:: + Use of Jinja templates is supported for cloud-config, user-data + scripts, and cloud-boothooks. Jinja templates are not supported for + meta configs. + diff --git a/doc/rtd/explanation/format/mime.rst b/doc/rtd/explanation/format/mime.rst new file mode 100644 index 00000000000..829367eb964 --- /dev/null +++ b/doc/rtd/explanation/format/mime.rst @@ -0,0 +1,80 @@ +.. _user_data_formats-mime_archive: + +MIME multi-part archive +======================= + +Example +------- + +.. code-block:: + + Content-Type: multipart/mixed; boundary="===============2389165605550749110==" + MIME-Version: 1.0 + Number-Attachments: 2 + + --===============2389165605550749110== + Content-Type: text/cloud-boothook; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="part-001" + + #!/bin/sh + echo "this is from a boothook." > /var/tmp/boothook.txt + + --===============2389165605550749110== + Content-Type: text/cloud-config; charset="us-ascii" + MIME-Version: 1.0 + Content-Transfer-Encoding: 7bit + Content-Disposition: attachment; filename="part-002" + + bootcmd: + - echo "this is from a cloud-config." > /var/tmp/bootcmd.txt + --===============2389165605550749110==-- + +Explanation +----------- + +Using a MIME multi-part file, the user can specify more than one type of data. + +For example, both a user-data script and a cloud-config type could be +specified. + +Each part must specify a valid +:ref:`content types`. Supported content-types +may also be listed from the ``cloud-init`` subcommand +:command:`make-mime`: + +.. code-block:: shell-session + + $ cloud-init devel make-mime --list-types + +Helper subcommand to generate MIME messages +------------------------------------------- + +The ``cloud-init`` `make-mime`_ subcommand can also generate MIME multi-part +files. + +The :command:`make-mime` subcommand takes pairs of (filename, "text/" mime +subtype) separated by a colon (e.g., ``config.yaml:cloud-config``) and emits a +MIME multipart message to :file:`stdout`. + +**MIME subcommand Examples** + +Create user-data containing both a cloud-config (:file:`config.yaml`) +and a shell script (:file:`script.sh`) + +.. code-block:: shell-session + + $ cloud-init devel make-mime -a config.yaml:cloud-config -a script.sh:x-shellscript > user-data.mime + +Create user-data containing 3 shell scripts: + +- :file:`always.sh` - run every boot +- :file:`instance.sh` - run once per instance +- :file:`once.sh` - run once + +.. code-block:: shell-session + + $ cloud-init devel make-mime -a always.sh:x-shellscript-per-boot -a instance.sh:x-shellscript-per-instance -a once.sh:x-shellscript-per-once + +.. _make-mime: https://github.com/canonical/cloud-init/blob/main/cloudinit/cmd/devel/make_mime.py diff --git a/doc/rtd/explanation/format/user-data-script.rst b/doc/rtd/explanation/format/user-data-script.rst new file mode 100644 index 00000000000..3e062f7176e --- /dev/null +++ b/doc/rtd/explanation/format/user-data-script.rst @@ -0,0 +1,25 @@ +.. _user_data_script: + +User-data script +================ + +Example +------- + +.. code-block:: shell + + #!/bin/sh + echo "Hello World" > /var/tmp/output.txt + +Explanation +----------- + +A user-data script is a single script to be executed once per instance. +User-data scripts are run relatively late in the boot process, during +cloud-init's :ref:`final stage` as part of the +:ref:`cc_scripts_user` module. + +.. warning:: + Use of ``INSTANCE_ID`` variable within user-data scripts is deprecated. + Use :ref:`jinja templates` with + :ref:`v1.instance_id` instead. diff --git a/doc/rtd/explanation/index.rst b/doc/rtd/explanation/index.rst index 5465a838fb2..82367a321e1 100644 --- a/doc/rtd/explanation/index.rst +++ b/doc/rtd/explanation/index.rst @@ -1,29 +1,18 @@ Explanation *********** -Our explanatory and conceptual guides are written to provide a better -understanding of how ``cloud-init`` works. They enable you to expand your -knowledge and become better at using and configuring ``cloud-init``. +The following guides explain how ``cloud-init`` works. ----- .. toctree:: :maxdepth: 1 - introduction.rst - format.rst - about-cloud-config.rst - configuration.rst - boot.rst - first_boot.rst - events.rst - instancedata.rst - vendordata.rst - security.rst - hardening.rst - analyze.rst - kernel-command-line.rst - failure_states.rst - exported_errors.rst - return_codes.rst - net-device-info.rst + Introduction + Configuration + Boot stages + Failure modes + Project status + Hardening + FAQ + Advanced explanation diff --git a/doc/rtd/explanation/instancedata.rst b/doc/rtd/explanation/instancedata.rst index 6d2b61c2d9f..5d4a45b43b2 100644 --- a/doc/rtd/explanation/instancedata.rst +++ b/doc/rtd/explanation/instancedata.rst @@ -1,17 +1,9 @@ -.. _instance-data: - - -Instance-data -************* - -.. toctree:: - :maxdepth: 1 - :hidden: +:orphan: - kernel-command-line.rst +.. _instance-data: -What is ``instance-data?`` -========================== +``Instance-data`` +***************** ``instance-data`` is a JSON object which contains instance-specific variables in a standardized format. These variables may be used in ``cloud-init`` @@ -50,10 +42,9 @@ provided to this instance. Non-root users referencing ``userdata`` or ``vendordata`` keys will see only redacted values. .. note:: - To save time designing a user data template for a specific cloud's - :file:`instance-data.json`, use the :command:`render` command on an - instance booted on your favorite cloud. See :ref:`cli_devel` for more - information. + + Run the :command:`cloud-init devel render` from an instance + to debug template rendering issues. .. _instancedata-Using: @@ -76,8 +67,7 @@ Any ``instance-data`` variables are surfaced as jinja template variables. .. note:: Trying to reference jinja variables that don't exist in ``instance-data`` will result in warnings in :file:`/var/log/cloud-init.log` and the following - string in your rendered :file:`user-data`: - ``CI_MISSING_JINJA_VAR/``. + string in your rendered ``user-data``: ``CI_MISSING_JINJA_VAR/``. Sensitive data such as user passwords may be contained in ``instance-data``. ``Cloud-init`` separates this sensitive data such that is it only readable by @@ -153,27 +143,15 @@ Example: CLI discovery of ``instance-data`` Reference ========= -Storage locations ------------------ - -* :file:`/run/cloud-init/instance-data.json`: world-readable JSON containing - standardized keys, sensitive keys redacted. -* :file:`/run/cloud-init/instance-data-sensitive.json`: root-readable - unredacted JSON blob. -* :file:`/run/cloud-init/combined-cloud-config.json`: root-readable - unredacted JSON blob. Any meta-data, vendor-data and user-data overrides - are applied to the :file:`/run/cloud-init/combined-cloud-config.json` config - values. - .. _instance-data-keys: -:file:`instance-data.json` top level keys ------------------------------------------ +`instance-data` top level keys +------------------------------ ``base64_encoded_keys`` ^^^^^^^^^^^^^^^^^^^^^^^ -A list of forward-slash delimited key paths into the :file:`instance-data.json` +A list of forward-slash delimited key paths into the ``instance-data`` JSON object whose value is base64encoded for JSON compatibility. Values at these paths should be decoded to get the original value. @@ -187,9 +165,9 @@ the feature is enabled. ``sensitive_keys`` ^^^^^^^^^^^^^^^^^^ -A list of forward-slash delimited key paths into the :file:`instance-data.json` +A list of forward-slash delimited key paths into the ``instance-data`` JSON object whose value is considered by the datasource as 'security sensitive'. -Only the keys listed here will be redacted from :file:`instance-data.json` for +Only the keys listed here will be redacted from ``instance-data`` JSON for non-root users. ``merged_cfg`` @@ -207,9 +185,7 @@ included in the ``sensitive-keys`` list which is only readable by root. .. note:: ``merged_system_cfg`` represents only the merged config from the underlying filesystem. These values can be overridden by meta-data, vendor-data or - user-data. The fully merged cloud-config provided to a machine - which accounts for any supplemental overrides is the file - :file:`/run/cloud-init/combined-cloud-config.json`. + user-data. ``ds`` ^^^^^^ @@ -248,7 +224,7 @@ top-level key aliases for any standardized ``v#`` keys present. The preceding ``v1`` is not required of ``v1.var_name`` These aliases will represent the value of the highest versioned standard key. For example, ``cloud_name`` value will be ``v2.cloud_name`` if both ``v1`` and ``v2`` keys are present in -:file:`instance-data.json`. +``instance-data``. ``Cloud-init`` also provides jinja-safe key aliases for any ``instance-data`` keys which contain jinja operator characters such as ``+``, ``-``, ``.``, @@ -257,8 +233,8 @@ jinja-safe key alias. This allows for ``cloud-init`` templates to use aliased variable references which allow for jinja's dot-notation reference such as ``{{ ds.v1_0.my_safe_key }}`` instead of ``{{ ds["v1.0"]["my/safe-key"] }}``. -Standardized :file:`instance-data.json` v1 keys ------------------------------------------------ +Standardized instance-data` v1 keys +----------------------------------- ``v1._beta_keys`` ^^^^^^^^^^^^^^^^^ @@ -278,7 +254,7 @@ on. This is different than the 'platform' item. For example, the cloud name of Amazon Web Services is 'aws', while the platform is 'ec2'. If determining a specific name is not possible or provided in -:file:`meta-data`, then this field may contain the same content as 'platform'. +``meta-data``, then this field may contain the same content as 'platform'. Example output: @@ -420,8 +396,7 @@ Example output: Example Output -------------- -Below is an example of ``/run/cloud-init/instance-data-sensitive.json`` on an -EC2 instance: +Below is an example of sensitive ``instance-data`` on an EC2 instance: .. sourcecode:: json diff --git a/doc/rtd/explanation/kernel-command-line.rst b/doc/rtd/explanation/kernel-command-line.rst index bfcb9488bb8..3659994467e 100644 --- a/doc/rtd/explanation/kernel-command-line.rst +++ b/doc/rtd/explanation/kernel-command-line.rst @@ -1,3 +1,5 @@ +:orphan: + Kernel command line ******************* diff --git a/doc/rtd/explanation/part_handlers.rst b/doc/rtd/explanation/part_handlers.rst new file mode 100644 index 00000000000..085946e19e3 --- /dev/null +++ b/doc/rtd/explanation/part_handlers.rst @@ -0,0 +1,30 @@ +.. _user_data_formats-part_handler: + +Part handler +************ + +Part handlers define configuration formats by modifying ``cloud-init``'s +source code. These are not recommended for most users. The part handler API +is not guaranteed to be stable. + +Example +------- + +.. literalinclude:: ../../examples/part-handler.txt + :language: python + :linenos: + + +Explanation +----------- + +A part handler contains custom code for either supporting new +mime-types in multi-part user-data or for overriding the existing handlers for +supported mime-types. + +See the :ref:`custom part handler` reference documentation +for details on writing custom handlers along with an annotated example. + +`This blog post`_ offers another example for more advanced usage. + +.. _This blog post: http://foss-boss.blogspot.com/2011/01/advanced-cloud-init-custom-handlers.html diff --git a/doc/rtd/explanation/project-status.rst b/doc/rtd/explanation/project-status.rst new file mode 100644 index 00000000000..33003f64fae --- /dev/null +++ b/doc/rtd/explanation/project-status.rst @@ -0,0 +1,11 @@ +Project status +************** + +.. toctree:: + :maxdepth: 1 + + Breaking changes <../reference/breaking_changes.rst> + Cloud and distro availability <../reference/availability.rst> + Check out the latest code <../reference/test_unreleased_packages.rst> + Downstream LTS releases <../reference/ubuntu_stable_release_updates.rst> + Security policy diff --git a/doc/rtd/explanation/return_codes.rst b/doc/rtd/explanation/return_codes.rst index 31a0f40fb67..e49a9eaed66 100644 --- a/doc/rtd/explanation/return_codes.rst +++ b/doc/rtd/explanation/return_codes.rst @@ -1,3 +1,5 @@ +:orphan: + .. _return_codes: Why did `cloud-init status` start returning exit code 2? diff --git a/doc/rtd/explanation/vendordata.rst b/doc/rtd/explanation/vendordata.rst index 1745f9cc053..2b192831e5c 100644 --- a/doc/rtd/explanation/vendordata.rst +++ b/doc/rtd/explanation/vendordata.rst @@ -1,3 +1,5 @@ +:orphan: + .. _vendor-data: Vendor-data diff --git a/doc/rtd/howto/index.rst b/doc/rtd/howto/index.rst index 0ccad80a7d3..139542bd9b5 100644 --- a/doc/rtd/howto/index.rst +++ b/doc/rtd/howto/index.rst @@ -18,14 +18,11 @@ How do I...? .. toctree:: :maxdepth: 1 - Launch cloud-init with... - Validate my user-data + Validate user-data + Debug cloud-init Check the status of cloud-init + Launch an instance using cloud-init Wait for cloud-init - Debug cloud-init - Report a bug - Disable cloud-init Re-run cloud-init - Change how often a module runs - Identify my datasource - Test development packages + Disable cloud-init + Report a bug diff --git a/doc/rtd/howto/launch_multipass.rst b/doc/rtd/howto/launch_multipass.rst index 2b7c19978f6..173eb40be83 100644 --- a/doc/rtd/howto/launch_multipass.rst +++ b/doc/rtd/howto/launch_multipass.rst @@ -8,9 +8,8 @@ Windows, and macOS. When launching a Multipass VM, user-data can be passed by adding the ``--cloud-init`` flag and an appropriate YAML file containing the user-data. -For more information about the file and how to construct it, see -:ref:`our explanatory guide ` about the *user-data -cloud-config* format. +For more information about cloud-config, see +:ref:`the explanatory guide `. Create your configuration ------------------------- diff --git a/doc/rtd/reference/advanced_reference.rst b/doc/rtd/reference/advanced_reference.rst new file mode 100644 index 00000000000..75d5ef6e67f --- /dev/null +++ b/doc/rtd/reference/advanced_reference.rst @@ -0,0 +1,20 @@ +Advanced reference +****************** + +Settings that are documented in these pages are subject to change. + +This documentation is intended for custom image creators, distribution +maintainers, and cloud providers. Modifying these configurations should not be +necessary for most end users and can result in a system that may be unreachable +or may no longer boot. + +----- + +.. toctree:: + :maxdepth: 1 + + Default configuration + Network configuration + Change cloud-config module run frequency + Merge cloud-config + Custom cloud-config modules diff --git a/doc/rtd/reference/base_config_reference.rst b/doc/rtd/reference/base_config_reference.rst index 30033265cb0..8001da77e97 100644 --- a/doc/rtd/reference/base_config_reference.rst +++ b/doc/rtd/reference/base_config_reference.rst @@ -4,10 +4,13 @@ Base configuration ****************** .. warning:: + This documentation is intended for custom image creators, such as distros - and cloud providers, not end users. Modifying the base configuration - should not be necessary for end users and can result in a system that may - be unreachable or may no longer boot. + and cloud providers, not end users. To learn how to configure an instance, + :ref:`start here `. + + Modifying the base configuration should not be necessary for most end users + and can result in a system that may be unreachable or may no longer boot. ``Cloud-init`` base config is primarily defined in two places: diff --git a/doc/rtd/reference/cli.rst b/doc/rtd/reference/cli.rst index 286ae6f16b2..cefb89ab2e7 100644 --- a/doc/rtd/reference/cli.rst +++ b/doc/rtd/reference/cli.rst @@ -17,38 +17,6 @@ For the latest list of subcommands and arguments use ``cloud-init``'s ``--help`` option. This can be used against ``cloud-init`` itself, or on any of its subcommands. -.. code-block:: shell-session - - $ cloud-init --help - -Example output: - -.. code-block:: - - usage: cloud-init [-h] [--version] [--debug] [--force] [--all-stages] {init,modules,single,query,features,analyze,devel,collect-logs,clean,status,schema} ... - - options: - -h, --help show this help message and exit - --version, -v Show program's version number and exit. - --debug, -d Show additional pre-action logging (default: False). - --force Force running even if no datasource is found (use at your own risk). - --all-stages Run cloud-init's stages under a single process using a synchronization protocol. This is not intended for CLI usage. - - Subcommands: - {init,modules,single,query,features,analyze,devel,collect-logs,clean,status,schema} - init DEPRECATED: Initialize cloud-init and perform initial modules. - modules DEPRECATED: Activate modules using a given configuration key. - single Manually run a single module. Useful for testing during development. - query Query standardized instance-data from the command line. - features List defined features. - analyze Devel tool: Analyze cloud-init logs and data. - devel Run development tools. - collect-logs Collect and tar all cloud-init debug info. - clean Remove logs and artifacts so cloud-init can re-run. - status Report cloud-init status or wait on completion. - schema Validate cloud-config files using jsonschema. - - The rest of this document will give an overview of each of the subcommands. .. _cli_analyze: @@ -127,41 +95,6 @@ Logs collected include: Ubuntu users can file bugs using :command:`ubuntu-bug cloud-init` to automatically attach these logs to a bug report. -.. _cli_devel: - -:command:`devel` ----------------- - -Collection of development tools under active development. These tools will -likely be promoted to top-level subcommands when stable. - -Do **NOT** rely on the output of these commands as they can and will change. - -Current subcommands: - -:command:`net-convert` ----------------------- - -Manually use ``cloud-init``'s network format conversion. Useful for testing -configuration or testing changes to the network conversion logic itself. - -:command:`render` ------------------ - -Use ``cloud-init``'s jinja template render to process **#cloud-config** or -**custom-scripts**, injecting any variables from -:file:`/run/cloud-init/instance-data.json`. It accepts a user-data file -containing the jinja template header ``## template: jinja`` and renders that -content with any :file:`instance-data.json` variables present. - -:command:`hotplug-hook` ------------------------ - -Hotplug related subcommands. This command is intended to be -called via a ``systemd`` service and is not considered user-accessible except -for debugging purposes. - - :command:`query` ---------------- @@ -181,92 +114,21 @@ administrators to enable hotplug in running instances. The recommended method is configuring :ref:`events`, if not enabled by default in the active datasource. -.. _cli_features: - -:command:`features` -------------------- - -Print out each feature supported. If ``cloud-init`` does not have the -:command:`features` subcommand, it also does not support any features -described in this document. - -.. code-block:: shell-session - - $ cloud-init features - -Example output: - -.. code-block:: - - NETWORK_CONFIG_V1 - NETWORK_CONFIG_V2 - - -.. _cli_init: - -:command:`init` (deprecated) ----------------------------- - -Generally run by OS init systems to execute ``cloud-init``'s stages: -*init* and *init-local*. See :ref:`boot_stages` for more info. -Can be run on the command line, but is deprecated, because incomplete -configuration can be applied when run later in boot. The boot stages are -generally gated to run only once due to semaphores in -:file:`/var/lib/cloud/instance/sem/` and :file:`/var/lib/cloud/sem`. - -* :command:`--local`: Run *init-local* stage instead of *init*. -* :command:`--file` : Use additional yaml configuration files. - -.. _cli_modules: - -:command:`modules` (deprecated) -------------------------------- - -Generally run by OS init systems to execute ``modules:config`` and -``modules:final`` boot stages. This executes cloud config :ref:`modules` -configured to run in the Init, Config and Final stages. Can be run on the -command line, but this is not recommended and will generate a warning because -incomplete configuration can be applied when run later in boot. -The modules are declared to run in various boot stages in the file -:file:`/etc/cloud/cloud.cfg` under keys: - -* ``cloud_init_modules`` -* ``cloud_config_modules`` -* ``cloud_final_modules`` - -Can be run on the command line, but is deprecated, because incomplete -configuration can be applied when run later in boot. Each module is gated to -run only once due to semaphores in :file:`/var/lib/cloud/`. - -* :command:`--mode [init|config|final]`: Run ``modules:init``, - ``modules:config`` or ``modules:final`` ``cloud-init`` stages. - See :ref:`boot_stages` for more info. -* :command:`--file` : Use additional yaml configuration files. - -.. warning:: - `--mode init` is deprecated in 24.1 and scheduled to be removed in 29.1. - Use :command:`cloud-init init` instead. - .. _cli_query: :command:`query` ---------------- -Query standardized instance-data crawled by ``cloud-init`` and -stored in :file:`/run/cloud-init/instance-data.json`. This is a convenience -command-line interface to reference any cached configuration meta-data that -``cloud-init`` crawls when booting the instance. See :ref:`instance-data` -for more info. +Query standardized instance-data crawled by ``cloud-init``. See +:ref:`instance-data` for more info. * :command:`--all`: Dump all available instance-data as JSON which can be queried. -* :command:`--instance-data`: Optional path to a different - :file:`instance-data.json` file to source for queries. * :command:`--list-keys`: List available query keys from cached instance-data. * :command:`--format`: A string that will use jinja-template syntax to render a string replacing. * :command:``: A dot-delimited variable path into the - :file:`instance-data.json` object. + instance-data object. Below demonstrates how to list all top-level query keys that are standardized aliases: diff --git a/doc/rtd/reference/cloud-config.rst b/doc/rtd/reference/cloud-config.rst new file mode 100644 index 00000000000..204747e8e02 --- /dev/null +++ b/doc/rtd/reference/cloud-config.rst @@ -0,0 +1,8 @@ +Cloud-config +************ + +.. toctree:: + :maxdepth: 1 + + Cloud-config reference + Cloud-config examples diff --git a/doc/rtd/reference/config-format-headers.rst b/doc/rtd/reference/config-format-headers.rst new file mode 100644 index 00000000000..e5d6de37e5e --- /dev/null +++ b/doc/rtd/reference/config-format-headers.rst @@ -0,0 +1,35 @@ +:orphan: + +.. _user_data_headers: + +Headers and content types +========================= + +A user-data header is required for cloud-init to recognize the format. See the +header and content types for each user-data format below: + ++--------------------+-----------------------------+-------------------------+ +|User-data format |Header |Content-Type | ++====================+=============================+=========================+ +|Cloud config data |#cloud-config |text/cloud-config | ++--------------------+-----------------------------+-------------------------+ +|User-data script |#! |text/x-shellscript | ++--------------------+-----------------------------+-------------------------+ +|Cloud boothook |#cloud-boothook |text/cloud-boothook | ++--------------------+-----------------------------+-------------------------+ +|MIME multi-part |Content-Type: multipart/mixed|multipart/mixed | ++--------------------+-----------------------------+-------------------------+ +|Cloud config archive|#cloud-config-archive |text/cloud-config-archive| ++--------------------+-----------------------------+-------------------------+ +|Jinja template |## template: jinja |text/jinja2 | ++--------------------+-----------------------------+-------------------------+ +|Include file |#include |text/x-include-url | ++--------------------+-----------------------------+-------------------------+ +|Part handler |#part-handler |text/part-handler | ++--------------------+-----------------------------+-------------------------+ + +.. note:: + + The gzip format is not included above because it is binary data. It is + identified by its magic bytes. + diff --git a/doc/rtd/reference/datasource_dsname_map.rst b/doc/rtd/reference/datasource_dsname_map.rst index b5b5a8db7b1..f5fe6ee0528 100644 --- a/doc/rtd/reference/datasource_dsname_map.rst +++ b/doc/rtd/reference/datasource_dsname_map.rst @@ -1,3 +1,5 @@ +:orphan: + .. _datasource_dsname: Datasource dsname diff --git a/doc/rtd/reference/datasources.rst b/doc/rtd/reference/datasources.rst index 6802878b52b..c35bd4af89c 100644 --- a/doc/rtd/reference/datasources.rst +++ b/doc/rtd/reference/datasources.rst @@ -9,23 +9,20 @@ configuration drive (i.e., meta-data). Typical user-data includes files, YAML, and shell scripts whereas typical meta-data includes server name, instance id, display name, and other cloud specific details. -Any meta-data processed by ``cloud-init``'s datasources is persisted as -:file:`/run/cloud-init/instance-data.json`. ``Cloud-init`` provides tooling to -quickly introspect some of that data. See :ref:`instance-data` for more -information. +Any meta-data processed by ``cloud-init``'s datasources can be inspected. See +:ref:`instance-data` for more information. How to configure which datasource to use ======================================== -By default ``cloud-init`` should automatically determine which datasource it is -running on. Therefore, in most cases, users of ``cloud-init`` should not -have to configure ``cloud-init`` to specify which datasource cloud-init is -running on; ``cloud-init`` should "figure it out". +In most cases, users of ``cloud-init`` should not have to configure +``cloud-init`` to specify which datasource cloud-init is running on; +``cloud-init`` should be able to identify the platform. There are exceptions, however, when the :ref:`datasource does not -identify` itself to ``cloud-init``. For these -exceptions, one can override datasource detection either by configuring a -single datasource in the :ref:`datasource_list`, +identify` itself to ``cloud-init``. In this case, the +datasource detection may be overridden by configuring a single datasource +in the :ref:`datasource_list` or by using :ref:`kernel command line arguments`. .. _datasources_supported: @@ -33,7 +30,7 @@ or by using :ref:`kernel command line arguments`. Datasources: ============ -The following is a list of documentation for each supported datasource: +The following is a page for each supported datasource: .. toctree:: :titlesonly: diff --git a/doc/rtd/reference/datasources/vmware.rst b/doc/rtd/reference/datasources/vmware.rst index d1a2e086617..16975560e8a 100644 --- a/doc/rtd/reference/datasources/vmware.rst +++ b/doc/rtd/reference/datasources/vmware.rst @@ -172,29 +172,8 @@ The above configuration causes the ``vmware-rpctool`` command to return a non-zero exit code with the error message ``Permission denied``. If this should occur, the datasource falls back to using ``vmtoolsd``. -Instance data and lazy networks -------------------------------- - -One of the hallmarks of ``cloud-init`` is -:ref:`its use of instance-data and JINJA queries ` -- the -ability to write queries in user-data and vendor-data that reference runtime -information present in :file:`/run/cloud-init/instance-data.json`. This works -well when the meta-data provides all of the information up front, such as the -network configuration. For systems that rely on DHCP, however, this -information may not be available when the meta-data is persisted to disk. - -This datasource ensures that even if the instance is using DHCP to configure -networking, the same details about the configured network are available in -:file:`/run/cloud-init/instance-data.json` as if static networking was used. -This information collected at runtime is easy to demonstrate by executing the -datasource on the command line. From the root of this repository, run the -following command: - -.. code-block:: bash - - PYTHONPATH="$(pwd)" python3 cloudinit/sources/DataSourceVMware.py - -The above command will result in output similar to the below JSON: +Example instance-data +--------------------- .. code-block:: json @@ -308,12 +287,9 @@ IPv4 and IPv6 addresses for a host. Waiting on the network ---------------------- -Sometimes ``cloud-init`` may bring up the network, but it will not finish -coming online before the datasource's ``setup`` function is called, resulting -in a :file:`/var/run/cloud-init/instance-data.json` file that does not have the -correct network information. It is possible to instruct the datasource to wait -until an IPv4 or IPv6 address is available before writing the instance-data -with the following meta-data properties: +It is possible to instruct the datasource to wait until an IPv4 or IPv6 address +is available before processing instance-data with the following meta-data +properties: .. code-block:: yaml diff --git a/doc/rtd/reference/examples.rst b/doc/rtd/reference/examples.rst index 1036ba259ed..88bf2d663c1 100644 --- a/doc/rtd/reference/examples.rst +++ b/doc/rtd/reference/examples.rst @@ -4,9 +4,8 @@ All cloud config examples ************************* .. note:: - This page is a summary containing all the cloud config YAML examples - together. If you would like to explore examples by operation or process - instead, refer to the :ref:`examples library `. + + :ref:`The page ` organizes examples by category. Including users and groups ========================== diff --git a/doc/rtd/reference/examples_library.rst b/doc/rtd/reference/examples_library.rst index d2ba0aaaa3d..5a1babb3a81 100644 --- a/doc/rtd/reference/examples_library.rst +++ b/doc/rtd/reference/examples_library.rst @@ -1,12 +1,13 @@ +:orphan: + .. _examples_library: -Cloud config examples library -***************************** +Cloud config examples index +*************************** .. note:: This page is an index to all the cloud config YAML examples, organized by - operation or process. If you prefer to use a single-page summary containing - every cloud config yaml example, refer to the + operation or process. Alternatively see the :ref:`all examples page `. .. include:: yaml_examples/index_boot.rst diff --git a/doc/rtd/reference/index.rst b/doc/rtd/reference/index.rst index 4a5e7f26b0a..3cb42a8e8ca 100644 --- a/doc/rtd/reference/index.rst +++ b/doc/rtd/reference/index.rst @@ -1,28 +1,17 @@ Reference ********* -Our reference section contains support information for ``cloud-init``. -This includes details on the network requirements, API definitions, support -matrices and so on. +This section contains support information for ``cloud-init``. +It includes details on the configuration formats, CLI commands +support matrices and so on. ----- .. toctree:: :maxdepth: 1 - modules.rst - examples.rst - examples_library.rst - cli.rst - availability.rst - faq.rst - merging.rst - datasources.rst - network-config.rst - base_config_reference.rst - datasource_dsname_map.rst - performance_analysis.rst - ubuntu_stable_release_updates.rst - breaking_changes.rst - user_files.rst - custom_modules.rst + Cloud-config + CLI + Logs + Datasources + Advanced customization diff --git a/doc/rtd/reference/merging.rst b/doc/rtd/reference/merging.rst index 11ae99db639..21240582f9a 100644 --- a/doc/rtd/reference/merging.rst +++ b/doc/rtd/reference/merging.rst @@ -1,9 +1,9 @@ .. _merging_user_data: -Merging user-data sections -************************** +Merging cloud-config +******************** -The ability to merge user-data sections allows a way to specify how +The ability to merge cloud-config allows a way to specify how cloud-config YAML "dictionaries" provided as user-data are handled when there are multiple YAML files to be merged together (e.g., when performing an #include). diff --git a/doc/rtd/howto/module_run_frequency.rst b/doc/rtd/reference/module_run_frequency.rst similarity index 100% rename from doc/rtd/howto/module_run_frequency.rst rename to doc/rtd/reference/module_run_frequency.rst diff --git a/doc/rtd/reference/network-config.rst b/doc/rtd/reference/network-config.rst index 5406f735465..37d9211a9fb 100644 --- a/doc/rtd/reference/network-config.rst +++ b/doc/rtd/reference/network-config.rst @@ -16,12 +16,6 @@ precedence; each item overriding the previous. - **Kernel command line**: ``ip=`` or ``network-config=`` -Cloud-init will write out the following files representing the network-config -processed: - -- :file:`/run/cloud-init/network-config.json`: world-readable JSON containing - the selected source network-config JSON used by cloud-init network renderers. - User-data cannot change an instance's network configuration. In the absence of network configuration in any of the above sources, ``cloud-init`` will write out a network configuration that will issue a DHCP request on a "first" @@ -39,7 +33,7 @@ Disabling network configuration Users may disable ``cloud-init``'s network configuration capability and rely on other methods, such as embedded configuration or other customisations. -``cloud-init`` supports the following methods for disabling ``cloud-init``. +``cloud-init`` supports the following methods for disabling networking. Kernel command line ------------------- diff --git a/doc/rtd/reference/performance_analysis.rst b/doc/rtd/reference/performance_analysis.rst deleted file mode 100644 index 8c76e5c8df0..00000000000 --- a/doc/rtd/reference/performance_analysis.rst +++ /dev/null @@ -1,110 +0,0 @@ -.. _performance: - -Performance analysis -******************** - -Occasionally, instances don't perform as well as expected, and so we provide -a simple tool to inspect which operations took the longest during boot and -setup. - -.. _boot_time_analysis: - -:command:`cloud-init analyze` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The `cloud-init` command has an analysis sub-command, :command:`analyze`, which -parses any :file:`cloud-init.log` file into formatted and sorted events. This -analysis reveals the most costly cloud-init operations and which configuration -options are responsible. These subcommands default to reading -:file:`/var/log/cloud-init.log`. - -:command:`analyze show` -^^^^^^^^^^^^^^^^^^^^^^^ - -Parse and organize :file:`cloud-init.log` events by stage and include each -sub-stage granularity with time delta reports. - -.. code-block:: shell-session - - $ cloud-init analyze show -i my-cloud-init.log - -Example output: - -.. code-block:: shell-session - - -- Boot Record 01 -- - The total time elapsed since completing an event is printed after the "@" - character. - The time the event takes is printed after the "+" character. - - Starting stage: modules-config - |`->config-snap_config ran successfully @05.47700s +00.00100s - |`->config-ssh-import-id ran successfully @05.47800s +00.00200s - |`->config-locale ran successfully @05.48000s +00.00100s - ... - - -:command:`analyze dump` -^^^^^^^^^^^^^^^^^^^^^^^ - -Parse :file:`cloud-init.log` into event records and return a list of -dictionaries that can be consumed for other reporting needs. - -.. code-block:: shell-session - - $ cloud-init analyze dump -i my-cloud-init.log - -Example output: - -.. code-block:: - - [ - { - "description": "running config modules", - "event_type": "start", - "name": "modules-config", - "origin": "cloudinit", - "timestamp": 1510807493.0 - },... - -:command:`analyze blame` -^^^^^^^^^^^^^^^^^^^^^^^^ - -Parse :file:`cloud-init.log` into event records and sort them based on the -highest time cost for a quick assessment of areas of cloud-init that may -need improvement. - -.. code-block:: shell-session - - $ cloud-init analyze blame -i my-cloud-init.log - -Example output: - -.. code-block:: - - -- Boot Record 11 -- - 00.01300s (modules-final/config-scripts-per-boot) - 00.00400s (modules-final/config-final-message) - ... - -:command:`analyze boot` -^^^^^^^^^^^^^^^^^^^^^^^ - -Make subprocess calls to the kernel in order to get relevant pre-cloud-init -timestamps, such as the kernel start, kernel finish boot, and cloud-init -start. - -.. code-block:: shell-session - - $ cloud-init analyze boot - -Example output: - -.. code-block:: - - -- Most Recent Boot Record -- - Kernel Started at: 2019-06-13 15:59:55.809385 - Kernel ended boot at: 2019-06-13 16:00:00.944740 - Kernel time to boot (seconds): 5.135355 - Cloud-init start: 2019-06-13 16:00:05.738396 - Time between Kernel boot and Cloud-init start (seconds): 4.793656 diff --git a/doc/rtd/howto/test_unreleased_packages.rst b/doc/rtd/reference/test_unreleased_packages.rst similarity index 100% rename from doc/rtd/howto/test_unreleased_packages.rst rename to doc/rtd/reference/test_unreleased_packages.rst diff --git a/doc/rtd/reference/user_files.rst b/doc/rtd/reference/user_files.rst index 38b2b800c14..ab1b951f9d4 100644 --- a/doc/rtd/reference/user_files.rst +++ b/doc/rtd/reference/user_files.rst @@ -1,68 +1,19 @@ .. _user_files: -Log and configuration files -********************************* - -Cloud-init uses the filesystem to read inputs and write outputs. These files -are configuration and log files, respectively. If other methods of -:ref:`debugging cloud-init` fail, then digging into log files is -your next step in debugging. +Log files +********* .. _log_files: -Cloud-init log files -==================== - -Cloud-init's early boot logic runs before system loggers are available -or filesystems are mounted. Runtime logs and early boot logs have different -locations. - -Runtime logs ------------- - -While booting, ``cloud-init`` logs to two different files: - - -- :file:`/var/log/cloud-init-output.log`: - Captures the output from each stage of ``cloud-init`` when it runs. -- :file:`/var/log/cloud-init.log`: - Very detailed log with debugging output, describing each action taken. - -Be aware that each time a system boots, new logs are appended to the files in -:file:`/var/log`. Therefore, the files may contain information from more -than one boot. - -When reviewing these logs, look for errors or Python tracebacks. - -Early boot logs ---------------- - -Prior to initialization, ``cloud-init`` runs early detection and -enablement / disablement logic. - -- :file:`/run/cloud-init/cloud-init-generator.log`: - On systemd systems, this log file describes early boot enablement of - cloud-init via the systemd generator. These logs are most useful if trying - to figure out why cloud-init did not run. -- :file:`/run/cloud-init/ds-identify.log`: - Contains logs about platform / datasource detection. These logs are most - useful if cloud-init did not identify the correct datasource (cloud) to run - on. - - - -.. _configuration_files: - -Configuration files -=================== - -``Cloud-init`` configuration files are provided in two places: - -- :file:`/etc/cloud/cloud.cfg` -- :file:`/etc/cloud/cloud.cfg.d/*.cfg` +``cloud-init`` logs to multiple files: -These files can define the modules that run during instance initialization, -the datasources to evaluate on boot, as well as other settings. +- :file:`/run/cloud-init/cloud-init-generator.log`: Early boot; useful to + understand why cloud-init didn't run. +- :file:`/run/cloud-init/ds-identify.log`: Early boot; useful to understand + why cloud-init didn't run or why it detected an unexpected platform. +- :file:`/var/log/cloud-init.log`: The primary log file. Verbose, but useful. +- :file:`/var/log/cloud-init-output.log`: Captures the output from each stage. + Output from user scripts goes here. -See the :ref:`configuration sources explanation` and -:ref:`configuration reference` pages for more details. +Logs are appended to the files in :file:`/var/log`: files may contain logs +from multiple boots. From 090026a3d9a4ddda2d309c6f5be81a0dc30116f5 Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Fri, 6 Feb 2026 09:52:56 -0700 Subject: [PATCH 5/9] fix: do not write meson version twice in version.py (#6729) --- cloudinit/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudinit/version.py b/cloudinit/version.py index 90d499d6344..7ae21f481d7 100644 --- a/cloudinit/version.py +++ b/cloudinit/version.py @@ -24,6 +24,6 @@ def version_string(): """Extract a version string from cloud-init.""" - if _DOWNSTREAM_VERSION != "@DOWNSTREAM_VERSION@": + if "DOWNSTREAM_VERSION" not in _DOWNSTREAM_VERSION: return _DOWNSTREAM_VERSION return __VERSION__ From 6ede1e075d20e9f0fb4e96663932b0d898b62d09 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Sat, 7 Feb 2026 15:43:23 -0700 Subject: [PATCH 6/9] update changelog (new upstream snapshot) --- debian/changelog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index d5a83f093eb..8dc5d4ad4a8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,8 +10,9 @@ cloud-init (25.3-0ubuntu1~24.04.2) UNRELEASED; urgency=medium * d/p/0001-Revert-fix-support-bond-names-in-network_data.patch revert bond name change * d/rules: replace DOWNSTREAM_VERSION with packaged DEB_VERSION value * Upstream snapshot based on upstream/main at 72809f80. + * Upstream snapshot based on upstream/main at 090026a3. - -- Brett Holman Thu, 05 Feb 2026 16:23:52 +0000 + -- Chad Smith Sat, 07 Feb 2026 15:43:23 -0700 cloud-init (25.3-0ubuntu1~24.04.1) noble; urgency=medium From 84e702e794da5209b39eae1330b6197ef96d2ad9 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Sat, 7 Feb 2026 15:43:50 -0700 Subject: [PATCH 7/9] d/rules: export DEB_VERSION and PACKAGED_VERSION --- debian/rules | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/rules b/debian/rules index b13e7a8feda..0b39bc6162c 100755 --- a/debian/rules +++ b/debian/rules @@ -4,6 +4,7 @@ include /usr/share/dpkg/pkg-info.mk INIT_SYSTEM ?= systemd export PYBUILD_INSTALL_ARGS=--init-system=$(INIT_SYSTEM) +export PACKAGED_VERSION=$(DEB_VERSION) %: dh $@ --with python3 --buildsystem pybuild From 9ffe39365efa2a1ba4316728f37224b215568129 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Sat, 7 Feb 2026 15:46:47 -0700 Subject: [PATCH 8/9] d/p/retain-setuptools: drop read-version use PACKAGED_VERSION env var --- debian/patches/retain-setuptools.patch | 165 +------------------------ 1 file changed, 4 insertions(+), 161 deletions(-) diff --git a/debian/patches/retain-setuptools.patch b/debian/patches/retain-setuptools.patch index 79afa66b414..acffcff93a5 100644 --- a/debian/patches/retain-setuptools.patch +++ b/debian/patches/retain-setuptools.patch @@ -364,7 +364,7 @@ Last-Update: 2025-08-25 +) --- /dev/null +++ b/setup_utils.py -@@ -0,0 +1,60 @@ +@@ -0,0 +1,59 @@ +import os +import subprocess +import sys @@ -411,13 +411,12 @@ Last-Update: 2025-08-25 + # read-version can spit out something like 22.4-15-g7f97aee24 + # which is invalid under PEP 440. If we replace the first - with a + + # that should give us a valid version. -+ return version.replace("-", "+", 1) ++ return version.strip("_").split("-")[0] + + +def get_version() -> str: -+ cmd = [sys.executable, "tools/read-version"] -+ ver = subprocess.check_output(cmd) # B603 -+ version = ver.decode("utf-8").strip() ++ ver = os.environ.get("PACKAGED_VERSION", "MISSING_ENVVAR_PACKAGED_VERSION") ++ version = ver.strip() + return version_to_pep440(version) + + @@ -438,159 +437,3 @@ Last-Update: 2025-08-25 passlib # This one is currently used only by the CloudSigma and SmartOS datasources. ---- /dev/null -+++ b/tools/read-version -@@ -0,0 +1,153 @@ -+#!/usr/bin/env python3 -+ -+# This script has tests. Run pytest on the tools directory if you make changes -+ -+import json -+import os -+import re -+import subprocess -+import sys -+from shutil import which -+ -+repo_base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) -+sys.path.insert(0, repo_base_dir) -+ -+from cloudinit import version as ci_version # noqa: E402 -+ -+ -+def tiny_p(cmd): -+ stderr = subprocess.PIPE -+ return subprocess.check_output( -+ cmd, stderr=stderr, stdin=None, universal_newlines=True -+ ) -+ -+ -+def is_gitdir(path): -+ # Return boolean indicating if path is a git tree. -+ git_meta = os.path.join(path, ".git") -+ if os.path.isdir(git_meta): -+ return True -+ if os.path.exists(git_meta): -+ # in a git worktree, .git is a file with 'gitdir: x' -+ with open(git_meta, "rb") as fp: -+ if b"gitdir:" in fp.read(): -+ return True -+ return False -+ -+ -+def get_version_details(version, version_long, is_release_branch_ci): -+ release = None -+ extra = None -+ commit = None -+ distance = None -+ -+ # Should match upstream version number. E.g., 23.1 or 23.1.2 -+ short_regex = r"(\d+\.\d+\.?\d*)" -+ # Should match version including upstream version, distance, and commit -+ # E.g., 23.1.2-10-g12ab34cd -+ long_regex = r"(\d+\.\d+\.?\d*){1}.*-(\d+)+-g([a-f0-9]{8}){1}.*" -+ -+ short_match = re.search(short_regex, version) -+ long_match = re.search(long_regex, version_long) -+ if long_match: -+ release, distance, commit = long_match.groups() -+ extra = f"-{distance}-g{commit}" -+ elif short_match: -+ release = short_match.groups()[0] -+ -+ return { -+ "release": release, -+ "version": version, -+ "version_long": version_long, -+ "extra": extra, -+ "commit": commit, -+ "distance": distance, -+ "is_release_branch_ci": is_release_branch_ci, -+ } -+ -+ -+def get_version_from_git( -+ src_version, major_minor_version, use_tags, is_release_branch_ci -+): -+ if is_gitdir(repo_base_dir) and which("git") and not is_release_branch_ci: -+ branch_name = tiny_p( -+ ["git", "rev-parse", "--abbrev-ref", "HEAD"] -+ ).strip() -+ if branch_name.startswith(f"upstream/{major_minor_version}"): -+ version = src_version -+ version_long = "" -+ else: -+ flags = ["--tags"] if use_tags else [] -+ cmd = [ -+ "git", -+ "describe", -+ branch_name, -+ "--abbrev=8", -+ ] + flags -+ -+ try: -+ version = tiny_p(cmd).strip() -+ version_long = tiny_p(cmd + ["--long"]).strip() -+ except subprocess.CalledProcessError as e: -+ if not any( -+ [ -+ "No tags can describe" in e.stderr, -+ "cannot describe anything" in e.stderr, -+ ] -+ ): -+ raise -+ version = src_version -+ version_long = "" -+ else: -+ version = src_version -+ version_long = "" -+ return version, version_long -+ -+ -+def main(use_tags: bool = False, output_json: bool = False): -+ src_version = ci_version.version_string() -+ # upstream/MM.NN.x tracks our patch level releases so ignore trailing '.x' -+ major_minor_version = ".".join(src_version.split(".")[:2]) -+ -+ # If we're performing CI for a new release branch (which our tooling -+ # creates with an "upstream/" prefix), then we don't want to enforce -+ # strict version matching because we know it will fail. -+ github_ci_release_br = bool( -+ os.environ.get("GITHUB_HEAD_REF", "").startswith( -+ f"upstream/{major_minor_version}" -+ ) -+ ) -+ travis_ci_release_br = bool( -+ os.environ.get("TRAVIS_PULL_REQUEST_BRANCH", "").startswith( -+ "upstream/" -+ ) -+ ) -+ is_release_branch_ci = github_ci_release_br or travis_ci_release_br -+ -+ version, version_long = get_version_from_git( -+ src_version=src_version, -+ major_minor_version=major_minor_version, -+ use_tags=use_tags, -+ is_release_branch_ci=is_release_branch_ci, -+ ) -+ -+ details = get_version_details(version, version_long, is_release_branch_ci) -+ -+ if output_json: -+ return json.dumps(details, indent=1) -+ -+ output = "" -+ if details["release"]: -+ output += details["release"] -+ if details["extra"]: -+ output += details["extra"] -+ if not output: -+ output = src_version -+ return output -+ -+ -+if __name__ == "__main__": -+ arg_use_tags = "--tags" in sys.argv or bool(os.environ.get("CI_RV_TAGS")) -+ arg_output_json = "--json" in sys.argv -+ output = main(arg_use_tags, arg_output_json) -+ print(output) From e62e8888ad26cc4f68c8e1219c54fbab6fa13a21 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Sat, 7 Feb 2026 15:49:12 -0700 Subject: [PATCH 9/9] update changelog --- debian/changelog | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/debian/changelog b/debian/changelog index 8dc5d4ad4a8..ccd7905b348 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,15 +1,14 @@ cloud-init (25.3-0ubuntu1~24.04.2) UNRELEASED; urgency=medium + * d/rules: replace DOWNSTREAM_VERSION with packaged DEB_VERSION value + * d/p/0001-Revert-fix-DNS-resolution-performance-regression-dur.patch revert Ec2 URL change + * d/p/0001-Revert-fix-support-bond-names-in-network_data.patch revert bond name change * refresh patches: - d/p/no-nocloud-network.patch - d/p/no-single-process.patch - d/p/grub-dpkg-support.patch - - d/p/retain-setuptools.patch. Include read-version, drop unsupported dev + - d/p/retain-setuptools.patch. Use PACKAGED_VERSION environment variable. build tools and tests. - * d/p/0001-Revert-fix-DNS-resolution-performance-regression-dur.patch revert Ec2 URL change - * d/p/0001-Revert-fix-support-bond-names-in-network_data.patch revert bond name change - * d/rules: replace DOWNSTREAM_VERSION with packaged DEB_VERSION value - * Upstream snapshot based on upstream/main at 72809f80. * Upstream snapshot based on upstream/main at 090026a3. -- Chad Smith Sat, 07 Feb 2026 15:43:23 -0700