Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,34 @@ config_setting(
],
)

# The location base dir to install packages in while building.
# The location that the bulk of the agent gets installed to. Like most *nix tools, this
# is in /opt. That will hold shared libraries, and python packages. It is not the
# complete installation, becuase some things go to /etc or /usr.
#
# Migration to bazel warning:
# The goal we are aiming for is that output base is always passed to build
# scripts and we install artifacts to output_base + install_dir. Unfortunately,
# many existing scripts only use install_dir, without regard to a a base. They
# put etc files under opt/datadog, then move them to /etc in the final part of the
# build.
# TODO: We need to learn how people expect to use install dir to create custom
# builds for local testing that do not wipe out their local installation.
string_flag(
name = "install_dir",
build_setting_default = "/tmp/opt/datadog-agent",
build_setting_default = "/opt/datadog-agent",
make_variable = "INSTALL_DIR",
)

# This seems to be the base of where to write config files during
# the build. That is, if we were creating /etc/foo, it would be
# the path prepended to /etc to get a safe place to write.
# We can set this from the omnibus variable OUTPUT_CONFIG_DIR.
# But, it seems to be empty in CI runs, so we end up writing to /.
# The default is /tmp so we don't shoot our feet off in local testing.
# If we end up keeping this flag, let's give it a better name and
# git it a better value.
string_flag(
name = "output_config_dir",
build_setting_default = "/tmp",
make_variable = "OUTPUT_CONFIG_DIR",
)
79 changes: 79 additions & 0 deletions bazel/rules/dd_agent_expand_template.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""dd_agent_expand_template. Expand a template, splicing in agent specific flags."""

load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")

# The place we will install to if we run bazel pkg_install without a destdir
# We use /tmp for lack of a better safe space.
DEFAULT_OUTPUT_CONFIG_DIR = "/tmp"

# The location where the product should be installed on a user system.
DEFAULT_PRODUCT_DIR = "/opt/datadog-agent"

def _dd_agent_expand_template_impl(ctx):
# Set up a fallback default.
# TODO: should this be different for windows? Or should we have different variables for windows?
subs = {}
subs["{output_config_dir}"] = DEFAULT_OUTPUT_CONFIG_DIR
if ctx.attr._output_config_dir:
if BuildSettingInfo in ctx.attr._output_config_dir:
output_config_dir = ctx.attr._output_config_dir[BuildSettingInfo].value.rstrip("/")
subs["{output_config_dir}"] = output_config_dir
subs["{install_dir}"] = DEFAULT_PRODUCT_DIR
if ctx.attr._install_dir:
if BuildSettingInfo in ctx.attr._install_dir:
install_dir = ctx.attr._install_dir[BuildSettingInfo].value
subs["{install_dir}"] = install_dir

# TODO: decide if we should default etc to the output base or relative to install_dir.
# There are use cases for either. For now, we are relative to the output base.
subs["{etc_dir}"] = subs["{output_config_dir}"] + "/etc"

# Now let local substitutions override the flags.
subs.update(ctx.attr.substitutions)

# let's add a little flavor. We don't need this today but it will be
# needed if we expand things like the file name of an artifact and we want
# to show compliation mode. This mostly shows the technique.
subs["{TARGET_CPU}"] = ctx.var["TARGET_CPU"]
subs["{COMPILATION_MODE}"] = ctx.var["COMPILATION_MODE"]

ctx.actions.expand_template(
template = ctx.file.template,
output = ctx.outputs.out,
substitutions = subs,
)

dd_agent_expand_template = rule(
implementation = _dd_agent_expand_template_impl,
doc = """Template expansion

This performs a simple search over the template file for the keys in
substitutions, and replaces them with the corresponding values. There are
some default substitutions which are computed from the build environment.

Default substitutions:
{install_dir}: The value of the flag //:install_dir
{output_config_dir}: The value of the flag //:output_config_dir
{etc_dir}: The output_config_dir + "/etc"
{TARGET_CPU}: Target CPU arch
{COMPILATION_MODE}: usually fastbuild, opt, or release.

There is no special syntax for the keys from substitutions. To avoid conflicts, you would need to
explicitly add delimiters to the key strings, for example "{KEY}" or "@KEY@".""",
attrs = {
"template": attr.label(
mandatory = True,
allow_single_file = True,
doc = "The template file to expand.",
),
"substitutions": attr.string_dict(
doc = "A dictionary mapping strings to their substitutions. These take precedence over flags.",
),
"out": attr.output(
mandatory = True,
doc = "The destination of the expanded file.",
),
"_install_dir": attr.label(default = "@@//:install_dir"),
"_output_config_dir": attr.label(default = "@@//:output_config_dir"),
},
)
12 changes: 8 additions & 4 deletions omnibus/config/software/init-scripts-agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@
description "Generate and configure init scripts packaging"

always_build true
skip_transitive_dependency_licensing true

build do
destdir = ENV["OMNIBUS_BASE_DIR"] || "/"
output_config_dir = ENV["OUTPUT_CONFIG_DIR"] || ""
if linux_target?
etc_dir = "#{output_config_dir}/etc/datadog-agent"
mkdir "/etc/init"
if debian_target?
# building into / is not acceptable. We'll continue to to that for now,
# but the replacement has to build to a build output tree.
command_on_repo_root "bazelisk run --//:output_config_dir='#{output_config_dir}' --//:install_dir=#{install_dir} -- //packages/debian/etc:install --verbose --destdir=#{destdir}"
command_on_repo_root "cp bazel-bin/packages/debian/etc/etc/init/datadog-agent.conf /etc/init"

# sysvinit support for debian only for now
mkdir "/etc/init.d"

erb source: "upstart_debian.conf.erb",
dest: "/etc/init/datadog-agent.conf",
mode: 0644,
vars: { install_dir: install_dir, etc_dir: etc_dir }
erb source: "upstart_debian.process.conf.erb",
dest: "/etc/init/datadog-agent-process.conf",
mode: 0644,
Expand Down Expand Up @@ -58,6 +61,7 @@
mode: 0755,
vars: { install_dir: install_dir, etc_dir: etc_dir }

project.extra_package_file '/etc/init/datadog-agent.conf'
project.extra_package_file '/etc/init.d/datadog-agent'
project.extra_package_file '/etc/init.d/datadog-agent-process'
project.extra_package_file '/etc/init.d/datadog-agent-trace'
Expand Down
30 changes: 30 additions & 0 deletions packages/debian/etc/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Rules to build /etc for Debian distributions."""

load("@rules_pkg//pkg:install.bzl", "pkg_install")
load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix")
load("//bazel/rules:dd_agent_expand_template.bzl", "dd_agent_expand_template")

package(default_visibility = ["//packages:__subpackages__"])

dd_agent_expand_template(
name = "gen_etc",
out = "etc/init/datadog-agent.conf",
template = "upstart_debian.conf.in",
)

# TODO: Have dd_agent_expand_template emit a pkg provider, so we
# don't need this intermediary any more.
pkg_files(
name = "all_files",
srcs = [
":gen_etc",
],
strip_prefix = strip_prefix.from_pkg(),
)

pkg_install(
name = "install",
srcs = [
":all_files",
],
)
24 changes: 24 additions & 0 deletions packages/debian/etc/upstart_debian.conf.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
description "Datadog Agent"

start on started networking
stop on runlevel [!2345]

respawn
respawn limit 4 25
normal exit 0

# Logging to console from the agent is disabled since the agent already logs using file or
# syslog depending on its configuration. We make upstart log what the process still outputs in order
# to log panics/crashes to /var/log/upstart/datadog-agent.log
console log
env DD_LOG_TO_CONSOLE=false

setuid dd-agent

script
exec {install_dir}/bin/agent/agent run -p {install_dir}/run/agent.pid
end script

post-stop script
rm -f {install_dir}/run/agent.pid
end script