poise-languages 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +20 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +32 -0
- data/LICENSE +202 -0
- data/README.md +27 -0
- data/Rakefile +17 -0
- data/lib/poise_languages.rb +25 -0
- data/lib/poise_languages/command.rb +25 -0
- data/lib/poise_languages/command/mixin.rb +231 -0
- data/lib/poise_languages/error.rb +21 -0
- data/lib/poise_languages/scl.rb +24 -0
- data/lib/poise_languages/scl/mixin.rb +110 -0
- data/lib/poise_languages/scl/resource.rb +124 -0
- data/lib/poise_languages/system.rb +24 -0
- data/lib/poise_languages/system/mixin.rb +165 -0
- data/lib/poise_languages/system/resource.rb +202 -0
- data/lib/poise_languages/utils.rb +49 -0
- data/lib/poise_languages/utils/which.rb +49 -0
- data/lib/poise_languages/version.rb +20 -0
- data/poise-languages.gemspec +40 -0
- data/test/gemfiles/chef-12.gemfile +19 -0
- data/test/gemfiles/master.gemfile +22 -0
- data/test/spec/command/mixin_spec.rb +328 -0
- data/test/spec/scl/mixin_spec.rb +209 -0
- data/test/spec/scl/resource_spec.rb +51 -0
- data/test/spec/spec_helper.rb +18 -0
- data/test/spec/system/mixin_spec.rb +172 -0
- data/test/spec/system/resource_spec.rb +123 -0
- data/test/spec/utils/which_spec.rb +69 -0
- data/test/spec/utils_spec.rb +55 -0
- metadata +132 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
|
18
|
+
module PoiseLanguages
|
19
|
+
class Error < ::Exception
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
|
18
|
+
module PoiseLanguages
|
19
|
+
module Scl
|
20
|
+
autoload :Mixin, 'poise_languages/scl/mixin'
|
21
|
+
autoload :Resource, 'poise_languages/scl/resource'
|
22
|
+
autoload :Provider, 'poise_languages/scl/resource'
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'poise_languages/scl/resource'
|
18
|
+
|
19
|
+
|
20
|
+
module PoiseLanguages
|
21
|
+
module Scl
|
22
|
+
module Mixin
|
23
|
+
private
|
24
|
+
|
25
|
+
def install_scl_package
|
26
|
+
pkg = scl_package
|
27
|
+
poise_languages_scl pkg[:name] do
|
28
|
+
parent new_resource
|
29
|
+
url pkg[:url]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def uninstall_scl_package
|
34
|
+
install_scl_package.tap do |r|
|
35
|
+
r.action(:uninstall)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def scl_package
|
40
|
+
@scl_package ||= self.class.find_scl_package(node, options['version']).tap do |p|
|
41
|
+
raise PoiseLanguages::Error.new("No SCL repoistory package for #{node['platform']} #{node['platform_version']}") unless p
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def scl_folder
|
46
|
+
::File.join('', 'opt', 'rh', scl_package[:name])
|
47
|
+
end
|
48
|
+
|
49
|
+
def scl_environment
|
50
|
+
parse_enable_file(::File.join(scl_folder, 'enable'))
|
51
|
+
end
|
52
|
+
|
53
|
+
# Parse an SCL enable file to extract the environment variables set in it.
|
54
|
+
#
|
55
|
+
# @param path [String] Path to the enable file.
|
56
|
+
# @return [Hash<String, String>]
|
57
|
+
def parse_enable_file(path)
|
58
|
+
# Doesn't exist yet, so running Python will fail anyway. Just make sure
|
59
|
+
# it fails in the expected way.
|
60
|
+
return {} unless File.exist?(path)
|
61
|
+
# Yes, this is a bash parser in regex. Feel free to be mad at me.
|
62
|
+
IO.readlines(path).inject({}) do |memo, line|
|
63
|
+
if match = line.match(/^export (\w+)=(.*)$/)
|
64
|
+
memo[match[1]] = match[2].gsub(/\$\{(\w+)(:\+:\$\{\w+\})?\}/) do
|
65
|
+
if $2
|
66
|
+
ENV[$1] ? ":#{ENV[$1]}" : ''
|
67
|
+
else
|
68
|
+
ENV[$1].to_s
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
memo
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module ClassMethods
|
77
|
+
def provides_auto?(node, resource)
|
78
|
+
version = inversion_options(node, resource)['version']
|
79
|
+
!!find_scl_package(node, version)
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_scl_package(node, version)
|
83
|
+
pkg = scl_packages.find {|p| p[:version].start_with?(version) }
|
84
|
+
return unless pkg
|
85
|
+
pkg[:url] = node.value_for_platform(pkg[:urls])
|
86
|
+
return unless pkg[:url]
|
87
|
+
pkg
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def scl_packages
|
93
|
+
@scl_packages ||= []
|
94
|
+
end
|
95
|
+
|
96
|
+
def scl_package(version, name, urls)
|
97
|
+
scl_packages << {version: version, name: name, urls: urls}
|
98
|
+
end
|
99
|
+
|
100
|
+
def included(klass)
|
101
|
+
super
|
102
|
+
klass.extend(ClassMethods)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
extend ClassMethods
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'chef/resource'
|
18
|
+
require 'chef/provider'
|
19
|
+
require 'poise'
|
20
|
+
|
21
|
+
|
22
|
+
module PoiseLanguages
|
23
|
+
module Scl
|
24
|
+
# A `poise_language_scl` resource to manage installing a language from
|
25
|
+
# SCL packages. This is an internal implementation detail of
|
26
|
+
# poise-languages.
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 1.0
|
30
|
+
# @provides poise_languages_scl
|
31
|
+
# @action install
|
32
|
+
# @action uninstall
|
33
|
+
class Resource < Chef::Resource
|
34
|
+
include Poise
|
35
|
+
provides(:poise_languages_scl)
|
36
|
+
actions(:install, :uninstall)
|
37
|
+
|
38
|
+
# @!attribute package_name
|
39
|
+
# Name of the SCL package for the language.
|
40
|
+
# @return [String]
|
41
|
+
attribute(:package_name, kind_of: String, name_attribute: true)
|
42
|
+
# @!attribute url
|
43
|
+
# URL to the SCL repository package for the language.
|
44
|
+
# @return [String]
|
45
|
+
attribute(:url, kind_of: String, required: true)
|
46
|
+
# @!attribute parent
|
47
|
+
# Resource for the language runtime. Used only for messages.
|
48
|
+
# @return [Chef::Resource]
|
49
|
+
attribute(:parent, kind_of: Chef::Resource, required: true)
|
50
|
+
end
|
51
|
+
|
52
|
+
# The default provider for `poise_languages_scl`.
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
# @since 1.0
|
56
|
+
# @see Resource
|
57
|
+
# @provides poise_languages_scl
|
58
|
+
class Provider < Chef::Provider
|
59
|
+
include Poise
|
60
|
+
provides(:poise_languages_scl)
|
61
|
+
|
62
|
+
# The `install` action for the `poise_languages_scl` resource.
|
63
|
+
#
|
64
|
+
# @return [void]
|
65
|
+
def action_install
|
66
|
+
notifying_block do
|
67
|
+
install_scl_utils
|
68
|
+
install_scl_repo_package
|
69
|
+
install_scl_package
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# The `uninstall` action for the `poise_languages_scl` resource.
|
74
|
+
#
|
75
|
+
# @return [void]
|
76
|
+
def action_uninstall
|
77
|
+
notifying_block do
|
78
|
+
uninstall_scl_utils
|
79
|
+
uninstall_scl_repo_package
|
80
|
+
uninstall_scl_package
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def install_scl_utils
|
87
|
+
package 'scl-utils' do
|
88
|
+
action :upgrade # This shouldn't be a problem. Famous last words.
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def install_scl_repo_package
|
93
|
+
rpm_package 'rhscl-' + new_resource.package_name do
|
94
|
+
source new_resource.url
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def install_scl_package
|
99
|
+
yum_package new_resource.package_name do
|
100
|
+
flush_cache before: true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def uninstall_scl_utils
|
105
|
+
install_scl_utils.tap do |r|
|
106
|
+
r.action(:remove)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def uninstall_scl_repo_package
|
111
|
+
install_scl_repo_package.tap do |r|
|
112
|
+
r.action(:remove)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def uninstall_scl_package
|
117
|
+
install_scl_package.tap do |r|
|
118
|
+
r.action(:remove)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
|
18
|
+
module PoiseLanguages
|
19
|
+
module System
|
20
|
+
autoload :Mixin, 'poise_languages/system/mixin'
|
21
|
+
autoload :Resource, 'poise_languages/system/resource'
|
22
|
+
autoload :Provider, 'poise_languages/system/resource'
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'poise_languages/system/resource'
|
18
|
+
|
19
|
+
|
20
|
+
module PoiseLanguages
|
21
|
+
module System
|
22
|
+
module Mixin
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Install a language using system packages.
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
# @return [PoiseLanguages::System::Resource]
|
30
|
+
def install_system_packages
|
31
|
+
dev_package_overrides = system_dev_package_overrides
|
32
|
+
poise_languages_system options['package_name'] || system_package_name do
|
33
|
+
# Otherwise use the default install action.
|
34
|
+
action(:upgrade) if options['package_upgrade']
|
35
|
+
parent new_resource
|
36
|
+
# Don't pass true because we want the default computed behavior for that.
|
37
|
+
dev_package options['dev_package'] unless options['dev_package'] == true
|
38
|
+
dev_package_overrides dev_package_overrides
|
39
|
+
package_version options['package_version'] if options['package_version']
|
40
|
+
version options['version']
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Uninstall a language using system packages.
|
45
|
+
#
|
46
|
+
# @api public
|
47
|
+
# @return [PoiseLanguages::System::Resource]
|
48
|
+
def uninstall_system_packages
|
49
|
+
install_system_packages.tap do |r|
|
50
|
+
r.action(:uninstall)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Compute all possible package names for a given language version. Must be
|
55
|
+
# implemented by mixin users. Versions are expressed as prefixes so ''
|
56
|
+
# matches all versions, '2' matches 2.x.
|
57
|
+
#
|
58
|
+
# @abstract
|
59
|
+
# @api public
|
60
|
+
# @param version [String] Language version prefix.
|
61
|
+
# @return [Array<String>]
|
62
|
+
def system_package_candidates(version)
|
63
|
+
raise NotImplementedError
|
64
|
+
end
|
65
|
+
|
66
|
+
# Compute the default package name for the base package for this language.
|
67
|
+
#
|
68
|
+
# @api public
|
69
|
+
# @return [String]
|
70
|
+
def system_package_name
|
71
|
+
# Look up all packages for this language on this platform.
|
72
|
+
system_packages = node.value_for_platform(self.class.packages)
|
73
|
+
if !system_packages && self.class.default_package
|
74
|
+
Chef::Log.debug("[#{new_resource}] No known packages for #{node['platform']} #{node['platform_version']}, defaulting to '#{self.class.default_package}'.")
|
75
|
+
system_packages = Array(self.class.default_package)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Find the first value on system_package_candidates that is in system_packages.
|
79
|
+
system_package_candidates(options['version'].to_s).each do |name|
|
80
|
+
return name if system_packages.include?(name)
|
81
|
+
end
|
82
|
+
# No valid candidate. Sad trombone.
|
83
|
+
raise PoiseLanguages::Error.new("Unable to find a candidate package for version #{options['version'].to_s.inspect}. Please set package_name provider option for #{new_resource}.")
|
84
|
+
end
|
85
|
+
|
86
|
+
# A hash mapping package names to their override dev package name.
|
87
|
+
#
|
88
|
+
# @api public
|
89
|
+
# @return [Hash<String, String>]
|
90
|
+
def system_dev_package_overrides
|
91
|
+
{}
|
92
|
+
end
|
93
|
+
|
94
|
+
module ClassMethods
|
95
|
+
# Install this as a default provider for platforms we are relatively
|
96
|
+
# certain work.
|
97
|
+
#
|
98
|
+
# @api private
|
99
|
+
def provides_auto?(node, resource)
|
100
|
+
super || node.platform_family?('debian', 'rhel', 'amazon', 'fedora')
|
101
|
+
end
|
102
|
+
|
103
|
+
# Set some default inversion provider options. Package name can't get
|
104
|
+
# a default value here because that would complicate the handling of
|
105
|
+
# {system_package_candidates}.
|
106
|
+
#
|
107
|
+
# @api private
|
108
|
+
def default_inversion_options(node, resource)
|
109
|
+
super.merge({
|
110
|
+
# Install dev headers?
|
111
|
+
dev_package: true,
|
112
|
+
# Manual overrides for package name and/or version.
|
113
|
+
package_name: nil,
|
114
|
+
package_version: nil,
|
115
|
+
# Set to true to use action :upgrade on system packages.
|
116
|
+
package_upgrade: false,
|
117
|
+
})
|
118
|
+
end
|
119
|
+
|
120
|
+
# @overload packages()
|
121
|
+
# Return a hash formatted for value_for_platform returning an Array
|
122
|
+
# of package names.
|
123
|
+
# @return [Hash]
|
124
|
+
# @overload packages(default_package, packages)
|
125
|
+
# Define what system packages are available for this language on each
|
126
|
+
# platform.
|
127
|
+
# @param default_package [String] Default package name for platforms
|
128
|
+
# not otherwise defined.
|
129
|
+
# @param [Hash] Hash formatted for value_for_platform returning an
|
130
|
+
# Array of package names.
|
131
|
+
# @return [Hash]
|
132
|
+
def packages(default_package=nil, packages=nil)
|
133
|
+
self.default_package(default_package) if default_package
|
134
|
+
if packages
|
135
|
+
@packages = packages
|
136
|
+
end
|
137
|
+
@packages
|
138
|
+
end
|
139
|
+
|
140
|
+
# @overload default_package()
|
141
|
+
# Return the default package name for platforms not otherwise defined.
|
142
|
+
# @return [String]
|
143
|
+
# @overload default_package(name)
|
144
|
+
# Set the default package name for platforms not defined in {packages}.
|
145
|
+
# @param name [String] Package name.
|
146
|
+
# @return [String]
|
147
|
+
def default_package(name=nil)
|
148
|
+
if name
|
149
|
+
@default_package = name
|
150
|
+
end
|
151
|
+
@default_package
|
152
|
+
end
|
153
|
+
|
154
|
+
# @api private
|
155
|
+
def included(klass)
|
156
|
+
super
|
157
|
+
klass.extend(ClassMethods)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
extend ClassMethods
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|