dewiring 0.1.3 → 0.1.4

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.
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