Module: ChefCLI::Helpers

Instance Method Summary collapse

Instance Method Details

#err(message) ⇒ Object



37
38
39
# File 'lib/chef-cli/helpers.rb', line 37

def err(message)
  stderr.print("#{message}\n")
end

#fetch_chef_cli_version_pkgObject

Check Standalone Chef-cli environment variable for version



117
118
119
120
121
122
123
124
125
# File 'lib/chef-cli/helpers.rb', line 117

def fetch_chef_cli_version_pkg
  chef_cli_version = ENV["CHEF_CLI_VERSION"]
  return unless chef_cli_version

  pkg_path = get_pkg_prefix("#{ChefCLI::Dist::HAB_PKG_NAME}/#{chef_cli_version}")
  return pkg_path if pkg_path && Dir.exist?(pkg_path)

  nil
end

#get_pkg_install_pathObject

Function to return the Chef CLI path based on standalone or Chef-DKE-enabled package



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/chef-cli/helpers.rb', line 102

def get_pkg_install_path
  # Check Chef-DKE package path
  chef_dk_path = get_pkg_prefix(ChefCLI::Dist::CHEF_DKE_PKG_NAME)
  return chef_dk_path if chef_dk_path

  # Check Standalone Chef-CLI package path
  chef_cli_path = fetch_chef_cli_version_pkg || get_pkg_prefix(ChefCLI::Dist::HAB_PKG_NAME)
  chef_cli_path

rescue => e
  ChefCLI::UI.new.err("Error fetching Chef-CLI path: #{e.message}")
  nil
end

#get_pkg_prefix(pkg_name) ⇒ Object



211
212
213
214
215
# File 'lib/chef-cli/helpers.rb', line 211

def get_pkg_prefix(pkg_name)
  stderr_redirect = Chef::Platform.windows? ? "2>NUL" : "2>/dev/null"
  path = `hab pkg path #{pkg_name} #{stderr_redirect}`.strip
  path if !path.empty? && Dir.exist?(path) # Return path only if it exists
end

#git_bin_dirObject

Unix users do not want git on their path if they already have it installed. Because we put embedded/bin on the path we must move the git binaries somewhere else that we can append to the end of the path. This is only a temporary solution - see github.com/chef/chef-cli/issues/854 for a better proposed solution.



144
145
146
# File 'lib/chef-cli/helpers.rb', line 144

def git_bin_dir
  @git_bin_dir ||= File.expand_path(File.join(omnibus_root, "gitbin"))
end

#git_windows_bin_dirObject

In our Windows ChefCLI omnibus package we include Git For Windows, which has a bunch of helpful unix utilties (like ssh, scp, etc.) bundled with it



150
151
152
# File 'lib/chef-cli/helpers.rb', line 150

def git_windows_bin_dir
  @git_windows_bin_dir ||= File.expand_path(File.join(omnibus_root, "embedded", "git", "usr", "bin"))
end

#habitat_chef_dke?Boolean

This method checks if the habitat version of chef-cli is installed with chef-workstation

Returns:



70
71
72
# File 'lib/chef-cli/helpers.rb', line 70

def habitat_chef_dke?
  @hab_dke ||= hab_pkg_installed?(ChefCLI::Dist::CHEF_DKE_PKG_NAME)
end

#habitat_env(show_warning: false) ⇒ Object

environment vars for habitat



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/chef-cli/helpers.rb', line 157

def habitat_env(show_warning: false)
  @habitat_env ||= begin
    if habitat_chef_dke?
      bin_pkg_prefix = get_pkg_prefix(ChefCLI::Dist::CHEF_DKE_PKG_NAME)
    end
    versioned_pkg_prefix = fetch_chef_cli_version_pkg if ENV["CHEF_CLI_VERSION"]

    if show_warning && ENV["CHEF_CLI_VERSION"] && !versioned_pkg_prefix
      ChefCLI::UI.new.msg("Warning: Habitat package '#{ChefCLI::Dist::HAB_PKG_NAME}' with version '#{ENV["CHEF_CLI_VERSION"]}' not found.")
    end
    # Use the first available package for bin_pkg_prefix
    bin_pkg_prefix ||= versioned_pkg_prefix || get_pkg_prefix(ChefCLI::Dist::HAB_PKG_NAME)
    raise "Error: Could not determine the Habitat package prefix. Ensure #{ChefCLI::Dist::HAB_PKG_NAME} is installed and CHEF_CLI_VERSION is set correctly." unless bin_pkg_prefix

    # Determine vendor_dir by prioritizing the versioned package first
    vendor_pkg_prefix = versioned_pkg_prefix || get_pkg_prefix(ChefCLI::Dist::HAB_PKG_NAME)
    raise "Error: Could not determine the vendor package prefix. Ensure #{ChefCLI::Dist::HAB_PKG_NAME} is installed and CHEF_CLI_VERSION is set correctly." unless vendor_pkg_prefix

    vendor_dir = File.join(vendor_pkg_prefix, "vendor")
    # Construct PATH
    path = [
      File.join(bin_pkg_prefix, "bin"),
      File.join(vendor_dir, "bin"),
      ENV["PATH"].split(File::PATH_SEPARATOR), # Preserve existing PATH
    ].flatten.uniq

    {
    "PATH" => path.join(File::PATH_SEPARATOR),
    "GEM_ROOT" => Gem.default_dir, # Default directory for gems
    "GEM_HOME" => vendor_dir,      # Set only if vendor_dir exists
    "GEM_PATH" => vendor_dir,      # Set only if vendor_dir exists
    }
  end
end

#habitat_install?Boolean

Returns:



74
75
76
# File 'lib/chef-cli/helpers.rb', line 74

def habitat_install?
  habitat_chef_dke? || habitat_standalone?
end

#habitat_standalone?Boolean

The habitat version of the chef-cli can be installed with standalone or chef-workstation This method checks if the habitat version of chef-cli is installed as standalone

Returns:



65
66
67
# File 'lib/chef-cli/helpers.rb', line 65

def habitat_standalone?
  @hab_standalone ||= (hab_pkg_installed?(ChefCLI::Dist::HAB_PKG_NAME) && !habitat_chef_dke?)
end

#msg(message) ⇒ Object



41
42
43
# File 'lib/chef-cli/helpers.rb', line 41

def msg(message)
  stdout.print("#{message}\n")
end

#omnibus_bin_dirObject



82
83
84
# File 'lib/chef-cli/helpers.rb', line 82

def omnibus_bin_dir
  @omnibus_bin_dir ||= omnibus_expand_path(omnibus_root, "bin")
end

#omnibus_embedded_bin_dirObject



86
87
88
# File 'lib/chef-cli/helpers.rb', line 86

def omnibus_embedded_bin_dir
  @omnibus_embedded_bin_dir ||= omnibus_expand_path(omnibus_root, "embedded", "bin")
end

#omnibus_envObject

environment vars for omnibus



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/chef-cli/helpers.rb', line 195

def omnibus_env
  @omnibus_env ||=
    begin
      user_bin_dir = File.expand_path(File.join(Gem.user_dir, "bin"))
      path = [ omnibus_bin_dir, user_bin_dir, omnibus_embedded_bin_dir, ENV["PATH"].split(File::PATH_SEPARATOR) ]
      path << git_bin_dir if Dir.exist?(git_bin_dir)
      path << git_windows_bin_dir if Dir.exist?(git_windows_bin_dir)
      {
      "PATH" => path.flatten.uniq.join(File::PATH_SEPARATOR),
      "GEM_ROOT" => Gem.default_dir,
      "GEM_HOME" => Gem.user_dir,
      "GEM_PATH" => Gem.path.join(File::PATH_SEPARATOR),
      }
    end
end

#omnibus_expand_path(*paths) ⇒ Object

Raises:



217
218
219
220
221
222
# File 'lib/chef-cli/helpers.rb', line 217

def omnibus_expand_path(*paths)
  dir = File.expand_path(File.join(paths))
  raise OmnibusInstallNotFound.new unless dir && File.directory?(dir)

  dir
end

#omnibus_install?Boolean

Locates the omnibus directories

Returns:



56
57
58
59
60
61
# File 'lib/chef-cli/helpers.rb', line 56

def omnibus_install?
  # We also check if the location we're running from (omnibus_root is relative to currently-running ruby)
  # includes the version manifest that omnibus packages ship with. If it doesn't, then we're running locally
  # or out of a gem - so not as an 'omnibus install'
  File.exist?(expected_omnibus_root) && File.exist?(File.join(expected_omnibus_root, "version-manifest.json"))
end

#omnibus_rootObject



78
79
80
# File 'lib/chef-cli/helpers.rb', line 78

def omnibus_root
  @omnibus_root ||= omnibus_expand_path(expected_omnibus_root)
end

#package_homeObject



90
91
92
93
94
95
96
97
98
99
# File 'lib/chef-cli/helpers.rb', line 90

def package_home
  @package_home ||= begin
                     package_home_set = !([nil, ""].include? ENV["CHEF_WORKSTATION_HOME"])
                     if package_home_set
                       ENV["CHEF_WORKSTATION_HOME"]
                     else
                       default_package_home
                     end
                   end
end

#stderrObject



49
50
51
# File 'lib/chef-cli/helpers.rb', line 49

def stderr
  $stderr
end

#stdoutObject



45
46
47
# File 'lib/chef-cli/helpers.rb', line 45

def stdout
  $stdout
end

#system_command(*command_args) ⇒ Object

Runs given commands using mixlib-shellout



31
32
33
34
35
# File 'lib/chef-cli/helpers.rb', line 31

def system_command(*command_args)
  cmd = Mixlib::ShellOut.new(*command_args)
  cmd.run_command
  cmd
end

#usr_bin_path(command) ⇒ Object

Returns the full path to the given command under usr_bin_prefix



135
136
137
# File 'lib/chef-cli/helpers.rb', line 135

def usr_bin_path(command)
  File.join(usr_bin_prefix, command)
end

#usr_bin_prefixObject

Returns the directory that contains our main symlinks. On Mac we place all of our symlinks under /usr/local/bin on other platforms they are under /usr/bin



130
131
132
# File 'lib/chef-cli/helpers.rb', line 130

def usr_bin_prefix
  @usr_bin_prefix ||= macos? ? "/usr/local/bin" : "/usr/bin"
end