Skip to content

Commit

Permalink
Support gateway mode for linux installer (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffreyc-splunk authored Apr 1, 2021
1 parent db5856d commit a4dd11d
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 29 deletions.
9 changes: 6 additions & 3 deletions internal/buildscripts/packaging/fpm/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ SERVICE_USER="splunk-otel-collector"
SERVICE_GROUP="splunk-otel-collector"

OTELCOL_INSTALL_PATH="/usr/bin/otelcol"
CONFIG_REPO_PATH="$REPO_DIR/cmd/otelcol/config/collector/agent_config.yaml"
CONFIG_INSTALL_PATH="/etc/otel/collector/agent_config.yaml"
AGENT_CONFIG_REPO_PATH="$REPO_DIR/cmd/otelcol/config/collector/agent_config.yaml"
AGENT_CONFIG_INSTALL_PATH="/etc/otel/collector/agent_config.yaml"
GATEWAY_CONFIG_REPO_PATH="$REPO_DIR/cmd/otelcol/config/collector/gateway_config.yaml"
GATEWAY_CONFIG_INSTALL_PATH="/etc/otel/collector/gateway_config.yaml"
SERVICE_REPO_PATH="$FPM_DIR/$SERVICE_NAME.service"
SERVICE_INSTALL_PATH="/lib/systemd/system/$SERVICE_NAME.service"

Expand Down Expand Up @@ -107,7 +109,8 @@ setup_files_and_permissions() {
sudo chmod 755 "$buildroot/$OTELCOL_INSTALL_PATH"

cp -r "$FPM_DIR/etc" "$buildroot/etc"
cp -f "$CONFIG_REPO_PATH" "$buildroot/$CONFIG_INSTALL_PATH"
cp -f "$AGENT_CONFIG_REPO_PATH" "$buildroot/$AGENT_CONFIG_INSTALL_PATH"
cp -f "$GATEWAY_CONFIG_REPO_PATH" "$buildroot/$GATEWAY_CONFIG_INSTALL_PATH"
sudo chown -R $SERVICE_USER:$SERVICE_GROUP "$buildroot/etc/otel"
sudo chmod -R 755 "$buildroot/etc/otel"
sudo chmod 600 "$buildroot/etc/otel/collector/$SERVICE_NAME.conf.example"
Expand Down
3 changes: 2 additions & 1 deletion internal/buildscripts/packaging/fpm/deb/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ sudo fpm -s dir -t deb -n "$PKG_NAME" -v "$VERSION" -f -p "$OUTPUT_DIR" \
--after-install "$POSTINSTALL_PATH" \
--before-remove "$PREUNINSTALL_PATH" \
--deb-no-default-config-files \
--config-files "$CONFIG_INSTALL_PATH" \
--config-files "$AGENT_CONFIG_INSTALL_PATH" \
--config-files "$GATEWAY_CONFIG_INSTALL_PATH" \
--config-files "$FLUENTD_CONFIG_INSTALL_DIR" \
"$buildroot/"=/

Expand Down
3 changes: 2 additions & 1 deletion internal/buildscripts/packaging/fpm/rpm/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ sudo fpm -s dir -t rpm -n "$PKG_NAME" -v "$VERSION" -f -p "$OUTPUT_DIR" \
--before-install "$PREINSTALL_PATH" \
--after-install "$POSTINSTALL_PATH" \
--before-remove "$PREUNINSTALL_PATH" \
--config-files "$CONFIG_INSTALL_PATH" \
--config-files "$AGENT_CONFIG_INSTALL_PATH" \
--config-files "$GATEWAY_CONFIG_INSTALL_PATH" \
--config-files "$FLUENTD_CONFIG_INSTALL_DIR" \
"$buildroot/"=/

Expand Down
53 changes: 48 additions & 5 deletions internal/buildscripts/packaging/installer/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ get_distro_codename() {
}

collector_config_dir="/etc/otel/collector"
collector_config_path="${collector_config_dir}/agent_config.yaml"
collector_config_old_path="${collector_config_dir}/splunk_config_linux.yaml"
agent_config_path="${collector_config_dir}/agent_config.yaml"
gateway_config_path="${collector_config_dir}/gateway_config.yaml"
old_config_path="${collector_config_dir}/splunk_config_linux.yaml"
collector_env_path="${collector_config_dir}/splunk-otel-collector.conf"
collector_env_old_path="${collector_config_dir}/splunk_env"
collector_bundle_dir="/usr/lib/splunk-otel-collector/agent-bundle"
Expand Down Expand Up @@ -514,6 +515,7 @@ Options:
(default: https://ingest.REALM.signalfx.com)
--memory <memory size> Total memory in MIB to allocate to the collector; automatically calculates the ballast size
(default: "$default_memory_size")
--mode <agent|gateway> Configure the collector service to run in agent or gateway mode (default: "agent")
--realm <us0|us1|eu0|...> The Splunk realm to use (default: "$default_realm")
The ingest, api, trace, and HEC endpoint URLs will automatically be inferred by this value
--service-group <group> Set the group for the splunk-otel-collector service (default: "$default_service_group")
Expand Down Expand Up @@ -549,7 +551,9 @@ parse_args_and_install() {
local td_agent_version="$default_td_agent_version"
local trace_url=
local uninstall="false"
local mode="agent"
local with_fluentd="true"
local collector_config_path=

while [ -n "${1-}" ]; do
case $1 in
Expand Down Expand Up @@ -591,6 +595,18 @@ parse_args_and_install() {
memory="$2"
shift 1
;;
--mode)
case $2 in
agent|gateway)
mode="$2"
;;
*)
echo "Unsupported mode '$2'" >&2
exit 1
;;
esac
shift 1
;;
--realm)
realm="$2"
shift 1
Expand Down Expand Up @@ -701,12 +717,39 @@ parse_args_and_install() {
create_user_group "$service_user" "$service_group"
configure_service_owner "$service_user" "$service_group"

if [ "$mode" = "agent" ]; then
if [ -f "$agent_config_path" ]; then
# use the agent config if the installed package includes it
collector_config_path="$agent_config_path"
elif [ -f "$old_config_path" ]; then
# use the old config if the installed package does not include the new agent config
collector_config_path="$old_config_path"
fi
else
if [ -f "$gateway_config_path" ]; then
# use the gateway config if the installed package includes it
collector_config_path="$gateway_config_path"
elif [ -f "$agent_config_path" ]; then
# use the agent config if the installed package includes it
collector_config_path="$agent_config_path"
elif [ -f "$old_config_path" ]; then
# use the old config if the installed package does not include the new agent or gateway config
collector_config_path="$old_config_path"
fi
fi

if [ -z "$collector_config_path" ]; then
echo "ERROR: The installed splunk-otel-collector package does not include a supported config file!" >&2
exit 1
elif [ ! -f "$collector_config_path" ]; then
echo "ERROR: Config file $collector_config_path not found!" >&2
exit 1
fi

if [ ! -f "${collector_env_path}.example" ]; then
collector_env_path=$collector_env_old_path
fi
if [ ! -f "${collector_config_path}" ]; then
collector_config_path=$collector_config_old_path
fi

configure_env_file "SPLUNK_CONFIG" "$collector_config_path" "$collector_env_path"
configure_env_file "SPLUNK_ACCESS_TOKEN" "$access_token" "$collector_env_path"
configure_env_file "SPLUNK_REALM" "$realm" "$collector_env_path"
Expand Down
156 changes: 140 additions & 16 deletions internal/buildscripts/packaging/tests/installer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,23 @@

SPLUNK_ENV_PATH = "/etc/otel/collector/splunk-otel-collector.conf"
OLD_SPLUNK_ENV_PATH = "/etc/otel/collector/splunk_env"
AGENT_CONFIG_PATH = "/etc/otel/collector/agent_config.yaml"
GATEWAY_CONFIG_PATH = "/etc/otel/collector/gateway_config.yaml"
OLD_CONFIG_PATH = "/etc/otel/collector/splunk_config_linux.yaml"
TOTAL_MEMORY = "256"
BALLAST = "128"


@pytest.mark.installer
@pytest.mark.parametrize(
"distro",
[pytest.param(distro, marks=pytest.mark.deb) for distro in DEB_DISTROS]
+ [pytest.param(distro, marks=pytest.mark.rpm) for distro in RPM_DISTROS],
)
@pytest.mark.parametrize("version", VERSIONS)
@pytest.mark.parametrize("memory_option", ["memory", "ballast"])
def test_installer(distro, version, memory_option):
install_cmd = f"sh -x /test/install.sh -- testing123 --realm us0"

if memory_option == "memory":
install_cmd = f"{install_cmd} --{memory_option} {TOTAL_MEMORY}"
elif memory_option == "ballast":
install_cmd = f"{install_cmd} --{memory_option} {BALLAST}"
@pytest.mark.parametrize("mode", ["agent", "gateway"])
def test_installer_mode(distro, version, mode):
install_cmd = f"sh -x /test/install.sh -- testing123 --realm us0 --memory {TOTAL_MEMORY} --mode {mode}"

if version != "latest":
install_cmd = f"{install_cmd} --collector-version {version.lstrip('v')}"
Expand All @@ -74,16 +73,20 @@ def test_installer(distro, version, memory_option):
run_container_cmd(container, install_cmd, env={"VERIFY_ACCESS_TOKEN": "false"})
time.sleep(5)

config_path = AGENT_CONFIG_PATH if mode == "agent" else GATEWAY_CONFIG_PATH
if container.exec_run(f"test -f {OLD_CONFIG_PATH}").exit_code == 0:
config_path = OLD_CONFIG_PATH
elif mode == "gateway" and container.exec_run(f"test -f {GATEWAY_CONFIG_PATH}").exit_code != 0:
config_path = AGENT_CONFIG_PATH

# verify env file created with configured parameters
splunk_env_path = SPLUNK_ENV_PATH
if container.exec_run(f"test -f {OLD_SPLUNK_ENV_PATH}").exit_code == 0:
splunk_env_path = OLD_SPLUNK_ENV_PATH
run_container_cmd(container, f"grep '^SPLUNK_CONFIG={config_path}$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_ACCESS_TOKEN=testing123$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_REALM=us0$' {splunk_env_path}")
if memory_option == "memory":
run_container_cmd(container, f"grep '^SPLUNK_MEMORY_TOTAL_MIB={TOTAL_MEMORY}$' {splunk_env_path}")
elif memory_option == "ballast":
run_container_cmd(container, f"grep '^SPLUNK_BALLAST_SIZE_MIB={BALLAST}$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_MEMORY_TOTAL_MIB={TOTAL_MEMORY}$' {splunk_env_path}")

# verify collector service status
assert wait_for(lambda: service_is_running(container, service_owner=SERVICE_OWNER))
Expand Down Expand Up @@ -112,6 +115,66 @@ def test_installer(distro, version, memory_option):
assert container.exec_run("test -f /tmp/splunk-support-bundle.tar.gz").exit_code == 0

run_container_cmd(container, "sh -x /test/install.sh --uninstall")

finally:
run_container_cmd(container, "journalctl -u td-agent --no-pager")
if container.exec_run("test -f /var/log/td-agent/td-agent.log").exit_code == 0:
run_container_cmd(container, "cat /var/log/td-agent/td-agent.log")
run_container_cmd(container, f"journalctl -u {SERVICE_NAME} --no-pager")


@pytest.mark.installer
@pytest.mark.parametrize(
"distro",
[pytest.param(distro, marks=pytest.mark.deb) for distro in DEB_DISTROS]
+ [pytest.param(distro, marks=pytest.mark.rpm) for distro in RPM_DISTROS],
)
@pytest.mark.parametrize("version", VERSIONS)
def test_installer_ballast(distro, version):
install_cmd = f"sh -x /test/install.sh -- testing123 --realm us0 --ballast {BALLAST}"

if version != "latest":
install_cmd = f"{install_cmd} --collector-version {version.lstrip('v')}"

if STAGE != "release":
assert STAGE in ("test", "beta"), f"Unsupported stage '{STAGE}'!"
install_cmd = f"{install_cmd} --{STAGE}"

print(f"Testing installation on {distro} from {STAGE} stage ...")
with run_distro_container(distro) as container:
# run installer script
copy_file_into_container(container, INSTALLER_PATH, "/test/install.sh")

try:
run_container_cmd(container, install_cmd, env={"VERIFY_ACCESS_TOKEN": "false"})
time.sleep(5)

config_path = AGENT_CONFIG_PATH
if container.exec_run(f"test -f {OLD_CONFIG_PATH}").exit_code == 0:
config_path = OLD_CONFIG_PATH

splunk_env_path = SPLUNK_ENV_PATH
if container.exec_run(f"test -f {OLD_SPLUNK_ENV_PATH}").exit_code == 0:
splunk_env_path = OLD_SPLUNK_ENV_PATH

# verify env file created with configured parameters
run_container_cmd(container, f"grep '^SPLUNK_CONFIG={config_path}$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_ACCESS_TOKEN=testing123$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_REALM=us0$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_BALLAST_SIZE_MIB={BALLAST}$' {splunk_env_path}")

# verify collector service status
assert wait_for(lambda: service_is_running(container, service_owner=SERVICE_OWNER))

# the td-agent service should only be running when installing
# collector packages that have our custom fluent config
if container.exec_run("test -f /etc/otel/collector/fluentd/fluent.conf").exit_code == 0:
assert container.exec_run("systemctl status td-agent").exit_code == 0
else:
assert container.exec_run("systemctl status td-agent").exit_code != 0

run_container_cmd(container, "sh -x /test/install.sh --uninstall")

finally:
run_container_cmd(container, "journalctl -u td-agent --no-pager")
if container.exec_run("test -f /var/log/td-agent/td-agent.log").exit_code == 0:
Expand Down Expand Up @@ -140,16 +203,23 @@ def test_installer_service_owner(distro, version):

print(f"Testing installation on {distro} from {STAGE} stage ...")
with run_distro_container(distro) as container:
# run installer script
copy_file_into_container(container, INSTALLER_PATH, "/test/install.sh")
run_container_cmd(container, install_cmd, env={"VERIFY_ACCESS_TOKEN": "false"})
time.sleep(5)

try:
# verify env file created with configured parameters
# run installer script
run_container_cmd(container, install_cmd, env={"VERIFY_ACCESS_TOKEN": "false"})
time.sleep(5)

config_path = AGENT_CONFIG_PATH
if container.exec_run(f"test -f {OLD_CONFIG_PATH}").exit_code == 0:
config_path = OLD_CONFIG_PATH

splunk_env_path = SPLUNK_ENV_PATH
if container.exec_run(f"test -f {OLD_SPLUNK_ENV_PATH}").exit_code == 0:
splunk_env_path = OLD_SPLUNK_ENV_PATH

# verify env file created with configured parameters
run_container_cmd(container, f"grep '^SPLUNK_CONFIG={config_path}$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_ACCESS_TOKEN=testing123$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_REALM=us0$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_MEMORY_TOTAL_MIB={TOTAL_MEMORY}$' {splunk_env_path}")
Expand All @@ -167,3 +237,57 @@ def test_installer_service_owner(distro, version):
finally:
run_container_cmd(container, "journalctl -u td-agent --no-pager")
run_container_cmd(container, f"journalctl -u {SERVICE_NAME} --no-pager")


@pytest.mark.installer
@pytest.mark.parametrize(
"distro",
[pytest.param(distro, marks=pytest.mark.deb) for distro in DEB_DISTROS]
+ [pytest.param(distro, marks=pytest.mark.rpm) for distro in RPM_DISTROS],
)
@pytest.mark.parametrize("version", VERSIONS)
def test_installer_without_fluentd(distro, version):
install_cmd = f"sh -x /test/install.sh -- testing123 --realm us0 --memory {TOTAL_MEMORY} --without-fluentd"

if version != "latest":
install_cmd = f"{install_cmd} --collector-version {version.lstrip('v')}"

if STAGE != "release":
assert STAGE in ("test", "beta"), f"Unsupported stage '{STAGE}'!"
install_cmd = f"{install_cmd} --{STAGE}"

print(f"Testing installation on {distro} from {STAGE} stage ...")
with run_distro_container(distro) as container:
copy_file_into_container(container, INSTALLER_PATH, "/test/install.sh")

try:
# run installer script
run_container_cmd(container, install_cmd, env={"VERIFY_ACCESS_TOKEN": "false"})
time.sleep(5)

config_path = AGENT_CONFIG_PATH
if container.exec_run(f"test -f {OLD_CONFIG_PATH}").exit_code == 0:
config_path = OLD_CONFIG_PATH

splunk_env_path = SPLUNK_ENV_PATH
if container.exec_run(f"test -f {OLD_SPLUNK_ENV_PATH}").exit_code == 0:
splunk_env_path = OLD_SPLUNK_ENV_PATH

# verify env file created with configured parameters
run_container_cmd(container, f"grep '^SPLUNK_CONFIG={config_path}$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_ACCESS_TOKEN=testing123$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_REALM=us0$' {splunk_env_path}")
run_container_cmd(container, f"grep '^SPLUNK_MEMORY_TOTAL_MIB={TOTAL_MEMORY}$' {splunk_env_path}")

# verify collector service status
assert wait_for(lambda: service_is_running(container, service_owner=SERVICE_OWNER))

if distro in DEB_DISTROS:
assert container.exec_run("dpkg -s td-agent").exit_code != 0
else:
assert container.exec_run("rpm -q td-agent").exit_code != 0

run_container_cmd(container, "sh -x /test/install.sh --uninstall")

finally:
run_container_cmd(container, f"journalctl -u {SERVICE_NAME} --no-pager")
11 changes: 8 additions & 3 deletions internal/buildscripts/packaging/tests/package_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ def test_collector_package_install(distro):
service_name = "splunk-otel-collector"
service_owner = "splunk-otel-collector"
service_proc = "otelcol"
config_path = "/etc/otel/collector/splunk-otel-collector.conf"
env_path = "/etc/otel/collector/splunk-otel-collector.conf"
agent_config_path = "/etc/otel/collector/agent_config.yaml"
gateway_config_path = "/etc/otel/collector/gateway_config.yaml"
bundle_dir = "/usr/lib/splunk-otel-collector/agent-bundle"

pkg_path = get_package(distro, pkg_name, pkg_dir)
Expand All @@ -75,12 +77,15 @@ def test_collector_package_install(distro):
run_container_cmd(container, f"test -d {bundle_dir}")
run_container_cmd(container, f"test -d {bundle_dir}/run/collectd")

run_container_cmd(container, f"test -f {agent_config_path}")
run_container_cmd(container, f"test -f {gateway_config_path}")

# verify service is not running after install without config file
time.sleep(5)
assert not service_is_running(container, service_name, service_owner, service_proc)

# verify service starts with config file
run_container_cmd(container, f"cp -f {config_path}.example {config_path}")
run_container_cmd(container, f"cp -f {env_path}.example {env_path}")
run_container_cmd(container, f"systemctl start {service_name}")
time.sleep(5)
assert wait_for(lambda: service_is_running(container, service_name, service_owner, service_proc))
Expand Down Expand Up @@ -111,4 +116,4 @@ def test_collector_package_install(distro):
assert not service_is_running(container, service_name, service_owner, service_proc)

# verify config file is not removed
run_container_cmd(container, f"test -f {config_path}")
run_container_cmd(container, f"test -f {env_path}")

0 comments on commit a4dd11d

Please sign in to comment.