staypuft 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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