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
| ... | ... |
@@ -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", |
| 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)) |