fhcap-cli 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +2 -0
  4. data/lib/cookbooks/provision/libraries/provision.rb +24 -0
  5. data/lib/cookbooks/provision/recipes/aws_cluster_create.rb +1 -2
  6. data/lib/cookbooks/provision/recipes/cluster_create_instances.rb +14 -0
  7. data/lib/cookbooks/provision/recipes/cluster_destroy_instances.rb +6 -6
  8. data/lib/cookbooks/provision/recipes/cluster_provision_instances.rb +7 -47
  9. data/lib/cookbooks/provision/recipes/openstack_cluster_create.rb +9 -9
  10. data/lib/cookbooks/provision/recipes/seed_cookbooks.rb +38 -0
  11. data/lib/fhcap/cli.rb +4 -0
  12. data/lib/fhcap/cluster.rb +13 -1
  13. data/lib/fhcap/config.rb +4 -0
  14. data/lib/fhcap/cookbook.rb +10 -0
  15. data/lib/fhcap/dns.rb +60 -0
  16. data/lib/fhcap/misc.rb +17 -24
  17. data/lib/fhcap/tasks/chef/chef_server_task.rb +105 -0
  18. data/lib/fhcap/tasks/chef/chef_task_base.rb +2 -40
  19. data/lib/fhcap/tasks/chef/chef_zero_server.rb +35 -0
  20. data/lib/fhcap/tasks/chef/cookbook/archive.rb +42 -0
  21. data/lib/fhcap/tasks/chef/cookbook/update_metadata.rb +1 -1
  22. data/lib/fhcap/tasks/chef/environments/destroy.rb +10 -10
  23. data/lib/fhcap/tasks/chef/provisioning/chef_provisioning_task.rb +3 -1
  24. data/lib/fhcap/tasks/chef/provisioning/chef_provisioning_task_base.rb +14 -7
  25. data/lib/fhcap/tasks/chef/provisioning/create.rb +12 -3
  26. data/lib/fhcap/tasks/chef/provisioning/destroy.rb +5 -2
  27. data/lib/fhcap/tasks/chef/provisioning/provision.rb +4 -2
  28. data/lib/fhcap/tasks/chef/server/bootstrap.rb +47 -122
  29. data/lib/fhcap/tasks/chef/server/info.rb +8 -7
  30. data/lib/fhcap/tasks/chef/server/provision.rb +17 -17
  31. data/lib/fhcap/tasks/cluster/chef_provisioning_task.rb +16 -0
  32. data/lib/fhcap/tasks/cluster/cluster_task_base.rb +8 -0
  33. data/lib/fhcap/tasks/cluster/create.rb +6 -5
  34. data/lib/fhcap/tasks/cluster/destroy.rb +15 -4
  35. data/lib/fhcap/tasks/cluster/destroy_environment.rb +1 -1
  36. data/lib/fhcap/tasks/cluster/info.rb +1 -1
  37. data/lib/fhcap/tasks/cluster/provision.rb +3 -3
  38. data/lib/fhcap/tasks/cluster/status.rb +1 -1
  39. data/lib/fhcap/tasks/dns/create_record.rb +79 -0
  40. data/lib/fhcap/tasks/dns/delete_record.rb +55 -0
  41. data/lib/fhcap/tasks/dns/list.rb +37 -0
  42. data/lib/fhcap/tasks/dns/route53_helper.rb +48 -0
  43. data/lib/fhcap/tasks/knife/add.rb +43 -8
  44. data/lib/fhcap/tasks/repo/checkout.rb +1 -0
  45. data/lib/fhcap/tasks/task_base.rb +25 -0
  46. data/lib/fhcap/version.rb +1 -1
  47. data/spec/fhcap/tasks/dns/create_record_spec.rb +34 -0
  48. data/spec/fhcap/tasks/dns/delete_record_spec.rb +30 -0
  49. data/templates/chef/environment_core.json.erb +1 -1
  50. data/templates/cluster/aws/common.json.erb +1 -1
  51. data/templates/cluster/aws/core-small-9node.json.erb +3 -3
  52. data/templates/cluster/aws/single-blank.json.erb +2 -1
  53. data/templates/cluster/openstack/core-3node.json.erb +1 -1
  54. data/templates/cluster/openstack/core-small-9node.json.erb +4 -4
  55. data/templates/cluster/openstack/mbaas-3node.json.erb +2 -2
  56. data/templates/cluster/openstack/single-blank.json.erb +0 -1
  57. data/templates/init/knife_local.rb.erb +9 -0
  58. metadata +19 -4
  59. data/lib/fhcap/tasks/misc/create_dns_record.rb +0 -100
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca661464735cee084781d5c7a514eefe7fa751ff
4
- data.tar.gz: c271b0c52264a968cc03ab551a934190ad621908
3
+ metadata.gz: 4068e4a42ccdb6ecf9ed5f1e74e34f8a7d1050ea
4
+ data.tar.gz: 9e703a039cda7f9572dbb78254ccc24d36b9a495
5
5
  SHA512:
6
- metadata.gz: 0a9928bc1d16df598a09bb284bacca492b4ac2cbde3d8631365264a353c09b9b4553a58e60d425cd9aef2623dba2ccdf390ae286a66c18dab4c34813f121352b
7
- data.tar.gz: 55beda877c80d8058d424a12abbc853235119b15bb5b1ed6bbe6d6d3833998e1f6e01a5f7e563a5f311d981f64c3dd225e363d4f5c51c6cb7392b46bfa827514
6
+ metadata.gz: c7c1c547d42be6f597042723e9f00e3a46cc30e93750bc93b65e50d2bc08436f5b1a1a2339a5be8d46e5a2eb97067e79aa89b85fab72f88fb6d81a1d23b2a883
7
+ data.tar.gz: 95daf1cb3fa9e7dc7f58b5574daf68a4084fff9cef39706f8f2ab3e89a9e3ee8c9124a8a4f27e505cea9ae6d5c15b4e994c2b83eead184a1e824d885d5e641d4
data/CHANGELOG.md CHANGED
@@ -1,4 +1,12 @@
1
1
 
2
+ ## 0.4.3
3
+
4
+ * [RHMAP-3056] - Adds the option to use 'local' chef server, removes the need to have access to a public server to provision anything.
5
+ * [RHMAP-3154] - Separate create and provision parts of cluster create, ensures that even if create fails, it will re-create everything again on the next attempt.
6
+ * [RHMAP-3099] - Add dns record delete task. Update create record to allow updating existing records. Add new cli options for dns.
7
+ * [RHMAP-3182] - Use a dns resolvable wildcard hostname for the apache ServerName/Alias
8
+ * [RHMAP-3270] - Ensure post repo checkout procedure executes after initial repo clone.
9
+
2
10
  ## 0.4.2
3
11
 
4
12
  * [RHMAP-2921] - Add nginx proxy back into AWS single vm run list (http only for the moment).
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  FHCAP Command Line Tool
4
4
 
5
+ For detailed help and documentation relating to fhcap-cli, please see [FHCAP Command Line Tool fhcap-cli](https://github.com/fheng/fhcap/wiki/FHCAP-Command-Line-Tool-(fhcap-cli))
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -138,3 +138,27 @@ end
138
138
  def cluster_config_for(node)
139
139
  JSON.parse(node.normal.to_json, {:symbolize_names => true})
140
140
  end
141
+
142
+ def with_cluster_config(node, &block)
143
+ cluster_config = cluster_config_for(node)
144
+ block.call cluster_config
145
+ end
146
+
147
+ def with_cluster_instances(node, &block)
148
+ with_cluster_config(node) do |cluster_config|
149
+ org_name = cluster_config[:id]
150
+ default_instance_options = cluster_config[:default_instance_options]
151
+ instances = {}
152
+ cluster_config[:environments].each do |env, env_config|
153
+ chef_environment = fh_name_for(org_name, env)
154
+ instances[chef_environment] = {}
155
+
156
+ env_config[:instances].each do |instance_name, instance_config|
157
+ instances[chef_environment][instance_name_for(org_name, env, instance_name)] = {}
158
+ instances[chef_environment][instance_name_for(org_name, env, instance_name)][:instance_config] = instance_config
159
+ instances[chef_environment][instance_name_for(org_name, env, instance_name)][:machine_options] = machine_options_for(cluster_config[:driver], org_name, env, default_instance_options.merge(instance_config[cluster_config[:driver].to_sym] || {}))
160
+ end
161
+ end
162
+ block.call instances
163
+ end
164
+ end
@@ -53,6 +53,5 @@ cluster_config[:environments].each do |env, env_config|
53
53
 
54
54
  end
55
55
 
56
- include_recipe "provision::cluster_provision_instances"
57
-
56
+ include_recipe "provision::cluster_create_instances"
58
57
  include_recipe "provision::aws_cluster_create_elb"
@@ -0,0 +1,14 @@
1
+ with_cluster_instances(node) do |cluster_instances|
2
+ cluster_instances.each do |chef_environment, instances|
3
+ with_chef_environment chef_environment do
4
+ machine_batch do
5
+ instances.each do |name, cfg|
6
+ machine name do
7
+ chef_environment chef_environment
8
+ machine_options(cfg[:machine_options])
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,11 +1,11 @@
1
1
  include_recipe "provision::common"
2
2
  include_recipe "provision::#{node['driver']}"
3
3
 
4
- cluster_config = cluster_config_for(node)
5
- org_name = cluster_config[:id]
6
- node_names = node_names_for(cluster_config)
4
+ with_cluster_config(node) do |cluster_config|
5
+ node_names = node_names_for(cluster_config)
7
6
 
8
- machine_batch do
9
- machines node_names
10
- action :destroy
7
+ machine_batch do
8
+ machines node_names
9
+ action :destroy
10
+ end
11
11
  end
@@ -1,55 +1,15 @@
1
- cluster_config = cluster_config_for(node)
2
- org_name = cluster_config[:id]
3
-
4
- # Create/Provision Instances
5
- default_instance_options = cluster_config[:default_instance_options]
6
- cluster_config[:environments].each do |env, env_config|
7
- chef_environment = fh_name_for(org_name, env)
8
-
9
- instances = {}
10
- env_config[:instances].each do |instance_name, instance_config|
11
- instances[instance_name_for(org_name, env, instance_name)] = {}
12
- instances[instance_name_for(org_name, env, instance_name)][:instance_config] = instance_config
13
- instances[instance_name_for(org_name, env, instance_name)][:machine_options] = machine_options_for(cluster_config[:driver], org_name, env, default_instance_options.merge(instance_config[cluster_config[:driver].to_sym] || {}))
14
- end
15
-
16
- current_nodes = search(:node, "chef_environment:#{chef_environment}").map { |n| n.name }
17
- required_nodes = instances.keys
18
- missing_nodes = required_nodes - current_nodes
19
-
20
- with_chef_environment chef_environment do
21
-
22
- machine_batch do
23
- missing_nodes.each do |instance_name|
24
- machine_options = instances[instance_name][:machine_options]
25
- machine instance_name do
26
- chef_environment chef_environment
27
- run_list ["recipe[feedhenry_common::hostname]"]
28
- machine_options(machine_options)
29
- end
30
- end
31
- not_if { missing_nodes.empty? }
32
- end
33
-
34
- if required_nodes.length > 1
35
- converge_times = missing_nodes.empty? ? 1 : 3
36
- else
37
- converge_times = 1
38
- end
39
-
40
- converge_times.times do
1
+ with_cluster_instances(node) do |cluster_instances|
2
+ cluster_instances.each do |chef_environment, instances|
3
+ with_chef_environment chef_environment do
41
4
  machine_batch do
42
- required_nodes.each do |instance_name|
43
- machine_options = instances[instance_name][:machine_options]
44
- instance_config = instances[instance_name][:instance_config]
45
- machine instance_name do
5
+ instances.each do |name, cfg|
6
+ machine name do
46
7
  chef_environment chef_environment
47
- run_list instance_config[:run_list]
48
- machine_options(machine_options)
8
+ run_list cfg[:instance_config][:run_list]
9
+ machine_options(cfg[:machine_options])
49
10
  end
50
11
  end
51
12
  end
52
13
  end
53
-
54
14
  end
55
15
  end
@@ -1,16 +1,16 @@
1
-
2
1
  include_recipe 'provision::common'
3
2
  include_recipe "provision::openstack"
4
3
 
5
- cluster_config = cluster_config_for(node)
6
- org_name = cluster_config[:id]
4
+ with_cluster_config(node) do |cluster_config|
5
+ org_name = cluster_config[:id]
7
6
 
8
- local_key_pairs_dir = File.join(node[:local_repo_path], node[:local_repo_clusters_dir], 'key_pairs')
9
- key_pair_name = key_pair_name_for(org_name)
7
+ local_key_pairs_dir = File.join(node[:local_repo_path], node[:local_repo_clusters_dir], 'key_pairs')
8
+ key_pair_name = key_pair_name_for(org_name)
10
9
 
11
- fog_key_pair key_pair_name do
12
- private_key_path File.join(local_key_pairs_dir, "#{key_pair_name}.pem")
13
- public_key_path File.join(local_key_pairs_dir, "#{key_pair_name}.pub")
10
+ fog_key_pair key_pair_name do
11
+ private_key_path File.join(local_key_pairs_dir, "#{key_pair_name}.pem")
12
+ public_key_path File.join(local_key_pairs_dir, "#{key_pair_name}.pub")
13
+ end
14
14
  end
15
15
 
16
- include_recipe "provision::cluster_provision_instances"
16
+ include_recipe "provision::cluster_create_instances"
@@ -0,0 +1,38 @@
1
+ include_recipe 'provision::common'
2
+ include_recipe "provision::#{node['driver']}"
3
+
4
+ cluster_config = cluster_config_for(node)
5
+ org_name = cluster_config[:id]
6
+
7
+ download_dir = '/tmp'
8
+ target_dir = '/var/chef/cache'
9
+ local_archive = "#{download_dir}/cookbooks.tgz"
10
+
11
+ cluster_config[:environments].each do |env, env_config|
12
+ chef_environment = fh_name_for(org_name, env)
13
+
14
+ nodes = search(:node, "chef_environment:#{chef_environment}")
15
+
16
+ with_chef_environment chef_environment do
17
+
18
+ nodes.each do |n|
19
+ machine_execute "Seed #{target_dir}/cookbooks" do
20
+ command "sudo tar -xvzf #{local_archive} -C #{target_dir} --keep-old-files"
21
+ live_stream false
22
+ machine n.name
23
+ action :nothing
24
+ end
25
+
26
+ machine_file local_archive do
27
+ machine n.name
28
+ local_path node[:local_cookbook_archive]
29
+ action :upload
30
+ only_if { node[:local_cookbook_archive]}
31
+ notifies :run, "machine_execute[Seed #{target_dir}/cookbooks]", :immediately
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
38
+ end
data/lib/fhcap/cli.rb CHANGED
@@ -5,6 +5,7 @@ require 'fhcap/cookbook'
5
5
  require 'fhcap/repo'
6
6
  require 'fhcap/knife'
7
7
  require 'fhcap/provider'
8
+ require 'fhcap/dns'
8
9
  require 'fhcap/misc'
9
10
  require 'fhcap/kitchen'
10
11
  require 'fhcap/version'
@@ -63,6 +64,9 @@ module Fhcap
63
64
  desc "provider COMMANDS", "Provider commands"
64
65
  subcommand "provider", Fhcap::CLI::Provider
65
66
 
67
+ desc "dns COMMANDS", "DNS commands"
68
+ subcommand "dns", Fhcap::CLI::Dns
69
+
66
70
  desc "misc COMMANDS", "Miscellaneous commands"
67
71
  subcommand "misc", Fhcap::CLI::Misc
68
72
 
data/lib/fhcap/cluster.rb CHANGED
@@ -23,7 +23,7 @@ module Fhcap
23
23
  method_option 'chef-server', :type => :string, :desc => "Chef Server to use", :enum => chef_server_names
24
24
  method_option 'provider-id', :type => :string, :desc => "Provider Id", :enum => provider_names_for('compute')
25
25
  method_option 'provider-config', :type => :hash, :desc => "Provider specific config"
26
- create_steps = %w{repo-checkout cookbook-promote server-bootstrap create dns-record}
26
+ create_steps = %w{repo-checkout cookbook-promote server-bootstrap create provision dns-record}
27
27
  create_steps.each do |step|
28
28
  method_option :"skip-#{step}", :type => :boolean, :default => false, :desc => "Skip #{step}"
29
29
  end
@@ -107,6 +107,18 @@ module Fhcap
107
107
  Tasks::Cluster::List.new(task_options(options.dup)).run
108
108
  end
109
109
 
110
+ desc "chef_provision", "[ADVANCED USAGE] Run a chef provisioning task against a particular cluster"
111
+
112
+ shared_options :verbose
113
+
114
+ method_option 'name', :type => :string, :required => true, :desc => 'Cluster name'
115
+ method_option 'run-list', :type => :array, :required => true, :desc => 'Chef Provisioning Run List i.e provision::cluster_provision'
116
+
117
+ def chef_provision
118
+ require 'fhcap/tasks/cluster/chef_provisioning_task'
119
+ Tasks::Cluster::ChefProvisioningTask.new(task_options(options.dup)).run
120
+ end
121
+
110
122
  end
111
123
  end
112
124
  end
data/lib/fhcap/config.rb CHANGED
@@ -86,6 +86,10 @@ module Fhcap
86
86
  },
87
87
  :knife_dir => File.join(default_dir, '.chef'),
88
88
  :knife => {
89
+ :local => {
90
+ :chef_server_url => 'http://127.0.0.1:7799',
91
+ :node_name => Etc.getlogin
92
+ },
89
93
  :bob => {
90
94
  :chef_server_url => 'https://bob.feedhenry.net:8443',
91
95
  :node_name => Etc.getlogin
@@ -70,6 +70,16 @@ module Fhcap
70
70
  Tasks::Chef::Cookbook::List.new(task_options(options.dup)).run
71
71
  end
72
72
 
73
+ desc "archive", "Create an archive of all cookbooks"
74
+
75
+ method_option 'git-ref', :type => :string, :desc => "fhcap git ref, can be a branch, tag or commit hash"
76
+ method_option 'git-remote', :type => :string, :desc => "git remote to use, default is the remote for the configured repos url"
77
+
78
+ def archive
79
+ require "fhcap/tasks/chef/cookbook/archive"
80
+ Tasks::Chef::Cookbook::Archive.new(task_options(options.dup)).run
81
+ end
82
+
73
83
  end
74
84
  end
75
85
  end
data/lib/fhcap/dns.rb ADDED
@@ -0,0 +1,60 @@
1
+ require 'thor'
2
+ require 'fhcap/thor_base'
3
+
4
+ module Fhcap
5
+ module CLI
6
+ class Dns < Fhcap::ThorBase
7
+
8
+ add_shared_option :verbose, :aliases => "-v", :desc => "Verbose output", :type => :boolean, :required => false, :default => false
9
+
10
+ desc "create_record", "Create a new DNS Record"
11
+ long_desc <<-LONGDESC
12
+ Create a new DNS Record or update an existing one.
13
+
14
+ Examples:
15
+
16
+ fhcap dns create_record --domain *.test.skunkhenry.com --ipaddress 192.168.33.10
17
+
18
+ fhcap dns create_record --domain *.test2.skunkhenry.com --alias-target dns_name:fh-lb-eng2-core-studio-584044547.eu-central-1.elb.amazonaws.com hosted_zone_id:Z215JYRZR1TBD5
19
+ LONGDESC
20
+
21
+ shared_options :verbose
22
+
23
+ method_option 'domain', :type => :string, :required => true, :desc => 'Domain'
24
+ method_option 'ipaddress', :type => :string, :desc => 'IP Address'
25
+ method_option 'alias-target', :type => :hash, :desc => 'Alias Target'
26
+ method_option 'ttl', :type => :numeric, :default => 300, :desc => 'Time To Live'
27
+
28
+ def create_record
29
+ require "fhcap/tasks/dns/create_record"
30
+ Tasks::Dns::CreateRecord.new(task_options(options.dup)).run
31
+ end
32
+
33
+ desc "delete_record", "Delete a DNS Record"
34
+ long_desc <<-LONGDESC
35
+ Delete a DNS Record
36
+
37
+ Examples:
38
+
39
+ fhcap dns delete_record --domain *.test.skunkhenry.com
40
+ LONGDESC
41
+
42
+ shared_options :verbose
43
+
44
+ method_option 'domain', :type => :string, :required => true, :desc => 'Domain'
45
+
46
+ def delete_record
47
+ require "fhcap/tasks/dns/delete_record"
48
+ Tasks::Dns::DeleteRecord.new(task_options(options.dup)).run
49
+ end
50
+
51
+ desc "list", "List DNS Records"
52
+
53
+ def list
54
+ require "fhcap/tasks/dns/list"
55
+ Tasks::Dns::List.new(task_options(options.dup)).run
56
+ end
57
+
58
+ end
59
+ end
60
+ end
data/lib/fhcap/misc.rb CHANGED
@@ -46,18 +46,6 @@ module Fhcap
46
46
  Tasks::Chef::Environments::Destroy.new(task_options(options.dup)).run
47
47
  end
48
48
 
49
- desc "chef_provision", "Run a chef provisioning task against a particular cluster"
50
-
51
- shared_options :verbose
52
-
53
- method_option 'name', :type => :string, :required => true, :desc => 'Cluster name'
54
- method_option 'run-list', :type => :array, :required => true, :desc => 'Chef Provisioning Run List i.e provision::cluster_provision'
55
-
56
- def chef_provision
57
- require 'fhcap/tasks/chef/provisioning/chef_provisioning_task'
58
- Tasks::Chef::Provisioning::ChefProvisioningTask.new(task_options(options.dup)).run
59
- end
60
-
61
49
  desc "create_cluster_environment", "Add an environment to a cluster"
62
50
 
63
51
  shared_options :verbose
@@ -84,18 +72,23 @@ module Fhcap
84
72
  Tasks::Cluster::DestroyEnvironment.new(task_options(options.dup)).run
85
73
  end
86
74
 
87
- desc "create_dns_record", "Create a new DNS Record"
88
-
89
- shared_options :verbose
90
-
91
- method_option 'domain', :type => :string, :required => true, :desc => 'Domain'
92
- method_option 'ipaddress', :type => :string, :desc => 'IP Address'
93
- method_option 'alias-target', :type => :hash, :desc => 'Alias Target'
94
- method_option 'ttl', :type => :numeric, :default => 300, :desc => 'Time To Live'
95
-
96
- def create_dns_record
97
- require "fhcap/tasks/misc/create_dns_record"
98
- Tasks::Misc::CreateDNSRecord.new(task_options(options.dup)).run
75
+ method_option 'log-level', :type => :string, :default => 'debug', :desc => 'Log level'
76
+ method_option 'port', :type => :string, :default => '7799', :desc => 'Server port'
77
+ method_option 'host', :type => :string, :default => '127.0.0.1', :desc => 'Server host'
78
+
79
+ desc "start_zero_server", "Zero Server"
80
+
81
+ def start_zero_server
82
+ require 'fhcap/tasks/chef/chef_zero_server'
83
+ zero_server = Fhcap::Tasks::Chef::ChefZeroServer.new(options)
84
+ thor.say "Starting chef zero server"
85
+ zero_server.zero_server.start
86
+ if zero_server.running?
87
+ thor.say "Chef Zero Server running at #{zero_server.url}"
88
+ else
89
+ thor.say "Failed to start Chef Zero Server", :red
90
+ exit(-1)
91
+ end
99
92
  end
100
93
 
101
94
  end
@@ -0,0 +1,105 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+ require 'chef'
3
+ require 'chef/knife'
4
+ require 'fhcap/tasks/chef/chef_zero_server'
5
+ require 'chef/knife/upload'
6
+ require 'chef/knife/download'
7
+ require 'chef/config'
8
+
9
+ module Fhcap
10
+ module Tasks
11
+ module Chef
12
+ class ChefServerTask < ChefTaskBase
13
+
14
+ attr_reader :chef_server, :chef_repo, :repos
15
+
16
+ def initialize(options)
17
+ super
18
+ @chef_server = options[:'chef-server']
19
+ @chef_repo = options[:'chef-repo']
20
+ @repos = options[:repos]
21
+ end
22
+
23
+ def with_chef_server(&block)
24
+ if local_chef_server?
25
+ with_local_chef_server(&block)
26
+ else
27
+ block.call
28
+ end
29
+ end
30
+
31
+ def with_local_chef_server(&block)
32
+ begin
33
+ ::Chef::Config.from_file(knife_config_file_for('local'))
34
+ uri = URI(::Chef::Config[:chef_server_url])
35
+ host = uri.hostname
36
+ port = uri.port
37
+ rescue
38
+ host = '127.0.0.1'
39
+ port = 7799
40
+ end
41
+
42
+ zero_server = Fhcap::Tasks::Chef::ChefZeroServer.new({host: host, port: port})
43
+
44
+ begin
45
+ zero_server.start_chef_zero_server
46
+ if zero_server.running?
47
+ thor.say "[Chef Zero Server] - running at #{zero_server.url}"
48
+ else
49
+ thor.say "[Chef Zero Server] - Failed to start server", :red
50
+ exit(-1)
51
+ end
52
+ rescue Errno::EADDRINUSE => e
53
+ thor.say "[Chef Zero Server] - Address in use (#{host}:#{port}), assuming this is ok"
54
+ end
55
+
56
+ local_repo = repo_dir(@chef_repo)
57
+ thor.say "[Chef Zero Server] - Syncing nodes from #{local_repo}"
58
+ knife_upload(local_repo, @chef_server, ['/nodes'])
59
+ begin
60
+ block.call
61
+ ensure
62
+ thor.say "[Chef Zero Server] - Syncing nodes to #{local_repo}"
63
+ FileUtils.rm_rf(File.join(local_repo, 'nodes'))
64
+ knife_download(local_repo, @chef_server, ['/nodes'])
65
+ end
66
+ end
67
+
68
+ def local_chef_server?
69
+ chef_server && chef_server == 'local'
70
+ end
71
+
72
+ def knife_upload(repo, server, pattern)
73
+ thor.say " * uploading local repo items from #{repo} - #{pattern} ..."
74
+ suppress_stdout(!options[:verbose]) do
75
+ Dir.chdir(repo) do
76
+ ::Chef::Knife::Upload.load_deps
77
+ knife_command = ::Chef::Knife::Upload.new(pattern)
78
+ knife_command.config[:config_file] = knife_config_file_for(server)
79
+ knife_command.config[:chef_repo_path] = repo
80
+ knife_command.configure_chef
81
+ knife_command.config[:recurse] = true
82
+ knife_command.run
83
+ end
84
+ end
85
+ end
86
+
87
+ def knife_download(repo, server, pattern)
88
+ thor.say " * downloading server items to #{repo} - #{pattern} ..."
89
+ suppress_stdout(!options[:verbose]) do
90
+ Dir.chdir(repo) do
91
+ ::Chef::Knife::Download.load_deps
92
+ knife_command = ::Chef::Knife::Download.new(pattern)
93
+ knife_command.config[:config_file] = knife_config_file_for(server)
94
+ knife_command.config[:chef_repo_path] = repo
95
+ knife_command.configure_chef
96
+ knife_command.config[:recurse] = true
97
+ knife_command.run
98
+ end
99
+ end
100
+ end
101
+
102
+ end
103
+ end
104
+ end
105
+ end
@@ -1,50 +1,12 @@
1
1
  require 'fhcap/tasks/task_base'
2
- require 'chef'
3
- require 'chef/knife'
4
2
 
5
3
  module Fhcap
6
4
  module Tasks
7
5
  module Chef
8
6
  class ChefTaskBase < TaskBase
9
7
 
10
- def select_chef_server(environment, chef_server, fail_on_missing=true)
11
- #ToDo Look at a better way of doing this rather than using a global variable
12
- $selected_chef_server = {} unless $selected_chef_server
13
- unless $selected_chef_server[environment]
14
- if chef_server
15
- $selected_chef_server[environment] = chef_server
16
- else
17
- chef_servers = chef_servers_for_environment(environment)
18
- if chef_servers.empty?
19
- exit_with_error("Unable to locate chef server for #{environment}") if fail_on_missing
20
- elsif chef_servers.length == 1
21
- $selected_chef_server[environment] = chef_servers.first
22
- else
23
- server = thor.ask("Multiple servers configured for environment '#{environment}'. Which one should be used?", {:limited_to => chef_servers})
24
- $selected_chef_server[environment] = server
25
- end
26
- end
27
- end
28
- $selected_chef_server[environment]
29
- end
30
-
31
- def chef_servers_for_environment(environment)
32
- chef_server_environments.collect do |server, environments|
33
- server.to_s if environments.include? environment
34
- end.compact
35
- end
36
-
37
- def chef_server_environments
38
- unless @chef_server_environments
39
- @chef_server_environments = {}
40
- config[:knife].each do |name, cfg|
41
- cmd = "environment list -F json"
42
- resp = run_knife_cmd(cmd, name)
43
- envs = JSON.parse(resp)
44
- @chef_server_environments[name] = envs
45
- end
46
- end
47
- @chef_server_environments
8
+ def initialize(options)
9
+ super
48
10
  end
49
11
 
50
12
  def knife_config_dir
@@ -0,0 +1,35 @@
1
+ require 'chef_zero/server'
2
+
3
+ module Fhcap
4
+ module Tasks
5
+ module Chef
6
+ class ChefZeroServer
7
+
8
+ attr_accessor :zero_server, :thread
9
+
10
+ def initialize(options={})
11
+ host = options[:host] || '127.0.0.1'
12
+ port = options[:port] || 7799
13
+ log_level = options[:'log-level'] || 'info'
14
+ @zero_server = ChefZero::Server.new(port: port, host: host, log_level: log_level)
15
+ end
16
+
17
+ def start_chef_zero_server
18
+ unless @thread
19
+ @thread = @zero_server.start_background
20
+ end
21
+ @thread
22
+ end
23
+
24
+ def running?
25
+ @zero_server.running?
26
+ end
27
+
28
+ def url
29
+ @zero_server.url
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ require 'fhcap/tasks/chef/chef_task_base'
2
+ require 'fhcap/tasks/repo/checkout'
3
+
4
+ module Fhcap
5
+ module Tasks
6
+ module Chef
7
+ module Cookbook
8
+ class Archive < ChefTaskBase
9
+
10
+ attr_reader :archive
11
+
12
+ def run
13
+ thor.say "Chef::Cookbook::Archive", :yellow
14
+ repo = 'fhcap'
15
+ Repo::Checkout.new(@options.dup.merge({:repo => repo})).run unless options[:'skip-repo-checkout']
16
+ cookbooks = get_cookbooks(options, nil, repo_cookbook_paths('cookbooks'))
17
+
18
+ archive_dir = File.join(config.tmp_dir, 'cookbooks')
19
+ @archive = File.join(config.tmp_dir, 'cookbook.tgz')
20
+
21
+ thor.remove_file @archive
22
+ thor.remove_file archive_dir
23
+ thor.empty_directory archive_dir
24
+
25
+ cookbooks.each do |name|
26
+ cookbook = cookbook_loader.cookbooks_by_name[name]
27
+ cookbook.root_paths.each do |cookbook_dir|
28
+ archive_cookbook_dir = File.join(archive_dir, name)
29
+ FileUtils.mkdir archive_cookbook_dir
30
+ FileUtils.copy_entry cookbook_dir, archive_cookbook_dir
31
+ end
32
+ end
33
+
34
+ thor.run("tar -czf #{@archive} -C #{config.tmp_dir} cookbooks")
35
+ thor.say_status 'create', @archive, :green
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end