diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d78f4dfce..b08d50cfa 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -61,10 +61,11 @@ jobs: path: - . - ./tests/integration/relations/opensearch_provider/application-charm/ - uses: canonical/data-platform-workflows/.github/workflows/build_charm.yaml@v22.0.0 + uses: canonical/data-platform-workflows/.github/workflows/build_charm.yaml@lucas/fix-collect-bases with: path-to-charm-directory: ${{ matrix.path }} - cache: true + cache: false + charmcraft-snap-revision: 5303 integration-test: strategy: diff --git a/.github/workflows/clone-pr.yaml b/.github/workflows/clone-pr.yaml new file mode 100644 index 000000000..0cc7d6847 --- /dev/null +++ b/.github/workflows/clone-pr.yaml @@ -0,0 +1,50 @@ +name: Clone PR to test 24.04 base + +on: + pull_request: + types: + - opened + - synchronize + +jobs: + clone-pr: + if: "!startsWith(github.event.pull_request.head.ref, '24.04-cloned')" # Skip if branch starts with "24.04-cloned" + runs-on: ubuntu-latest + + steps: + - name: Checkout PR code + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git + + - name: Install tox + run: | + pipx install tox + + - name: Run switch to 24.04 + run: | + tox run -e switch-24.04 + + - name: Create and push to a new branch + run: | + NEW_BRANCH="24.04-cloned-${{ github.event.pull_request.number }}" + git checkout -b $NEW_BRANCH + git add . + git commit -m "switch to 24.04" + git push origin $NEW_BRANCH + + - name: Create a pull request + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + BASE_BRANCH="${{ github.event.pull_request.base.ref }}" + NEW_BRANCH="24.04-cloned-${{ github.event.pull_request.number }}" + PR_TITLE="Automated PR: 24.04 Changes from ${NEW_BRANCH}" + PR_BODY="This pull request was created automatically. Will test 24.04 base on the charm." + gh pr create --title "$PR_TITLE" --body "$PR_BODY" --head "$NEW_BRANCH" --base "$BASE_BRANCH" --repo "${{ github.repository }}" diff --git a/charmcraft-24.04.patch b/charmcraft-24.04.patch new file mode 100644 index 000000000..99d791209 --- /dev/null +++ b/charmcraft-24.04.patch @@ -0,0 +1,9 @@ +@@ -2,7 +2,7 @@ + # See LICENSE file for licensing details. + + type: charm +-base: ubuntu@24.04 ++base: ubuntu@22.04 + platforms: + amd64: + parts: diff --git a/charmcraft.yaml b/charmcraft.yaml index eb494f4f2..23258f0ef 100644 --- a/charmcraft.yaml +++ b/charmcraft.yaml @@ -2,13 +2,9 @@ # See LICENSE file for licensing details. type: charm -bases: - - build-on: - - name: "ubuntu" - channel: "22.04" - run-on: - - name: "ubuntu" - channel: "22.04" +base: ubuntu@24.04 +platforms: + amd64: parts: files: plugin: dump diff --git a/lib/charms/opensearch/v0/constants_charm.py b/lib/charms/opensearch/v0/constants_charm.py index 1b75ed268..d93479a12 100644 --- a/lib/charms/opensearch/v0/constants_charm.py +++ b/lib/charms/opensearch/v0/constants_charm.py @@ -114,7 +114,7 @@ # Opensearch Snap revision -OPENSEARCH_SNAP_REVISION = 58 # Keep in sync with `workload_version` file +OPENSEARCH_SNAP_REVISION = 62 # Keep in sync with `workload_version` file # User-face Backup ID format OPENSEARCH_BACKUP_ID_FORMAT = "%Y-%m-%dT%H:%M:%SZ" diff --git a/lib/charms/opensearch/v0/opensearch_distro.py b/lib/charms/opensearch/v0/opensearch_distro.py index 7eb4e79e3..3b161d60b 100644 --- a/lib/charms/opensearch/v0/opensearch_distro.py +++ b/lib/charms/opensearch/v0/opensearch_distro.py @@ -197,15 +197,15 @@ def is_node_up(self, host: Optional[str] = None) -> bool: return False def run_bin(self, bin_script_name: str, args: str = None, stdin: str = None) -> str: - """Run opensearch provided bin command, relative to OPENSEARCH_BIN. + """Run opensearch provided bin command, through the snap. Args: bin_script_name: opensearch script located in OPENSEARCH_BIN to be executed args: arguments passed to the script stdin: string input to be passed on the standard input of the subprocess. """ - script_path = f"{self.paths.bin}/{bin_script_name}" - return self._run_cmd(script_path, args, stdin=stdin) + opensearch_command = f"opensearch.{bin_script_name}" + return self._run_cmd(opensearch_command, args, stdin=stdin) def run_script(self, script_name: str, args: str = None): """Run script provided by Opensearch in another directory, relative to OPENSEARCH_HOME.""" diff --git a/lib/charms/opensearch/v0/opensearch_keystore.py b/lib/charms/opensearch/v0/opensearch_keystore.py index 1deaeb6fd..0be480a86 100644 --- a/lib/charms/opensearch/v0/opensearch_keystore.py +++ b/lib/charms/opensearch/v0/opensearch_keystore.py @@ -41,7 +41,7 @@ def __init__(self, charm): """Creates the keystore manager class.""" self._charm = charm self._opensearch = charm.opensearch - self._keytool = charm.opensearch.paths.jdk + "/bin/keytool" + self._keytool = "opensearch.keytool" self._keystore = "" self._password = None @@ -132,7 +132,7 @@ class OpenSearchKeystore(Keystore): def __init__(self, charm): """Creates the keystore manager class.""" super().__init__(charm) - self._keytool = "opensearch-keystore" + self._keytool = "keystore" def add(self, entries: Dict[str, str]) -> None: """Adds a given key to the "opensearch" keystore.""" diff --git a/lib/charms/opensearch/v0/opensearch_plugin_manager.py b/lib/charms/opensearch/v0/opensearch_plugin_manager.py index 97171c694..0283cd6b4 100644 --- a/lib/charms/opensearch/v0/opensearch_plugin_manager.py +++ b/lib/charms/opensearch/v0/opensearch_plugin_manager.py @@ -221,7 +221,7 @@ def _install_plugin(self, plugin: OpenSearchPlugin) -> bool: if missing_deps: raise OpenSearchPluginMissingDepsError(plugin.name, missing_deps) - self._opensearch.run_bin("opensearch-plugin", f"install --batch {plugin.name}") + self._opensearch.run_bin("plugin", f"install --batch {plugin.name}") except KeyError as e: raise OpenSearchPluginMissingConfigError(e) except OpenSearchCmdError as e: @@ -418,7 +418,7 @@ def _remove_if_needed(self, plugin: OpenSearchPlugin) -> bool: def _remove_plugin(self, plugin: OpenSearchPlugin) -> bool: """Remove a plugin without restarting the node.""" try: - self._opensearch.run_bin("opensearch-plugin", f"remove {plugin.name}") + self._opensearch.run_bin("plugin", f"remove {plugin.name}") except OpenSearchCmdError as e: if "not found" in str(e): logger.info(f"Plugin {plugin.name} to be deleted, not found. Continuing...") @@ -429,6 +429,6 @@ def _remove_plugin(self, plugin: OpenSearchPlugin) -> bool: def _installed_plugins(self) -> List[str]: """List plugins.""" try: - return self._opensearch.run_bin("opensearch-plugin", "list").split("\n") + return self._opensearch.run_bin("plugin", "list").split("\n") except OpenSearchCmdError as e: raise OpenSearchPluginError("Failed to list plugins: " + str(e)) diff --git a/lib/charms/opensearch/v0/opensearch_tls.py b/lib/charms/opensearch/v0/opensearch_tls.py index 846a14dd0..6c6b04ed0 100644 --- a/lib/charms/opensearch/v0/opensearch_tls.py +++ b/lib/charms/opensearch/v0/opensearch_tls.py @@ -79,7 +79,7 @@ def __init__( self.peer_relation = peer_relation self.jdk_path = jdk_path self.certs_path = certs_path - self.keytool = self.jdk_path + "/bin/keytool" + self.keytool = "opensearch.keytool" self.certs = TLSCertificatesRequiresV3(charm, TLS_RELATION, expiry_notification_time=23) self.framework.observe( @@ -499,8 +499,6 @@ def _create_keystore_pwd_if_not_exists(self, scope: Scope, cert_type: CertType, def store_new_ca(self, secrets: Dict[str, Any]) -> bool: # noqa: C901 """Add new CA cert to trust store.""" - keytool = f"sudo {self.jdk_path}/bin/keytool" - if not (deployment_desc := self.charm.opensearch_peer_cm.deployment_desc()): return False @@ -518,7 +516,7 @@ def store_new_ca(self, secrets: Dict[str, Any]) -> bool: # noqa: C901 try: run_cmd( - f"""{keytool} -changealias \ + f"""{self.keytool} -changealias \ -alias {alias} \ -destalias old-{alias} \ -keystore {store_path} \ @@ -535,13 +533,15 @@ def store_new_ca(self, secrets: Dict[str, Any]) -> bool: # noqa: C901 ): raise - with tempfile.NamedTemporaryFile(mode="w+t") as ca_tmp_file: + with tempfile.NamedTemporaryFile( + mode="w+t", dir=self.charm.opensearch.paths.tmp + ) as ca_tmp_file: ca_tmp_file.write(secrets.get("ca-cert")) ca_tmp_file.flush() try: run_cmd( - f"""{keytool} -importcert \ + f"""{self.keytool} -importcert \ -trustcacerts \ -noprompt \ -alias {alias} \ @@ -590,7 +590,6 @@ def read_stored_ca(self, alias: str = "ca") -> Optional[str]: def remove_old_ca(self) -> None: """Remove old CA cert from trust store.""" - keytool = f"sudo {self.jdk_path}/bin/keytool" ca_trust_store = f"{self.certs_path}/ca.p12" old_alias = "old-ca" @@ -599,7 +598,7 @@ def remove_old_ca(self) -> None: try: run_cmd( - f"""{keytool} \ + f"""{self.keytool} \ -list \ -keystore {ca_trust_store} \ -storepass {store_pwd} \ @@ -614,7 +613,7 @@ def remove_old_ca(self) -> None: old_ca_content = self.read_stored_ca(alias=old_alias) run_cmd( - f"""{keytool} \ + f"""{self.keytool} \ -delete \ -keystore {ca_trust_store} \ -storepass {store_pwd} \ @@ -658,12 +657,16 @@ def store_new_tls_resources(self, cert_type: CertType, secrets: Dict[str, Any]): except OSError: pass - tmp_key = tempfile.NamedTemporaryFile(mode="w+t", suffix=".pem") + tmp_key = tempfile.NamedTemporaryFile( + mode="w+t", suffix=".pem", dir=self.charm.opensearch.paths.tmp + ) tmp_key.write(secrets.get("key")) tmp_key.flush() tmp_key.seek(0) - tmp_cert = tempfile.NamedTemporaryFile(mode="w+t", suffix=".cert") + tmp_cert = tempfile.NamedTemporaryFile( + mode="w+t", suffix=".cert", dir=self.charm.opensearch.paths.tmp + ) tmp_cert.write(secrets.get("cert")) tmp_cert.flush() tmp_cert.seek(0) @@ -700,7 +703,7 @@ def all_tls_resources_stored(self, only_unit_resources: bool = False) -> bool: return False # to make sure the content is processed correctly by openssl, temporary store it in a file - tmp_ca_file = tempfile.NamedTemporaryFile(mode="w+t") + tmp_ca_file = tempfile.NamedTemporaryFile(mode="w+t", dir=self.charm.opensearch.paths.tmp) tmp_ca_file.write(current_ca) tmp_ca_file.flush() tmp_ca_file.seek(0) @@ -805,12 +808,12 @@ def reload_tls_certificates(self): # using the SSL API requires authentication with app-admin cert and key admin_secret = self.charm.secrets.get_object(Scope.APP, CertType.APP_ADMIN.val) - tmp_cert = tempfile.NamedTemporaryFile(mode="w+t") + tmp_cert = tempfile.NamedTemporaryFile(mode="w+t", dir=self.charm.opensearch.paths.tmp) tmp_cert.write(admin_secret["cert"]) tmp_cert.flush() tmp_cert.seek(0) - tmp_key = tempfile.NamedTemporaryFile(mode="w+t") + tmp_key = tempfile.NamedTemporaryFile(mode="w+t", dir=self.charm.opensearch.paths.tmp) tmp_key.write(admin_secret["key"]) tmp_key.flush() tmp_key.seek(0) diff --git a/poetry.lock b/poetry.lock index 73503e593..b7adf8535 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "allure-pytest" @@ -1734,8 +1734,8 @@ pyyaml = "*" [package.source] type = "git" url = "https://github.com/canonical/data-platform-workflows" -reference = "v22.0.0" -resolved_reference = "da2da4b1e4469b5ed8f9187981fe2d747f8ee129" +reference = "lucas/fix-collect-bases" +resolved_reference = "a801123cd31d8ef32b7468ba3787fbb34e7cd5d7" subdirectory = "python/pytest_plugins/pytest_operator_cache" [[package]] @@ -2443,4 +2443,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "c1d623796668b0cb433f13db66235a8b32334290c7838d17ba9fdd81b269e8e0" +content-hash = "780482ebe26b8b68ed91d75af6433a3841c7e21bba0826ea2a504189811a9fea" diff --git a/pyproject.toml b/pyproject.toml index b0384743b..e9a3d1cd4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ pytest = "^8.2.2" pytest-github-secrets = {git = "https://github.com/canonical/data-platform-workflows", tag = "v22.0.0", subdirectory = "python/pytest_plugins/github_secrets"} pytest-asyncio = "^0.21.2" pytest-operator = "^0.35.0" -pytest-operator-cache = {git = "https://github.com/canonical/data-platform-workflows", tag = "v22.0.0", subdirectory = "python/pytest_plugins/pytest_operator_cache"} +pytest-operator-cache = {git = "https://github.com/canonical/data-platform-workflows", branch = "lucas/fix-collect-bases", subdirectory = "python/pytest_plugins/pytest_operator_cache"} pytest-operator-groups = {git = "https://github.com/canonical/data-platform-workflows", tag = "v22.0.0", subdirectory = "python/pytest_plugins/pytest_operator_groups"} pytest-microceph = {git = "https://github.com/canonical/data-platform-workflows", tag = "v22.0.0", subdirectory = "python/pytest_plugins/microceph"} # should not be updated unless https://github.com/juju/python-libjuju/issues/1093 is fixed diff --git a/tests/unit/lib/test_opensearch_keystore.py b/tests/unit/lib/test_opensearch_keystore.py index 723b8a280..f0d66c9ec 100644 --- a/tests/unit/lib/test_opensearch_keystore.py +++ b/tests/unit/lib/test_opensearch_keystore.py @@ -54,7 +54,7 @@ def test_keystore_add_keypair(self) -> None: self.charm.opensearch.run_bin = MagicMock(return_value="") self.keystore.add({"key1": "secret1"}) self.charm.opensearch.run_bin.assert_has_calls( - [call("opensearch-keystore", "add --force key1", stdin="secret1\n")] + [call("keystore", "add --force key1", stdin="secret1\n")] ) def test_keystore_delete_keypair(self) -> None: @@ -62,6 +62,4 @@ def test_keystore_delete_keypair(self) -> None: self.charm.opensearch.request = MagicMock(return_value={"status": 200}) self.charm.opensearch.run_bin = MagicMock(return_value="") self.keystore.delete({"key1": "secret1"}) - self.charm.opensearch.run_bin.assert_has_calls( - [call("opensearch-keystore", "remove key1")] - ) + self.charm.opensearch.run_bin.assert_has_calls([call("keystore", "remove key1")]) diff --git a/tests/unit/lib/test_opensearch_tls.py b/tests/unit/lib/test_opensearch_tls.py index 47975bada..3ada87658 100644 --- a/tests/unit/lib/test_opensearch_tls.py +++ b/tests/unit/lib/test_opensearch_tls.py @@ -473,6 +473,7 @@ def test_truststore_password_secret_only_created_by_main_orchestrator( (DeploymentType.FAILOVER_ORCHESTRATOR), ] ) + @patch("charms.opensearch.v0.opensearch_tls.tempfile.NamedTemporaryFile") @patch("charms.opensearch.v0.opensearch_tls.run_cmd") @patch(f"{PEER_CLUSTERS_MANAGER}.deployment_desc") # Mocks to avoid I/O @@ -486,6 +487,7 @@ def test_on_certificate_available_leader_app_cert_full_workflow( read_stored_ca, deployment_desc, run_cmd, + named_temporary_file, ): """New certificate received. @@ -560,6 +562,10 @@ def test_on_certificate_available_leader_app_cert_full_workflow( "sudo chmod +r /var/snap/opensearch/current/etc/opensearch/certificates/app-admin.p12" in run_cmd.call_args_list[1].args[0] ) + assert ( + "/var/snap/opensearch/common/usr/share/tmp" + in named_temporary_file.call_args_list[0][1]["dir"] + ) assert self.harness.model.app.status == original_status_app assert self.harness.model.unit.status == original_status_unit @@ -587,6 +593,7 @@ def test_on_certificate_available_leader_app_cert_full_workflow( [CertType.UNIT_HTTP.val, CertType.UNIT_TRANSPORT.val], ) ) + @patch("charms.opensearch.v0.opensearch_tls.tempfile.NamedTemporaryFile") @patch("charms.opensearch.v0.opensearch_tls.run_cmd") @patch(f"{PEER_CLUSTERS_MANAGER}.deployment_desc") # Mocks to avoid I/O @@ -602,6 +609,7 @@ def test_on_certificate_available_any_node_unit_cert_full_workflow( read_stored_ca, deployment_desc, run_cmd, + named_temporary_file, ): """New *unit* certificate received. @@ -702,6 +710,10 @@ def test_on_certificate_available_any_node_unit_cert_full_workflow( f"sudo chmod +r /var/snap/opensearch/current/etc/opensearch/certificates/{cert_type}.p12" in run_cmd.call_args_list[1].args[0] ) + assert ( + "/var/snap/opensearch/common/usr/share/tmp" + in named_temporary_file.call_args_list[0][1]["dir"] + ) assert self.harness.model.unit.status == original_status_unit @@ -728,6 +740,7 @@ def test_on_certificate_available_any_node_unit_cert_full_workflow( (DeploymentType.FAILOVER_ORCHESTRATOR), ] ) + @patch("charms.opensearch.v0.opensearch_tls.tempfile.NamedTemporaryFile") @patch("charms.opensearch.v0.opensearch_tls.run_cmd") @patch("charms.opensearch.v0.opensearch_tls.OpenSearchTLS.read_stored_ca") @patch(f"{PEER_CLUSTERS_MANAGER}.deployment_desc") @@ -741,6 +754,7 @@ def test_on_certificate_available_ca_rotation_first_stage_any_cluster_leader( deployment_desc, read_stored_ca, run_cmd, + named_temporary_file, ): """Test CA rotation 1st stage. @@ -824,6 +838,10 @@ def test_on_certificate_available_ca_rotation_first_stage_any_cluster_leader( "chmod +r /var/snap/opensearch/current/etc/opensearch/certificates/ca.p12" in run_cmd.call_args_list[2].args[0] ) + assert ( + "/var/snap/opensearch/common/usr/share/tmp" + in named_temporary_file.call_args_list[0][1]["dir"] + ) # NOTE: The new cert and chain are NOT saved into the keystore (disk) # Set flag, set status, restart @@ -1259,6 +1277,7 @@ def test_on_certificate_available_ca_rotation_second_stage_any_cluster_non_leade (DeploymentType.FAILOVER_ORCHESTRATOR), ] ) + @patch("charms.opensearch.v0.opensearch_tls.tempfile.NamedTemporaryFile") @patch("charms.opensearch.v0.opensearch_tls.run_cmd") @patch(f"{PEER_CLUSTERS_MANAGER}.deployment_desc") # Mocks to avoid I/O @@ -1272,6 +1291,7 @@ def test_on_certificate_available_ca_rotation_third_stage_leader_cert_app( read_stored_ca, deployment_desc, run_cmd, + named_temporary_file, ): """Test CA rotation 3rd stage -- *app* certificate. @@ -1354,6 +1374,10 @@ def mock_stored_ca(alias: str | None = None): "chmod +r /var/snap/opensearch/current/etc/opensearch/certificates/app-admin.p12" in run_cmd.call_args_list[1].args[0] ) + assert ( + "/var/snap/opensearch/common/usr/share/tmp" + in named_temporary_file.call_args_list[0][1]["dir"] + ) assert ( self.harness.get_relation_data(self.rel_id, "opensearch/0")["tls_ca_renewed"] == "True" ) @@ -1392,6 +1416,7 @@ def mock_stored_ca(alias: str | None = None): ) ) @patch("charms.opensearch.v0.opensearch_tls.OpenSearchTLS.reload_tls_certificates") + @patch("charms.opensearch.v0.opensearch_tls.tempfile.NamedTemporaryFile") @patch("charms.opensearch.v0.opensearch_tls.run_cmd") @patch(f"{PEER_CLUSTERS_MANAGER}.deployment_desc") # Mocks to avoid I/O @@ -1414,6 +1439,7 @@ def test_on_certificate_available_ca_rotation_third_stage_any_unit_cert_unit( read_stored_ca, deployment_desc, run_cmd, + named_temporary_file, reload_tls_certificates, ): """Test CA rotation 3rd stage -- *unit* certificate. @@ -1541,6 +1567,10 @@ def test_on_certificate_available_ca_rotation_third_stage_any_unit_cert_unit( in run_cmd.call_args_list[1].args[0] ) assert re.search("keytool .*-delete .*-alias old-ca", run_cmd.call_args_list[-1].args[0]) + assert ( + "/var/snap/opensearch/common/usr/share/tmp" + in named_temporary_file.call_args_list[0][1]["dir"] + ) assert "tls_ca_renewing" not in self.harness.get_relation_data(self.rel_id, "opensearch/0") assert "tls_ca_renewed" not in self.harness.get_relation_data(self.rel_id, "opensearch/0") @@ -1563,6 +1593,7 @@ def test_on_certificate_available_ca_rotation_third_stage_any_unit_cert_unit( ) ) ) + @patch("charms.opensearch.v0.opensearch_tls.tempfile.NamedTemporaryFile") @patch("charms.opensearch.v0.opensearch_tls.run_cmd") @patch(f"{PEER_CLUSTERS_MANAGER}.deployment_desc") # Mock to avoid I/O @@ -1577,6 +1608,7 @@ def test_on_certificate_available_rotation_ongoing_on_this_unit( read_stored_ca, deployment_desc, run_cmd, + named_temporary_file, ): """Additional 'certificate-available' event while processing CA rotation. @@ -1661,6 +1693,7 @@ def test_on_certificate_available_rotation_ongoing_on_this_unit( ) ) ) + @patch("charms.opensearch.v0.opensearch_tls.tempfile.NamedTemporaryFile") @patch("charms.opensearch.v0.opensearch_tls.run_cmd") @patch(f"{PEER_CLUSTERS_MANAGER}.deployment_desc") # Mock to avoid I/O @@ -1675,6 +1708,7 @@ def test_on_certificate_available_rotation_ongoing_on_another_unit( read_stored_ca, deployment_desc, run_cmd, + named_temporary_file, ): """Additional 'certificate-available' event while processing CA rotation. diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index 4e31f8e57..d810b9919 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -22,6 +22,7 @@ def test_store_tls_resources(self, grp_getgrnam, pwd_getpwnam, os_chown): """Test the storing of TLS resources.""" self.charm.tls.certs_path = MagicMock() self.charm.tls.jdk_path = MagicMock() + self.charm.opensearch.paths.tmp = "tests/unit/" with tempfile.TemporaryDirectory() as tmp_dir: self.charm.tls.certs_path = tmp_dir diff --git a/tox.ini b/tox.ini index 26bc84247..73966d95e 100644 --- a/tox.ini +++ b/tox.ini @@ -81,3 +81,10 @@ commands_pre = sudo sysctl -w vm.max_map_count=262144 vm.swappiness=0 net.ipv4.tcp_retries2=5 commands = poetry run pytest -v --tb native --log-cli-level=INFO -s --ignore={[vars]tests_path}/unit/ {posargs} + +[testenv:switch-24.04] +description = Patch charmcraft.yaml with necessary changes for a 24.04 build +allowlist_externals = + sh +commands = + sh -c "patch -R {toxinidir}/charmcraft.yaml < {toxinidir}/charmcraft-24.04.patch"