from-scratch 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Berksfile.lock +11 -0
- data/chefignore +1 -0
- data/cookbooks/apt/CHANGELOG.md +248 -0
- data/cookbooks/apt/README.md +294 -0
- data/cookbooks/apt/attributes/default.rb +51 -0
- data/cookbooks/apt/files/default/15update-stamp +1 -0
- data/cookbooks/apt/files/default/apt-proxy-v2.conf +50 -0
- data/cookbooks/apt/libraries/helpers.rb +61 -0
- data/cookbooks/apt/libraries/matchers.rb +17 -0
- data/cookbooks/apt/libraries/network.rb +31 -0
- data/cookbooks/apt/metadata.json +1 -0
- data/cookbooks/apt/providers/preference.rb +84 -0
- data/cookbooks/apt/providers/repository.rb +246 -0
- data/cookbooks/apt/recipes/cacher-client.rb +83 -0
- data/cookbooks/apt/recipes/cacher-ng.rb +43 -0
- data/cookbooks/apt/recipes/default.rb +112 -0
- data/cookbooks/apt/recipes/unattended-upgrades.rb +47 -0
- data/cookbooks/apt/resources/preference.rb +37 -0
- data/cookbooks/apt/resources/repository.rb +60 -0
- data/cookbooks/apt/templates/debian-6.0/acng.conf.erb +173 -0
- data/cookbooks/apt/templates/default/01proxy.erb +9 -0
- data/cookbooks/apt/templates/default/10recommends.erb +3 -0
- data/cookbooks/apt/templates/default/20auto-upgrades.erb +2 -0
- data/cookbooks/apt/templates/default/50unattended-upgrades.erb +68 -0
- data/cookbooks/apt/templates/default/acng.conf.erb +275 -0
- data/cookbooks/apt/templates/default/unattended-upgrades.seed.erb +1 -0
- data/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb +269 -0
- data/cookbooks/build-essential/CHANGELOG.md +136 -0
- data/cookbooks/build-essential/README.md +108 -0
- data/cookbooks/build-essential/attributes/default.rb +20 -0
- data/cookbooks/build-essential/libraries/matchers.rb +5 -0
- data/cookbooks/build-essential/libraries/timing.rb +124 -0
- data/cookbooks/build-essential/libraries/xcode_command_line_tools.rb +210 -0
- data/cookbooks/build-essential/metadata.json +1 -0
- data/cookbooks/build-essential/recipes/_debian.rb +28 -0
- data/cookbooks/build-essential/recipes/_fedora.rb +32 -0
- data/cookbooks/build-essential/recipes/_freebsd.rb +24 -0
- data/cookbooks/build-essential/recipes/_mac_os_x.rb +22 -0
- data/cookbooks/build-essential/recipes/_omnios.rb +33 -0
- data/cookbooks/build-essential/recipes/_rhel.rb +36 -0
- data/cookbooks/build-essential/recipes/_smartos.rb +27 -0
- data/cookbooks/build-essential/recipes/_solaris2.rb +48 -0
- data/cookbooks/build-essential/recipes/_suse.rb +29 -0
- data/cookbooks/build-essential/recipes/default.rb +29 -0
- data/cookbooks/chef-sugar/CHANGELOG.md +159 -0
- data/cookbooks/chef-sugar/README.md +464 -0
- data/cookbooks/chef-sugar/metadata.json +1 -0
- data/cookbooks/chef-sugar/recipes/default.rb +34 -0
- data/cookbooks/openssl/CHANGELOG.md +30 -0
- data/cookbooks/openssl/README.md +115 -0
- data/cookbooks/openssl/attributes/default.rb +21 -0
- data/cookbooks/openssl/libraries/secure_password.rb +37 -0
- data/cookbooks/openssl/metadata.json +31 -0
- data/cookbooks/openssl/providers/x509.rb +94 -0
- data/cookbooks/openssl/recipes/default.rb +18 -0
- data/cookbooks/openssl/recipes/upgrade.rb +39 -0
- data/cookbooks/openssl/resources/x509.rb +16 -0
- data/cookbooks/postgresql/CHANGELOG.md +220 -0
- data/cookbooks/postgresql/README.md +464 -0
- data/cookbooks/postgresql/attributes/default.rb +549 -0
- data/cookbooks/postgresql/files/default/tests/minitest/apt_pgdg_postgresql_test.rb +39 -0
- data/cookbooks/postgresql/files/default/tests/minitest/default_test.rb +27 -0
- data/cookbooks/postgresql/files/default/tests/minitest/ruby_test.rb +28 -0
- data/cookbooks/postgresql/files/default/tests/minitest/server_test.rb +43 -0
- data/cookbooks/postgresql/files/default/tests/minitest/support/helpers.rb +29 -0
- data/cookbooks/postgresql/libraries/default.rb +377 -0
- data/cookbooks/postgresql/metadata.json +56 -0
- data/cookbooks/postgresql/recipes/apt_pgdg_postgresql.rb +18 -0
- data/cookbooks/postgresql/recipes/client.rb +32 -0
- data/cookbooks/postgresql/recipes/config_initdb.rb +148 -0
- data/cookbooks/postgresql/recipes/config_pgtune.rb +284 -0
- data/cookbooks/postgresql/recipes/contrib.rb +44 -0
- data/cookbooks/postgresql/recipes/default.rb +18 -0
- data/cookbooks/postgresql/recipes/ruby.rb +117 -0
- data/cookbooks/postgresql/recipes/server.rb +89 -0
- data/cookbooks/postgresql/recipes/server_conf.rb +34 -0
- data/cookbooks/postgresql/recipes/server_debian.rb +38 -0
- data/cookbooks/postgresql/recipes/server_redhat.rb +100 -0
- data/cookbooks/postgresql/recipes/yum_pgdg_postgresql.rb +45 -0
- data/cookbooks/postgresql/templates/default/pg_hba.conf.erb +35 -0
- data/cookbooks/postgresql/templates/default/pgsql.sysconfig.erb +4 -0
- data/cookbooks/postgresql/templates/default/postgresql.conf.erb +21 -0
- data/cookbooks/scratchify/.chef/knife.rb +2 -5
- data/cookbooks/scratchify/Berksfile +2 -1
- data/cookbooks/scratchify/Berksfile.lock +11 -0
- data/cookbooks/scratchify/README.md +34 -17
- data/cookbooks/scratchify/bin/scratchify +1 -1
- data/cookbooks/scratchify/chefignore +1 -0
- data/cookbooks/scratchify/from-scratch.gemspec +2 -5
- data/cookbooks/scratchify/lib/from-scratch.rb +25 -0
- data/cookbooks/scratchify/lib/{from/scratch → from-scratch}/version.rb +1 -1
- data/cookbooks/scratchify/metadata.json +2 -1
- data/cookbooks/scratchify/templates/node.json.erb +34 -0
- data/cookbooks/scratchify/templates/user.json.erb +6 -0
- data/lib/from-scratch.rb +2 -2
- data/lib/from-scratch/version.rb +1 -1
- data/templates/node.json.erb +6 -3
- metadata +85 -10
- data/cookbooks/scratchify/bin/console +0 -14
- data/cookbooks/scratchify/bin/setup +0 -7
- data/cookbooks/scratchify/data_bags/users/deploy.json +0 -6
- data/cookbooks/scratchify/environments/.gitkeep +0 -0
- data/cookbooks/scratchify/lib/from/scratch.rb +0 -31
- data/cookbooks/scratchify/lib/from/scratch/interviewer.rb +0 -35
- data/cookbooks/scratchify/nodes/normfood.ru.json +0 -75
- data/cookbooks/scratchify/roles/.gitkeep +0 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
#
|
2
|
+
# Cookbook Name:: apt
|
3
|
+
# Attributes:: default
|
4
|
+
#
|
5
|
+
# Copyright 2009-2013, Chef Software, Inc.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
default['apt']['cacher-client']['restrict_environment'] = false
|
21
|
+
default['apt']['cacher_dir'] = '/var/cache/apt-cacher-ng'
|
22
|
+
default['apt']['cacher_interface'] = nil
|
23
|
+
default['apt']['cacher_port'] = 3142
|
24
|
+
default['apt']['cacher_ssl_support'] = false
|
25
|
+
default['apt']['caching_server'] = false
|
26
|
+
default['apt']['compiletime'] = false
|
27
|
+
default['apt']['compile_time_update'] = false
|
28
|
+
default['apt']['key_proxy'] = ''
|
29
|
+
default['apt']['cache_bypass'] = {}
|
30
|
+
default['apt']['periodic_update_min_delay'] = 86_400
|
31
|
+
default['apt']['launchpad_api_version'] = '1.0'
|
32
|
+
default['apt']['unattended_upgrades']['enable'] = false
|
33
|
+
default['apt']['unattended_upgrades']['update_package_lists'] = true
|
34
|
+
# this needs a good default
|
35
|
+
codename = node.attribute?('lsb') ? node['lsb']['codename'] : 'notlinux'
|
36
|
+
default['apt']['unattended_upgrades']['allowed_origins'] = [
|
37
|
+
"#{node['platform'].capitalize} #{codename}"
|
38
|
+
]
|
39
|
+
default['apt']['unattended_upgrades']['package_blacklist'] = []
|
40
|
+
default['apt']['unattended_upgrades']['auto_fix_interrupted_dpkg'] = false
|
41
|
+
default['apt']['unattended_upgrades']['minimal_steps'] = false
|
42
|
+
default['apt']['unattended_upgrades']['install_on_shutdown'] = false
|
43
|
+
default['apt']['unattended_upgrades']['mail'] = nil
|
44
|
+
default['apt']['unattended_upgrades']['mail_only_on_error'] = true
|
45
|
+
default['apt']['unattended_upgrades']['remove_unused_dependencies'] = false
|
46
|
+
default['apt']['unattended_upgrades']['automatic_reboot'] = false
|
47
|
+
default['apt']['unattended_upgrades']['automatic_reboot_time'] = 'now'
|
48
|
+
default['apt']['unattended_upgrades']['dl_limit'] = nil
|
49
|
+
|
50
|
+
default['apt']['confd']['install_recommends'] = true
|
51
|
+
default['apt']['confd']['install_suggests'] = false
|
@@ -0,0 +1 @@
|
|
1
|
+
APT::Update::Post-Invoke-Success {"touch /var/lib/apt/periodic/update-success-stamp 2>/dev/null || true";};
|
@@ -0,0 +1,50 @@
|
|
1
|
+
[DEFAULT]
|
2
|
+
;; All times are in seconds, but you can add a suffix
|
3
|
+
;; for minutes(m), hours(h) or days(d)
|
4
|
+
|
5
|
+
;; commented out address so apt-proxy will listen on all IPs
|
6
|
+
;; address = 127.0.0.1
|
7
|
+
port = 9999
|
8
|
+
cache_dir = /var/cache/apt-proxy
|
9
|
+
|
10
|
+
;; Control files (Packages/Sources/Contents) refresh rate
|
11
|
+
min_refresh_delay = 1s
|
12
|
+
complete_clientless_downloads = 1
|
13
|
+
|
14
|
+
;; Debugging settings.
|
15
|
+
debug = all:4 db:0
|
16
|
+
|
17
|
+
time = 30
|
18
|
+
passive_ftp = on
|
19
|
+
|
20
|
+
;;--------------------------------------------------------------
|
21
|
+
;; Cache housekeeping
|
22
|
+
|
23
|
+
cleanup_freq = 1d
|
24
|
+
max_age = 120d
|
25
|
+
max_versions = 3
|
26
|
+
|
27
|
+
;;---------------------------------------------------------------
|
28
|
+
;; Backend servers
|
29
|
+
;;
|
30
|
+
;; Place each server in its own [section]
|
31
|
+
|
32
|
+
[ubuntu]
|
33
|
+
; Ubuntu archive
|
34
|
+
backends =
|
35
|
+
http://us.archive.ubuntu.com/ubuntu
|
36
|
+
|
37
|
+
[ubuntu-security]
|
38
|
+
; Ubuntu security updates
|
39
|
+
backends = http://security.ubuntu.com/ubuntu
|
40
|
+
|
41
|
+
[debian]
|
42
|
+
;; Backend servers, in order of preference
|
43
|
+
backends =
|
44
|
+
http://debian.osuosl.org/debian/
|
45
|
+
|
46
|
+
[security]
|
47
|
+
;; Debian security archive
|
48
|
+
backends =
|
49
|
+
http://security.debian.org/debian-security
|
50
|
+
http://ftp2.de.debian.org/debian-security
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#
|
2
|
+
# Cookbook Name:: apt
|
3
|
+
# Library:: helpers
|
4
|
+
#
|
5
|
+
# Copyright 2013 Chef Software, Inc.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
module Apt
|
21
|
+
# Helpers for apt
|
22
|
+
module Helpers
|
23
|
+
# Determines if apt is installed on a system.
|
24
|
+
#
|
25
|
+
# @return [Boolean]
|
26
|
+
def apt_installed?
|
27
|
+
!which('apt-get').nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
# Determines whether we need to run `apt-get update`
|
31
|
+
#
|
32
|
+
# @return [Boolean]
|
33
|
+
def apt_up_to_date?
|
34
|
+
if ::File.exist?('/var/lib/apt/periodic/update-success-stamp') &&
|
35
|
+
::File.mtime('/var/lib/apt/periodic/update-success-stamp') > Time.now - node['apt']['periodic_update_min_delay']
|
36
|
+
true
|
37
|
+
else
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Finds a command in $PATH
|
43
|
+
#
|
44
|
+
# @return [String, nil]
|
45
|
+
def which(cmd)
|
46
|
+
ENV['PATH'] = '' if ENV['PATH'].nil?
|
47
|
+
paths = (ENV['PATH'].split(::File::PATH_SEPARATOR) + %w(/bin /usr/bin /sbin /usr/sbin))
|
48
|
+
|
49
|
+
paths.each do |path|
|
50
|
+
possible = File.join(path, cmd)
|
51
|
+
return possible if File.executable?(possible)
|
52
|
+
end
|
53
|
+
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
Chef::Recipe.send(:include, ::Apt::Helpers)
|
60
|
+
Chef::Resource.send(:include, ::Apt::Helpers)
|
61
|
+
Chef::Provider.send(:include, ::Apt::Helpers)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
if defined?(ChefSpec)
|
2
|
+
def add_apt_preference(resource_name)
|
3
|
+
ChefSpec::Matchers::ResourceMatcher.new(:apt_preference, :add, resource_name)
|
4
|
+
end
|
5
|
+
|
6
|
+
def remove_apt_preference(resource_name)
|
7
|
+
ChefSpec::Matchers::ResourceMatcher.new(:apt_preference, :remove, resource_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_apt_repository(resource_name)
|
11
|
+
ChefSpec::Matchers::ResourceMatcher.new(:apt_repository, :add, resource_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove_apt_repository(resource_name)
|
15
|
+
ChefSpec::Matchers::ResourceMatcher.new(:apt_repository, :remove, resource_name)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# Cookbook Name:: apt
|
3
|
+
# library:: network
|
4
|
+
#
|
5
|
+
# Copyright 2013, Chef Software, Inc.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
module ::Apt
|
21
|
+
def interface_ipaddress(host, interface)
|
22
|
+
if interface
|
23
|
+
addresses = host['network']['interfaces'][interface]['addresses']
|
24
|
+
addresses.select do |ip, data|
|
25
|
+
return ip if data['family'].eql?('inet')
|
26
|
+
end
|
27
|
+
else
|
28
|
+
return host.ipaddress
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"name":"apt","version":"2.9.2","description":"Configures apt and apt services. Ships resources for managing apt repositories","long_description":"","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{"ubuntu":">= 0.0.0","debian":">= 0.0.0"},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"apt::default":"Runs apt-get update during compile phase and sets up preseed directories","apt::cacher-ng":"Set up an apt-cacher-ng caching proxy","apt::cacher-client":"Client for the apt::cacher-ng caching proxy"}}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#
|
2
|
+
# Cookbook Name:: apt
|
3
|
+
# Provider:: preference
|
4
|
+
#
|
5
|
+
# Copyright 2010-2011, Chef Software, Inc.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
use_inline_resources if defined?(use_inline_resources)
|
21
|
+
|
22
|
+
def whyrun_supported?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
# Build preferences.d file contents
|
27
|
+
def build_pref(package_name, pin, pin_priority)
|
28
|
+
"Package: #{package_name}\nPin: #{pin}\nPin-Priority: #{pin_priority}\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
def safe_name(name)
|
32
|
+
name.tr('.', '_').gsub('*', 'wildcard')
|
33
|
+
end
|
34
|
+
|
35
|
+
action :add do
|
36
|
+
preference = build_pref(
|
37
|
+
new_resource.glob || new_resource.package_name,
|
38
|
+
new_resource.pin,
|
39
|
+
new_resource.pin_priority
|
40
|
+
)
|
41
|
+
|
42
|
+
directory '/etc/apt/preferences.d' do
|
43
|
+
owner 'root'
|
44
|
+
group 'root'
|
45
|
+
mode 00755
|
46
|
+
recursive true
|
47
|
+
action :create
|
48
|
+
end
|
49
|
+
|
50
|
+
name = safe_name(new_resource.name)
|
51
|
+
|
52
|
+
file "/etc/apt/preferences.d/#{new_resource.name}.pref" do
|
53
|
+
action :delete
|
54
|
+
if ::File.exist?("/etc/apt/preferences.d/#{new_resource.name}.pref")
|
55
|
+
Chef::Log.warn "Replacing #{new_resource.name}.pref with #{name}.pref in /etc/apt/preferences.d/"
|
56
|
+
end
|
57
|
+
only_if { name != new_resource.name }
|
58
|
+
end
|
59
|
+
|
60
|
+
file "/etc/apt/preferences.d/#{new_resource.name}" do
|
61
|
+
action :delete
|
62
|
+
if ::File.exist?("/etc/apt/preferences.d/#{new_resource.name}")
|
63
|
+
Chef::Log.warn "Replacing #{new_resource.name} with #{new_resource.name}.pref in /etc/apt/preferences.d/"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
file "/etc/apt/preferences.d/#{name}.pref" do
|
68
|
+
owner 'root'
|
69
|
+
group 'root'
|
70
|
+
mode 00644
|
71
|
+
content preference
|
72
|
+
action :create
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
action :remove do
|
77
|
+
name = safe_name(new_resource.name)
|
78
|
+
if ::File.exist?("/etc/apt/preferences.d/#{name}.pref")
|
79
|
+
Chef::Log.info "Un-pinning #{name} from /etc/apt/preferences.d/"
|
80
|
+
file "/etc/apt/preferences.d/#{name}.pref" do
|
81
|
+
action :delete
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
#
|
2
|
+
# Cookbook Name:: apt
|
3
|
+
# Provider:: repository
|
4
|
+
#
|
5
|
+
# Copyright 2010-2011, Chef Software, Inc.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
use_inline_resources if defined?(use_inline_resources)
|
21
|
+
|
22
|
+
def whyrun_supported?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
# install apt key from keyserver
|
27
|
+
def install_key_from_keyserver(key, keyserver, key_proxy)
|
28
|
+
execute "install-key #{key}" do
|
29
|
+
if keyserver.start_with?('hkp://')
|
30
|
+
command "apt-key adv --keyserver #{keyserver} --recv #{key}"
|
31
|
+
elsif key_proxy.empty?
|
32
|
+
command "apt-key adv --keyserver hkp://#{keyserver}:80 --recv #{key}"
|
33
|
+
else
|
34
|
+
command "apt-key adv --keyserver-options http-proxy=#{key_proxy} --keyserver hkp://#{keyserver}:80 --recv #{key}"
|
35
|
+
end
|
36
|
+
sensitive new_resource.sensitive if respond_to?(:sensitive)
|
37
|
+
action :run
|
38
|
+
not_if do
|
39
|
+
key_present = extract_fingerprints_from_cmd('apt-key finger').any? do |fingerprint|
|
40
|
+
fingerprint.end_with?(key.upcase)
|
41
|
+
end
|
42
|
+
|
43
|
+
key_present && key_is_valid('apt-key list', key.upcase)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
ruby_block "validate-key #{key}" do
|
48
|
+
block do
|
49
|
+
fail "The key #{key} is no longer valid and cannot be used for an apt repository."
|
50
|
+
end
|
51
|
+
not_if { key_is_valid('apt-key list', key.upcase) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# run command and extract gpg ids
|
56
|
+
def extract_fingerprints_from_cmd(cmd)
|
57
|
+
so = Mixlib::ShellOut.new(cmd, env: { 'LANG' => 'en_US', 'LANGUAGE' => 'en_US' })
|
58
|
+
so.run_command
|
59
|
+
so.stdout.split(/\n/).map do |t|
|
60
|
+
if z = t.match(/^ +Key fingerprint = ([0-9A-F ]+)/)
|
61
|
+
z[1].split.join
|
62
|
+
end
|
63
|
+
end.compact
|
64
|
+
end
|
65
|
+
|
66
|
+
# determine whether apt thinks the key is still valid
|
67
|
+
def key_is_valid(cmd, key)
|
68
|
+
valid = true
|
69
|
+
|
70
|
+
so = Mixlib::ShellOut.new(cmd, env: { 'LANG' => 'en_US', 'LANGUAGE' => 'en_US' })
|
71
|
+
so.run_command
|
72
|
+
# rubocop:disable Style/Next
|
73
|
+
so.stdout.split(/\n/).map do |t|
|
74
|
+
if t.match(%r{^\/#{key}.*\[expired: .*\]$})
|
75
|
+
Chef::Log.debug "Found expired key: #{t}"
|
76
|
+
valid = false
|
77
|
+
break
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
Chef::Log.debug "key #{key} validity: #{valid}"
|
82
|
+
valid
|
83
|
+
end
|
84
|
+
|
85
|
+
# install apt key from URI
|
86
|
+
def install_key_from_uri(uri)
|
87
|
+
key_name = uri.split(%r{\/}).last
|
88
|
+
cached_keyfile = "#{Chef::Config[:file_cache_path]}/#{key_name}"
|
89
|
+
if new_resource.key =~ /http/
|
90
|
+
remote_file cached_keyfile do
|
91
|
+
source new_resource.key
|
92
|
+
mode 00644
|
93
|
+
sensitive new_resource.sensitive if respond_to?(:sensitive)
|
94
|
+
action :create
|
95
|
+
end
|
96
|
+
else
|
97
|
+
cookbook_file cached_keyfile do
|
98
|
+
source new_resource.key
|
99
|
+
cookbook new_resource.cookbook
|
100
|
+
mode 00644
|
101
|
+
sensitive new_resource.sensitive if respond_to?(:sensitive)
|
102
|
+
action :create
|
103
|
+
end
|
104
|
+
|
105
|
+
ruby_block "validate-key #{cached_keyfile}" do
|
106
|
+
block do
|
107
|
+
fail "The key #{cached_keyfile} is no longer valid and cannot be used for an apt repository." unless key_is_valid("gpg #{cached_keyfile}", '')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
execute "install-key #{key_name}" do
|
113
|
+
command "apt-key add #{cached_keyfile}"
|
114
|
+
sensitive new_resource.sensitive if respond_to?(:sensitive)
|
115
|
+
action :run
|
116
|
+
not_if do
|
117
|
+
installed_keys = extract_fingerprints_from_cmd('apt-key finger')
|
118
|
+
proposed_keys = extract_fingerprints_from_cmd("gpg --with-fingerprint #{cached_keyfile}")
|
119
|
+
(installed_keys & proposed_keys).sort == proposed_keys.sort
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# build repo file contents
|
125
|
+
def build_repo(uri, distribution, components, trusted, arch, add_deb_src)
|
126
|
+
uri = '"' + uri + '"' unless uri.start_with?("\"", "'")
|
127
|
+
components = components.join(' ') if components.respond_to?(:join)
|
128
|
+
repo_options = []
|
129
|
+
repo_options << "arch=#{arch}" if arch
|
130
|
+
repo_options << 'trusted=yes' if trusted
|
131
|
+
repo_opts = '[' + repo_options.join(' ') + ']' unless repo_options.empty?
|
132
|
+
repo_info = "#{repo_opts} #{uri} #{distribution} #{components}\n".lstrip
|
133
|
+
repo = "deb #{repo_info}"
|
134
|
+
repo << "deb-src #{repo_info}" if add_deb_src
|
135
|
+
repo
|
136
|
+
end
|
137
|
+
|
138
|
+
def get_ppa_key(ppa_owner, ppa_repo, key_proxy)
|
139
|
+
# Launchpad has currently only one stable API which is marked as EOL April 2015.
|
140
|
+
# The new api in devel still uses the same api call for +archive, so I made the version
|
141
|
+
# configurable to provide some sort of workaround if api 1.0 ceases to exist.
|
142
|
+
# See https://launchpad.net/+apidoc/
|
143
|
+
launchpad_ppa_api = "https://launchpad.net/api/#{node['apt']['launchpad_api_version']}/~%s/+archive/%s"
|
144
|
+
default_keyserver = 'keyserver.ubuntu.com'
|
145
|
+
|
146
|
+
require 'open-uri'
|
147
|
+
api_query = format("#{launchpad_ppa_api}/signing_key_fingerprint", ppa_owner, ppa_repo)
|
148
|
+
begin
|
149
|
+
key_id = open(api_query).read.delete('"')
|
150
|
+
rescue OpenURI::HTTPError => e
|
151
|
+
error = 'Could not access launchpad ppa key api: HttpError: ' + e.message
|
152
|
+
raise error
|
153
|
+
rescue SocketError => e
|
154
|
+
error = 'Could not access launchpad ppa key api: SocketError: ' + e.message
|
155
|
+
raise error
|
156
|
+
end
|
157
|
+
|
158
|
+
install_key_from_keyserver(key_id, default_keyserver, key_proxy)
|
159
|
+
end
|
160
|
+
|
161
|
+
# fetch ppa key, return full repo url
|
162
|
+
def get_ppa_url(ppa, key_proxy)
|
163
|
+
repo_schema = 'http://ppa.launchpad.net/%s/%s/ubuntu'
|
164
|
+
|
165
|
+
# ppa:user/repo logic ported from
|
166
|
+
# http://bazaar.launchpad.net/~ubuntu-core-dev/software-properties/main/view/head:/softwareproperties/ppa.py#L86
|
167
|
+
return false unless ppa.start_with?('ppa:')
|
168
|
+
|
169
|
+
ppa_name = ppa.split(':')[1]
|
170
|
+
ppa_owner = ppa_name.split('/')[0]
|
171
|
+
ppa_repo = ppa_name.split('/')[1]
|
172
|
+
ppa_repo = 'ppa' if ppa_repo.nil?
|
173
|
+
|
174
|
+
get_ppa_key(ppa_owner, ppa_repo, key_proxy)
|
175
|
+
|
176
|
+
format(repo_schema, ppa_owner, ppa_repo)
|
177
|
+
end
|
178
|
+
|
179
|
+
action :add do
|
180
|
+
# add key
|
181
|
+
if new_resource.keyserver && new_resource.key
|
182
|
+
install_key_from_keyserver(new_resource.key, new_resource.keyserver, new_resource.key_proxy)
|
183
|
+
elsif new_resource.key
|
184
|
+
install_key_from_uri(new_resource.key)
|
185
|
+
end
|
186
|
+
|
187
|
+
file '/var/lib/apt/periodic/update-success-stamp' do
|
188
|
+
action :nothing
|
189
|
+
end
|
190
|
+
|
191
|
+
execute 'apt-cache gencaches' do
|
192
|
+
ignore_failure true
|
193
|
+
action :nothing
|
194
|
+
end
|
195
|
+
|
196
|
+
execute 'apt-get update' do
|
197
|
+
command "apt-get update -o Dir::Etc::sourcelist='sources.list.d/#{new_resource.name}.list' -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0'"
|
198
|
+
ignore_failure true
|
199
|
+
sensitive new_resource.sensitive if respond_to?(:sensitive)
|
200
|
+
action :nothing
|
201
|
+
notifies :run, 'execute[apt-cache gencaches]', :immediately
|
202
|
+
end
|
203
|
+
|
204
|
+
if new_resource.uri.start_with?('ppa:')
|
205
|
+
# build ppa repo file
|
206
|
+
repository = build_repo(
|
207
|
+
get_ppa_url(new_resource.uri, new_resource.key_proxy),
|
208
|
+
new_resource.distribution,
|
209
|
+
'main',
|
210
|
+
new_resource.trusted,
|
211
|
+
new_resource.arch,
|
212
|
+
new_resource.deb_src
|
213
|
+
)
|
214
|
+
else
|
215
|
+
# build repo file
|
216
|
+
repository = build_repo(
|
217
|
+
new_resource.uri,
|
218
|
+
new_resource.distribution,
|
219
|
+
new_resource.components,
|
220
|
+
new_resource.trusted,
|
221
|
+
new_resource.arch,
|
222
|
+
new_resource.deb_src
|
223
|
+
)
|
224
|
+
end
|
225
|
+
|
226
|
+
file "/etc/apt/sources.list.d/#{new_resource.name}.list" do
|
227
|
+
owner 'root'
|
228
|
+
group 'root'
|
229
|
+
mode 00644
|
230
|
+
content repository
|
231
|
+
sensitive new_resource.sensitive if respond_to?(:sensitive)
|
232
|
+
action :create
|
233
|
+
notifies :delete, 'file[/var/lib/apt/periodic/update-success-stamp]', :immediately
|
234
|
+
notifies :run, 'execute[apt-get update]', :immediately if new_resource.cache_rebuild
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
action :remove do
|
239
|
+
if ::File.exist?("/etc/apt/sources.list.d/#{new_resource.name}.list")
|
240
|
+
Chef::Log.info "Removing #{new_resource.name} repository from /etc/apt/sources.list.d/"
|
241
|
+
file "/etc/apt/sources.list.d/#{new_resource.name}.list" do
|
242
|
+
sensitive new_resource.sensitive if respond_to?(:sensitive)
|
243
|
+
action :delete
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|