Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Elastic Agent] Adjust installation path in container #27396

Merged
merged 8 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from 7 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
2 changes: 2 additions & 0 deletions x-pack/elastic-agent/CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
- Remove symlink.prev from previously failed upgrade {pull}26785[26785]
- Fix apm-server supported outputs not being in sync with supported output types. {pull}26885[26885]
- Set permissions during installation {pull}26665[26665]
- Fix issue with atomic extract running in K8s {pull}27396[27396]
- Fix issue with install directory in state path in K8s {pull}27396[27396]

==== New features

Expand Down
30 changes: 30 additions & 0 deletions x-pack/elastic-agent/pkg/agent/application/paths/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ var (
configPath string
configFilePath string
logsPath string
downloadsPath string
installPath string
unversionedHome bool
tmpCreator sync.Once
)
Expand All @@ -44,6 +46,8 @@ func init() {
fs.StringVar(&configPath, "path.config", configPath, "Config path is the directory Agent looks for its config file")
fs.StringVar(&configFilePath, "c", DefaultConfigName, "Configuration file, relative to path.config")
fs.StringVar(&logsPath, "path.logs", logsPath, "Logs path contains Agent log output")
fs.StringVar(&downloadsPath, "path.downloads", downloadsPath, "Downloads path contains binaries Agent downloads")
fs.StringVar(&installPath, "path.install", installPath, "Install path contains binaries Agent extracts")
}

// Top returns the top directory for Elastic Agent, all the versioned
Expand Down Expand Up @@ -139,6 +143,32 @@ func VersionedHome(base string) string {
return filepath.Join(base, "data", fmt.Sprintf("elastic-agent-%s", release.ShortCommit()))
}

// Downloads returns the downloads directory for Agent
func Downloads() string {
if downloadsPath == "" {
return filepath.Join(Home(), "downloads")
}
return downloadsPath
}

// SetDownloads updates the path for the downloads.
func SetDownloads(path string) {
downloadsPath = path
}

// Install returns the install directory for Agent
func Install() string {
if installPath == "" {
return filepath.Join(Home(), "install")
}
return installPath
}

// SetInstall updates the path for the install.
func SetInstall(path string) {
installPath = path
}

// initialTop returns the initial top-level path for the binary
//
// When nested in top-level/data/elastic-agent-${hash}/ the result is top-level/.
Expand Down
2 changes: 2 additions & 0 deletions x-pack/elastic-agent/pkg/agent/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func NewCommandWithArgs(args []string, streams *cli.IOStreams) *cobra.Command {
cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.config"))
cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("c"))
cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.logs"))
cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.downloads"))
cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.install"))

// logging flags
cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("v"))
Expand Down
12 changes: 10 additions & 2 deletions x-pack/elastic-agent/pkg/agent/cmd/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,12 @@ func buildEnrollArgs(cfg setupConfig, token string, policyID string) ([]string,
"--path.config", paths.Config(),
"--path.logs", paths.Logs(),
}
if paths.Downloads() != "" {
args = append(args, "--path.downloads", paths.Downloads())
}
if paths.Install() != "" {
args = append(args, "--path.install", paths.Install())
}
if !paths.IsVersionHome() {
args = append(args, "--path.home.unversioned")
}
Expand Down Expand Up @@ -704,16 +710,18 @@ func setPaths(statePath, configPath, logsPath string, writePaths bool) error {
}
}
// sync the downloads to the data directory
srcDownloads := filepath.Join(paths.Home(), "downloads")
destDownloads := filepath.Join(statePath, "data", "downloads")
if err := syncDir(srcDownloads, destDownloads); err != nil {
if err := syncDir(paths.Downloads(), destDownloads); err != nil {
return fmt.Errorf("syncing download directory to STATE_PATH(%s) failed: %s", statePath, err)
}
originalInstall := paths.Install()
originalTop := paths.Top()
paths.SetTop(topPath)
paths.SetConfig(configPath)
// when custom top path is provided the home directory is not versioned
paths.SetVersionHome(false)
// install path stays on container default mount (otherwise a bind mounted directory could have noexec set)
paths.SetInstall(originalInstall)
// set LOGS_PATH is given
logsPath = envWithDefault(logsPath, "LOGS_PATH")
if logsPath != "" {
Expand Down
6 changes: 6 additions & 0 deletions x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,12 @@ func (c *enrollCmd) startAgent(ctx context.Context) (<-chan *os.ProcessState, er
"--path.home", paths.Top(), "--path.config", paths.Config(),
"--path.logs", paths.Logs(),
}
if paths.Downloads() != "" {
args = append(args, "--path.downloads", paths.Downloads())
}
if paths.Install() != "" {
args = append(args, "--path.install", paths.Install())
}
if !paths.IsVersionHome() {
args = append(args, "--path.home.unversioned")
}
Expand Down
6 changes: 2 additions & 4 deletions x-pack/elastic-agent/pkg/artifact/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package artifact

import (
"path/filepath"
"runtime"
"strings"
"time"
Expand Down Expand Up @@ -43,16 +42,15 @@ type Config struct {

// DefaultConfig creates a config with pre-set default values.
func DefaultConfig() *Config {
homePath := paths.Home()
transport := httpcommon.DefaultHTTPTransportSettings()

// binaries are a getting bit larger it might take >30s to download them
transport.Timeout = 120 * time.Second

return &Config{
SourceURI: "https://artifacts.elastic.co/downloads/",
TargetDirectory: filepath.Join(homePath, "downloads"),
InstallPath: filepath.Join(homePath, "install"),
TargetDirectory: paths.Downloads(),
InstallPath: paths.Install(),
HTTPTransportSettings: transport,
}
}
Expand Down
4 changes: 2 additions & 2 deletions x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ func (e *Downloader) downloadFile(filename, fullPath string) (string, error) {
func getDropPath(cfg *artifact.Config) string {
// if drop path is not provided fallback to beats subfolder
if cfg == nil || cfg.DropPath == "" {
return filepath.Join(paths.Home(), "downloads")
return paths.Downloads()
}

// if droppath does not exist fallback to beats subfolder
stat, err := os.Stat(cfg.DropPath)
if err != nil || !stat.IsDir() {
return filepath.Join(paths.Home(), "downloads")
return paths.Downloads()
}

return cfg.DropPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (

"github.com/hashicorp/go-multierror"

"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program"
)

Expand All @@ -37,10 +36,19 @@ func NewInstaller(i embeddedInstaller) (*Installer, error) {
// Install performs installation of program in a specific version.
func (i *Installer) Install(ctx context.Context, spec program.Spec, version, installDir string) error {
// tar installer uses Dir of installDir to determine location of unpack
tempDir, err := ioutil.TempDir(paths.TempDir(), "elastic-agent-install")
//
// installer is ran inside a tmp directory created in the parent installDir, this is so the atomic
// rename always occurs on the same mount path that holds the installation directory
tempDir, err := ioutil.TempDir(filepath.Dir(installDir), "tmp")
if err != nil {
return err
}

// always remove the entire tempDir
defer func() {
os.RemoveAll(tempDir)
}()

tempInstallDir := filepath.Join(tempDir, filepath.Base(installDir))

// cleanup install directory before Install
Expand Down