dewiring 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NzZlOTQxOTc2YzIyMmExOWQ1OGJmZmRmYzQ4MDRlMWJiMTZkMmI0Yg==
4
+ MWI3MDA5Yzc1ZGNhY2JlNzJiYjQyMTJjMmQwNTJiNWU5Njc0NzhmNw==
5
5
  data.tar.gz: !binary |-
6
- OGRjNWIyNWNlYjFkMGFkOTM1OTRkYWI4YWY0NTRlY2I4YWFiYTgwMg==
6
+ NDIxM2Y4Mzc2NDM4NzYwMzQ4MzJmYzFiMzYzOTBlMjJjMDY1NWEyNw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZjNmNzNhNDUzYTU2YzBkNmFmYWEyMWQ5Y2I2Mzk3ZDJjZjA3MmUxNGE5ODFm
10
- OGEwYjk3N2I1NDQ4MDgyYzNmZDJkODVhZWNlYjA5MDE3M2JhMDBiMzQyMGQ3
11
- MWRiODg2NGQ1MzRlNTFjNzQ3MWQ2YWM0MDI4Y2NjODJhNzVmOTQ=
9
+ NDY5OGNmMzIxNjJmZTUwM2I5NTZhZjVkNzM2NjZmNzg5YTAyMTk4OTJkMjZk
10
+ M2FhYzNmODI4YWM5ZjE4NzU4MDk0OGY5MjI5N2MwMmZkNWU0ZWNhNWU3OTM5
11
+ ZThmNDQ3ZDYzMDhlMWI4N2MwY2YzZjFiNzI4Mzc2ZTRiNTllNmM=
12
12
  data.tar.gz: !binary |-
13
- MjNiNjllYTJiZjU2YWJmNGZiOGJmMDEyMTBiYjNmNzUxOTJlZTQwMmJkZDkx
14
- ZDUzYmI5ZjJlMTM1OTBjM2RhYTdhYjdjZGVlMDhlZTY2ODhlMDA0YTI0ZGMz
15
- NDhjN2IxODMxOWUwMmI5ZTIzZTExM2UyMjU0MjgwMTBjYmEwNjU=
13
+ ZGYxNDY4Yzg1MTM3NDZhZjIyMzJhMThmOTUxMWE4Zjc0YzMzYTQyY2NkNWI4
14
+ ZGFhMWQ4YzNkN2E4ZDdiYjIxZmNhYmQyZDg2NTk5MmExMjEwOTU3YzVjM2Vh
15
+ NjE1ZTUwMTA3MTliYzlkZjdjNTYwNjg2OTU1YjdkYWQxMGMzZjc=
@@ -23,9 +23,9 @@ function usage() {
23
23
  echo ' -n/--noop only print commands, do not change'
24
24
  echo ' -d/--debug show debug output'
25
25
  echo ' -q/--quiet be quiet'
26
- # echo ' -s/--state <FILE> write state to <FILE>' # TODO
26
+ echo ' -s/--state <FILE> write state to <FILE>'
27
27
  echo ' Examples:'
28
- echo ' attach-containers.sh attach --debug -- eth1:br1 eth2:br2 02978729 12673482'
28
+ echo ' attach-containers.sh attach --debug -- eth1:br1:NODHCP eth2:br2 02978729 12673482'
29
29
  echo ' attach-containers.sh verify -- eth1:br1 eth2:br2 02978729 12673482'
30
30
  echo ' attach-containers.sh detach -q -- eth1:br1 eth2:br2 02978729 12673482'
31
31
  }
@@ -64,6 +64,7 @@ MODE=
64
64
  ACTION=
65
65
  DEBUG=nodebug
66
66
  QUIET=
67
+ STATEFILE=
67
68
 
68
69
  while :
69
70
  do
@@ -80,6 +81,11 @@ do
80
81
  NOOP=1
81
82
  shift
82
83
  ;;
84
+ -s | --state)
85
+ shift
86
+ STATEFILE=$1
87
+ shift
88
+ ;;
83
89
  -d | --debug)
84
90
  DEBUG=debug
85
91
  shift
@@ -124,6 +130,12 @@ if [[ -z "$ID_ARR" ]]; then
124
130
  exit 3
125
131
  fi
126
132
 
133
+ # empty state file
134
+ if [[ ! -z "$STATEFILE" ]]; then
135
+ echo "# This is a wire network state file" >"$STATEFILE"
136
+ echo "TIMESTAMP=`date`" >>"$STATEFILE"
137
+ fi
138
+
127
139
  [[ "$NOOP" -eq 1 ]] && MODE='echo NOOP% '
128
140
 
129
141
  # DEBUG
@@ -136,12 +148,25 @@ OVS_VSCTL=$(which ovs-vsctl)
136
148
  DOCKER=$(which docker)
137
149
  DHCLIENT=$(which dhclient)
138
150
 
151
+ # -- FUNCTION ----------------------------------------------------------------
152
+ # Name: add_to_state
153
+ # Description: Adds given text line to state file. If STATEFILE is empty,
154
+ # nothing is done
155
+ # Parameters
156
+ # 1: state info line
157
+ # ----------------------------------------------------------------------------
158
+ function add_to_state() {
159
+ if [[ ! -z "$STATEFILE" ]]; then
160
+ echo $* >>"$STATEFILE"
161
+ fi
162
+ }
163
+
139
164
  # -- FUNCTION ----------------------------------------------------------------
140
165
  # Name: container_process
141
166
  # Description: Given ID of container, this returns the Process id
142
167
  # Parameters
143
168
  # 1: Docker Container ID
144
- # Returns : Container Process ID
169
+ # Returns : Container Process ID
145
170
  # ----------------------------------------------------------------------------
146
171
  function container_process() {
147
172
  T="$1"
@@ -170,7 +195,11 @@ function link_netns() {
170
195
  # ----------------------------------------------------------------------------
171
196
  function unlink_netns() {
172
197
  local PID=$1
173
- $MODE sudo rm /var/run/netns/$PID
198
+ if [[ -z $PID ]]; then
199
+ log_error unlink_netns: pid not specified
200
+ else
201
+ $MODE sudo rm "/var/run/netns/$PID"
202
+ fi
174
203
  }
175
204
 
176
205
  # -- FUNCTION ----------------------------------------------------------------
@@ -292,11 +321,11 @@ function has_interfaces() {
292
321
  if [[ $? -ne 0 ]]; then
293
322
  return 1
294
323
  fi
295
- # check if we have an ip
296
- $MODE sudo $IP netns exec $NS $IP addr show $DEVICE 2>&1 | grep 'inet ' >/dev/null 2>&1
297
- if [[ $? -ne 0 ]]; then
298
- return 1
299
- fi
324
+ # check if we have an ip (todo: fix in NODHCP mode)
325
+ #$MODE sudo $IP netns exec $NS $IP addr show $DEVICE 2>&1 | grep 'inet ' >/dev/null 2>&1
326
+ #if [[ $? -ne 0 ]]; then
327
+ # return 1
328
+ #fi
300
329
 
301
330
  # host devices
302
331
  $MODE sudo $IP link show $HOST_IF >/dev/null 2>&1
@@ -376,8 +405,9 @@ function handle_verify() {
376
405
  # on host and in container
377
406
 
378
407
  $DEBUG - Checking devices in $ID
379
- link_netns "${PID}"
380
-
408
+ link_netns "${PID}"
409
+ add_to_state ${ID}.CONTAINER_PID=${TARGET_PID}
410
+
381
411
  # iterate given devices
382
412
  for DEVICE_PAIR in $DEVICE_ARR; do
383
413
  INTF=$(echo "$DEVICE_PAIR" | awk -F':' '{ print $1 }' )
@@ -419,11 +449,13 @@ function handle_attach() {
419
449
  $DEBUG PID of $TARGET is $TARGET_PID
420
450
 
421
451
  link_netns "${TARGET_PID}"
422
-
452
+ add_to_state ${TARGET}.CONTAINER_PID=${TARGET_PID}
453
+
423
454
  # iterate given devices
424
455
  for DEVICE_PAIR in $DEVICE_ARR; do
425
456
  INTF=$(echo $DEVICE_PAIR | awk -F':' '{ print $1 }' )
426
457
  BRIDGE=$(echo $DEVICE_PAIR | awk -F':' '{ print $2 }' )
458
+ FLAGS=$(echo $DEVICE_PAIR | awk -F':' '{ print $3 }' )
427
459
  $DEBUG Attaching $INTF to $BRIDGE
428
460
 
429
461
  BRIDGEDEV_MTU=$(get_mtu $BRIDGE)
@@ -432,6 +464,7 @@ function handle_attach() {
432
464
  RES=1
433
465
  break
434
466
  fi
467
+ add_to_state ${TARGET}.BRIDGEDEV_MTU=${BRIDGEDEV_MTU}
435
468
 
436
469
  HOST_IFNAME=v${INTF}h${TARGET_PID}
437
470
  CONTAINER_IFNAME=v${INTF}c${TARGET_PID}
@@ -444,7 +477,10 @@ function handle_attach() {
444
477
  RES=1
445
478
  continue
446
479
  fi
447
-
480
+
481
+ add_to_state ${TARGET}.HOST_IFNAME=${HOST_IFNAME}
482
+ add_to_state ${TARGET}.CONTAINER_IFNAME=${CONTAINER_IFNAME}
483
+
448
484
  $DEBUG - adding $HOST_IFNAME to $BRIDGE
449
485
  add_device_to_switch "$HOST_IFNAME" "$BRIDGE"
450
486
  if [[ $? -ne 0 ]]; then
@@ -452,25 +488,35 @@ function handle_attach() {
452
488
  RES=1
453
489
  continue
454
490
  fi
455
-
491
+ add_to_state ${TARGET}.ON_BRIDGE=$BRIDGE
492
+
456
493
  $DEBUG - configuring interfaces
457
494
  configure_interfaces "$HOST_IFNAME" "$CONTAINER_IFNAME" "$TARGET_PID" "$INTF"
458
495
  if [[ $? -ne 0 ]]; then
459
496
  log_error configuring interfaces. aborting
460
497
  RES=1
461
- continue
462
- fi
463
-
464
- $DEBUG - dhcp requesting address
465
- dhcp_container "$TARGET_PID" "$INTF"
466
- if [[ $? -ne 0 ]]; then
467
- log_error running dhcp. aborting
468
- RES=1
469
- continue
498
+ add_to_state ${CONTAINER_IFNAME}.configured=error
499
+ continue
470
500
  fi
471
- done
501
+ add_to_state ${TARGET}.${CONTAINER_IFNAME}.configured=ok
472
502
 
473
- unlink_netns "$TARGET_PID"
503
+ if [[ "$FLAGS" =~ NODHCP ]]; then
504
+ $DEBUG - skipping dhcp for $INTF
505
+ else
506
+ $DEBUG - dhcp requesting address
507
+ dhcp_container "$TARGET_PID" "$INTF"
508
+ if [[ $? -ne 0 ]]; then
509
+ log_error running dhcp. aborting
510
+ add_to_state ${CONTAINER_IFNAME}.dhcp=error
511
+ RES=1
512
+ continue
513
+ fi
514
+ add_to_state ${TARGET}.${CONTAINER_IFNAME}.dhcp=ok
515
+
516
+ fi
517
+
518
+ done
519
+ unlink_netns "$TARGET_PID"
474
520
  done
475
521
 
476
522
  return $RES
@@ -490,10 +536,10 @@ function handle_detach() {
490
536
  $DEBUG Detaching $TARGET
491
537
 
492
538
  TARGET_PID=$(container_process $TARGET)
493
- $DEBUG PID of $TARGET is $TARGET_PID
494
-
495
- link_netns ${TARGET_PID}
539
+ $DEBUG PID of $TARGET is $TARGET_PID
496
540
 
541
+ link_netns ${TARGET_PID}
542
+
497
543
  # iterate given devices
498
544
  for DEVICE_PAIR in $DEVICE_ARR; do
499
545
  INTF=$(echo $DEVICE_PAIR | awk -F':' '{ print $1 }' )
@@ -113,6 +113,37 @@ module Wire
113
113
  end
114
114
  end
115
115
 
116
+ # brings given +resource+ up by first asking if its up?.
117
+ # If not, call up. Writes states, outputs state
118
+ # Params:
119
+ # ++resource++: Resource object, i.e. BridgeResource
120
+ # ++resource_type++: Resource type symbol, i.e. :bridge
121
+ # ++resource_desc_str++: Description to dump out
122
+ # ++action++: one of :up, :down
123
+ def default_handle_resource(resource, resource_type, resource_desc_str, action)
124
+ question = "#{action}?".to_sym
125
+ output_method = action.to_s.upcase
126
+
127
+ b_ok = false
128
+
129
+ if resource.send(question)
130
+ outputs output_method, "#{resource_desc_str} is already #{action}.", :ok2
131
+ b_ok = true
132
+ else
133
+ resource.send(action)
134
+
135
+ if resource.send(question)
136
+ outputs output_method, "#{resource_desc_str} is #{action}.", :ok
137
+ b_ok = true
138
+ else
139
+ outputs output_method, "#{resource_desc_str} could not be brought #{action}.", :err
140
+ end
141
+ end
142
+
143
+ state.update(resource_type, resource.name, action) if b_ok
144
+ b_ok
145
+ end
146
+
116
147
  private
117
148
 
118
149
  # Save state to state file
@@ -122,18 +153,15 @@ module Wire
122
153
  state.save
123
154
  rescue => save_exception
124
155
  $stderr.puts "Error saving state, #{save_exception}"
125
- $log.debug? && puts(save_exception.inspect)
126
- $log.debug? && puts(save_exception.backtrace)
127
156
  end
128
157
 
158
+ # Load state from state file
129
159
  def handle_state_load
130
160
  state.load
131
161
  # dump state
132
162
  $log.debug? && dump_state
133
163
  rescue => load_exception
134
164
  $stderr.puts "Error loading state, #{load_exception}"
135
- $log.debug? && puts(load_exception.inspect)
136
- $log.debug? && puts(load_exception.backtrace)
137
165
  end
138
166
  end
139
167
  end
@@ -38,6 +38,7 @@ module Wire
38
38
  success = handler.handle_network_attachments(zone_name, zone_networks,
39
39
  appgroup_name, appgroup_data,
40
40
  @project.target_dir)
41
+
41
42
  b_result &= success
42
43
 
43
44
  # then take down containers
@@ -7,32 +7,19 @@
7
7
  # Wire module
8
8
  module Wire
9
9
  # implements handle_xxx methods for DownCommand
10
+ # delegates to BaseCommand.default_handle_resource for most parts
10
11
  # rubocop:disable ClassLength
11
12
  class DownCommandHandler < BaseCommand
12
13
  # take bridge down
13
14
  def handle_bridge(bridge_name)
14
15
  bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
15
- if bridge_resource.down?
16
- outputs 'DOWN', "Bridge #{bridge_name} already down.", :ok2
17
- return true
18
- end
19
-
20
- bridge_resource.down
21
- if bridge_resource.down?
22
- outputs 'DOWN', "Bridge #{bridge_name} down/removed.", :ok
23
- state.update(:bridge, bridge_name, :down)
24
- else
25
- outputs 'DOWN', "Error bringing down bridge #{bridge_name}.", :err
26
- b_result = false
27
- end
28
-
29
- b_result
16
+ default_handle_resource(bridge_resource, :bridge, "Bridge \'#{bridge_name}\'", :down)
17
+ rescue => e
18
+ $log.error "processing bridge: #{e}"
30
19
  end
31
20
 
32
21
  # remove ip from bridge interface
33
22
  def handle_hostip(bridge_name, hostip)
34
- b_result = true
35
-
36
23
  bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
37
24
  if bridge_resource.down?
38
25
  outputs 'DOWN', "Bridge #{bridge_name} already down, will not care about ip", :ok2
@@ -42,22 +29,10 @@ module Wire
42
29
  # we should have a bridge with that name.
43
30
  hostip_resource = Wire::Resource::ResourceFactory
44
31
  .instance.create(:bridgeip, hostip, bridge_name)
45
- if hostip_resource.down?
46
- outputs 'DOWN', "IP #{hostip} on bridge #{bridge_name} already down.", :ok2
47
- return
48
- end
49
-
50
- hostip_resource.down
51
- if hostip_resource.down?
52
- outputs 'DOWN', "IP #{hostip} on bridge #{bridge_name} down/removed.", :ok
53
- state.update(:hostip, hostip, :down)
54
- else
55
- outputs 'DOWN', "Error taking down ip #{hostip} on bridge #{bridge_name}.", :err
56
-
57
- b_result = false
58
- end
59
-
60
- b_result
32
+ default_handle_resource(hostip_resource, :hostip,
33
+ "IP \'#{hostip}\' on bridge \'#{bridge_name}\'", :down)
34
+ rescue => e
35
+ $log.error "processing host ip: #{e}"
61
36
  end
62
37
 
63
38
  # unconfigures dnsmasq for dhcp
@@ -73,21 +48,10 @@ module Wire
73
48
  resource_dhcp = Wire::Resource::ResourceFactory
74
49
  .instance.create(:dhcpconfig, "wire__#{zone_name}", network_name,
75
50
  network_entry, address_start, address_end)
76
- if resource_dhcp.down?
77
- outputs 'DOWN', "dnsmasq/dhcp config on network \'#{network_name}\' is already down.", :ok2
78
- return true
79
- end
80
-
81
- resource_dhcp.down
82
- if resource_dhcp.down?
83
- outputs 'DOWN', "dnsmasq/dhcp config on network \'#{network_name}\' is down.", :ok
84
- state.update(:dnsmasq, network_name, :down)
85
- return true
86
- else
87
- outputs 'DOWN', 'Error unconfiguring dnsmasq/dhcp ' \
88
- "config on network \'#{network_name}\'.", :err
89
- return false
90
- end
51
+ default_handle_resource(resource_dhcp, :dnsmasq,
52
+ "dnsmasq/dhcp config on network \'#{network_name}\'", :down)
53
+ rescue => e
54
+ $log.error "processing dhcp configuration: #{e}"
91
55
  end
92
56
 
93
57
  # take the appgroups' controller and directs methods to
@@ -109,6 +73,8 @@ module Wire
109
73
  $log.error "Appgroup not handled for zone #{zone_name}, " \
110
74
  "unknown controller type #{controller_entry[:type]}"
111
75
  false
76
+ rescue => e
77
+ $log.error "processing appgroup: #{e}"
112
78
  end
113
79
 
114
80
  # implement appgroup handling for fig controller
@@ -126,24 +92,10 @@ module Wire
126
92
  resource_fig = Wire::Resource::ResourceFactory
127
93
  .instance.create(:figadapter, "#{appgroup_name}", fig_path)
128
94
 
129
- if resource_fig.down?
130
- outputs 'DOWN', "appgroup \'#{appgroup_name}\' for zone #{zone_name} is already down.", :ok2
131
- return true
132
- end
133
-
134
- b_result = false
135
- resource_fig.down
136
- if resource_fig.down?
137
- outputs 'DOWN', "appgroup \'#{appgroup_name}\' for zone #{zone_name} is down.", :ok
138
- state.update(:appgroup, appgroup_name, :down)
139
- b_result = true
140
- else
141
- outputs 'DOWN', "Error taking down appgroup \'#{appgroup_name}\' for zone #{zone_name}.",
142
- :err
143
- b_result = false
144
- end
145
-
146
- b_result
95
+ default_handle_resource(resource_fig, :appgroup,
96
+ "appgroup \'#{appgroup_name}\' for zone \'#{zone_name}\'", :down)
97
+ rescue => e
98
+ $log.error "processing appgroup/fig: #{e}"
147
99
  end
148
100
 
149
101
  # detaches networks to containers of appgroup
@@ -175,25 +127,13 @@ module Wire
175
127
 
176
128
  #
177
129
  resource_nw = Wire::Resource::ResourceFactory
178
- .instance.create(:networkinjection, appgroup_name, networks.keys, container_ids)
179
- if resource_nw.down?
180
- outputs 'DOWN', "appgroup \'#{appgroup_name}\' network " \
181
- 'attachments already detached.', :ok2
182
- state.update(:appgroup, appgroup_name, :down)
183
- return true
184
- else
185
- resource_nw.down
186
- if resource_nw.down?
187
- outputs 'DOWN', "appgroup \'#{appgroup_name}\' detached " \
188
- "networks #{networks.keys.join(',')}.", :ok
189
- state.update(:appgroup, appgroup_name, :down)
190
- return true
191
- else
192
- outputs 'DOWN', "Error detaching networks to appgroup \'#{appgroup_name}\'.",
193
- :err
194
- return false
195
- end
196
- end
130
+ .instance.create(:networkinjection, appgroup_name, networks, container_ids)
131
+
132
+ default_handle_resource(resource_nw, :network_injection,
133
+ "Network(s) \'#{networks.keys.join(',')}\' in "\
134
+ "appgroup \'#{appgroup_name}\'", :down)
135
+ rescue => e
136
+ $log.error "processing network attachments: #{e}"
197
137
  end
198
138
  end
199
139
  end
@@ -45,7 +45,7 @@ module Wire
45
45
  outputs 'SPEC', 'To run automatically, use --run'
46
46
  rescue => exception
47
47
  $log.error "Error writing serverspec files, #{exception}"
48
- STDERR.puts e.inspect
48
+ STDERR.puts exception.inspect
49
49
  end
50
50
 
51
51
  run_serverspec(target_specdir) if @params[:auto_run]
@@ -102,14 +102,31 @@ module Wire
102
102
  def run_on_network_in_zone(zone_name, bridge_name, network_data)
103
103
  $log.debug("Creating specs for network #{bridge_name}")
104
104
 
105
- template = SpecTemplates.build_template__bridge_exists
105
+ template = SpecTemplatesNetwork.build_template__bridge_exists
106
106
  erb = ERB.new(template, nil, '%')
107
107
  @spec_code << erb.result(binding)
108
108
 
109
+ vlan = network_data[:vlan]
110
+ if vlan
111
+ vlanid = vlan[:id]
112
+ on_trunk = vlan[:on_trunk]
113
+ template = SpecTemplatesNetwork.build_template__bridge_vlan_id_and_trunk
114
+ erb = ERB.new(template, nil, '%')
115
+ @spec_code << erb.result(binding)
116
+ end
117
+
109
118
  # render template for hostip (if any)
110
119
  ip = network_data[:hostip]
111
120
  if ip
112
- template = SpecTemplates.build_template__ip_is_up
121
+ template = SpecTemplatesNetwork.build_template__ip_is_up
122
+ erb = ERB.new(template, nil, '%')
123
+ @spec_code << erb.result(binding)
124
+ end
125
+
126
+ # render template for network/port attachments (if any)
127
+ attach_intf = network_data[:attach]
128
+ if attach_intf
129
+ template = SpecTemplatesNetwork.build_template__port_exists
113
130
  erb = ERB.new(template, nil, '%')
114
131
  @spec_code << erb.result(binding)
115
132
  end
@@ -120,7 +137,7 @@ module Wire
120
137
  ip_start = dhcp_data[:start]
121
138
  ip_end = dhcp_data[:end]
122
139
  hostip = ip
123
- template = SpecTemplates.build_template__dhcp_is_valid
140
+ template = SpecTemplatesNetwork.build_template__dhcp_is_valid
124
141
  erb = ERB.new(template, nil, '%')
125
142
  @spec_code << erb.result(binding)
126
143
 
@@ -147,11 +164,11 @@ module Wire
147
164
  figfile_part = controller_data[:file] || "#{zone_name}/fig.yaml"
148
165
  figfile = File.join(File.expand_path(@target_dir), figfile_part)
149
166
 
150
- template = SpecTemplates.build_template__fig_file_is_valid
167
+ template = SpecTemplatesContainers.build_template__fig_file_is_valid
151
168
  erb = ERB.new(template, nil, '%')
152
169
  @spec_code << erb.result(binding)
153
170
 
154
- template = SpecTemplates.build_template__fig_containers_are_up
171
+ template = SpecTemplatesContainers.build_template__fig_containers_are_up
155
172
  erb = ERB.new(template, nil, '%')
156
173
  @spec_code << erb.result(binding)
157
174
  end
@@ -159,4 +176,4 @@ module Wire
159
176
  $log.debug("Done for appgroup #{appgroup_name}")
160
177
  end
161
178
  end
162
- end
179
+ end
@@ -8,6 +8,53 @@
8
8
  module Wire
9
9
  # stateless erb template methods used by spec_command.rb
10
10
  class SpecTemplates
11
+ # generate template part
12
+ # returns
13
+ # - erb template for spec_helper.rb file
14
+ def self.template_spec_helper
15
+ <<ERB
16
+ require 'serverspec'
17
+
18
+ set :backend, :exec
19
+ ERB
20
+ end
21
+
22
+ # generate template part
23
+ # returns
24
+ # - erb template for Rakefile
25
+ def self.template_rakefile
26
+ <<ERB
27
+ require 'rake'
28
+ require 'rspec/core/rake_task'
29
+
30
+ task :spec => 'spec:all'
31
+ task :default => :spec
32
+
33
+ namespace :spec do
34
+ targets = []
35
+ Dir.glob('./spec/*').each do |dir|
36
+ next unless File.directory?(dir)
37
+ targets << File.basename(dir)
38
+ end
39
+
40
+ task :all => targets
41
+ task :default => :all
42
+
43
+ targets.each do |target|
44
+ desc "Run serverspec tests to \#{target}"
45
+ RSpec::Core::RakeTask.new(target.to_sym) do |t|
46
+ ENV['TARGET_HOST'] = target
47
+ t.pattern = "spec/\#{target}/*_spec.rb"
48
+ t.rspec_opts = '--format documentation --color'
49
+ end
50
+ end
51
+ end
52
+ ERB
53
+ end
54
+ end
55
+
56
+ # Templates for network-related stuff
57
+ class SpecTemplatesNetwork
11
58
  # rubocop:disable Lint/UnusedMethodArgument
12
59
  # :reek:UnusedParameters
13
60
  def self.build_template__bridge_exists
@@ -20,6 +67,38 @@ module Wire
20
67
  ERB
21
68
  end
22
69
 
70
+ # rubocop:disable Lint/UnusedMethodArgument
71
+ # :reek:UnusedParameters
72
+ def self.build_template__port_exists
73
+ <<ERB
74
+ describe 'In zone <%= zone_name %> we should have a port <%= attach_intf %> on ovs ' \
75
+ 'bridge <%= bridge_name %>' do
76
+ describe command "sudo ovs-vsctl list-ports <%= bridge_name %>" do
77
+ its(:stdout) { should match /<%= attach_intf %>/ }
78
+ end
79
+ end
80
+ ERB
81
+ end
82
+
83
+ # rubocop:disable Lint/UnusedMethodArgument
84
+ # :reek:UnusedParameters
85
+ def self.build_template__bridge_vlan_id_and_trunk
86
+ <<ERB
87
+ describe 'In zone <%= zone_name %>, ovs vlan bridge named <%= bridge_name %> ' \
88
+ 'should have id <%= vlanid %>' do
89
+ describe command "sudo ovs-vsctl br-to-vlan <%= bridge_name %>" do
90
+ its(:stdout) { should match /<%= vlanid %>/ }
91
+ end
92
+ end
93
+ describe 'In zone <%= zone_name %>, ovs vlan bridge named <%= bridge_name %> ' \
94
+ 'should have parent <%= on_trunk %>' do
95
+ describe command "sudo ovs-vsctl br-to-parent <%= bridge_name %>" do
96
+ its(:stdout) { should match /<%= on_trunk %>/ }
97
+ end
98
+ end
99
+ ERB
100
+ end
101
+
23
102
  # rubocop:disable Lint/UnusedMethodArgument
24
103
  # :reek:UnusedParameters
25
104
  def self.build_template__ip_is_up
@@ -63,7 +142,10 @@ ERB
63
142
  end
64
143
  ERB
65
144
  end
145
+ end
66
146
 
147
+ # templates for container-related specs
148
+ class SpecTemplatesContainers
67
149
  # rubocop:disable Lint/UnusedMethodArgument
68
150
  # :reek:UnusedParameters
69
151
  # requires figfile, appgroup_name
@@ -89,45 +171,6 @@ ERB
89
171
  its(:stdout) { should match /Up/ }
90
172
  end
91
173
  end
92
- ERB
93
- end
94
-
95
- # generate template part
96
- # returns
97
- # - erb template for spec_helper.rb file
98
- def self.template_spec_helper
99
- <<ERB
100
- require 'serverspec'
101
- require 'rspec/its'
102
-
103
- include SpecInfra::Helper::Exec
104
- include SpecInfra::Helper::DetectOS
105
-
106
- RSpec.configure do |c|
107
- if ENV['ASK_SUDO_PASSWORD']
108
- require 'highline/import'
109
- c.sudo_password = ask("Enter sudo password: ") { |q| q.echo = false }
110
- else
111
- c.sudo_password = ENV['SUDO_PASSWORD']
112
- end
113
- end
114
- ERB
115
- end
116
-
117
- # generate template part
118
- # returns
119
- # - erb template for Rakefile
120
- def self.template_rakefile
121
- <<ERB
122
- require 'rake'
123
- require 'rspec/core/rake_task'
124
-
125
- RSpec::Core::RakeTask.new(:spec) do |t|
126
- t.pattern = 'spec/*/*_spec.rb'
127
- t.rspec_opts = '--format documentation --color'
128
- end
129
-
130
- task :default => :spec
131
174
  ERB
132
175
  end
133
176
  end
@@ -59,7 +59,7 @@ module Wire
59
59
  zone_networks = objects_in_zone('networks', zone_name)
60
60
  success = handler.handle_network_attachments(zone_name, zone_networks,
61
61
  appgroup_name, appgroup_data,
62
- @project.target_dir)
62
+ @project.target_dir, @project.vartmp_dir)
63
63
  b_result &= success
64
64
  end
65
65
 
@@ -7,6 +7,7 @@
7
7
  # Wire module
8
8
  module Wire
9
9
  # handle_xxx methods for UpCommand
10
+ # delegates to BaseCommand.default_handle_resource for most parts
10
11
  # rubocop:disable ClassLength
11
12
  class UpCommandHandler < BaseCommand
12
13
  # bring bridge resource up, identified by
@@ -14,24 +15,13 @@ module Wire
14
15
  # Returns
15
16
  # - [Bool] true if hostip if up on bridge
16
17
  def handle_bridge(bridge_name)
17
- b_result = true
18
-
19
18
  # we should have a bridge with that name.
20
19
  bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
21
- if bridge_resource.up?
22
- outputs 'UP', "Bridge #{bridge_name} already up.", :ok2
23
- else
24
- bridge_resource.up
25
- if bridge_resource.up?
26
- outputs 'UP', "Bridge #{bridge_name} up.", :ok
27
- state.update(:bridge, bridge_name, :up)
28
- else
29
- outputs 'UP', "Error bringing up bridge #{bridge_name}.", :err
30
- b_result = false
31
- end
32
20
 
33
- end
34
- b_result
21
+ default_handle_resource(bridge_resource, :bridge,
22
+ "Bridge \'#{bridge_name}\'", :up)
23
+ rescue => e
24
+ $log.error "processing bridge: #{e}"
35
25
  end
36
26
 
37
27
  # bring ip resource up on device identified by
@@ -39,25 +29,14 @@ module Wire
39
29
  # Returns
40
30
  # - [Bool] true if hostip if up on bridge
41
31
  def handle_hostip(bridge_name, hostip)
42
- b_result = true
43
-
44
32
  # we should have a bridge with that name.
45
33
  hostip_resource = Wire::Resource::ResourceFactory
46
34
  .instance.create(:bridgeip, hostip, bridge_name)
47
- if hostip_resource.up?
48
- outputs 'UP', "IP #{hostip} on bridge #{bridge_name} already up.", :ok2
49
- else
50
- hostip_resource.up
51
- if hostip_resource.up?
52
- outputs 'UP', "IP #{hostip} on bridge #{bridge_name} up.", :ok
53
- state.update(:hostip, hostip, :up)
54
- else
55
- outputs 'UP', "Error bringing up ip #{hostip} on bridge #{bridge_name}.", :err
56
- b_result = false
57
- end
58
35
 
59
- end
60
- b_result
36
+ default_handle_resource(hostip_resource, :hostip,
37
+ "IP \'#{hostip}\' on bridge \'#{bridge_name}\'", :up)
38
+ rescue => e
39
+ $log.error "processing host ip: #{e}"
61
40
  end
62
41
 
63
42
  # configures dnsmasq for dhcp
@@ -72,21 +51,11 @@ module Wire
72
51
  resource_dhcp = Wire::Resource::ResourceFactory
73
52
  .instance.create(:dhcpconfig, "wire__#{zone_name}", network_name,
74
53
  network_entry, address_start, address_end)
75
- if resource_dhcp.up?
76
- outputs 'UP', "dnsmasq/dhcp config on network \'#{network_name}\' is already up.", :ok2
77
- return true
78
- else
79
- resource_dhcp.up
80
- if resource_dhcp.up?
81
- outputs 'UP', "dnsmasq/dhcp config on network \'#{network_name}\' is up.", :ok
82
- state.update(:dnsmasq, network_name, :up)
83
- return true
84
- else
85
- outputs 'UP', "Error configuring dnsmasq/dhcp config on network \'#{network_name}\'.",
86
- :err
87
- return false
88
- end
89
- end
54
+
55
+ default_handle_resource(resource_dhcp, :dnsmasq,
56
+ "dnsmasq/dhcp config on network \'#{network_name}\'", :up)
57
+ rescue => e
58
+ $log.error "processing dhcp: #{e}"
90
59
  end
91
60
 
92
61
  # take the appgroups' controller and directs methods to
@@ -106,6 +75,8 @@ module Wire
106
75
 
107
76
  $log.error "Appgroup not handled, unknown controller type #{controller_entry[:type]}"
108
77
  false
78
+ rescue => e
79
+ $log.error "processing appgroup: #{e}"
109
80
  end
110
81
 
111
82
  # implement appgroup handling for fig controller
@@ -123,21 +94,10 @@ module Wire
123
94
  resource_fig = Wire::Resource::ResourceFactory
124
95
  .instance.create(:figadapter, "#{appgroup_name}", fig_path)
125
96
 
126
- if resource_fig.up?
127
- outputs 'UP', "appgroup \'#{appgroup_name}\' in zone #{zone_name} is already up.", :ok2
128
- return true
129
- else
130
- resource_fig.up
131
- if resource_fig.up?
132
- outputs 'UP', "appgroup \'#{appgroup_name}\' in zone #{zone_name} is up.", :ok
133
- state.update(:appgroup, appgroup_name, :up)
134
- return true
135
- else
136
- outputs 'UP', "Error bringing up appgroup \'#{appgroup_name}\' in zone #{zone_name} .",
137
- :err
138
- return false
139
- end
140
- end
97
+ default_handle_resource(resource_fig, :appgroup,
98
+ "appgroup \'#{appgroup_name}\' for zone \'#{zone_name}\'", :up)
99
+ rescue => e
100
+ $log.error "processing appgroup/fig: #{e}"
141
101
  end
142
102
 
143
103
  # attaches networks to containers of appgroup
@@ -147,10 +107,11 @@ module Wire
147
107
  # ++appgroup_name++: Name of appgroup
148
108
  # ++appgroup_entry++: appgroup hash
149
109
  # ++target_dir++: project target dir
110
+ # ++state_dir++: project state dir (network statefile is written there)
150
111
  # Returns
151
112
  # - [Bool] true if appgroup setup is ok
152
113
  def handle_network_attachments(_zone_name, networks, appgroup_name,
153
- appgroup_entry, target_dir)
114
+ appgroup_entry, target_dir, state_dir)
154
115
  # query container ids of containers running here
155
116
  # get path
156
117
  controller_entry = appgroup_entry[:controller]
@@ -168,26 +129,15 @@ module Wire
168
129
  end
169
130
 
170
131
  #
132
+ statefile_name = File.join(state_dir, ".network_attachment_#{Time.now.to_i}")
171
133
  resource_nw = Wire::Resource::ResourceFactory
172
- .instance.create(:networkinjection, appgroup_name, networks.keys, container_ids)
173
- if resource_nw.up?
174
- outputs 'UP', "appgroup \'#{appgroup_name}\' already has valid network " \
175
- 'attachments.', :ok2
176
- state.update(:appgroup, appgroup_name, :up)
177
- return true
178
- else
179
- resource_nw.up
180
- if resource_nw.up?
181
- outputs 'UP', "appgroup \'#{appgroup_name}\' attached " \
182
- "networks #{networks.keys.join(',')}.", :ok
183
- state.update(:appgroup, appgroup_name, :up)
184
- return true
185
- else
186
- outputs 'UP', "Error attaching networks to appgroup \'#{appgroup_name}\'.",
187
- :err
188
- return false
189
- end
190
- end
134
+ .instance.create(:networkinjection, appgroup_name, networks, container_ids, statefile_name)
135
+
136
+ default_handle_resource(resource_nw, :network_injection,
137
+ "Network(s) \'#{networks.keys.join(',')}\' in "\
138
+ "appgroup \'#{appgroup_name}\'", :up)
139
+ rescue => e
140
+ $log.error "processing network attachments: #{e}"
191
141
  end
192
142
  end
193
143
  end
@@ -8,21 +8,32 @@
8
8
  module Wire
9
9
  # handle_xxx methods for VerifyCommand
10
10
  class VerifyCommandHandler < BaseCommand
11
+ # asks given +resource+ if it is up. Writes states, outputs state
12
+ # Params:
13
+ # ++resource++: Resource object, i.e. BridgeResource
14
+ # ++resource_type++: Resource type symbol, i.e. :bridge
15
+ # ++resource_desc_str++: Description to dump out
16
+ # Returns
17
+ # [Bool] true = resource is up, false otherwise
18
+ def default_handle_resource(resource, resource_type, resource_desc_str)
19
+ if resource.up?
20
+ outputs 'VERIFY', "#{resource_desc_str} is up.", :ok
21
+ state.update(resource_type, resource.name, :up)
22
+ return true
23
+ else
24
+ outputs 'VERIFY', "#{resource_desc_str} is not up.", :err
25
+ state.update(resource_type, resource.name, :down)
26
+ return false
27
+ end
28
+ end
29
+
11
30
  # runs verification for a bridge resource identified by
12
31
  # +bridge_name+
13
32
  # Returns
14
33
  # - [Bool] true if bridge exists
15
34
  def handle_bridge(bridge_name)
16
35
  bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
17
- if bridge_resource.exist?
18
- outputs 'VERIFY', "Bridge \'#{bridge_name}\' exists.", :ok
19
- state.update(:bridge, bridge_name, :up)
20
- return true
21
- else
22
- outputs 'VERIFY', "Bridge \'#{bridge_name}\' does not exist.", :err
23
- state.update(:bridge, bridge_name, :down)
24
- return false
25
- end
36
+ default_handle_resource(bridge_resource, :bridge, "Bridge \'#{bridge_name}\'")
26
37
  end
27
38
 
28
39
  # runs verification for a ip resource identified by
@@ -32,15 +43,8 @@ module Wire
32
43
  def handle_hostip(bridge_name, hostip)
33
44
  hostip_resource = Wire::Resource::ResourceFactory
34
45
  .instance.create(:bridgeip, hostip, bridge_name)
35
- if hostip_resource.up?
36
- outputs 'VERIFY', "IP \'#{hostip}\' on bridge \'#{bridge_name}\' exists.", :ok
37
- state.update(:hostip, hostip, :up)
38
- return true
39
- else
40
- outputs 'VERIFY', "IP \'#{hostip}\' on bridge \'#{bridge_name}\' does not exist.", :err
41
- state.update(:hostip, hostip, :down)
42
- return false
43
- end
46
+ default_handle_resource(hostip_resource, :hostip,
47
+ "IP \'#{hostip}\' on bridge \'#{bridge_name}\'")
44
48
  end
45
49
 
46
50
  # runs verification for dnsmasqs dhcp resource
@@ -50,15 +54,8 @@ module Wire
50
54
  resource = Wire::Resource::ResourceFactory
51
55
  .instance.create(:dhcpconfig, "wire__#{zone_name}", network_name,
52
56
  network_entry, address_start, address_end)
53
- if resource.up?
54
- outputs 'VERIFY', "dnsmasq/dhcp config on network \'#{network_name}\' is valid.", :ok
55
- state.update(:dnsmasq, network_name, :up)
56
- return true
57
- else
58
- outputs 'VERIFY', "dnsmasq/dhcp config on network \'#{network_name}\' is not valid.", :err
59
- state.update(:dnsmasq, network_name, :down)
60
- return false
61
- end
57
+ default_handle_resource(resource, :dnsmasq,
58
+ "dnsmasq/dhcp config on network \'#{network_name}\'")
62
59
  end
63
60
 
64
61
  # runs verification for appgroups
@@ -73,15 +70,8 @@ module Wire
73
70
 
74
71
  resource = Wire::Resource::ResourceFactory
75
72
  .instance.create(:figadapter, "#{appgroup_name}", fig_path)
76
- if resource.up?
77
- outputs 'VERIFY', "appgroup \'#{appgroup_name}\' is running.", :ok
78
- state.update(:appgroup, appgroup_name, :up)
79
- return true
80
- else
81
- outputs 'VERIFY', "appgroup \'#{appgroup_name}\' is not running.", :err
82
- state.update(:appgroup, appgroup_name, :down)
83
- return false
84
- end
73
+ return default_handle_resource(resource, :appgroup,
74
+ "Fig Appgroup \'#{appgroup_name}\'")
85
75
  end
86
76
 
87
77
  $log.error "Appgroup not handled, unknown controller type #{controller_entry[:type]}"
@@ -117,18 +107,10 @@ module Wire
117
107
 
118
108
  #
119
109
  resource = Wire::Resource::ResourceFactory
120
- .instance.create(:networkinjection, appgroup_name, networks.keys, container_ids)
121
- if resource.up?
122
- outputs 'VERIFY', "appgroup \'#{appgroup_name}\' has network(s) " \
123
- "\'#{networks.keys.join(',')}\' attached.", :ok
124
- state.update(:appgroup, appgroup_name, :up)
125
- return true
126
- else
127
- outputs 'VERIFY', "appgroup \'#{appgroup_name}\' does not have " \
128
- "all networks \'#{networks.keys.join(',')}\' attached.", :err
129
- state.update(:appgroup, appgroup_name, :down)
130
- return false
131
- end
110
+ .instance.create(:networkinjection, appgroup_name, networks, container_ids)
111
+ default_handle_resource(resource, :network_injection,
112
+ "Network(s) \'#{networks.keys.join(',')}\' in " \
113
+ "appgroup \'#{appgroup_name}\'")
132
114
  end
133
115
  end
134
116
  end
@@ -12,7 +12,7 @@ module Wire
12
12
  module Execution
13
13
  # return singleton object
14
14
  def self.global_execution_options
15
- ExecutionOptions.singleton
15
+ ExecutionOptions.instance
16
16
  end
17
17
 
18
18
  # Global execution options, such as noop mode etc.
@@ -17,6 +17,7 @@ module Wire
17
17
  missing_network_def_found?
18
18
  nonmatching_hostips_found?
19
19
  dhcp_address_ranges_valid?
20
+ networks_names_too_long?
20
21
  end
21
22
 
22
23
  # ensures that all networks are attached to a zone
@@ -24,6 +25,20 @@ module Wire
24
25
  objects_attached_to_zones? 'networks'
25
26
  end
26
27
 
28
+ # ensures that networks with names > 6 chars have
29
+ # a short name defined, and short names are 6 chars. max.
30
+ def networks_names_too_long?
31
+ @project.get_element('networks').each do |network_name, network_data|
32
+ b_short_name_ok = (network_data[:shortname] && network_data[:shortname].size <= 6)
33
+
34
+ mark("Network name #{network_name} too long, please define a :shortname with 6 chars. max.",
35
+ 'network', network_name) if network_name.size > 6 && !b_short_name_ok
36
+ mark("Network short name of network #{network_name} too long, please define a :shortname " \
37
+ 'with 6 chars. max.',
38
+ 'network', network_name) if network_data[:shortname] && !b_short_name_ok
39
+ end
40
+ end
41
+
27
42
  # ensures that all network ranges are unique
28
43
  def duplicate_networks_found?
29
44
  dup_map = {}
@@ -86,26 +101,26 @@ module Wire
86
101
  'network', network_name)
87
102
  return false
88
103
  else
89
- # check ip ranges
90
-
91
- begin
92
- dhcp_start_ip = IPAddr.new(dhcp_data[:start])
93
- dhcp_end_ip = IPAddr.new(dhcp_data[:end])
94
- network_ip = IPAddr.new(network)
95
-
96
- mark("Network dhcp start ip #{dhcp_data[:start]} is not within network range" \
97
- "#{network} of network #{network_name}", 'network', network_name) unless
98
- dhcp_start_ip.in_range_of?(network_ip)
99
-
100
- mark("Network dhcp end ip #{dhcp_data[:end]} is not within network range" \
101
- "#{network} of network #{network_name}", 'network', network_name) unless
102
- dhcp_end_ip.in_range_of?(network_ip)
103
- rescue => e
104
- mark("Network dhcp ip range is not valid: #{e}", 'network', network_name)
105
- end
104
+ check_network_ip_ranges(dhcp_data, network, network_name)
106
105
  end
107
106
  end
108
107
  end
109
108
  end
109
+
110
+ # check ip ranges of +dhcp_data+ and given +network+
111
+ # with name +network_name+
112
+ def check_network_ip_ranges(dhcp_data, network, network_name)
113
+ network_ip = IPAddr.new(network)
114
+
115
+ # check both starting/ending ip range
116
+ { :start => IPAddr.new(dhcp_data[:start]),
117
+ :end => IPAddr.new(dhcp_data[:end]) }.each do |type, data|
118
+ mark("Network dhcp #{type} ip #{dhcp_data[type]} is not within network range" \
119
+ "#{network} of network #{network_name}",
120
+ 'network', network_name) unless data.in_range_of?(network_ip)
121
+ end
122
+ rescue => e
123
+ mark("Network dhcp ip range is not valid: #{e}", 'network', network_name)
124
+ end
110
125
  end
111
126
  end
@@ -48,6 +48,18 @@ module Wire
48
48
  @data[element_name.to_sym]
49
49
  end
50
50
 
51
+ # return project's var/tmp directory, will be configurable
52
+ # in the future
53
+ def vartmp_dir
54
+ # as of now, use .state in target dir
55
+ state_dir = File.join(@target_dir, '.state')
56
+ unless File.directory? state_dir
57
+ FileUtils.mkdir_p state_dir
58
+ $log.debug "created state dir #{state_dir}"
59
+ end
60
+ state_dir
61
+ end
62
+
51
63
  # calculates count statistics on project
52
64
  # returns:
53
65
  # - [Hash], key => element type, value => [int] count
@@ -114,13 +114,14 @@ module Wire
114
114
  @state = YAML.load_file(statefile_filename)
115
115
  else
116
116
  $log.debug 'No statefile found.'
117
+ clean
117
118
  end
118
119
  @changed = false
119
120
  end
120
121
 
121
122
  # construct name of state file
122
123
  def state_filename
123
- File.join(@project.target_dir, '.state.yaml')
124
+ File.join(@project.vartmp_dir, '.state.yaml')
124
125
  end
125
126
  end
126
127
 
@@ -30,6 +30,8 @@ module Wire
30
30
  }
31
31
  end
32
32
 
33
+ # TODO: move to generic execution method
34
+ # https://codeclimate.com/github/de-wiring/wire/Wire::Resource::OVSBridge
33
35
  # checks if the bridge exists
34
36
  def exist?
35
37
  LocalExecution.with(@executables[:vsctl],
@@ -24,16 +24,21 @@ module Wire
24
24
  # names of networks to attach appgroup containers to
25
25
  attr_accessor :networks
26
26
 
27
+ # filename of state file
28
+ attr_accessor :statefile
29
+
27
30
  # initialize the object with
28
31
  # given appgroup +name+ and +container+ ids
29
32
  # params:
30
33
  # ++name++: Application group name
31
- # ++networks++: [Array] of network names to attach containers to
32
- # ++containers+: [Array] of container ids (i.e. from fig ps -q)
33
- def initialize(name, networks, containers)
34
+ # ++networks++: [Array] of network objects to attach containers to
35
+ # ++containers++: [Array] of container ids (i.e. from fig ps -q)
36
+ # ++statefile++: Optional name of (network) statefile
37
+ def initialize(name, networks, containers, statefile = nil)
34
38
  super(name)
35
39
  self.containers = containers
36
40
  self.networks = networks
41
+ self.statefile = statefile
37
42
 
38
43
  begin
39
44
  # try to locate the gem base path and find shell script
@@ -73,12 +78,18 @@ module Wire
73
78
  # an array of container devices names and bridge names,
74
79
  # i.e. eht1:br0 meaning container will be attached
75
80
  # to bridge br0 with eth1.
76
- # first iteration: choose device=network_name=bridge_name,
77
- # all the same.
81
+ # if a network defines a short name, it will be used for
82
+ # the container interface.
83
+ # will check if a network does not have dhcp enable and add a
84
+ # NODHCP flag.
78
85
  def construct_helper_params
79
86
  res = []
80
- networks.each do |network|
81
- res << "#{network}:#{network}"
87
+ networks.each do |network_name, network_data|
88
+ name = (network_data[:shortname]) ? network_data[:shortname] : network_name
89
+
90
+ line = "#{name}:#{network_name}"
91
+ (network_data[:dhcp]) || line << ':NODHCP'
92
+ res << line
82
93
  end
83
94
  res.join(' ')
84
95
  end
@@ -93,17 +104,23 @@ module Wire
93
104
  end
94
105
  end
95
106
 
96
- # attaches containers to networks
97
- def up
98
- $log.debug 'Attaching containers to networks ...'
99
- with_helper('attach', [construct_helper_params,
100
- containers.join(' ')]) do |exec_obj|
107
+ # Params:
108
+ # ++cmd++: One of :attach, :detach
109
+ def updown_command(cmd)
110
+ $log.debug "About to #{cmd.to_s.capitalize} containers to networks ..."
111
+ statefile_param = (@statefile) ? "-s #{@statefile}" : ''
112
+ with_helper(cmd.to_s, [construct_helper_params,
113
+ containers.join(' ')], statefile_param) do |exec_obj|
101
114
  exec_obj.run
102
-
103
115
  return (exec_obj.exitstatus == 0 && count_errors(exec_obj) == 0)
104
116
  end
105
117
  end
106
118
 
119
+ # attaches containers to networks
120
+ def up
121
+ updown_command :attach
122
+ end
123
+
107
124
  # checks if the bridge is down
108
125
  def down?
109
126
  !(up?)
@@ -111,13 +128,7 @@ module Wire
111
128
 
112
129
  # detaches network interfaces form containers and bridges
113
130
  def down
114
- $log.debug 'Taking down container network attachments ...'
115
- with_helper('detach', [construct_helper_params,
116
- containers.join(' ')]) do |exec_obj|
117
- exec_obj.run
118
-
119
- return (exec_obj.exitstatus == 0 && count_errors(exec_obj) == 0)
120
- end
131
+ updown_command :detach
121
132
  end
122
133
 
123
134
  # Returns a string representation
@@ -26,11 +26,11 @@ module Wire
26
26
  end
27
27
 
28
28
  # ResourceFactory creates Resource objects
29
- # given by name
29
+ # given by symbolic name
30
30
  class ResourceFactory
31
31
  include Singleton
32
32
 
33
- # given a +resource_name+ as a symbol (i.e. :ovsbridge)
33
+ # given a +resource_symname+ as a symbol (i.e. :ovsbridge)
34
34
  # this creates a resource with given name (i.e. "testbridge")
35
35
  # and hands on arguments (+resource_nameargs+, may be 1..n)
36
36
  # returns
data/lib/wire/version.rb CHANGED
@@ -9,6 +9,6 @@ module Wire
9
9
  # Wire Version information
10
10
  module WireVersion
11
11
  # current version
12
- VERSION = '0.1.3'
12
+ VERSION = '0.1.4'
13
13
  end
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dewiring
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Schmidt