vagrant-lxc 1.2.1 → 1.2.2

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