def test_puppet(base_image, init_system): dockerfile = os.path.join(DOCKERFILES_DIR, "Dockerfile.%s" % base_image) with run_init_system_image(base_image, path=REPO_ROOT_DIR, dockerfile=dockerfile, with_socat=False) as [ cont, backend, ]: if (base_image, init_system) in DEB_DISTROS: code, output = cont.exec_run( f"puppet module install puppetlabs-apt --version {APT_MODULE_VERSION}" ) assert code == 0, output.decode("utf-8") print_lines(output) try: monitors = '{ type => "host-metadata" },' run_puppet_agent(cont, backend, monitors, INITIAL_VERSION, STAGE) assert is_agent_running_as_non_root( cont), "Agent is not running as non-root user" assert wait_for( p(has_datapoint_with_dim, backend, "plugin", "host-metadata")), "Datapoints didn't come through" run_puppet_agent(cont, backend, monitors, UPGRADE_VERSION, STAGE) backend.reset_datapoints() assert is_agent_running_as_non_root( cont), "Agent is not running as non-root user" assert wait_for( p(has_datapoint_with_dim, backend, "plugin", "host-metadata")), "Datapoints didn't come through" run_puppet_agent(cont, backend, monitors, INITIAL_VERSION, STAGE) backend.reset_datapoints() assert is_agent_running_as_non_root( cont), "Agent is not running as non-root user" assert wait_for( p(has_datapoint_with_dim, backend, "plugin", "host-metadata")), "Datapoints didn't come through" monitors = '{ type => "internal-metrics" },' run_puppet_agent(cont, backend, monitors, INITIAL_VERSION, STAGE) backend.reset_datapoints() assert is_agent_running_as_non_root( cont), "Agent is not running as non-root user" assert wait_for( p(has_datapoint_with_metric_name, backend, "sfxagent.datapoints_sent") ), "Didn't get internal metric datapoints" finally: print("Agent log:") print_lines(get_agent_logs(cont, init_system))
def run_ansible(cont, init_system, backend, monitors, agent_version, stage, user="******"): with tempfile.NamedTemporaryFile(mode="w+") as fd: config_yaml = get_config(backend, monitors, agent_version, stage, user) print(config_yaml) fd.write(config_yaml) fd.flush() copy_file_into_container(fd.name, cont, CONFIG_DEST_PATH) code, output = cont.exec_run(ANSIBLE_CMD) assert code == 0, output.decode("utf-8") print_lines(output) verify_override_files(cont, init_system, user) installed_version = get_agent_version(cont).replace("~", "-") agent_version = re.sub(r"-\d+$", "", agent_version).replace("~", "-") assert installed_version == agent_version, "installed agent version is '%s', expected '%s'" % ( installed_version, agent_version, ) assert is_agent_running_as_non_root( cont, user=user), f"Agent is not running as {user} user"
def run_puppet_agent(cont, init_system, backend, monitors, agent_version, stage, user="******"): with tempfile.NamedTemporaryFile(mode="w+") as fd: hiera_yaml = get_hiera(HIERA_SRC_PATH, backend, monitors) print(hiera_yaml) fd.write(hiera_yaml) fd.flush() copy_file_into_container(fd.name, cont, HIERA_DEST_PATH) with tempfile.NamedTemporaryFile(mode="w+") as fd: config = get_config(agent_version, stage, user=user) print(config) fd.write(config) fd.flush() copy_file_into_container(fd.name, cont, "/root/agent.pp") code, output = cont.exec_run("puppet apply /root/agent.pp") assert code in (0, 2), output.decode("utf-8") print_lines(output) verify_override_files(cont, init_system, user) installed_version = get_agent_version(cont) assert installed_version == agent_version, "installed agent version is '%s', expected '%s'" % ( installed_version, agent_version, ) assert is_agent_running_as_non_root( cont, user=user), f"Agent is not running as {user} user"
def test_puppet(base_image, init_system): with run_puppet_agent(base_image, init_system) as [cont, backend]: assert is_agent_running_as_non_root( cont), "Agent is not running as non-root user" assert wait_for( p(has_datapoint_with_dim, backend, "plugin", "host-metadata")), "Datapoints didn't come through"
def _run_tests(base_image, init_system, installer_args, user=None, **extra_run_kwargs): if user: installer_args = f"--service-user {user} --service-group {user} {installer_args}" else: user = "******" with run_init_system_image(base_image, **extra_run_kwargs) as [cont, backend]: copy_file_into_container(INSTALLER_PATH, cont, "/opt/install.sh") # Unfortunately, wget and curl both don't like self-signed certs, even # if they are in the system bundle, so we need to use the --insecure # flag. code, output = cont.exec_run( f"sh /opt/install.sh --insecure {installer_args}") print("Output of install script:") print_lines(output) assert code == 0, "Agent could not be installed!" try: verify_override_files(cont, init_system, user) assert is_agent_running_as_non_root( cont, user), f"Agent is not running as {user} user" yield backend, cont finally: print("Agent log:") print_lines(get_agent_logs(cont, init_system))
def run_chef_client(cont, init_system, chef_version, agent_version, stage, monitors, user="******"): attributes = json.loads(ATTRIBUTES_JSON) attributes["signalfx_agent"]["agent_version"] = agent_version attributes["signalfx_agent"]["package_stage"] = stage attributes["signalfx_agent"]["user"] = user attributes["signalfx_agent"]["group"] = user attributes["signalfx_agent"]["conf"]["monitors"] = monitors print(attributes) with tempfile.NamedTemporaryFile(mode="w", dir="/tmp/scratch") as fd: fd.write(json.dumps(attributes)) fd.flush() cmd = CHEF_CMD.format(fd.name) if chef_version == "latest" or int(chef_version.split(".")[0]) >= 15: cmd += " --chef-license accept-silent" print('running "%s" ...' % cmd) code, output = cont.exec_run(cmd) output = output.decode("utf-8").strip() assert code == 0, "failed to install agent:\n%s" % output print(output) verify_override_files(cont, init_system, user) installed_version = get_agent_version(cont) assert installed_version == agent_version, "installed agent version is '%s', expected '%s'" % ( installed_version, agent_version, ) assert is_agent_running_as_non_root( cont, user=user), f"Agent is not running as {user} user"
def run_puppet_agent(cont, backend, monitors, agent_version, stage): with tempfile.NamedTemporaryFile(mode="w+") as fd: fd.write(get_config(backend, monitors, agent_version, stage)) fd.flush() copy_file_into_container(fd.name, cont, "/root/agent.pp") code, output = cont.exec_run("puppet apply /root/agent.pp") assert code in (0, 2), output.decode("utf-8") print_lines(output) installed_version = get_agent_version(cont) assert installed_version == agent_version, "installed agent version is '%s', expected '%s'" % ( installed_version, agent_version, ) assert is_agent_running_as_non_root(cont), "Agent is not running as non-root user"
def run_chef_client(cont, agent_version=None): attributes = json.loads(ATTRIBUTES_JSON) attributes["signalfx_agent"]["agent_version"] = agent_version print(attributes) with tempfile.NamedTemporaryFile(mode="w", dir="/tmp/scratch") as fd: fd.write(json.dumps(attributes)) fd.flush() print('running "%s" ...' % CHEF_CMD.format(fd.name)) code, output = cont.exec_run(CHEF_CMD.format(fd.name)) output = output.decode("utf-8").strip() assert code == 0, "failed to install agent:\n%s" % output print(output) assert is_agent_running_as_non_root(cont), "Agent is not running as non-root user" return get_agent_version(cont)
def run_chef_client(cont, package_version=None): attributes = json.loads(open(ATTRIBUTES_PATH, "r").read()) attributes["signalfx_agent"]["package_version"] = package_version attributes["signalfx_agent"]["conf"]["ingestUrl"] = "https://ingest.us0.signalfx.com" attributes["signalfx_agent"]["conf"]["apiUrl"] = "https://api.us0.signalfx.com" print(attributes) with tempfile.NamedTemporaryFile(mode="w", dir="/tmp/scratch") as fd: fd.write(json.dumps(attributes)) fd.flush() print('running "%s" ...' % CHEF_CMD.format(fd.name)) code, output = cont.exec_run(CHEF_CMD.format(fd.name)) output = output.decode("utf-8").strip() assert code == 0, "failed to install agent:\n%s" % output print(output) assert is_agent_running_as_non_root(cont), "Agent is not running as non-root user" return get_agent_version(cont)
def run_chef_client(cont, chef_version, agent_version=None, stage="final"): attributes = json.loads(ATTRIBUTES_JSON % stage) attributes["signalfx_agent"]["agent_version"] = agent_version print(attributes) with tempfile.NamedTemporaryFile(mode="w", dir="/tmp/scratch") as fd: fd.write(json.dumps(attributes)) fd.flush() cmd = CHEF_CMD.format(fd.name) if chef_version == "latest" or int(chef_version.split(".")[0]) >= 15: cmd += " --chef-license accept-silent" print('running "%s" ...' % cmd) code, output = cont.exec_run(cmd) output = output.decode("utf-8").strip() assert code == 0, "failed to install agent:\n%s" % output print(output) assert is_agent_running_as_non_root( cont), "Agent is not running as non-root user" return get_agent_version(cont)
def run_salt(cont, backend, agent_version, monitors, stage): with tempfile.NamedTemporaryFile(mode="w+") as fd: config_yaml = get_config(backend, agent_version, monitors, stage) print(config_yaml) fd.write(config_yaml) fd.flush() copy_file_into_container(fd.name, cont, PILLAR_PATH) code, output = cont.exec_run(SALT_CMD) print_lines(output) assert code == 0, f"'{SALT_CMD}' failed" installed_version = get_agent_version(cont) assert installed_version == agent_version, "installed agent version is '%s', expected '%s'" % ( installed_version, agent_version, ) assert is_agent_running_as_non_root( cont), "Agent is not running as non-root user"
def test_bundle_non_root_user(request, base_image): # Get bundle path from command line flag to pytest bundle_path = request.config.getoption("--test-bundle-path") if not bundle_path: raise ValueError( "You must specify the --test-bundle-path flag to run bundle tests") with run_service("activemq") as activemq_container: with run_init_system_image(base_image, command="/usr/bin/tail -f /dev/null") as [ cont, backend ]: code, output = cont.exec_run( "useradd --system --user-group --no-create-home --shell /sbin/nologin test-user" ) assert code == 0, f"failed to create test-user:\n{output.decode('utf-8')}" copy_file_into_container(bundle_path, cont, "/opt/bundle.tar.gz") code, output = cont.exec_run(f"tar -xf /opt/bundle.tar.gz -C /opt") assert code == 0, f"Could not untar bundle: {output}" cont.exec_run("chown -R test-user:test-user /opt/signalfx-agent") code, output = cont.exec_run( f"/opt/signalfx-agent/bin/patch-interpreter /opt/signalfx-agent", user="******") assert code == 0, f"Could not patch interpreter: {output}" write_agent_config(cont, activemq_container) cont.exec_run("chown test-user:test-user /etc/signalfx/agent.yaml") _, output = cont.exec_run( [ "/bin/sh", "-c", "exec /opt/signalfx-agent/bin/signalfx-agent > /opt/signalfx-agent/signalfx-agent.log", ], detach=True, stream=True, user="******", ) try: assert is_agent_running_as_non_root( cont, user="******"), f"agent is not running as test-user" assert wait_for( p(has_datapoint, backend, metric_name="cpu.utilization"), timeout_seconds=10 ), "Python metadata datapoint didn't come through" assert wait_for( p(has_datapoint, backend, metric_name="gauge.amq.queue.QueueSize") ), "Didn't get activemq queue size datapoint" code, output = cont.exec_run( "/opt/signalfx-agent/bin/agent-status", user="******") assert code == 0, f"failed to execute agent-status:\n{output.decode('utf-8')}" finally: print("Agent log:") _, output = cont.exec_run( "cat /opt/signalfx-agent/signalfx-agent.log") print_lines(output)