Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DPE-2758 better messaging when no bucket + ceph testing #332

Merged
merged 18 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ jobs:
echo Skipping unstable tests
echo "mark_expression=not unstable" >> "$GITHUB_OUTPUT"
fi
- name: Setup microceph
# setup microceph before any tox call due to it writing a file
# used by tox
uses: phvalguima/[email protected]
paulomach marked this conversation as resolved.
Show resolved Hide resolved
with:
channel: 'latest/edge'
devname: '/dev/sdi'
accesskey: 'accesskey'
secretkey: 'secretkey'
bucket: 'testbucket'
osdsize: '1G'
- name: Collect test groups
id: collect-groups
run: tox run -e integration -- tests/integration -m '${{ steps.select-test-stability.outputs.mark_expression }}' --collect-groups
Expand Down Expand Up @@ -147,6 +158,16 @@ jobs:
echo Skipping unstable tests
echo "mark_expression=not unstable" >> "$GITHUB_OUTPUT"
fi
- name: Setup microceph
# setup microceph before tests
uses: phvalguima/[email protected]
with:
channel: 'latest/edge'
devname: '/dev/sdi'
accesskey: 'accesskey'
secretkey: 'secretkey'
bucket: 'testbucket'
osdsize: '1G'
- name: Run integration tests
run: tox run -e integration -- "${{ matrix.groups.path_to_test_file }}" --group="${{ matrix.groups.group_number }}" -m '${{ steps.select-test-stability.outputs.mark_expression }}'
env:
Expand Down
8 changes: 5 additions & 3 deletions lib/charms/mysql/v0/backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,11 @@ def _on_list_backups(self, event: ActionEvent) -> None:
logger.info("Listing backups in the specified s3 path")
backups = sorted(list_backups_in_s3_path(s3_parameters), key=lambda pair: pair[0])
event.set_results({"backups": self._format_backups_list(backups)})
except Exception:
error_message = "Failed to retrieve backup ids from S3"
logger.exception(error_message)
except Exception as e:
error_message = (
e.message if hasattr(e, "message") else "Failed to retrieve backup ids from S3"
)
logger.error(error_message)
Comment on lines -223 to +227
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using a more specific exception type instead

event.fail(error_message)

# ------------------ Create Backup ------------------
Expand Down
1 change: 0 additions & 1 deletion lib/charms/mysql/v0/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -2338,7 +2338,6 @@ def retrieve_backup_with_xbcloud(

try:
logger.debug(f"Command to retrieve backup: {' '.join(retrieve_backup_command)}")

# ACCESS_KEY_ID and SECRET_ACCESS_KEY envs auto picked by xbcloud
stdout, stderr = self._execute_commands(
retrieve_backup_command,
Expand Down
22 changes: 19 additions & 3 deletions lib/charms/mysql/v0/s3_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 4
LIBPATCH = 5


# botocore/urllib3 clutter the logs when on debug
logging.getLogger("botocore").setLevel(logging.ERROR)
logging.getLogger("urllib3").setLevel(logging.ERROR)
paulomach marked this conversation as resolved.
Show resolved Hide resolved
paulomach marked this conversation as resolved.
Show resolved Hide resolved


def upload_content_to_s3(content: str, content_path: str, s3_parameters: Dict) -> bool:
Expand All @@ -55,6 +60,7 @@ def upload_content_to_s3(content: str, content_path: str, s3_parameters: Dict) -
)

s3 = session.resource("s3", endpoint_url=s3_parameters["endpoint"])

bucket = s3.Bucket(s3_parameters["bucket"])

with tempfile.NamedTemporaryFile() as temp_file:
Expand Down Expand Up @@ -147,9 +153,19 @@ def list_backups_in_s3_path(s3_parameters: Dict) -> List[Tuple[str, str]]:

return _compile_backups_from_file_ids(metadata_ids, md5_ids, log_ids)
except Exception as e:
try:
# botocore raises dynamically generated exceptions
# with a response attribute. We can use this to
# set a more meaningful error message.
if e.response["Error"]["Code"] == "NoSuchBucket":
message = f"Bucket {s3_parameters['bucket']} does not exist"
setattr(e, "message", message)
raise
except (KeyError, AttributeError):
pass
paulomach marked this conversation as resolved.
Show resolved Hide resolved
# default handling exposes exception
logger.exception(
f"Failed to list subdirectories in S3 bucket={s3_parameters['bucket']}, path={s3_parameters['path']}",
exc_info=e,
f"Failed to list subdirectories in S3 bucket={s3_parameters['bucket']}, path={s3_parameters['path']}"
)
raise

Expand Down
23 changes: 19 additions & 4 deletions tests/integration/test_backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# See LICENSE file for licensing details.

import logging
import os
import socket
from pathlib import Path

import boto3
Expand All @@ -24,6 +26,8 @@

logger = logging.getLogger(__name__)

host_ip = socket.gethostbyname(socket.gethostname())

CLOUD_CONFIGS = {
"aws": {
"endpoint": "https://s3.amazonaws.com",
Expand All @@ -37,6 +41,12 @@
"path": "mysql-k8s",
"region": "",
},
"ceph": {
"endpoint": f"http://{host_ip}",
"bucket": os.environ["S3_BUCKET"],
"path": "mysql-k8s",
"region": os.environ["S3_REGION"],
},
carlcsaposs-canonical marked this conversation as resolved.
Show resolved Hide resolved
}
S3_INTEGRATOR = "s3-integrator"
TIMEOUT = 10 * 60
Expand All @@ -62,11 +72,15 @@ def cloud_credentials(github_secrets) -> dict[str, dict[str, str]]:
"access-key": github_secrets["GCP_ACCESS_KEY"],
"secret-key": github_secrets["GCP_SECRET_KEY"],
},
"ceph": {
"access-key": os.environ["S3_ACCESS_KEY"],
"secret-key": os.environ["S3_SECRET_KEY"],
},
paulomach marked this conversation as resolved.
Show resolved Hide resolved
}


@pytest.fixture(scope="session", autouse=True)
def clean_backups_from_buckets(cloud_credentials) -> None:
def clean_backups_from_buckets(cloud_credentials):
"""Teardown to clean up created backups from clouds."""
yield

Expand Down Expand Up @@ -105,9 +119,9 @@ async def test_build_and_deploy(ops_test: OpsTest) -> None:
await rotate_credentials(mysql_unit, username="root", password=ROOT_PASSWORD)

# deploy and relate to s3-integrator
logger.info("Deploying s3 integrator")
logger.info("Deploying s3 integrator and tls operator")

await ops_test.model.deploy(S3_INTEGRATOR, channel="edge")
await ops_test.model.deploy(S3_INTEGRATOR, channel="stable")
await ops_test.model.relate(mysql_application_name, S3_INTEGRATOR)

await ops_test.model.wait_for_idle(
Expand Down Expand Up @@ -139,9 +153,10 @@ async def test_backup(ops_test: OpsTest, cloud_credentials) -> None:

for cloud_name, config in CLOUD_CONFIGS.items():
# set the s3 config and credentials
logger.info(f"Syncing credentials for {cloud_name}")

logger.info(f"Setting s3 config for {cloud_name}")
await ops_test.model.applications[S3_INTEGRATOR].set_config(config)
logger.info(f"Syncing credentials for {cloud_name}")
action = await ops_test.model.units[f"{S3_INTEGRATOR}/0"].run_action(
"sync-s3-credentials", **cloud_credentials[cloud_name]
)
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ set_env =
# Workaround for https://github.com/python-poetry/poetry/issues/6958
POETRY_INSTALLER_PARALLEL = false
LIBJUJU_VERSION_SPECIFIER = {env:LIBJUJU_VERSION_SPECIFIER:3.2.2}
file|microceph.source
paulomach marked this conversation as resolved.
Show resolved Hide resolved
pass_env =
CI
GITHUB_OUTPUT
Expand Down