Browse code

cloud-init: Fix network config in cloud-init

Changes include:
1. Enable update_etc_hosts and timezone in cloud cfg file
2. Disable_vmware_customization is set to true in cloud.cfg for now.
This has to be manually set to false if users want cloud-init GOS workflow instead of traditional GOSC workflow.
Setting this to false will default customization workflow to cloud-init instead of traditional GOSC.
By setting this to false we observed that cloud-init service takes more time start if it does not find
a local datasource leading to higher boot time. This is because of a logic in DataSourceOVF where they
set a max time of 90s to search for a local OVF datasource before declaring No configurations found.
https://github.com/cloud-init/cloud-init/blob/496aaa947ec563bd02b3148f220ff0afe1b32abb/cloudinit/sources/DataSourceOVF.py#L119
3. Add manage_etc_hosts in cloud cfg file
4. Fix to add DNS nameservers and DNS search in resolved.conf
5. Logic to create network files and delete the older network files for the same interface.
6. Fix to add DHCP entry in the network file.

NOTE: 99-disable-networking-config.cfg file is packaged as part of cloud-init RPM, this cfg file
prevents cloud-init from configuring network. This has to be removed before starting cloud-init
customiztion and has to be put back to the same folder (/etc/cloud/cloud.cfg.d/) once the cloud-init
workflow is done. Removing this file makes cloud-init to fallback to its default network configuration
on every reboot.

Change-Id: Iedc7eace5921adc460a8ae510d9b7553222aa023
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/7631
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Anish Swaminathan <anishs@vmware.com>

Keerthana K authored on 2019/06/25 15:41:02
Showing 4 changed files
... ...
@@ -21,19 +21,19 @@ diff -rup cloud-init-18.3/cloudinit/sources/helpers/azure.py cloud-init-18.3-new
21 21
  
22 22
  from cloudinit.net import dhcp
23 23
  from cloudinit import stages
24
-@@ -16,9 +17,10 @@ from xml.etree import ElementTree
25
- 
24
+@@ -18,9 +18,10 @@
26 25
  from cloudinit import url_helper
27 26
  from cloudinit import util
27
+ from cloudinit.reporting import events
28 28
 +from io import StringIO
29 29
  
30 30
  LOG = logging.getLogger(__name__)
31 31
 -
32 32
 +NETWORKD_LEASES_DIR = '/run/systemd/netif/leases'
33 33
  
34
- @contextmanager
35
- def cd(newdir):
36
-@@ -281,6 +283,32 @@ class WALinuxAgentShim(object):
34
+ azure_ds_reporter = events.ReportEventStack(
35
+     name="azure-ds",
36
+@@ -332,6 +333,32 @@
37 37
          return dhcp_options
38 38
  
39 39
      @staticmethod
... ...
@@ -63,9 +63,9 @@ diff -rup cloud-init-18.3/cloudinit/sources/helpers/azure.py cloud-init-18.3-new
63 63
 +        return ret
64 64
 +
65 65
 +    @staticmethod
66
+     @azure_ds_telemetry_reporter
66 67
      def _get_value_from_dhcpoptions(dhcp_options):
67 68
          if dhcp_options is None:
68
-             return None
69 69
 @@ -306,8 +334,9 @@ class WALinuxAgentShim(object):
70 70
              # Option-245 stored in /run/cloud-init/dhclient.hooks/<ifc>.json
71 71
              # a dhclient exit hook that calls cloud-init-dhclient-hook
... ...
@@ -1,8 +1,8 @@
1 1
 %define python3_sitelib /usr/lib/python3.7/site-packages
2 2
 
3 3
 Name:           cloud-init
4
-Version:        18.3
5
-Release:        4%{?dist}
4
+Version:        19.1
5
+Release:        1%{?dist}
6 6
 Summary:        Cloud instance init scripts
7 7
 Group:          System Environment/Base
8 8
 License:        GPLv3
... ...
@@ -10,7 +10,7 @@ URL:            http://launchpad.net/cloud-init
10 10
 Vendor:         VMware, Inc
11 11
 Distribution:   Photon
12 12
 Source0:        https://launchpad.net/cloud-init/trunk/%{version}/+download/%{name}-%{version}.tar.gz
13
-%define sha1 cloud-init=a317e2add93578d244328dcf97d46fad1c3140f9
13
+%define sha1 cloud-init=6de398dd755959dde47c8d6f6e255a0857017c44
14 14
 Source1:        cloud-photon.cfg
15 15
 Source2:        99-disable-networking-config.cfg
16 16
 
... ...
@@ -138,15 +138,17 @@ rm -rf $RPM_BUILD_ROOT
138 138
 /lib/systemd/system-generators/cloud-init-generator
139 139
 /lib/udev/rules.d/66-azure-ephemeral.rules
140 140
 /lib/systemd/system/*
141
-/etc/bash_completion.d/cloud-init
142 141
 %{_docdir}/cloud-init/*
143 142
 %{_libdir}/cloud-init/*
144 143
 %{python3_sitelib}/*
145 144
 %{_bindir}/cloud-init*
145
+%{_bindir}/cloud-id
146
+%{_datadir}/bash-completion/completions/cloud-init
146 147
 %dir /var/lib/cloud
147 148
 
148
-
149 149
 %changelog
150
+*   Tue Jun 25 2019 Keerthana K <keerthanak@vmware.com> 19.1-1
151
+-   Upgrade to version 19.1 and fix cloud-init GOS logic.
150 152
 *   Thu Jun 13 2019 Keerthana K <keerthanak@vmware.com> 18.3-4
151 153
 -   Fix to delete the contents of /etc/systemd/network dir at the beginning
152 154
 -   of write_network instead of looping through each NIC and delete the contents
... ...
@@ -53,7 +53,7 @@ cloud_init_modules:
53 53
  - resizefs
54 54
  - set_hostname
55 55
  - update_hostname
56
-# - update_etc_hosts
56
+ - update_etc_hosts
57 57
 # - ca-certs
58 58
 # - rsyslog
59 59
  - users-groups
... ...
@@ -70,7 +70,7 @@ cloud_config_modules:
70 70
 # - set-passwords
71 71
  - package-update-upgrade-install
72 72
 # - landscape
73
-# - timezone
73
+ - timezone
74 74
 # - puppet
75 75
 # - chef
76 76
 # - salt-minion
... ...
@@ -105,3 +105,5 @@ system_info:
105 105
       templates_dir: /etc/cloud/templates/
106 106
 
107 107
    ssh_svcname: sshd
108
+
109
+manage_etc_hosts: true
... ...
@@ -1,7 +1,7 @@
1 1
 diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/cloudinit/distros/photon.py
2
-+++ cloud-init-0.7.9-new/cloudinit/distros/photon.py	2017-05-15 05:13:49.156848344 -0700
3
-@@ -0,0 +1,320 @@
2
+--- cloud-init-0.7.9/cloudinit/distros/photon.py        1969-12-31 16:00:00.000000000 -0800
3
+@@ -0,0 +1,335 @@
4 4
 +# vi: ts=4 expandtab
5 5
 +#
6 6
 +# Copyright (C) 2017 VMware Inc.
... ...
@@ -9,6 +9,7 @@ diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/clo
9 9
 +#
10 10
 +
11 11
 +import os
12
++import fnmatch
12 13
 +
13 14
 +from cloudinit import distros
14 15
 +from cloudinit import helpers
... ...
@@ -16,6 +17,7 @@ diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/clo
16 16
 +from cloudinit import util
17 17
 +from cloudinit.distros import net_util
18 18
 +from cloudinit.distros.parsers.hostname import HostnameConf
19
++from cloudinit.net.network_state import mask_to_net_prefix
19 20
 +
20 21
 +from cloudinit.settings import PER_INSTANCE
21 22
 +
... ...
@@ -57,7 +59,6 @@ diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/clo
57 57
 +        entries = net_util.translate_network(settings)
58 58
 +        LOG.debug("Translated ubuntu style network settings %s into %s",
59 59
 +                  settings, entries)
60
-+        util.delete_dir_contents(self.network_conf_dir)
61 60
 +        route_entries = []
62 61
 +        route_entries = translate_routes(settings)
63 62
 +        dev_names = entries.keys()
... ...
@@ -66,9 +67,17 @@ diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/clo
66 66
 +        searchdomains = []
67 67
 +        # Format for systemd
68 68
 +        for (dev, info) in entries.items():
69
++            if 'dns-nameservers' in info:
70
++                nameservers.extend(info['dns-nameservers'])
71
++            if 'dns-search' in info:
72
++                searchdomains.extend(info['dns-search'])
69 73
 +            if dev == 'lo':
70 74
 +                continue
71
-+            net_fn = self.network_conf_dir + str(dev_index) + '-' + dev + '.network'
75
++            net_fn = network_file_name(self.network_conf_dir, dev)
76
++            if not net_fn:
77
++               net_fn = self.network_conf_dir + str(dev_index) + '-' + dev + '.network'
78
++            else:
79
++                net_fn = self.network_conf_dir + net_fn
72 80
 +            dhcp_enabled = 'no'
73 81
 +            if info.get('bootproto') == 'dhcp':
74 82
 +                dhcp_enabled = 'yes'        
... ...
@@ -81,7 +90,7 @@ diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/clo
81 81
 +            if info.get('address'):
82 82
 +                net_cfg['Address'] = "%s" % (info.get('address'))
83 83
 +                if info.get('netmask'):
84
-+                    net_cfg['Address'] += "/%s" % (info.get('netmask'))
84
++                    net_cfg['Address'] += "/%s" % (mask_to_net_prefix(info.get('netmask')))
85 85
 +            if info.get('gateway'):
86 86
 +                net_cfg['Gateway'] = info.get('gateway')
87 87
 +            if info.get('dns-nameservers'):
... ...
@@ -105,11 +114,6 @@ diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/clo
105 105
 +
106 106
 +            if info.get('auto'):
107 107
 +                self._write_interface_file(net_fn, net_cfg, route_entry)
108
-+            if 'dns-nameservers' in info:
109
-+                nameservers.extend(info['dns-nameservers'])
110
-+            if 'dns-search' in info:
111
-+                searchdomains.extend(info['dns-search'])
112
-+            dev_index = dev_index + 1;
113 108
 +
114 109
 +        resolve_data = []
115 110
 +        new_resolve_data = []
... ...
@@ -146,6 +150,8 @@ diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/clo
146 146
 +                content += "Address=%s\n" % (net_cfg['Address'])
147 147
 +            if 'Gateway' in net_cfg:
148 148
 +                content += "Gateway=%s\n" % (net_cfg['Gateway'])
149
++            if 'DHCP' in net_cfg and net_cfg['DHCP'] == 'no':
150
++                content += "DHCP=%s\n" % (net_cfg['DHCP'])
149 151
 +            route_index = 0
150 152
 +            found = True
151 153
 +            if route_entry:
... ...
@@ -322,3 +328,12 @@ diff -rupN cloud-init-0.7.9/cloudinit/distros/photon.py cloud-init-0.7.9-new/clo
322 322
 +        else:
323 323
 +            out_ifaces[dev_name] = route_info
324 324
 +    return out_ifaces
325
++
326
++def network_file_name(dirname, dev_name):
327
++    network_file_pattern = "*"+dev_name+".network*"
328
++    for node in os.listdir(dirname):
329
++        node_fullpath = os.path.join(dirname, node)
330
++        if fnmatch.fnmatch(node, network_file_pattern):
331
++           util.del_file(node_fullpath)
332
++           return node
333
++    return ""