Skip to content

Commit

Permalink
Merge 0c3f50c into 7f693e2
Browse files Browse the repository at this point in the history
  • Loading branch information
javierdelapuente authored Jan 29, 2025
2 parents 7f693e2 + 0c3f50c commit db2c57b
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 13 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/integration_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
# INTEGRATION_TEST_ARGS to operator-workflows automatically.
integration-tests:
name: Integration test with juju 3.1
uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@main
uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@javi-testing
secrets: inherit
with:
juju-channel: 3.1/stable
Expand All @@ -30,7 +30,7 @@ jobs:
self-hosted-runner-label: stg-private-endpoint
openstack-interface-tests-private-endpoint:
name: openstack interface test using private-endpoint
uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@main
uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@javi-testing
secrets: inherit
with:
juju-channel: 3.6/stable
Expand All @@ -42,7 +42,7 @@ jobs:
self-hosted-runner-label: stg-private-endpoint
openstack-integration-tests-private-endpoint:
name: Integration test using private-endpoint
uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@main
uses: canonical/operator-workflows/.github/workflows/integration_test.yaml@javi-testing
secrets: inherit
with:
juju-channel: 3.6/stable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ def _run_health_check_cloud_init(
"""
result: invoke.runners.Result = _execute_ssh_command(ssh_conn, "cloud-init status")
if not result.ok:
logger.warning("cloud-init status command failed on %s: %s.", server_name, result.stderr)
logger.error("cloud-init status command failed on %s: %s.", server_name, result.stderr)
cloud_init_log_output_result = _execute_ssh_command(ssh_conn, "cat /var/log/cloud-init-output.log")
logger.error("/var/log/cloud-init-output.log stdout: %s", cloud_init_log_output_result.stdout)
cloud_init_log_result = _execute_ssh_command(ssh_conn, "cat /var/log/cloud-init.log")
logger.error("/var/log/cloud-init.log stdout: %s", cloud_init_log_result.stdout)
return False

if CloudInitStatus.DONE in result.stdout:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,10 @@ def _wait_runner_startup(self, instance: OpenstackInstance) -> None:
logger.warning(
"cloud-init status command failed on %s: %s.", instance.server_name, result.stderr
)
cloud_init_log_output_result = ssh_conn.run(ssh_conn, "cat /var/log/cloud-init-output.log")
logger.error("/var/log/cloud-init-output.log stdout: %s", cloud_init_log_output_result.stdout)
cloud_init_log_result = ssh_conn.run(ssh_conn, "cat /var/log/cloud-init.log")
logger.error("/var/log/cloud-init.log stdout: %s", cloud_init_log_result.stdout)
raise RunnerStartError(f"Runner startup process not found on {instance.server_name}")
# A short running job may have already completed and exited the runner, hence check the
# condition via cloud-init status check.
Expand Down
4 changes: 2 additions & 2 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class ReconcileRunnersEvent(EventBase):


def catch_charm_errors(
func: Callable[["GithubRunnerCharm", EventT], None]
func: Callable[["GithubRunnerCharm", EventT], None],
) -> Callable[["GithubRunnerCharm", EventT], None]:
"""Catch common errors in charm.
Expand Down Expand Up @@ -145,7 +145,7 @@ def func_with_catch_errors(self: "GithubRunnerCharm", event: EventT) -> None:


def catch_action_errors(
func: Callable[["GithubRunnerCharm", ActionEvent], None]
func: Callable[["GithubRunnerCharm", ActionEvent], None],
) -> Callable[["GithubRunnerCharm", ActionEvent], None]:
"""Catch common errors in actions.
Expand Down
8 changes: 5 additions & 3 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ async def app_no_runner(
) -> AsyncIterator[Application]:
"""Application with no runner."""
await basic_app.set_config({VIRTUAL_MACHINES_CONFIG_NAME: "0"})
await model.wait_for_idle(apps=[basic_app.name], status=ACTIVE, timeout=90 * 60)
await model.wait_for_idle(apps=[basic_app.name], status=ACTIVE, timeout=20 * 60)
yield basic_app


Expand Down Expand Up @@ -401,7 +401,9 @@ async def app_openstack_runner_fixture(
wait_idle=False,
)
await model.integrate(f"{image_builder.name}:image", f"{application.name}:image")
await model.wait_for_idle(apps=[application.name], status=ACTIVE, timeout=90 * 60)
await model.wait_for_idle(
apps=[application.name, image_builder.name], status=ACTIVE, timeout=20 * 60
)

return application

Expand All @@ -415,7 +417,7 @@ async def app_scheduled_events_fixture(
application = app_openstack_runner
await application.set_config({"reconcile-interval": "8"})
await application.set_config({VIRTUAL_MACHINES_CONFIG_NAME: "1"})
await model.wait_for_idle(apps=[application.name], status=ACTIVE, timeout=90 * 60)
await model.wait_for_idle(apps=[application.name], status=ACTIVE, timeout=20 * 60)
await reconcile(app=application, model=model)
return application

Expand Down
45 changes: 45 additions & 0 deletions tests/integration/helpers/openstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# See LICENSE file for licensing details.
import logging
import secrets
import threading
from asyncio import sleep
from typing import Optional, TypedDict

Expand All @@ -17,6 +18,36 @@
logger = logging.getLogger(__name__)


async def javi_wait_for_idle(openstack_connection, model, *args, **kwargs) -> None:
"""TODO.
Args:
openstack_connection: OpenStack connection object.
model: model
args: args
kwargs: kwargs
"""
logger.info("javi_wait_for_idle")
e = threading.Event()

def _log_openstack():
"""TODO."""
while not e.wait(10):
# probably not thread safe, but...
servers = openstack_connection.list_servers()
logger.info(" [ runner list ]")
for runner in servers:
logger.info(" [ runner %s ] %s", runner.name, runner)

try:
t = threading.Thread(target=_log_openstack)
t.start()
await model.wait_for_idle(*args, **kwargs)
finally:
e.set()
t.join()


class OpenStackInstanceHelper:
"""Helper class to interact with OpenStack instances."""

Expand Down Expand Up @@ -179,6 +210,20 @@ async def get_runner_name(self, unit: Unit) -> str:
assert len(runners) == 1
return runners[0].name

def log_runners(self, unit: Unit) -> None:
"""TODO LOG RUNNERS.
Expects only one runner to be present.
Args:
unit: The GitHub Runner Charm unit to get the runner name for.
"""
runners = self._get_runners(unit)
logger.info("[ list of runners for unit %s]", unit)
for runner in runners:
logger.info("[ runner %s ]: %s", runner.name, runner)
logger.info("[ end list of runners for unit %s]")

async def delete_single_runner(self, unit: Unit) -> None:
"""Delete the only runner.
Expand Down
5 changes: 3 additions & 2 deletions tests/integration/test_charm_scheduled_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from juju.model import Model

from tests.integration.helpers.common import wait_for
from tests.integration.helpers.openstack import OpenStackInstanceHelper
from tests.integration.helpers.openstack import OpenStackInstanceHelper, javi_wait_for_idle
from tests.status_name import ACTIVE

logger = logging.getLogger(__name__)
Expand All @@ -28,6 +28,7 @@ async def test_update_interval(
model: Model,
app_scheduled_events: Application,
instance_helper: OpenStackInstanceHelper,
openstack_connection,
) -> None:
"""
arrange: A working application with one runner.
Expand Down Expand Up @@ -57,7 +58,7 @@ async def _no_runners_available() -> bool:

logger.info("Wait for 10 minutes")
await sleep(10 * 60)
await model.wait_for_idle(status=ACTIVE, timeout=20 * 60)
await javi_wait_for_idle(openstack_connection, model, status=ACTIVE, timeout=20 * 60)

newnames = await instance_helper.get_runner_names(unit)
assert len(newnames) == 1, "There should be one runner after reconciliation"
Expand Down
12 changes: 10 additions & 2 deletions tests/integration/test_debug_ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from juju.model import Model

from tests.integration.helpers.common import dispatch_workflow, get_job_logs
from tests.integration.helpers.openstack import OpenStackInstanceHelper
from tests.integration.helpers.openstack import OpenStackInstanceHelper, javi_wait_for_idle
from tests.status_name import ACTIVE

logger = logging.getLogger(__name__)
Expand All @@ -28,24 +28,30 @@ async def test_ssh_debug(
test_github_branch: Branch,
tmate_ssh_server_unit_ip: str,
instance_helper: OpenStackInstanceHelper,
openstack_connection,
):
"""
arrange: given an integrated GitHub-Runner charm and tmate-ssh-server charm.
act: when canonical/action-tmate is triggered.
assert: the ssh connection info from action-log and tmate-ssh-server matches.
"""
await model.wait_for_idle(status=ACTIVE, timeout=60 * 120)
await javi_wait_for_idle(openstack_connection, model, status=ACTIVE, timeout=60 * 120)

unit = app_no_wait_tmate.units[0]
# We need the runner to connect to the current machine, instead of the tmate_ssh_server unit,
# as the tmate_ssh_server is not routable.
logger.info("before iptables")
instance_helper.log_runners(unit)

dnat_comman_in_runner = f"sudo iptables -t nat -A OUTPUT -p tcp -d {tmate_ssh_server_unit_ip} --dport 10022 -j DNAT --to-destination 127.0.0.1:10022"
_, _, _ = await instance_helper.run_in_instance(
unit,
dnat_comman_in_runner,
assert_on_failure=True,
)
await instance_helper.expose_to_instance(unit=unit, port=10022, host=tmate_ssh_server_unit_ip)
logger.info("after exposing instance")
instance_helper.log_runners(unit)

# trigger tmate action
logger.info("Dispatching workflow_dispatch_ssh_debug.yaml workflow.")
Expand All @@ -59,6 +65,8 @@ async def test_ssh_debug(
workflow_id_or_name=SSH_DEBUG_WORKFLOW_FILE_NAME,
)

logger.info("after workflow run")
instance_helper.log_runners(unit)
logs = get_job_logs(workflow_run.jobs("latest")[0])

# ensure ssh connection info printed in logs.
Expand Down

0 comments on commit db2c57b

Please sign in to comment.