-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add resources for dealing with the system python
- Loading branch information
1 parent
49e504d
commit 7210aea
Showing
18 changed files
with
768 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
require 'chef/mixin/shell_out' | ||
|
||
module Boxcutter | ||
class Python | ||
module Helpers | ||
extend Chef::Mixin::ShellOut | ||
|
||
def self.read_pyvenv_cfg(pyvenv_cfg_path) | ||
config = {} | ||
::File.foreach(pyvenv_cfg_path) do |line| | ||
# Skip comments or blank lines | ||
next if line.strip.empty? || line.strip.start_with?('#') | ||
|
||
# Split each line into key-value pairs | ||
key, value = line.strip.split('=', 2) | ||
config[key.strip] = value.strip if key && value | ||
end | ||
config | ||
end | ||
|
||
def self.remove_surrounding_single_quotes(string) | ||
if string.start_with?("'") && string.end_with?("'") | ||
string[1..-2] | ||
else | ||
string | ||
end | ||
end | ||
|
||
# these methods are the required overrides of | ||
# a provider that extends from Chef::Provider::Package | ||
# so refactoring into core Chef should be easy | ||
|
||
def self.current_installed_version(new_resource) | ||
@current_installed_version ||= begin | ||
# Normalize package name (e.g., replace underscores with hyphens) | ||
normalized_package_name = new_resource.package_name.gsub('_', '-') | ||
|
||
# Command to get package details using pip3 show | ||
version_check_cmd = "#{which_pip(new_resource)} show #{normalized_package_name}" | ||
|
||
# Run the command and capture the result | ||
result = shell_out(version_check_cmd) | ||
if result.exitstatus == 0 | ||
# Extract the version from the 'Version:' line in `pip3 show` output | ||
result.stdout.match(/^Version:\s*(.+)$/i)[1] | ||
end | ||
end | ||
end | ||
|
||
def self.candidate_version(new_resource) | ||
@candidate_version ||= new_resource.version||'latest' | ||
end | ||
|
||
def self.install_package(version, new_resource) | ||
# if a version isn't specified (latest), is a source archive | ||
# (ex. http://my.package.repo/SomePackage-1.0.4.zip), | ||
# or from a VCS (ex. git+https://git.repo/some_pkg.git) then do not | ||
# append a version as this will break the source link | ||
if version == 'latest' || \ | ||
new_resource.package_name.downcase.start_with?('http:', 'https:') || \ | ||
['git', 'hg', 'svn'].include?(new_resource.package_name.downcase.split('+')[0]) | ||
version = '' | ||
else | ||
version = "==#{version}" | ||
end | ||
pip_cmd('install', version, new_resource) | ||
end | ||
|
||
def self.upgrade_package(version, new_resource) | ||
# Upgrades are just an install with the `--upgrade` parameter added | ||
new_resource.options "#{new_resource.options} --upgrade" | ||
install_package(version, new_resource) | ||
end | ||
|
||
def self.remove_package(_version, new_resource) | ||
new_resource.options "#{new_resource.options} --yes" | ||
# Python only allows one version to be installed at a time, so it's | ||
# not necessary to provide a version on uninstall. | ||
pip_cmd('uninstall', '', new_resource) | ||
end | ||
|
||
def self.removing_package?(current_resource, new_resource) | ||
if current_resource.version.nil? | ||
false # nothing to remove | ||
elsif new_resource.version.nil? | ||
true # remove any version of a package | ||
else | ||
new_resource.version == current_resource.version # we don't have the version we want to remove | ||
end | ||
end | ||
|
||
def self.pip_cmd(subcommand, version = '', new_resource) | ||
options = { :timeout => new_resource.timeout, :user => new_resource.user, :group => new_resource.group } | ||
environment = {} | ||
environment['HOME'] = Dir.home(new_resource.user) if new_resource.user | ||
environment.merge!(new_resource.environment) if new_resource.environment && !new_resource.environment.empty? | ||
options[:environment] = environment | ||
shell_out!( | ||
"#{which_pip(new_resource)} #{subcommand} #{new_resource.extra_options}" \ | ||
"#{new_resource.package_name}#{version}", **options | ||
) | ||
end | ||
|
||
def self.which_pip(new_resource) | ||
if new_resource.respond_to?('virtualenv') && new_resource.virtualenv | ||
::File.join(new_resource.virtualenv, '/bin/pip') | ||
else | ||
new_resource.pip_binary | ||
end | ||
end | ||
end | ||
end | ||
end |
18 changes: 18 additions & 0 deletions
18
cookbooks/boxcutter_python/policyfiles/Policyfile.pyenv.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Policyfile.pyenv.rb - Describe how you want Chef Infra Client to build your system. | ||
# | ||
# For more information on the Policyfile feature, visit | ||
# https://docs.chef.io/policyfile/ | ||
|
||
# A name that describes what the system you're building with Chef does. | ||
name 'boxcutter_python' | ||
|
||
# Where to find external cookbooks: | ||
default_source :chef_repo, '../../../../chef-cookbooks/cookbooks' | ||
default_source :chef_repo, '../../' | ||
|
||
# run_list: chef-client will run these recipes in the order specified. | ||
run_list 'boxcutter_ohai', 'boxcutter_init', 'boxcutter_python_test::pyenv' | ||
|
||
# Specify a custom source for a single cookbook: | ||
cookbook 'boxcutter_python', path: '..' | ||
cookbook 'boxcutter_python_test', path: '../test/cookbooks/boxcutter_python_test' |
18 changes: 18 additions & 0 deletions
18
cookbooks/boxcutter_python/policyfiles/Policyfile.system.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Policyfile.system.rb - Describe how you want Chef Infra Client to build your system. | ||
# | ||
# For more information on the Policyfile feature, visit | ||
# https://docs.chef.io/policyfile/ | ||
|
||
# A name that describes what the system you're building with Chef does. | ||
name 'boxcutter_python' | ||
|
||
# Where to find external cookbooks: | ||
default_source :chef_repo, '../../../../chef-cookbooks/cookbooks' | ||
default_source :chef_repo, '../../' | ||
|
||
# run_list: chef-client will run these recipes in the order specified. | ||
run_list 'boxcutter_ohai', 'boxcutter_init', 'boxcutter_python_test::system' | ||
|
||
# Specify a custom source for a single cookbook: | ||
cookbook 'boxcutter_python', path: '..' | ||
cookbook 'boxcutter_python_test', path: '../test/cookbooks/boxcutter_python_test' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.