[Cloud-init-dev] [Merge] lp:~smoser/cloud-init/trunk.smartos-fabric into lp:cloud-init

2016-07-14 Thread Scott Moser
The proposal to merge lp:~smoser/cloud-init/trunk.smartos-fabric into 
lp:cloud-init has been updated.

Commit Message changed to:

SmartOS: more improvements for network configuration

This improves smart os network configuration
 - fix the SocketClient which was previously completely broken.
 - adds support for configuring dns servers and dns search (based off the
   sdc:dns_domain).
 - support 'sdc:gateways' information from the datasource for configuring
   default routes.
 - add converted network information to output when module is run as a main

TODO: add support for sdc:routes as described at 
http://eng.joyent.com/mdata/datadict.html

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/trunk.smartos-fabric/+merge/300115
-- 
Your team cloud init development team is requested to review the proposed merge 
of lp:~smoser/cloud-init/trunk.smartos-fabric into lp:cloud-init.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


[Cloud-init-dev] [Merge] lp:~smoser/cloud-init/trunk.smartos-fabric into lp:cloud-init

2016-07-14 Thread Scott Moser
Scott Moser has proposed merging lp:~smoser/cloud-init/trunk.smartos-fabric 
into lp:cloud-init.

Requested reviews:
  cloud init development team (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/trunk.smartos-fabric/+merge/300115
-- 
Your team cloud init development team is requested to review the proposed merge 
of lp:~smoser/cloud-init/trunk.smartos-fabric into lp:cloud-init.
=== modified file 'cloudinit/sources/DataSourceSmartOS.py'
--- cloudinit/sources/DataSourceSmartOS.py	2016-07-13 22:18:46 +
+++ cloudinit/sources/DataSourceSmartOS.py	2016-07-14 19:15:20 +
@@ -60,11 +60,14 @@
 'availability_zone': ('sdc:datacenter_name', True),
 'vendor-data': ('sdc:vendor-data', False),
 'operator-script': ('sdc:operator-script', False),
+'hostname': ('sdc:hostname', True),
+'dns_domain': ('sdc:dns_domain', True),
 }
 
 SMARTOS_ATTRIB_JSON = {
 # Cloud-init Key : (SmartOS Key known JSON)
 'network-data': 'sdc:nics',
+'dns_servers': 'sdc:resolvers'
 }
 
 SMARTOS_ENV_LX_BRAND = "lx-brand"
@@ -311,7 +314,10 @@
 if self._network_config is None:
 if self.network_data is not None:
 self._network_config = (
-convert_smartos_network_data(self.network_data))
+convert_smartos_network_data(
+network_data=self.network_data,
+dns_servers=self.metadata['dns_servers'],
+dns_domain=self.metadata['dns_domain']))
 return self._network_config
 
 
@@ -445,7 +451,8 @@
 
 
 class JoyentMetadataSocketClient(JoyentMetadataClient):
-def __init__(self, socketpath):
+def __init__(self, socketpath, smartos_type=SMARTOS_ENV_LX_BRAND):
+super(JoyentMetadataSocketClient, self).__init__(smartos_type)
 self.socketpath = socketpath
 
 def open_transport(self):
@@ -461,7 +468,7 @@
 
 
 class JoyentMetadataSerialClient(JoyentMetadataClient):
-def __init__(self, device, timeout=10, smartos_type=None):
+def __init__(self, device, timeout=10, smartos_type=SMARTOS_ENV_KVM):
 super(JoyentMetadataSerialClient, self).__init__(smartos_type)
 self.device = device
 self.timeout = timeout
@@ -583,7 +590,8 @@
 device=serial_device, timeout=serial_timeout,
 smartos_type=smartos_type)
 elif smartos_type == SMARTOS_ENV_LX_BRAND:
-return JoyentMetadataSocketClient(socketpath=metadata_sockfile)
+return JoyentMetadataSocketClient(socketpath=metadata_sockfile,
+  smartos_type=smartos_type)
 
 raise ValueError("Unknown value for smartos_type: %s" % smartos_type)
 
@@ -671,8 +679,9 @@
 return None
 
 
-# Covert SMARTOS 'sdc:nics' data to network_config yaml
-def convert_smartos_network_data(network_data=None):
+# Convert SMARTOS 'sdc:nics' data to network_config yaml
+def convert_smartos_network_data(network_data=None,
+ dns_servers=None, dns_domain=None):
 """Return a dictionary of network_config by parsing provided
SMARTOS sdc:nics configuration data
 
@@ -706,9 +715,7 @@
 'broadcast',
 'dns_nameservers',
 'dns_search',
-'gateway',
 'metric',
-'netmask',
 'pointopoint',
 'routes',
 'scope',
@@ -716,6 +723,29 @@
 ],
 }
 
+if dns_servers:
+if not isinstance(dns_servers, (list, tuple)):
+dns_servers = [dns_servers]
+else:
+dns_servers = []
+
+if dns_domain:
+if not isinstance(dns_domain, (list, tuple)):
+dns_domain = [dns_domain]
+else:
+dns_domain = []
+
+def is_valid_ipv4(addr):
+return '.' in addr
+
+def is_valid_ipv6(addr):
+return ':' in addr
+
+pgws = {
+'ipv4': {'match': is_valid_ipv4, 'gw': None},
+'ipv6': {'match': is_valid_ipv6, 'gw': None},
+}
+
 config = []
 for nic in network_data:
 cfg = dict((k, v) for k, v in nic.items()
@@ -727,18 +757,40 @@
 cfg.update({'mac_address': nic['mac']})
 
 subnets = []
-for ip, gw in zip(nic['ips'], nic['gateways']):
-subnet = dict((k, v) for k, v in nic.items()
-  if k in valid_keys['subnet'])
-subnet.update({
-'type': 'static',
-'address': ip,
-'gateway': gw,
-})
+for ip in nic.get('ips', []):
+if ip == "dhcp":
+subnet = {'type': 'dhcp4'}
+else:
+subnet = dict((k, v) for k, v in nic.items()
+  if k in valid_keys['subnet'])
+subnet.update({
+'type': 'static',
+'address': ip,
+})
+
+proto = 'ipv4' if is_valid_ipv4(ip) else 'ipv6'
+

[Cloud-init-dev] [Merge] lp:~smoser/cloud-init/trunk.net-improve-lo-dns into lp:cloud-init

2016-07-14 Thread noreply
The proposal to merge lp:~smoser/cloud-init/trunk.net-improve-lo-dns into 
lp:cloud-init has been updated.

Status: Needs review => Merged

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/trunk.net-improve-lo-dns/+merge/298035
-- 
Your team cloud init development team is requested to review the proposed merge 
of lp:~smoser/cloud-init/trunk.net-improve-lo-dns into lp:cloud-init.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


Re: [Cloud-init-dev] [Merge] lp:~smoser/cloud-init/trunk.net-improve-lo-dns into lp:cloud-init

2016-07-14 Thread Scott Moser
i added a test of the _write_network fallback in the fix for 1602373 (revno 
1255 on trunk).
and pulled that in here.
going to merge this in now.

-- 
https://code.launchpad.net/~smoser/cloud-init/trunk.net-improve-lo-dns/+merge/298035
Your team cloud init development team is requested to review the proposed merge 
of lp:~smoser/cloud-init/trunk.net-improve-lo-dns into lp:cloud-init.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


[Cloud-init-dev] [Merge] lp:~smoser/cloud-init/trunk.lp1602373 into lp:cloud-init

2016-07-14 Thread noreply
The proposal to merge lp:~smoser/cloud-init/trunk.lp1602373 into lp:cloud-init 
has been updated.

Status: Needs review => Merged

For more details, see:
https://code.launchpad.net/~smoser/cloud-init/trunk.lp1602373/+merge/300021
-- 
Your team cloud init development team is requested to review the proposed merge 
of lp:~smoser/cloud-init/trunk.lp1602373 into lp:cloud-init.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


[Cloud-init-dev] [Merge] lp:~sgolovatiuk/cloud-init/fix_mcollective into lp:cloud-init

2016-07-14 Thread noreply
The proposal to merge lp:~sgolovatiuk/cloud-init/fix_mcollective into 
lp:cloud-init has been updated.

Status: Needs review => Merged

For more details, see:
https://code.launchpad.net/~sgolovatiuk/cloud-init/fix_mcollective/+merge/298759
-- 
Your team cloud init development team is requested to review the proposed merge 
of lp:~sgolovatiuk/cloud-init/fix_mcollective into lp:cloud-init.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


Re: [Cloud-init-dev] [Merge] lp:~bbaude/cloud-init/azure_dhcp into lp:cloud-init

2016-07-14 Thread Scott Moser
update the commit message to address the different behavior (we now write json 
for 1).

is it possible to put cloud-init-dhclient-hook outside of /usr/bin ?
we could put it in /usr/lib/cloud-init and hten just name it 'dhclient-hook' . 
i say this because its not really intende to be used as an executable.

other suggestions in line. 

this is looking good though, thanks Brent and Lars.

Diff comments:

> === added file 'cloudinit/cmd/dhclient_hook.py'
> --- cloudinit/cmd/dhclient_hook.py1970-01-01 00:00:00 +
> +++ cloudinit/cmd/dhclient_hook.py2016-07-13 22:57:56 +
> @@ -0,0 +1,51 @@
> +import os
> +import json
> +from cloudinit import stages
> +from cloudinit import log as logging
> +
> +
> +class LogDhclient():
> +
> +LOG = logging.getLogger(__name__)
> +
> +def __init__(self):
> +self.hooks_dir = self._get_hooks_dir()
> +
> +@staticmethod
> +def _get_hooks_dir():
> +i = stages.Init()
> +return os.path.join(i.paths.get_runpath(), 'dhclient.hooks')
> +
> +def check_hooks_dir(self):
> +if not os.path.exists(self.hooks_dir):
> +os.makedirs(self.hooks_dir)
> +else:
> +hook_files = [os.path.join(self.hooks_dir, x)
> +  for x in os.listdir(self.hooks_dir)]
> +for hook_file in hook_files:
> +os.remove(hook_file)
> +
> +@staticmethod
> +def get_vals(info):
> +new_info = {}
> +for k, v in info.iteritems():
> +if k.startswith("DHCP4_") or k.startswith("new_"):
> +key = (k.replace('DHCP4_', '').replace('new_', '')).lower()
> +new_info[key] = v
> +return new_info
> +
> +def record(self):
> +envs = os.environ
> +ifc_name = envs.get("interface", envs.get("DEVICE_IFACE", None))
> +if ifc_name is None:
> +return
> +ifc_file_name = os.path.join(self.hooks_dir, ifc_name + '.json')
> +with open(ifc_file_name, 'w') as outfile:
> +json.dump(self.get_vals(envs), outfile, indent=4)

return json.dumps(data, indent=1, sort_keys=True,
  separators=(',', ': ')).encode('utf-8')

that is nice and pretty output. ie, please use sort_keys and separators also.

> +self.LOG.debug("Wrote dhclient options in %s", ifc_file_name)
> +
> +
> +def main():
> +record = LogDhclient()
> +record.check_hooks_dir()
> +record.record()
> 
> === modified file 'cloudinit/sources/helpers/azure.py'
> --- cloudinit/sources/helpers/azure.py2016-05-12 20:52:56 +
> +++ cloudinit/sources/helpers/azure.py2016-07-13 22:57:56 +
> @@ -213,15 +228,74 @@
>  return socket.inet_ntoa(packed_bytes)
>  
>  @staticmethod
> -def find_endpoint():
> +def _get_value_from_leases_file(lease_file):
> +leases = []
> +content = util.load_file(lease_file)
> +LOG.debug("content is {}".format(content))
> +for line in content.splitlines():
> +if 'unknown-245' in line:

can you give an example here of what that line looks like ? line.strip(''. 
that is hard to parse in your head.

> +leases.append(line.strip(' ').split(' ', 
> 2)[-1].strip(';\n"'))
> +# Return the "most recent" one in the list
> +if len(leases) < 1:
> +return None
> +else:
> +return leases[-1]
> +
> +@staticmethod
> +def _load_dhclient_json():
> +dhcp_options = {}
> +hooks_dir = WALinuxAgentShim._get_hooks_dir()
> +if not os.path.exists(hooks_dir):
> +LOG.debug("%s not found.", hooks_dir)
> +return None
> +hook_files = [os.path.join(hooks_dir, x)
> +  for x in os.listdir(hooks_dir)]
> +for hook_file in hook_files:
> +try:
> +_file_dict = json.load(open(hook_file))
> +dhcp_options[os.path.basename(
> +hook_file).replace('.json', '')] = _file_dict
> +except ValueError:
> +LOG.info("%s is not valid JSON data", hook_file)

Probably best to raise some exception here so caller can tell the difference 
between "there just wasnt data in the file" and "the file did not exist"

> +return dhcp_options
> +
> +@staticmethod
> +def _get_value_from_dhcpoptions(dhcp_options):
> +if dhcp_options is None:
> +return None
> +# the MS endpoint server is given to us as DHPC option 245
> +_value = None
> +for interface in dhcp_options:
> +_value = dhcp_options[interface].get('unknown_245', None)
> +if _value is not None:
> +break
> +return _value
> +
> +@staticmethod
> +def find_endpoint(lease_file):
>  LOG.debug('Finding Azure endpoint...')
> -content = util.load_file('/var/lib/dhcp/dhclient.eth0.leases')
>  value = None
> -for 

Re: [Cloud-init-dev] [Merge] lp:~smoser/cloud-init/trunk.net-improve-lo-dns into lp:cloud-init

2016-07-14 Thread Ryan Harper
Looks good.  Could we add unittests for distro using apply_network, including 
one without a _write_network so we can test that fallback logic?


Diff comments:

> 
> === modified file 'tests/unittests/test_net.py'
> --- tests/unittests/test_net.py   2016-06-15 23:11:24 +
> +++ tests/unittests/test_net.py   2016-07-14 02:45:33 +
> @@ -323,6 +634,53 @@
>  self.assertEqual(found, self.simple_cfg)
>  
>  
> +class TestEniRoundTrip(TestCase):

Nice!

> +def setUp(self):
> +super(TestCase, self).setUp()
> +self.tmp_dir = tempfile.mkdtemp()
> +self.addCleanup(shutil.rmtree, self.tmp_dir)
> +
> +def _render_and_read(self, network_config=None, state=None, 
> eni_path=None,
> + links_prefix=None, netrules_path=None):
> +if network_config:
> +ns = network_state.parse_net_config_data(network_config)
> +elif state:
> +ns = state
> +else:
> +raise ValueError("Expected data or state, got neither")
> +
> +if eni_path is None:
> +eni_path = 'etc/network/interfaces'
> +
> +renderer = eni.Renderer(
> +config={'eni_path': eni_path, 'links_path_prefix': links_prefix,
> +'netrules_path': netrules_path})
> +
> +renderer.render_network_state(self.tmp_dir, ns)
> +return dir2dict(self.tmp_dir)
> +
> +def testsimple_convert_and_render(self):
> +network_config = eni.convert_eni_data(EXAMPLE_ENI)
> +files = self._render_and_read(network_config=network_config)
> +self.assertEqual(
> +RENDERED_ENI.splitlines(),
> +files['/etc/network/interfaces'].splitlines())
> +
> +def testsimple_render_all(self):
> +entry = NETWORK_CONFIGS['all']
> +files = 
> self._render_and_read(network_config=yaml.load(entry['yaml']))
> +self.assertEqual(
> +entry['expected_eni'].splitlines(),
> +files['/etc/network/interfaces'].splitlines())
> +
> +def testsimple_render_small(self):
> +entry = NETWORK_CONFIGS['small']
> +files = 
> self._render_and_read(network_config=yaml.load(entry['yaml']))
> +self.assertEqual(
> +entry['expected_eni'].splitlines(),
> +files['/etc/network/interfaces'].splitlines())
> +
> +
>  def _gzip_data(data):
>  with io.BytesIO() as iobuf:
>  gzfp = gzip.GzipFile(mode="wb", fileobj=iobuf)


-- 
https://code.launchpad.net/~smoser/cloud-init/trunk.net-improve-lo-dns/+merge/298035
Your team cloud init development team is requested to review the proposed merge 
of lp:~smoser/cloud-init/trunk.net-improve-lo-dns into lp:cloud-init.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


Re: [Cloud-init-dev] [Merge] lp:~smoser/cloud-init/trunk.net-improve-lo-dns into lp:cloud-init

2016-07-14 Thread Ryan Harper
> - use arrays for each 'section' rather than content += . This allows better
>   separation of the sections and also will perform better as long strings
>   with += are slow.


+1 for better separation.  I don't think there is significant difference:

For an 100-line eni (that's rather high for typical usage)

% python3 t.py 
Concat: 7.116918564017396
Array : 7.6817819369607605

% python2 t.py 
Generating data...
Concat: 8.51635122299
Array : 7.93058490753

For a 10-line eni

% python3 t.py 
Generating data...
Concat: 1.0464658139972016
Array : 1.2140009650029242

% python2 t.py 
Generating data...
Concat: 0.956037998199
Array : 1.08836984634

% cat t.py
import timeit

concat = """
c=''
for x in range(0, 100):
c += 'iface eth0 inet static'
"""

append = """
c = []
for x in range(0, 100):
c.append('iface eth0 inet static')
"""

print('Generating data...')
print("Concat: %s" % timeit.timeit(concat))
print("Array : %s" % timeit.timeit(append))

-- 
https://code.launchpad.net/~smoser/cloud-init/trunk.net-improve-lo-dns/+merge/298035
Your team cloud init development team is requested to review the proposed merge 
of lp:~smoser/cloud-init/trunk.net-improve-lo-dns into lp:cloud-init.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


[Cloud-init-dev] [Merge] lp:~swem/cloud-init/cloud-init.target.typo into lp:cloud-init

2016-07-14 Thread Chen-Han Hsiao (Stanley)
Chen-Han Hsiao (Stanley) has proposed merging 
lp:~swem/cloud-init/cloud-init.target.typo into lp:cloud-init.

Requested reviews:
  cloud init development team (cloud-init-dev)

For more details, see:
https://code.launchpad.net/~swem/cloud-init/cloud-init.target.typo/+merge/300048

Fix typo in cloud-init.target.
-- 
Your team cloud init development team is requested to review the proposed merge 
of lp:~swem/cloud-init/cloud-init.target.typo into lp:cloud-init.
=== modified file 'systemd/cloud-init.target'
--- systemd/cloud-init.target	2016-03-03 22:49:10 +
+++ systemd/cloud-init.target	2016-07-14 09:32:35 +
@@ -1,6 +1,6 @@
 # cloud-init target is enabled by cloud-init-generator
 # To disable it you can either:
-#  a.) boot with kernel cmdline of 'cloudinit=disabled'
+#  a.) boot with kernel cmdline of 'cloud-init=disabled'
 #  b.) touch a file /etc/cloud/cloud-init.disabled
 [Unit]
 Description=Cloud-init target

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp