vagrant-lxc 1.2.1 → 1.2.2

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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f32c69313fa7841bc705a4d5c34886ef805a1683
4
- data.tar.gz: 75f6f51414b4848ec43b2d1f8143d0826222af9d
3
+ metadata.gz: d84ceba1d5fb8d5d083ade786cbacccc062dafe0
4
+ data.tar.gz: 433489fcf70ecd5ae43094c8470c025f4040d59b
5
5
  SHA512:
6
- metadata.gz: 855233099329744d0dbadaf3995ab20880482439cf6543b11099fa20d4ee591c804059a80ee9958f8c74c2c66a41aaf12e132898b36eeca59addbe1365e1975d
7
- data.tar.gz: eb3e87438de2a701dc267891006e3e615cb0e28f35fe2e5eae75e89fd640d3b043bff592f94af7126d518fcbdb54cfd6ce808ff1940b1c72150a1bdc6b7ba47a
6
+ metadata.gz: 840b7e84fad95f8585486a8b5dea5a86ce292a2c8edbb02a45fe6f99071480f4fd469db462783717418b8a48a49df59bc561425dd8ac69090d7327d1c1fd345e
7
+ data.tar.gz: 56c4c1fe8a20e36f45f0edbb6e587de557f67ceb8bd7d78beeacc47497833228e2fbb038e9d1d514456d01208e6746016d7f1995c8cb6ba1e9a80937e1c35629
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [1.2.2](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.1...v1.2.2) (Dec 20, 2016)
2
+
3
+ - Make the timeout for fetching container IP's configurable [[GH-426]]
4
+ - Load locale file only once [[GH-423]]
5
+ - Preserve xattrs in container filesystems [[GH-411]]
6
+ - Forward port latest pipework script [[GH-408]]
7
+ - Fix handling of non-fatal lxc-stop return code [[GH-405]]
8
+
1
9
  ## [1.2.1](https://github.com/fgrehm/vagrant-lxc/compare/v1.2.0...v1.2.1) (Sep 24, 2015)
2
10
 
3
11
  BUGFIX:
data/Gemfile.lock CHANGED
@@ -2,7 +2,7 @@ GIT
2
2
  remote: https://github.com/fgrehm/vagrant-cachier.git
3
3
  revision: 40dddfb368526948e769492a00a7937c5a044a4d
4
4
  specs:
5
- vagrant-cachier (1.2.1)
5
+ vagrant-cachier (1.2.2)
6
6
 
7
7
  GIT
8
8
  remote: https://github.com/fgrehm/vagrant-pristine.git
data/README.md CHANGED
@@ -19,6 +19,7 @@ to see it in action.
19
19
 
20
20
  * [Vagrant 1.5+](http://www.vagrantup.com/downloads.html) (tested with 1.7.2)
21
21
  * lxc 0.7.5+
22
+ * tar 1.27 (the lxc-template script uses the --xattrs option)
22
23
  * `redir` (if you are planning to use port forwarding)
23
24
  * `brctl` (if you are planning to use private networks, on Ubuntu this means `apt-get install bridge-utils`)
24
25
  * A [kernel != 3.5.0-17.28](https://github.com/fgrehm/vagrant-lxc/wiki/Troubleshooting#wiki-im-unable-to-restart-containers)
@@ -19,9 +19,11 @@ module Vagrant
19
19
  end
20
20
 
21
21
  def assigned_ip(env)
22
+ config = env[:machine].provider_config
23
+ fetch_ip_tries = config.fetch_ip_tries
22
24
  driver = env[:machine].provider.driver
23
25
  ip = ''
24
- retryable(:on => LXC::Errors::ExecuteError, :tries => 10, :sleep => 3) do
26
+ retryable(:on => LXC::Errors::ExecuteError, :tries => fetch_ip_tries, :sleep => 3) do
25
27
  unless ip = get_container_ip_from_ip_addr(driver)
26
28
  # retry
27
29
  raise LXC::Errors::ExecuteError, :command => "lxc-attach"
@@ -18,12 +18,15 @@ module Vagrant
18
18
  # machine name, set this to :machine
19
19
  attr_accessor :container_name
20
20
 
21
+ attr_accessor :fetch_ip_tries
22
+
21
23
  def initialize
22
24
  @customizations = []
23
25
  @backingstore = UNSET_VALUE
24
26
  @backingstore_options = []
25
27
  @sudo_wrapper = UNSET_VALUE
26
28
  @container_name = UNSET_VALUE
29
+ @fetch_ip_tries = UNSET_VALUE
27
30
  end
28
31
 
29
32
  # Customize the container by calling `lxc-start` with the given
@@ -51,6 +54,7 @@ module Vagrant
51
54
  @container_name = nil if @container_name == UNSET_VALUE
52
55
  @backingstore = "best" if @backingstore == UNSET_VALUE
53
56
  @existing_container_name = nil if @existing_container_name == UNSET_VALUE
57
+ @fetch_ip_tries = 10 if @fetch_ip_tries == UNSET_VALUE
54
58
  end
55
59
  end
56
60
  end
@@ -85,9 +85,20 @@ module Vagrant
85
85
  run :start, '-d', '--name', @name, *Array(options)
86
86
  end
87
87
 
88
+ ## lxc-stop will exit 2 if machine was already stopped
89
+ # Man Page:
90
+ # 2 The specified container exists but was not running.
88
91
  def stop
89
92
  attach '/sbin/halt' if supports_attach?
90
- run :stop, '--name', @name
93
+ begin
94
+ run :stop, '--name', @name
95
+ rescue LXC::Errors::ExecuteError => e
96
+ if e.exitcode == 2
97
+ @logger.debug "Machine already stopped, lxc-stop returned 2"
98
+ else
99
+ raise e
100
+ end
101
+ end
91
102
  end
92
103
 
93
104
  def attach(*cmd)
@@ -5,12 +5,13 @@ module Vagrant
5
5
  module Errors
6
6
  class ExecuteError < Vagrant::Errors::VagrantError
7
7
  error_key(:lxc_execute_error)
8
- attr_reader :stderr, :stdout
8
+ attr_reader :stderr, :stdout, :exitcode
9
9
  def initialize(message, *args)
10
10
  super
11
11
  if message.is_a?(Hash)
12
12
  @stderr = message[:stderr]
13
13
  @stdout = message[:stdout]
14
+ @exitcode = message[:exitcode]
14
15
  end
15
16
  end
16
17
  end
@@ -11,20 +11,19 @@ module Vagrant
11
11
 
12
12
  provider(:lxc, parallel: true, priority: 7) do
13
13
  require File.expand_path("../provider", __FILE__)
14
-
15
- I18n.load_path << File.expand_path(File.dirname(__FILE__) + '/../../locales/en.yml')
16
- I18n.reload!
17
-
14
+ init!
18
15
  Provider
19
16
  end
20
17
 
21
18
  command "lxc" do
22
19
  require_relative 'command/root'
20
+ init!
23
21
  Command::Root
24
22
  end
25
23
 
26
24
  config(:lxc, :provider) do
27
25
  require File.expand_path("../config", __FILE__)
26
+ init!
28
27
  Config
29
28
  end
30
29
 
@@ -37,6 +36,16 @@ module Vagrant
37
36
  require_relative "provider/cap/public_address"
38
37
  Provider::Cap::PublicAddress
39
38
  end
39
+
40
+ protected
41
+
42
+ def self.init!
43
+ return if defined?(@_init)
44
+ I18n.load_path << File.expand_path(File.dirname(__FILE__) + '/../../locales/en.yml')
45
+ I18n.reload!
46
+ @_init = true
47
+ end
48
+
40
49
  end
41
50
  end
42
51
  end
@@ -49,7 +49,7 @@ module Vagrant
49
49
  @logger.info("Exit code != 0, but interrupted. Ignoring.")
50
50
  else
51
51
  raise LXC::Errors::ExecuteError,
52
- command: command.inspect, stderr: r.stderr, stdout: r.stdout
52
+ command: command.inspect, stderr: r.stderr, stdout: r.stdout, exitcode: r.exit_code
53
53
  end
54
54
  end
55
55
  end
@@ -1,5 +1,5 @@
1
1
  module Vagrant
2
2
  module LXC
3
- VERSION = "1.2.1"
3
+ VERSION = "1.2.2"
4
4
  end
5
5
  end
data/scripts/lxc-template CHANGED
@@ -124,7 +124,7 @@ mkdir -p /var/lock/subsys
124
124
  fi
125
125
 
126
126
  mkdir -p ${LXC_ROOTFS}
127
- (cd ${LXC_ROOTFS} && tar xfz ${LXC_TARBALL} --strip-components=${LXC_STRIP_COMPONENTS})
127
+ (cd ${LXC_ROOTFS} && tar xfz ${LXC_TARBALL} --strip-components=${LXC_STRIP_COMPONENTS} --xattrs --xattrs-include=*)
128
128
  if [ $? -ne 0 ]; then
129
129
  echo "Failed to extract rootfs"
130
130
  exit 1
data/scripts/pipework CHANGED
@@ -1,13 +1,12 @@
1
- #!/usr/bin/env bash
2
-
3
- # Borrowed from https://github.com/jpetazzo/pipework
4
-
1
+ #!/bin/sh
2
+ # This code should (try to) follow Google's Shell Style Guide
3
+ # (https://google-styleguide.googlecode.com/svn/trunk/shell.xml)
5
4
  set -e
6
5
 
7
6
  case "$1" in
8
- --wait)
9
- WAIT=1
10
- ;;
7
+ --wait)
8
+ WAIT=1
9
+ ;;
11
10
  esac
12
11
 
13
12
  IFNAME=$1
@@ -19,280 +18,405 @@ if [ "$2" = "-i" ]; then
19
18
  shift 2
20
19
  fi
21
20
 
21
+ if [ "$2" = "-l" ]; then
22
+ LOCAL_IFNAME=$3
23
+ shift 2
24
+ fi
25
+
22
26
  GUESTNAME=$2
23
27
  IPADDR=$3
24
28
  MACADDR=$4
25
29
 
26
- if echo $MACADDR | grep -q @
27
- then
28
- VLAN=$(echo $MACADDR | cut -d@ -f2)
29
- MACADDR=$(echo $MACADDR | cut -d@ -f1)
30
- else
31
- VLAN=
32
- fi
30
+ case "$MACADDR" in
31
+ *@*)
32
+ VLAN="${MACADDR#*@}"
33
+ VLAN="${VLAN%%@*}"
34
+ MACADDR="${MACADDR%%@*}"
35
+ ;;
36
+ *)
37
+ VLAN=
38
+ ;;
39
+ esac
40
+
41
+ # did they ask to generate a custom MACADDR?
42
+ # generate the unique string
43
+ case "$MACADDR" in
44
+ U:*)
45
+ macunique="${MACADDR#*:}"
46
+ # now generate a 48-bit hash string from $macunique
47
+ MACADDR=$(echo $macunique|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')
48
+ ;;
49
+ esac
50
+
33
51
 
34
52
  [ "$IPADDR" ] || [ "$WAIT" ] || {
35
- echo "Syntax:"
36
- echo "pipework <hostinterface> [-i containerinterface] <guest> <ipaddr>/<subnet>[@default_gateway] [macaddr][@vlan]"
37
- echo "pipework <hostinterface> [-i containerinterface] <guest> dhcp [macaddr][@vlan]"
38
- echo "pipework --wait [-i containerinterface]"
39
- exit 1
53
+ echo "Syntax:"
54
+ echo "pipework <hostinterface> [-i containerinterface] [-l localinterfacename] <guest> <ipaddr>/<subnet>[@default_gateway] [macaddr][@vlan]"
55
+ echo "pipework <hostinterface> [-i containerinterface] [-l localinterfacename] <guest> dhcp [macaddr][@vlan]"
56
+ echo "pipework route <guest> <route_command>"
57
+ echo "pipework --wait [-i containerinterface]"
58
+ exit 1
40
59
  }
41
60
 
42
- # First step: determine type of first argument (bridge, physical interface...), skip if --wait set
43
- if [ -z "$WAIT" ]; then
44
- if [ -d /sys/class/net/$IFNAME ]
45
- then
46
- if [ -d /sys/class/net/$IFNAME/bridge ]
47
- then
48
- IFTYPE=bridge
49
- BRTYPE=linux
50
- elif $(which ovs-vsctl >/dev/null 2>&1) && $(ovs-vsctl list-br|grep -q ^$IFNAME$)
51
- then
52
- IFTYPE=bridge
53
- BRTYPE=openvswitch
54
- elif [ $(cat /sys/class/net/$IFNAME/type) -eq 32 ]; # Infiniband IPoIB interface type 32
55
- then
56
- IFTYPE=ipoib
57
- # The IPoIB kernel module is fussy, set device name to ib0 if not overridden
58
- CONTAINER_IFNAME=${CONTAINER_IFNAME:-ib0}
59
- else IFTYPE=phys
60
- fi
61
- else
62
- # case "$IFNAME" in
63
- # br*)
64
- IFTYPE=bridge
65
- BRTYPE=linux
66
- # ;;
67
- # ovs*)
68
- # if ! $(which ovs-vsctl >/dev/null)
69
- # then
70
- # echo "Need OVS installed on the system to create an ovs bridge"
71
- # exit 1
72
- # fi
73
- # IFTYPE=bridge
74
- # BRTYPE=openvswitch
75
- # ;;
76
- # *)
77
- # echo "I do not know how to setup interface $IFNAME."
78
- # exit 1
79
- # ;;
80
- # esac
61
+ # Succeed if the given utility is installed. Fail otherwise.
62
+ # For explanations about `which` vs `type` vs `command`, see:
63
+ # http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script/677212#677212
64
+ # (Thanks to @chenhanxiao for pointing this out!)
65
+ installed () {
66
+ command -v "$1" >/dev/null 2>&1
67
+ }
68
+
69
+ # Google Styleguide says error messages should go to standard error.
70
+ warn () {
71
+ echo "$@" >&2
72
+ }
73
+ die () {
74
+ status="$1"
75
+ shift
76
+ warn "$@"
77
+ exit "$status"
78
+ }
79
+
80
+ # First step: determine type of first argument (bridge, physical interface...),
81
+ # Unless "--wait" is set (then skip the whole section)
82
+ if [ -z "$WAIT" ]; then
83
+ if [ -d "/sys/class/net/$IFNAME" ]
84
+ then
85
+ if [ -d "/sys/class/net/$IFNAME/bridge" ]; then
86
+ IFTYPE=bridge
87
+ BRTYPE=linux
88
+ elif installed ovs-vsctl && ovs-vsctl list-br|grep -q "^${IFNAME}$"; then
89
+ IFTYPE=bridge
90
+ BRTYPE=openvswitch
91
+ elif [ "$(cat "/sys/class/net/$IFNAME/type")" -eq 32 ]; then # InfiniBand IPoIB interface type 32
92
+ IFTYPE=ipoib
93
+ # The IPoIB kernel module is fussy, set device name to ib0 if not overridden
94
+ CONTAINER_IFNAME=${CONTAINER_IFNAME:-ib0}
95
+ PKEY=$VLAN
96
+ else IFTYPE=phys
81
97
  fi
98
+ else
99
+ case "$IFNAME" in
100
+ br*)
101
+ IFTYPE=bridge
102
+ BRTYPE=linux
103
+ ;;
104
+ ovs*)
105
+ if ! installed ovs-vsctl; then
106
+ die 1 "Need OVS installed on the system to create an ovs bridge"
107
+ fi
108
+ IFTYPE=bridge
109
+ BRTYPE=openvswitch
110
+ ;;
111
+ route*)
112
+ IFTYPE=route
113
+ ;;
114
+ dummy*)
115
+ IFTYPE=dummy
116
+ ;;
117
+ *) die 1 "I do not know how to setup interface $IFNAME." ;;
118
+ esac
119
+ fi
82
120
  fi
83
121
 
84
122
  # Set the default container interface name to eth1 if not already set
85
123
  CONTAINER_IFNAME=${CONTAINER_IFNAME:-eth1}
86
124
 
87
125
  [ "$WAIT" ] && {
88
- while ! grep -q ^1$ /sys/class/net/$CONTAINER_IFNAME/carrier 2>/dev/null
89
- do sleep 1
90
- done
126
+ while true; do
127
+ # This first method works even without `ip` or `ifconfig` installed,
128
+ # but doesn't work on older kernels (e.g. CentOS 6.X). See #128.
129
+ grep -q '^1$' "/sys/class/net/$CONTAINER_IFNAME/carrier" && break
130
+ # This method hopefully works on those older kernels.
131
+ ip link ls dev "$CONTAINER_IFNAME" && break
132
+ sleep 1
133
+ done > /dev/null 2>&1
91
134
  exit 0
92
135
  }
93
136
 
94
- [ $IFTYPE = bridge ] && [ $BRTYPE = linux ] && [ "$VLAN" ] && {
95
- echo "VLAN configuration currently unsupported for Linux bridge."
96
- exit 1
137
+ [ "$IFTYPE" = bridge ] && [ "$BRTYPE" = linux ] && [ "$VLAN" ] && {
138
+ die 1 "VLAN configuration currently unsupported for Linux bridge."
97
139
  }
98
140
 
99
- [ $IFTYPE = ipoib ] && [ $MACADDR ] && {
100
- echo "MACADDR configuration unsupported for IPoIB interfaces."
101
- exit 1
141
+ [ "$IFTYPE" = ipoib ] && [ "$MACADDR" ] && {
142
+ die 1 "MACADDR configuration unsupported for IPoIB interfaces."
102
143
  }
103
144
 
104
145
  # Second step: find the guest (for now, we only support LXC containers)
105
- while read dev mnt fstype options dump fsck
106
- do
107
- [ "$fstype" != "cgroup" ] && continue
108
- echo $options | grep -qw devices || continue
109
- CGROUPMNT=$mnt
146
+ while read _ mnt fstype options _; do
147
+ [ "$fstype" != "cgroup" ] && continue
148
+ echo "$options" | grep -qw devices || continue
149
+ CGROUPMNT=$mnt
110
150
  done < /proc/mounts
111
151
 
112
152
  [ "$CGROUPMNT" ] || {
113
- echo "Could not locate cgroup mount point."
114
- exit 1
153
+ die 1 "Could not locate cgroup mount point."
115
154
  }
116
155
 
117
156
  # Try to find a cgroup matching exactly the provided name.
118
157
  N=$(find "$CGROUPMNT" -name "$GUESTNAME" | wc -l)
119
158
  case "$N" in
120
- 0)
121
- # If we didn't find anything, try to lookup the container with Docker.
122
- if which docker >/dev/null
123
- then
124
- RETRIES=3
125
- while [ $RETRIES -gt 0 ]; do
126
- DOCKERPID=$(docker inspect --format='{{ .State.Pid }}' $GUESTNAME)
127
- [ $DOCKERPID != 0 ] && break
128
- sleep 1
129
- RETRIES=$((RETRIES - 1))
130
- done
131
-
132
- [ "$DOCKERPID" = 0 ] && {
133
- echo "Docker inspect returned invalid PID 0"
134
- exit 1
135
- }
136
-
137
- [ "$DOCKERPID" = "<no value>" ] && {
138
- echo "Container $GUESTNAME not found, and unknown to Docker."
139
- exit 1
140
- }
141
- else
142
- echo "Container $GUESTNAME not found, and Docker not installed."
143
- exit 1
144
- fi
145
- ;;
146
- 1)
147
- true
148
- ;;
149
- *)
150
- echo "Found more than one container matching $GUESTNAME."
151
- exit 1
152
- ;;
153
- esac
159
+ 0)
160
+ # If we didn't find anything, try to lookup the container with Docker.
161
+ if installed docker; then
162
+ RETRIES=3
163
+ while [ "$RETRIES" -gt 0 ]; do
164
+ DOCKERPID=$(docker inspect --format='{{ .State.Pid }}' "$GUESTNAME")
165
+ [ "$DOCKERPID" != 0 ] && break
166
+ sleep 1
167
+ RETRIES=$((RETRIES - 1))
168
+ done
154
169
 
155
- if [ "$IPADDR" = "dhcp" ]
156
- then
157
- # Check for first available dhcp client
158
- DHCP_CLIENT_LIST="udhcpc dhcpcd dhclient"
159
- for CLIENT in $DHCP_CLIENT_LIST; do
160
- which $CLIENT >/dev/null && {
161
- DHCP_CLIENT=$CLIENT
162
- break
163
- }
164
- done
165
- [ -z $DHCP_CLIENT ] && {
166
- echo "You asked for DHCP; but no DHCP client could be found."
167
- exit 1
168
- }
169
- else
170
- # Check if a subnet mask was provided.
171
- echo $IPADDR | grep -q / || {
172
- echo "The IP address should include a netmask."
173
- echo "Maybe you meant $IPADDR/24 ?"
174
- exit 1
175
- }
176
- # Check if a gateway address was provided.
177
- if echo $IPADDR | grep -q @
178
- then
179
- GATEWAY=$(echo $IPADDR | cut -d@ -f2)
180
- IPADDR=$(echo $IPADDR | cut -d@ -f1)
170
+ [ "$DOCKERPID" = 0 ] && {
171
+ die 1 "Docker inspect returned invalid PID 0"
172
+ }
173
+
174
+ [ "$DOCKERPID" = "<no value>" ] && {
175
+ die 1 "Container $GUESTNAME not found, and unknown to Docker."
176
+ }
181
177
  else
182
- GATEWAY=
178
+ die 1 "Container $GUESTNAME not found, and Docker not installed."
183
179
  fi
180
+ ;;
181
+ 1) true ;;
182
+ *) die 1 "Found more than one container matching $GUESTNAME." ;;
183
+ esac
184
+
185
+ # only check IPADDR if we are not in a route mode
186
+ [ "$IFTYPE" != route ] && {
187
+ case "$IPADDR" in
188
+ # Let's check first if the user asked for DHCP allocation.
189
+ dhcp|dhcp:*)
190
+ # Use Docker-specific strategy to run the DHCP client
191
+ # from the busybox image, in the network namespace of
192
+ # the container.
193
+ if ! [ "$DOCKERPID" ]; then
194
+ warn "You asked for a Docker-specific DHCP method."
195
+ warn "However, $GUESTNAME doesn't seem to be a Docker container."
196
+ warn "Try to replace 'dhcp' with another option?"
197
+ die 1 "Aborting."
198
+ fi
199
+ DHCP_CLIENT=${IPADDR%%:*}
200
+ ;;
201
+ udhcpc|udhcpc:*|udhcpc-f|udhcpc-f:*|dhcpcd|dhcpcd:*|dhclient|dhclient:*|dhclient-f|dhclient-f:*)
202
+ DHCP_CLIENT=${IPADDR%%:*}
203
+ # did they ask for the client to remain?
204
+ DHCP_FOREGROUND=
205
+ [ "${DHCP_CLIENT: -2}" = '-f' ] && {
206
+ DHCP_FOREGROUND=true
207
+ }
208
+ DHCP_CLIENT=${DHCP_CLIENT%-f}
209
+ if ! installed "$DHCP_CLIENT"; then
210
+ die 1 "You asked for DHCP client $DHCP_CLIENT, but I can't find it."
211
+ fi
212
+ ;;
213
+ # Alright, no DHCP? Then let's see if we have a subnet *and* gateway.
214
+ */*@*)
215
+ GATEWAY="${IPADDR#*@}" GATEWAY="${GATEWAY%%@*}"
216
+ IPADDR="${IPADDR%%@*}"
217
+ ;;
218
+ # No gateway? We need at least a subnet, anyway!
219
+ */*) : ;;
220
+ # ... No? Then stop right here.
221
+ *)
222
+ warn "The IP address should include a netmask."
223
+ die 1 "Maybe you meant $IPADDR/24 ?"
224
+ ;;
225
+ esac
226
+ }
227
+
228
+ # If a DHCP method was specified, extract the DHCP options.
229
+ if [ "$DHCP_CLIENT" ]; then
230
+ case "$IPADDR" in
231
+ *:*) DHCP_OPTIONS="${IPADDR#*:}" ;;
232
+ esac
184
233
  fi
185
234
 
186
- if [ $DOCKERPID ]; then
235
+ if [ "$DOCKERPID" ]; then
187
236
  NSPID=$DOCKERPID
188
237
  else
189
- NSPID=$(head -n 1 $(find "$CGROUPMNT" -name "$GUESTNAME" | head -n 1)/tasks)
238
+ NSPID=$(head -n 1 "$(find "$CGROUPMNT" -name "$GUESTNAME" | head -n 1)/tasks")
190
239
  [ "$NSPID" ] || {
191
- echo "Could not find a process inside container $GUESTNAME."
192
- exit 1
240
+ # it is an alternative way to get the pid
241
+ NSPID=$(lxc-info -n "$GUESTNAME" | grep PID | grep -Eo '[0-9]+')
242
+ [ "$NSPID" ] || {
243
+ die 1 "Could not find a process inside container $GUESTNAME."
244
+ }
193
245
  }
194
246
  fi
195
247
 
196
248
  # Check if an incompatible VLAN device already exists
197
- [ $IFTYPE = phys ] && [ "$VLAN" ] && [ -d /sys/class/net/$IFNAME.VLAN ] && {
198
- [ -z "$(ip -d link show $IFNAME.$VLAN | grep "vlan.*id $VLAN")" ] && {
199
- echo "$IFNAME.VLAN already exists but is not a VLAN device for tag $VLAN"
200
- exit 1
201
- }
249
+ [ "$IFTYPE" = phys ] && [ "$VLAN" ] && [ -d "/sys/class/net/$IFNAME.VLAN" ] && {
250
+ ip -d link show "$IFNAME.$VLAN" | grep -q "vlan.*id $VLAN" || {
251
+ die 1 "$IFNAME.VLAN already exists but is not a VLAN device for tag $VLAN"
252
+ }
202
253
  }
203
254
 
204
255
  [ ! -d /var/run/netns ] && mkdir -p /var/run/netns
205
- [ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID
206
- ln -s /proc/$NSPID/ns/net /var/run/netns/$NSPID
256
+ rm -f "/var/run/netns/$NSPID"
257
+ ln -s "/proc/$NSPID/ns/net" "/var/run/netns/$NSPID"
207
258
 
208
259
  # Check if we need to create a bridge.
209
- [ $IFTYPE = bridge ] && [ ! -d /sys/class/net/$IFNAME ] && {
210
- [ $BRTYPE = linux ] && {
211
- (ip link add dev $IFNAME type bridge > /dev/null 2>&1) || (brctl addbr $IFNAME)
212
- ip link set $IFNAME up
213
- }
214
- [ $BRTYPE = openvswitch ] && {
215
- ovs-vsctl add-br $IFNAME
216
- }
260
+ [ "$IFTYPE" = bridge ] && [ ! -d "/sys/class/net/$IFNAME" ] && {
261
+ [ "$BRTYPE" = linux ] && {
262
+ (ip link add dev "$IFNAME" type bridge > /dev/null 2>&1) || (brctl addbr "$IFNAME")
263
+ ip link set "$IFNAME" up
264
+ }
265
+ [ "$BRTYPE" = openvswitch ] && {
266
+ ovs-vsctl add-br "$IFNAME"
267
+ }
217
268
  }
218
269
 
219
- MTU=$(ip link show $IFNAME | awk '{print $5}')
270
+ [ "$IFTYPE" != "route" ] && [ "$IFTYPE" != "dummy" ] && MTU=$(ip link show "$IFNAME" | awk '{print $5}')
271
+
220
272
  # If it's a bridge, we need to create a veth pair
221
- [ $IFTYPE = bridge ] && {
273
+ [ "$IFTYPE" = bridge ] && {
274
+ if [ -z "$LOCAL_IFNAME" ]; then
222
275
  LOCAL_IFNAME="v${CONTAINER_IFNAME}pl${NSPID}"
223
- GUEST_IFNAME="v${CONTAINER_IFNAME}pg${NSPID}"
224
- ip link add name $LOCAL_IFNAME mtu $MTU type veth peer name $GUEST_IFNAME mtu $MTU
225
- case "$BRTYPE" in
226
- linux)
227
- (ip link set $LOCAL_IFNAME master $IFNAME > /dev/null 2>&1) || (brctl addif $IFNAME $LOCAL_IFNAME)
228
- ;;
229
- openvswitch)
230
- ovs-vsctl add-port $IFNAME $LOCAL_IFNAME ${VLAN:+"tag=$VLAN"}
231
- ;;
232
- esac
233
- ip link set $LOCAL_IFNAME up
234
- }
235
-
236
- # Note: if no container interface name was specified, pipework will default to ib0
237
- # Note: no macvlan subinterface or ethernet bridge can be created against an
238
- # ipoib interface. Infiniband is not ethernet. ipoib is an IP layer for it.
239
- # To provide additional ipoib interfaces to containers use SR-IOV and pipework
240
- # to assign them.
241
- [ $IFTYPE = ipoib ] && {
242
- GUEST_IFNAME=$CONTAINER_IFNAME
276
+ fi
277
+ GUEST_IFNAME="v${CONTAINER_IFNAME}pg${NSPID}"
278
+ # Does the link already exist?
279
+ if ip link show "$LOCAL_IFNAME" >/dev/null 2>&1; then
280
+ # link exists, is it in use?
281
+ if ip link show "$LOCAL_IFNAME" up | grep -q "UP"; then
282
+ echo "Link $LOCAL_IFNAME exists and is up"
283
+ exit 1
284
+ fi
285
+ # delete the link so we can re-add it afterwards
286
+ ip link del "$LOCAL_IFNAME"
287
+ fi
288
+ ip link add name "$LOCAL_IFNAME" mtu "$MTU" type veth peer name "$GUEST_IFNAME" mtu "$MTU"
289
+ case "$BRTYPE" in
290
+ linux)
291
+ (ip link set "$LOCAL_IFNAME" master "$IFNAME" > /dev/null 2>&1) || (brctl addif "$IFNAME" "$LOCAL_IFNAME")
292
+ ;;
293
+ openvswitch)
294
+ if ! ovs-vsctl list-ports "$IFNAME" | grep -q "^${LOCAL_IFNAME}$"; then
295
+ ovs-vsctl add-port "$IFNAME" "$LOCAL_IFNAME" ${VLAN:+tag="$VLAN"}
296
+ fi
297
+ ;;
298
+ esac
299
+ ip link set "$LOCAL_IFNAME" up
243
300
  }
244
301
 
245
302
  # If it's a physical interface, create a macvlan subinterface
246
- [ $IFTYPE = phys ] && {
247
- [ "$VLAN" ] && {
248
- [ ! -d /sys/class/net/$IFNAME.$VLAN ] && {
249
- ip link add link $IFNAME name $IFNAME.$VLAN mtu $MTU type vlan id $VLAN
250
- }
251
-
252
- ip link set $IFNAME up
253
- IFNAME=$IFNAME.$VLAN
303
+ [ "$IFTYPE" = phys ] && {
304
+ [ "$VLAN" ] && {
305
+ [ ! -d "/sys/class/net/${IFNAME}.${VLAN}" ] && {
306
+ ip link add link "$IFNAME" name "$IFNAME.$VLAN" mtu "$MTU" type vlan id "$VLAN"
254
307
  }
255
- GUEST_IFNAME=ph$NSPID$CONTAINER_IFNAME
256
- ip link add link $IFNAME dev $GUEST_IFNAME mtu $MTU type macvlan mode bridge
257
- ip link set $IFNAME up
308
+ ip link set "$IFNAME" up
309
+ IFNAME=$IFNAME.$VLAN
310
+ }
311
+ GUEST_IFNAME=ph$NSPID$CONTAINER_IFNAME
312
+ ip link add link "$IFNAME" dev "$GUEST_IFNAME" mtu "$MTU" type macvlan mode bridge
313
+ ip link set "$IFNAME" up
258
314
  }
259
315
 
260
- ip link set $GUEST_IFNAME netns $NSPID
261
- ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME
262
- [ "$MACADDR" ] && ip netns exec $NSPID ip link set dev $CONTAINER_IFNAME address $MACADDR
263
- if [ "$IPADDR" = "dhcp" ]
264
- then
265
- [ $DHCP_CLIENT = "udhcpc" ] && ip netns exec $NSPID $DHCP_CLIENT -qi $CONTAINER_IFNAME -x hostname:$GUESTNAME
266
- if [ $DHCP_CLIENT = "dhclient" ]
267
- then
268
- # kill dhclient after get ip address to prevent device be used after container close
269
- ip netns exec $NSPID $DHCP_CLIENT -pf "/var/run/dhclient.$NSPID.pid" $CONTAINER_IFNAME
270
- kill "$(cat "/var/run/dhclient.$NSPID.pid")"
271
- rm "/var/run/dhclient.$NSPID.pid"
272
- fi
273
- [ $DHCP_CLIENT = "dhcpcd" ] && ip netns exec $NSPID $DHCP_CLIENT -q $CONTAINER_IFNAME -h $GUESTNAME
274
- else
275
- ip netns exec $NSPID ip addr add $IPADDR dev $CONTAINER_IFNAME
276
- [ "$GATEWAY" ] && {
277
- ip netns exec $NSPID ip route delete default >/dev/null 2>&1 && true
278
- }
279
- ip netns exec $NSPID ip link set $CONTAINER_IFNAME up
280
- [ "$GATEWAY" ] && {
281
- ip netns exec $NSPID ip route get $GATEWAY >/dev/null 2>&1 || \
282
- ip netns exec $NSPID ip route add $GATEWAY/32 dev $CONTAINER_IFNAME
283
- ip netns exec $NSPID ip route replace default via $GATEWAY
284
- }
285
- fi
316
+ # If it's an IPoIB interface, create a virtual IPoIB interface (the IPoIB
317
+ # equivalent of a macvlan device)
318
+ #
319
+ # Note: no macvlan subinterface nor Ethernet bridge can be created on top of an
320
+ # IPoIB interface. InfiniBand is not Ethernet. IPoIB is an IP layer on top of
321
+ # InfiniBand, without an intermediate Ethernet layer.
322
+ [ "$IFTYPE" = ipoib ] && {
323
+ GUEST_IFNAME="${IFNAME}.${NSPID}"
286
324
 
287
- # Give our ARP neighbors a nudge about the new interface
288
- if which arping > /dev/null 2>&1
289
- then
290
- IPADDR=$(echo $IPADDR | cut -d/ -f1)
291
- ip netns exec $NSPID arping -c 1 -A -I $CONTAINER_IFNAME $IPADDR > /dev/null 2>&1 || true
292
- else
325
+ # If a partition key is provided, use it
326
+ [ "$PKEY" ] && {
327
+ GUEST_IFNAME="${IFNAME}.${PKEY}.${NSPID}"
328
+ PKEY="pkey 0x$PKEY"
329
+ }
330
+
331
+ ip link add link "$IFNAME" name "$GUEST_IFNAME" type ipoib $PKEY
332
+ ip link set "$IFNAME" up
333
+ }
334
+
335
+ # If its a dummy interface, create a dummy interface.
336
+ [ "$IFTYPE" = dummy ] && {
337
+ GUEST_IFNAME=du$NSPID$CONTAINER_IFNAME
338
+ ip link add dev "$GUEST_IFNAME" type dummy
339
+ }
340
+
341
+ # If the `route` command was specified ...
342
+ if [ "$IFTYPE" = route ]; then
343
+ # ... discard the first two arguments and pass the rest to the route command.
344
+ shift 2
345
+ ip netns exec "$NSPID" ip route "$@"
346
+ else
347
+ # Otherwise, run normally.
348
+ ip link set "$GUEST_IFNAME" netns "$NSPID"
349
+ ip netns exec "$NSPID" ip link set "$GUEST_IFNAME" name "$CONTAINER_IFNAME"
350
+ [ "$MACADDR" ] && ip netns exec "$NSPID" ip link set dev "$CONTAINER_IFNAME" address "$MACADDR"
351
+
352
+ # When using any of the DHCP methods, we start a DHCP client in the
353
+ # network namespace of the container. With the 'dhcp' method, the
354
+ # client used is taken from the Docker busybox image (therefore
355
+ # requiring no specific client installed on the host). Other methods
356
+ # use a locally installed client.
357
+ case "$DHCP_CLIENT" in
358
+ dhcp)
359
+ docker run -d --net container:$GUESTNAME --cap-add NET_ADMIN \
360
+ busybox udhcpc -i "$CONTAINER_IFNAME" -x "hostname:$GUESTNAME" \
361
+ $DHCP_OPTIONS \
362
+ >/dev/null
363
+ ;;
364
+ udhcpc)
365
+ DHCP_Q="-q"
366
+ [ "$DHCP_FOREGROUND" ] && {
367
+ DHCP_OPTIONS="$DHCP_OPTIONS -f"
368
+ }
369
+ ip netns exec "$NSPID" "$DHCP_CLIENT" -qi "$CONTAINER_IFNAME" \
370
+ -x "hostname:$GUESTNAME" \
371
+ -p "/var/run/udhcpc.$GUESTNAME.pid" \
372
+ $DHCP_OPTIONS
373
+ [ ! "$DHCP_FOREGROUND" ] && {
374
+ rm "/var/run/udhcpc.$GUESTNAME.pid"
375
+ }
376
+ ;;
377
+ dhclient)
378
+ ip netns exec "$NSPID" "$DHCP_CLIENT" "$CONTAINER_IFNAME" \
379
+ -pf "/var/run/dhclient.$GUESTNAME.pid" \
380
+ -lf "/etc/dhclient/dhclient.$GUESTNAME.leases" \
381
+ $DHCP_OPTIONS
382
+ # kill dhclient after get ip address to prevent device be used after container close
383
+ [ ! "$DHCP_FOREGROUND" ] && {
384
+ kill "$(cat "/var/run/dhclient.$GUESTNAME.pid")"
385
+ rm "/var/run/dhclient.$GUESTNAME.pid"
386
+ }
387
+ ;;
388
+ dhcpcd)
389
+ ip netns exec "$NSPID" "$DHCP_CLIENT" -q "$CONTAINER_IFNAME" -h "$GUESTNAME"
390
+ ;;
391
+ "")
392
+ if installed ipcalc; then
393
+ eval $(ipcalc -b $IPADDR)
394
+ ip netns exec "$NSPID" ip addr add "$IPADDR" brd "$BROADCAST" dev "$CONTAINER_IFNAME"
395
+ else
396
+ ip netns exec "$NSPID" ip addr add "$IPADDR" dev "$CONTAINER_IFNAME"
397
+ fi
398
+
399
+ [ "$GATEWAY" ] && {
400
+ ip netns exec "$NSPID" ip route delete default >/dev/null 2>&1 && true
401
+ }
402
+ ip netns exec "$NSPID" ip link set "$CONTAINER_IFNAME" up
403
+ [ "$GATEWAY" ] && {
404
+ ip netns exec "$NSPID" ip route get "$GATEWAY" >/dev/null 2>&1 || \
405
+ ip netns exec "$NSPID" ip route add "$GATEWAY/32" dev "$CONTAINER_IFNAME"
406
+ ip netns exec "$NSPID" ip route replace default via "$GATEWAY"
407
+ }
408
+ ;;
409
+ esac
410
+
411
+ # Give our ARP neighbors a nudge about the new interface
412
+ if installed arping; then
413
+ IPADDR=$(echo "$IPADDR" | cut -d/ -f1)
414
+ ip netns exec "$NSPID" arping -c 1 -A -I "$CONTAINER_IFNAME" "$IPADDR" > /dev/null 2>&1 || true
415
+ else
293
416
  echo "Warning: arping not found; interface may not be immediately reachable"
417
+ fi
294
418
  fi
295
-
296
419
  # Remove NSPID to avoid `ip netns` catch it.
297
- [ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID
298
- exit 0
420
+ rm -f "/var/run/netns/$NSPID"
421
+
422
+ # vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab :
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-lxc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Rehm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-24 00:00:00.000000000 Z
11
+ date: 2016-12-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Linux Containers provider for Vagrant
14
14
  email:
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  version: '0'
102
102
  requirements: []
103
103
  rubyforge_project:
104
- rubygems_version: 2.4.1
104
+ rubygems_version: 2.2.2
105
105
  signing_key:
106
106
  specification_version: 4
107
107
  summary: Linux Containers provider for Vagrant