From fbc748fe981f90152b847f0910e7efb654ef06ec Mon Sep 17 00:00:00 2001 From: Florian Arthofer Date: Mon, 25 Nov 2024 09:10:12 +0100 Subject: [PATCH] Bump libbuildpack-dynatrace to v1.8.0 --- go.mod | 2 +- go.sum | 4 +- .../libbuildpack-dynatrace/.gitignore | 3 + .../libbuildpack-dynatrace/README.md | 4 +- .../Dynatrace/libbuildpack-dynatrace/hook.go | 188 ++++++++---------- .../Dynatrace/libbuildpack-dynatrace/unix.go | 97 +++++++++ .../libbuildpack-dynatrace/windows.go | 99 +++++++++ vendor/modules.txt | 2 +- 8 files changed, 287 insertions(+), 112 deletions(-) create mode 100644 vendor/github.com/Dynatrace/libbuildpack-dynatrace/unix.go create mode 100644 vendor/github.com/Dynatrace/libbuildpack-dynatrace/windows.go diff --git a/go.mod b/go.mod index 5fba7f32..c093e6aa 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/cloudfoundry/nginx-buildpack go 1.22.5 require ( - github.com/Dynatrace/libbuildpack-dynatrace v1.5.2 + github.com/Dynatrace/libbuildpack-dynatrace v1.8.0 github.com/cloudfoundry/libbuildpack v0.0.0-20240716203800-e8e9729b7ef9 github.com/golang/mock v1.6.0 github.com/miekg/dns v1.1.57 diff --git a/go.sum b/go.sum index a040f48d..f6d6c10d 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ code.cloudfoundry.org/lager v2.0.0+incompatible h1:WZwDKDB2PLd/oL+USK4b4aEjUymIej9My2nUQ9oWEwQ= code.cloudfoundry.org/lager v2.0.0+incompatible/go.mod h1:O2sS7gKP3HM2iemG+EnwvyNQK7pTSC6Foi4QiMp9sSk= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/Dynatrace/libbuildpack-dynatrace v1.5.2 h1:yiF8yuJ4762ocmZEM+/K8auciKFQ3XfQb/0Qt7VL+rU= -github.com/Dynatrace/libbuildpack-dynatrace v1.5.2/go.mod h1:Uu9aa5UFAk1Ua+zZXnvzo+avDXuEi+GtegeOyja9xg4= +github.com/Dynatrace/libbuildpack-dynatrace v1.8.0 h1:VNcd8+rurUUdY12emGfLGUUj5cMH4hkNgrdk8LO3dHE= +github.com/Dynatrace/libbuildpack-dynatrace v1.8.0/go.mod h1:Uu9aa5UFAk1Ua+zZXnvzo+avDXuEi+GtegeOyja9xg4= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= diff --git a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/.gitignore b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/.gitignore index f1c181ec..31c5c6ff 100644 --- a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/.gitignore +++ b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/.gitignore @@ -10,3 +10,6 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out + +# vim session file +Session.vim diff --git a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/README.md b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/README.md index 24f8c310..c8586438 100644 --- a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/README.md +++ b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/README.md @@ -31,7 +31,9 @@ We support the following configuration fields, | apitoken | string | The API Token for the Dynatrace environment. | Yes | N/A | | apiurl | string | Overrides the default Dynatrace API URL to connect to. | No | Default API URL | | skiperrors | boolean | If true, the deployment doesn't fail if the Dynatrace agent download fails. | No | false | -| networkzone | string | If set, agent is configured to choose communication endpoints located at the field's value. | No | empty | +| networkzone | string | If set, agent is configured to choose communication endpoints located at the field's value. | No | empty | +| enablefips | boolean | If true, the [FIPS 140-2 mode](https://www.dynatrace.com/news/blog/dynatrace-achieves-fips-140-2-certification/) is enabled | No | false | +| addtechnologies| string | Adds additional OneAgent code-modules via a comma-separated list. See [supported values](https://docs.dynatrace.com/docs/dynatrace-api/environment-api/deployment/oneagent/download-oneagent-version#parameters) in the "included" row | No | empty | For example, diff --git a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/hook.go b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/hook.go index 1029be3a..bef46b81 100644 --- a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/hook.go +++ b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/hook.go @@ -3,15 +3,16 @@ package dynatrace import ( "bufio" "encoding/json" + "errors" "fmt" "io" - "io/ioutil" "math" "net/http" "net/url" "os" "path/filepath" "regexp" + "runtime" "strings" "time" @@ -33,6 +34,8 @@ type credentials struct { APIURL string SkipErrors bool NetworkZone string + EnableFIPS bool + AddTechnologies string } // Hook implements libbuildpack.Hook. It downloads and install the Dynatrace OneAgent. @@ -77,108 +80,41 @@ func (h *Hook) AfterCompile(stager *libbuildpack.Stager) error { h.Log.Info("Dynatrace service credentials found. Setting up Dynatrace OneAgent.") - // Get buildpack version and language - - lang := stager.BuildpackLanguage() - ver, err := stager.BuildpackVersion() - if err != nil { - h.Log.Warning("Failed to get buildpack version: %v", err) - ver = "unknown" - } - - // Download installer... - - installerFilePath := filepath.Join(os.TempDir(), "paasInstaller.sh") - url := h.getDownloadURL(creds) - - h.Log.Info("Downloading '%s' to '%s'", url, installerFilePath) - if err = h.download(url, installerFilePath, ver, lang, creds); err != nil { - if creds.SkipErrors { - h.Log.Warning("Error during installer download, skipping installation") - return nil - } - return err - } - - // Run installer... - - h.Log.Debug("Making %s executable...", installerFilePath) - os.Chmod(installerFilePath, 0755) - - h.Log.BeginStep("Starting Dynatrace OneAgent installer") - - if os.Getenv("BP_DEBUG") != "" { - err = h.Command.Execute("", os.Stdout, os.Stderr, installerFilePath, stager.BuildDir()) - } else { - err = h.Command.Execute("", ioutil.Discard, ioutil.Discard, installerFilePath, stager.BuildDir()) - } - if err != nil { - return err - } - - h.Log.Info("Dynatrace OneAgent installed.") - - // Post-installation setup... - - dynatraceEnvName := "dynatrace-env.sh" installDir := filepath.Join("dynatrace", "oneagent") - dynatraceEnvPath := filepath.Join(stager.DepDir(), "profile.d", dynatraceEnvName) - agentLibPath, err := h.findAgentPath(filepath.Join(stager.BuildDir(), installDir)) - if err != nil { - h.Log.Error("Manifest handling failed!") - return err - } - - agentLibPath = filepath.Join(installDir, agentLibPath) - agentBuilderLibPath := filepath.Join(stager.BuildDir(), agentLibPath) - - if _, err = os.Stat(agentBuilderLibPath); os.IsNotExist(err) { - h.Log.Error("Agent library (%s) not found!", agentBuilderLibPath) - return err - } - h.Log.BeginStep("Setting up Dynatrace OneAgent injection...") - h.Log.Debug("Copy %s to %s", dynatraceEnvName, dynatraceEnvPath) - if err = libbuildpack.CopyFile(filepath.Join(stager.BuildDir(), installDir, dynatraceEnvName), dynatraceEnvPath); err != nil { - return err + // download installer + var installerFilename string + if runtime.GOOS == "linux" { + installerFilename = "paasInstaller.sh" + } else if runtime.GOOS == "windows" { + installerFilename = "paasInstaller.zip" + } else { + // This is the only place where we need to return an error. + // All following operating system checks are just to determine installation specifics. + return errors.New("libbuildpack-dynatrace: Unsupported operating system: " + runtime.GOOS) } - h.Log.Debug("Open %s for modification...", dynatraceEnvPath) - f, err := os.OpenFile(dynatraceEnvPath, os.O_APPEND|os.O_WRONLY, os.ModeAppend) - if err != nil { + installerFilePath := filepath.Join(os.TempDir(), installerFilename) + url := h.getDownloadURL(creds) + err = h.download(url, installerFilePath, stager, creds) + if err != nil && creds.SkipErrors { + h.Log.Warning("Error during installer download, skipping installation") + return nil + }else if err != nil { return err } - defer f.Close() - - extra := "" - - h.Log.Debug("Setting LD_PRELOAD...") - extra += fmt.Sprintf("\nexport LD_PRELOAD=${HOME}/%s", agentLibPath) - - if creds.NetworkZone != "" { - h.Log.Debug("Setting DT_NETWORK_ZONE...") - extra += fmt.Sprintf("\nexport DT_NETWORK_ZONE=${DT_NETWORK_ZONE:-%s}", creds.NetworkZone) - } - - // By default, OneAgent logs are printed to stderr. If the customer doesn't override this behavior through an - // environment variable, then we change the default output to stdout. - if os.Getenv("DT_LOGSTREAM") == "" { - h.Log.Debug("Setting DT_LOGSTREAM to stdout...") - extra += "\nexport DT_LOGSTREAM=stdout" - } - - h.Log.Debug("Preparing custom properties...") - extra += fmt.Sprintf( - "\nexport DT_CUSTOM_PROP=\"${DT_CUSTOM_PROP} CloudFoundryBuildpackLanguage=%s CloudFoundryBuildpackVersion=%s\"", lang, ver) - - if _, err = f.WriteString(extra); err != nil { - return err + // run installer + if runtime.GOOS == "linux" { + err = h.runInstallerUnix(installerFilePath, installDir, creds, stager) + } else if runtime.GOOS == "windows" { + err = h.runInstallerWindows(installerFilePath, installDir, creds, stager) } + // update agent config h.Log.Debug("Fetching updated OneAgent configuration from tenant... ") configDir := filepath.Join(stager.BuildDir(), installDir) - if err := h.updateAgentConfig(creds, configDir, lang, ver); err != nil { + if err := h.updateAgentConfig(creds, configDir, stager); err != nil { if creds.SkipErrors { h.Log.Warning("Error during agent config update, skipping it") return nil @@ -188,8 +124,16 @@ func (h *Hook) AfterCompile(stager *libbuildpack.Stager) error { } - h.Log.Info("Dynatrace OneAgent injection is set up.") + if h.getCredentials().EnableFIPS { + h.Log.Debug("Removing file 'dt_fips_disabled.flag' to enable FIPS mode...") + flagFilePath := filepath.Join(stager.BuildDir(), installDir, "agent", "dt_fips_disabled.flag") + if err := os.Remove(flagFilePath); err != nil { + h.Log.Error("Error during fips flag file deletion: %s", err) + return err + } + } + h.Log.Info("Dynatrace OneAgent injection is set up.") return nil } @@ -231,6 +175,8 @@ func (h *Hook) getCredentials() *credentials { CustomOneAgentURL: queryString("customoneagenturl"), SkipErrors: queryString("skiperrors") == "true", NetworkZone: queryString("networkzone"), + EnableFIPS: queryString("enablefips") == "true", + AddTechnologies: queryString("addtechnologies"), } if (creds.EnvironmentID != "" && creds.APIToken != "") || creds.CustomOneAgentURL != "" { @@ -255,13 +201,16 @@ func (h *Hook) getCredentials() *credentials { } // download gets url, and stores it as filePath, retrying a few more times if the downloads fail. -func (h *Hook) download(url, filePath string, buildPackVersion string, language string, creds *credentials) error { - const baseWaitTime = 3 * time.Second - +func (h *Hook) download(url, filePath string, stager *libbuildpack.Stager, creds *credentials) error { client := &http.Client{} req, _ := http.NewRequest("GET", url, nil) if creds.CustomOneAgentURL == "" { - req.Header.Set("User-Agent", fmt.Sprintf("cf-%s-buildpack/%s", language, buildPackVersion)) + ver, err := stager.BuildpackVersion() + if err != nil { + h.Log.Warning("Failed to get buildpack version: %v", err) + ver = "unknown" + } + req.Header.Set("User-Agent", fmt.Sprintf("cf-%s-buildpack/%s", stager.BuildpackLanguage(), ver)) req.Header.Set("Authorization", fmt.Sprintf("Api-Token %s", creds.APIToken)) } @@ -270,7 +219,8 @@ func (h *Hook) download(url, filePath string, buildPackVersion string, language return err } defer out.Close() - + + const baseWaitTime = 3 * time.Second for i := 0; ; i++ { resp, err := client.Do(req) if err == nil { @@ -315,9 +265,19 @@ func (h *Hook) download(url, filePath string, buildPackVersion string, language h.Log.Warning("Error during installer download, retrying in %v", waitTime) time.Sleep(waitTime) } + } func (h *Hook) getDownloadURL(c *credentials) string { + var osType, installerType string + if runtime.GOOS == "linux" { + osType = "unix" + installerType = "paas-sh" + } else if runtime.GOOS == "windows" { + osType = "windows" + installerType = "paas" + } + if c.CustomOneAgentURL != "" { return c.CustomOneAgentURL } @@ -327,7 +287,7 @@ func (h *Hook) getDownloadURL(c *credentials) string { return "" } - u, err := url.ParseRequestURI(fmt.Sprintf("%s/v1/deployment/installer/agent/unix/paas-sh/latest", apiURL)) + u, err := url.ParseRequestURI(fmt.Sprintf("%s/v1/deployment/installer/agent/%s/%s/latest", apiURL, osType, installerType)) if err != nil { return "" } @@ -341,6 +301,13 @@ func (h *Hook) getDownloadURL(c *credentials) string { for _, t := range h.IncludeTechnologies { qv.Add("include", t) } + if c.AddTechnologies != "" { + // add optionally configured OneAgent code modules + for _, t := range strings.Split(c.AddTechnologies, ",") { + h.Log.Debug("Adding additional code module to download: %s", t) + qv.Add("include", t) + } + } u.RawQuery = qv.Encode() // Parameters will be sorted by key. return u.String() @@ -369,7 +336,7 @@ func (h *Hook) ensureApiURL(creds *credentials) (string, error) { // findAgentPath reads the manifest file included in the OneAgent package, and looks // for the process agent file path. -func (h *Hook) findAgentPath(installDir string) (string, error) { +func (h *Hook) findAgentPath(installDir string, technology string, binaryType string, libraryFilename string, platformName string) (string, error) { // With these classes, we try to replicate the structure for the manifest.json file, so that we can parse it. type Binary struct { @@ -384,7 +351,7 @@ func (h *Hook) findAgentPath(installDir string) (string, error) { Technologies Technologies `json:"technologies"` } - fallbackPath := filepath.Join("agent", "lib64", "liboneagentproc.so") + fallbackPath := filepath.Join("agent", "lib64", libraryFilename) manifestPath := filepath.Join(installDir, "manifest.json") if _, err := os.Stat(manifestPath); os.IsNotExist(err) { @@ -394,14 +361,14 @@ func (h *Hook) findAgentPath(installDir string) (string, error) { var manifest Manifest - if raw, err := ioutil.ReadFile(manifestPath); err != nil { + if raw, err := os.ReadFile(manifestPath); err != nil { return "", err } else if err = json.Unmarshal(raw, &manifest); err != nil { return "", err } - for _, binary := range manifest.Technologies["process"]["linux-x86-64"] { - if binary.BinaryType == "primary" { + for _, binary := range manifest.Technologies[technology][platformName] { + if binary.BinaryType == binaryType { return binary.Path, nil } } @@ -413,7 +380,7 @@ func (h *Hook) findAgentPath(installDir string) (string, error) { // Downloads most recent agent config from configuration API of the tenant // and merges it with the local version the standalone installer package brings along. -func (h *Hook) updateAgentConfig(creds *credentials, installDir, buildPackLanguage, buildPackVersion string) error { +func (h *Hook) updateAgentConfig(creds *credentials, installDir string, stager *libbuildpack.Stager) error { // agentConfigProperty represents a line of raw data we get from the config api type agentConfigProperty struct { Section string @@ -437,9 +404,16 @@ func (h *Hook) updateAgentConfig(creds *credentials, installDir, buildPackLangua } agentConfigUrl := apiURL + "/v1/deployment/installer/agent/processmoduleconfig" + lang := stager.BuildpackLanguage() + ver, err := stager.BuildpackVersion() + if err != nil { + h.Log.Warning("Failed to get buildpack version: %v", err) + ver = "unknown" + } + h.Log.Debug("Downloading updated OneAgent config from %s", agentConfigUrl) req, _ := http.NewRequest("GET", agentConfigUrl, nil) - req.Header.Set("User-Agent", fmt.Sprintf("cf-%s-buildpack/%s", buildPackLanguage, buildPackVersion)) + req.Header.Set("User-Agent", fmt.Sprintf("cf-%s-buildpack/%s", lang, ver)) req.Header.Set("Authorization", fmt.Sprintf("Api-Token %s", creds.APIToken)) client.Do(req) resp, err := client.Do(req) @@ -467,7 +441,7 @@ func (h *Hook) updateAgentConfig(creds *credentials, installDir, buildPackLangua } // read data from ruxitagentproc.conf file - agentConfigPath := filepath.Join(installDir, "agent/conf/ruxitagentproc.conf") + agentConfigPath := filepath.Join(installDir, "agent", "conf", "ruxitagentproc.conf") agentConfigFile, err := os.Open(agentConfigPath) if err != nil { h.Log.Error("Failure while reading OneAgent config file %s: %s", agentConfigPath, err) diff --git a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/unix.go b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/unix.go new file mode 100644 index 00000000..08bd9174 --- /dev/null +++ b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/unix.go @@ -0,0 +1,97 @@ +package dynatrace + +import ( + "fmt" + "io" + "os" + "path/filepath" + + "github.com/cloudfoundry/libbuildpack" +) + +func (h *Hook) runInstallerUnix(installerFilePath, installDir string, creds *credentials, stager *libbuildpack.Stager) error { + h.Log.Debug("Making %s executable...", installerFilePath) + err := os.Chmod(installerFilePath, 0755) + if err != nil { + h.Log.Error("Error while setting installer file %s executable", installerFilePath) + return err + } + + + h.Log.BeginStep("Starting Dynatrace OneAgent installer") + + if os.Getenv("BP_DEBUG") != "" { + err = h.Command.Execute("", os.Stdout, os.Stderr, installerFilePath, stager.BuildDir()) + } else { + err = h.Command.Execute("", io.Discard, io.Discard, installerFilePath, stager.BuildDir()) + } + if err != nil { + return err + } + + h.Log.Info("Dynatrace OneAgent installed.") + + // Post-installation setup... + + dynatraceEnvName := "dynatrace-env.sh" + dynatraceEnvPath := filepath.Join(stager.DepDir(), "profile.d", dynatraceEnvName) + agentLibPath, err := h.findAgentPath(filepath.Join(stager.BuildDir(), installDir), "process", "primary", "liboneagentproc.so", "linux-x86-64") + if err != nil { + h.Log.Error("Manifest handling failed!") + return err + } + + agentLibPath = filepath.Join(installDir, agentLibPath) + agentBuilderLibPath := filepath.Join(stager.BuildDir(), agentLibPath) + + if _, err = os.Stat(agentBuilderLibPath); os.IsNotExist(err) { + h.Log.Error("Agent library (%s) not found!", agentBuilderLibPath) + return err + } + + h.Log.BeginStep("Setting up Dynatrace OneAgent injection...") + h.Log.Debug("Copy %s to %s", dynatraceEnvName, dynatraceEnvPath) + if err = libbuildpack.CopyFile(filepath.Join(stager.BuildDir(), installDir, dynatraceEnvName), dynatraceEnvPath); err != nil { + return err + } + + h.Log.Debug("Open %s for modification...", dynatraceEnvPath) + f, err := os.OpenFile(dynatraceEnvPath, os.O_APPEND|os.O_WRONLY, os.ModeAppend) + if err != nil { + return err + } + + defer f.Close() + + extra := "" + + h.Log.Debug("Setting LD_PRELOAD...") + extra += fmt.Sprintf("\nexport LD_PRELOAD=${HOME}/%s", agentLibPath) + + if creds.NetworkZone != "" { + h.Log.Debug("Setting DT_NETWORK_ZONE...") + extra += fmt.Sprintf("\nexport DT_NETWORK_ZONE=${DT_NETWORK_ZONE:-%s}", creds.NetworkZone) + } + + // By default, OneAgent logs are printed to stderr. If the customer doesn't override this behavior through an + // environment variable, then we change the default output to stdout. + if os.Getenv("DT_LOGSTREAM") == "" { + h.Log.Debug("Setting DT_LOGSTREAM to stdout...") + extra += "\nexport DT_LOGSTREAM=stdout" + } + + ver, err := stager.BuildpackVersion() + if err != nil { + h.Log.Warning("Failed to get buildpack version: %v", err) + ver = "unknown" + } + h.Log.Debug("Preparing custom properties...") + extra += fmt.Sprintf( + "\nexport DT_CUSTOM_PROP=\"${DT_CUSTOM_PROP} CloudFoundryBuildpackLanguage=%s CloudFoundryBuildpackVersion=%s\"", stager.BuildpackLanguage(), ver) + + if _, err = f.WriteString(extra); err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/Dynatrace/libbuildpack-dynatrace/windows.go b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/windows.go new file mode 100644 index 00000000..2763fb11 --- /dev/null +++ b/vendor/github.com/Dynatrace/libbuildpack-dynatrace/windows.go @@ -0,0 +1,99 @@ +package dynatrace + +import ( + "fmt" + "os" + "path/filepath" + "slices" + "strings" + + "github.com/cloudfoundry/libbuildpack" +) + +func (h *Hook) runInstallerWindows(installerFilePath, installDir string, creds *credentials, stager *libbuildpack.Stager) error { + h.Log.BeginStep("Starting Dynatrace OneAgent installation") + + h.Log.Info("Unzipping archive '%s' to '%s'", installerFilePath, filepath.Join(stager.BuildDir(), installDir)) + err := libbuildpack.ExtractZip(installerFilePath, filepath.Join(stager.BuildDir(), installDir)) + if err != nil { + h.Log.Error("Error during unzipping paas archive") + return err + } + + h.Log.Info("Dynatrace OneAgent installed.") + + // Post-installation setup... + + h.Log.BeginStep("Setting up Dynatrace OneAgent injection...") + if slices.Contains(h.IncludeTechnologies, "dotnet") { + err = h.setUpDotNetCorProfilerInjection(creds, installDir, stager) + } else { + h.Log.Warning("No injection method available for technology stack") + return nil + } + if err != nil { + return err + } + + return nil +} + +func (h *Hook) setUpDotNetCorProfilerInjection(creds *credentials, installDir string, stager *libbuildpack.Stager) error { + loaderPath, err := h.findAbsoluteLoaderPath(stager, installDir) + if err != nil { + return fmt.Errorf("cannot find oneagentloader.dll: %s", err) + } + + scriptContent := "set COR_ENABLE_PROFILING=1\n" + scriptContent += "set COR_PROFILER={B7038F67-52FC-4DA2-AB02-969B3C1EDA03}\n" + scriptContent += "set DT_AGENTACTIVE=true\n" + scriptContent += "set DT_BLOCKLIST=powershell*\n" + scriptContent += fmt.Sprintf("set COR_PROFILER_PATH_64=%s\n", loaderPath) + + if creds.NetworkZone != "" { + h.Log.Debug("Setting DT_NETWORK_ZONE...") + scriptContent += "set DT_NETWORK_ZONE=" + creds.NetworkZone + "\n" + } + + ver, err := stager.BuildpackVersion() + if err != nil { + h.Log.Warning("Failed to get buildpack version: %v", err) + ver = "unknown" + } + h.Log.Debug("Preparing custom properties...") + scriptContent += fmt.Sprintf("set DT_CUSTOM_PROP=\"%%DT_CUSTOM_PROP%% CloudFoundryBuildpackLanguage=%s CloudFoundryBuildpackVersion=%s\"\n", stager.BuildpackLanguage(), ver) + + stager.WriteProfileD("dynatrace-env.cmd", scriptContent) + + return nil +} + +func (h *Hook) findAbsoluteLoaderPath(stager *libbuildpack.Stager, installDir string) (string, error) { + + // look for dotnet loader DLL file relative to the root of the downloaded zip archive + // and get the path from the manifest e.g. agent/bin/windows-x86-64/oneagentloader.dll + loaderDllPath, err := h.findAgentPath(filepath.Join(stager.BuildDir(), installDir), "dotnet", "loader", "oneagentloader.dll", "windows-x86-64") + if err != nil { + h.Log.Error("Manifest handling failed!") + return "", err + } + + // windows path separator is "\" instead of "/" + loaderDllPath = strings.ReplaceAll(loaderDllPath, "/", "\\") + + // build the loader DLL path relative to the app directory + // e.g. dynatrace/oneagent/agent/bin/windows-x86-64/oneagentloader.dll + loaderDllPathInAppDir := filepath.Join(installDir, loaderDllPath) + + // check that the loader dll is present in the build dir + // e.g. at \tmp\app\dynatrace\oneagent\agent\bin\1.303.0.20240930-081133\windows-x86-32\oneagentloader.dll + loaderDllPathInBuildDir := filepath.Join(stager.BuildDir(), loaderDllPathInAppDir) + + if _, err = os.Stat(loaderDllPathInBuildDir); os.IsNotExist(err) { + h.Log.Error("Agent library (%s) not found!", loaderDllPathInBuildDir) + return "", err + } + + // build the absolute path of the loader DLL as it will be available at runtime + return filepath.Join("C:\\users\\vcap\\app", loaderDllPathInAppDir), nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e5e09a6f..b68d2b1d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,7 +1,7 @@ # code.cloudfoundry.org/lager v2.0.0+incompatible ## explicit code.cloudfoundry.org/lager -# github.com/Dynatrace/libbuildpack-dynatrace v1.5.2 +# github.com/Dynatrace/libbuildpack-dynatrace v1.8.0 ## explicit; go 1.19 github.com/Dynatrace/libbuildpack-dynatrace # github.com/Masterminds/semver v1.5.0