summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Howard <ben@prongs>2015-07-17 14:24:20 -0600
committerusd-importer <ubuntu-server@lists.ubuntu.com>2015-07-17 21:23:35 +0000
commit0afc048f2a6ff3638ecfa33e7ded5dc8dddf041a (patch)
treebe55edf0ceacac21db4872fe335019fdb8b71623
parent7cb11e70e6c639cefc143e8df243b3e88f5fe232 (diff)
downloadvyos-walinuxagent-0afc048f2a6ff3638ecfa33e7ded5dc8dddf041a.tar.gz
vyos-walinuxagent-0afc048f2a6ff3638ecfa33e7ded5dc8dddf041a.zip
Import patches-unapplied version 2.0.14-0ubuntu1 to ubuntu/wily-proposed
Imported using git-ubuntu import. Changelog parent: 7cb11e70e6c639cefc143e8df243b3e88f5fe232 New changelog entries: * New upstream release. - Rebased patches for 2.0.13 onto 2.0.14. - Fix rdma config - Fix page blob uploading for python 2.6 . Fix http request error handling
-rw-r--r--Changelog5
-rw-r--r--Dockerfile10
-rw-r--r--README22
-rw-r--r--config/docker-waagent.conf75
-rw-r--r--config/waagent.conf12
-rw-r--r--debian/changelog10
-rwxr-xr-xdebian/rules4
-rw-r--r--tests/test_shared_config.py69
-rw-r--r--tests/upload_status_blob.py8
-rw-r--r--waagent223
10 files changed, 370 insertions, 68 deletions
diff --git a/Changelog b/Changelog
index 44788c8..6706892 100644
--- a/Changelog
+++ b/Changelog
@@ -1,5 +1,10 @@
WALinuxAgent Changelog
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+1 Jul 2015, WALinuxAgent 2.0.14
+ . Fix rdma config
+ . Fix page blob uploading for python 2.6
+ . Fix http request error handling
+
1 Jun 2015, WALinuxAgent 2.0.13
. Handle http 410 returned by host
. Add support for http proxy
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..bc917e7
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,10 @@
+FROM debian:jessie
+RUN apt-get update && apt-get upgrade --no-install-recommends -y
+RUN apt-get install -y --no-install-recommends \
+ openssl ca-certificates ssh parted sudo net-tools ifupdown python python-pyasn1 python-rpm
+COPY waagent /usr/sbin/
+COPY config/docker-waagent.conf /etc/waagent.conf
+RUN chmod +x /usr/sbin/waagent && \
+ rm -rf /etc/skel && \
+ ln -sf /dev/stdout /var/log/waagent.log
+ENTRYPOINT ["/usr/sbin/waagent"]
diff --git a/README b/README
index 59fab95..b1c97e5 100644
--- a/README
+++ b/README
@@ -128,6 +128,10 @@ Flags:
-force: Skip interactive confirmation for some commands
+Options:
+
+ -conf=/path/to/file.conf: Specify configuration file to use instead of default one.
+
Commands:
-help: Lists the supported commands and flags.
@@ -203,6 +207,8 @@ ResourceDisk.MountPoint=/mnt/resource
ResourceDisk.EnableSwap=n
ResourceDisk.SwapSizeMB=0
LBProbeResponder=y
+Logs.File=/var/log/waagent.log
+Logs.Console=y
Logs.Verbose=n
OS.RootDeviceScsiTimeout=300
OS.OpensslPath=None
@@ -337,11 +343,23 @@ Type: Boolean Default: y
If set, waagent will respond to load balancer probes from the platform (if
present).
+Logs.File:
+Type: String Default: /dev/stdout
+
+If set, logs are appended to this file (instead of stdout). Bundled
+config (config/waagent.conf) sets this to '/var/log/waagent.log'.
+
+Logs.Console:
+Type: Boolean Default: n
+
+If set, waagent also logs to serial console. Bundled config (config/waagent.conf)
+sets this to 'y'.
+
Logs.Verbose:
Type: Boolean Default: n
-If set, log verbosity is boosted. Waagent logs to /var/log/waagent.log and
-leverages the system logrotate functionality to rotate logs.
+If set, log verbosity is boosted. When waagent logs to file it can
+leverage the system logrotate functionality to rotate logs.
OS.RootDeviceScsiTimeout:
Type: Integer Default: 300
diff --git a/config/docker-waagent.conf b/config/docker-waagent.conf
new file mode 100644
index 0000000..def7231
--- /dev/null
+++ b/config/docker-waagent.conf
@@ -0,0 +1,75 @@
+#
+# Windows Azure Linux Agent Configuration
+#
+
+# Specified program is invoked with the argument "Ready" when we report ready status
+# to the endpoint server.
+Role.StateConsumer=None
+
+# Specified program is invoked with XML file argument specifying role
+# configuration.
+Role.ConfigurationConsumer=None
+
+# Specified program is invoked with XML file argument specifying role topology.
+Role.TopologyConsumer=None
+
+# Enable instance creation
+Provisioning.Enabled=y
+
+# Password authentication for root account will be unavailable.
+Provisioning.DeleteRootPassword=y
+
+# Generate fresh host key pair.
+Provisioning.RegenerateSshHostKeyPair=n
+
+# Supported values are "rsa", "dsa" and "ecdsa".
+Provisioning.SshHostKeyPairType=rsa
+
+# Monitor host name changes and publish changes via DHCP requests.
+Provisioning.MonitorHostName=y
+
+# Decode CustomData from Base64.
+Provisioning.DecodeCustomData=n
+
+# Execute CustomData after provisioning.
+Provisioning.ExecuteCustomData=n
+
+# Format if unformatted. If 'n', resource disk will not be mounted.
+ResourceDisk.Format=y
+
+# File system on the resource disk
+# Typically ext3 or ext4. FreeBSD images should use 'ufs2' here.
+ResourceDisk.Filesystem=ext4
+
+# Mount point for the resource disk
+ResourceDisk.MountPoint=/mnt/resource
+
+# Create and use swapfile on resource disk.
+ResourceDisk.EnableSwap=n
+
+# Size of the swapfile.
+ResourceDisk.SwapSizeMB=0
+
+# Respond to load balancer probes if requested by Windows Azure.
+LBProbeResponder=y
+
+# File to write log to.
+# '/var/log/waagent.log' if not set
+Logs.File=/dev/stdout
+
+# Enable logging to serial console (y|n)
+# When stdout is not enough...
+# 'y' if not set
+Logs.Console=n
+
+# Enable verbose logging (y|n)
+Logs.Verbose=n
+
+# Preferred network interface to communicate with Azure platform
+Network.Interface=eth0
+
+# Root device timeout in seconds.
+OS.RootDeviceScsiTimeout=300
+
+# If "None", the system default version is used.
+OS.OpensslPath=None
diff --git a/config/waagent.conf b/config/waagent.conf
index 756eb4d..97da2b9 100644
--- a/config/waagent.conf
+++ b/config/waagent.conf
@@ -53,9 +53,21 @@ ResourceDisk.SwapSizeMB=0
# Respond to load balancer probes if requested by Windows Azure.
LBProbeResponder=y
+# File to write log to.
+# '/var/log/waagent.log' if not set
+Logs.File=/var/log/waagent.log
+
+# Enable logging to serial console (y|n)
+# When stdout is not enough...
+# 'y' if not set
+Logs.Console=y
+
# Enable verbose logging (y|n)
Logs.Verbose=n
+# Preferred network interface to communicate with Azure platform
+#Network.Interface=eth0
+
# Root device timeout in seconds.
OS.RootDeviceScsiTimeout=300
diff --git a/debian/changelog b/debian/changelog
index fe6d8fb..9c9260d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+walinuxagent (2.0.14-0ubuntu1) wily; urgency=medium
+
+ * New upstream release.
+ - Rebased patches for 2.0.13 onto 2.0.14.
+ - Fix rdma config
+ - Fix page blob uploading for python 2.6
+ . Fix http request error handling
+
+ -- Ben Howard <ben@prongs> Fri, 17 Jul 2015 14:24:20 -0600
+
walinuxagent (2.0.13-0ubuntu2) wily; urgency=medium
* Added missing udev rule for product-uuid.
diff --git a/debian/rules b/debian/rules
index 5358b7e..412afa9 100755
--- a/debian/rules
+++ b/debian/rules
@@ -6,11 +6,13 @@ DEB_VERSION=$(shell dpkg-parsechangelog | sed -rne 's,^Version: ([^-]+).*,\1,p')
ORIG_SRC=https://github.com/WindowsAzure/WALinuxAgent
get-packaged-orig-source:
- git clone --separate-git-dir=.git \
+ git clone --separate-git-dir=walinuxagent.checkout \
$(ORIG_SRC) orig_source
git checkout -b tags/$(DEB_VERSION)
git archive --format=tar.gz WALinuxAgent-$(DEB_VERSION) \
-o walinuxagent_$(DEB_VERSION).orig.tar.gz
+ rm -rf walinuxagent.checkout
+ rm -rf orig_source
%:
dh $@ --with python2,systemd
diff --git a/tests/test_shared_config.py b/tests/test_shared_config.py
index ede2766..8252b3b 100644
--- a/tests/test_shared_config.py
+++ b/tests/test_shared_config.py
@@ -13,6 +13,8 @@
# limitations under the License.
#
+import os
+import re
import unittest
from env import waagent
@@ -24,6 +26,16 @@ class MockDistro(object):
pass
class TestSharedConfig(unittest.TestCase):
+
+ def test_reg(self):
+ mac = "00:15:5D:34:00:08"
+ output = Ifconfig_Out
+ output = output.replace('\n', '')
+ reg = r"(eth\d).*(HWaddr|ether) {0}".format(mac)
+ match = re.search(reg, output, re.IGNORECASE)
+ output = match.group(0)
+ eths = re.findall(r"eth\d", output)
+ self.assertNotEquals(0, len(eths))
def test_parse_shared_config(self):
conf = waagent.SharedConfig().Parse(SharedConfigText)
@@ -34,15 +46,32 @@ class TestSharedConfig(unittest.TestCase):
return conf
def test_config_rdma(self):
- #waagent.LoggerInit("/dev/stdout", "/dev/null", verbose=True)
waagent.MyDistro= MockDistro()
- testDev = "/tmp/hvnd_rdma"
- waagent.SetFileContents(testDev, "")
+ waagent.LibDir="/tmp"
+
+ test_dev = "/tmp/hvnd_rdma"
+ test_dat_conf_files = ["/tmp/dat.conf"]
+ if os.path.isfile("/tmp/rdmaconfiged"):
+ os.remove("/tmp/rdmaconfiged")
+ waagent.SetFileContents(test_dev, "")
+ old = ("ofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 "
+ "dapl.2.0 \"oldip 0\"")
+ waagent.SetFileContents(test_dat_conf_files[0], old)
conf = self.test_parse_shared_config()
- conf.ConfigRdma(dev=testDev)
- rdmaConf = waagent.GetFileContents(testDev)
- self.assertNotEquals(None, rdmaConf)
- self.assertNotEquals("", rdmaConf)
+ handler = waagent.RdmaHandler(conf.RdmaMacAddress, conf.RdmaIPv4Address,
+ test_dev, test_dat_conf_files)
+ handler.set_dat_conf()
+ handler.set_rdma_dev()
+
+ rdma_conf = waagent.GetFileContents(test_dev)
+ self.assertNotEquals(None, rdma_conf)
+ self.assertNotEquals(0, rdma_conf.count(conf.RdmaIPv4Address))
+ self.assertNotEquals(0, rdma_conf.count(conf.RdmaMacAddress))
+
+ dat_conf = waagent.GetFileContents(test_dat_conf_files[0])
+ self.assertNotEquals(None, dat_conf)
+ self.assertNotEquals(0, dat_conf.count(conf.RdmaIPv4Address))
+ self.assertEquals(0, dat_conf.count("oldip"))
SharedConfigText="""\
<?xml version="1.0" encoding="utf-8"?>
@@ -88,6 +117,32 @@ SharedConfigText="""\
</Instances>
</SharedConfig>
"""
+Ifconfig_Out="""\
+eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
+inet 100.74.52.8 netmask 255.255.255.0 broadcast 100.74.52.255
+inet6 fe80::20d:3aff:fe10:672f prefixlen 64 scopeid 0x20<link>
+ether 00:0d:3a:10:67:2f txqueuelen 1000 (Ethernet)
+RX packets 9911 bytes 4451278 (4.2 MiB)
+RX errors 0 dropped 0 overruns 0 frame 0
+TX packets 10505 bytes 1643251 (1.5 MiB)
+TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
+inet6 fe80::215:5dff:fe34:8 prefixlen 64 scopeid 0x20<link>
+ether 00:15:5d:34:00:08 txqueuelen 1000 (Ethernet)
+RX packets 16 bytes 672 (672.0 B)
+RX errors 0 dropped 0 overruns 0 frame 0
+TX packets 16 bytes 2544 (2.4 KiB)
+TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
+inet 127.0.0.1 netmask 255.0.0.0
+inet6 ::1 prefixlen 128 scopeid 0x10<host>
+loop txqueuelen 0 (Local Loopback)
+RX packets 0 bytes 0 (0.0 B)
+RX errors 0 dropped 0 overruns 0 frame 0
+TX packets 0 bytes 0 (0.0 B)
+"""
if __name__ == '__main__':
unittest.main()
diff --git a/tests/upload_status_blob.py b/tests/upload_status_blob.py
index af8c580..59cb732 100644
--- a/tests/upload_status_blob.py
+++ b/tests/upload_status_blob.py
@@ -30,8 +30,14 @@ and defined the following 2 variables like:
"""
from status_blob_url import blockBlobUrl, pageBlobUrl
+class MockConfig(object):
+ def get(self, keyName):
+ return None
+
+waagent.Config = MockConfig()
+
if __name__ == '__main__':
waagent.LoggerInit('/dev/stdout', '/dev/null', verbose=True)
status = "a" * 512
waagent.UploadStatusBlob(blockBlobUrl, status.encode("utf-8"))
- waagent.UploadStatusBlob(pageBlobUrl, status.encode("utf-8"))
+ #waagent.UploadStatusBlob(pageBlobUrl, status.encode("utf-8"))
diff --git a/waagent b/waagent
index dd67353..2b616bf 100644
--- a/waagent
+++ b/waagent
@@ -80,7 +80,7 @@ if not hasattr(subprocess,'check_output'):
GuestAgentName = "WALinuxAgent"
GuestAgentLongName = "Windows Azure Linux Agent"
-GuestAgentVersion = "WALinuxAgent-2.0.13"
+GuestAgentVersion = "WALinuxAgent-2.0.14"
ProtocolVersion = "2012-11-30" #WARNING this value is used to confirm the correct fabric protocol.
Config = None
@@ -624,17 +624,24 @@ class AbstractDistro(object):
ret, output = RunGetOutput("ifconfig -a")
if ret != 0:
raise Exception("Failed to get network interface info")
- match = re.search(r"(eth\d)[^\n]+HWaddr {0}".format(mac), output)
+ output = output.replace('\n', '')
+ match = re.search(r"(eth\d).*(HWaddr|ether) {0}".format(mac),
+ output, re.IGNORECASE)
if match is None:
raise Exception("Failed to get ifname with mac: {0}".format(mac))
- return match.group(1)
+ output = match.group(0)
+ eths = re.findall(r"eth\d", output)
+ if eths is None or len(eths) == 0:
+ raise Exception("Failed to get ifname with mac: {0}".format(mac))
+ return eths[-1]
- def configIpV4(self, ifName, addr):
+ def configIpV4(self, ifName, addr, netmask=24):
ret, output = RunGetOutput("ifconfig {0} up".format(ifName))
if ret != 0:
raise Exception("Failed to bring up {0}: {1}".format(ifName,
output))
- ret, output = RunGetOutput("ifconfig {0} {1}/24".format(ifName, addr))
+ ret, output = RunGetOutput("ifconfig {0} {1}/{2}".format(ifName, addr,
+ netmask))
if ret != 0:
raise Exception("Failed to config ipv4 for {0}: {1}".format(ifName,
output))
@@ -1315,6 +1322,18 @@ class debianDistro(AbstractDistro):
return 0
############################################################
+# KaliDistro - WIP
+# Functioning on Kali 1.1.0a so far
+############################################################
+class KaliDistro(debianDistro):
+ """
+ Kali Distro concrete class
+ Put Kali specific behavior here...
+ """
+ def __init__(self):
+ super(KaliDistro,self).__init__()
+
+############################################################
# UbuntuDistro
############################################################
ubuntu_upstart_file = """\
@@ -2526,18 +2545,22 @@ def GetFirstActiveNetworkInterfaceNonLoopback():
"""
iface=''
expected=16 # how many devices should I expect...
- struct_size=40 # for 64bit the size is 40 bytes
+ is_64bits = sys.maxsize > 2**32
+ struct_size=40 if is_64bits else 32 # for 64bit the size is 40 bytes, for 32bits it is 32 bytes.
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
buff=array.array('B', b'\0' * (expected*struct_size))
retsize=(struct.unpack('iL', fcntl.ioctl(s.fileno(), 0x8912, struct.pack('iL',expected*struct_size,buff.buffer_info()[0]))))[0]
if retsize == (expected*struct_size) :
Warn('SIOCGIFCONF returned more than ' + str(expected) + ' up network interfaces.')
s=buff.tostring()
+ preferred_nic = Config.get("Network.Interface")
for i in range(0,struct_size*expected,struct_size):
iface=s[i:i+16].split(b'\0', 1)[0]
if iface == b'lo':
continue
- else :
+ elif preferred_nic is None:
+ break
+ elif iface == preferred_nic:
break
return iface.decode('latin-1'), socket.inet_ntoa(s[i+20:i+24])
@@ -2722,8 +2745,9 @@ class Util(object):
secure = False
proxyHost, proxyPort = self.GetHttpProxy(secure)
- resp = self._HttpRequest(method, host, path, port, data,
- secure, headers, proxyHost, proxyPort)
+ resp = self._HttpRequest(method, host, path, port=port, data=data,
+ secure=secure, headers=headers,
+ proxyHost=proxyHost, proxyPort=proxyPort)
for retry in range(0, maxRetry):
if resp is not None and \
(resp.status == httplib.OK or \
@@ -2747,31 +2771,38 @@ class Util(object):
Error("HTTP Err: Body={0}".format(resp.read()))
time.sleep(self.__class__.RetryWaitingInterval)
- resp = self._HttpRequest(method, host, path, data, secure,
- headers, proxyHost, proxyPort)
+ resp = self._HttpRequest(method, host, path, port=port, data=data,
+ secure=secure, headers=headers,
+ proxyHost=proxyHost, proxyPort=proxyPort)
return None
def HttpGet(self, url, headers=None, maxRetry=3, chkProxy=False):
- return self.HttpRequest("GET", url, None, headers, maxRetry, chkProxy)
+ return self.HttpRequest("GET", url, headers=headers,
+ maxRetry=maxRetry, chkProxy=chkProxy)
def HttpHead(self, url, headers=None, maxRetry=3, chkProxy=False):
- return self.HttpRequest("HEAD", url, None, headers, maxRetry, chkProxy)
+ return self.HttpRequest("HEAD", url, headers=headers,
+ maxRetry=maxRetry, chkProxy=chkProxy)
def HttpPost(self, url, data, headers=None, maxRetry=3, chkProxy=False):
- return self.HttpRequest("POST", url, data, headers, maxRetry, chkProxy)
+ return self.HttpRequest("POST", url, data=data, headers=headers,
+ maxRetry=maxRetry, chkProxy=chkProxy)
def HttpPut(self, url, data, headers=None, maxRetry=3, chkProxy=False):
- return self.HttpRequest("PUT", url, data, headers, maxRetry, chkProxy)
+ return self.HttpRequest("PUT", url, data=data, headers=headers,
+ maxRetry=maxRetry, chkProxy=chkProxy)
def HttpDelete(self, url, headers=None, maxRetry=3, chkProxy=False):
- return self.HttpRequest("DELETE", url, None, headers, maxRetry, chkProxy)
+ return self.HttpRequest("DELETE", url, headers=headers,
+ maxRetry=maxRetry, chkProxy=chkProxy)
def HttpGetWithoutHeaders(self, url, maxRetry=3, chkProxy=False):
"""
Return data from an HTTP get on 'url'.
"""
- resp = self.HttpGet(url, None, maxRetry, chkProxy)
+ resp = self.HttpGet(url, headers=None, maxRetry=maxRetry,
+ chkProxy=chkProxy)
return resp.read() if resp is not None else None
def HttpGetWithHeaders(self, url, maxRetry=3, chkProxy=False):
@@ -2780,10 +2811,10 @@ class Util(object):
x-ms-agent-name and x-ms-version
headers.
"""
- resp = self.HttpGet(url, {
+ resp = self.HttpGet(url, headers={
"x-ms-agent-name": GuestAgentName,
"x-ms-version": ProtocolVersion
- }, maxRetry, chkProxy)
+ }, maxRetry=maxRetry, chkProxy=chkProxy)
return resp.read() if resp is not None else None
def HttpSecureGetWithHeaders(self, url, transportCert, maxRetry=3,
@@ -2791,21 +2822,22 @@ class Util(object):
"""
Return output of get using ssl cert.
"""
- resp = self.HttpGet(url, {
+ resp = self.HttpGet(url, headers={
"x-ms-agent-name": GuestAgentName,
"x-ms-version": ProtocolVersion,
"x-ms-cipher-name": "DES_EDE3_CBC",
"x-ms-guest-agent-public-x509-cert": transportCert
- }, maxRetry, chkProxy)
+ }, maxRetry=maxRetry, chkProxy=chkProxy)
return resp.read() if resp is not None else None
def HttpPostWithHeaders(self, url, data, maxRetry=3, chkProxy=False):
- header = {
+ headers = {
"x-ms-agent-name": GuestAgentName,
"Content-Type": "text/xml; charset=utf-8",
"x-ms-version": ProtocolVersion
}
- return self.HttpPost(url, data, header, maxRetry, chkProxy)
+ return self.HttpPost(url, data=data, headers=headers,
+ maxRetry=maxRetry, chkProxy=chkProxy)
__StorageVersion="2014-02-14"
@@ -2873,7 +2905,7 @@ def PutPageBlob(url, data):
bufSize = pageEnd - start
buf = bytearray(bufSize)
buf[0 : contentSize] = data[start : end]
- ret = restutil.HttpPut(url, buf, {
+ ret = restutil.HttpPut(url, buffer(buf), {
"x-ms-date" : timestamp,
"x-ms-range" : "bytes={0}-{1}".format(start, pageEnd - 1),
"x-ms-page-write" : "update",
@@ -2956,12 +2988,13 @@ class ConfigurationProvider(object):
"""
Parse amd store key:values in waagent.conf
"""
- def __init__(self):
+ def __init__(self, walaConfigFile):
self.values = dict()
if 'MyDistro' not in globals():
global MyDistro
MyDistro = GetMyDistro()
- walaConfigFile = MyDistro.getConfigurationPath()
+ if walaConfigFile is None:
+ walaConfigFile = MyDistro.getConfigurationPath()
if os.path.isfile(walaConfigFile) == False:
raise Exception("Missing configuration in {0}".format(walaConfigFile))
try:
@@ -3239,35 +3272,6 @@ class SharedConfig(object):
LogIfVerbose("Save SharedConfig.xml")
SetFileContents("SharedConfig.xml", self.xmlText)
- def ConfigRdma(self, dev="/dev/hvnd_rdma", datConf="/etc/dat.conf"):
- if self.RdmaIPv4Address is None or self.RdmaMacAddress is None:
- return
-
- if os.path.isfile(datConf):
- old = ("ofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 "
- "dapl.2.0 \"\S+ 0\"")
- new = ("ofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 "
- "dapl.2.0 \"{0} 0\"").format(self.RdmaIPv4Address)
- lines = GetFileContents(datConf)
- lines = re.sub(old, new, lines)
- SetFileContents(lines)
-
- if os.path.isfile(dev):
- data = ('rdmaMacAddress="{0}" rdmaIPv4Address="{1}"'
- '').format(self.RdmaMacAddress, self.RdmaIPv4Address)
- Log("Write rdma config to {0}: {1}".format(dev, data))
- try:
- with open(dev, "w") as c:
- c.write(data)
- except IOError, e:
- Error("Error writing {0}, {1}".format(dev, e))
-
- try:
- ifName = MyDistro.getInterfaceNameByMac(self.RdmaMacAddress)
- MyDistro.configIpV4(ifName, self.RdmaIPv4Address)
- except Exception as e:
- Error("Failed to config rdma device: {0}".format(e))
-
def InvokeTopologyConsumer(self):
program = Config.get("Role.TopologyConsumer")
if program != None:
@@ -3277,9 +3281,105 @@ class SharedConfig(object):
ErrorWithPrefix('Agent.Run','Exception: '+ str(e) +' occured launching ' + program )
def Process(self):
- self.ConfigRdma()
+ global rdma_configured
+ if not rdma_configured and self.RdmaMacAddress is not None and self.RdmaIPv4Address is not None:
+ handler = RdmaHandler(self.RdmaMacAddress, self.RdmaIPv4Address)
+ handler.start()
+ rdma_configured = True
self.InvokeTopologyConsumer()
+rdma_configured = False
+
+class RdmaError(Exception):
+ pass
+
+class RdmaHandler(object):
+ """
+ Handle rdma configuration.
+ """
+
+ def __init__(self, mac, ip_addr, dev="/dev/hvnd_rdma",
+ dat_conf_files=['/etc/dat.conf', '/etc/rdma/dat.conf',
+ '/usr/local/etc/dat.conf']):
+ self.mac = mac
+ self.ip_addr = ip_addr
+ self.dev = dev
+ self.dat_conf_files = dat_conf_files
+ self.data = ('rdmaMacAddress="{0}" rdmaIPv4Address="{1}"'
+ '').format(self.mac, self.ip_addr)
+
+ def start(self):
+ """
+ Start a new thread to process rdma
+ """
+ threading.Thread(target=self.process).start()
+
+ def process(self):
+ try:
+ self.set_dat_conf()
+ self.set_rdma_dev()
+ self.set_rdma_ip()
+ except RdmaError as e:
+ Error("Failed to config rdma device: {0}".format(e))
+
+ def set_dat_conf(self):
+ """
+ Agent needs to search all possible locations for dat.conf
+ """
+ Log("Set dat.conf")
+ for dat_conf_file in self.dat_conf_files:
+ if not os.path.isfile(dat_conf_file):
+ continue
+ try:
+ self.write_dat_conf(dat_conf_file)
+ except IOError as e:
+ raise RdmaError("Failed to write to dat.conf: {0}".format(e))
+
+ def write_dat_conf(self, dat_conf_file):
+ Log("Write config to {0}".format(dat_conf_file))
+ old = ("ofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 "
+ "dapl.2.0 \"\S+ 0\"")
+ new = ("ofa-v2-ib0 u2.0 nonthreadsafe default libdaplofa.so.2 "
+ "dapl.2.0 \"{0} 0\"").format(self.ip_addr)
+ lines = GetFileContents(dat_conf_file)
+ lines = re.sub(old, new, lines)
+ SetFileContents(dat_conf_file, lines)
+
+ def set_rdma_dev(self):
+ """
+ Write config string to /dev/hvnd_rdma
+ """
+ Log("Set /dev/hvnd_rdma")
+ self.wait_rdma_dev()
+ self.write_rdma_dev_conf()
+
+ def write_rdma_dev_conf(self):
+ Log("Write rdma config to {0}: {1}".format(self.dev, self.data))
+ try:
+ with open(self.dev, "w") as c:
+ c.write(self.data)
+ except IOError, e:
+ raise RdmaError("Error writing {0}, {1}".format(self.dev, e))
+
+ def wait_rdma_dev(self):
+ Log("Wait for /dev/hvnd_rdma")
+ retry = 0
+ while retry < 120:
+ if os.path.exists(self.dev):
+ return
+ time.sleep(1)
+ retry += 1
+ raise RdmaError("The device doesn't show up in 120 seconds")
+
+ def set_rdma_ip(self):
+ Log("Set ip addr for rdma")
+ try:
+ if_name = MyDistro.getInterfaceNameByMac(self.mac)
+ #Azure is using 12 bits network mask for infiniband.
+ MyDistro.configIpV4(if_name, self.ip_addr, 12)
+ except Exception as e:
+ raise RdmaError("Failed to config rdma device: {0}".format(e))
+
class ExtensionsConfig(object):
"""
Parse ExtensionsConfig, downloading and unpacking them to /var/lib/waagent.
@@ -5884,6 +5984,7 @@ def main():
if MyDistro == None :
sys.exit(1)
args = []
+ conf_file = None
global force
force = False
for a in sys.argv[1:]:
@@ -5896,6 +5997,8 @@ def main():
myLogger.verbose = True
elif re.match("^([-/]*)force", a):
force = True
+ elif re.match("^(?:[-/]*)conf=.+", a):
+ conf_file = re.match("^(?:[-/]*)conf=(.+)", a).groups()[0]
elif re.match("^([-/]*)(setup|install)", a):
sys.exit(MyDistro.Install())
elif re.match("^([-/]*)(uninstall)", a):
@@ -5903,8 +6006,14 @@ def main():
else:
args.append(a)
global Config
- Config = ConfigurationProvider()
+ Config = ConfigurationProvider(conf_file)
+ logfile = Config.get("Logs.File")
+ if logfile is not None:
+ myLogger.file_path = logfile
+ logconsole = Config.get("Logs.Console")
+ if logconsole is not None and logconsole.lower().startswith("n"):
+ myLogger.con_path = None
verbose = Config.get("Logs.Verbose")
if verbose != None and verbose.lower().startswith("y"):
myLogger.verbose=True