about summary refs log tree commit diff
path: root/pkgs/tools/admin/azure-cli
diff options
context:
space:
mode:
authorPaul Meyer <49727155+katexochen@users.noreply.github.com>2023-12-14 22:17:46 +0100
committerPaul Meyer <49727155+katexochen@users.noreply.github.com>2024-03-02 17:03:59 +0100
commitb34ca295cb18cac7b853883cda21e516070213df (patch)
treeebaeb0ae78c005839caa8d8ac233b5509c9b989f /pkgs/tools/admin/azure-cli
parent92682867ac34c886b1e30301ae793e9349dc8250 (diff)
azure-cli: immutable command index
Diffstat (limited to 'pkgs/tools/admin/azure-cli')
-rw-r--r--pkgs/tools/admin/azure-cli/0001-optional-immutable-configuration-dir.patch98
-rw-r--r--pkgs/tools/admin/azure-cli/default.nix20
-rw-r--r--pkgs/tools/admin/azure-cli/python-packages.nix13
3 files changed, 127 insertions, 4 deletions
diff --git a/pkgs/tools/admin/azure-cli/0001-optional-immutable-configuration-dir.patch b/pkgs/tools/admin/azure-cli/0001-optional-immutable-configuration-dir.patch
new file mode 100644
index 0000000000000..e163915d1c724
--- /dev/null
+++ b/pkgs/tools/admin/azure-cli/0001-optional-immutable-configuration-dir.patch
@@ -0,0 +1,98 @@
+From c12adfdefd8a091e1fa870305a3cc61de6426914 Mon Sep 17 00:00:00 2001
+From: Paul Meyer <49727155+katexochen@users.noreply.github.com>
+Date: Thu, 14 Dec 2023 21:16:20 +0100
+Subject: [PATCH] optional immutable configuration dir
+
+Adding the possibility to configure an immutable configuration dir via
+env variable `AZURE_IMMUTABLE_DIR`. This path is used for the files
+that configure the dynamic behavior of the CLI code.
+An immutable session is used for these files to ensure we don't try to
+write to them.
+
+Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
+---
+ azure/cli/core/__init__.py |  5 +++--
+ azure/cli/core/_session.py | 19 ++++++++++++++++---
+ .../cli/core/extension/dynamic_install.py     |  3 ++-
+ 3 files changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/azure/cli/core/__init__.py b/azure/cli/core/__init__.py
+index d112633ec..20b6d045b 100644
+--- a/azure/cli/core/__init__.py
++++ b/azure/cli/core/__init__.py
+@@ -75,12 +75,13 @@ class AzCli(CLI):
+         self.data['query_active'] = False
+
+         azure_folder = self.config.config_dir
++        azure_immutable_folder = os.environ.get('AZURE_IMMUTABLE_DIR', azure_folder)
+         ensure_dir(azure_folder)
+         ACCOUNT.load(os.path.join(azure_folder, 'azureProfile.json'))
+         CONFIG.load(os.path.join(azure_folder, 'az.json'))
+         SESSION.load(os.path.join(azure_folder, 'az.sess'), max_age=3600)
+-        INDEX.load(os.path.join(azure_folder, 'commandIndex.json'))
+-        VERSIONS.load(os.path.join(azure_folder, 'versionCheck.json'))
++        INDEX.load(os.path.join(azure_immutable_folder, 'commandIndex.json'))
++        VERSIONS.load(os.path.join(azure_immutable_folder, 'versionCheck.json'))
+         handle_version_update()
+
+         self.cloud = get_active_cloud(self)
+diff --git a/azure/cli/core/_session.py b/azure/cli/core/_session.py
+index 471a0344c..acaef6fb8 100644
+--- a/azure/cli/core/_session.py
++++ b/azure/cli/core/_session.py
+@@ -85,6 +85,19 @@ class Session(MutableMapping):
+         return len(self.data)
+
+
++class ImmutableSession(Session):
++    """
++    A session that is backed by an immutable JSON file. This session is read-only.
++    """
++    def save(self):
++        if os.getenv('AZURE_IMMUTABLE_DIR'):
++            get_logger(__name__).log(logging.DEBUG,
++                                     "Skipping update of file %s due to immutable directory.",
++                                     self.filename)
++            return
++        super().save()
++
++
+ # ACCOUNT contains subscriptions information
+ ACCOUNT = Session()
+
+@@ -95,16 +108,16 @@ CONFIG = Session()
+ SESSION = Session()
+
+ # INDEX contains {top-level command: [command_modules and extensions]} mapping index
+-INDEX = Session()
++INDEX = ImmutableSession()
+
+ # VERSIONS provides local versions and pypi versions.
+ # DO NOT USE it to get the current version of azure-cli,
+ # it could be lagged behind and can be used to check whether
+ # an upgrade of azure-cli happens
+-VERSIONS = Session()
++VERSIONS = ImmutableSession()
+
+ # EXT_CMD_TREE provides command to extension name mapping
+-EXT_CMD_TREE = Session()
++EXT_CMD_TREE = ImmutableSession()
+
+ # CLOUD_ENDPOINTS provides endpoints/suffixes of clouds
+ CLOUD_ENDPOINTS = Session()
+diff --git a/azure/cli/core/extension/dynamic_install.py b/azure/cli/core/extension/dynamic_install.py
+index cb03980a0..29279be2b 100644
+--- a/azure/cli/core/extension/dynamic_install.py
++++ b/azure/cli/core/extension/dynamic_install.py
+@@ -17,7 +17,8 @@ def _get_extension_command_tree(cli_ctx):
+     VALID_SECOND = 3600 * 24 * 10
+     if not cli_ctx:
+         return None
+-    EXT_CMD_TREE.load(os.path.join(cli_ctx.config.config_dir, 'extensionCommandTree.json'), VALID_SECOND)
++    azure_immutable_folder = os.environ.get('AZURE_IMMUTABLE_DIR', cli_ctx.config.config_dir)
++    EXT_CMD_TREE.load(os.path.join(azure_immutable_folder, 'extensionCommandTree.json'), VALID_SECOND)
+     if not EXT_CMD_TREE.data:
+         import posixpath
+         import requests
+--
+2.42.0
diff --git a/pkgs/tools/admin/azure-cli/default.nix b/pkgs/tools/admin/azure-cli/default.nix
index 71c478d612169..6c540df765402 100644
--- a/pkgs/tools/admin/azure-cli/default.nix
+++ b/pkgs/tools/admin/azure-cli/default.nix
@@ -2,6 +2,10 @@
 , callPackage
 , fetchFromGitHub
 , installShellFiles
+
+  # Whether to include patches that enable placing certain behavior-defining
+  # configuration files in the Nix store.
+, withImmutableConfig ? true
 }:
 
 let
@@ -177,7 +181,13 @@ py.pkgs.toPythonApplication (py.pkgs.buildAzureCliPackage {
       --replace register-python-argcomplete ${py.pkgs.argcomplete}/bin/register-python-argcomplete
     installShellCompletion --bash --name az.bash az.completion.sh
     installShellCompletion --zsh --name _az az.completion.sh
-
+  '' + lib.optionalString withImmutableConfig ''
+    export HOME=$TMPDIR
+    $out/bin/az --version
+    mkdir -p $out/etc/azure
+    mv $TMPDIR/.azure/commandIndex.json $out/etc/azure/commandIndex.json
+    mv $TMPDIR/.azure/versionCheck.json $out/etc/azure/versionCheck.json
+  '' + ''
     # remove garbage
     rm $out/bin/az.bat
     rm $out/bin/az.completion.sh
@@ -187,8 +197,12 @@ py.pkgs.toPythonApplication (py.pkgs.buildAzureCliPackage {
   # it's just a shebang script which calls `python -m azure.cli "$@"`
   postFixup = ''
     wrapProgram $out/bin/az \
-      --set PYTHONPATH $PYTHONPATH
-  '';
+  '' + lib.optionalString withImmutableConfig ''
+    --set AZURE_IMMUTABLE_DIR $out/etc/azure \
+  '' + ''
+    --set PYTHONPATH $PYTHONPATH
+  ''
+  ;
 
   doInstallCheck = true;
   installCheckPhase = ''
diff --git a/pkgs/tools/admin/azure-cli/python-packages.nix b/pkgs/tools/admin/azure-cli/python-packages.nix
index 3714c5bec0208..318b5044a8e34 100644
--- a/pkgs/tools/admin/azure-cli/python-packages.nix
+++ b/pkgs/tools/admin/azure-cli/python-packages.nix
@@ -1,4 +1,5 @@
-{ stdenv
+{ lib
+, stdenv
 , python3
 , fetchPypi
 , fetchpatch
@@ -30,6 +31,16 @@ let
 
         sourceRoot = "${src.name}/src/azure-cli-core";
 
+        patches = [
+          # Adding the possibility to configure an immutable configuration dir via `AZURE_IMMUTABLE_DIR`.
+          # This enables us to place configuration files that alter the behavior of the CLI in the Nix store.
+          #
+          # This is a downstream patch without an commit or PR upstream.
+          # There is an issue to discuss possible solutions upstream:
+          # https://github.com/Azure/azure-cli/issues/28093
+          ./0001-optional-immutable-configuration-dir.patch
+        ];
+
         propagatedBuildInputs = with self; [
           argcomplete
           azure-cli-telemetry