Browse code

Merge branch 'master' of https://github.com/vmware/photon

archive authored on 2018/01/12 23:30:16
Showing 30 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,114 @@
0
+From 4ebd0c4191c6073cc8a7c5fdcf1d182c4719bcbb Mon Sep 17 00:00:00 2001
1
+From: Aurelien Jarno <aurelien@aurel32.net>
2
+Date: Sat, 30 Dec 2017 10:54:23 +0100
3
+Subject: [PATCH] elf: Check for empty tokens before dynamic string token
4
+ expansion [BZ #22625]
5
+
6
+The fillin_rpath function in elf/dl-load.c loops over each RPATH or
7
+RUNPATH tokens and interprets empty tokens as the current directory
8
+("./"). In practice the check for empty token is done *after* the
9
+dynamic string token expansion. The expansion process can return an
10
+empty string for the $ORIGIN token if __libc_enable_secure is set
11
+or if the path of the binary can not be determined (/proc not mounted).
12
+
13
+Fix that by moving the check for empty tokens before the dynamic string
14
+token expansion. In addition, check for NULL pointer or empty strings
15
+return by expand_dynamic_string_token.
16
+
17
+The above changes highlighted a bug in decompose_rpath, an empty array
18
+is represented by the first element being NULL at the fillin_rpath
19
+level, but by using a -1 pointer in decompose_rpath and other functions.
20
+
21
+Changelog:
22
+	[BZ #22625]
23
+	* elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic
24
+	string token expansion. Check for NULL pointer or empty string possibly
25
+	returned by expand_dynamic_string_token.
26
+	(decompose_rpath): Check for empty path after dynamic string
27
+	token expansion.
28
+(cherry picked from commit 3e3c904daef69b8bf7d5cc07f793c9f07c3553ef)
29
+---
30
+ ChangeLog     | 10 ++++++++++
31
+ NEWS          |  4 ++++
32
+ elf/dl-load.c | 49 +++++++++++++++++++++++++++++++++----------------
33
+ 3 files changed, 47 insertions(+), 16 deletions(-)
34
+
35
+diff --git a/elf/dl-load.c b/elf/dl-load.c
36
+index 50996e2..7397c18 100644
37
+--- a/elf/dl-load.c
38
+@@ -434,31 +434,40 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep,
39
+ {
40
+   char *cp;
41
+   size_t nelems = 0;
42
+-  char *to_free;
43
+ 
44
+   while ((cp = __strsep (&rpath, sep)) != NULL)
45
+     {
46
+       struct r_search_path_elem *dirp;
47
++      char *to_free = NULL;
48
++      size_t len = 0;
49
+ 
50
+-      to_free = cp = expand_dynamic_string_token (l, cp, 1);
51
++      /* `strsep' can pass an empty string.  */
52
++      if (*cp != '\0')
53
++	{
54
++	  to_free = cp = expand_dynamic_string_token (l, cp, 1);
55
+ 
56
+-      size_t len = strlen (cp);
57
++	  /* expand_dynamic_string_token can return NULL in case of empty
58
++	     path or memory allocation failure.  */
59
++	  if (cp == NULL)
60
++	    continue;
61
+ 
62
+-      /* `strsep' can pass an empty string.  This has to be
63
+-	 interpreted as `use the current directory'. */
64
+-      if (len == 0)
65
+-	{
66
+-	  static const char curwd[] = "./";
67
+-	  cp = (char *) curwd;
68
+-	}
69
++	  /* Compute the length after dynamic string token expansion and
70
++	     ignore empty paths.  */
71
++	  len = strlen (cp);
72
++	  if (len == 0)
73
++	    {
74
++	      free (to_free);
75
++	      continue;
76
++	    }
77
+ 
78
+-      /* Remove trailing slashes (except for "/").  */
79
+-      while (len > 1 && cp[len - 1] == '/')
80
+-	--len;
81
++	  /* Remove trailing slashes (except for "/").  */
82
++	  while (len > 1 && cp[len - 1] == '/')
83
++	    --len;
84
+ 
85
+-      /* Now add one if there is none so far.  */
86
+-      if (len > 0 && cp[len - 1] != '/')
87
+-	cp[len++] = '/';
88
++	  /* Now add one if there is none so far.  */
89
++	  if (len > 0 && cp[len - 1] != '/')
90
++	    cp[len++] = '/';
91
++	}
92
+ 
93
+       /* Make sure we don't use untrusted directories if we run SUID.  */
94
+       if (__glibc_unlikely (check_trusted) && !is_trusted_path (cp, len))
95
+@@ -622,6 +631,14 @@ decompose_rpath (struct r_search_path_struct *sps,
96
+      necessary.  */
97
+   free (copy);
98
+ 
99
++  /* There is no path after expansion.  */
100
++  if (result[0] == NULL)
101
++    {
102
++      free (result);
103
++      sps->dirs = (struct r_search_path_elem **) -1;
104
++      return false;
105
++    }
106
++
107
+   sps->dirs = result;
108
+   /* The caller will change this value if we haven't used a real malloc.  */
109
+   sps->malloced = 1;
110
+-- 
111
+2.9.3
112
+
... ...
@@ -4,7 +4,7 @@
4 4
 Summary:        Main C library
5 5
 Name:           glibc
6 6
 Version:        2.26
7
-Release:        8%{?dist}
7
+Release:        9%{?dist}
8 8
 License:        LGPLv2+
9 9
 URL:            http://www.gnu.org/software/libc
10 10
 Group:          Applications/System
... ...
@@ -21,6 +21,7 @@ Patch3:         0002-malloc-arena-fix.patch
21 21
 Patch4:         glibc-fix-CVE-2017-15670.patch
22 22
 Patch5:         glibc-fix-CVE-2017-15804.patch
23 23
 Patch6:         glibc-fix-CVE-2017-17426.patch
24
+Patch7:         glibc-fix-CVE-2017-16997.patch
24 25
 Provides:       rtld(GNU_HASH)
25 26
 Requires:       filesystem
26 27
 %description
... ...
@@ -81,6 +82,7 @@ sed -i 's/\\$$(pwd)/`pwd`/' timezone/Makefile
81 81
 %patch4 -p1
82 82
 %patch5 -p1
83 83
 %patch6 -p1
84
+%patch7 -p1
84 85
 install -vdm 755 %{_builddir}/%{name}-build
85 86
 # do not try to explicitly provide GLIBC_PRIVATE versioned libraries
86 87
 %define __find_provides %{_builddir}/%{name}-%{version}/find_provides.sh
... ...
@@ -285,6 +287,8 @@ grep "^FAIL: nptl/tst-eintr1" tests.sum >/dev/null && n=$((n+1)) ||:
285 285
 
286 286
 
287 287
 %changelog
288
+*   Mon Jan 08 2018 Xiaolin Li <xiaolinl@vmware.com> 2.26-9
289
+-   Fix CVE-2017-16997
288 290
 *   Thu Dec 21 2017 Xiaolin Li <xiaolinl@vmware.com> 2.26-8
289 291
 -   Fix CVE-2017-17426
290 292
 *   Tue Nov 14 2017 Alexey Makhalov <amakhalov@vmware.com> 2.26-7
291 293
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+%{!?python3_sitelib: %define python3_sitelib %(python3 -c "from distutils.sysconfig import get_python_lib;print(get_python_lib())")}
1
+
2
+Name:           meson
3
+Summary:        Extremely fast and user friendly build system
4
+Version:        0.44.0
5
+Release:        1%{?dist}
6
+License:        ASL 2.0
7
+URL:            https://mesonbuild.com/
8
+Vendor:         VMware, Inc.
9
+Distribution:   Photon
10
+Source0:        https://github.com/mesonbuild/meson/archive/%{version}/%{name}-%{version}.tar.gz
11
+%define sha1    meson=4a5aa56f81fc1350a5c501ef6046eef8a13467c7
12
+BuildArch:      noarch
13
+BuildRequires:  gcc
14
+BuildRequires:  python3-devel
15
+BuildRequires:  python3-libs
16
+BuildRequires:  python3-setuptools
17
+BuildRequires:  ninja-build
18
+BuildRequires:  gtest-devel
19
+BuildRequires:  gmock-devel
20
+BuildRequires:  gettext
21
+
22
+Requires:       ninja-build
23
+Requires:       python3
24
+
25
+%description
26
+Meson is an open source build system meant to be both extremely fast, 
27
+and, even more importantly, as user friendly as possible.
28
+The main design point of Meson is that every moment a developer spends 
29
+writing or debugging build definitions is a second wasted. 
30
+So is every second spent waiting for the build system to actually start compiling code.
31
+
32
+%prep
33
+%setup 
34
+
35
+%build
36
+
37
+%install
38
+python3 setup.py install --root=%{buildroot}/
39
+install -Dpm0644 data/macros.%{name} %{buildroot}%{_libdir}/rpm/macros.d/macros.%{name}
40
+
41
+%check
42
+export MESON_PRINT_TEST_OUTPUT=1
43
+python3 ./run_tests.py
44
+
45
+%files
46
+%license COPYING
47
+%{_bindir}/%{name}
48
+%{_bindir}/%{name}conf
49
+%{_bindir}/%{name}introspect
50
+%{_bindir}/%{name}test
51
+%{_bindir}/wraptool
52
+%{python3_sitelib}/mesonbuild
53
+%{python3_sitelib}/%{name}-*.egg-info
54
+%{_mandir}/man1/%{name}.1*
55
+%{_mandir}/man1/%{name}conf.1*
56
+%{_mandir}/man1/%{name}introspect.1*
57
+%{_mandir}/man1/%{name}test.1*
58
+%{_mandir}/man1/wraptool.1*
59
+%{_libdir}/rpm/macros.d/macros.%{name}
60
+
61
+%changelog
62
+*   Wed Dec 27 2017 Anish Swaminathan <anishs@vmware.com> 0.44.0-1
63
+-   Initial packaging
64
+
0 65
new file mode 100644
... ...
@@ -0,0 +1,8 @@
0
+%__ninja %{_bindir}/ninja
1
+%__ninja_common_opts -v %{?_smp_mflags}
2
+%ninja_build \
3
+    %{__ninja} %{__ninja_common_opts}
4
+%ninja_install \
5
+    DESTDIR=%{buildroot} %{__ninja} install %{__ninja_common_opts}
6
+%ninja_test \
7
+    %{__ninja} test %{__ninja_common_opts}
0 8
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+Name:           ninja-build
1
+Summary:        Small build system with focus on speed
2
+Version:        1.8.2
3
+Release:        1%{?dist}
4
+License:        ASL 2.0
5
+URL:            https://ninja-build.org
6
+Vendor:         VMware, Inc.
7
+Distribution:   Photon
8
+Source0:        https://github.com/ninja-build/ninja/archive/%{name}-%{version}.tar.gz
9
+%define sha1    ninja-build=17219deb34dd816363e37470f77ff7231509143a
10
+Source1:        macros.ninja
11
+BuildRequires:  gcc
12
+BuildRequires:  python3-devel
13
+BuildRequires:  gtest-devel
14
+
15
+%description
16
+Ninja is a small build system with a focus on speed. 
17
+It differs from other build systems in two major respects: 
18
+it is designed to have its input files generated by a higher-level build system, 
19
+and it is designed to run builds as fast as possible.
20
+
21
+%prep
22
+%setup -n ninja-%{version}
23
+
24
+%build
25
+python3 configure.py --bootstrap --verbose
26
+./ninja -v all
27
+
28
+%install
29
+install -Dpm0755 ninja -t %{buildroot}%{_bindir}/
30
+install -Dpm0644 misc/bash-completion %{buildroot}%{_datadir}/bash-completion/completions/ninja
31
+ln -s ninja %{buildroot}%{_bindir}/ninja-build
32
+install -Dpm0644 %{SOURCE1} %{buildroot}%{_libdir}/rpm/macros.d/macros.ninja
33
+
34
+%check
35
+./ninja_test --gtest_filter=-SubprocessTest.SetWithLots
36
+
37
+%files
38
+%license COPYING
39
+%doc HACKING.md README
40
+%{_bindir}/ninja
41
+%{_bindir}/ninja-build
42
+%{_datadir}/bash-completion/completions/ninja
43
+%{_libdir}/rpm/macros.d/macros.ninja
44
+
45
+%changelog
46
+*   Wed Dec 27 2017 Anish Swaminathan <anishs@vmware.com> 1.8.2-1
47
+-   Initial packaging
... ...
@@ -1,14 +1,14 @@
1 1
 Summary:        Ruby
2 2
 Name:           ruby
3
-Version:        2.4.2
3
+Version:        2.4.3
4 4
 Release:        1%{?dist}
5 5
 License:        BSDL
6 6
 URL:            https://www.ruby-lang.org/en/
7 7
 Group:          System Environment/Security
8 8
 Vendor:         VMware, Inc.
9 9
 Distribution:   Photon
10
-Source0:        http://cache.ruby-lang.org/pub/ruby/%{name}-%{version}.tar.xz
11
-%define sha1    ruby=8373e32c63bba2180799da091b572664aa9faf6f
10
+Source0:        http://cache.ruby-lang.org/pub/ruby/2.4/%{name}-%{version}.tar.bz2
11
+%define sha1    ruby=3ca96536320b915762d57fe1ee540df6810bf631
12 12
 Patch0:         ruby-CVE-2017-9224.patch
13 13
 Patch1:         ruby-CVE-2017-9226.patch
14 14
 Patch2:         ruby-CVE-2017-9227.patch
... ...
@@ -63,6 +63,8 @@ rm -rf %{buildroot}/*
63 63
 %{_docdir}/%{name}-%{version}
64 64
 %{_mandir}/man1/*
65 65
 %changelog
66
+*   Wed Jan 03 2018 Xiaolin Li <xiaolinl@vmware.com> 2.4.3-1
67
+-   Update to version 2.4.3, fix CVE-2017-17405
66 68
 *   Fri Sep 29 2017 Xiaolin Li <xiaolinl@vmware.com> 2.4.2-1
67 69
 -   Update to version 2.4.2
68 70
 *   Fri Sep 15 2017 Xiaolin Li <xiaolinl@vmware.com> 2.4.1-5
... ...
@@ -1,28 +1,18 @@
1
-diff -Naur a/Makefile.am b/Makefile.am
2
-+++ b/Makefile.am	2016-08-29 13:42:31.472636829 -0700
3
-@@ -309,7 +309,7 @@
4
- 	set -- $(USER_UNIT_ALIASES) && \
5
- 		dir=$(userunitdir) && $(install-relative-aliases)
6
- 	set -- $(GENERAL_ALIASES) && \
7
--		dir= && $(install-relative-aliases)
8
-+		dir= && $(install-general-aliases)
1
+diff -rup systemd-236/units/meson-add-wants.sh systemd-236-new/units/meson-add-wants.sh
2
+--- systemd-236/units/meson-add-wants.sh	2017-12-14 14:09:57.000000000 -0800
3
+@@ -13,8 +13,6 @@ case "$target" in
4
+                 ;;
5
+ esac
9 6
  
10
- define install-aliases
11
- 	while [ -n "$$1" ]; do \
12
-@@ -328,6 +328,15 @@
13
- 		shift 2 || exit $$?; \
14
- 	done
15
- endef
16
-+
17
-+define install-general-aliases
18
-+	while [ -n "$$1" ]; do \
19
-+		$(MKDIR_P) `dirname $(DESTDIR)$$dir/$$2` && \
20
-+		rm -f $(DESTDIR)$$dir/$$2 && \
21
-+		$(LN_S) /usr$$1 $(DESTDIR)$$dir/$$2 && \
22
-+		shift 2 || exit $$?; \
23
-+	done
24
-+endef
7
+-unitpath="${DESTDIR:-}${unitdir}/${unit}"
8
+-
9
+ case "$target" in
10
+         */)
11
+                 mkdir -p -m 0755 "$dir"
12
+@@ -24,4 +22,4 @@ case "$target" in
13
+                 ;;
14
+ esac
25 15
  
26
- install-touch-usr-hook:
27
- 	touch -c $(DESTDIR)/$(prefix)
16
+-ln -vfs --relative "$unitpath" "$dir"
17
++ln -vfs "${unitdir}/${unit}" "$dir"
28 18
deleted file mode 100644
... ...
@@ -1,36 +0,0 @@
1
-From 9f939335a07085aa9a9663efd1dca06ef6405d62 Mon Sep 17 00:00:00 2001
2
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
3
-Date: Wed, 25 Oct 2017 11:19:19 +0200
4
-Subject: [PATCH] resolved: fix loop on packets with pseudo dns types
5
-
6
-Reported by Karim Hossen & Thomas Imbert from Sogeti ESEC R&D.
7
-
8
-https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1725351
9
- src/resolve/resolved-dns-packet.c | 6 +-----
10
- 1 file changed, 1 insertion(+), 5 deletions(-)
11
-
12
-diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
13
-index e2f227bfc6..35f4d0689b 100644
14
-+++ b/src/resolve/resolved-dns-packet.c
15
-@@ -1514,7 +1514,7 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
16
- 
17
-                 found = true;
18
- 
19
--                while (bitmask) {
20
-+                for (; bitmask; bit++, bitmask >>= 1)
21
-                         if (bitmap[i] & bitmask) {
22
-                                 uint16_t n;
23
- 
24
-@@ -1528,10 +1528,6 @@ static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *sta
25
-                                 if (r < 0)
26
-                                         return r;
27
-                         }
28
--
29
--                        bit++;
30
--                        bitmask >>= 1;
31
--                }
32
-         }
33
- 
34
-         if (!found)
35 1
deleted file mode 100644
... ...
@@ -1,305 +0,0 @@
1
-diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
2
-index 6a6dadda2b..49a5c53f96 100644
3
-+++ b/src/core/load-fragment.c
4
-@@ -636,26 +636,36 @@ int config_parse_exec(
5
- 
6
-                 r = unit_full_printf(u, f, &path);
7
-                 if (r < 0) {
8
--                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", f);
9
--                        return 0;
10
-+                        log_syntax(unit, LOG_ERR, filename, line, r,
11
-+                                   "Failed to resolve unit specifiers on %s%s: %m",
12
-+                                   f, ignore ? ", ignoring" : "");
13
-+                        return ignore ? 0 : -ENOEXEC;
14
-                 }
15
- 
16
-                 if (isempty(path)) {
17
-                         /* First word is either "-" or "@" with no command. */
18
--                        log_syntax(unit, LOG_ERR, filename, line, 0, "Empty path in command line, ignoring: \"%s\"", rvalue);
19
--                        return 0;
20
-+                        log_syntax(unit, LOG_ERR, filename, line, 0,
21
-+                                   "Empty path in command line%s: \"%s\"",
22
-+                                   ignore ? ", ignoring" : "", rvalue);
23
-+                        return ignore ? 0 : -ENOEXEC;
24
-                 }
25
-                 if (!string_is_safe(path)) {
26
--                        log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path contains special characters, ignoring: %s", rvalue);
27
--                        return 0;
28
-+                        log_syntax(unit, LOG_ERR, filename, line, 0,
29
-+                                   "Executable path contains special characters%s: %s",
30
-+                                   ignore ? ", ignoring" : "", rvalue);
31
-+                        return ignore ? 0 : -ENOEXEC;
32
-                 }
33
-                 if (!path_is_absolute(path)) {
34
--                        log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path is not absolute, ignoring: %s", rvalue);
35
--                        return 0;
36
-+                        log_syntax(unit, LOG_ERR, filename, line, 0,
37
-+                                   "Executable path is not absolute%s: %s",
38
-+                                   ignore ? ", ignoring" : "", rvalue);
39
-+                        return ignore ? 0 : -ENOEXEC;
40
-                 }
41
-                 if (endswith(path, "/")) {
42
--                        log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path specifies a directory, ignoring: %s", rvalue);
43
--                        return 0;
44
-+                        log_syntax(unit, LOG_ERR, filename, line, 0,
45
-+                                   "Executable path specifies a directory%s: %s",
46
-+                                   ignore ? ", ignoring" : "", rvalue);
47
-+                        return ignore ? 0 : -ENOEXEC;
48
-                 }
49
- 
50
-                 if (!separate_argv0) {
51
-@@ -708,12 +718,14 @@ int config_parse_exec(
52
-                         if (r == 0)
53
-                                 break;
54
-                         if (r < 0)
55
--                                return 0;
56
-+                                return ignore ? 0 : -ENOEXEC;
57
- 
58
-                         r = unit_full_printf(u, word, &resolved);
59
-                         if (r < 0) {
60
--                                log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to resolve unit specifiers on %s, ignoring: %m", word);
61
--                                return 0;
62
-+                                log_syntax(unit, LOG_ERR, filename, line, r,
63
-+                                           "Failed to resolve unit specifiers on %s%s: %m",
64
-+                                           word, ignore ? ", ignoring" : "");
65
-+                                return ignore ? 0 : -ENOEXEC;
66
-                         }
67
- 
68
-                         if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
69
-@@ -724,8 +736,10 @@ int config_parse_exec(
70
-                 }
71
- 
72
-                 if (!n || !n[0]) {
73
--                        log_syntax(unit, LOG_ERR, filename, line, 0, "Empty executable name or zeroeth argument, ignoring: %s", rvalue);
74
--                        return 0;
75
-+                        log_syntax(unit, LOG_ERR, filename, line, 0,
76
-+                                   "Empty executable name or zeroeth argument%s: %s",
77
-+                                   ignore ? ", ignoring" : "", rvalue);
78
-+                        return ignore ? 0 : -ENOEXEC;
79
-                 }
80
- 
81
-                 nce = new0(ExecCommand, 1);
82
-@@ -1332,8 +1346,10 @@ int config_parse_exec_selinux_context(
83
- 
84
-         r = unit_full_printf(u, rvalue, &k);
85
-         if (r < 0) {
86
--                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
87
--                return 0;
88
-+                log_syntax(unit, LOG_ERR, filename, line, r,
89
-+                           "Failed to resolve specifiers%s: %m",
90
-+                           ignore ? ", ignoring" : "");
91
-+                return ignore ? 0 : -ENOEXEC;
92
-         }
93
- 
94
-         free(c->selinux_context);
95
-@@ -1380,8 +1396,10 @@ int config_parse_exec_apparmor_profile(
96
- 
97
-         r = unit_full_printf(u, rvalue, &k);
98
-         if (r < 0) {
99
--                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
100
--                return 0;
101
-+                log_syntax(unit, LOG_ERR, filename, line, r,
102
-+                           "Failed to resolve specifiers%s: %m",
103
-+                           ignore ? ", ignoring" : "");
104
-+                return ignore ? 0 : -ENOEXEC;
105
-         }
106
- 
107
-         free(c->apparmor_profile);
108
-@@ -1428,8 +1446,10 @@ int config_parse_exec_smack_process_label(
109
- 
110
-         r = unit_full_printf(u, rvalue, &k);
111
-         if (r < 0) {
112
--                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
113
--                return 0;
114
-+                log_syntax(unit, LOG_ERR, filename, line, r,
115
-+                           "Failed to resolve specifiers%s: %m",
116
-+                           ignore ? ", ignoring" : "");
117
-+                return ignore ? 0 : -ENOEXEC;
118
-         }
119
- 
120
-         free(c->smack_process_label);
121
-@@ -1647,19 +1667,19 @@ int config_parse_socket_service(
122
- 
123
-         r = unit_name_printf(UNIT(s), rvalue, &p);
124
-         if (r < 0) {
125
--                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
126
--                return 0;
127
-+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers: %s", rvalue);
128
-+                return -ENOEXEC;
129
-         }
130
- 
131
-         if (!endswith(p, ".service")) {
132
--                log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service, ignoring: %s", rvalue);
133
--                return 0;
134
-+                log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service: %s", rvalue);
135
-+                return -ENOEXEC;
136
-         }
137
- 
138
-         r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x);
139
-         if (r < 0) {
140
--                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r));
141
--                return 0;
142
-+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s: %s", rvalue, bus_error_message(&error, r));
143
-+                return -ENOEXEC;
144
-         }
145
- 
146
-         unit_ref_set(&s->service, x);
147
-@@ -1907,13 +1927,13 @@ int config_parse_user_group(
148
- 
149
-                 r = unit_full_printf(u, rvalue, &k);
150
-                 if (r < 0) {
151
--                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
152
--                        return 0;
153
-+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", rvalue);
154
-+                        return -ENOEXEC;
155
-                 }
156
- 
157
-                 if (!valid_user_group_name_or_id(k)) {
158
--                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k);
159
--                        return 0;
160
-+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
161
-+                        return -ENOEXEC;
162
-                 }
163
- 
164
-                 n = k;
165
-@@ -1971,19 +1991,19 @@ int config_parse_user_group_strv(
166
-                 if (r == -ENOMEM)
167
-                         return log_oom();
168
-                 if (r < 0) {
169
--                        log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
170
--                        break;
171
-+                        log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax: %s", rvalue);
172
-+                        return -ENOEXEC;
173
-                 }
174
- 
175
-                 r = unit_full_printf(u, word, &k);
176
-                 if (r < 0) {
177
--                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", word);
178
--                        continue;
179
-+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", word);
180
-+                        return -ENOEXEC;
181
-                 }
182
- 
183
-                 if (!valid_user_group_name_or_id(k)) {
184
--                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k);
185
--                        continue;
186
-+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
187
-+                        return -ENOEXEC;
188
-                 }
189
- 
190
-                 r = strv_push(users, k);
191
-@@ -2142,25 +2162,28 @@ int config_parse_working_directory(
192
- 
193
-                 r = unit_full_printf(u, rvalue, &k);
194
-                 if (r < 0) {
195
--                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in working directory path '%s', ignoring: %m", rvalue);
196
--                        return 0;
197
-+                        log_syntax(unit, LOG_ERR, filename, line, r,
198
-+                                   "Failed to resolve unit specifiers in working directory path '%s'%s: %m",
199
-+                                   rvalue, missing_ok ? ", ignoring" : "");
200
-+                        return missing_ok ? 0 : -ENOEXEC;
201
-                 }
202
- 
203
-                 path_kill_slashes(k);
204
- 
205
-                 if (!utf8_is_valid(k)) {
206
-                         log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
207
--                        return 0;
208
-+                        return missing_ok ? 0 : -ENOEXEC;
209
-                 }
210
- 
211
-                 if (!path_is_absolute(k)) {
212
--                        log_syntax(unit, LOG_ERR, filename, line, 0, "Working directory path '%s' is not absolute, ignoring.", rvalue);
213
--                        return 0;
214
-+                        log_syntax(unit, LOG_ERR, filename, line, 0,
215
-+                                   "Working directory path '%s' is not absolute%s.",
216
-+                                   rvalue, missing_ok ? ", ignoring" : "");
217
-+                        return missing_ok ? 0 : -ENOEXEC;
218
-                 }
219
- 
220
--                free_and_replace(c->working_directory, k);
221
--
222
-                 c->working_directory_home = false;
223
-+                free_and_replace(c->working_directory, k);
224
-         }
225
- 
226
-         c->working_directory_missing_ok = missing_ok;
227
-@@ -4456,8 +4479,11 @@ int unit_load_fragment(Unit *u) {
228
-                         return r;
229
- 
230
-                 r = load_from_path(u, k);
231
--                if (r < 0)
232
-+                if (r < 0) {
233
-+                        if (r == -ENOEXEC)
234
-+                                log_unit_notice(u, "Unit configuration has fatal error, unit will not be started.");
235
-                         return r;
236
-+                }
237
- 
238
-                 if (u->load_state == UNIT_STUB) {
239
-                         SET_FOREACH(t, u->names, i) {
240
-diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
241
-index 12f48bf435..fd797b587e 100644
242
-+++ b/src/test/test-unit-file.c
243
-@@ -146,7 +146,7 @@ static void test_config_parse_exec(void) {
244
-         r = config_parse_exec(NULL, "fake", 4, "section", 1,
245
-                               "LValue", 0, "/RValue/ argv0 r1",
246
-                               &c, u);
247
--        assert_se(r == 0);
248
-+        assert_se(r == -ENOEXEC);
249
-         assert_se(c1->command_next == NULL);
250
- 
251
-         log_info("/* honour_argv0 */");
252
-@@ -161,7 +161,7 @@ static void test_config_parse_exec(void) {
253
-         r = config_parse_exec(NULL, "fake", 3, "section", 1,
254
-                               "LValue", 0, "@/RValue",
255
-                               &c, u);
256
--        assert_se(r == 0);
257
-+        assert_se(r == -ENOEXEC);
258
-         assert_se(c1->command_next == NULL);
259
- 
260
-         log_info("/* no command, whitespace only, reset */");
261
-@@ -220,7 +220,7 @@ static void test_config_parse_exec(void) {
262
-                               "-@/RValue argv0 r1 ; ; "
263
-                               "/goo/goo boo",
264
-                               &c, u);
265
--        assert_se(r >= 0);
266
-+        assert_se(r == -ENOEXEC);
267
-         c1 = c1->command_next;
268
-         check_execcommand(c1, "/RValue", "argv0", "r1", NULL, true);
269
- 
270
-@@ -374,7 +374,7 @@ static void test_config_parse_exec(void) {
271
-                 r = config_parse_exec(NULL, "fake", 4, "section", 1,
272
-                                       "LValue", 0, path,
273
-                                       &c, u);
274
--                assert_se(r == 0);
275
-+                assert_se(r == -ENOEXEC);
276
-                 assert_se(c1->command_next == NULL);
277
-         }
278
- 
279
-@@ -401,21 +401,21 @@ static void test_config_parse_exec(void) {
280
-         r = config_parse_exec(NULL, "fake", 4, "section", 1,
281
-                               "LValue", 0, "/path\\",
282
-                               &c, u);
283
--        assert_se(r == 0);
284
-+        assert_se(r == -ENOEXEC);
285
-         assert_se(c1->command_next == NULL);
286
- 
287
-         log_info("/* missing ending ' */");
288
-         r = config_parse_exec(NULL, "fake", 4, "section", 1,
289
-                               "LValue", 0, "/path 'foo",
290
-                               &c, u);
291
--        assert_se(r == 0);
292
-+        assert_se(r == -ENOEXEC);
293
-         assert_se(c1->command_next == NULL);
294
- 
295
-         log_info("/* missing ending ' with trailing backslash */");
296
-         r = config_parse_exec(NULL, "fake", 4, "section", 1,
297
-                               "LValue", 0, "/path 'foo\\",
298
-                               &c, u);
299
--        assert_se(r == 0);
300
-+        assert_se(r == -ENOEXEC);
301
-         assert_se(c1->command_next == NULL);
302
- 
303
-         log_info("/* invalid space between modifiers */");
304 1
deleted file mode 100644
... ...
@@ -1,100 +0,0 @@
1
-diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
2
-index c43b7885be..5b5a86250e 100644
3
-+++ b/src/core/load-fragment-gperf.gperf.m4
4
-@@ -18,8 +18,8 @@ struct ConfigPerfItem;
5
- m4_dnl Define the context options only once
6
- m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
7
- `$1.WorkingDirectory,            config_parse_working_directory,     0,                             offsetof($1, exec_context)
8
--$1.RootDirectory,                config_parse_unit_path_printf,      0,                             offsetof($1, exec_context.root_directory)
9
--$1.RootImage,                    config_parse_unit_path_printf,      0,                             offsetof($1, exec_context.root_image)
10
-+$1.RootDirectory,                config_parse_unit_path_printf,      true,                          offsetof($1, exec_context.root_directory)
11
-+$1.RootImage,                    config_parse_unit_path_printf,      true,                          offsetof($1, exec_context.root_image)
12
- $1.User,                         config_parse_user_group,            0,                             offsetof($1, exec_context.user)
13
- $1.Group,                        config_parse_user_group,            0,                             offsetof($1, exec_context.group)
14
- $1.SupplementaryGroups,          config_parse_user_group_strv,       0,                             offsetof($1, exec_context.supplementary_groups)
15
-@@ -35,7 +35,7 @@ $1.UMask,                        config_parse_mode,                  0,
16
- $1.Environment,                  config_parse_environ,               0,                             offsetof($1, exec_context.environment)
17
- $1.EnvironmentFile,              config_parse_unit_env_file,         0,                             offsetof($1, exec_context.environment_files)
18
- $1.PassEnvironment,              config_parse_pass_environ,          0,                             offsetof($1, exec_context.pass_environment)
19
--$1.DynamicUser,                  config_parse_bool,                  0,                             offsetof($1, exec_context.dynamic_user)
20
-+$1.DynamicUser,                  config_parse_bool,                  true,                          offsetof($1, exec_context.dynamic_user)
21
- $1.StandardInput,                config_parse_exec_input,            0,                             offsetof($1, exec_context)
22
- $1.StandardOutput,               config_parse_exec_output,           0,                             offsetof($1, exec_context)
23
- $1.StandardError,                config_parse_exec_output,           0,                             offsetof($1, exec_context)
24
-diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
25
-index 49a5c53f96..9d5c39b3dd 100644
26
-+++ b/src/core/load-fragment.c
27
-@@ -242,6 +242,7 @@ int config_parse_unit_path_printf(
28
-         _cleanup_free_ char *k = NULL;
29
-         Unit *u = userdata;
30
-         int r;
31
-+        bool fatal = ltype;
32
- 
33
-         assert(filename);
34
-         assert(lvalue);
35
-@@ -250,8 +251,10 @@ int config_parse_unit_path_printf(
36
- 
37
-         r = unit_full_printf(u, rvalue, &k);
38
-         if (r < 0) {
39
--                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue);
40
--                return 0;
41
-+                log_syntax(unit, LOG_ERR, filename, line, r,
42
-+                           "Failed to resolve unit specifiers on %s%s: %m",
43
-+                           fatal ? "" : ", ignoring", rvalue);
44
-+                return fatal ? -ENOEXEC : 0;
45
-         }
46
- 
47
-         return config_parse_path(unit, filename, line, section, section_line, lvalue, ltype, k, data, userdata);
48
-diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
49
-index 44df7493e2..e08402e3d2 100644
50
-+++ b/src/shared/conf-parser.c
51
-@@ -615,6 +615,7 @@ int config_parse_bool(const char* unit,
52
- 
53
-         int k;
54
-         bool *b = data;
55
-+        bool fatal = ltype;
56
- 
57
-         assert(filename);
58
-         assert(lvalue);
59
-@@ -623,8 +624,10 @@ int config_parse_bool(const char* unit,
60
- 
61
-         k = parse_boolean(rvalue);
62
-         if (k < 0) {
63
--                log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue);
64
--                return 0;
65
-+                log_syntax(unit, LOG_ERR, filename, line, k,
66
-+                           "Failed to parse boolean value%s: %s",
67
-+                           fatal ? "" : ", ignoring", rvalue);
68
-+                return fatal ? -ENOEXEC : 0;
69
-         }
70
- 
71
-         *b = !!k;
72
-@@ -715,6 +718,7 @@ int config_parse_path(
73
-                 void *userdata) {
74
- 
75
-         char **s = data, *n;
76
-+        bool fatal = ltype;
77
- 
78
-         assert(filename);
79
-         assert(lvalue);
80
-@@ -723,12 +727,14 @@ int config_parse_path(
81
- 
82
-         if (!utf8_is_valid(rvalue)) {
83
-                 log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
84
--                return 0;
85
-+                return fatal ? -ENOEXEC : 0;
86
-         }
87
- 
88
-         if (!path_is_absolute(rvalue)) {
89
--                log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", rvalue);
90
--                return 0;
91
-+                log_syntax(unit, LOG_ERR, filename, line, 0,
92
-+                           "Not an absolute path%s: %s",
93
-+                           fatal ? "" : ", ignoring", rvalue);
94
-+                return fatal ? -ENOEXEC : 0;
95
-         }
96
- 
97
-         n = strdup(rvalue);
98 1
deleted file mode 100644
... ...
@@ -1,25 +0,0 @@
1
-From a924f43f30f9c4acaf70618dd2a055f8b0f166be Mon Sep 17 00:00:00 2001
2
-From: Evgeny Vereshchagin <evvers@ya.ru>
3
-Date: Wed, 24 May 2017 08:56:48 +0300
4
-Subject: [PATCH] resolved: bugfix of null pointer p->question dereferencing
5
- (#6020)
6
-
7
-See https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1621396
8
- src/resolve/resolved-dns-packet.c | 3 +++
9
- 1 file changed, 3 insertions(+)
10
-
11
-diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
12
-index 652970284e..240ee448f4 100644
13
-+++ b/src/resolve/resolved-dns-packet.c
14
-@@ -2269,6 +2269,9 @@ int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
15
-         if (r < 0)
16
-                 return r;
17
- 
18
-+        if (!p->question)
19
-+                return 0;
20
-+
21
-         if (p->question->n_keys != 1)
22
-                 return 0;
23
- 
24 1
deleted file mode 100644
... ...
@@ -1,48 +0,0 @@
1
-From 8587c3351003b1613ad2e439cebbb20fbae07e70 Mon Sep 17 00:00:00 2001
2
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek () in waw pl>
3
-Date: Sun, 18 Jun 2017 16:07:57 -0400
4
-Subject: [PATCH 2/2] resolved: simplify alloc size calculation
5
-
6
-The allocation size was calculated in a complicated way, and for values
7
-close to the page size we would actually allocate less than requested.
8
-
9
-Reported by Chris Coulson <chris.coulson () canonical com>.
10
- src/resolve/resolved-dns-packet.c | 8 +-------
11
- src/resolve/resolved-dns-packet.h | 2 --
12
- 2 files changed, 1 insertion(+), 9 deletions(-)
13
-
14
-diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
15
-index 240ee448f4..821b66e266 100644
16
-+++ b/src/resolve/resolved-dns-packet.c
17
-@@ -47,13 +47,7 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
18
- 
19
-         assert(ret);
20
- 
21
--        if (mtu <= UDP_PACKET_HEADER_SIZE)
22
--                a = DNS_PACKET_SIZE_START;
23
--        else
24
--                a = mtu - UDP_PACKET_HEADER_SIZE;
25
--
26
--        if (a < DNS_PACKET_HEADER_SIZE)
27
--                a = DNS_PACKET_HEADER_SIZE;
28
-+        a = MAX(mtu, DNS_PACKET_HEADER_SIZE);
29
- 
30
-         /* round up to next page size */
31
-         a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
32
-diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
33
-index 2c92392e4d..3abcaf8cf3 100644
34
-+++ b/src/resolve/resolved-dns-packet.h
35
-@@ -66,8 +66,6 @@ struct DnsPacketHeader {
36
- /* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */
37
- #define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096
38
- 
39
--#define DNS_PACKET_SIZE_START 512
40
--
41
- struct DnsPacket {
42
-         int n_ref;
43
-         DnsProtocol protocol;
44
-2.13.0
45 1
deleted file mode 100644
... ...
@@ -1,23 +0,0 @@
1
-diff -uNr systemd-233/src/resolve/resolved-conf.c systemd-233-new/src/resolve/resolved-conf.c
2
-+++ systemd-233-new/src/resolve/resolved-conf.c	2017-07-07 03:29:00.130502439 +0000
3
-@@ -229,6 +229,7 @@
4
- 
5
- int manager_parse_config_file(Manager *m) {
6
-         int r;
7
-+        char *default_dns_servers;
8
- 
9
-         assert(m);
10
- 
11
-@@ -241,7 +242,10 @@
12
-                 return r;
13
- 
14
-         if (m->need_builtin_fallbacks) {
15
--                r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
16
-+                default_dns_servers = secure_getenv("DEFAULT_DNS_SERVERS");
17
-+                if (default_dns_servers == NULL)
18
-+                        default_dns_servers = DNS_SERVERS;
19
-+                r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, default_dns_servers);
20
-                 if (r < 0)
21
-                         return r;
22
-         }
23 1
deleted file mode 100644
... ...
@@ -1,39 +0,0 @@
1
-diff -rup systemd-232/src/network/networkd-link.c systemd-232-new/src/network/networkd-link.c
2
-+++ systemd-232-new/src/network/networkd-link.c	2016-11-18 11:19:04.687209642 -0800
3
-@@ -199,6 +199,26 @@ static bool link_proxy_arp_enabled(Link
4
-         return true;
5
- }
6
- 
7
-+static bool link_ipv6_disabled(Link *link) {
8
-+        const char *p = NULL;
9
-+        int r;
10
-+        if (link->flags & IFF_LOOPBACK)
11
-+                return true;
12
-+        /* Make this a NOP if IPv6 is not available */
13
-+        if (!socket_ipv6_is_supported())
14
-+                return true;
15
-+
16
-+        p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/disable_ipv6");
17
-+        _cleanup_free_ char *val = NULL;
18
-+        r = read_one_line_file(p, &val);
19
-+        if (r < 0)
20
-+                log_link_warning_errno(link, r, "Cannot read ipv6 state for interface: %m");
21
-+	if (streq(val, "0"))
22
-+                return false;
23
-+        
24
-+        return true;
25
-+}
26
-+
27
- static bool link_ipv6_accept_ra_enabled(Link *link) {
28
-         assert(link);
29
- 
30
-@@ -720,7 +740,7 @@ void link_check_ready(Link *link) {
31
-                     !link->ipv4ll_route)
32
-                         return;
33
- 
34
--        if (link_ipv6ll_enabled(link))
35
-+        if (!link_ipv6_disabled(link) && link_ipv6ll_enabled(link))
36
-                 if (in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0)
37
-                         return;
38
- 
39 1
deleted file mode 100644
... ...
@@ -1,15 +0,0 @@
1
-diff -uNr systemd-233/src/network/networkd-link.c systemd-233-new/src/network/networkd-link.c
2
-+++ systemd-233-new/src/network/networkd-link.c	2017-11-07 21:02:26.532914705 +0000
3
-@@ -213,8 +213,10 @@
4
-         p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/disable_ipv6");
5
-         _cleanup_free_ char *val = NULL;
6
-         r = read_one_line_file(p, &val);
7
--        if (r < 0)
8
-+        if (r < 0) {
9
-                 log_link_warning_errno(link, r, "Cannot read ipv6 state for interface: %m");
10
-+                return false;
11
-+        }
12
- 	if (streq(val, "0"))
13
-                 return false;
14
-         
15 1
deleted file mode 100644
... ...
@@ -1,1452 +0,0 @@
1
-Backports the following commits from systemd 234:
2
-
3
-ce905cb44620e979862e63743133d354c90d28df icmp6-util: Bind Router Advertisement socket
4
-9dab3e066bb5dfeefa28854ab7f95648eaf0d75d sd-radv: Receive Router Solicitations
5
-d0d6045f658ac3e043235aee68a540650e0f98e0 sd-radv: Send Router Advertisments
6
-dd39628ac19c691917aeeb01babaef411f146039 sd-radv: Implement Router Advertisement timeout handling
7
-938c9ff7d374086b996d6a9a484f88ebd94731a3 sd-radv: Add Router Advertisement functionality
8
-b076a89bb331b91a7cafcd77fb3c13484805b24f sd-radv: Add Router Advertisement prefix handling
9
-1e4a54de3a79a0ba764e482122e381398eaf3e25 icmp6-util: Move multicast address definitions
10
-42a7accc3dec5350f0e88ffa145a55293b6fd0e9 sd-ndisc.c: Move Router Solicitation sending after timer computaion
11
-7b72b034e7c406209dfc55643b79ec0cb2636e4f sd-ndisc: Implement Router Solicitation backoff method
12
-33261358b2a16d895d7beb5b34ebdacadb56cb56 sd-ndisc: Reset counter for sent Router Solicitations (#5874)
13
-b40e6a51d55531314666e866d7f9813fce385023 networkd: RFC compliant autonomous prefix handling (#5636)
14
-
15
- Makefile.am                             |   3 +
16
- src/libsystemd-network/icmp6-util.c     | 117 ++++++++++-
17
- src/libsystemd-network/icmp6-util.h     |  13 ++
18
- src/libsystemd-network/ndisc-internal.h |   7 +-
19
- src/libsystemd-network/radv-internal.h  |  88 +++++++++
20
- src/libsystemd-network/sd-ndisc.c       | 184 ++++++++---------
21
- src/libsystemd-network/sd-radv.c        | 653 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22
- src/libsystemd-network/test-ndisc-rs.c  |  15 ++
23
- src/network/networkd-ndisc.c            |  30 ++-
24
- src/systemd/sd-radv.h                   |  81 ++++++++
25
- 10 files changed, 1086 insertions(+), 105 deletions(-)
26
- create mode 100644 src/libsystemd-network/radv-internal.h
27
- create mode 100644 src/libsystemd-network/sd-radv.c
28
- create mode 100644 src/systemd/sd-radv.h
29
-
30
-diff -rupN systemd-base/Makefile.am systemd/Makefile.am
31
-+++ systemd/Makefile.am	2017-09-18 14:58:25.561666434 -0700
32
-@@ -3629,6 +3629,7 @@ libsystemd_network_la_SOURCES = \
33
- 	src/systemd/sd-ipv4ll.h \
34
- 	src/systemd/sd-ipv4acd.h \
35
- 	src/systemd/sd-ndisc.h \
36
-+	src/systemd/sd-radv.h \
37
- 	src/systemd/sd-dhcp6-client.h \
38
- 	src/systemd/sd-dhcp6-lease.h \
39
- 	src/systemd/sd-lldp.h \
40
-@@ -3652,6 +3653,8 @@ libsystemd_network_la_SOURCES = \
41
- 	src/libsystemd-network/ndisc-internal.h \
42
- 	src/libsystemd-network/ndisc-router.h \
43
- 	src/libsystemd-network/ndisc-router.c \
44
-+	src/libsystemd-network/sd-radv.c \
45
-+	src/libsystemd-network/radv-internal.h \
46
- 	src/libsystemd-network/icmp6-util.h \
47
- 	src/libsystemd-network/icmp6-util.c \
48
- 	src/libsystemd-network/sd-dhcp6-client.c \
49
-diff -rupN systemd-base/src/libsystemd-network/icmp6-util.c systemd/src/libsystemd-network/icmp6-util.c
50
-+++ systemd/src/libsystemd-network/icmp6-util.c	2017-09-18 15:06:31.020575497 -0700
51
-@@ -32,6 +32,7 @@
52
- #include "fd-util.h"
53
- #include "icmp6-util.h"
54
- #include "socket-util.h"
55
-+#include "in-addr-util.h"
56
- 
57
- #define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
58
-         { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
59
-@@ -41,12 +42,9 @@
60
-         { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
61
-               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
62
- 
63
--int icmp6_bind_router_solicitation(int index) {
64
--        struct icmp6_filter filter = { };
65
--        struct ipv6_mreq mreq = {
66
--                .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
67
--                .ipv6mr_interface = index,
68
--        };
69
-+static int icmp6_bind_router_message(const struct icmp6_filter *filter,
70
-+                                     const struct ipv6_mreq *mreq) {
71
-+        int index = mreq->ipv6mr_interface;
72
-         _cleanup_close_ int s = -1;
73
-         char ifname[IF_NAMESIZE] = "";
74
-         static const int zero = 0, one = 1, hops = 255;
75
-@@ -56,9 +54,11 @@ int icmp6_bind_router_solicitation(int i
76
-         if (s < 0)
77
-                 return -errno;
78
- 
79
--        ICMP6_FILTER_SETBLOCKALL(&filter);
80
--        ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
81
--        r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter));
82
-+        r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, filter, sizeof(*filter));
83
-+        if (r < 0)
84
-+                return -errno;
85
-+
86
-+        r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq, sizeof(*mreq));
87
-         if (r < 0)
88
-                 return -errno;
89
- 
90
-@@ -78,7 +78,7 @@ int icmp6_bind_router_solicitation(int i
91
-         if (r < 0)
92
-                 return -errno;
93
- 
94
--        r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
95
-+        r = setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops));
96
-         if (r < 0)
97
-                 return -errno;
98
- 
99
-@@ -102,6 +102,32 @@ int icmp6_bind_router_solicitation(int i
100
-         return r;
101
- }
102
- 
103
-+int icmp6_bind_router_solicitation(int index) {
104
-+        struct icmp6_filter filter = {};
105
-+        struct ipv6_mreq mreq = {
106
-+                .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
107
-+                .ipv6mr_interface = index,
108
-+        };
109
-+
110
-+        ICMP6_FILTER_SETBLOCKALL(&filter);
111
-+        ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
112
-+
113
-+        return icmp6_bind_router_message(&filter, &mreq);
114
-+}
115
-+
116
-+int icmp6_bind_router_advertisement(int index) {
117
-+        struct icmp6_filter filter = {};
118
-+        struct ipv6_mreq mreq = {
119
-+                .ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
120
-+                .ipv6mr_interface = index,
121
-+        };
122
-+
123
-+        ICMP6_FILTER_SETBLOCKALL(&filter);
124
-+        ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
125
-+
126
-+        return icmp6_bind_router_message(&filter, &mreq);
127
-+}
128
-+
129
- int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
130
-         struct sockaddr_in6 dst = {
131
-                 .sin6_family = AF_INET6,
132
-@@ -139,3 +165,74 @@ int icmp6_send_router_solicitation(int s
133
- 
134
-         return 0;
135
- }
136
-+
137
-+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
138
-+                  triple_timestamp *timestamp) {
139
-+        union {
140
-+                struct cmsghdr cmsghdr;
141
-+                uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
142
-+                            CMSG_SPACE(sizeof(struct timeval))];
143
-+        } control = {};
144
-+        struct iovec iov = {};
145
-+        union sockaddr_union sa = {};
146
-+        struct msghdr msg = {
147
-+                .msg_name = &sa.sa,
148
-+                .msg_namelen = sizeof(sa),
149
-+                .msg_iov = &iov,
150
-+                .msg_iovlen = 1,
151
-+                .msg_control = &control,
152
-+                .msg_controllen = sizeof(control),
153
-+        };
154
-+        struct cmsghdr *cmsg;
155
-+        ssize_t len;
156
-+
157
-+        iov.iov_base = buffer;
158
-+        iov.iov_len = size;
159
-+
160
-+        len = recvmsg(fd, &msg, MSG_DONTWAIT);
161
-+        if (len < 0) {
162
-+                if (errno == EAGAIN || errno == EINTR)
163
-+                        return 0;
164
-+
165
-+                return -errno;
166
-+        }
167
-+
168
-+        if ((size_t) len != size)
169
-+                return -EINVAL;
170
-+
171
-+        if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
172
-+            sa.in6.sin6_family == AF_INET6)  {
173
-+
174
-+                *dst = sa.in6.sin6_addr;
175
-+                if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) dst) <= 0)
176
-+                        return -EADDRNOTAVAIL;
177
-+
178
-+        } else if (msg.msg_namelen > 0)
179
-+                return -EPFNOSUPPORT;
180
-+
181
-+        /* namelen == 0 only happens when running the test-suite over a socketpair */
182
-+
183
-+        assert(!(msg.msg_flags & MSG_CTRUNC));
184
-+        assert(!(msg.msg_flags & MSG_TRUNC));
185
-+
186
-+        CMSG_FOREACH(cmsg, &msg) {
187
-+                if (cmsg->cmsg_level == SOL_IPV6 &&
188
-+                    cmsg->cmsg_type == IPV6_HOPLIMIT &&
189
-+                    cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
190
-+                        int hops = *(int*) CMSG_DATA(cmsg);
191
-+
192
-+                        if (hops != 255)
193
-+                                return -EMULTIHOP;
194
-+                }
195
-+
196
-+                if (cmsg->cmsg_level == SOL_SOCKET &&
197
-+                    cmsg->cmsg_type == SO_TIMESTAMP &&
198
-+                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
199
-+                        triple_timestamp_from_realtime(timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
200
-+        }
201
-+
202
-+        if (!triple_timestamp_is_set(timestamp))
203
-+                triple_timestamp_get(timestamp);
204
-+
205
-+        return 0;
206
-+}
207
-diff -rupN systemd-base/src/libsystemd-network/icmp6-util.h systemd/src/libsystemd-network/icmp6-util.h
208
-+++ systemd/src/libsystemd-network/icmp6-util.h	2017-09-18 15:06:31.020575497 -0700
209
-@@ -21,5 +21,18 @@
210
- 
211
- #include <net/ethernet.h>
212
- 
213
-+#include "time-util.h"
214
-+
215
-+#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
216
-+        { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
217
-+              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } }
218
-+
219
-+#define IN6ADDR_ALL_NODES_MULTICAST_INIT \
220
-+        { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
221
-+              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
222
-+
223
- int icmp6_bind_router_solicitation(int index);
224
-+int icmp6_bind_router_advertisement(int index);
225
- int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
226
-+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
227
-+                  triple_timestamp *timestamp);
228
-diff -rupN systemd-base/src/libsystemd-network/ndisc-internal.h systemd/src/libsystemd-network/ndisc-internal.h
229
-+++ systemd/src/libsystemd-network/ndisc-internal.h	2017-09-18 14:55:04.905317356 -0700
230
-@@ -23,6 +23,10 @@
231
- 
232
- #include "sd-ndisc.h"
233
- 
234
-+#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
235
-+#define NDISC_MAX_ROUTER_SOLICITATION_INTERVAL (3600U * USEC_PER_SEC)
236
-+#define NDISC_MAX_ROUTER_SOLICITATIONS 3U
237
-+
238
- struct sd_ndisc {
239
-         unsigned n_ref;
240
- 
241
-@@ -38,8 +42,9 @@ struct sd_ndisc {
242
- 
243
-         sd_event_source *recv_event_source;
244
-         sd_event_source *timeout_event_source;
245
-+        sd_event_source *timeout_no_ra;
246
- 
247
--        unsigned nd_sent;
248
-+        usec_t retransmit_time;
249
- 
250
-         sd_ndisc_callback_t callback;
251
-         void *userdata;
252
-diff -rupN systemd-base/src/libsystemd-network/radv-internal.h systemd/src/libsystemd-network/radv-internal.h
253
-+++ systemd/src/libsystemd-network/radv-internal.h	2017-09-18 15:00:40.022354604 -0700
254
-@@ -0,0 +1,88 @@
255
-+#pragma once
256
-+
257
-+/***
258
-+  This file is part of systemd.
259
-+
260
-+  Copyright (C) 2017 Intel Corporation. All rights reserved.
261
-+
262
-+  systemd is free software; you can redistribute it and/or modify it
263
-+  under the terms of the GNU Lesser General Public License as published by
264
-+  the Free Software Foundation; either version 2.1 of the License, or
265
-+  (at your option) any later version.
266
-+
267
-+  systemd is distributed in the hope that it will be useful, but
268
-+  WITHOUT ANY WARRANTY; without even the implied warranty of
269
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
270
-+  Lesser General Public License for more details.
271
-+
272
-+  You should have received a copy of the GNU Lesser General Public License
273
-+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
274
-+***/
275
-+
276
-+#include "sd-radv.h"
277
-+
278
-+#include "log.h"
279
-+#include "list.h"
280
-+#include "sparse-endian.h"
281
-+
282
-+#define SD_RADV_DEFAULT_MIN_TIMEOUT_USEC        (200*USEC_PER_SEC)
283
-+#define SD_RADV_DEFAULT_MAX_TIMEOUT_USEC        (600*USEC_PER_SEC)
284
-+assert_cc(SD_RADV_DEFAULT_MIN_TIMEOUT_USEC <= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC)
285
-+
286
-+#define SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16*USEC_PER_SEC)
287
-+#define SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS  3
288
-+#define SD_RADV_MAX_FINAL_RTR_ADVERTISEMENTS    3
289
-+#define SD_RADV_MIN_DELAY_BETWEEN_RAS           3
290
-+#define SD_RADV_MAX_RA_DELAY_TIME_USEC          (500*USEC_PER_MSEC)
291
-+
292
-+enum RAdvState {
293
-+        SD_RADV_STATE_IDLE                      = 0,
294
-+        SD_RADV_STATE_ADVERTISING               = 1,
295
-+};
296
-+typedef enum RAdvState RAdvState;
297
-+
298
-+struct sd_radv {
299
-+        unsigned n_ref;
300
-+        RAdvState state;
301
-+
302
-+        int ifindex;
303
-+
304
-+        sd_event *event;
305
-+        int event_priority;
306
-+
307
-+        struct ether_addr mac_addr;
308
-+        uint8_t hop_limit;
309
-+        uint8_t flags;
310
-+        uint32_t mtu;
311
-+        uint16_t lifetime;
312
-+
313
-+        int fd;
314
-+        unsigned ra_sent;
315
-+        sd_event_source *recv_event_source;
316
-+        sd_event_source *timeout_event_source;
317
-+
318
-+        unsigned n_prefixes;
319
-+        LIST_HEAD(sd_radv_prefix, prefixes);
320
-+};
321
-+
322
-+struct sd_radv_prefix {
323
-+        unsigned n_ref;
324
-+
325
-+        struct {
326
-+                uint8_t type;
327
-+                uint8_t length;
328
-+                uint8_t prefixlen;
329
-+                uint8_t flags;
330
-+                be32_t valid_lifetime;
331
-+                be32_t preferred_lifetime;
332
-+                uint32_t reserved;
333
-+                struct in6_addr in6_addr;
334
-+        } _packed_ opt;
335
-+
336
-+        LIST_FIELDS(struct sd_radv_prefix, prefix);
337
-+};
338
-+
339
-+#define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
340
-+#define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__)
341
-+#define log_radv_warning_errno(error, fmt, ...) log_radv_full(LOG_WARNING, error, fmt, ##__VA_ARGS__)
342
-+#define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__)
343
-diff -rupN systemd-base/src/libsystemd-network/sd-ndisc.c systemd/src/libsystemd-network/sd-ndisc.c
344
-+++ systemd/src/libsystemd-network/sd-ndisc.c	2017-09-18 15:00:40.038396204 -0700
345
-@@ -28,12 +28,12 @@
346
- #include "in-addr-util.h"
347
- #include "ndisc-internal.h"
348
- #include "ndisc-router.h"
349
-+#include "random-util.h"
350
- #include "socket-util.h"
351
- #include "string-util.h"
352
- #include "util.h"
353
- 
354
--#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
355
--#define NDISC_MAX_ROUTER_SOLICITATIONS 3U
356
-+#define NDISC_TIMEOUT_NO_RA_USEC (NDISC_ROUTER_SOLICITATION_INTERVAL * NDISC_MAX_ROUTER_SOLICITATIONS)
357
- 
358
- static void ndisc_callback(sd_ndisc *ndisc, sd_ndisc_event event, sd_ndisc_router *rt) {
359
-         assert(ndisc);
360
-@@ -129,6 +129,8 @@ static int ndisc_reset(sd_ndisc *nd) {
361
-         assert(nd);
362
- 
363
-         nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
364
-+        nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
365
-+        nd->retransmit_time = 0;
366
-         nd->recv_event_source = sd_event_source_unref(nd->recv_event_source);
367
-         nd->fd = safe_close(nd->fd);
368
- 
369
-@@ -221,23 +223,9 @@ static int ndisc_handle_datagram(sd_ndis
370
- static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
371
-         _cleanup_(sd_ndisc_router_unrefp) sd_ndisc_router *rt = NULL;
372
-         sd_ndisc *nd = userdata;
373
--        union {
374
--                struct cmsghdr cmsghdr;
375
--                uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
376
--                            CMSG_SPACE(sizeof(struct timeval))];
377
--        } control = {};
378
--        struct iovec iov = {};
379
--        union sockaddr_union sa = {};
380
--        struct msghdr msg = {
381
--                .msg_name = &sa.sa,
382
--                .msg_namelen = sizeof(sa),
383
--                .msg_iov = &iov,
384
--                .msg_iovlen = 1,
385
--                .msg_control = &control,
386
--                .msg_controllen = sizeof(control),
387
--        };
388
--        struct cmsghdr *cmsg;
389
--        ssize_t len, buflen;
390
-+        ssize_t buflen;
391
-+        int r;
392
-+        _cleanup_free_ char *addr = NULL;
393
- 
394
-         assert(s);
395
-         assert(nd);
396
-@@ -251,110 +239,90 @@ static int ndisc_recv(sd_event_source *s
397
-         if (!rt)
398
-                 return -ENOMEM;
399
- 
400
--        iov.iov_base = NDISC_ROUTER_RAW(rt);
401
--        iov.iov_len = rt->raw_size;
402
--
403
--        len = recvmsg(fd, &msg, MSG_DONTWAIT);
404
--        if (len < 0) {
405
--                if (errno == EAGAIN || errno == EINTR)
406
--                        return 0;
407
--
408
--                return log_ndisc_errno(errno, "Could not receive message from ICMPv6 socket: %m");
409
--        }
410
--
411
--        if ((size_t) len != rt->raw_size) {
412
--                log_ndisc("Packet size mismatch.");
413
--                return -EINVAL;
414
--        }
415
--
416
--        if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
417
--            sa.in6.sin6_family == AF_INET6)  {
418
--
419
--                if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr) <= 0) {
420
--                        _cleanup_free_ char *addr = NULL;
421
--
422
--                        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr, &addr);
423
--                        log_ndisc("Received RA from non-link-local address %s. Ignoring.", strna(addr));
424
--                        return 0;
425
--                }
426
--
427
--                rt->address = sa.in6.sin6_addr;
428
--
429
--        } else if (msg.msg_namelen > 0) {
430
--                log_ndisc("Received invalid source address size from ICMPv6 socket: %zu bytes", (size_t) msg.msg_namelen);
431
--                return -EINVAL;
432
--        }
433
--
434
--        /* namelen == 0 only happens when running the test-suite over a socketpair */
435
--
436
--        assert(!(msg.msg_flags & MSG_CTRUNC));
437
--        assert(!(msg.msg_flags & MSG_TRUNC));
438
--
439
--        CMSG_FOREACH(cmsg, &msg) {
440
--                if (cmsg->cmsg_level == SOL_IPV6 &&
441
--                    cmsg->cmsg_type == IPV6_HOPLIMIT &&
442
--                    cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
443
--                        int hops = *(int*) CMSG_DATA(cmsg);
444
--
445
--                        if (hops != 255) {
446
--                                log_ndisc("Received RA with invalid hop limit %d. Ignoring.", hops);
447
--                                return 0;
448
--                        }
449
-+        r = icmp6_receive(fd, NDISC_ROUTER_RAW(rt), rt->raw_size, &rt->address,
450
-+                     &rt->timestamp);
451
-+        if (r < 0) {
452
-+                switch (r) {
453
-+                case -EADDRNOTAVAIL:
454
-+                        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &rt->address, &addr);
455
-+                        log_ndisc("Received RA from non-link-local address %s. Ignoring", addr);
456
-+                        break;
457
-+
458
-+                case -EMULTIHOP:
459
-+                        log_ndisc("Received RA with invalid hop limit. Ignoring.");
460
-+                        break;
461
-+
462
-+                case -EPFNOSUPPORT:
463
-+                        log_ndisc("Received invalid source address from ICMPv6 socket.");
464
-+                        break;
465
-                 }
466
- 
467
--                if (cmsg->cmsg_level == SOL_SOCKET &&
468
--                    cmsg->cmsg_type == SO_TIMESTAMP &&
469
--                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
470
--                        triple_timestamp_from_realtime(&rt->timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
471
-+                return 0;
472
-         }
473
- 
474
--        if (!triple_timestamp_is_set(&rt->timestamp))
475
--                triple_timestamp_get(&rt->timestamp);
476
--
477
-         nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
478
- 
479
-         return ndisc_handle_datagram(nd, rt);
480
- }
481
- 
482
-+static usec_t ndisc_timeout_compute_random(usec_t val) {
483
-+        /* compute a time that is random within ±10% of the given value */
484
-+        return val - val / 10 +
485
-+                (random_u64() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
486
-+}
487
-+
488
- static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
489
-         sd_ndisc *nd = userdata;
490
--        usec_t time_now, next_timeout;
491
-+        usec_t time_now;
492
-         int r;
493
-+        char time_string[FORMAT_TIMESPAN_MAX];
494
- 
495
-         assert(s);
496
-         assert(nd);
497
-         assert(nd->event);
498
- 
499
--        if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) {
500
--                nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
501
--                ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
502
--                return 0;
503
-+        assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
504
-+
505
-+        nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
506
-+
507
-+        if (!nd->retransmit_time)
508
-+                nd->retransmit_time = ndisc_timeout_compute_random(NDISC_ROUTER_SOLICITATION_INTERVAL);
509
-+        else {
510
-+                if (nd->retransmit_time > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 2)
511
-+                        nd->retransmit_time = ndisc_timeout_compute_random(NDISC_MAX_ROUTER_SOLICITATION_INTERVAL);
512
-+                else
513
-+                        nd->retransmit_time += ndisc_timeout_compute_random(nd->retransmit_time);
514
-         }
515
- 
516
--        r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
517
--        if (r < 0) {
518
--                log_ndisc_errno(r, "Error sending Router Solicitation: %m");
519
-+        r = sd_event_add_time(nd->event, &nd->timeout_event_source,
520
-+                              clock_boottime_or_monotonic(),
521
-+                              time_now + nd->retransmit_time,
522
-+                              10 * USEC_PER_MSEC, ndisc_timeout, nd);
523
-+        if (r < 0)
524
-                 goto fail;
525
--        }
526
- 
527
--        log_ndisc("Sent Router Solicitation");
528
--        nd->nd_sent++;
529
-+        r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority);
530
-+        if (r < 0)
531
-+                goto fail;
532
- 
533
--        assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
534
--        next_timeout = time_now + NDISC_ROUTER_SOLICITATION_INTERVAL;
535
-+        (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout-no-ra");
536
- 
537
--        r = sd_event_source_set_time(nd->timeout_event_source, next_timeout);
538
-+        r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT);
539
-         if (r < 0) {
540
--                log_ndisc_errno(r, "Error updating timer: %m");
541
-+                log_ndisc_errno(r, "Error reenabling timer: %m");
542
-                 goto fail;
543
-         }
544
- 
545
--        r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT);
546
-+        r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
547
-         if (r < 0) {
548
--                log_ndisc_errno(r, "Error reenabling timer: %m");
549
-+                log_ndisc_errno(r, "Error sending Router Solicitation: %m");
550
-                 goto fail;
551
-         }
552
- 
553
-+        log_ndisc("Sent Router Solicitation, next solicitation in %s",
554
-+                  format_timespan(time_string, FORMAT_TIMESPAN_MAX,
555
-+                                  nd->retransmit_time, USEC_PER_SEC));
556
-+
557
-         return 0;
558
- 
559
- fail:
560
-@@ -362,6 +330,20 @@ fail:
561
-         return 0;
562
- }
563
- 
564
-+static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata) {
565
-+        sd_ndisc *nd = userdata;
566
-+
567
-+        assert(s);
568
-+        assert(nd);
569
-+
570
-+        log_ndisc("No RA received before link confirmation timeout");
571
-+
572
-+        nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
573
-+        ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
574
-+
575
-+        return 0;
576
-+}
577
-+
578
- _public_ int sd_ndisc_stop(sd_ndisc *nd) {
579
-         assert_return(nd, -EINVAL);
580
- 
581
-@@ -376,6 +358,7 @@ _public_ int sd_ndisc_stop(sd_ndisc *nd)
582
- 
583
- _public_ int sd_ndisc_start(sd_ndisc *nd) {
584
-         int r;
585
-+        usec_t time_now;
586
- 
587
-         assert_return(nd, -EINVAL);
588
-         assert_return(nd->event, -EINVAL);
589
-@@ -387,6 +370,10 @@ _public_ int sd_ndisc_start(sd_ndisc *nd
590
-         assert(!nd->recv_event_source);
591
-         assert(!nd->timeout_event_source);
592
- 
593
-+        r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
594
-+        if (r < 0)
595
-+                goto fail;
596
-+
597
-         nd->fd = icmp6_bind_router_solicitation(nd->ifindex);
598
-         if (nd->fd < 0)
599
-                 return nd->fd;
600
-@@ -411,6 +398,19 @@ _public_ int sd_ndisc_start(sd_ndisc *nd
601
- 
602
-         (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout");
603
- 
604
-+        r = sd_event_add_time(nd->event, &nd->timeout_no_ra,
605
-+                              clock_boottime_or_monotonic(),
606
-+                              time_now + NDISC_TIMEOUT_NO_RA_USEC,
607
-+                              10 * USEC_PER_MSEC, ndisc_timeout_no_ra, nd);
608
-+        if (r < 0)
609
-+                goto fail;
610
-+
611
-+        r = sd_event_source_set_priority(nd->timeout_no_ra, nd->event_priority);
612
-+        if (r < 0)
613
-+                goto fail;
614
-+
615
-+        (void) sd_event_source_set_description(nd->timeout_no_ra, "ndisc-timeout-no-ra");
616
-+
617
-         log_ndisc("Started IPv6 Router Solicitation client");
618
-         return 1;
619
- 
620
-diff -rupN systemd-base/src/libsystemd-network/sd-radv.c systemd/src/libsystemd-network/sd-radv.c
621
-+++ systemd/src/libsystemd-network/sd-radv.c	2017-09-18 15:00:40.022354604 -0700
622
-@@ -0,0 +1,653 @@
623
-+/***
624
-+  This file is part of systemd.
625
-+
626
-+  Copyright (C) 2017 Intel Corporation. All rights reserved.
627
-+
628
-+  systemd is free software; you can redistribute it and/or modify it
629
-+  under the terms of the GNU Lesser General Public License as published by
630
-+  the Free Software Foundation; either version 2.1 of the License, or
631
-+  (at your option) any later version.
632
-+
633
-+  systemd is distributed in the hope that it will be useful, but
634
-+  WITHOUT ANY WARRANTY; without even the implied warranty of
635
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
636
-+  Lesser General Public License for more details.
637
-+
638
-+  You should have received a copy of the GNU Lesser General Public License
639
-+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
640
-+***/
641
-+
642
-+#include <netinet/icmp6.h>
643
-+#include <netinet/in.h>
644
-+#include <arpa/inet.h>
645
-+#include <linux/in6.h>
646
-+
647
-+#include "sd-radv.h"
648
-+
649
-+#include "macro.h"
650
-+#include "alloc-util.h"
651
-+#include "fd-util.h"
652
-+#include "icmp6-util.h"
653
-+#include "in-addr-util.h"
654
-+#include "radv-internal.h"
655
-+#include "socket-util.h"
656
-+#include "string-util.h"
657
-+#include "util.h"
658
-+#include "random-util.h"
659
-+
660
-+_public_ int sd_radv_new(sd_radv **ret) {
661
-+        _cleanup_(sd_radv_unrefp) sd_radv *ra = NULL;
662
-+
663
-+        assert_return(ret, -EINVAL);
664
-+
665
-+        ra = new0(sd_radv, 1);
666
-+        if (!ra)
667
-+                return -ENOMEM;
668
-+
669
-+        ra->n_ref = 1;
670
-+        ra->fd = -1;
671
-+
672
-+        LIST_HEAD_INIT(ra->prefixes);
673
-+
674
-+        *ret = ra;
675
-+        ra = NULL;
676
-+
677
-+        return 0;
678
-+}
679
-+
680
-+_public_ int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority) {
681
-+        int r;
682
-+
683
-+        assert_return(ra, -EINVAL);
684
-+        assert_return(!ra->event, -EBUSY);
685
-+
686
-+        if (event)
687
-+                ra->event = sd_event_ref(event);
688
-+        else {
689
-+                r = sd_event_default(&ra->event);
690
-+                if (r < 0)
691
-+                        return 0;
692
-+        }
693
-+
694
-+        ra->event_priority = priority;
695
-+
696
-+        return 0;
697
-+}
698
-+
699
-+_public_ int sd_radv_detach_event(sd_radv *ra) {
700
-+
701
-+        assert_return(ra, -EINVAL);
702
-+
703
-+        ra->event = sd_event_unref(ra->event);
704
-+        return 0;
705
-+}
706
-+
707
-+_public_ sd_event *sd_radv_get_event(sd_radv *ra) {
708
-+        assert_return(ra, NULL);
709
-+
710
-+        return ra->event;
711
-+}
712
-+
713
-+static void radv_reset(sd_radv *ra) {
714
-+
715
-+        ra->timeout_event_source =
716
-+                sd_event_source_unref(ra->timeout_event_source);
717
-+
718
-+        ra->recv_event_source =
719
-+                sd_event_source_unref(ra->recv_event_source);
720
-+
721
-+        ra->ra_sent = 0;
722
-+}
723
-+
724
-+_public_ sd_radv *sd_radv_ref(sd_radv *ra) {
725
-+        if (!ra)
726
-+                return NULL;
727
-+
728
-+        assert(ra->n_ref > 0);
729
-+        ra->n_ref++;
730
-+
731
-+        return ra;
732
-+}
733
-+
734
-+_public_ sd_radv *sd_radv_unref(sd_radv *ra) {
735
-+        if (!ra)
736
-+                return NULL;
737
-+
738
-+        assert(ra->n_ref > 0);
739
-+        ra->n_ref--;
740
-+
741
-+        if (ra->n_ref > 0)
742
-+                return NULL;
743
-+
744
-+        while (ra->prefixes) {
745
-+                sd_radv_prefix *p = ra->prefixes;
746
-+
747
-+                LIST_REMOVE(prefix, ra->prefixes, p);
748
-+                sd_radv_prefix_unref(p);
749
-+        }
750
-+
751
-+        radv_reset(ra);
752
-+
753
-+        sd_radv_detach_event(ra);
754
-+        return mfree(ra);
755
-+}
756
-+
757
-+static int radv_send(sd_radv *ra, const struct in6_addr *dst,
758
-+                     const uint32_t router_lifetime) {
759
-+        static const struct ether_addr mac_zero = {};
760
-+        sd_radv_prefix *p;
761
-+        struct sockaddr_in6 dst_addr = {
762
-+                .sin6_family = AF_INET6,
763
-+                .sin6_addr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
764
-+        };
765
-+        struct nd_router_advert adv = {};
766
-+        struct {
767
-+                struct nd_opt_hdr opthdr;
768
-+                struct ether_addr slladdr;
769
-+        } _packed_ opt_mac = {
770
-+                .opthdr = {
771
-+                        .nd_opt_type = ND_OPT_SOURCE_LINKADDR,
772
-+                        .nd_opt_len = (sizeof(struct nd_opt_hdr) +
773
-+                                       sizeof(struct ether_addr) - 1) /8 + 1,
774
-+                },
775
-+        };
776
-+        struct nd_opt_mtu opt_mtu =  {
777
-+                .nd_opt_mtu_type = ND_OPT_MTU,
778
-+                .nd_opt_mtu_len = 1,
779
-+        };
780
-+        /* Reserve iov space for RA header, linkaddr, MTU + N prefixes */
781
-+        struct iovec iov[3 + ra->n_prefixes];
782
-+        struct msghdr msg = {
783
-+                .msg_name = &dst_addr,
784
-+                .msg_namelen = sizeof(dst_addr),
785
-+                .msg_iov = iov,
786
-+        };
787
-+
788
-+        if (dst && !in_addr_is_null(AF_INET6, (union in_addr_union*) dst))
789
-+                dst_addr.sin6_addr = *dst;
790
-+
791
-+        adv.nd_ra_type = ND_ROUTER_ADVERT;
792
-+        adv.nd_ra_curhoplimit = ra->hop_limit;
793
-+        adv.nd_ra_flags_reserved = ra->flags;
794
-+        adv.nd_ra_router_lifetime = htobe16(router_lifetime);
795
-+        iov[msg.msg_iovlen].iov_base = &adv;
796
-+        iov[msg.msg_iovlen].iov_len = sizeof(adv);
797
-+        msg.msg_iovlen++;
798
-+
799
-+        /* MAC address is optional, either because the link does not use L2
800
-+           addresses or load sharing is desired. See RFC 4861, Section 4.2 */
801
-+        if (memcmp(&mac_zero, &ra->mac_addr, sizeof(mac_zero))) {
802
-+                opt_mac.slladdr = ra->mac_addr;
803
-+                iov[msg.msg_iovlen].iov_base = &opt_mac;
804
-+                iov[msg.msg_iovlen].iov_len = sizeof(opt_mac);
805
-+                msg.msg_iovlen++;
806
-+        }
807
-+
808
-+        if (ra->mtu) {
809
-+                opt_mtu.nd_opt_mtu_mtu = htobe32(ra->mtu);
810
-+                iov[msg.msg_iovlen].iov_base = &opt_mtu;
811
-+                iov[msg.msg_iovlen].iov_len = sizeof(opt_mtu);
812
-+                msg.msg_iovlen++;
813
-+        }
814
-+
815
-+        LIST_FOREACH(prefix, p, ra->prefixes) {
816
-+                iov[msg.msg_iovlen].iov_base = &p->opt;
817
-+                iov[msg.msg_iovlen].iov_len = sizeof(p->opt);
818
-+                msg.msg_iovlen++;
819
-+        }
820
-+
821
-+        if (sendmsg(ra->fd, &msg, 0) < 0)
822
-+                return -errno;
823
-+
824
-+        return 0;
825
-+}
826
-+
827
-+static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
828
-+        sd_radv *ra = userdata;
829
-+        _cleanup_free_ char *addr = NULL;
830
-+        struct in6_addr src;
831
-+        triple_timestamp timestamp;
832
-+        int r;
833
-+        ssize_t buflen;
834
-+        _cleanup_free_ char *buf = NULL;
835
-+
836
-+        assert(s);
837
-+        assert(ra);
838
-+        assert(ra->event);
839
-+
840
-+        buflen = next_datagram_size_fd(fd);
841
-+
842
-+        if ((unsigned) buflen < sizeof(struct nd_router_solicit))
843
-+                return log_radv("Too short packet received");
844
-+
845
-+        buf = new0(char, buflen);
846
-+        if (!buf)
847
-+                return 0;
848
-+
849
-+        r = icmp6_receive(fd, buf, buflen, &src, &timestamp);
850
-+        if (r < 0) {
851
-+                switch (r) {
852
-+                case -EADDRNOTAVAIL:
853
-+                        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr);
854
-+                        log_radv("Received RS from non-link-local address %s. Ignoring", addr);
855
-+                        break;
856
-+
857
-+                case -EMULTIHOP:
858
-+                        log_radv("Received RS with invalid hop limit. Ignoring.");
859
-+                        break;
860
-+
861
-+                case -EPFNOSUPPORT:
862
-+                        log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
863
-+                        break;
864
-+
865
-+                default:
866
-+                        log_radv_warning_errno(r, "Error receiving from ICMPv6 socket: %m");
867
-+                        break;
868
-+                }
869
-+
870
-+                return 0;
871
-+        }
872
-+
873
-+        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr);
874
-+
875
-+        r = radv_send(ra, &src, ra->lifetime);
876
-+        if (r < 0)
877
-+                log_radv_warning_errno(r, "Unable to send solicited Router Advertisment to %s: %m", addr);
878
-+        else
879
-+                log_radv("Sent solicited Router Advertisement to %s", addr);
880
-+
881
-+        return 0;
882
-+}
883
-+
884
-+static usec_t radv_compute_timeout(usec_t min, usec_t max) {
885
-+        assert_return(min <= max, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC);
886
-+
887
-+        return min + (random_u32() % (max - min));
888
-+}
889
-+
890
-+static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
891
-+        int r;
892
-+        sd_radv *ra = userdata;
893
-+        usec_t min_timeout = SD_RADV_DEFAULT_MIN_TIMEOUT_USEC;
894
-+        usec_t max_timeout = SD_RADV_DEFAULT_MAX_TIMEOUT_USEC;
895
-+        usec_t time_now, timeout;
896
-+        char time_string[FORMAT_TIMESPAN_MAX];
897
-+
898
-+        assert(s);
899
-+        assert(ra);
900
-+        assert(ra->event);
901
-+
902
-+        ra->timeout_event_source = sd_event_source_unref(ra->timeout_event_source);
903
-+
904
-+        r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now);
905
-+        if (r < 0)
906
-+                goto fail;
907
-+
908
-+        r = radv_send(ra, NULL, ra->lifetime);
909
-+        if (r < 0)
910
-+                log_radv_warning_errno(r, "Unable to send Router Advertisement: %m");
911
-+
912
-+        /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
913
-+        if (ra->ra_sent < SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS) {
914
-+                max_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC;
915
-+                min_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC / 3;
916
-+        }
917
-+
918
-+        timeout = radv_compute_timeout(min_timeout, max_timeout);
919
-+
920
-+        log_radv("Next Router Advertisement in %s",
921
-+                 format_timespan(time_string, FORMAT_TIMESPAN_MAX,
922
-+                                 timeout, USEC_PER_SEC));
923
-+
924
-+        r = sd_event_add_time(ra->event, &ra->timeout_event_source,
925
-+                              clock_boottime_or_monotonic(),
926
-+                              time_now + timeout, MSEC_PER_SEC,
927
-+                              radv_timeout, ra);
928
-+        if (r < 0)
929
-+                goto fail;
930
-+
931
-+        r = sd_event_source_set_priority(ra->timeout_event_source,
932
-+                                         ra->event_priority);
933
-+        if (r < 0)
934
-+                goto fail;
935
-+
936
-+        r = sd_event_source_set_description(ra->timeout_event_source,
937
-+                                            "radv-timeout");
938
-+        if (r < 0)
939
-+                goto fail;
940
-+
941
-+        ra->ra_sent++;
942
-+
943
-+fail:
944
-+        if (r < 0)
945
-+                sd_radv_stop(ra);
946
-+
947
-+        return 0;
948
-+}
949
-+
950
-+_public_ int sd_radv_stop(sd_radv *ra) {
951
-+        int r;
952
-+
953
-+        assert_return(ra, -EINVAL);
954
-+
955
-+        log_radv("Stopping IPv6 Router Advertisement daemon");
956
-+
957
-+        /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
958
-+           with zero lifetime  */
959
-+        r = radv_send(ra, NULL, 0);
960
-+        if (r < 0)
961
-+                log_radv_warning_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
962
-+
963
-+        radv_reset(ra);
964
-+        ra->fd = safe_close(ra->fd);
965
-+        ra->state = SD_RADV_STATE_IDLE;
966
-+
967
-+        return 0;
968
-+}
969
-+
970
-+_public_ int sd_radv_start(sd_radv *ra) {
971
-+        int r = 0;
972
-+
973
-+        assert_return(ra, -EINVAL);
974
-+        assert_return(ra->event, -EINVAL);
975
-+        assert_return(ra->ifindex > 0, -EINVAL);
976
-+
977
-+        if (ra->state != SD_RADV_STATE_IDLE)
978
-+                return 0;
979
-+
980
-+        r = sd_event_add_time(ra->event, &ra->timeout_event_source,
981
-+                              clock_boottime_or_monotonic(), 0, 0,
982
-+                              radv_timeout, ra);
983
-+        if (r < 0)
984
-+                goto fail;
985
-+
986
-+        r = sd_event_source_set_priority(ra->timeout_event_source,
987
-+                                         ra->event_priority);
988
-+        if (r < 0)
989
-+                goto fail;
990
-+
991
-+        (void) sd_event_source_set_description(ra->timeout_event_source,
992
-+                                               "radv-timeout");
993
-+
994
-+        r = icmp6_bind_router_advertisement(ra->ifindex);
995
-+        if (r < 0)
996
-+                goto fail;
997
-+
998
-+        ra->fd = r;
999
-+
1000
-+        r = sd_event_add_io(ra->event, &ra->recv_event_source, ra->fd, EPOLLIN, radv_recv, ra);
1001
-+        if (r < 0)
1002
-+                goto fail;
1003
-+
1004
-+        r = sd_event_source_set_priority(ra->recv_event_source, ra->event_priority);
1005
-+        if (r < 0)
1006
-+                goto fail;
1007
-+
1008
-+        (void) sd_event_source_set_description(ra->recv_event_source, "radv-receive-message");
1009
-+
1010
-+        ra->state = SD_RADV_STATE_ADVERTISING;
1011
-+
1012
-+        log_radv("Started IPv6 Router Advertisement daemon");
1013
-+
1014
-+        return 0;
1015
-+
1016
-+ fail:
1017
-+        radv_reset(ra);
1018
-+
1019
-+        return r;
1020
-+}
1021
-+
1022
-+_public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) {
1023
-+        assert_return(ra, -EINVAL);
1024
-+        assert_return(ifindex >= -1, -EINVAL);
1025
-+
1026
-+        if (ra->state != SD_RADV_STATE_IDLE)
1027
-+                return -EBUSY;
1028
-+
1029
-+        ra->ifindex = ifindex;
1030
-+
1031
-+        return 0;
1032
-+}
1033
-+
1034
-+_public_ int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr) {
1035
-+        assert_return(ra, -EINVAL);
1036
-+
1037
-+        if (ra->state != SD_RADV_STATE_IDLE)
1038
-+                return -EBUSY;
1039
-+
1040
-+        if (mac_addr)
1041
-+                ra->mac_addr = *mac_addr;
1042
-+        else
1043
-+                zero(ra->mac_addr);
1044
-+
1045
-+        return 0;
1046
-+}
1047
-+
1048
-+_public_ int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu) {
1049
-+        assert_return(ra, -EINVAL);
1050
-+        assert_return(mtu >= 1280, -EINVAL);
1051
-+
1052
-+        if (ra->state != SD_RADV_STATE_IDLE)
1053
-+                return -EBUSY;
1054
-+
1055
-+        ra->mtu = mtu;
1056
-+
1057
-+        return 0;
1058
-+}
1059
-+
1060
-+_public_ int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) {
1061
-+        assert_return(ra, -EINVAL);
1062
-+
1063
-+        if (ra->state != SD_RADV_STATE_IDLE)
1064
-+                return -EBUSY;
1065
-+
1066
-+        ra->hop_limit = hop_limit;
1067
-+
1068
-+        return 0;
1069
-+}
1070
-+
1071
-+_public_ int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime) {
1072
-+        assert_return(ra, -EINVAL);
1073
-+
1074
-+        if (ra->state != SD_RADV_STATE_IDLE)
1075
-+                return -EBUSY;
1076
-+
1077
-+        /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
1078
-+           preference value MUST be set to (00) by the sender..." */
1079
-+        if (router_lifetime == 0 &&
1080
-+            (ra->flags & (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM << 3))
1081
-+                return -ETIME;
1082
-+
1083
-+        ra->lifetime = router_lifetime;
1084
-+
1085
-+        return 0;
1086
-+}
1087
-+
1088
-+_public_ int sd_radv_set_managed_information(sd_radv *ra, int managed) {
1089
-+        assert_return(ra, -EINVAL);
1090
-+
1091
-+        if (ra->state != SD_RADV_STATE_IDLE)
1092
-+                return -EBUSY;
1093
-+
1094
-+        SET_FLAG(ra->flags, ND_RA_FLAG_MANAGED, managed);
1095
-+
1096
-+        return 0;
1097
-+}
1098
-+
1099
-+_public_ int sd_radv_set_other_information(sd_radv *ra, int other) {
1100
-+        assert_return(ra, -EINVAL);
1101
-+
1102
-+        if (ra->state != SD_RADV_STATE_IDLE)
1103
-+                return -EBUSY;
1104
-+
1105
-+        SET_FLAG(ra->flags, ND_RA_FLAG_OTHER, other);
1106
-+
1107
-+        return 0;
1108
-+}
1109
-+
1110
-+_public_ int sd_radv_set_preference(sd_radv *ra, unsigned preference) {
1111
-+        int r = 0;
1112
-+
1113
-+        assert_return(ra, -EINVAL);
1114
-+        assert_return(IN_SET(preference,
1115
-+                             SD_NDISC_PREFERENCE_LOW,
1116
-+                             SD_NDISC_PREFERENCE_MEDIUM,
1117
-+                             SD_NDISC_PREFERENCE_HIGH), -EINVAL);
1118
-+
1119
-+        ra->flags = (ra->flags & ~(0x3 << 3)) | (preference << 3);
1120
-+
1121
-+        return r;
1122
-+}
1123
-+
1124
-+_public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) {
1125
-+        sd_radv_prefix *cur;
1126
-+        _cleanup_free_ char *addr_p = NULL;
1127
-+
1128
-+        assert_return(ra, -EINVAL);
1129
-+
1130
-+        if (!p)
1131
-+                return -EINVAL;
1132
-+
1133
-+        LIST_FOREACH(prefix, cur, ra->prefixes) {
1134
-+                int r;
1135
-+
1136
-+                r = in_addr_prefix_intersect(AF_INET6,
1137
-+                                             (union in_addr_union*) &cur->opt.in6_addr,
1138
-+                                             cur->opt.prefixlen,
1139
-+                                             (union in_addr_union*) &p->opt.in6_addr,
1140
-+                                             p->opt.prefixlen);
1141
-+                if (r > 0) {
1142
-+                        _cleanup_free_ char *addr_cur = NULL;
1143
-+
1144
-+                        (void) in_addr_to_string(AF_INET6,
1145
-+                                                 (union in_addr_union*) &cur->opt.in6_addr,
1146
-+                                                 &addr_cur);
1147
-+                        (void) in_addr_to_string(AF_INET6,
1148
-+                                                 (union in_addr_union*) &p->opt.in6_addr,
1149
-+                                                 &addr_p);
1150
-+
1151
-+                        log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
1152
-+                                 addr_cur, cur->opt.prefixlen,
1153
-+                                 addr_p, p->opt.prefixlen);
1154
-+
1155
-+                        return -EEXIST;
1156
-+                }
1157
-+        }
1158
-+
1159
-+        p = sd_radv_prefix_ref(p);
1160
-+
1161
-+        LIST_APPEND(prefix, ra->prefixes, p);
1162
-+
1163
-+        ra->n_prefixes++;
1164
-+
1165
-+        (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &p->opt.in6_addr, &addr_p);
1166
-+        log_radv("Added prefix %s/%d", addr_p, p->opt.prefixlen);
1167
-+
1168
-+        return 0;
1169
-+}
1170
-+
1171
-+_public_ int sd_radv_prefix_new(sd_radv_prefix **ret) {
1172
-+        _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
1173
-+
1174
-+        assert_return(ret, -EINVAL);
1175
-+
1176
-+        p = new0(sd_radv_prefix, 1);
1177
-+        if (!p)
1178
-+                return -ENOMEM;
1179
-+
1180
-+        p->n_ref = 1;
1181
-+
1182
-+        p->opt.type = ND_OPT_PREFIX_INFORMATION;
1183
-+        p->opt.length = (sizeof(p->opt) - 1) /8 + 1;
1184
-+
1185
-+        p->opt.prefixlen = 64;
1186
-+
1187
-+        /* RFC 4861, Section 6.2.1 */
1188
-+        SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, true);
1189
-+        SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, true);
1190
-+        p->opt.preferred_lifetime = htobe32(604800);
1191
-+        p->opt.valid_lifetime = htobe32(2592000);
1192
-+
1193
-+        LIST_INIT(prefix, p);
1194
-+
1195
-+        *ret = p;
1196
-+        p = NULL;
1197
-+
1198
-+        return 0;
1199
-+}
1200
-+
1201
-+_public_ sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *p) {
1202
-+        if (!p)
1203
-+                return NULL;
1204
-+
1205
-+        assert(p->n_ref > 0);
1206
-+        p->n_ref++;
1207
-+
1208
-+        return p;
1209
-+}
1210
-+
1211
-+_public_ sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *p) {
1212
-+        if (!p)
1213
-+                return NULL;
1214
-+
1215
-+        assert(p->n_ref > 0);
1216
-+        p->n_ref--;
1217
-+
1218
-+        if (p->n_ref > 0)
1219
-+                return NULL;
1220
-+
1221
-+        return mfree(p);
1222
-+}
1223
-+
1224
-+_public_ int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr,
1225
-+                                       unsigned char prefixlen) {
1226
-+        assert_return(p, -EINVAL);
1227
-+        assert_return(in6_addr, -EINVAL);
1228
-+
1229
-+        if (prefixlen < 3 || prefixlen > 128)
1230
-+                return -EINVAL;
1231
-+
1232
-+        if (prefixlen > 64)
1233
-+                /* unusual but allowed, log it */
1234
-+                log_radv("Unusual prefix length %d greater than 64", prefixlen);
1235
-+
1236
-+        p->opt.in6_addr = *in6_addr;
1237
-+        p->opt.prefixlen = prefixlen;
1238
-+
1239
-+        return 0;
1240
-+}
1241
-+
1242
-+_public_ int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink) {
1243
-+        assert_return(p, -EINVAL);
1244
-+
1245
-+        SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, onlink);
1246
-+
1247
-+        return 0;
1248
-+}
1249
-+
1250
-+_public_ int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p,
1251
-+                                                          int address_autoconfiguration) {
1252
-+        assert_return(p, -EINVAL);
1253
-+
1254
-+        SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, address_autoconfiguration);
1255
-+
1256
-+        return 0;
1257
-+}
1258
-+
1259
-+_public_ int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p,
1260
-+                                               uint32_t valid_lifetime) {
1261
-+        assert_return(p, -EINVAL);
1262
-+
1263
-+        p->opt.valid_lifetime = htobe32(valid_lifetime);
1264
-+
1265
-+        return 0;
1266
-+}
1267
-+
1268
-+_public_ int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p,
1269
-+                                                   uint32_t preferred_lifetime) {
1270
-+        assert_return(p, -EINVAL);
1271
-+
1272
-+        p->opt.preferred_lifetime = htobe32(preferred_lifetime);
1273
-+
1274
-+        return 0;
1275
-+}
1276
-diff -rupN systemd-base/src/libsystemd-network/test-ndisc-rs.c systemd/src/libsystemd-network/test-ndisc-rs.c
1277
-+++ systemd/src/libsystemd-network/test-ndisc-rs.c	2017-09-18 15:07:09.099322638 -0700
1278
-@@ -193,6 +193,21 @@ int icmp6_bind_router_solicitation(int i
1279
-         return test_fd[0];
1280
- }
1281
- 
1282
-+int icmp6_bind_router_advertisement(int index) {
1283
-+
1284
-+        return -ENOSYS;
1285
-+}
1286
-+
1287
-+int icmp6_receive(int fd, void *iov_base, size_t iov_len,
1288
-+                  struct in6_addr *dst, triple_timestamp *timestamp) {
1289
-+        assert (read (fd, iov_base, iov_len) == (ssize_t)iov_len);
1290
-+
1291
-+        if (timestamp)
1292
-+                triple_timestamp_get(timestamp);
1293
-+
1294
-+        return 0;
1295
-+}
1296
-+
1297
- static int send_ra(uint8_t flags) {
1298
-         uint8_t advertisement[] = {
1299
-                 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
1300
-diff -rupN systemd-base/src/network/networkd-ndisc.c systemd/src/network/networkd-ndisc.c
1301
-+++ systemd/src/network/networkd-ndisc.c	2017-09-18 14:39:40.690643380 -0700
1302
-@@ -27,6 +27,7 @@
1303
- 
1304
- #define NDISC_DNSSL_MAX 64U
1305
- #define NDISC_RDNSS_MAX 64U
1306
-+#define NDISC_PREFIX_LFT_MIN 7200U
1307
- 
1308
- static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
1309
-         _cleanup_link_unref_ Link *link = userdata;
1310
-@@ -152,13 +153,21 @@ static void ndisc_router_process_default
1311
- 
1312
- static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
1313
-         _cleanup_address_free_ Address *address = NULL;
1314
--        uint32_t lifetime_valid, lifetime_preferred;
1315
-+        Address *existing_address;
1316
-+        uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining;
1317
-+        usec_t time_now;
1318
-         unsigned prefixlen;
1319
-         int r;
1320
- 
1321
-         assert(link);
1322
-         assert(rt);
1323
- 
1324
-+        r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
1325
-+        if (r < 0) {
1326
-+                log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
1327
-+                return;
1328
-+        }
1329
-+
1330
-         r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
1331
-         if (r < 0) {
1332
-                 log_link_error_errno(link, r, "Failed to get prefix length: %m");
1333
-@@ -207,7 +216,24 @@ static void ndisc_router_process_autonom
1334
-         address->prefixlen = prefixlen;
1335
-         address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
1336
-         address->cinfo.ifa_prefered = lifetime_preferred;
1337
--        address->cinfo.ifa_valid = lifetime_valid;
1338
-+
1339
-+        /* see RFC4862 section 5.5.3.e */
1340
-+        r = address_get(link, address->family, &address->in_addr, address->prefixlen, &existing_address);
1341
-+        if (r > 0) {
1342
-+                lifetime_remaining = existing_address->cinfo.tstamp / 100 + existing_address->cinfo.ifa_valid - time_now / USEC_PER_SEC;
1343
-+                if (lifetime_valid > NDISC_PREFIX_LFT_MIN || lifetime_valid > lifetime_remaining)
1344
-+                        address->cinfo.ifa_valid = lifetime_valid;
1345
-+                else if (lifetime_remaining <= NDISC_PREFIX_LFT_MIN)
1346
-+                        address->cinfo.ifa_valid = lifetime_remaining;
1347
-+                else
1348
-+                        address->cinfo.ifa_valid = NDISC_PREFIX_LFT_MIN;
1349
-+        } else if (lifetime_valid > 0)
1350
-+                address->cinfo.ifa_valid = lifetime_valid;
1351
-+        else
1352
-+                return; /* see RFC4862 section 5.5.3.d */
1353
-+
1354
-+        if (address->cinfo.ifa_valid == 0)
1355
-+                return;
1356
- 
1357
-         r = address_configure(address, link, ndisc_netlink_handler, true);
1358
-         if (r < 0) {
1359
-diff -rupN systemd-base/src/systemd/sd-radv.h systemd/src/systemd/sd-radv.h
1360
-+++ systemd/src/systemd/sd-radv.h	2017-09-18 14:58:44.807575602 -0700
1361
-@@ -0,0 +1,81 @@
1362
-+#ifndef foosdradvfoo
1363
-+#define foosdradvfoo
1364
-+
1365
-+/***
1366
-+  This file is part of systemd.
1367
-+
1368
-+  Copyright (C) 2017 Intel Corporation. All rights reserved.
1369
-+
1370
-+  systemd is free software; you can redistribute it and/or modify it
1371
-+  under the terms of the GNU Lesser General Public License as published by
1372
-+  the Free Software Foundation; either version 2.1 of the License, or
1373
-+  (at your option) any later version.
1374
-+
1375
-+  systemd is distributed in the hope that it will be useful, but
1376
-+  WITHOUT ANY WARRANTY; without even the implied warranty of
1377
-+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1378
-+  Lesser General Public License for more details.
1379
-+
1380
-+  You should have received a copy of the GNU Lesser General Public License
1381
-+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
1382
-+***/
1383
-+
1384
-+#include <inttypes.h>
1385
-+#include <net/ethernet.h>
1386
-+#include <netinet/in.h>
1387
-+#include <sys/types.h>
1388
-+
1389
-+#include "sd-ndisc.h"
1390
-+
1391
-+#include "sd-event.h"
1392
-+
1393
-+#include "_sd-common.h"
1394
-+
1395
-+_SD_BEGIN_DECLARATIONS;
1396
-+
1397
-+typedef struct sd_radv sd_radv;
1398
-+typedef struct sd_radv_prefix sd_radv_prefix;
1399
-+
1400
-+/* Router Advertisment */
1401
-+int sd_radv_new(sd_radv **ret);
1402
-+sd_radv *sd_radv_ref(sd_radv *ra);
1403
-+sd_radv *sd_radv_unref(sd_radv *ra);
1404
-+
1405
-+int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority);
1406
-+int sd_radv_detach_event(sd_radv *nd);
1407
-+sd_event *sd_radv_get_event(sd_radv *ra);
1408
-+
1409
-+int sd_radv_start(sd_radv *ra);
1410
-+int sd_radv_stop(sd_radv *ra);
1411
-+
1412
-+int sd_radv_set_ifindex(sd_radv *ra, int interface_index);
1413
-+int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);
1414
-+int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu);
1415
-+int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit);
1416
-+int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime);
1417
-+int sd_radv_set_managed_information(sd_radv *ra, int managed);
1418
-+int sd_radv_set_other_information(sd_radv *ra, int other);
1419
-+int sd_radv_set_preference(sd_radv *ra, unsigned preference);
1420
-+int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p);
1421
-+
1422
-+/* Advertised prefixes */
1423
-+int sd_radv_prefix_new(sd_radv_prefix **ret);
1424
-+sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *ra);
1425
-+sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *ra);
1426
-+
1427
-+int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr,
1428
-+                              unsigned char prefixlen);
1429
-+int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink);
1430
-+int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p,
1431
-+                                                 int address_autoconfiguration);
1432
-+int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p,
1433
-+                                      uint32_t valid_lifetime);
1434
-+int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p,
1435
-+                                          uint32_t preferred_lifetime);
1436
-+
1437
-+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv, sd_radv_unref);
1438
-+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv_prefix, sd_radv_prefix_unref);
1439
-+
1440
-+_SD_END_DECLARATIONS;
1441
-+
1442
-+#endif
1443 1
deleted file mode 100644
... ...
@@ -1,12 +0,0 @@
1
-diff -rup systemd-232/tmpfiles.d/etc.conf.m4 systemd-232-new/tmpfiles.d/etc.conf.m4
2
-+++ systemd-232-new/tmpfiles.d/etc.conf.m4	2016-11-23 16:39:04.837676446 -0800
3
-@@ -14,7 +14,7 @@ m4_ifdef(`HAVE_SMACK_RUN_LABEL',
4
- t /etc/mtab - - - - security.SMACK64=_
5
- )m4_dnl
6
- m4_ifdef(`ENABLE_RESOLVED',
7
--L! /etc/resolv.conf - - - - ../usr/lib/systemd/resolv.conf
8
-+L! /etc/resolv.conf - - - - ../run/systemd/resolve/resolv.conf
9
- )m4_dnl
10
- C /etc/nsswitch.conf - - - -
11
- m4_ifdef(`HAVE_PAM',
12 1
new file mode 100644
... ...
@@ -0,0 +1,23 @@
0
+diff -uNr systemd-233/src/resolve/resolved-conf.c systemd-233-new/src/resolve/resolved-conf.c
1
+--- systemd-233/src/resolve/resolved-conf.c	2017-03-01 21:43:06.000000000 +0000
2
+@@ -229,6 +229,7 @@
3
+ 
4
+ int manager_parse_config_file(Manager *m) {
5
+         int r;
6
++        char *default_dns_servers;
7
+ 
8
+         assert(m);
9
+ 
10
+@@ -241,7 +242,10 @@
11
+                 return r;
12
+ 
13
+         if (m->need_builtin_fallbacks) {
14
+-                r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
15
++                default_dns_servers = secure_getenv("DEFAULT_DNS_SERVERS");
16
++                if (default_dns_servers == NULL)
17
++                        default_dns_servers = DNS_SERVERS;
18
++                r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, default_dns_servers);
19
+                 if (r < 0)
20
+                         return r;
21
+         }
... ...
@@ -1,14 +1,14 @@
1
-Summary:          Systemd-233
1
+Summary:          Systemd-236
2 2
 Name:             systemd
3
-Version:          233
4
-Release:          11%{?dist}
3
+Version:          236
4
+Release:          1%{?dist}
5 5
 License:          LGPLv2+ and GPLv2+ and MIT
6 6
 URL:              http://www.freedesktop.org/wiki/Software/systemd/
7 7
 Group:            System Environment/Security
8 8
 Vendor:           VMware, Inc.
9 9
 Distribution:     Photon
10 10
 Source0:          %{name}-%{version}.tar.gz
11
-%define sha1      systemd=432ec4ce665f65d1d616558358fb7e7cba953930
11
+%define sha1      systemd=eab372a3441997dfba1dfa41183918764c31a7df
12 12
 Source1:          99-vmware-hotplug.rules
13 13
 Source2:          50-security-hardening.conf
14 14
 Source3:          systemd.cfg
... ...
@@ -16,24 +16,18 @@ Source4:          99-dhcp-en.network
16 16
 
17 17
 Patch0:           01-enoX-uses-instance-number-for-vmware-hv.patch
18 18
 Patch1:           02-install-general-aliases.patch
19
-Patch2:           systemd-233-query-duid.patch
20
-Patch3:           systemd-233-ipv6-disabled-fix.patch
21
-Patch4:           systemd-233-default-dns-from-env.patch
22
-Patch5:           systemd-macros.patch
23
-Patch6:           systemd-233-resolv-conf-symlink.patch
24
-Patch7:           systemd-233-CVE-2017-9217.patch
25
-Patch8:           systemd-233-CVE-2017-9445-dns-oob.patch
26
-Patch9:           systemd-233-CVE-2017-1000082-1.patch
27
-Patch10:          systemd-233-CVE-2017-1000082-2.patch
28
-Patch11:          systemd-233-ra-improvements.patch
29
-Patch12:          systemd-233-link-disabled-nullptr-fix.patch
30
-Patch13:          systemd-228-CVE-2017-15908-dns-pkt-loop-fix.patch
19
+Patch2:           systemd-236-default-dns-from-env.patch
20
+Patch3:           systemd-macros.patch
21
+
22
+#TODO: Verify this patch is necessary or not
23
+#Patch4:           systemd-233-query-duid.patch
31 24
 
32 25
 Requires:         Linux-PAM
33 26
 Requires:         libcap
34 27
 Requires:         xz
35 28
 Requires:         kmod
36 29
 Requires:         glib
30
+Requires:         libgcrypt
37 31
 Requires:         filesystem >= 1.1
38 32
 BuildRequires:    intltool
39 33
 BuildRequires:    gperf
... ...
@@ -43,11 +37,15 @@ BuildRequires:    Linux-PAM-devel
43 43
 BuildRequires:    XML-Parser
44 44
 BuildRequires:    kbd
45 45
 BuildRequires:    kmod-devel
46
-BuildRequires:    util-linux-devel
46
+BuildRequires:    util-linux-devel >= 2.30
47 47
 BuildRequires:    libxslt
48 48
 BuildRequires:    docbook-xsl
49 49
 BuildRequires:    docbook-xml
50 50
 BuildRequires:    glib-devel
51
+BuildRequires:    meson
52
+BuildRequires:    gettext
53
+BuildRequires:    shadow
54
+BuildRequires:    libgcrypt-devel
51 55
 
52 56
 %description
53 57
 Systemd is an init replacement with better process control and security
... ...
@@ -75,57 +73,44 @@ BLKID_LIBS="-lblkid"
75 75
 BLKID_CFLAGS="-I/usr/include/blkid"
76 76
 cc_cv_CFLAGS__flto=no
77 77
 EOF
78
-sed -i "s:blkid/::" $(grep -rl "blkid/blkid.h")
79
-# xlocale.h has been removed from glibc 2.26
80
-# The above include of locale.h is sufficient
81
-# Further details: https://sourceware.org/git/?p=glibc.git;a=commit;h=f0be25b6336db7492e47d2e8e72eb8af53b5506d */
82
-sed -i "/xlocale.h/d" src/basic/parse-util.c
83 78
 
84 79
 %patch0 -p1
85 80
 %patch1 -p1
86 81
 %patch2 -p1
87 82
 %patch3 -p1
88
-%patch4 -p1
89
-%patch5 -p1
90
-%patch6 -p1
91
-%patch7 -p1
92
-%patch8 -p1
93
-%patch9 -p1
94
-%patch10 -p1
95
-%patch11 -p1
96
-%patch12 -p1
97
-%patch13 -p1
98 83
 
99 84
 sed -i "s#\#DefaultTasksMax=512#DefaultTasksMax=infinity#g" src/core/system.conf
100 85
 
101 86
 %build
102
-./autogen.sh
103
-./configure --prefix=%{_prefix}                                    \
104
-            --sysconfdir=/etc                                       \
105
-            --localstatedir=/var                                    \
106
-            --config-cache                                          \
107
-            --with-rootprefix=                                      \
108
-            --with-rootlibdir=/usr/lib                                  \
109
-            --enable-split-usr                                      \
110
-            --disable-firstboot                                     \
111
-            --disable-ldconfig                                      \
112
-            --disable-sysusers                                      \
113
-            --without-python                                        \
114
-            --enable-pam                                            \
115
-            --docdir=%{_prefix}/share/doc/systemd-228                     \
116
-            --with-dbuspolicydir=/etc/dbus-1/system.d               \
117
-            --with-dbusinterfacedir=%{_prefix}/share/dbus-1/interfaces    \
118
-            --with-dbussessionservicedir=%{_prefix}/share/dbus-1/services \
119
-            --with-dbussystemservicedir=%{_prefix}/share/dbus-1/system-services \
120
-            --enable-compat-libs \
121
-            --disable-elfutils \
122
-            --with-sysvinit-path=/etc/rc.d/init.d \
123
-            --with-rc-local-script-path-start=/etc/rc.d/rc.local
87
+export LANG=en_US.UTF-8
88
+export LC_ALL=en_US.UTF-8
89
+meson  --prefix %{_prefix}                                            \
90
+       --sysconfdir /etc                                              \
91
+       --localstatedir /var                                           \
92
+       -Dblkid=true                                                   \
93
+       -Dbuildtype=release                                            \
94
+       -Ddefault-dnssec=no                                            \
95
+       -Dfirstboot=false                                              \
96
+       -Dinstall-tests=false                                          \
97
+       -Dldconfig=false                                               \
98
+       -Drootprefix=                                                  \
99
+       -Drootlibdir=/lib                                              \
100
+       -Dsplit-usr=true                                               \
101
+       -Dsysusers=false                                               \
102
+       -Dpam=true                                                     \
103
+       -Dpolkit=true                                                  \
104
+       -Ddbuspolicydir=/etc/dbus-1/system.d                           \
105
+       -Ddbussessionservicedir=%{_prefix}/share/dbus-1/services       \
106
+       -Ddbussystemservicedir=%{_prefix}/share/dbus-1/system-services \
107
+       -Dsysvinit-path=/etc/rc.d/init.d                               \
108
+       -Drc-local=/etc/rc.d/rc.local                                  \
109
+       $PWD build &&
110
+       cd build &&
111
+       %ninja_build
124 112
 
125
-make %{?_smp_mflags}
126 113
 %install
127
-[ %{buildroot} != "/"] && rm -rf %{buildroot}/*
128
-make DESTDIR=%{buildroot} install
114
+cd build && %ninja_install
115
+
129 116
 install -vdm 755 %{buildroot}/sbin
130 117
 for tool in runlevel reboot shutdown poweroff halt telinit; do
131 118
      ln -sfv ../bin/systemctl %{buildroot}/sbin/${tool}
... ...
@@ -147,7 +132,7 @@ rm %{buildroot}/lib/systemd/system/default.target
147 147
 ln -sfv multi-user.target %{buildroot}/lib/systemd/system/default.target
148 148
 install -dm 0755 %{buildroot}/%{_sysconfdir}/systemd/network
149 149
 install -m 0644 %{SOURCE4} %{buildroot}/%{_sysconfdir}/systemd/network
150
-%find_lang %{name}
150
+%find_lang %{name} ../%{name}.lang
151 151
 
152 152
 %post
153 153
 /sbin/ldconfig
... ...
@@ -203,18 +188,18 @@ rm -rf %{buildroot}/*
203 203
 /lib/systemd/resolv.conf
204 204
 %config(noreplace) /lib/systemd/network/99-default.link
205 205
 %{_libdir}/environment.d/99-environment.conf
206
-/var/lib/polkit-1/localauthority/10-vendor.d/systemd-networkd.pkla
207 206
 %exclude %{_libdir}/debug
208 207
 %exclude %{_datadir}/locale
209 208
 %{_libdir}/binfmt.d
210 209
 %{_libdir}/kernel
211 210
 %{_libdir}/modules-load.d
212 211
 %{_libdir}/rpm
213
-%{_libdir}/security
212
+/lib/security
214 213
 %{_libdir}/sysctl.d
215 214
 %{_libdir}/systemd
216 215
 %{_libdir}/tmpfiles.d
217
-%{_libdir}/*.so*
216
+/lib/*.so*
217
+/lib/modprobe.d/systemd.conf
218 218
 %{_bindir}/*
219 219
 /bin/*
220 220
 /sbin/*
... ...
@@ -230,8 +215,8 @@ rm -rf %{buildroot}/*
230 230
 
231 231
 %files devel
232 232
 %dir %{_includedir}/systemd
233
-%{_libdir}/libudev.so
234
-%{_libdir}/libsystemd.so
233
+/lib/libudev.so
234
+/lib/libsystemd.so
235 235
 %{_includedir}/systemd/*.h
236 236
 %{_includedir}/libudev.h
237 237
 %{_libdir}/pkgconfig/libudev.pc
... ...
@@ -243,6 +228,8 @@ rm -rf %{buildroot}/*
243 243
 %files lang -f %{name}.lang
244 244
 
245 245
 %changelog
246
+*    Fri Dec 29 2017 Anish Swaminathan <anishs@vmware.com>  236-1
247
+-    Update systemd to 236
246 248
 *    Thu Nov 09 2017 Vinay Kulkarni <kulkarniv@vmware.com>  233-11
247 249
 -    Fix CVE-2017-15908 dns packet loop fix.
248 250
 *    Tue Nov 07 2017 Vinay Kulkarni <kulkarniv@vmware.com>  233-10
... ...
@@ -1,14 +1,14 @@
1 1
 Summary:        Utilities for file systems, consoles, partitions, and messages
2 2
 Name:           util-linux
3
-Version:        2.29.2
4
-Release:        5%{?dist}
3
+Version:        2.31.1
4
+Release:        1%{?dist}
5 5
 URL:            http://www.kernel.org/pub/linux/utils/util-linux
6 6
 License:        GPLv2+
7 7
 Group:          Applications/System
8 8
 Vendor:         VMware, Inc.
9 9
 Distribution:   Photon
10 10
 Source0:        %{name}-%{version}.tar.xz
11
-%define sha1    util-linux=b488f185e74187a63b55baef9d3f48d5b1780118
11
+%define sha1    util-linux=66e1eaeedfb3137b1e583d038a4a3f404474ded1
12 12
 BuildRequires:  ncurses-devel
13 13
 %if %{with_check}
14 14
 BuildRequires:  ncurses-terminfo
... ...
@@ -97,6 +97,8 @@ rm -rf %{buildroot}/lib/systemd/system
97 97
 %{_mandir}/man3/*
98 98
 
99 99
 %changelog
100
+*   Wed Dec 27 2017 Anish Swaminathan <anishs@vmware.com> 2.31.1-1
101
+-   Upgrade to version 2.31.1.
100 102
 *   Mon Oct 02 2017 Alexey Makhalov <amakhalov@vmware.com> 2.29.2-5
101 103
 -   Added conflicts toybox
102 104
 *   Fri Sep 15 2017 Bo Gan <ganb@vmware.com> 2.29.2-4
... ...
@@ -3,7 +3,6 @@
3 3
 #    Author: Mahmoud Bassiouny <mbassiouny@vmware.com>
4 4
 
5 5
 import subprocess
6
-import curses
7 6
 import os
8 7
 import shutil
9 8
 import signal
... ...
@@ -34,7 +33,7 @@ class Installer(object):
34 34
         else:
35 35
             self.working_directory = "/mnt/photon-root"
36 36
         self.photon_root = self.working_directory + "/photon-chroot"
37
-
37
+        self.rpms_tobeinstalled = None
38 38
         self.restart_command = "shutdown"
39 39
 
40 40
         if self.iso_installer:
... ...
@@ -62,7 +61,9 @@ class Installer(object):
62 62
         signal.signal(signal.SIGINT, self.exit_gracefully)
63 63
 
64 64
     # This will be called if the installer interrupted by Ctrl+C or exception
65
-    def exit_gracefully(self, signal, frame):
65
+    def exit_gracefully(self, signal1, frame1):
66
+        del signal1
67
+        del frame1
66 68
         if self.iso_installer:
67 69
             self.progress_bar.hide()
68 70
             self.window.addstr(0, 0, 'Oops, Installer got interrupted.\n\n' +
... ...
@@ -73,8 +74,9 @@ class Installer(object):
73 73
         sys.exit(1)
74 74
 
75 75
     def install(self, params):
76
+        del params
76 77
         try:
77
-            return self.unsafe_install(params)
78
+            return self.unsafe_install()
78 79
         except Exception as inst:
79 80
             if self.iso_installer:
80 81
                 modules.commons.log(modules.commons.LOG_ERROR, repr(inst))
... ...
@@ -82,105 +84,13 @@ class Installer(object):
82 82
             else:
83 83
                 raise
84 84
 
85
-    def unsafe_install(self, params):
86
-
87
-        if self.iso_installer:
88
-            self.window.show_window()
89
-            self.progress_bar.initialize('Initializing installation...')
90
-            self.progress_bar.show()
91
-            #self.rpm_path = "https://dl.bintray.com/vmware/photon_release_1.0_TP2_x86_64"
92
-            if self.rpm_path.startswith("https://") or self.rpm_path.startswith("http://"):
93
-                cmdoption = 's/baseurl.*/baseurl={}/g'.format(self.rpm_path.replace('/', '\/'))
94
-                process = subprocess.Popen(['sed', '-i', cmdoption,
95
-                                            '/etc/yum.repos.d/photon-iso.repo'])
96
-                retval = process.wait()
97
-                if retval != 0:
98
-                    modules.commons.log(modules.commons.LOG_INFO, "Failed to reset repo")
99
-                    self.exit_gracefully(None, None)
100
-
101
-            cmdoption = ('s/cachedir=\/var/cachedir={}/g'
102
-                         .format(self.photon_root.replace('/', '\/')))
103
-            process = subprocess.Popen(['sed', '-i', cmdoption, '/etc/tdnf/tdnf.conf'])
104
-            retval = process.wait()
105
-            if retval != 0:
106
-                modules.commons.log(modules.commons.LOG_INFO, "Failed to reset tdnf cachedir")
107
-                self.exit_gracefully(None, None)
85
+    def unsafe_install(self):
86
+        self.setup_install_repo()
108 87
         self.execute_modules(modules.commons.PRE_INSTALL)
109 88
 
110 89
         self.initialize_system()
111
-
112
-        if self.iso_installer:
113
-            self.adjust_packages_for_vmware_virt()
114
-            selected_packages = self.install_config['packages']
115
-            state = 0
116
-            packages_to_install = {}
117
-            total_size = 0
118
-            with open(modules.commons.TDNF_CMDLINE_FILE_NAME, "w") as tdnf_cmdline_file:
119
-                tdnf_cmdline_file.write("tdnf install --installroot {0} --nogpgcheck {1}"
120
-                                        .format(self.photon_root, " ".join(selected_packages)))
121
-            with open(modules.commons.TDNF_LOG_FILE_NAME, "w") as tdnf_errlog:
122
-                process = subprocess.Popen(['tdnf', 'install'] + selected_packages +
123
-                                           ['--installroot', self.photon_root, '--nogpgcheck',
124
-                                            '--assumeyes'], stdout=subprocess.PIPE,
125
-                                           stderr=tdnf_errlog)
126
-                while True:
127
-                    output = process.stdout.readline().decode()
128
-                    if output == '':
129
-                        retval = process.poll()
130
-                        if retval is not None:
131
-                            break
132
-                    if state == 0:
133
-                        if output == 'Installing:\n':
134
-                            state = 1
135
-                    elif state == 1: #N A EVR Size(readable) Size(in bytes)
136
-                        if output == '\n':
137
-                            state = 2
138
-                            self.progress_bar.update_num_items(total_size)
139
-                        else:
140
-                            info = output.split()
141
-                            package = '{0}-{1}.{2}'.format(info[0], info[2], info[1])
142
-                            packages_to_install[package] = int(info[5])
143
-                            total_size += int(info[5])
144
-                    elif state == 2:
145
-                        if output == 'Downloading:\n':
146
-                            self.progress_bar.update_message('Preparing ...')
147
-                            state = 3
148
-                    elif state == 3:
149
-                        self.progress_bar.update_message(output)
150
-                        if output == 'Running transaction\n':
151
-                            state = 4
152
-                    else:
153
-                        modules.commons.log(modules.commons.LOG_INFO, "[tdnf] {0}".format(output))
154
-                        prefix = 'Installing/Updating: '
155
-                        if output.startswith(prefix):
156
-                            package = output[len(prefix):].rstrip('\n')
157
-                            self.progress_bar.increment(packages_to_install[package])
158
-
159
-                        self.progress_bar.update_message(output)
160
-                # 0 : succeed; 137 : package already installed; 65 : package not found in repo.
161
-                if retval != 0 and retval != 137:
162
-                    modules.commons.log(modules.commons.LOG_ERROR,
163
-                                        "Failed to install some packages, refer to {0}"
164
-                                        .format(modules.commons.TDNF_LOG_FILE_NAME))
165
-                    self.exit_gracefully(None, None)
166
-        else:
167
-        #install packages
168
-            rpms = []
169
-            for rpm in self.rpms_tobeinstalled:
170
-                # We already installed the filesystem in the preparation
171
-                if rpm['package'] == 'filesystem':
172
-                    continue
173
-                rpms.append(rpm['filename'])
174
-            return_value = self.install_package(rpms)
175
-            if return_value != 0:
176
-                self.exit_gracefully(None, None)
177
-
178
-
179
-        if self.iso_installer:
180
-            self.progress_bar.show_loading('Finalizing installation')
181
-
182
-        if os.path.exists("/etc/resolv.conf"):
183
-            shutil.copy("/etc/resolv.conf", self.photon_root + '/etc/.')
90
+        self.install_packages()
91
+        self.enable_network_in_chroot()
184 92
         self.finalize_system()
185 93
 
186 94
         if not self.install_config['iso_system']:
... ...
@@ -228,9 +138,7 @@ class Installer(object):
228 228
             retval = process.wait()
229 229
 
230 230
             self.update_fstab()
231
-
232
-        if os.path.exists(self.photon_root + '/etc/resolv.conf'):
233
-            os.remove(self.photon_root + '/etc/resolv.conf')
231
+        self.disable_network_in_chroot()
234 232
 
235 233
         command = [self.unmount_disk_command, '-w', self.photon_root]
236 234
         if not self.install_config['iso_system']:
... ...
@@ -240,17 +148,10 @@ class Installer(object):
240 240
 
241 241
         if self.iso_installer:
242 242
             self.progress_bar.hide()
243
-            self.window.addstr(0, 0, 'Congratulations, Photon has been installed in {0} secs.\n\n' +
243
+            self.window.addstr(0, 0, 'Congratulations, Photon has been installed in {0} secs.\n\n'
244 244
                                'Press any key to continue to boot...'
245 245
                                .format(self.progress_bar.time_elapsed))
246
-            eject_cdrom = True
247
-            if 'ui_install' in self.install_config:
248
-                self.window.content_window().getch()
249
-            if 'eject_cdrom' in self.install_config and not self.install_config['eject_cdrom']:
250
-                eject_cdrom = False
251
-            if eject_cdrom:
252
-                process = subprocess.Popen(['eject', '-r'], stdout=self.output)
253
-                process.wait()
246
+            self.eject_cdrom()
254 247
         return ActionResult(True, None)
255 248
 
256 249
     def copy_rpms(self):
... ...
@@ -263,7 +164,7 @@ class Installer(object):
263 263
 
264 264
         for pkg in selected_packages:
265 265
             if pkg in pkg_to_rpm_map:
266
-                if not pkg_to_rpm_map[pkg]['rpm'] is None:
266
+                if pkg_to_rpm_map[pkg]['rpm'] is not None:
267 267
                     name = pkg_to_rpm_map[pkg]['rpm']
268 268
                     basename = os.path.basename(name)
269 269
                     self.rpms_tobeinstalled.append({'filename': basename, 'path': name,
... ...
@@ -421,7 +322,7 @@ class Installer(object):
421 421
 
422 422
         rpms = set(rpm_file_names)
423 423
         rpm_paths = []
424
-        for root, dirs, files in os.walk(self.rpm_path):
424
+        for root, _, files in os.walk(self.rpm_path):
425 425
             for f in files:
426 426
                 if f in rpms:
427 427
                     rpm_paths.append(os.path.join(root, f))
... ...
@@ -457,7 +358,7 @@ class Installer(object):
457 457
                 continue
458 458
 
459 459
             # the module default is disabled
460
-            if not hasattr(mod, 'enabled') or mod.enabled == False:
460
+            if not hasattr(mod, 'enabled') or mod.enabled is False:
461 461
                 modules.commons.log(modules.commons.LOG_INFO,
462 462
                                     "module {} is not enabled".format(module))
463 463
                 continue
... ...
@@ -475,7 +376,7 @@ class Installer(object):
475 475
                                     "Error: not able to execute module {}".format(module))
476 476
                 continue
477 477
 
478
-            mod.execute(module, self.install_config, self.photon_root)
478
+            mod.execute(self.install_config, self.photon_root)
479 479
 
480 480
     def adjust_packages_for_vmware_virt(self):
481 481
         try:
... ...
@@ -492,3 +393,115 @@ class Installer(object):
492 492
                 selected_packages.append('linux-esx')
493 493
         except KeyError:
494 494
             pass
495
+
496
+    def setup_install_repo(self):
497
+        if self.iso_installer:
498
+            self.window.show_window()
499
+            self.progress_bar.initialize('Initializing installation...')
500
+            self.progress_bar.show()
501
+            #self.rpm_path = "https://dl.bintray.com/vmware/photon_release_1.0_TP2_x86_64"
502
+            if self.rpm_path.startswith("https://") or self.rpm_path.startswith("http://"):
503
+                cmdoption = 's/baseurl.*/baseurl={}/g'.format(self.rpm_path.replace('/', '\/'))
504
+                process = subprocess.Popen(['sed', '-i', cmdoption,
505
+                                            '/etc/yum.repos.d/photon-iso.repo'])
506
+                retval = process.wait()
507
+                if retval != 0:
508
+                    modules.commons.log(modules.commons.LOG_INFO, "Failed to reset repo")
509
+                    self.exit_gracefully(None, None)
510
+
511
+            cmdoption = ('s/cachedir=\/var/cachedir={}/g'
512
+                         .format(self.photon_root.replace('/', '\/')))
513
+            process = subprocess.Popen(['sed', '-i', cmdoption, '/etc/tdnf/tdnf.conf'])
514
+            retval = process.wait()
515
+            if retval != 0:
516
+                modules.commons.log(modules.commons.LOG_INFO, "Failed to reset tdnf cachedir")
517
+                self.exit_gracefully(None, None)
518
+
519
+    def install_packages(self):
520
+        if self.iso_installer:
521
+            self.tdnf_install_packages()
522
+        else:
523
+        #install packages
524
+            rpms = []
525
+            for rpm in self.rpms_tobeinstalled:
526
+                # We already installed the filesystem in the preparation
527
+                if rpm['package'] == 'filesystem':
528
+                    continue
529
+                rpms.append(rpm['filename'])
530
+            return_value = self.install_package(rpms)
531
+            if return_value != 0:
532
+                self.exit_gracefully(None, None)
533
+
534
+    def tdnf_install_packages(self):
535
+        self.adjust_packages_for_vmware_virt()
536
+        selected_packages = self.install_config['packages']
537
+        state = 0
538
+        packages_to_install = {}
539
+        total_size = 0
540
+        with open(modules.commons.TDNF_CMDLINE_FILE_NAME, "w") as tdnf_cmdline_file:
541
+            tdnf_cmdline_file.write("tdnf install --installroot {0} --nogpgcheck {1}"
542
+                                    .format(self.photon_root, " ".join(selected_packages)))
543
+        with open(modules.commons.TDNF_LOG_FILE_NAME, "w") as tdnf_errlog:
544
+            process = subprocess.Popen(['tdnf', 'install'] + selected_packages +
545
+                                       ['--installroot', self.photon_root, '--nogpgcheck',
546
+                                        '--assumeyes'], stdout=subprocess.PIPE,
547
+                                       stderr=tdnf_errlog)
548
+            while True:
549
+                output = process.stdout.readline().decode()
550
+                if output == '':
551
+                    retval = process.poll()
552
+                    if retval is not None:
553
+                        break
554
+                if state == 0:
555
+                    if output == 'Installing:\n':
556
+                        state = 1
557
+                elif state == 1: #N A EVR Size(readable) Size(in bytes)
558
+                    if output == '\n':
559
+                        state = 2
560
+                        self.progress_bar.update_num_items(total_size)
561
+                    else:
562
+                        info = output.split()
563
+                        package = '{0}-{1}.{2}'.format(info[0], info[2], info[1])
564
+                        packages_to_install[package] = int(info[5])
565
+                        total_size += int(info[5])
566
+                elif state == 2:
567
+                    if output == 'Downloading:\n':
568
+                        self.progress_bar.update_message('Preparing ...')
569
+                        state = 3
570
+                elif state == 3:
571
+                    self.progress_bar.update_message(output)
572
+                    if output == 'Running transaction\n':
573
+                        state = 4
574
+                else:
575
+                    modules.commons.log(modules.commons.LOG_INFO, "[tdnf] {0}".format(output))
576
+                    prefix = 'Installing/Updating: '
577
+                    if output.startswith(prefix):
578
+                        package = output[len(prefix):].rstrip('\n')
579
+                        self.progress_bar.increment(packages_to_install[package])
580
+
581
+                    self.progress_bar.update_message(output)
582
+            # 0 : succeed; 137 : package already installed; 65 : package not found in repo.
583
+            if retval != 0 and retval != 137:
584
+                modules.commons.log(modules.commons.LOG_ERROR,
585
+                                    "Failed to install some packages, refer to {0}"
586
+                                    .format(modules.commons.TDNF_LOG_FILE_NAME))
587
+                self.exit_gracefully(None, None)
588
+        self.progress_bar.show_loading('Finalizing installation')
589
+
590
+    def eject_cdrom(self):
591
+        eject_cdrom = True
592
+        if 'ui_install' in self.install_config:
593
+            self.window.content_window().getch()
594
+        if 'eject_cdrom' in self.install_config and not self.install_config['eject_cdrom']:
595
+            eject_cdrom = False
596
+        if eject_cdrom:
597
+            process = subprocess.Popen(['eject', '-r'], stdout=self.output)
598
+            process.wait()
599
+
600
+    def enable_network_in_chroot(self):
601
+        if os.path.exists("/etc/resolv.conf"):
602
+            shutil.copy("/etc/resolv.conf", self.photon_root + '/etc/.')
603
+
604
+    def disable_network_in_chroot(self):
605
+        if os.path.exists(self.photon_root + '/etc/resolv.conf'):
606
+            os.remove(self.photon_root + '/etc/resolv.conf')
... ...
@@ -18,24 +18,35 @@ from license import License
18 18
 from linuxselector import LinuxSelector
19 19
 
20 20
 class IsoConfig(object):
21
-    def Configure(self,options_file, maxy, maxx):
21
+    """This class handles iso installer configuration."""
22
+    def __init__(self):
22 23
         self.cd_path = None
24
+        self.alpha_chars = list(range(65, 91))
25
+        self.alpha_chars.extend(range(97, 123))
26
+        self.hostname_accepted_chars = self.alpha_chars
27
+        # Adding the numeric chars
28
+        self.hostname_accepted_chars.extend(range(48, 58))
29
+        # Adding the . and -
30
+        self.hostname_accepted_chars.extend([ord('.'), ord('-')])
31
+        self.random_id = '%12x' % random.randrange(16**12)
32
+        self.random_hostname = "photon-" + self.random_id.strip()
23 33
 
34
+    def Configure(self, options_file, maxy, maxx):
24 35
         kernel_params = subprocess.check_output(['cat', '/proc/cmdline'])
25 36
 
26 37
         # check for the repo param
27 38
         m = re.match(r".*repo=(\S+)\s*.*\s*", kernel_params.decode())
28
-        if m != None:
39
+        if m is not None:
29 40
             rpm_path = m.group(1)
30 41
         else:
31 42
             # the rpms should be in the cd
32
-            self.mount_RPMS_cd()
43
+            self.mount_cd()
33 44
             rpm_path = os.path.join(self.cd_path, "RPMS")
34 45
 
35 46
         # check the kickstart param
36 47
         ks_config = None
37 48
         m = re.match(r".*ks=(\S+)\s*.*\s*", kernel_params.decode())
38
-        if m != None:
49
+        if m is not None:
39 50
             ks_config = self.get_config(m.group(1))
40 51
 
41 52
         install_config = None
... ...
@@ -45,21 +56,23 @@ class IsoConfig(object):
45 45
             install_config = self.ui_config(options_file, maxy, maxx)
46 46
         return rpm_path, install_config
47 47
 
48
-    def is_vmware_virtualization(self):
48
+    @staticmethod
49
+    def is_vmware_virtualization():
50
+        """Detect vmware vm"""
49 51
         process = subprocess.Popen(['systemd-detect-virt'], stdout=subprocess.PIPE)
50 52
         out, err = process.communicate()
51 53
         if err is not None and err != 0:
52 54
             return False
53
-        else:
54
-            return out == 'vmware\n'
55
+        return out == 'vmware\n'
55 56
 
56 57
     def get_config(self, path):
58
+        """kick start configuration"""
57 59
         if path.startswith("http://"):
58 60
             # Do 5 trials to get the kick start
59 61
             # TODO: make sure the installer run after network is up
60 62
             ks_file_error = "Failed to get the kickstart file at {0}".format(path)
61 63
             wait = 1
62
-            for x in range(0, 5):
64
+            for _ in range(0, 5):
63 65
                 err_msg = ""
64 66
                 try:
65 67
                     response = requests.get(path, timeout=3)
... ...
@@ -70,9 +83,9 @@ class IsoConfig(object):
70 70
                     err_msg = e
71 71
 
72 72
                 modules.commons.log(modules.commons.LOG_ERROR,
73
-                    ks_file_error)
73
+                                    ks_file_error)
74 74
                 modules.commons.log(modules.commons.LOG_ERROR,
75
-                    "error msg: {0}".format(err_msg))
75
+                                    "error msg: {0}".format(err_msg))
76 76
                 print(ks_file_error)
77 77
                 print("retry in a second")
78 78
                 time.sleep(wait)
... ...
@@ -84,11 +97,12 @@ class IsoConfig(object):
84 84
             raise Exception(err_msg)
85 85
         else:
86 86
             if path.startswith("cdrom:/"):
87
-                self.mount_RPMS_cd()
87
+                self.mount_cd()
88 88
                 path = os.path.join(self.cd_path, path.replace("cdrom:/", "", 1))
89 89
             return (JsonWrapper(path)).read()
90 90
 
91
-    def mount_RPMS_cd(self):
91
+    def mount_cd(self):
92
+        """Mount the cd with RPMS"""
92 93
         # check if the cd is already mounted
93 94
         if self.cd_path:
94 95
             return
... ...
@@ -98,7 +112,7 @@ class IsoConfig(object):
98 98
         retval = process.wait()
99 99
 
100 100
         # Retry mount the CD
101
-        for i in range(0, 3):
101
+        for _ in range(0, 3):
102 102
             process = subprocess.Popen(['mount', '/dev/cdrom', '/mnt/cdrom'])
103 103
             retval = process.wait()
104 104
             if retval == 0:
... ...
@@ -111,6 +125,8 @@ class IsoConfig(object):
111 111
         raise Exception("Can not mount the cd")
112 112
 
113 113
     def ks_config(self, options_file, ks_config):
114
+        """Load configuration from file"""
115
+        del options_file
114 116
         install_config = ks_config
115 117
         install_config['iso_system'] = False
116 118
         if self.is_vmware_virtualization() and 'install_linux_esx' not in install_config:
... ...
@@ -123,7 +139,9 @@ class IsoConfig(object):
123 123
         base_path = os.path.dirname("build_install_options_all.json")
124 124
         package_list = []
125 125
 
126
-        package_list = PackageSelector.get_packages_to_install(options_sorted, install_config['type'], base_path)
126
+        package_list = PackageSelector.get_packages_to_install(options_sorted,
127
+                                                               install_config['type'],
128
+                                                               base_path)
127 129
         if 'additional_packages' in install_config:
128 130
             package_list.extend(install_config['additional_packages'])
129 131
         install_config['packages'] = package_list
... ...
@@ -139,77 +157,103 @@ class IsoConfig(object):
139 139
             evalhostname = os.popen('printf ' + install_config["hostname"].strip(" ")).readlines()
140 140
             install_config['hostname'] = evalhostname[0]
141 141
         if "hostname" not in install_config or install_config['hostname'] == "":
142
-            random_id = '%12x' % random.randrange(16**12)
143
-            install_config['hostname'] = "photon-" + random_id.strip()
142
+            install_config['hostname'] = "photon-" + self.random_id.strip()
144 143
 
145 144
         # crypt the password if needed
146 145
         if install_config['password']['crypted']:
147 146
             install_config['password'] = install_config['password']['text']
148 147
         else:
149
-            install_config['password'] = crypt.crypt(install_config['password']['text'],
150
-                "$6$" + "".join([random.choice(string.ascii_letters + string.digits) for _ in range(16)]))
148
+            install_config['password'] = crypt.crypt(
149
+                install_config['password']['text'],
150
+                "$6$" + "".join([random.choice(
151
+                    string.ascii_letters + string.digits) for _ in range(16)]))
151 152
         return install_config
152 153
 
153
-    def validate_hostname(self, hostname):
154
+    @staticmethod
155
+    def validate_hostname(hostname):
156
+        """A valid hostname must start with a letter"""
154 157
         error_empty = "Empty hostname or domain is not allowed"
155 158
         error_dash = "Hostname or domain should not start or end with '-'"
156 159
         error_hostname = "Hostname should start with alpha char and <= 64 chars"
157 160
 
158
-        if hostname is None or len(hostname) == 0:
161
+        if hostname is None or not hostname:
159 162
             return False, error_empty
160 163
 
161 164
         fields = hostname.split('.')
162 165
         for field in fields:
163
-            if len(field) == 0:
166
+            if not field:
164 167
                 return False, error_empty
165 168
             if field[0] == '-' or field[-1] == '-':
166 169
                 return False, error_dash
167 170
 
168 171
         machinename = fields[0]
169
-        return (len(machinename) <= 64) and (ord(machinename[0]) in self.alpha_chars), error_hostname
172
+        return (len(machinename) <= 64 and
173
+                machinename[0].isalpha(), error_hostname)
170 174
 
171 175
     @staticmethod
172 176
     def validate_password(text):
177
+        """Validate password with cracklib"""
173 178
         try:
174
-            p = cracklib.VeryFascistCheck(text)
179
+            password = cracklib.VeryFascistCheck(text)
175 180
         except ValueError as message:
176
-            p = str(message)
177
-        return p == text, "Error: " + p
181
+            password = str(message)
182
+        return password == text, "Error: " + password
178 183
 
179 184
     @staticmethod
180 185
     def generate_password_hash(password):
181
-        shadow_password = crypt.crypt(password, "$6$" + "".join([random.choice(string.ascii_letters + string.digits) for _ in range(16)]))
186
+        """Generate hash for the password"""
187
+        shadow_password = crypt.crypt(
188
+            password, "$6$" + "".join(
189
+                [random.choice(
190
+                    string.ascii_letters + string.digits) for _ in range(16)]))
182 191
         return shadow_password
183 192
 
184 193
     def ui_config(self, options_file, maxy, maxx):
185
-        # This represents the installer screen, the bool indicated if I can go back to this window or not
186
-        items = []
187
-        random_id = '%12x' % random.randrange(16**12)
188
-        random_hostname = "photon-" + random_id.strip()
194
+        """Configuration through UI"""
195
+        # This represents the installer screen, the bool indicated if
196
+        # I can go back to this window or not
189 197
         install_config = {'iso_system': False}
190 198
         install_config['ui_install'] = True
199
+        items, select_linux_index = self.add_ui_pages(options_file, maxy, maxx,
200
+                                                      install_config)
201
+        index = 0
202
+        while True:
203
+            result = items[index][0](None)
204
+            if result.success:
205
+                index += 1
206
+                if index == len(items):
207
+                    break
208
+                #Skip linux select screen for ostree installation.
209
+                if index == select_linux_index:
210
+                    if install_config['type'] == 'ostree_server':
211
+                        index += 1
212
+            else:
213
+                index -= 1
214
+                while index >= 0 and items[index][1] is False:
215
+                    index -= 1
216
+                if index < 0:
217
+                    index = 0
218
+                #Skip linux select screen for ostree installation.
219
+                if index == select_linux_index:
220
+                    if install_config['type'] == 'ostree_server':
221
+                        index -= 1
222
+        return install_config
223
+    def add_ui_pages(self, options_file, maxy, maxx, install_config):
224
+        items = []
191 225
         license_agreement = License(maxy, maxx)
192 226
         select_disk = SelectDisk(maxy, maxx, install_config)
193 227
         select_partition = PartitionISO(maxy, maxx, install_config)
194 228
         package_selector = PackageSelector(maxy, maxx, install_config, options_file)
195
-        self.alpha_chars = list(range(65, 91))
196
-        self.alpha_chars.extend(range(97, 123))
197
-        hostname_accepted_chars = self.alpha_chars
198
-        # Adding the numeric chars
199
-        hostname_accepted_chars.extend(range(48, 58))
200
-        # Adding the . and -
201
-        hostname_accepted_chars.extend([ord('.'), ord('-')])
202
-
203 229
         hostname_reader = WindowStringReader(
204 230
             maxy, maxx, 10, 70,
205 231
             'hostname',
206 232
             None, # confirmation error msg if it's a confirmation text
207 233
             None, # echo char
208
-            hostname_accepted_chars, # set of accepted chars
209
-            self.validate_hostname, # validation function of the input
234
+            self.hostname_accepted_chars, # set of accepted chars
235
+            IsoConfig.validate_hostname, # validation function of the input
210 236
             None, # post processing of the input field
211 237
             'Choose the hostname for your system', 'Hostname:', 2, install_config,
212
-            random_hostname,
238
+            self.random_hostname,
213 239
             True)
214 240
         root_password_reader = WindowStringReader(
215 241
             maxy, maxx, 10, 70,
... ...
@@ -223,7 +267,8 @@ class IsoConfig(object):
223 223
         confirm_password_reader = WindowStringReader(
224 224
             maxy, maxx, 10, 70,
225 225
             'password',
226
-            "Passwords don't match, please try again.", # confirmation error msg if it's a confirmation text
226
+            # confirmation error msg if it's a confirmation text
227
+            "Passwords don't match, please try again.",
227 228
             '*', # echo char
228 229
             None, # set of accepted chars
229 230
             None, # validation function of the input
... ...
@@ -243,27 +288,4 @@ class IsoConfig(object):
243 243
         items.append((hostname_reader.get_user_string, True))
244 244
         items.append((root_password_reader.get_user_string, True))
245 245
         items.append((confirm_password_reader.get_user_string, False))
246
-        index = 0
247
-        params = None
248
-        while True:
249
-            result = items[index][0](params)
250
-            if result.success:
251
-                index += 1
252
-                params = result.result
253
-                if index == len(items):
254
-                    break
255
-                #Skip linux select screen for ostree installation.
256
-                if index == select_linux_index:
257
-                    if install_config['type'] == 'ostree_server':
258
-                        index += 1
259
-            else:
260
-                index -= 1
261
-                while index >= 0 and items[index][1] is False:
262
-                    index -= 1
263
-                if index < 0:
264
-                    index = 0
265
-                #Skip linux select screen for ostree installation.
266
-                if index == select_linux_index:
267
-                    if install_config['type'] == 'ostree_server':
268
-                        index -= 1
269
-        return install_config
246
+        return items, select_linux_index
... ...
@@ -6,8 +6,8 @@ PRE_INSTALL = "pre-install"
6 6
 POST_INSTALL = "post-install"
7 7
 
8 8
 LOG_LEVEL_DESC = ["emerg", "alert", "crit", "err", "warning", "notice", "info", "debug"]
9
-LOG_FILE_NAME  = "/var/log/installer.log"
10
-TDNF_LOG_FILE_NAME  = "/var/log/tdnf.log"
9
+LOG_FILE_NAME = "/var/log/installer.log"
10
+TDNF_LOG_FILE_NAME = "/var/log/tdnf.log"
11 11
 TDNF_CMDLINE_FILE_NAME = "/var/log/tdnf.cmdline"
12 12
 KS_POST_INSTALL_LOG_FILE_NAME = "/var/log/installer-kickstart.log"
13 13
 SIGNATURE   = "localhost echo"
... ...
@@ -21,8 +21,8 @@ LOG_INFO    = 6
21 21
 LOG_DEBUG   = 7
22 22
 
23 23
 default_partitions = [
24
-                        {"mountpoint": "/", "size": 0, "filesystem": "ext4"},
25
-                     ]
24
+    {"mountpoint": "/", "size": 0, "filesystem": "ext4"},
25
+    ]
26 26
 
27 27
 def partition_compare(p):
28 28
     if 'mountpoint' in p:
... ...
@@ -36,7 +36,7 @@ def partition_disk(disk, partitions):
36 36
     output = open(os.devnull, 'w')
37 37
 
38 38
     # Clear the disk
39
-    process = subprocess.Popen(['sgdisk', '-o', '-g', disk], stderr = output, stdout = output)
39
+    process = subprocess.Popen(['sgdisk', '-o', '-g', disk], stderr=output, stdout=output)
40 40
     retval = process.wait()
41 41
     if retval != 0:
42 42
         log(LOG_ERROR, "Failed clearing disk {0}".format(disk))
... ...
@@ -58,7 +58,7 @@ def partition_disk(disk, partitions):
58 58
     # Adding the known size partitions
59 59
     for partition in partitions:
60 60
         if partition['size'] == 0:
61
-            # Can not have more than 1 extensible partition 
61
+            # Can not have more than 1 extensible partition
62 62
             if extensible_partition != None:
63 63
                 log(LOG_ERROR, "Can not have more than 1 extensible partition")
64 64
                 return None
... ...
@@ -80,13 +80,13 @@ def partition_disk(disk, partitions):
80 80
     partition_cmd.extend(['-p', disk])
81 81
 
82 82
     # Run the partitioning command
83
-    process = subprocess.Popen(partition_cmd, stderr = output, stdout = output)
83
+    process = subprocess.Popen(partition_cmd, stderr=output, stdout=output)
84 84
     retval = process.wait()
85 85
     if retval != 0:
86 86
         log(LOG_ERROR, "Faild partition disk, command: {0}". format(partition_cmd))
87 87
         return None
88 88
 
89
-    process = subprocess.Popen(['sgdisk', '-t1' + grub_flag, disk], stderr = output, stdout = output)
89
+    process = subprocess.Popen(['sgdisk', '-t1' + grub_flag, disk], stderr=output, stdout=output)
90 90
     retval = process.wait()
91 91
     if retval != 0:
92 92
         log(LOG_ERROR, "Failed to setup grub partition")
... ...
@@ -103,25 +103,27 @@ def partition_disk(disk, partitions):
103 103
                 partitions_data['boot_partition_number'] = partition['partition_number']
104 104
                 partitions_data['bootdirectory'] = '/'
105 105
         if partition['filesystem'] == "swap":
106
-            process = subprocess.Popen(['mkswap', partition['path']], stderr = output, stdout = output)
106
+            process = subprocess.Popen(['mkswap', partition['path']], stderr=output, stdout=output)
107 107
             retval = process.wait()
108 108
             if retval != 0:
109 109
                 log(LOG_ERROR, "Failed to create swap partition @ {}".format(partition['path']))
110 110
                 return None
111 111
         else:
112 112
             mkfs_cmd = ['mkfs', '-t', partition['filesystem'], partition['path']]
113
-            process = subprocess.Popen(mkfs_cmd, stderr = output, stdout = output)
113
+            process = subprocess.Popen(mkfs_cmd, stderr=output, stdout=output)
114 114
             retval = process.wait()
115 115
             if retval != 0:
116
-                log(LOG_ERROR, "Failed to format {} partition @ {}".format(partition['filesystem'], partition['path']))
116
+                log(LOG_ERROR,
117
+                    "Failed to format {} partition @ {}".format(partition['filesystem'],
118
+                                                                partition['path']))
117 119
                 return None
118 120
 
119 121
     # Check if there is no root partition
120
-    if not 'root' in partitions_data:
122
+    if 'root' not in partitions_data:
121 123
         log(LOG_ERROR, "There is no partition assigned to root '/'")
122 124
         return None
123 125
 
124
-    if not 'boot' in partitions_data:
126
+    if 'boot' not in partitions_data:
125 127
         partitions_data['boot'] = partitions_data['root']
126 128
         partitions_data['boot_partition_number'] = partitions_data['root_partition_number']
127 129
         partitions_data['bootdirectory'] = '/boot/'
... ...
@@ -130,9 +132,9 @@ def partition_disk(disk, partitions):
130 130
 
131 131
     return partitions_data
132 132
 
133
-def replace_string_in_file(filename,  search_string,  replace_string):
133
+def replace_string_in_file(filename, search_string, replace_string):
134 134
     with open(filename, "r") as source:
135
-        lines=source.readlines()
135
+        lines = source.readlines()
136 136
 
137 137
     with open(filename, "w") as destination:
138 138
         for line in lines:
... ...
@@ -145,7 +147,8 @@ def log(type, message):
145 145
     return retval
146 146
 
147 147
 def dump(type, filename):
148
-    command = "journalctl -p {0} | grep --line-buffered \"{1}\" > {2}".format(LOG_LEVEL_DESC[type], SIGNATURE, filename)
148
+    command = ("journalctl -p {0} | grep --line-buffered \"{1}\" > {2}"
149
+               .format(LOG_LEVEL_DESC[type], SIGNATURE, filename))
149 150
     process = subprocess.Popen([command], shell=True)
150 151
     retval = process.wait()
151 152
     return retval
... ...
@@ -153,5 +156,5 @@ def dump(type, filename):
153 153
 def dump(filename):
154 154
     command = "journalctl | grep --line-buffered \"{0}\" > {1}".format(SIGNATURE, filename)
155 155
     process = subprocess.Popen([command], shell=True)
156
-    retval = process.wait()    
156
+    retval = process.wait()
157 157
     return retval
... ...
@@ -5,7 +5,7 @@ import commons
5 5
 install_phase = commons.POST_INSTALL
6 6
 enabled = True
7 7
 
8
-def execute(name, config, root):
8
+def execute(config, root):
9 9
     if 'postinstall' not in config:
10 10
         return
11 11
     # run the script in the chroot environment
... ...
@@ -13,14 +13,15 @@ def execute(name, config, root):
13 13
 
14 14
     script_file = os.path.join(root, 'etc/tmpfiles.d/postinstall.sh')
15 15
 
16
-    with open(script_file,  'wb') as outfile:
16
+    with open(script_file, 'wb') as outfile:
17 17
         outfile.write("\n".join(script).encode())
18 18
 
19
-    os.chmod(script_file, 0o700);
20
-    with open(commons.KS_POST_INSTALL_LOG_FILE_NAME,"w") as logfile:
21
-        process = subprocess.Popen(["./mk-run-chroot.sh", '-w', root, "/etc/tmpfiles.d/postinstall.sh"],
22
-            stdout=logfile,stderr=logfile)
19
+    os.chmod(script_file, 0o700)
20
+    with open(commons.KS_POST_INSTALL_LOG_FILE_NAME, "w") as logfile:
21
+        process = subprocess.Popen(["./mk-run-chroot.sh", '-w', root,
22
+                                    "/etc/tmpfiles.d/postinstall.sh"],
23
+                                   stdout=logfile, stderr=logfile)
23 24
         retval = process.wait()
24
-        if retval==0:
25
+        if retval == 0:
25 26
             return True
26 27
         return False
... ...
@@ -1,11 +1,11 @@
1 1
 import os
2
-import commons
3 2
 import random
3
+import commons
4 4
 
5 5
 install_phase = commons.POST_INSTALL
6 6
 enabled = True
7 7
 
8
-def execute(name, config, root):
8
+def execute(config, root):
9 9
     hostname = config['hostname']
10 10
 
11 11
     hostname_file = os.path.join(root, 'etc/hostname')
... ...
@@ -1,26 +1,25 @@
1 1
 import os
2
-import commons
3 2
 import crypt
4 3
 import random
5 4
 import string
5
+import commons
6 6
 
7 7
 install_phase = commons.POST_INSTALL
8 8
 enabled = True
9 9
 
10
-def execute(name, config, root):
10
+def execute(config, root):
11 11
     shadow_password = config['password']
12 12
 
13 13
     passwd_filename = os.path.join(root, 'etc/passwd')
14 14
     shadow_filename = os.path.join(root, 'etc/shadow')
15
-    
15
+
16 16
     #replace root blank password in passwd file to point to shadow file
17
-    commons.replace_string_in_file(passwd_filename,  "root::", "root:x:")
17
+    commons.replace_string_in_file(passwd_filename, "root::", "root:x:")
18 18
 
19 19
     if os.path.isfile(shadow_filename) == False:
20 20
         with open(shadow_filename, "w") as destination:
21
-            destination.write("root:"+shadow_password+":")
21
+            destination.write("root:" + shadow_password + ":")
22 22
     else:
23 23
         #add password hash in shadow file
24 24
         commons.replace_string_in_file(shadow_filename, "root::", "root:"+shadow_password+":")
25 25
         commons.replace_string_in_file(shadow_filename, "root:x:", "root:"+shadow_password+":")
26
-
... ...
@@ -5,7 +5,7 @@ import commons
5 5
 install_phase = commons.POST_INSTALL
6 6
 enabled = True
7 7
 
8
-def execute(name, config, root):
8
+def execute(config, root):
9 9
     if 'public_key' not in config:
10 10
         return
11 11
 
... ...
@@ -21,5 +21,6 @@ def execute(name, config, root):
21 21
     os.chmod(authorized_keys_filename, 0o600)
22 22
 
23 23
     # Change the sshd config to allow root login
24
-    process = subprocess.Popen(["sed", "-i", "s/^\\s*PermitRootLogin\s\+no/PermitRootLogin yes/", sshd_config_filename])
24
+    process = subprocess.Popen(["sed", "-i", "s/^\\s*PermitRootLogin\s\+no/PermitRootLogin yes/",
25
+                                sshd_config_filename])
25 26
     return process.wait()
... ...
@@ -1,13 +1,13 @@
1
-#!/usr/bin/python2
1
+#!/usr/bin/python3
2 2
 
3 3
 import os
4 4
 import re
5 5
 import shutil
6 6
 import tarfile
7 7
 import fileinput
8
-from optparse import OptionParser
9
-from utils import Utils
8
+from argparse import ArgumentParser
10 9
 import json
10
+from utils import Utils
11 11
 
12 12
 def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
13 13
     output_path = os.path.dirname(os.path.realpath(raw_image_name))
... ...
@@ -19,15 +19,23 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
19 19
             os.remove(os.path.join(output_path, file))
20 20
 
21 21
     vmx_path = output_path + '/photon-ova.vmx'
22
-    utils.replaceandsaveasnewfile(build_scripts_path + '/vmx-template', vmx_path, 'VMDK_IMAGE', output_path + '/photon-ova.vmdk')
22
+    utils.replaceandsaveasnewfile(build_scripts_path + '/vmx-template',
23
+                                  vmx_path, 'VMDK_IMAGE',
24
+                                  output_path + '/photon-ova.vmdk')
23 25
     vixdiskutil_path = tools_path + 'vixdiskutil'
24 26
     vmdk_path = output_path + '/photon-ova.vmdk'
25 27
     ovf_path = output_path + '/photon-ova.ovf'
26 28
     mf_path = output_path + '/photon-ova.mf'
27 29
     ovfinfo_path = build_scripts_path + '/ovfinfo.txt'
28
-    vmdk_capacity = (int(config['size']['root']) + int(config['size']['swap'])) * 1024
29
-    utils.runshellcommand("{} -convert {} -cap {} {}".format(vixdiskutil_path, raw_image_name, vmdk_capacity, vmdk_path))
30
-    utils.runshellcommand("{} -wmeta toolsVersion 2147483647 {}".format(vixdiskutil_path, vmdk_path))
30
+    vmdk_capacity = (int(config['size']['root']) +
31
+                     int(config['size']['swap'])) * 1024
32
+    utils.runshellcommand(
33
+        "{} -convert {} -cap {} {}".format(vixdiskutil_path,
34
+                                           raw_image_name,
35
+                                           vmdk_capacity,
36
+                                           vmdk_path))
37
+    utils.runshellcommand(
38
+        "{} -wmeta toolsVersion 2147483647 {}".format(vixdiskutil_path, vmdk_path))
31 39
 
32 40
     utils.runshellcommand("ovftool {} {}".format(vmx_path, ovf_path))
33 41
     utils.replaceinfile(ovf_path, 'otherGuest', 'other3xLinux64Guest')
... ...
@@ -39,9 +47,9 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
39 39
             for line in fileinput.input(ovf_path, inplace=True):
40 40
                 if line.strip() == '</VirtualHardwareSection>':
41 41
                     for ovfinfoline in lines:
42
-                        print ovfinfoline,
42
+                        print(ovfinfoline)
43 43
                 else:
44
-                    print line,
44
+                    print(line)
45 45
 
46 46
     if os.path.exists(mf_path):
47 47
         os.remove(mf_path)
... ...
@@ -54,7 +62,7 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
54 54
     rawsplit = os.path.splitext(raw_image_name)
55 55
     ova_name = rawsplit[0] + '.ova'
56 56
 
57
-    ovatar = tarfile.open(ova_name, "w", format = tarfile.USTAR_FORMAT)
57
+    ovatar = tarfile.open(ova_name, "w", format=tarfile.USTAR_FORMAT)
58 58
     for name in ["photon-ova.ovf", "photon-ova.mf", "photon-ova-disk1.vmdk"]:
59 59
         ovatar.add(name, arcname=os.path.basename(name))
60 60
     ovatar.close()
... ...
@@ -65,15 +73,17 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
65 65
         for addlversion in config['additionalhwversion']:
66 66
             new_ovf_path = output_path + "/photon-ova-hw{}.ovf".format(addlversion)
67 67
             mf_path = output_path + "/photon-ova-hw{}.mf".format(addlversion)
68
-            utils.replaceandsaveasnewfile(ovf_path, new_ovf_path, "vmx-.*<", "vmx-{}<".format(addlversion))
69
-            out = utils.runshellcommand("openssl sha1 photon-ova-disk1.vmdk photon-ova-hw{}.ovf".format(addlversion))
68
+            utils.replaceandsaveasnewfile(
69
+                ovf_path, new_ovf_path, "vmx-.*<", "vmx-{}<".format(addlversion))
70
+            out = utils.runshellcommand("openssl sha1 photon-ova-disk1.vmdk "
71
+                                        "photon-ova-hw{}.ovf".format(addlversion))
70 72
             with open(mf_path, "w") as source:
71 73
                 source.write(out)
72 74
             temp_name_list = os.path.basename(ova_name).split('-')
73 75
             temp_name_list = temp_name_list[:2] + ["hw{}".format(addlversion)] + temp_name_list[2:]
74 76
             new_ova_name = '-'.join(temp_name_list)
75 77
             new_ova_path = output_path + '/' + new_ova_name
76
-            ovatar = tarfile.open(new_ova_path, "w", format = tarfile.USTAR_FORMAT)
78
+            ovatar = tarfile.open(new_ova_path, "w", format=tarfile.USTAR_FORMAT)
77 79
             for name in [new_ovf_path, mf_path, "photon-ova-disk1.vmdk"]:
78 80
                 ovatar.add(name, arcname=os.path.basename(name))
79 81
             ovatar.close()
... ...
@@ -91,70 +101,81 @@ def create_ova_image(raw_image_name, tools_path, build_scripts_path, config):
91 91
 
92 92
 if __name__ == '__main__':
93 93
     usage = "Usage: %prog [options]"
94
-    parser = OptionParser(usage)
95
-
96
-    parser.add_option("-r", "--raw-image-path",  dest="raw_image_path")
97
-    parser.add_option("-c", "--vmdk-config-path", dest="vmdk_config_path")
98
-    parser.add_option("-w",  "--working-directory",  dest="working_directory")
99
-    parser.add_option("-m",  "--mount-path",  dest="mount_path")
100
-    parser.add_option("-a",  "--additional-rpms-path",  dest="additional_rpms_path")
101
-    parser.add_option("-i",  "--image-name",  dest="image_name")
102
-    parser.add_option("-t",  "--tools-bin-path",  dest="tools_bin_path")
103
-    parser.add_option("-b",  "--build-scripts-path",  dest="build_scripts_path")
104
-    parser.add_option("-s",  "--src-root",  dest="src_root")
105
-
106
-    (options,  args) = parser.parse_args()
94
+    parser = ArgumentParser(usage)
95
+
96
+    parser.add_argument("-r", "--raw-image-path", dest="raw_image_path")
97
+    parser.add_argument("-c", "--vmdk-config-path", dest="vmdk_config_path")
98
+    parser.add_argument("-w", "--working-directory", dest="working_directory")
99
+    parser.add_argument("-m", "--mount-path", dest="mount_path")
100
+    parser.add_argument("-a", "--additional-rpms-path", dest="additional_rpms_path")
101
+    parser.add_argument("-i", "--image-name", dest="image_name")
102
+    parser.add_argument("-t", "--tools-bin-path", dest="tools_bin_path")
103
+    parser.add_argument("-b", "--build-scripts-path", dest="build_scripts_path")
104
+    parser.add_argument("-s", "--src-root", dest="src_root")
105
+
106
+    options = parser.parse_args()
107 107
     utils = Utils()
108 108
     config = utils.jsonread(options.vmdk_config_path)
109
-    print options
109
+    print(options)
110 110
 
111
-    disk_device = (utils.runshellcommand("losetup --show -f {}".format(options.raw_image_path))).rstrip('\n')
111
+    disk_device = (utils.runshellcommand(
112
+        "losetup --show -f {}".format(options.raw_image_path))).rstrip('\n')
112 113
     disk_partitions = utils.runshellcommand("kpartx -as {}".format(disk_device))
113 114
     device_name = disk_device.split('/')[2]
114 115
 
115 116
     if not os.path.exists(options.mount_path):
116 117
         os.mkdir(options.mount_path)
117
-    loop_device_path =  "/dev/mapper/{}p2".format(device_name)
118
+    loop_device_path = "/dev/mapper/{}p2".format(device_name)
118 119
 
119 120
     try:
120
-        print "Generating PARTUUID for the loop device ..."
121
-        partuuidval = (utils.runshellcommand("blkid -s PARTUUID -o value {}".format(loop_device_path))).rstrip('\n')
122
-        uuidval = (utils.runshellcommand("blkid -s UUID -o value {}".format(loop_device_path))).rstrip('\n')
123
-        if (partuuidval == ''):
124
-            sgdiskout = utils.runshellcommand("sgdisk -i 2 {} ".format(disk_device))
125
-            partuuidval = (re.findall(r'Partition unique GUID.*', sgdiskout))[0].split(':')[1].strip(' ').lower()
126
-
127
-        if (partuuidval == ''):
121
+        print("Generating PARTUUID for the loop device ...")
122
+        partuuidval = (utils.runshellcommand(
123
+            "blkid -s PARTUUID -o value {}".format(loop_device_path))).rstrip('\n')
124
+        uuidval = (utils.runshellcommand(
125
+            "blkid -s UUID -o value {}".format(loop_device_path))).rstrip('\n')
126
+        if partuuidval == '':
127
+            sgdiskout = utils.runshellcommand(
128
+                "sgdisk -i 2 {} ".format(disk_device))
129
+            partuuidval = (re.findall(r'Partition unique GUID.*',
130
+                                      sgdiskout))[0].split(':')[1].strip(' ').lower()
131
+
132
+        if partuuidval == '':
128 133
             raise RuntimeError("Cannot generate partuuid")
129 134
 
130 135
         # Mount the loop device
131
-        print "Mounting the loop device for customization ..."
132
-        utils.runshellcommand("mount -t ext4 {} {}".format(loop_device_path, options.mount_path))
136
+        print("Mounting the loop device for customization ...")
137
+        utils.runshellcommand(
138
+            "mount -t ext4 {} {}".format(loop_device_path, options.mount_path))
133 139
         shutil.rmtree(options.mount_path + "/installer", ignore_errors=True)
134 140
         shutil.rmtree(options.mount_path + "/LOGS", ignore_errors=True)
135 141
         # Clear the root password if not set explicitly from the config file
136
-        if (config['password']['text'] != 'PASSWORD'):
137
-            utils.replaceinfile(options.mount_path + "/etc/shadow",'root:.*?:','root:*:')
142
+        if config['password']['text'] != 'PASSWORD':
143
+            utils.replaceinfile(options.mount_path + "/etc/shadow",
144
+                                'root:.*?:', 'root:*:')
138 145
         # Clear machine-id so it gets regenerated on boot
139 146
         open(options.mount_path + "/etc/machine-id", "w").close()
140 147
         os.remove(options.mount_path + "/etc/fstab")
141 148
 
142 149
         f = open(options.mount_path + "/etc/fstab", "w")
143
-        if (uuidval != ''):
150
+        if uuidval != '':
144 151
             f.write("UUID={}    /    ext4    defaults 1 1\n".format(uuidval))
145 152
         else:
146 153
             f.write("PARTUUID={}    /    ext4    defaults 1 1\n".format(partuuidval))
147 154
         f.close()
148
-        utils.replaceinfile(options.mount_path + "/boot/grub/grub.cfg", "rootpartition=PARTUUID=.*$", "rootpartition=PARTUUID={}".format(partuuidval))
155
+        utils.replaceinfile(options.mount_path + "/boot/grub/grub.cfg",
156
+                            "rootpartition=PARTUUID=.*$",
157
+                            "rootpartition=PARTUUID={}".format(partuuidval))
149 158
 
150 159
         if os.path.exists(options.additional_rpms_path):
151
-            print "Installing additional rpms"
160
+            print("Installing additional rpms")
152 161
             os.mkdir(options.mount_path + "/additional_rpms")
153 162
             os.mkdir(options.mount_path + "/var/run")
154
-            utils.copyallfiles(additional_rpms_path, options.mount_path + "/additional_rpms")
155
-            utils.runshellcommand("chroot {} /bin/bash -c 'rpm -i /additional_rpms/*'".format(options.mount_path))
163
+            utils.copyallfiles(options.additional_rpms_path,
164
+                               options.mount_path + "/additional_rpms")
165
+            utils.runshellcommand(
166
+                "chroot {} /bin/bash -c 'rpm -i /additional_rpms/*'".format(options.mount_path))
156 167
             shutil.rmtree(options.mount_path + "/additional_rpms", ignore_errors=True)
157
-            shutil.rmtree(additional_rpms_path, ignore_errors=True)
168
+            shutil.rmtree(options.additional_rpms_path, ignore_errors=True)
158 169
 
159 170
         utils.runshellcommand("mount -o bind /proc {}".format(options.mount_path + "/proc"))
160 171
         utils.runshellcommand("mount -o bind /dev {}".format(options.mount_path + "/dev"))
... ...
@@ -162,28 +183,36 @@ if __name__ == '__main__':
162 162
         utils.runshellcommand("mount -o bind /sys {}".format(options.mount_path + "/sys"))
163 163
 
164 164
         if 'additionalfiles' in config:
165
-            print "  Copying additional files into the raw image ..."
165
+            print("  Copying additional files into the raw image ...")
166 166
             for filetuples in config['additionalfiles']:
167
-                for src,dest in filetuples.iteritems():
168
-		    if (os.path.isdir(options.build_scripts_path + '/' + options.image_name + '/' + src)):
169
-                        shutil.copytree(options.build_scripts_path + '/' + options.image_name + '/' + src, options.mount_path + dest, True)
167
+                for src, dest in filetuples.items():
168
+                    if (os.path.isdir(options.build_scripts_path + '/' +
169
+                                      options.image_name + '/' + src)):
170
+                        shutil.copytree(options.build_scripts_path + '/' +
171
+                                        options.image_name + '/' + src,
172
+                                        options.mount_path + dest, True)
170 173
                     else:
171
-                        shutil.copyfile(options.build_scripts_path + '/' + options.image_name + '/' + src, options.mount_path + dest)
174
+                        shutil.copyfile(options.build_scripts_path + '/' +
175
+                                        options.image_name + '/' + src,
176
+                                        options.mount_path + dest)
172 177
 
173 178
 
174 179
         if 'postinstallscripts' in config:
175
-            print "  Running post install scripts ..."
180
+            print("  Running post install scripts ...")
176 181
             if not os.path.exists(options.mount_path + "/tempscripts"):
177 182
                 os.mkdir(options.mount_path + "/tempscripts")
178 183
             for script in config['postinstallscripts']:
179
-                shutil.copy(options.build_scripts_path + '/' + options.image_name + '/' + script, options.mount_path + "/tempscripts")
184
+                shutil.copy(options.build_scripts_path + '/' +
185
+                            options.image_name + '/' + script,
186
+                            options.mount_path + "/tempscripts")
180 187
             for script in os.listdir(options.mount_path + "/tempscripts"):
181
-                print "     ...running script {}".format(script)
182
-                utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'".format(options.mount_path, script))
188
+                print("     ...running script {}".format(script))
189
+                utils.runshellcommand(
190
+                    "chroot {} /bin/bash -c '/tempscripts/{}'".format(options.mount_path, script))
183 191
             shutil.rmtree(options.mount_path + "/tempscripts", ignore_errors=True)
184 192
 
185 193
     except Exception as e:
186
-	print e
194
+        print(e)
187 195
 
188 196
     finally:
189 197
         utils.runshellcommand("umount -l {}".format(options.mount_path + "/sys"))
... ...
@@ -195,8 +224,8 @@ if __name__ == '__main__':
195 195
         utils.runshellcommand("umount -l {}".format(options.mount_path))
196 196
 
197 197
         mount_out = utils.runshellcommand("mount")
198
-        print "List of mounted devices:"
199
-        print mount_out
198
+        print("List of mounted devices:")
199
+        print(mount_out)
200 200
 
201 201
         utils.runshellcommand("kpartx -d {}".format(disk_device))
202 202
         utils.runshellcommand("losetup -d {}".format(disk_device))
... ...
@@ -210,39 +239,56 @@ if __name__ == '__main__':
210 210
         img_path = os.path.dirname(os.path.realpath(raw_image))
211 211
         # Rename gce image to disk.raw
212 212
         if options.image_name == "gce":
213
-            print "Renaming the raw file to disk.raw ..."
213
+            print("Renaming the raw file to disk.raw ...")
214 214
             new_name = img_path + '/disk.raw'
215 215
 
216 216
         else:
217
-            new_name = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.raw'
217
+            new_name = (img_path + '/photon-' + options.image_name +
218
+                        '-' + photon_release_ver + '-' +
219
+                        photon_build_num + '.raw')
218 220
 
219 221
         shutil.move(raw_image, new_name)
220 222
         raw_image = new_name
221 223
 
222 224
         if config['artifacttype'] == 'tgz':
223
-            print "Generating the tar.gz artifact ..."
224
-            tarname = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.tar.gz'
225
+            print("Generating the tar.gz artifact ...")
226
+            tarname = (img_path + '/photon-' + options.image_name +
227
+                       '-' + photon_release_ver + '-' +
228
+                       photon_build_num + '.tar.gz')
229
+
225 230
             tgzout = tarfile.open(tarname, "w:gz")
226 231
             tgzout.add(raw_image, arcname=os.path.basename(raw_image))
227 232
             tgzout.close()
228 233
         elif config['artifacttype'] == 'xz':
229
-            print "Generating the xz artifact ..."
234
+            print("Generating the xz artifact ...")
230 235
             utils.runshellcommand("xz -z -k {}".format(raw_image))
231
-#            tarname = img_path + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.xz'
236
+#            tarname = img_path + '/photon-' + options.image_name +
237
+#            '-' + photon_release_ver + '-' + photon_build_num +
238
+#            '.xz'
232 239
 #            tgzout = tarfile.open(tarname, "w:xz")
233 240
 #            tgzout.add(raw_image, arcname=os.path.basename(raw_image))
234 241
 #            tgzout.close()
235 242
         elif config['artifacttype'] == 'vhd':
236 243
             relrawpath = os.path.relpath(raw_image, options.src_root)
237
-            vhdname = os.path.dirname(relrawpath) + '/photon-' + options.image_name + '-' + photon_release_ver + '-' + photon_build_num + '.vhd'
238
-            print "Converting raw disk to vhd ..."
239
-            info_output=utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img info -f raw --output json {}".format(options.src_root, '/mnt/' + relrawpath))
244
+            vhdname = (os.path.dirname(relrawpath) + '/photon-' +
245
+                       options.image_name + '-' + photon_release_ver + '-' +
246
+                       photon_build_num + '.vhd')
247
+            print("Converting raw disk to vhd ...")
248
+            info_output = utils.runshellcommand(
249
+                "docker run -v {}:/mnt:rw anishs/qemu-img info -f raw --output json {}"
250
+                .format(options.src_root, '/mnt/' + relrawpath))
240 251
             mbsize = 1024 * 1024
241 252
             mbroundedsize = ((int(json.loads(info_output)["virtual-size"])/mbsize + 1) * mbsize)
242
-            utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img resize -f raw {} {}".format(options.src_root, '/mnt/' + relrawpath, mbroundedsize))
243
-            utils.runshellcommand("docker run -v {}:/mnt:rw anishs/qemu-img convert {} -O vpc -o subformat=fixed,force_size {}".format(options.src_root, '/mnt/' + relrawpath, '/mnt/' + vhdname))
253
+            utils.runshellcommand(
254
+                "docker run -v {}:/mnt:rw anishs/qemu-img resize -f raw {} {}"
255
+                .format(options.src_root, '/mnt/' + relrawpath, mbroundedsize))
256
+            utils.runshellcommand(
257
+                "docker run -v {}:/mnt:rw anishs/qemu-img convert {} -O "
258
+                "vpc -o subformat=fixed,force_size {}"
259
+                .format(options.src_root, '/mnt/' + relrawpath, '/mnt/' + vhdname))
244 260
         elif config['artifacttype'] == 'ova':
245
-            create_ova_image(raw_image, options.tools_bin_path, options.build_scripts_path + '/' + options.image_name, config)
261
+            create_ova_image(raw_image, options.tools_bin_path,
262
+                             options.build_scripts_path + '/' + options.image_name, config)
246 263
             if 'customartifacts' in config:
247 264
                 if 'postinstallscripts' in config['customartifacts']:
248 265
                     custom_path = img_path + '/photon-custom'
... ...
@@ -250,34 +296,46 @@ if __name__ == '__main__':
250 250
                         os.mkdir(custom_path)
251 251
                     index = 1
252 252
                     for script in config['customartifacts']['postinstallscripts']:
253
-                        print "Creating custom ova {}...".format(index)
253
+                        print("Creating custom ova {}...".format(index))
254 254
                         if index > 1:
255
-                            raw_image_custom = img_path + "/photon-custom-{}".format(index) + photon_release_ver + '-' + photon_build_num + '.raw'
255
+                            raw_image_custom = (img_path + "/photon-custom-{}".format(index) +
256
+                                                photon_release_ver + '-' +
257
+                                                photon_build_num + '.raw')
256 258
                         else:
257
-                            raw_image_custom = img_path + "/photon-custom-" + photon_release_ver + '-' + photon_build_num + '.raw'
259
+                            raw_image_custom = (img_path + "/photon-custom-" +
260
+                                                photon_release_ver + '-' +
261
+                                                photon_build_num + '.raw')
258 262
                         shutil.move(raw_image, raw_image_custom)
259
-                        disk_device = (utils.runshellcommand("losetup --show -f {}".format(raw_image_custom))).rstrip('\n')
260
-                        disk_partitions = utils.runshellcommand("kpartx -as {}".format(disk_device))
263
+                        disk_device = (
264
+                            utils.runshellcommand(
265
+                                "losetup --show -f {}".format(raw_image_custom))).rstrip('\n')
266
+                        disk_partitions = utils.runshellcommand(
267
+                            "kpartx -as {}".format(disk_device))
261 268
                         device_name = disk_device.split('/')[2]
262
-                        loop_device_path =  "/dev/mapper/{}p2".format(device_name)
269
+                        loop_device_path = "/dev/mapper/{}p2".format(device_name)
263 270
 
264
-                        print "Mounting the loop device for ova customization ..."
265
-                        utils.runshellcommand("mount -t ext4 {} {}".format(loop_device_path, custom_path))
271
+                        print("Mounting the loop device for ova customization ...")
272
+                        utils.runshellcommand(
273
+                            "mount -t ext4 {} {}".format(loop_device_path, custom_path))
266 274
                         if not os.path.exists(custom_path + "/tempscripts"):
267 275
                             os.mkdir(custom_path + "/tempscripts")
268
-                        shutil.copy(options.build_scripts_path + '/' + options.image_name + '/' + script, custom_path + "/tempscripts")
269
-                        print "Running custom ova script {}".format(script)
270
-                        utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'".format(custom_path, script))
276
+                        shutil.copy(options.build_scripts_path + '/' + options.image_name +
277
+                                    '/' + script, custom_path + "/tempscripts")
278
+                        print("Running custom ova script {}".format(script))
279
+                        utils.runshellcommand("chroot {} /bin/bash -c '/tempscripts/{}'"
280
+                                              .format(custom_path, script))
271 281
                         shutil.rmtree(custom_path + "/tempscripts", ignore_errors=True)
272 282
                         utils.runshellcommand("umount -l {}".format(custom_path))
273 283
 
274 284
                         mount_out = utils.runshellcommand("mount")
275
-                        print "List of mounted devices:"
276
-                        print mount_out
285
+                        print("List of mounted devices:")
286
+                        print(mount_out)
277 287
 
278 288
                         utils.runshellcommand("kpartx -d {}".format(disk_device))
279 289
                         utils.runshellcommand("losetup -d {}".format(disk_device))
280
-                        create_ova_image(raw_image_custom, options.tools_bin_path, options.build_scripts_path + '/' + options.image_name, config)
290
+                        create_ova_image(raw_image_custom, options.tools_bin_path,
291
+                                         options.build_scripts_path + '/' + options.image_name,
292
+                                         config)
281 293
                         raw_image = raw_image_custom
282 294
                         index = index + 1
283 295
 
... ...
@@ -1,5 +1,3 @@
1
-#!/usr/bin/python2
2
-
3 1
 import os
4 2
 import ctypes
5 3
 import ctypes.util
... ...
@@ -8,6 +6,7 @@ import collections
8 8
 import subprocess
9 9
 import fileinput
10 10
 import re
11
+import shutil
11 12
 
12 13
 class Utils(object):
13 14
     def __init__(self):
... ...
@@ -33,45 +32,51 @@ class Utils(object):
33 33
                                     ctypes.c_char_p(flags),
34 34
                                     0)
35 35
         if ret != 0:
36
-            raise RuntimeError("Cannot mount {} : {}".format(source, os.strerror(ctypes.get_errno())))
36
+            raise RuntimeError(
37
+                "Cannot mount {} : {}".format(source, os.strerror(ctypes.get_errno())))
37 38
 
38 39
     def umount(self, destination):
39 40
         ret = self.libcloader.umount(ctypes.c_char_p(destination))
40 41
         if ret != 0:
41
-            raise RuntimeError("Cannot umount {} : {}".format(destination, os.strerror(ctypes.get_errno())))
42
-    
43
-    def jsonread(self, filename):
42
+            raise RuntimeError(
43
+                "Cannot umount {} : {}".format(destination, os.strerror(ctypes.get_errno())))
44
+    @staticmethod
45
+    def jsonread(filename):
44 46
         json_data = open(filename)
45 47
         data = json.load(json_data, object_pairs_hook=collections.OrderedDict)
46 48
         json_data.close()
47 49
         return data
48 50
 
49
-    def runshellcommand(self, cmd, ignore_errors=False):
50
-        print cmd
51
-        command=cmd.split()
51
+    @staticmethod
52
+    def runshellcommand(cmd, ignore_errors=False):
53
+        print(cmd)
54
+        command = cmd.split()
52 55
         p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
53 56
         output, err = p.communicate()
54 57
         rc = p.returncode
55 58
         if not ignore_errors:
56 59
             if rc != 0:
57
-                print err
60
+                print(err)
58 61
                 raise RuntimeError("Cannot run command {}".format(cmd))
59
-        return output
62
+        return output.decode()
60 63
 
61
-    def replaceinfile(self, filename, pattern, sub):
64
+    @staticmethod
65
+    def replaceinfile(filename, pattern, sub):
62 66
         for line in fileinput.input(filename, inplace=True):
63 67
             line = re.sub(pattern, sub, line)
64
-            print line,
68
+            print(line)
65 69
 
66
-    def replaceandsaveasnewfile(self, old_file, new_file, pattern, sub):
70
+    @staticmethod
71
+    def replaceandsaveasnewfile(old_file, new_file, pattern, sub):
67 72
         with open(old_file, "r") as old, open(new_file, "w") as new:
68 73
             for line in old:
69 74
                 line = re.sub(pattern, sub, line)
70 75
                 new.write(line)
71 76
 
72
-    def copyallfiles(self, src, target):
77
+    @staticmethod
78
+    def copyallfiles(src, target):
73 79
         files = os.listdir(src)
74 80
         for file in files:
75 81
             filename = os.path.join(src, file)
76
-            if (os.path.isfile(filename)):
82
+            if os.path.isfile(filename):
77 83
                 shutil.copy(filename, target)
... ...
@@ -5,9 +5,7 @@
5 5
 #    Author: Harish Udaiya Kumar <hudaiyakumar@vmware.com>
6 6
 import sys
7 7
 import os
8
-from optparse import OptionParser
9
-from SpecUtils import Specutils
10
-from SpecData import SerializableSpecObject
8
+from argparse import ArgumentParser
11 9
 from SpecData import SerializedSpecObjects
12 10
 from jsonwrapper import JsonWrapper
13 11
 
... ...
@@ -17,19 +15,17 @@ SPEC_FILE_DIR = "../../SPECS"
17 17
 LOG_FILE_DIR = "../../stage/LOGS"
18 18
 
19 19
 def main():
20
-    usage = (os.path.basename(__file__) +
21
-             "--input-type=[json/pkg/who-needs/who-needs-build] " +
22
-             "--pkg=[pkg_name] --file=<JSON_FILE_NAME> --disp=[tree/list/json]")
23
-    parser = OptionParser(usage)
24
-    parser.add_option("-i", "--input-type", dest="input_type", default=DEFAULT_INPUT_TYPE)
25
-    parser.add_option("-p", "--pkg", dest="pkg")
26
-    parser.add_option("-f", "--file", dest="json_file", default="packages_minimal.json")
27
-    parser.add_option("-d", "--disp", dest="display_option", default=DEFAULT_DISPLAY_OPTION)
28
-    parser.add_option("-s", "--spec-dir", dest="spec_dir", default=SPEC_FILE_DIR)
29
-    parser.add_option("-t", "--stage-dir", dest="stage_dir", default="../../stage")
30
-    parser.add_option("-a", "--input-data-dir", dest="input_data_dir",
31
-                      default="../../common/data/")
32
-    (options,  args) = parser.parse_args()
20
+    usage = "Usage: %prog [options]"
21
+    parser = ArgumentParser(usage)
22
+    parser.add_argument("-i", "--input-type", dest="input_type", default=DEFAULT_INPUT_TYPE)
23
+    parser.add_argument("-p", "--pkg", dest="pkg")
24
+    parser.add_argument("-f", "--file", dest="json_file", default="packages_minimal.json")
25
+    parser.add_argument("-d", "--disp", dest="display_option", default=DEFAULT_DISPLAY_OPTION)
26
+    parser.add_argument("-s", "--spec-dir", dest="spec_dir", default=SPEC_FILE_DIR)
27
+    parser.add_argument("-t", "--stage-dir", dest="stage_dir", default="../../stage")
28
+    parser.add_argument("-a", "--input-data-dir", dest="input_data_dir",
29
+                        default="../../common/data/")
30
+    options = parser.parse_args()
33 31
 
34 32
     if not options.input_data_dir.endswith('/'):
35 33
         options.input_data_dir += '/'
... ...
@@ -42,13 +38,13 @@ def main():
42 42
 
43 43
         # To display/print package dependencies on console
44 44
         if(options.input_type == "pkg" or
45
-            options.input_type == "who-needs" or
46
-            options.input_type == "who-needs-build"):
45
+           options.input_type == "who-needs" or
46
+           options.input_type == "who-needs-build"):
47 47
             targetName = options.pkg
48 48
             specDeps.readSpecsAndConvertToSerializableObjects(options.spec_dir,
49 49
                                                               options.input_type,
50 50
                                                               targetName, displayOption)
51
-        elif(options.input_type == "json"):
51
+        elif options.input_type == "json":
52 52
         # Generate the expanded package dependencies json file based on package_list_file
53 53
             json_wrapper_option_list = JsonWrapper(options.json_file)
54 54
             option_list_json = json_wrapper_option_list.read()
... ...
@@ -60,7 +56,7 @@ def main():
60 60
                     options.spec_dir,
61 61
                     options.input_type, install_option[1]["file"],
62 62
                     displayOption)
63
-    except Exception as error:
63
+    except Exception as _:
64 64
         sys.stderr.write("Failed to generate dependency lists from spec files\n")
65 65
         sys.exit(1)
66 66