staypuft 0.3.0 → 0.3.1

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/staypuft/nics_assignment.js +32 -0
  3. data/app/assets/javascripts/staypuft/staypuft.js +38 -0
  4. data/app/assets/javascripts/staypuft/subnets_assignment.js +40 -0
  5. data/app/assets/stylesheets/staypuft/bootstrap_and_overrides.css.scss +5 -1
  6. data/app/assets/stylesheets/staypuft/staypuft.css.scss +102 -0
  7. data/app/controllers/staypuft/deployments_controller.rb +5 -0
  8. data/app/controllers/staypuft/interface_assignments_controller.rb +76 -0
  9. data/app/controllers/staypuft/steps_controller.rb +15 -1
  10. data/app/controllers/staypuft/subnet_typings_controller.rb +42 -0
  11. data/app/helpers/staypuft/deployments_helper.rb +18 -3
  12. data/app/lib/actions/staypuft/hostgroup/deploy.rb +38 -1
  13. data/app/lib/staypuft/network_query.rb +35 -0
  14. data/app/lib/staypuft/seeder.rb +113 -39
  15. data/app/models/staypuft/concerns/host_interface_management.rb +28 -0
  16. data/app/models/staypuft/deployment.rb +35 -3
  17. data/app/models/staypuft/interface_assigner.rb +137 -0
  18. data/app/models/staypuft/layout.rb +3 -0
  19. data/app/models/staypuft/layout_subnet_type.rb +12 -0
  20. data/app/models/staypuft/role.rb +15 -0
  21. data/app/models/staypuft/subnet_type.rb +27 -0
  22. data/app/models/staypuft/subnet_typing.rb +11 -0
  23. data/app/views/staypuft/deployments/_assigned_hosts.html.erb +5 -2
  24. data/app/views/staypuft/deployments/_assigned_hosts_table.html.erb +13 -46
  25. data/app/views/staypuft/deployments/_deployed_hosts_table.html.erb +12 -33
  26. data/app/views/staypuft/deployments/_deployment_overview.html.erb +12 -9
  27. data/app/views/staypuft/deployments/_deployment_summary.html.erb +18 -0
  28. data/app/views/staypuft/deployments/_empty_hosts.html.erb +8 -0
  29. data/app/views/staypuft/deployments/_free_hosts.html.erb +1 -1
  30. data/app/views/staypuft/deployments/_free_hosts_table.html.erb +11 -34
  31. data/app/views/staypuft/deployments/_host_head_row.html.erb +11 -0
  32. data/app/views/staypuft/deployments/_host_row.html.erb +30 -0
  33. data/app/views/staypuft/deployments/_hosts_header.html.erb +7 -0
  34. data/app/views/staypuft/deployments/index.html.erb +1 -1
  35. data/app/views/staypuft/deployments/show.html.erb +2 -2
  36. data/app/views/staypuft/interface_assignments/create.js.erb +12 -0
  37. data/app/views/staypuft/interface_assignments/destroy.js.erb +12 -0
  38. data/app/views/staypuft/interface_assignments/index.html.erb +38 -0
  39. data/app/views/staypuft/interfaces/_drop_zone.html.erb +30 -0
  40. data/app/views/staypuft/steps/network_configuration.html.erb +52 -0
  41. data/app/views/staypuft/steps/services_configuration.html.erb +45 -39
  42. data/app/views/staypuft/steps/services_overview.html.erb +1 -1
  43. data/app/views/staypuft/subnet_types/_subnet_type_pull.html.erb +9 -0
  44. data/app/views/staypuft/subnet_typings/create.js.erb +12 -0
  45. data/app/views/staypuft/subnet_typings/destroy.js.erb +12 -0
  46. data/app/views/staypuft/subnet_typings/update.js.erb +14 -0
  47. data/app/views/staypuft/subnets/_drop_zone.html.erb +16 -0
  48. data/app/views/staypuft/subnets/_subnet_pull.html.erb +9 -0
  49. data/config/routes.rb +3 -0
  50. data/db/migrate/20140701074900_create_subnet_type.rb +9 -0
  51. data/db/migrate/20140701075033_create_layout_subnet.rb +10 -0
  52. data/db/migrate/20140701090256_create_staypuft_subnet_typings.rb +14 -0
  53. data/db/migrate/20140825164900_add_orchestration_to_staypuft_role.rb +5 -0
  54. data/db/migrate/20140831234000_add_required_to_subnet_types.rb +5 -0
  55. data/db/seeds.rb +1 -1
  56. data/lib/staypuft/engine.rb +11 -8
  57. data/lib/staypuft/version.rb +1 -1
  58. metadata +135 -91
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99a1f5f5c7b85101293d953b4593b62a0c5c88ef
4
- data.tar.gz: 4191b40752bd2f7d390dfe7e91aba3b526919042
3
+ metadata.gz: 21289b770a15e38194b88261c2de8622344538f5
4
+ data.tar.gz: d53a1a5ca729733020a5da1e539cd3c46f6422e9
5
5
  SHA512:
6
- metadata.gz: 99beb2ceafae6e36557f209ca737a06c999f6bca9854f3996eaa9d34846df6c4c8c7f77786fbfb66ccddf0ac2f37c0538679c8b60aba6101f304d3d29c876ebe
7
- data.tar.gz: 6363d35d9dc329d997f51c230b719da0937b50a525dfa7f2be6d6ad91ce278b0089f794b9bd1c6bfee7b5d7476d5bf9ae746de931a11ba63de73445d42942ec3
6
+ metadata.gz: 08d0914ace7e6cfeadcc1f618bba70a765a3ff02ed933ffb5272d169a8b8e96654f333dd33dc3342742f6ac862476b7be31bd9e2e82e7543264f26b26c8766de
7
+ data.tar.gz: dab396f6ac46c3ca10b0f614ed42671a88a7ecef079887ee47457b96e53e2e169fb5af26236b458a7bcace11785e98268894eebb0bac0e7482da75eaad5833e7
@@ -0,0 +1,32 @@
1
+ $(function() {
2
+ $("div.subnet-pull.active").draggable({
3
+ revert: 'invalid'
4
+ });
5
+
6
+ $("div.interface").droppable({
7
+ activeClass: "ui-state-default",
8
+ hoverClass: "ui-state-hover",
9
+ accept: "div.subnet-pull",
10
+ drop: function(event, ui) {
11
+ $.ajax({
12
+ type: 'POST',
13
+ url: ui.draggable.data('create-url'),
14
+ data: 'interface=' + $(this).data('interface'),
15
+ dataType: 'script'
16
+ });
17
+ }
18
+ });
19
+ $("#subnets").droppable({
20
+ activeClass: "ui-state-default",
21
+ hoverClass: "ui-state-hover",
22
+ accept: "div.subnet-pull.existing",
23
+ drop: function(event, ui) {
24
+ $.ajax({
25
+ type: 'DELETE',
26
+ url: ui.draggable.data('delete-url'),
27
+ data: 'interface=' + ui.draggable.closest('div.interface').data('interface'),
28
+ dataType: 'script'
29
+ });
30
+ }
31
+ });
32
+ });
@@ -11,6 +11,8 @@
11
11
  // GO AFTER THE REQUIRES BELOW.
12
12
  //
13
13
  //= require_tree .
14
+ //= require jquery.ui.draggable
15
+ //= require jquery.ui.droppable
14
16
 
15
17
  $(function () {
16
18
  // Check all checkboxes in table
@@ -48,6 +50,22 @@ $(function () {
48
50
  $(this).siblings('.hidden_password, .shown_password').toggleClass('hide');
49
51
  });
50
52
 
53
+ $('#ceph_notification_dismissal').click(function(e) {
54
+ e.preventDefault();
55
+ $('.ceph_notification').toggleClass('hide');
56
+ var pathname = window.location.pathname
57
+ var id = pathname.substring(pathname.lastIndexOf('/') + 1)
58
+ var cephDeploymentNotification = readFromCookie();
59
+ cephDeploymentNotification[id] = true
60
+ $.cookie('ceph-deployment-notification', JSON.stringify(cephDeploymentNotification))
61
+ });
62
+ function readFromCookie() {
63
+ if (r = $.cookie('ceph-deployment-notification'))
64
+ return $.parseJSON(r);
65
+ else
66
+ return {};
67
+ }
68
+
51
69
  var duration = 150;
52
70
 
53
71
  showPasswords();
@@ -127,6 +145,18 @@ $(function () {
127
145
  }
128
146
  }
129
147
 
148
+ showCephNotification();
149
+ function showCephNotification() {
150
+ var cephDeploymentNotification = readFromCookie();
151
+ var pathname = window.location.pathname;
152
+ var id = pathname.substring(pathname.lastIndexOf('/') + 1);
153
+ if (cephDeploymentNotification !== null && cephDeploymentNotification !== undefined) {
154
+ if (cephDeploymentNotification[id]) {
155
+ $('.ceph_notification').addClass('hide');
156
+ }
157
+ }
158
+ }
159
+
130
160
  if ($('.configuration').length > 0) {
131
161
  $('.configuration').find('li').first().find('a')[0].click();
132
162
  }
@@ -186,6 +216,13 @@ $(function () {
186
216
  $(window).scrollTop( 0 );
187
217
  }
188
218
 
219
+ $('.dynamic-submit').click(function() {
220
+ this.form.action = $(this).data('submit-to');
221
+ this.form.method = $(this).data('method');
222
+ this.form.submit();
223
+ return false;
224
+ })
225
+
189
226
  var free_host_checkboxes = $('#free-hosts table input:checkbox');
190
227
  free_host_checkboxes.click(function(){
191
228
  $("#assign_hosts_modal").attr("disabled", !free_host_checkboxes.is(":checked"));
@@ -194,6 +231,7 @@ $(function () {
194
231
  var assigned_host_checkboxes = $('#assigned-hosts table input:checkbox');
195
232
  assigned_host_checkboxes.click(function(){
196
233
  $("#unassign_hosts_button").attr("disabled", !assigned_host_checkboxes.is(":checked"));
234
+ $("#configure_networks_button").attr("disabled", !assigned_host_checkboxes.is(":checked"));
197
235
  });
198
236
 
199
237
  var deployed_host_checkboxes = $('#deployed-hosts table input:checkbox');
@@ -0,0 +1,40 @@
1
+ $(function() {
2
+ $("div.subnet-type-pull").draggable({
3
+ revert: 'invalid'
4
+ });
5
+
6
+ $("div.subnet-drop-zone").droppable({
7
+ activeClass: "ui-state-default",
8
+ hoverClass: "ui-state-hover",
9
+ accept: "div.subnet-type-pull",
10
+ drop: function(event, ui) {
11
+ if(ui.draggable.hasClass('new')) {
12
+ $.ajax({
13
+ type: 'POST',
14
+ url: ui.draggable.data('create-url'),
15
+ data: 'subnet_type_id=' + ui.draggable.data('subnet-type-id') + '&subnet_id=' + $(this).data('subnet-id'),
16
+ dataType: 'script'
17
+ })
18
+ } else {
19
+ $.ajax({
20
+ type: 'PUT',
21
+ url: ui.draggable.data('update-url'),
22
+ data: 'subnet_id=' + $(this).data('subnet-id'),
23
+ dataType: 'script'
24
+ })
25
+ }
26
+ }
27
+ });
28
+ $("#subnet_types").droppable({
29
+ activeClass: "ui-state-default",
30
+ hoverClass: "ui-state-hover",
31
+ accept: "div.subnet-type-pull.existing",
32
+ drop: function(event, ui) {
33
+ $.ajax({
34
+ type: 'DELETE',
35
+ url: ui.draggable.data('delete-url'),
36
+ dataType: 'script'
37
+ });
38
+ }
39
+ });
40
+ });
@@ -46,6 +46,10 @@
46
46
  padding: 19px 36px;
47
47
  background-color: #f5f5f5;
48
48
  @include center-block;
49
+
50
+ table tbody td {
51
+ background-color: #fff;
52
+ }
49
53
  }
50
54
 
51
55
  .tabbed_side_nav_form{
@@ -80,7 +84,7 @@
80
84
  }
81
85
 
82
86
  .wizard {
83
- width: 675px;
87
+ width: 900px;
84
88
  display: block;
85
89
  @include center-block;
86
90
  }
@@ -101,6 +101,18 @@ span.editable, span.editable:hover {
101
101
  overflow: auto;
102
102
  }
103
103
 
104
+
105
+ .nav > li > a.roles_list {
106
+ padding: 0;
107
+ border: 1px solid #ddd;
108
+ & > div {
109
+ padding: 10px;
110
+ &:not(:first-child) {
111
+ border-left: 1px solid #ddd;
112
+ }
113
+ }
114
+ }
115
+
104
116
  .association.well {
105
117
  min-height: 500px;
106
118
  margin-top: 50px;
@@ -111,3 +123,93 @@ span.editable, span.editable:hover {
111
123
  }
112
124
  }
113
125
  }
126
+
127
+ $pull_line_height: 40px;
128
+ .subnet-type-pull, .empty-zone {
129
+ height: $pull_line_height;
130
+ line-height: $pull_line_height;
131
+ }
132
+
133
+ .subnet-type-pull, .subnet-pull, .empty-zone {
134
+ float: left;
135
+ min-width: 100px;
136
+ text-align: center;
137
+ margin-left: 10px;
138
+ background-color: #f5f5f5;
139
+ border-color: #000;
140
+ border-width: 1px;
141
+ }
142
+
143
+ .subnet-type-pull, .subnet-pull {
144
+ z-index: 1;
145
+ border-style: solid;
146
+ background-color: #ffffff;
147
+ }
148
+
149
+ .subnet-type-pull, .subnet-pull.active {
150
+ cursor: pointer;
151
+ background-color: #f5f5f5;
152
+ }
153
+
154
+ .subnet-pull {
155
+ height: $pull_line_height;
156
+ display: table;
157
+ padding-left: 5px;
158
+ padding-right: 5px;
159
+ margin-top: 10px;
160
+
161
+ .name {
162
+ font-weight: bold;
163
+ }
164
+
165
+ .content {
166
+ display: table-cell;
167
+ vertical-align: middle;
168
+ }
169
+ }
170
+
171
+ .subnet-pull.virtual {
172
+ background-color: #d7f5f5;
173
+ }
174
+
175
+ div.cleared {
176
+ clear: left;
177
+ }
178
+
179
+ .empty-zone {
180
+ border-style: dashed;
181
+ }
182
+
183
+ .subnet-drop-zone {
184
+ border: 1px solid black;
185
+ height: 90px;
186
+ margin-bottom: 10px;
187
+
188
+ .name {
189
+ margin-left: 5px;
190
+ margin-top: 5px;
191
+ margin-bottom: 10px;
192
+ font-weight: bold;
193
+ }
194
+ }
195
+
196
+ div.interface {
197
+ margin-bottom: 10px;
198
+
199
+ div.identifier {
200
+ float: left;
201
+ width: 70px;
202
+ border: 1px solid #000;
203
+ height: $pull_line_height + 20px;
204
+ line-height: $pull_line_height + 20px;
205
+ text-align: center;
206
+ font-weight: bold;
207
+ }
208
+
209
+ div.subnet-drop-zones {
210
+ border: 1px solid #000;
211
+ padding-top: 10px;
212
+ width: 100%;
213
+ height: $pull_line_height + 20px;
214
+ }
215
+ }
@@ -190,6 +190,11 @@ module Staypuft
190
190
  # root_pass is not copied for some reason
191
191
  host.root_pass = hostgroup.root_pass
192
192
 
193
+ # clear all virtual devices that may have been created during previous assignment
194
+ host.clean_vlan_interfaces
195
+ # by default foreman will try to manage all NICs unless user disables manually after assignment
196
+ host.make_all_interfaces_managed
197
+
193
198
  # I do not why but the final save! adds following condytion to the update SQL command
194
199
  # "WHERE "hosts"."type" IN ('Host::Managed') AND "hosts"."id" = 283"
195
200
  # which will not find the record since it's still Host::Discovered.
@@ -0,0 +1,76 @@
1
+ module Staypuft
2
+ class InterfaceAssignmentsController < Staypuft::ApplicationController
3
+ def index
4
+ @deployment = Deployment.find(params[:deployment_id])
5
+ @hosts = Host::Managed.where(:id => params[:host_ids]).includes(:interfaces)
6
+ @subnets = @deployment.subnets.uniq
7
+ @host = @hosts.first
8
+ @interfaces = @host ? @host.interfaces.where("type <> 'Nic::BMC'").order(:identifier).physical : []
9
+
10
+ errors = {}
11
+ @hosts.each do |host|
12
+ host_errors = compare(host, @host)
13
+ errors[host.name] = host_errors.join(' and ') if host_errors.present?
14
+ end
15
+
16
+ if errors.present?
17
+ flash[:error] = errors.map{ |k, v| "#{k}: #{v}" }.join('<br />')
18
+ redirect_to deployment_path(@deployment)
19
+ end
20
+ end
21
+
22
+ def create
23
+ @errors = {}
24
+ @deployment = Deployment.find(params[:deployment_id])
25
+ @hosts = Host::Managed.where(:id => params[:host_ids])
26
+ @hosts.each do |host|
27
+ @interface = host.interfaces.find_by_identifier(params[:interface]) || host
28
+ @subnet = Subnet.find(params[:subnet_id])
29
+ @assigner = InterfaceAssigner.new(@deployment, @interface, @subnet)
30
+ @assigner.assign
31
+ @errors[host.name] = @assigner.errors if @assigner.errors.present?
32
+ end
33
+ @saved = @errors.blank?
34
+ end
35
+
36
+ def destroy
37
+ @errors = {}
38
+ @deployment = Deployment.find(params[:deployment_id])
39
+ @hosts = Host::Managed.where(:id => params[:host_ids])
40
+ @hosts.each do |host|
41
+ @interface = host.interfaces.find_by_identifier(params[:interface]) || host
42
+ @subnet = Subnet.find(params[:subnet_id])
43
+ @assigner = InterfaceAssigner.new(@deployment, @interface, @subnet)
44
+ @assigner.unassign
45
+ @errors[host.name] = @assigner.errors if @assigner.errors.present?
46
+ end
47
+ @destroyed = @errors.blank?
48
+ end
49
+
50
+ private
51
+
52
+ def compare(comparing, original)
53
+ errors = []
54
+ # primary interfaces, we don't check subnet_id since it's always PXE subnet
55
+ if comparing.primary_interface != original.primary_interface
56
+ errors.push _('does not have interfaces with same names')
57
+ return errors
58
+ end
59
+
60
+ # other interfaces
61
+ comparing = get_interfaces_to_compare(comparing)
62
+ original = get_interfaces_to_compare(original)
63
+ errors.push _('does not have same amount of interfaces') and return errors if comparing.size != original.size
64
+ comparing.each do |interface|
65
+ original_interface = original.select { |i| i.identifier == interface.identifier }.first
66
+ errors.push _('does not have interfaces with same names') and return errors if original_interface.nil?
67
+ errors.push _('has different subnet assignment on interface %s') % interface.identifier if interface.subnet_id != original_interface.subnet_id
68
+ end
69
+ errors
70
+ end
71
+
72
+ def get_interfaces_to_compare(host)
73
+ host.interfaces.where("type <> 'Nic::BMC'").order(:identifier)
74
+ end
75
+ end
76
+ end
@@ -1,7 +1,7 @@
1
1
  module Staypuft
2
2
  class StepsController < Staypuft::ApplicationController
3
3
  include Wicked::Wizard
4
- steps :deployment_settings, :services_overview, :services_configuration
4
+ steps :deployment_settings, :network_configuration, :services_overview, :services_configuration
5
5
 
6
6
  before_filter :get_deployment
7
7
 
@@ -13,6 +13,8 @@ module Staypuft
13
13
  if !@deployment.ha? && @deployment.cinder.lvm_ptable.nil?
14
14
  flash[:warning] = "Missing Partition Table 'LVM with cinder-volumes', LVM cinder backend won't work."
15
15
  end
16
+ when :network_configuration
17
+ @subnets = Subnet.search_for(params[:search], :order => params[:order]).includes(:domains, :dhcp).paginate :page => params[:page]
16
18
  when :services_configuration
17
19
  @services_map = [:nova, :neutron, :glance, :cinder]
18
20
  end
@@ -30,6 +32,15 @@ module Staypuft
30
32
  @deployment.passwords.attributes = params[:staypuft_deployment].delete(:passwords)
31
33
  @deployment.attributes = params[:staypuft_deployment]
32
34
 
35
+ # we don't care too much whether pxe network was detected or all typings were saved since it's
36
+ # just a helper for user to have all types preassigned to pxe network
37
+ pxe_network = Subnet.where('dhcp_id IS NOT NULL').first
38
+ if pxe_network
39
+ @deployment.unassigned_subnet_types.each do |type|
40
+ @deployment.subnet_typings.new(:subnet_id => pxe_network.id, :subnet_type_id => type.id).save
41
+ end
42
+ end
43
+
33
44
  when :services_overview
34
45
  @deployment.form_step = Deployment::STEP_OVERVIEW
35
46
 
@@ -41,6 +52,9 @@ module Staypuft
41
52
  @deployment.send(service).attributes = params[:staypuft_deployment].delete(service)
42
53
  end
43
54
  end
55
+ when :network_configuration
56
+ @deployment.form_step = Deployment::STEP_NETWORKING
57
+ @subnets = Subnet.search_for(params[:search], :order => params[:order]).includes(:domains, :dhcp).paginate :page => params[:page]
44
58
  else
45
59
  raise 'unknown step'
46
60
  end
@@ -0,0 +1,42 @@
1
+ module Staypuft
2
+ class SubnetTypingsController < ActionController::Base
3
+ def create
4
+ @deployment = Deployment.find(params[:deployment_id])
5
+ @subnet_type = SubnetType.find(params[:subnet_type_id])
6
+ @subnet = Subnet.find(params[:subnet_id])
7
+ check_for_existing_assignments
8
+ @subnet_typing = @deployment.subnet_typings.new(:subnet_id => @subnet.id, :subnet_type_id => @subnet_type.id)
9
+ @saved = @subnet_typing.save
10
+ end
11
+
12
+ def update
13
+ @subnet_typing = SubnetTyping.find(params[:id])
14
+ @deployment = @subnet_typing.deployment
15
+ @subnet_type = @subnet_typing.subnet_type
16
+ @subnet = Subnet.find(params[:subnet_id])
17
+ check_for_existing_assignments
18
+ @subnet_typing.subnet = @subnet
19
+ @saved = @subnet_typing.save
20
+ end
21
+
22
+ def destroy
23
+ @subnet_typing = SubnetTyping.find(params[:id])
24
+ @deployment = @subnet_typing.deployment
25
+ @subnet = @subnet_typing.subnet
26
+ check_for_existing_assignments
27
+ @subnet_type = @subnet_typing.subnet_type
28
+ @destroyed = @subnet_typing.destroy
29
+ end
30
+
31
+ private
32
+
33
+ def check_for_existing_assignments
34
+ existing = @deployment.hosts.includes(:interfaces).any? do |h|
35
+ h.subnet_id == @subnet.id || h.interfaces.any? { |i| i.subnet_id == @subnet.id }
36
+ end
37
+ if existing
38
+ @warn = _('Some hosts interfaces were already assigned to this subnet, check interface assignment before deploying!')
39
+ end
40
+ end
41
+ end
42
+ end
@@ -4,6 +4,7 @@ module Staypuft
4
4
  wizard_header(
5
5
  step,
6
6
  _("Deployment Settings"),
7
+ _("Network Configuration"),
7
8
  _("Services Overview"),
8
9
  _("Services Configuration")
9
10
  )
@@ -33,9 +34,7 @@ module Staypuft
33
34
  style ="label-default"
34
35
  short = s_("Discovered|D")
35
36
  label = _('Discovered Host')
36
- # TODO remove after migrating to foreman_discover 1.3.0
37
- hash_for_method = [:hash_for_discovered_host_path, :hash_for_discover_path].find { |m| respond_to? m }
38
- path = send hash_for_method, host
37
+ path = hash_for_discovered_host_path(host)
39
38
  else
40
39
  style = 'label-warning'
41
40
  short = s_("Error|E")
@@ -48,6 +47,22 @@ module Staypuft
48
47
  :class => "label label-light " + style,
49
48
  :"data-original-title" => _(label) }) + link_to(trunc(" #{host}", 32), path)
50
49
  end
50
+
51
+ def host_nics(host)
52
+ host.interfaces_identifiers.compact.sort.join(tag(:br)).html_safe
53
+ end
54
+
55
+ def is_pxe?(deployment, subnet)
56
+ subnet_typings(deployment, subnet).any? { |t| t.subnet_type.name == Staypuft::SubnetType::PXE }
57
+ end
58
+
59
+ def subnet_types(deployment, subnet)
60
+ subnet_typings(deployment, subnet).map { |t| h(t.subnet_type.name) }.join(' + ')
61
+ end
62
+
63
+ def subnet_typings(deployment, subnet)
64
+ deployment.subnet_typings.where(:subnet_id => subnet.id).includes(:subnet_type)
65
+ end
51
66
  end
52
67
 
53
68
  end
@@ -26,12 +26,49 @@ module Actions
26
26
  # hostgroup.hosts returns already converted hosts from Host::Discovered with build flag
27
27
  # set to false so they are not built when assigned to the hostgroup in wizard
28
28
  # run Hostgroup's Hosts filtered by hosts
29
- (hostgroup.hosts & hosts).each do |host|
29
+ host_list = hostgroup.hosts & hosts
30
+ orchestration_mode = hostgroup.role.orchestration unless hostgroup.role.nil?
31
+
32
+ case orchestration_mode
33
+ when ::Staypuft::Role::ORCHESTRATION_CONCURRENT
34
+ deploy_concurrently(host_list)
35
+ when ::Staypuft::Role::ORCHESTRATION_SERIAL
36
+ deploy_serially(host_list)
37
+ when ::Staypuft::Role::ORCHESTRATION_LEADER
38
+ deploy_leader_first(host_list)
39
+ else
40
+ deploy_concurrently(host_list)
41
+ end
42
+ end
43
+
44
+ def deploy_concurrently(hosts)
45
+ hosts.each do |host|
30
46
  # planned in concurrence
31
47
  plan_action Host::Deploy, host
32
48
  end
33
49
  end
34
50
 
51
+ def deploy_serially(hosts)
52
+ sequence do
53
+ hosts.each do |host|
54
+ plan_action Host::Deploy, host
55
+ end
56
+ end
57
+ end
58
+
59
+ def deploy_leader_first(hosts)
60
+ first_host = hosts.shift
61
+ sequence do
62
+ #deploy first host, then deploy remainder in parallel
63
+ plan_action Host::Deploy, first_host unless first_host.nil?
64
+ concurrence do
65
+ hosts.each do |host|
66
+ plan_action Host::Deploy, host
67
+ end
68
+ end
69
+ end
70
+ end
71
+
35
72
  def humanized_input
36
73
  input[:name]
37
74
  end
@@ -0,0 +1,35 @@
1
+ module Staypuft
2
+ class NetworkQuery
3
+
4
+ def initialize(deployment)
5
+ @deployment = deployment
6
+ end
7
+
8
+ private
9
+ def interface_hash_for_host(host, subnet_type_name)
10
+ subnet_type = @deployment.layout.subnet_types.where(:name=> subnet_type_name).first
11
+
12
+ # raise error if no subnet with this name is assigned to this layout
13
+ if subnet_type.nil?
14
+ raise ArgumentError, "Invalid subnet type '#{subnet_type_name}' for layout of this deployment #{@deployment.name}"
15
+ end
16
+
17
+ subnet_typing = @deployment.subnet_typings.where(:subnet_type_id => subnet_type.id).first
18
+ # if this subnet type isn't assigned to a subnet for this deployment, return nil
19
+ return nil if subnet_typing.nil?
20
+ subnet = subnet_typing.subnet
21
+
22
+ secondary_iface = host.interfaces.where(:subnet_id => subnet.id).first
23
+ # check for primary interface
24
+ if (host.subnet_id == subnet.id)
25
+ {:subnet => host.subnet, :ip => host.ip,
26
+ :interface => host.primary_interface, :mac => host.mac }
27
+ elsif !iface.nil?
28
+ {:subnet => secondary_iface.subnet, :ip => secondary_iface.ip,
29
+ :interface => secondary_iface.name, :mac => secondary_iface.mac }
30
+ else
31
+ nil
32
+ end
33
+ end
34
+ end
35
+ end