Browse code

rt-iso: Add a realtime flavour in Photon ISO

Change-Id: Ib009761ff07003802859e7a636545cce47b27049
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/10448
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
(cherry picked from commit f674efb0e66d406ab918b20320c0cd1c23c9c183)
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/10619

Him Kalyan Bordoloi authored on 2020/07/22 13:12:19
Showing 10 changed files
... ...
@@ -31,6 +31,7 @@ endif
31 31
 
32 32
 FULL_PACKAGE_LIST_FILE := build_install_options_all.json
33 33
 MINIMAL_PACKAGE_LIST_FILE := build_install_options_minimal.json
34
+RT_PACKAGE_LIST_FILE := build_install_options_rt.json
34 35
 
35 36
 ifdef PHOTON_PUBLISH_RPMS_PATH
36 37
 PHOTON_PUBLISH_RPMS := publish-rpms-cached
... ...
@@ -154,6 +155,29 @@ packages-minimal: check-tools photon-stage $(PHOTON_PUBLISH_RPMS) $(PHOTON_SOURC
154 154
 		$(PACKAGE_WEIGHTS) \
155 155
 		--threads ${THREADS}
156 156
 
157
+packages-rt: check-tools photon-stage $(PHOTON_PUBLISH_RPMS) $(PHOTON_SOURCES) generate-dep-lists
158
+	@echo "Building minimal RPMS for Real Time..."
159
+	@echo ""
160
+	@cd $(PHOTON_PKG_BUILDER_DIR) && \
161
+	$(PHOTON_PACKAGE_BUILDER) \
162
+		--spec-path $(PHOTON_SPECS_DIR) \
163
+		--rpm-path $(PHOTON_RPMS_DIR) \
164
+		--source-path $(PHOTON_SRCS_DIR) \
165
+		--build-root-path $(PHOTON_CHROOT_PATH) \
166
+		--packages-json-input $(PHOTON_DATA_DIR)/packages_rt.json \
167
+		--log-path $(PHOTON_LOGS_DIR) \
168
+		--log-level $(LOGLEVEL) \
169
+		--publish-RPMS-path $(PHOTON_PUBLISH_RPMS_DIR) \
170
+		--pullsources-config $(PHOTON_PULLSOURCES_CONFIG) \
171
+		--dist-tag $(PHOTON_DIST_TAG) \
172
+		--build-number $(PHOTON_BUILD_NUMBER) \
173
+		--release-version $(PHOTON_RELEASE_VERSION) \
174
+		--pkginfo-file $(PHOTON_PKGINFO_FILE) \
175
+		$(PHOTON_RPMCHECK_FLAGS) \
176
+		$(PUBLISH_BUILD_DEPENDENCIES) \
177
+		$(PACKAGE_WEIGHTS) \
178
+		--threads ${THREADS}
179
+
157 180
 packages-initrd: check-tools photon-stage $(PHOTON_PUBLISH_RPMS) $(PHOTON_SOURCES) generate-dep-lists
158 181
 	@echo "Building all initrd package RPMS..."
159 182
 	@echo ""
... ...
@@ -403,6 +427,23 @@ minimal-iso: check-tools photon-stage $(PHOTON_PUBLISH_XRPMS) packages-minimal p
403 403
                 --pkg-to-rpm-map-file $(PHOTON_PKGINFO_FILE) \
404 404
                 --pkg-to-be-copied-conf-file $(PHOTON_GENERATED_DATA_DIR)/$(MINIMAL_PACKAGE_LIST_FILE)
405 405
 
406
+rt-iso: check-tools photon-stage $(PHOTON_PUBLISH_XRPMS) packages-rt packages-initrd
407
+	@echo "Building Photon Real Time ISO..."
408
+	@$(PHOTON_REPO_TOOL) $(PHOTON_RPMS_DIR)
409
+	@$(CP) -f $(PHOTON_DATA_DIR)/$(RT_PACKAGE_LIST_FILE) $(PHOTON_GENERATED_DATA_DIR)/
410
+	@cd $(PHOTON_IMAGE_BUILDER_DIR) && \
411
+	sudo $(PHOTON_IMAGE_BUILDER) \
412
+                --iso-path $(PHOTON_STAGE)/photon-rt-$(PHOTON_RELEASE_VERSION)-$(PHOTON_BUILD_NUM).iso \
413
+                --debug-iso-path $(PHOTON_STAGE)/photon-rt-$(PHOTON_RELEASE_VERSION)-$(PHOTON_BUILD_NUMBER).debug.iso \
414
+                --log-path $(PHOTON_STAGE)/LOGS \
415
+                --log-level $(LOGLEVEL) \
416
+                --rpm-path $(PHOTON_STAGE)/RPMS \
417
+                --srpm-path $(PHOTON_STAGE)/SRPMS \
418
+                --package-list-file $(PHOTON_DATA_DIR)/$(RT_PACKAGE_LIST_FILE) \
419
+                --generated-data-path $(PHOTON_STAGE)/common/data \
420
+                --pkg-to-rpm-map-file $(PHOTON_PKGINFO_FILE) \
421
+                --pkg-to-be-copied-conf-file $(PHOTON_GENERATED_DATA_DIR)/$(RT_PACKAGE_LIST_FILE)
422
+
406 423
 src-iso: check-tools photon-stage $(PHOTON_PACKAGES)
407 424
 	@echo "Building Photon Full Source ISO..."
408 425
 	@cd $(PHOTON_IMAGE_BUILDER_DIR) && \
... ...
@@ -21,6 +21,11 @@
21 21
         "include" : [],
22 22
         "additional-files" : ["ostree-repo.tar.gz"]
23 23
     },
24
+    "realtime" : {
25
+        "title" : "5. Photon Real Time",
26
+        "packagelist_file" : "packages_rt.json",
27
+        "visible" : true
28
+    },
24 29
     "appliance" : {
25 30
         "title" : "Minimal packages to support appliances.",
26 31
         "packagelist_file" : "packages_appliance.json",
27 32
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+{
1
+    "realtime" : {
2
+        "title" : "Photon Real Time",
3
+        "packagelist_file" : "packages_rt.json",
4
+        "visible" : false
5
+    }
6
+}
0 7
new file mode 100644
... ...
@@ -0,0 +1,34 @@
0
+{
1
+    "packages": [
2
+                 "minimal",
3
+                 "linux-rt",
4
+                 "linux-rt-devel",
5
+                 "linux-tools",
6
+                 "initramfs",
7
+                 "build-essential",
8
+                 "git",
9
+                 "mpc",
10
+                 "tar",
11
+                 "less",
12
+                 "device-mapper",
13
+                 "python3",
14
+                 "wget",
15
+                 "sudo",
16
+                 "lvm2",
17
+                 "linux-firmware",
18
+                 "curl",
19
+                 "coreutils",
20
+                 "iputils",
21
+                 "pciutils",
22
+                 "tuna",
23
+                 "tuned",
24
+                 "linuxptp",
25
+                 "lxcfs",
26
+                 "lksctp-tools",
27
+                 "libhugetlbfs",
28
+                 "libhugetlbfs-devel",
29
+                 "libnuma",
30
+                 "libnuma-devel",
31
+                 "cmake"
32
+                 ]
33
+}
... ...
@@ -66,7 +66,8 @@ class Installer(object):
66 66
         'setup_grub_script',
67 67
         'shadow_password',
68 68
         'type',
69
-        'ui'
69
+        'ui',
70
+        'linux_flavor'
70 71
     }
71 72
 
72 73
     default_partitions = [{"mountpoint": "/", "size": 0, "filesystem": "ext4"}]
... ...
@@ -232,8 +233,13 @@ class Installer(object):
232 232
         if not 'disk' in install_config:
233 233
             return "No disk configured"
234 234
 
235
-        if 'install_linux_esx' not in install_config:
236
-            install_config['install_linux_esx'] = False
235
+
236
+        if 'linux_flavor' not in install_config:
237
+            if install_config.get('install_linux_esx', False) == True:
238
+                install_config['linux_flavor'] = "linux-esx"
239
+            else:
240
+                install_config['linux_flavor'] = "linux"
241
+        install_config['install_linux_esx'] = False
237 242
 
238 243
         # Perform following checks here:
239 244
         # 1) Only one extensible partition is allowed per disk
... ...
@@ -779,9 +785,47 @@ class Installer(object):
779 779
                 self.install_config['packages'] = list(filter(regex.match,self.install_config['packages']))
780 780
             self.install_config['packages'].append('linux-esx')
781 781
         else:
782
-            regex = re.compile(r'(?!linux-esx-[0-9].*)')
783
-            self.install_config['packages'] = list(filter(regex.match,self.install_config['packages']))
782
+            if 'linux-esx' in self.install_config['packages']:
783
+                self.install_config['packages'].remove('linux-esx')
784
+            else:
785
+                regex = re.compile(r'(?!linux-esx-[0-9].*)')
786
+                self.install_config['packages'] = list(filter(regex.match,self.install_config['packages']))
787
+
788
+    def filter_packages(self, package):
789
+        all_linux_flavors = ["", "esx", "aws", "secure", "rt"]
790
+        linux_dependencies = ["devel", "drivers", "docs", "oprofile", "dtb", "hmacgen"]
791
+        redundent_linux_flavors = list(filter(self.filter_flavors, all_linux_flavors))
792
+        package = package.split('-')
793
+        if len(package) > 1:
794
+            flavor = package[1]
795
+        else:
796
+            flavor = ""
797
+        if(package[0] != "linux"):
798
+            return True
799
+        elif("" in redundent_linux_flavors and flavor in linux_dependencies):
800
+            return False
801
+        elif(flavor in redundent_linux_flavors):
802
+            return False
803
+        else:
804
+            return True
805
+
806
+    def filter_flavors(self, linux_flavor):
807
+        selected_linux_flavor = self.install_config['linux_flavor'].split('-')
808
+        if len(selected_linux_flavor) > 1:
809
+            selected_linux_flavor = selected_linux_flavor[1]
810
+        else:
811
+            selected_linux_flavor = ""
812
+        if(linux_flavor == selected_linux_flavor):
813
+            return False
814
+        else:
815
+            return True
784 816
 
817
+    def _adjust_packages_based_on_selected_flavor(self):
818
+        """
819
+        Install slected linux flavor only
820
+        """
821
+        if 'linux_flavor' in self.install_config:
822
+            self.install_config['packages'] = list(filter(self.filter_packages,self.install_config['packages']))
785 823
 
786 824
     def _add_packages_to_install(self, package):
787 825
         """
... ...
@@ -830,7 +874,7 @@ class Installer(object):
830 830
         """
831 831
         Install packages using tdnf command
832 832
         """
833
-        self._adjust_packages_for_vmware_virt()
833
+        self._adjust_packages_based_on_selected_flavor()
834 834
         selected_packages = self.install_config['packages']
835 835
         state = 0
836 836
         packages_to_install = {}
... ...
@@ -255,9 +255,8 @@ class IsoConfig(object):
255 255
             fd = FileDownloader(maxy, maxx, install_config, title, intro, dest, True)
256 256
             items.append((fd.display, True))
257 257
 
258
-        if CommandUtils.is_vmware_virtualization():
259
-            linux_selector = LinuxSelector(maxy, maxx, install_config)
260
-            items.append((linux_selector.display, True))
258
+        linux_selector = LinuxSelector(maxy, maxx, install_config)
259
+        items.append((linux_selector.display, True))
261 260
         items.append((hostname_reader.get_user_string, True))
262 261
         items.append((root_password_reader.get_user_string, True))
263 262
         items.append((confirm_password_reader.get_user_string, False))
... ...
@@ -235,4 +235,10 @@ Kickstart config file is a json format with following possible parameters:
235 235
 	Default value: false
236 236
 	Example: { "ui": true }
237 237
 
238
+"linux_flavor" (optional)
239
+	Contains the flavor of linux to install, if multiple linux flavors
240
+	are present in "packages" or "packagelist_file"
241
+	Acceptable values are: "linux", "linux-esx", "linux-rt", "linux-aws", and "linux-secure"
242
+	Example: { "linux_flavor": "linux-esx" }
243
+
238 244
 For reference, look at "sample_ks.cfg" file
... ...
@@ -6,6 +6,7 @@
6 6
 from menu import Menu
7 7
 from window import Window
8 8
 from actionresult import ActionResult
9
+from commandutils import CommandUtils
9 10
 
10 11
 class LinuxSelector(object):
11 12
     def __init__(self, maxy, maxx, install_config):
... ...
@@ -13,16 +14,33 @@ class LinuxSelector(object):
13 13
         self.maxx = maxx
14 14
         self.maxy = maxy
15 15
         self.win_width = 60
16
-        self.win_height = 13
16
+        self.win_height = 16
17 17
 
18 18
         self.win_starty = (self.maxy - self.win_height) // 2
19 19
         self.win_startx = (self.maxx - self.win_width) // 2
20 20
 
21 21
         self.menu_starty = self.win_starty + 6
22 22
 
23
+    def set_linux_esx_installation(self, is_linux_esx):
24
+        self.install_config['install_linux_esx'] = is_linux_esx
25
+        return ActionResult(True, None)
26
+
27
+    def set_linux_installation(self, selected_linux_package):
28
+        self.install_config['linux_flavor'] = selected_linux_package
29
+        return ActionResult(True, None)
30
+
31
+    def create_available_linux_menu(self):
32
+        linux_flavors = {"linux":"Generic", "linux-esx":"VMware hypervisor optimized", "linux-aws":"AWS optimized", "linux-secure":"Security hardened", "linux-rt":"Real Time"}
33
+
23 34
         self.menu_items = []
24
-        self.menu_items.append(("1. VMware hypervisor optimized", self.set_linux_esx_installation, True))
25
-        self.menu_items.append(("2. Generic", self.set_linux_esx_installation, False))
35
+        for flavor,menu_entry in linux_flavors.items():
36
+            if flavor in self.install_config['packages']:
37
+                if flavor == "linux-esx" and not CommandUtils.is_vmware_virtualization():
38
+                    continue
39
+                self.menu_items.append((menu_entry, self.set_linux_installation, flavor))
40
+
41
+        if len(self.menu_items) == 1:
42
+            self.install_config['linux_flavor'] = self.menu_items[0][2]
26 43
 
27 44
         self.host_menu = Menu(self.menu_starty, self.maxx, self.menu_items,
28 45
                               default_selected=0, tab_enable=False)
... ...
@@ -32,15 +50,13 @@ class LinuxSelector(object):
32 32
                              position=1, can_go_next=True)
33 33
         self.window.set_action_panel(self.host_menu)
34 34
 
35
-    def set_linux_esx_installation(self, is_linux_esx):
36
-        self.install_config['install_linux_esx'] = is_linux_esx
37
-        return ActionResult(True, None)
38
-
39 35
     def display(self):
40 36
         if 'ostree' in self.install_config:
41 37
             return ActionResult(None, {"inactive_screen": True})
42 38
 
43
-        self.window.addstr(0, 0, 'The installer has detected that you are installing')
44
-        self.window.addstr(1, 0, 'Photon OS on a VMware hypervisor.')
45
-        self.window.addstr(2, 0, 'Which type of Linux kernel would you like to install?')
39
+        self.create_available_linux_menu()
40
+        if len(self.menu_items) < 2:
41
+            return ActionResult(None, {"inactive_screen": True})
42
+
43
+        self.window.addstr(0, 0, 'Which type of Linux kernel would you like to install?')
46 44
         return self.window.do_action()
... ...
@@ -34,7 +34,7 @@ def create_pkg_list_to_copy_to_iso(build_install_option, output_data_path):
34 34
     packages = []
35 35
     for install_option in options_sorted:
36 36
         if install_option[0] != "iso":
37
-            file_path = os.path.join(output_data_path, install_option[1]["packagelist_file"])
37
+            file_path = os.path.join(output_data_path, os.path.splitext(install_option[1]["packagelist_file"])[0]+"_expanded.json")
38 38
             package_list_json = Utils.jsonread(file_path)
39 39
             packages = packages + package_list_json["packages"]
40 40
     return packages
... ...
@@ -253,8 +253,9 @@ def main():
253 253
             for json_file in list_json_files:
254 254
                 output_file = None
255 255
                 if options.display_option == "json":
256
-                    output_file = os.path.join(options.output_dir, os.path.basename(json_file))
256
+                    output_file = os.path.join(options.output_dir, os.path.splitext(os.path.basename(json_file))[0]+"_expanded.json")
257 257
                     specDeps.process(options.input_type, json_file, options.display_option, output_file)
258
+                    shutil.copyfile(json_file, os.path.join(options.output_dir, os.path.basename(json_file)))
258 259
     except Exception as e:
259 260
         traceback.print_exc()
260 261
         sys.stderr.write(str(e))