From e0fa55cef8806bfd537ce1c7d33f0a13337966e4 Mon Sep 17 00:00:00 2001 From: John Mulligan Date: Mon, 29 Sep 2025 15:47:30 -0400 Subject: [PATCH] qa/tasks: move smb related task funcs out of cephadm.py to smb.py Move a bunch of functionality specific to smb out of cephadm.py and in to a new qa/tasks/smb.py file. The cephadm.py file had contained a bunch of smb specific stuff because it was easy to add it that way initially. Now that I am planning on expanding to add some more smb tasks, it makes sense to move these smb specific functions first. Update the needed yaml files with the new module. Signed-off-by: John Mulligan --- .../cephadm/smb/tasks/deploy_smb_basic.yaml | 2 +- .../deploy_smb_ctdb_node_gone_state.yaml | 2 +- .../cephadm/smb/tasks/deploy_smb_domain.yaml | 2 +- .../smb/tasks/deploy_smb_mgr_basic.yaml | 2 +- .../tasks/deploy_smb_mgr_clustering_ips.yaml | 2 +- .../tasks/deploy_smb_mgr_ctdb_res_basic.yaml | 2 +- .../tasks/deploy_smb_mgr_ctdb_res_dom.yaml | 2 +- .../tasks/deploy_smb_mgr_ctdb_res_ips.yaml | 2 +- .../deploy_smb_mgr_ctdb_res_ports2c.yaml | 2 +- .../smb/tasks/deploy_smb_mgr_domain.yaml | 2 +- .../smb/tasks/deploy_smb_mgr_res_basic.yaml | 2 +- .../smb/tasks/deploy_smb_mgr_res_dom.yaml | 2 +- .../smb/tasks/deploy_smb_mgr_res_ports.yaml | 2 +- .../smb/tasks/deploy_smb_proxy_disabled.yaml | 2 +- .../smb/tasks/deploy_smb_proxy_enabled.yaml | 2 +- qa/tasks/cephadm.py | 287 ----------------- qa/tasks/smb.py | 299 ++++++++++++++++++ 17 files changed, 314 insertions(+), 302 deletions(-) create mode 100644 qa/tasks/smb.py diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_basic.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_basic.yaml index eba5025cf35..aed5723e9c0 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_basic.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_basic.yaml @@ -17,7 +17,7 @@ overrides: tasks: # TODO: (jjm) I don't think `install` is necessary for this file. Remove? - install: - - cephadm.configure_samba_client_container: + - smb.configure_samba_client_container: role: host.b - cephadm: - cephadm.shell: diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_ctdb_node_gone_state.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_ctdb_node_gone_state.yaml index 2a1257e5c95..92f84d7df80 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_ctdb_node_gone_state.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_ctdb_node_gone_state.yaml @@ -22,7 +22,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.configure_samba_client_container: +- smb.configure_samba_client_container: role: host.d - pexec: all: diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_domain.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_domain.yaml index 86220108c23..82a21253f7b 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_domain.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_domain.yaml @@ -14,7 +14,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.b - cephadm: diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_basic.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_basic.yaml index 957977c0b6b..94033e59fb5 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_basic.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_basic.yaml @@ -14,7 +14,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.configure_samba_client_container: +- smb.configure_samba_client_container: role: host.b - cephadm: single_host_defaults: true diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_clustering_ips.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_clustering_ips.yaml index 14e28c89f4e..6db409638a5 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_clustering_ips.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_clustering_ips.yaml @@ -22,7 +22,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.configure_samba_client_container: +- smb.configure_samba_client_container: role: host.d - vip: count: 1 diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_basic.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_basic.yaml index d3a979be5f1..cb253520297 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_basic.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_basic.yaml @@ -22,7 +22,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.configure_samba_client_container: +- smb.configure_samba_client_container: role: host.d - pexec: all: diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_dom.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_dom.yaml index bf96de81f2f..ce5d2b49000 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_dom.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_dom.yaml @@ -22,7 +22,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.d - pexec: all: diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_ips.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_ips.yaml index f0405e4d14d..63efb232d08 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_ips.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_ips.yaml @@ -22,7 +22,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.d - vip: count: 2 diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_ports2c.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_ports2c.yaml index bbac4357f6f..77b98882827 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_ports2c.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_ctdb_res_ports2c.yaml @@ -22,7 +22,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.d - vip: count: 3 diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_domain.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_domain.yaml index ac7ad45c036..985eb4cf4f8 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_domain.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_domain.yaml @@ -14,7 +14,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.b - cephadm: single_host_defaults: true diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_basic.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_basic.yaml index 735966e876e..99f145f9d98 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_basic.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_basic.yaml @@ -14,7 +14,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.configure_samba_client_container: +- smb.configure_samba_client_container: role: host.b - cephadm: single_host_defaults: true diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_dom.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_dom.yaml index 64fd109f66a..36f15575ee9 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_dom.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_dom.yaml @@ -14,7 +14,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.b - cephadm: single_host_defaults: true diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_ports.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_ports.yaml index 542ff065079..65402886c2a 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_ports.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_mgr_res_ports.yaml @@ -14,7 +14,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.b - cephadm: single_host_defaults: true diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_proxy_disabled.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_proxy_disabled.yaml index a1fd177cf5c..a7253328c29 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_proxy_disabled.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_proxy_disabled.yaml @@ -14,7 +14,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.b - cephadm: single_host_defaults: true diff --git a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_proxy_enabled.yaml b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_proxy_enabled.yaml index 2f281366a57..05001b67f68 100644 --- a/qa/suites/orch/cephadm/smb/tasks/deploy_smb_proxy_enabled.yaml +++ b/qa/suites/orch/cephadm/smb/tasks/deploy_smb_proxy_enabled.yaml @@ -14,7 +14,7 @@ overrides: log-only-match: - CEPHADM_ tasks: -- cephadm.deploy_samba_ad_dc: +- smb.deploy_samba_ad_dc: role: host.b - cephadm: single_host_defaults: true diff --git a/qa/tasks/cephadm.py b/qa/tasks/cephadm.py index a312f7fe7bc..5d48c904e61 100644 --- a/qa/tasks/cephadm.py +++ b/qa/tasks/cephadm.py @@ -8,7 +8,6 @@ import json import logging import os import re -import time import uuid import yaml @@ -1885,292 +1884,6 @@ def initialize_config(ctx, config): yield -def _disable_systemd_resolved(ctx, remote): - r = remote.run(args=['ss', '-lunH'], stdout=StringIO()) - # this heuristic tries to detect if systemd-resolved is running - if '%lo:53' not in r.stdout.getvalue(): - return - log.info('Disabling systemd-resolved on %s', remote.shortname) - # Samba AD DC container DNS support conflicts with resolved stub - # resolver when using host networking. And we want host networking - # because it is the simplest thing to set up. We therefore will turn - # off the stub resolver. - r = remote.run( - args=['sudo', 'cat', '/etc/systemd/resolved.conf'], - stdout=StringIO(), - ) - resolved_conf = r.stdout.getvalue() - setattr(ctx, 'orig_resolved_conf', resolved_conf) - new_resolved_conf = ( - resolved_conf + '\n# EDITED BY TEUTHOLOGY: deploy_samba_ad_dc\n' - ) - if '[Resolve]' not in new_resolved_conf.splitlines(): - new_resolved_conf += '[Resolve]\n' - new_resolved_conf += 'DNSStubListener=no\n' - remote.write_file( - path='/etc/systemd/resolved.conf', - data=new_resolved_conf, - sudo=True, - ) - remote.run(args=['sudo', 'systemctl', 'restart', 'systemd-resolved']) - r = remote.run(args=['ss', '-lunH'], stdout=StringIO()) - assert '%lo:53' not in r.stdout.getvalue() - # because docker is a big fat persistent deamon, we need to bounce it - # after resolved is restarted - remote.run(args=['sudo', 'systemctl', 'restart', 'docker']) - - -def _reset_systemd_resolved(ctx, remote): - orig_resolved_conf = getattr(ctx, 'orig_resolved_conf', None) - if not orig_resolved_conf: - return # no orig_resolved_conf means nothing to reset - log.info('Resetting systemd-resolved state on %s', remote.shortname) - remote.write_file( - path='/etc/systemd/resolved.conf', - data=orig_resolved_conf, - sudo=True, - ) - remote.run(args=['sudo', 'systemctl', 'restart', 'systemd-resolved']) - setattr(ctx, 'orig_resolved_conf', None) - - -def _samba_ad_dc_conf(ctx, remote, cengine): - # this config has not been tested outside of smithi nodes. it's possible - # that this will break when used elsewhere because we have to list - # interfaces explicitly. Later I may add a feature to sambacc to exclude - # known-unwanted interfaces that having to specify known good interfaces. - cf = { - "samba-container-config": "v0", - "configs": { - "demo": { - "instance_features": ["addc"], - "domain_settings": "sink", - "instance_name": "dc1", - } - }, - "domain_settings": { - "sink": { - "realm": "DOMAIN1.SINK.TEST", - "short_domain": "DOMAIN1", - "admin_password": "Passw0rd", - "interfaces": { - "exclude_pattern": "^docker[0-9]+$", - }, - } - }, - "domain_groups": { - "sink": [ - {"name": "supervisors"}, - {"name": "employees"}, - {"name": "characters"}, - {"name": "bulk"}, - ] - }, - "domain_users": { - "sink": [ - { - "name": "bwayne", - "password": "1115Rose.", - "given_name": "Bruce", - "surname": "Wayne", - "member_of": ["supervisors", "characters", "employees"], - }, - { - "name": "ckent", - "password": "1115Rose.", - "given_name": "Clark", - "surname": "Kent", - "member_of": ["characters", "employees"], - }, - { - "name": "user0", - "password": "1115Rose.", - "given_name": "George0", - "surname": "Hue-Sir", - "member_of": ["bulk"], - }, - { - "name": "user1", - "password": "1115Rose.", - "given_name": "George1", - "surname": "Hue-Sir", - "member_of": ["bulk"], - }, - { - "name": "user2", - "password": "1115Rose.", - "given_name": "George2", - "surname": "Hue-Sir", - "member_of": ["bulk"], - }, - { - "name": "user3", - "password": "1115Rose.", - "given_name": "George3", - "surname": "Hue-Sir", - "member_of": ["bulk"], - }, - ] - }, - } - cf_json = json.dumps(cf) - remote.run(args=['sudo', 'mkdir', '-p', '/var/tmp/samba']) - remote.write_file( - path='/var/tmp/samba/container.json', data=cf_json, sudo=True - ) - return [ - '--volume=/var/tmp/samba:/etc/samba-container:ro', - '-eSAMBACC_CONFIG=/etc/samba-container/container.json', - ] - - -@contextlib.contextmanager -def configure_samba_client_container(ctx, config): - # TODO: deduplicate logic between this task and deploy_samba_ad_dc - role = config.get('role') - samba_client_image = config.get( - 'samba_client_image', 'quay.io/samba.org/samba-client:latest' - ) - if not role: - raise ConfigError( - "you must specify a role to discover container engine / pull image" - ) - (remote,) = ctx.cluster.only(role).remotes.keys() - cengine = 'podman' - try: - log.info("Testing if podman is available") - remote.run(args=['sudo', cengine, '--help']) - except CommandFailedError: - log.info("Failed to find podman. Using docker") - cengine = 'docker' - - remote.run(args=['sudo', cengine, 'pull', samba_client_image]) - samba_client_container_cmd = [ - 'sudo', - cengine, - 'run', - '--rm', - '--net=host', - '-eKRB5_CONFIG=/dev/null', - samba_client_image, - ] - - setattr(ctx, 'samba_client_container_cmd', samba_client_container_cmd) - try: - yield - finally: - setattr(ctx, 'samba_client_container_cmd', None) - - -@contextlib.contextmanager -def deploy_samba_ad_dc(ctx, config): - role = config.get('role') - ad_dc_image = config.get( - 'ad_dc_image', 'quay.io/samba.org/samba-ad-server:latest' - ) - samba_client_image = config.get( - 'samba_client_image', 'quay.io/samba.org/samba-client:latest' - ) - test_user_pass = config.get('test_user_pass', 'DOMAIN1\\ckent%1115Rose.') - if not role: - raise ConfigError( - "you must specify a role to allocate a host for the AD DC" - ) - (remote,) = ctx.cluster.only(role).remotes.keys() - ip = remote.ssh.get_transport().getpeername()[0] - cengine = 'podman' - try: - log.info("Testing if podman is available") - remote.run(args=['sudo', cengine, '--help']) - except CommandFailedError: - log.info("Failed to find podman. Using docker") - cengine = 'docker' - remote.run(args=['sudo', cengine, 'pull', ad_dc_image]) - remote.run(args=['sudo', cengine, 'pull', samba_client_image]) - _disable_systemd_resolved(ctx, remote) - remote.run( - args=[ - 'sudo', - 'mkdir', - '-p', - '/var/lib/samba/container/logs', - '/var/lib/samba/container/data', - ] - ) - remote.run( - args=[ - 'sudo', - cengine, - 'run', - '-d', - '--name=samba-ad', - '--network=host', - '--privileged', - ] - + _samba_ad_dc_conf(ctx, remote, cengine) - + [ad_dc_image] - ) - - # test that the ad dc is running and basically works - connected = False - samba_client_container_cmd = [ - 'sudo', - cengine, - 'run', - '--rm', - '--net=host', - f'--dns={ip}', - '-eKRB5_CONFIG=/dev/null', - samba_client_image, - ] - for idx in range(10): - time.sleep((2 ** (1 + idx)) / 8) - log.info("Probing SMB status of DC %s, idx=%s", ip, idx) - cmd = samba_client_container_cmd + [ - 'smbclient', - '-U', - test_user_pass, - '//domain1.sink.test/sysvol', - '-c', - 'ls', - ] - try: - remote.run(args=cmd) - connected = True - log.info("SMB status probe succeeded") - break - except CommandFailedError: - pass - if not connected: - raise RuntimeError('failed to connect to AD DC SMB share') - - setattr(ctx, 'samba_ad_dc_ip', ip) - setattr(ctx, 'samba_client_container_cmd', samba_client_container_cmd) - try: - yield - finally: - try: - remote.run(args=['sudo', cengine, 'stop', 'samba-ad']) - except CommandFailedError: - log.error("Failed to stop samba-ad container") - try: - remote.run(args=['sudo', cengine, 'rm', 'samba-ad']) - except CommandFailedError: - log.error("Failed to remove samba-ad container") - remote.run( - args=[ - 'sudo', - 'rm', - '-rf', - '/var/lib/samba/container/logs', - '/var/lib/samba/container/data', - ] - ) - _reset_systemd_resolved(ctx, remote) - setattr(ctx, 'samba_ad_dc_ip', None) - setattr(ctx, 'samba_client_container_cmd', None) - - @contextlib.contextmanager def task(ctx, config): """ diff --git a/qa/tasks/smb.py b/qa/tasks/smb.py new file mode 100644 index 00000000000..23f49dc8ae9 --- /dev/null +++ b/qa/tasks/smb.py @@ -0,0 +1,299 @@ +""" +Ceph teuthology task for managed smb features. +""" +from io import StringIO +import contextlib +import logging +import json +import time + +from teuthology.exceptions import ConfigError, CommandFailedError + + +log = logging.getLogger(__name__) + + +def _disable_systemd_resolved(ctx, remote): + r = remote.run(args=['ss', '-lunH'], stdout=StringIO()) + # this heuristic tries to detect if systemd-resolved is running + if '%lo:53' not in r.stdout.getvalue(): + return + log.info('Disabling systemd-resolved on %s', remote.shortname) + # Samba AD DC container DNS support conflicts with resolved stub + # resolver when using host networking. And we want host networking + # because it is the simplest thing to set up. We therefore will turn + # off the stub resolver. + r = remote.run( + args=['sudo', 'cat', '/etc/systemd/resolved.conf'], + stdout=StringIO(), + ) + resolved_conf = r.stdout.getvalue() + setattr(ctx, 'orig_resolved_conf', resolved_conf) + new_resolved_conf = ( + resolved_conf + '\n# EDITED BY TEUTHOLOGY: deploy_samba_ad_dc\n' + ) + if '[Resolve]' not in new_resolved_conf.splitlines(): + new_resolved_conf += '[Resolve]\n' + new_resolved_conf += 'DNSStubListener=no\n' + remote.write_file( + path='/etc/systemd/resolved.conf', + data=new_resolved_conf, + sudo=True, + ) + remote.run(args=['sudo', 'systemctl', 'restart', 'systemd-resolved']) + r = remote.run(args=['ss', '-lunH'], stdout=StringIO()) + assert '%lo:53' not in r.stdout.getvalue() + # because docker is a big fat persistent deamon, we need to bounce it + # after resolved is restarted + remote.run(args=['sudo', 'systemctl', 'restart', 'docker']) + + +def _reset_systemd_resolved(ctx, remote): + orig_resolved_conf = getattr(ctx, 'orig_resolved_conf', None) + if not orig_resolved_conf: + return # no orig_resolved_conf means nothing to reset + log.info('Resetting systemd-resolved state on %s', remote.shortname) + remote.write_file( + path='/etc/systemd/resolved.conf', + data=orig_resolved_conf, + sudo=True, + ) + remote.run(args=['sudo', 'systemctl', 'restart', 'systemd-resolved']) + setattr(ctx, 'orig_resolved_conf', None) + + +def _samba_ad_dc_conf(ctx, remote, cengine): + # this config has not been tested outside of smithi nodes. it's possible + # that this will break when used elsewhere because we have to list + # interfaces explicitly. Later I may add a feature to sambacc to exclude + # known-unwanted interfaces that having to specify known good interfaces. + cf = { + "samba-container-config": "v0", + "configs": { + "demo": { + "instance_features": ["addc"], + "domain_settings": "sink", + "instance_name": "dc1", + } + }, + "domain_settings": { + "sink": { + "realm": "DOMAIN1.SINK.TEST", + "short_domain": "DOMAIN1", + "admin_password": "Passw0rd", + "interfaces": { + "exclude_pattern": "^docker[0-9]+$", + }, + } + }, + "domain_groups": { + "sink": [ + {"name": "supervisors"}, + {"name": "employees"}, + {"name": "characters"}, + {"name": "bulk"}, + ] + }, + "domain_users": { + "sink": [ + { + "name": "bwayne", + "password": "1115Rose.", + "given_name": "Bruce", + "surname": "Wayne", + "member_of": ["supervisors", "characters", "employees"], + }, + { + "name": "ckent", + "password": "1115Rose.", + "given_name": "Clark", + "surname": "Kent", + "member_of": ["characters", "employees"], + }, + { + "name": "user0", + "password": "1115Rose.", + "given_name": "George0", + "surname": "Hue-Sir", + "member_of": ["bulk"], + }, + { + "name": "user1", + "password": "1115Rose.", + "given_name": "George1", + "surname": "Hue-Sir", + "member_of": ["bulk"], + }, + { + "name": "user2", + "password": "1115Rose.", + "given_name": "George2", + "surname": "Hue-Sir", + "member_of": ["bulk"], + }, + { + "name": "user3", + "password": "1115Rose.", + "given_name": "George3", + "surname": "Hue-Sir", + "member_of": ["bulk"], + }, + ] + }, + } + cf_json = json.dumps(cf) + remote.run(args=['sudo', 'mkdir', '-p', '/var/tmp/samba']) + remote.write_file( + path='/var/tmp/samba/container.json', data=cf_json, sudo=True + ) + return [ + '--volume=/var/tmp/samba:/etc/samba-container:ro', + '-eSAMBACC_CONFIG=/etc/samba-container/container.json', + ] + + +@contextlib.contextmanager +def configure_samba_client_container(ctx, config): + # TODO: deduplicate logic between this task and deploy_samba_ad_dc + role = config.get('role') + samba_client_image = config.get( + 'samba_client_image', 'quay.io/samba.org/samba-client:latest' + ) + if not role: + raise ConfigError( + "you must specify a role to discover container engine / pull image" + ) + (remote,) = ctx.cluster.only(role).remotes.keys() + cengine = 'podman' + try: + log.info("Testing if podman is available") + remote.run(args=['sudo', cengine, '--help']) + except CommandFailedError: + log.info("Failed to find podman. Using docker") + cengine = 'docker' + + remote.run(args=['sudo', cengine, 'pull', samba_client_image]) + samba_client_container_cmd = [ + 'sudo', + cengine, + 'run', + '--rm', + '--net=host', + '-eKRB5_CONFIG=/dev/null', + samba_client_image, + ] + + setattr(ctx, 'samba_client_container_cmd', samba_client_container_cmd) + try: + yield + finally: + setattr(ctx, 'samba_client_container_cmd', None) + + +@contextlib.contextmanager +def deploy_samba_ad_dc(ctx, config): + role = config.get('role') + ad_dc_image = config.get( + 'ad_dc_image', 'quay.io/samba.org/samba-ad-server:latest' + ) + samba_client_image = config.get( + 'samba_client_image', 'quay.io/samba.org/samba-client:latest' + ) + test_user_pass = config.get('test_user_pass', 'DOMAIN1\\ckent%1115Rose.') + if not role: + raise ConfigError( + "you must specify a role to allocate a host for the AD DC" + ) + (remote,) = ctx.cluster.only(role).remotes.keys() + ip = remote.ssh.get_transport().getpeername()[0] + cengine = 'podman' + try: + log.info("Testing if podman is available") + remote.run(args=['sudo', cengine, '--help']) + except CommandFailedError: + log.info("Failed to find podman. Using docker") + cengine = 'docker' + remote.run(args=['sudo', cengine, 'pull', ad_dc_image]) + remote.run(args=['sudo', cengine, 'pull', samba_client_image]) + _disable_systemd_resolved(ctx, remote) + remote.run( + args=[ + 'sudo', + 'mkdir', + '-p', + '/var/lib/samba/container/logs', + '/var/lib/samba/container/data', + ] + ) + remote.run( + args=[ + 'sudo', + cengine, + 'run', + '-d', + '--name=samba-ad', + '--network=host', + '--privileged', + ] + + _samba_ad_dc_conf(ctx, remote, cengine) + + [ad_dc_image] + ) + + # test that the ad dc is running and basically works + connected = False + samba_client_container_cmd = [ + 'sudo', + cengine, + 'run', + '--rm', + '--net=host', + f'--dns={ip}', + '-eKRB5_CONFIG=/dev/null', + samba_client_image, + ] + for idx in range(10): + time.sleep((2 ** (1 + idx)) / 8) + log.info("Probing SMB status of DC %s, idx=%s", ip, idx) + cmd = samba_client_container_cmd + [ + 'smbclient', + '-U', + test_user_pass, + '//domain1.sink.test/sysvol', + '-c', + 'ls', + ] + try: + remote.run(args=cmd) + connected = True + log.info("SMB status probe succeeded") + break + except CommandFailedError: + pass + if not connected: + raise RuntimeError('failed to connect to AD DC SMB share') + + setattr(ctx, 'samba_ad_dc_ip', ip) + setattr(ctx, 'samba_client_container_cmd', samba_client_container_cmd) + try: + yield + finally: + try: + remote.run(args=['sudo', cengine, 'stop', 'samba-ad']) + except CommandFailedError: + log.error("Failed to stop samba-ad container") + try: + remote.run(args=['sudo', cengine, 'rm', 'samba-ad']) + except CommandFailedError: + log.error("Failed to remove samba-ad container") + remote.run( + args=[ + 'sudo', + 'rm', + '-rf', + '/var/lib/samba/container/logs', + '/var/lib/samba/container/data', + ] + ) + _reset_systemd_resolved(ctx, remote) + setattr(ctx, 'samba_ad_dc_ip', None) + setattr(ctx, 'samba_client_container_cmd', None) -- 2.39.5