Skip to content

Commit

Permalink
[Backport] Revert "unbundle agent and remove associated code (#31228)" (
Browse files Browse the repository at this point in the history
#31796) (#32160)

Co-authored-by: Alex Lopez <[email protected]>
  • Loading branch information
Pythyu and alopezz authored Dec 13, 2024
1 parent b095396 commit 2fcc87a
Show file tree
Hide file tree
Showing 12 changed files with 352 additions and 17 deletions.
32 changes: 32 additions & 0 deletions cmd/agent/launcher/launcher.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#ifndef DD_AGENT_PATH
#error DD_AGENT_PATH must be defined
#endif

#ifndef DD_AGENT
#define DD_AGENT "agent"
#endif

int main(int argc, char **argv) {
if (argc > 1) {
argv[0] = DD_AGENT;
} else {
argv = malloc(sizeof(char *) * 2);
argv[0] = DD_AGENT;
argv[1] = NULL;
}

if (strlen(DD_AGENT_PATH) == 0) {
fprintf(stderr, "Cannot determine agent location\n");
exit(1);
}

setenv("DD_BUNDLED_AGENT", DD_AGENT, 0);

execvp(DD_AGENT_PATH, argv);
return 1;
}
51 changes: 50 additions & 1 deletion cmd/agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,62 @@
package main

import (
"fmt"
"os"
"path"
"strings"

"github.com/DataDog/datadog-agent/cmd/agent/command"
"github.com/DataDog/datadog-agent/cmd/agent/subcommands"
"github.com/DataDog/datadog-agent/cmd/internal/runcmd"
"github.com/spf13/cobra"
)

var agents = map[string]func() *cobra.Command{}

func registerAgent(names []string, getCommand func() *cobra.Command) {
for _, name := range names {
agents[name] = getCommand
}
}

func coreAgentMain() *cobra.Command {
return command.MakeCommand(subcommands.AgentSubcommands())
}

func init() {
registerAgent([]string{"agent", "datadog-agent", "dd-agent"}, coreAgentMain)
}

func main() {
os.Exit(runcmd.Run(command.MakeCommand(subcommands.AgentSubcommands())))
process := strings.TrimSpace(os.Getenv("DD_BUNDLED_AGENT"))

if process == "" {
if len(os.Args) > 0 {
process = strings.TrimSpace(path.Base(os.Args[0]))
}

if process == "" {
executable, err := os.Executable()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to determine the Agent process name: %s\n", err.Error())
os.Exit(1)
}
process = executable
}

process = strings.TrimSuffix(process, path.Ext(process))
}

agentCmdBuilder := agents[process]
if agentCmdBuilder == nil {
fmt.Fprintf(os.Stderr, "Invoked as '%s', acting as main Agent.\n", process)
agentCmdBuilder = coreAgentMain
}

rootCmd := agentCmdBuilder()
if err := setProcessName(process); err != nil {
fmt.Fprintf(os.Stderr, "Failed to set process name as '%s': %s\n", process, err)
}
os.Exit(runcmd.Run(rootCmd))
}
13 changes: 13 additions & 0 deletions cmd/agent/main_common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build !linux

package main

// nolint: deadcode, unused
func setProcessName(_ string) error {
return nil
}
42 changes: 42 additions & 0 deletions cmd/agent/main_linux_cgo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build linux && cgo

package main

/*
#include <errno.h>
#include <sys/prctl.h>
#include <stdlib.h>
int prctl_err = 0;
int set_process_name () __attribute__((constructor));
int set_process_name()
{
const char *name = getenv("DD_BUNDLED_AGENT");
if (name != NULL) {
int ret = prctl(PR_SET_NAME, name, 0, 0);
if (!ret) {
prctl_err = errno;
}
return ret;
}
return 0;
}
*/
import (
"C"
)
import "syscall"

func setProcessName(_ string) error {
if C.prctl_err == 0 {
return nil
}
return syscall.Errno(C.prctl_err)
}
22 changes: 22 additions & 0 deletions cmd/agent/main_linux_no_cgo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build linux && !cgo

package main

import (
"syscall"
"unsafe"

"golang.org/x/sys/unix"
)

func setProcessName(process string) error {
processName := make([]byte, len(process)+1)
copy(processName, process)
_, _, err := syscall.AllThreadsSyscall(unix.SYS_PRCTL, unix.PR_SET_NAME, uintptr(unsafe.Pointer(&processName[0])), 0)
return err
}
26 changes: 26 additions & 0 deletions cmd/agent/process_agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build !windows && bundle_process_agent

// Main package for the agent binary
package main

import (
"os"

processcommand "github.com/DataDog/datadog-agent/cmd/process-agent/command"
processsubcommands "github.com/DataDog/datadog-agent/cmd/process-agent/subcommands"
"github.com/DataDog/datadog-agent/pkg/util/flavor"
"github.com/spf13/cobra"
)

func init() {
registerAgent([]string{"process-agent"}, func() *cobra.Command {
flavor.SetFlavor(flavor.ProcessAgent)
os.Args = processcommand.FixDeprecatedFlags(os.Args, os.Stdout)
return processcommand.MakeCommand(processsubcommands.ProcessAgentSubcommands(), processcommand.UseWinParams, processcommand.RootCmdRun)
})
}
23 changes: 23 additions & 0 deletions cmd/agent/security_agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build !windows && bundle_security_agent

// Main package for the agent binary
package main

import (
seccommand "github.com/DataDog/datadog-agent/cmd/security-agent/command"
secsubcommands "github.com/DataDog/datadog-agent/cmd/security-agent/subcommands"
"github.com/DataDog/datadog-agent/pkg/util/flavor"
"github.com/spf13/cobra"
)

func init() {
registerAgent([]string{"security-agent"}, func() *cobra.Command {
flavor.SetFlavor(flavor.SecurityAgent)
return seccommand.MakeCommand(secsubcommands.SecurityAgentSubcommands())
})
}
23 changes: 23 additions & 0 deletions cmd/agent/system_probe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build !windows && bundle_system_probe

// Main package for the agent binary
package main

import (
sysprobecommand "github.com/DataDog/datadog-agent/cmd/system-probe/command"
sysprobesubcommands "github.com/DataDog/datadog-agent/cmd/system-probe/subcommands"
"github.com/spf13/cobra"
)

func init() {
registerAgent([]string{"system-probe"}, func() *cobra.Command {
rootCmd := sysprobecommand.MakeCommand(sysprobesubcommands.SysprobeSubcommands())
sysprobecommand.SetDefaultCommandIfNonePresent(rootCmd)
return rootCmd
})
}
23 changes: 23 additions & 0 deletions cmd/agent/trace_agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.

//go:build !windows && bundle_trace_agent

// Main package for the agent binary
package main

import (
"os"

tracecommand "github.com/DataDog/datadog-agent/cmd/trace-agent/command"
"github.com/spf13/cobra"
)

func init() {
registerAgent([]string{"trace-agent"}, func() *cobra.Command {
os.Args = tracecommand.FixDeprecatedFlags(os.Args, os.Stdout)
return tracecommand.MakeRootCommand()
})
}
24 changes: 24 additions & 0 deletions docs/dev/agent_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,30 @@ Also note that the trace agent needs to be built and run separately. For more in
We use `pkg-config` to make compilers and linkers aware of Python. The required .pc files are
provided automatically when building python through omnibus.

As an option, the Agent can combine multiple functionalities into a single binary to reduce
the space used on disk. The `DD_BUNDLED_AGENT` environment variable is used to select
which functionality to enable. For instance, if set to `process-agent`, it will act as the process Agent.
If the environment variable is not defined, the process name is used as a fallback.
As the last resort meaning, the executable will behave as the 'main' Agent.

Different combinations can be obtained through the usage of build tags. As an example,
building the Agent with the `bundle_process_agent` and `bundle_security_agent` will produce
a binary that has the process Agent and security Agent capabilities.

The `--bundle` argument can be used to override the default set of functionalities bundled
into the Agent binary. For instance, to override the defaults and bundle only the process and
and the security Agents:

```
deva agent.build --bundle process-agent --bundle security-agent
```

To disable bundling entirely:

```
deva agent.build --bundle agent
```

## Testing Agent changes in containerized environments

Building an Agent Docker image from scratch through an embedded build is a slow process.
Expand Down
22 changes: 16 additions & 6 deletions omnibus/config/software/datadog-agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
build do
license :project_license

bundled_agents = []
if heroku_target?
bundled_agents = ["process-agent"]
end

# set GOPATH on the omnibus source dir for this software
gopath = Pathname.new(project_dir) + '../../../..'
msgoroot = "/usr/local/msgo"
Expand Down Expand Up @@ -83,15 +88,16 @@
command "inv -e rtloader.clean"
command "inv -e rtloader.make --install-prefix \"#{install_dir}/embedded\" --cmake-options '-DCMAKE_CXX_FLAGS:=\"-D_GLIBCXX_USE_CXX11_ABI=0\" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_FIND_FRAMEWORK:STRING=NEVER -DPython3_EXECUTABLE=#{install_dir}/embedded/bin/python3'", :env => env
command "inv -e rtloader.install"
bundle_arg = bundled_agents ? bundled_agents.map { |k| "--bundle #{k}" }.join(" ") : "--bundle agent"

include_sds = ""
if linux_target?
include_sds = "--include-sds" # we only support SDS on Linux targets for now
end
command "inv -e agent.build --exclude-rtloader #{include_sds} --major-version #{major_version_arg} --rebuild --no-development --install-path=#{install_dir} --embedded-path=#{install_dir}/embedded --flavor #{flavor_arg}", env: env
command "inv -e agent.build --exclude-rtloader #{include_sds} --major-version #{major_version_arg} --no-development --install-path=#{install_dir} --embedded-path=#{install_dir}/embedded --flavor #{flavor_arg} #{bundle_arg}", env: env

if heroku_target?
command "inv -e agent.build --exclude-rtloader --major-version #{major_version_arg} --rebuild --no-development --install-path=#{install_dir} --embedded-path=#{install_dir}/embedded --flavor #{flavor_arg} --agent-bin=bin/agent/core-agent", env: env
command "inv -e agent.build --exclude-rtloader --major-version #{major_version_arg} --no-development --install-path=#{install_dir} --embedded-path=#{install_dir}/embedded --flavor #{flavor_arg} --agent-bin=bin/agent/core-agent --bundle agent", env: env
end
end

Expand Down Expand Up @@ -120,8 +126,10 @@
mkdir Omnibus::Config.package_dir() unless Dir.exists?(Omnibus::Config.package_dir())
end

platform = windows_arch_i386? ? "x86" : "x64"
command "invoke trace-agent.build --install-path=#{install_dir} --major-version #{major_version_arg} --flavor #{flavor_arg}", :env => env
if not bundled_agents.include? "trace-agent"
platform = windows_arch_i386? ? "x86" : "x64"
command "invoke trace-agent.build --install-path=#{install_dir} --major-version #{major_version_arg} --flavor #{flavor_arg}", :env => env
end

if windows_target?
copy 'bin/trace-agent/trace-agent.exe', "#{install_dir}/bin/agent"
Expand All @@ -130,7 +138,9 @@
end

# Process agent
command "invoke -e process-agent.build --install-path=#{install_dir} --major-version #{major_version_arg} --flavor #{flavor_arg}", :env => env
if not bundled_agents.include? "process-agent"
command "invoke -e process-agent.build --install-path=#{install_dir} --major-version #{major_version_arg} --flavor #{flavor_arg}", :env => env
end

if windows_target?
copy 'bin/process-agent/process-agent.exe', "#{install_dir}/bin/agent"
Expand Down Expand Up @@ -180,7 +190,7 @@
copy 'bin/cws-instrumentation/cws-instrumentation', "#{install_dir}/embedded/bin"
end

# OTel agent
# OTel agent - can never be bundled
if ot_target?
unless windows_target?
command "invoke -e otel-agent.build", :env => env
Expand Down
Loading

0 comments on commit 2fcc87a

Please sign in to comment.