/x-pack/elastic-agent/pkg/agent/cmd/common.go

https://github.com/elastic/beats · Go · 137 lines · 98 code · 26 blank · 13 comment · 17 complexity · c3300121dd3fdc51da9826482cd27849 MD5 · raw file

  1. // Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
  2. // or more contributor license agreements. Licensed under the Elastic License;
  3. // you may not use this file except in compliance with the Elastic License.
  4. package cmd
  5. import (
  6. "flag"
  7. "fmt"
  8. "io/ioutil"
  9. "os"
  10. "path/filepath"
  11. "runtime"
  12. "strings"
  13. "github.com/spf13/cobra"
  14. "gopkg.in/yaml.v2"
  15. // import logp flags
  16. _ "github.com/elastic/beats/v7/libbeat/logp/configure"
  17. "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths"
  18. "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/basecmd"
  19. "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/cli"
  20. )
  21. const (
  22. defaultConfig = "elastic-agent.yml"
  23. hashLen = 6
  24. commitFile = ".elastic-agent.active.commit"
  25. )
  26. type globalFlags struct {
  27. PathConfigFile string
  28. }
  29. // Config returns path which identifies configuration file.
  30. func (f *globalFlags) Config() string {
  31. if len(f.PathConfigFile) == 0 || f.PathConfigFile == defaultConfig {
  32. return filepath.Join(paths.Config(), defaultConfig)
  33. }
  34. return f.PathConfigFile
  35. }
  36. // NewCommand returns the default command for the agent.
  37. func NewCommand() *cobra.Command {
  38. return NewCommandWithArgs(os.Args, cli.NewIOStreams())
  39. }
  40. // NewCommandWithArgs returns a new agent with the flags and the subcommand.
  41. func NewCommandWithArgs(args []string, streams *cli.IOStreams) *cobra.Command {
  42. cmd := &cobra.Command{
  43. Use: "elastic-agent [subcommand]",
  44. }
  45. flags := &globalFlags{}
  46. // path flags
  47. cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.home"))
  48. cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.config"))
  49. cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.data"))
  50. cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("path.logs"))
  51. cmd.PersistentFlags().StringVarP(&flags.PathConfigFile, "c", "c", defaultConfig, `Configuration file, relative to path.config`)
  52. // logging flags
  53. cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("v"))
  54. cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("e"))
  55. cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("d"))
  56. cmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("environment"))
  57. // sub-commands
  58. run := newRunCommandWithArgs(flags, args, streams)
  59. cmd.AddCommand(basecmd.NewDefaultCommandsWithArgs(args, streams)...)
  60. cmd.AddCommand(run)
  61. cmd.AddCommand(newEnrollCommandWithArgs(flags, args, streams))
  62. cmd.AddCommand(newInspectCommandWithArgs(flags, args, streams))
  63. // windows special hidden sub-command (only added on windows)
  64. reexec := newReExecWindowsCommand(flags, args, streams)
  65. if reexec != nil {
  66. cmd.AddCommand(reexec)
  67. }
  68. cmd.PersistentPreRunE = preRunCheck(flags)
  69. cmd.Run = run.Run
  70. return cmd
  71. }
  72. func hashedDirName(filecontent []byte) string {
  73. s := strings.TrimSpace(string(filecontent))
  74. if len(s) == 0 {
  75. return "elastic-agent"
  76. }
  77. s = smallHash(s)
  78. return fmt.Sprintf("elastic-agent-%s", s)
  79. }
  80. func smallHash(hash string) string {
  81. if len(hash) > hashLen {
  82. hash = hash[:hashLen]
  83. }
  84. return hash
  85. }
  86. func generatePaths(dir, origExec string) error {
  87. pathsCfg := map[string]interface{}{
  88. "path.data": paths.Data(),
  89. "path.home": dir,
  90. "path.config": paths.Config(),
  91. "path.service_name": origExec,
  92. }
  93. pathsCfgPath := filepath.Join(paths.Data(), "paths.yml")
  94. pathsContent, err := yaml.Marshal(pathsCfg)
  95. if err != nil {
  96. return err
  97. }
  98. if err := ioutil.WriteFile(pathsCfgPath, pathsContent, 0740); err != nil {
  99. return err
  100. }
  101. if runtime.GOOS == "windows" {
  102. // due to two binaries we need to do a path dance
  103. // as versioned binary will look for path inside it's own directory
  104. versionedPath := filepath.Join(dir, "data", "paths.yml")
  105. if err := os.MkdirAll(filepath.Dir(versionedPath), 0700); err != nil {
  106. return err
  107. }
  108. return os.Symlink(pathsCfgPath, versionedPath)
  109. }
  110. return nil
  111. }