1import time 2import uuid 3 4import attr 5from saltfactories.daemons.container import SaltMinion 6from saltfactories.utils import ports 7from tests.support.runtests import RUNTIME_VARS 8 9 10@attr.s(kw_only=True, slots=True) 11class SaltVirtMinionContainerFactory(SaltMinion): 12 13 host_uuid = attr.ib(default=attr.Factory(uuid.uuid4)) 14 ssh_port = attr.ib( 15 default=attr.Factory(ports.get_unused_localhost_port), repr=False 16 ) 17 sshd_port = attr.ib(default=attr.Factory(ports.get_unused_localhost_port)) 18 libvirt_tcp_port = attr.ib( 19 default=attr.Factory(ports.get_unused_localhost_port), repr=False 20 ) 21 libvirt_tls_port = attr.ib( 22 default=attr.Factory(ports.get_unused_localhost_port), repr=False 23 ) 24 25 uri = attr.ib(init=False) 26 ssh_uri = attr.ib(init=False) 27 tcp_uri = attr.ib(init=False) 28 tls_uri = attr.ib(init=False) 29 30 def __attrs_post_init__(self): 31 self.uri = "localhost:{}".format(self.sshd_port) 32 self.ssh_uri = "qemu+ssh://{}/system".format(self.uri) 33 self.tcp_uri = "qemu+tcp://localhost:{}/system".format(self.libvirt_tcp_port) 34 self.tls_uri = "qemu+tls://127.0.0.1:{}/system".format(self.libvirt_tls_port) 35 36 # pylint: disable=access-member-before-definition 37 if self.check_ports is None: 38 self.check_ports = [] 39 # pylint: enable=access-member-before-definition 40 self.check_ports.extend( 41 [self.sshd_port, self.libvirt_tcp_port, self.libvirt_tls_port] 42 ) 43 if "environment" not in self.container_run_kwargs: 44 self.container_run_kwargs["environment"] = {} 45 self.container_run_kwargs["environment"].update( 46 { 47 "SSH_PORT": str(self.ssh_port), 48 "SSHD_PORT": str(self.sshd_port), 49 "LIBVIRT_TCP_PORT": str(self.libvirt_tcp_port), 50 "LIBVIRT_TLS_PORT": str(self.libvirt_tls_port), 51 "NO_START_MINION": "1", 52 "HOST_UUID": self.host_uuid, 53 "PYTHONDONTWRITEBYTECODE": "1", 54 } 55 ) 56 if "ports" not in self.container_run_kwargs: 57 self.container_run_kwargs["ports"] = {} 58 self.container_run_kwargs["ports"].update( 59 { 60 "{}/tcp".format(self.ssh_port): self.ssh_port, 61 "{}/tcp".format(self.sshd_port): self.sshd_port, 62 "{}/tcp".format(self.libvirt_tcp_port): self.libvirt_tcp_port, 63 "{}/tcp".format(self.libvirt_tls_port): self.libvirt_tls_port, 64 } 65 ) 66 if "volumes" not in self.container_run_kwargs: 67 self.container_run_kwargs["volumes"] = {} 68 self.container_run_kwargs["volumes"].update( 69 { 70 RUNTIME_VARS.CODE_DIR: {"bind": "/salt", "mode": "z"}, 71 RUNTIME_VARS.CODE_DIR: {"bind": RUNTIME_VARS.CODE_DIR, "mode": "z"}, 72 } 73 ) 74 self.container_run_kwargs["working_dir"] = RUNTIME_VARS.CODE_DIR 75 self.container_run_kwargs["network_mode"] = "host" 76 self.container_run_kwargs["cap_add"] = ["ALL"] 77 self.container_run_kwargs["privileged"] = True 78 super().__attrs_post_init__() 79 self.python_executable = "python3" 80 81 def _container_start_checks(self): 82 # Once we're able to ls the salt-minion script it means the container 83 # has salt installed 84 ret = self.run("ls", "-lah", self.get_script_path()) 85 if ret.exitcode == 0: 86 return True 87 time.sleep(1) 88 return False 89