This the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Photon OS Documentation

The Photon OS Documentation provides information about how to install, configure, and use VMware Photon OS™.

PhotonOS Logo

Product version: 5.0

This documentation applies to all 5.0.x releases.

Intended Audiences

This information is intended for Photon OS administrators and developers:

Description of TaskRelevant Documentation
Understand Photon OSOverview of Photon OS
Download and Install Photon OSInstallation Guide
Fundamentals of administering Photon OSAdministration Guide
Using Photon OSUser Guide
Using Photon OS command-line utilitiesCommand-Line Interface Reference
Solutions for common problemsTroubleshooting Guide

1 - Quick Start Links

If you want to start using Photon OS straight away, see the following topics:

2 - What is New in Photon OS 5

Photon OS 5.0 provides enhancements in Network Configuration Manager, PMD-nextgen, Container Runtime Security, Linux Real-Time Kernel, and TDNF Features. The release introduces the Photon OS Container Builder tool. This release of Photon OS also supports XFS and BTRFS filesystems, Control Group V2, ARM64 on Linux-esx kernel, PostgreSQL. It contains installer improvements and critical updates to the OSS packages including Linux kernel version updates. This topic summarizes what’s new and different in Photon OS 5.0.

New Features

  • Enhancements in Network Configuration Manager: You can now use Network Configuration Manager to perform the following tasks:

    • Configure multiple routes and addresses section
    • Configure WireGuard
    • Configure SR-IOV
    • Create NetDev, VLAN, VXLAN, Bridge, Bond, VETH (Virtual Ethernet), MacVLAN/MacVTap, IPvlan/IPvtap, tunnels (IPIP, SIT, GRE, VTI)
    • Create, configure, and remove virtual network devices
    • Generate more flexible netplan like network configuration from a YAML file

    You can run query or configure the following parameters of network devices:

    • Alias, Description, MTUBytes, WakeOnLan, WakeOnLanPassword, Port, BitsPerSecond, Duplex and Advertise
    • Offload parameters and other features
    • MACAddressPolicy or MACAddress
    • NamePolicy or Name
    • AlternativeNamesPolicy or AlternativeName
    • Pending packets receive a buffer
    • Queue size
    • Flow control
    • GSO
    • Channels
    • Coalesce
    • Coalesced frames
    • Coalesce packet rate
  • PMD-Nextgen Enhancement: The capabilities to configure the following options are added to pmd-nextgen:

    • Configure system hostname
    • Configure network sriov
    • Configure Tun
    • Configure Tap
    • Configure TLS
  • Network-event-broker: Network-event-broker now supports emitting network data in JSON format.

  • Photon OS Container Builder: The cntrctl tool in Photon OS 5.0 allows you to build a lightweight Photon OS container.

  • Kernel-Version Update: The following Kernel flavors are updated to kernel version 6.1.10 in Photon OS:

    • Linux
    • Linux-esx
    • Linux-secure
    • Linux-rt
  • Support for New Filesystems: Support is added for the following filesystems in Photon OS:

    • XFS: With the support of the XFS filesystem, you can implement an environment that requires high performance, and scalability for data-intensive tasks.
    • BTRFS: You can use the BTRFS filesystem for high performance, better reliability, and efficient data storage capabilities.
  • Support for Control Group V2: cgroup v2 is now available in Photon OS. With cgroup v2, you get improved resource management capabilities, a unified hierarchy scheme, and a safer sub-tree delegation to containers. Features like Pressure Stall Information and rootless containers in cgroup v2 ensure better management and security capabilities of the control groups.

  • Support for Kernel Live Patching: With Kernel Live Patching, an administrator can patch a running kernel without rebooting.

  • Enhanced Container Runtime Security: To improve the runtime security of the containers, the following enhancements are added to Photon OS:

    • Support for SELinux policy: You can now enable and configure the SELinux policy to manage access to files, directories, and other system resources. This drastically reduces the risk of a security breach.
    • Support for rootless containers: Photon OS supports rootless containers. An unprivileged user can now create and manage containers. Since unprivileged users do not have root privileges on the host machine, it prevents any security threat to the host machine.
  • Improved Linux Real-Time Kernel: The linux-rt kernel flavor comes with improvements such as low-latency optimizations, stability enhancements, and debugging enhancements. Linux-rt now also supports the Intel Sapphire Rapids CPUs including the Telco-specific 5G ISA.

  • Support for ARM64: Support for ARM64 is now available for the linux-esx kernel in Photon OS.

  • PostgreSQL versions: The following PostgreSQL versions are supported on Photon OS:

    • PostgreSQL 13
    • PostgreSQL 14
    • PostgreSQL 15
  • TDNF Feature Enhancements: The metalink functionality in tdnf is now available as a plugin. In tdnf, support is added for the following:

    • history (list, rollback, undo and redo)
    • mark command
    • checking the available cache size of a download
    • multiple base URLs
    • --skip-broken option
    • --alldeps option when downloading
    • --testonly option
    • --nodeps option for --downloadonly
    • --source and --builddeps options
    • dnf_check_update_compat config file option
    • support for tsflags=nodocs
    • --repofromdir option
    • --arch option to repoquery
    • Configuration tool: Set of commands to change tdnf’s configuration files and repository files.
  • OVA Updates: UEFI OVA is built with hardware version 15.

Installer and Build System Updates

  • Support Pre-install script in photon installer
  • A tool is now available to generate a custom initial RAM disk (initrd)
  • A tool is now available to generate a custom installer ISO
  • A tool is now available to generate a custom RPM-OSTree ISO
  • Support is added for the following features in Kickstart:

    • sizepercent: specifies the size of the partition in percent of the total disk space.
    • repos: Specifies the RPM repositories to install the RPMs.
  • Support for A/B Partition System: Photon OS 5.0 supports seamless updates and rollback with the A/B storage partition system.
  • Kickstart Network Configuration: Improved flexibility for network configuration that allows multiple interfaces and facilitates better handling of the VLAN interfaces.

Package Updates:

The following OS packages are updated:

  • Linux kernel 6.1.10
  • Gcc : 12.2
  • Glibc 2.36
  • Systemd 253
  • Python3 3.11
  • Openjdk : 11 and 17
  • Openssl : 3.0.8
  • Cloud-init: 23.1.1
  • Rubygem: 3.1.2
  • Perl: 5.36
  • Kubernetes 1.26.1
  • Go 1.20.2

Notes

The following OS packages are removed in this release.

  • Photon Management Daemon (PMD)
  • lightwave
  • likewise-open
  • openjdk8
  • fcgi
  • libnss-ato
  • tiptop
  • ndsend
  • ulogd
  • lightstep-tracer-cpp
  • json_spirit
  • cgroup-utils
  • c-rest-engine
  • dcerpc
  • gssapi-unix
  • python3-PyPAM
  • python3-backports_abc
  • sshfs

3 - Overview

Overview of Photon OS provides an introduction to Photon OS, its versions, and distinguishing features.

Product version: 5.0

This documentation applies to all 5.0.x releases.

Intended Audiences

This information is intended for Photon OS administrators who install and set up Photon OS.

3.1 - Introduction to Photon OS

Photon OS, is an open-source minimalist Linux operating system from VMware that is optimized for cloud computing platforms, VMware vSphere deployments, and applications native to the cloud.

Photon OS is a Linux container host optimized for vSphere and cloud-computing platforms such as Amazon Elastic Compute and Google Compute Engine. As a lightweight and extensible operating system, Photon OS works with the most common container formats, including Docker, Rocket, and Garden. Photon OS includes a yum-compatible, package-based lifecycle management system called tdnf.

When used with development tools and environments such as VMware Fusion, VMware Workstation, and production runtime environments (vSphere), Photon OS lets you seamlessly migrate container-based applications from development to production. With a small footprint and fast boot and run times, Photon OS is optimized for cloud computing and cloud applications.

3.2 - Flavours

Photon OS consists of a minimal version, a full version, RPM OSTree, and Photon Real-Time Operating System.

  • The minimal version of Photon OS is lightweight container host runtime environment that is suited to managing and hosting containers. The minimal version contains just enough packaging and functionality to manage and modify containers while remaining a fast runtime environment. The minimal version is ready to work with appliances.

  • The Developer version of Photon OS includes additional packages to help you customize the system and create containerized applications. For running containers, the developer version is excessive. The developer version helps you create, develop, test, and package an application that runs a container.

  • OSTree is a tool to manage bootable, immutable, versioned filesystem trees. Unlike traditional package managers like rpm or dpkg that know how to install, uninstall, configure packages, OSTree has no knowledge of the relationship between files. But when you add rpm capabilities on top of OSTree, it becomes RPM-OSTree, meaning a filetree replication system that is also package-aware.

  • Photon OS features a kernel flavor called linux-rt to support low-latency real time applications. linux-rt is based on the Linux kernel PREEMPT_RT patchset that turns Linux into a hard real time operating system. In addition to the real time kernel itself, Photon OS 5.0 supports several userspace packages such as tuned, tuna, stalld, and others, that are useful to configure the operating system for real time workloads. The linux-rt kernel and the associated userspace packages together are referred to as Photon Real Time (RT).
    In Photon OS 5.0, the linux-rt kernel flavor comes with the following improvements:

    • Low-latency Optimizations: Low-latency is achieved with the following feature enhancements:

      • Guest Timer Advancement feature in linux-rt mitigates the cost of timer virtualization on ESXi. This makes Photon RT on ESXi and bare-metal indistinguishable in terms of the cyclictest benchmark results.
      • Enhancements to tuned and trace-cmd packages to reduce OS jitter to real-time workloads.
    • Stability Enhancements: Enhanced stability is achieved with the following improvements:

      • stalld version is updated to 1.17.1, which brings in several improvements to the effectiveness and efficiency of stalld in resolving kernel thread starvation.
      • Updated stalld configuration file with more effective and field-proven defaults.
    • Debugging Enhancements:: Debugging enhancements are achieved with the following improvements:

      • To aid with latency tuning and debugging, osnoise and timerlat latency tracers are enabled in the linux-rt kernel.
      • Enabled Kernel’s hung-task detector in tuned real-time profile’s configuration.
    • Hardware Enablement: Support is added for Intel Sapphire Rapids CPUs, including its Telco-specific 5G ISA.

    • Driver Updates: Updated out-of-tree Intel network drivers to the following versions:

      • i40e – v2.22.18
      • iavf – v4.8.2
      • ice – v1.11.14

4 - Installation Guide

The Photon OS Installation Guide provides information about how administrators can install Photon OS.

Product version: 5.0

This documentation applies to all 5.0.x releases.

Intended Audiences

This information is intended for Photon OS administrators who install and set up Photon OS.

4.1 - Downloading Photon OS

Detailed instructions for obtaining Photon OS 5.0 are located at: https://github.com/vmware/photon/wiki/Downloading-Photon-OS

Download Formats

Photon OS is available in the following pre-packaged, binary formats:

FormatDescription
ISO ImageContains everything needed to install the minimal or full installation of Photon OS or the Real-Time flavor of Photon OS. The bootable ISO has a manual installer or can be used with PXE/kickstart environments for automated installations.
OVAPre-installed minimal environment, customized for VMware hypervisor environments. These customizations include a highly sanitized and optimized kernel to give improved boot and runtime performance for containers and Linux applications. Since an OVA is a complete virtual machine definition, we’ve made available a Photon OS OVA that has virtual hardware version 13 arm64, version 13, and version 11; this will allow for compatibility with several versions of VMware platforms or allow for the latest and greatest virtual hardware enhancements.
Amazon AMIPre-packaged and tested version of Photon OS with Amazon AMI and Amazon AMI arm64 packages made ready to deploy in your Amazon EC2 cloud environment. Previously, we’d published documentation on how to create an Amazon compatible instance, but, now we’ve done the work for you.
Google GCE ImagePre-packaged and tested Google GCE image that is ready to deploy in your Google Compute Engine Environment, with all modifications and package requirements for running Photon OS in GCE.
Azure VHDPre-packaged and tested Azure HD image that is ready to deploy in your Microsoft Azure Cloud, with all modifications and package requirements for running Photon OS in Azure.
Raspberry Pi ImagePre-packaged and tested Raspberry Pi Image on ARM64 architecture.

4.2 - Upgrading Photon OS 4.0 system to Photon OS 5.0

You can upgrade the existing Photon OS 4.0 systems to Photon OS 5.0, and take advantage of the functionality enhancements in Photon OS 5.0. For details, see What’s New in Photon OS 5.0.

The photon-upgrade package provides a seamless upgrade for Photon OS. To use the package, you need to perform the following steps:

  1. Install the photon-upgrade package on the Photon OS 4.0 system.
  2. Run the following script:
    /bin/photon-upgrade.sh
    
  3. Follow the interactions with that script.

Please note that the script also supports a non-interactive invocation using the --assume-yes option. The --help option of the photon-upgrade.sh script provides online help.

The photon-upgrade.sh script updates packages to the latest available versions in Photon OS 5.0. Also, the upgrade retains your 4.0 customizations in your new Photon OS 5.0 system.

Note: If your 4.0 VM is a full install, then you will have a 5.0 VM that represents a full install (all packages and dependencies). Upgrading a minimal installation takes less time due to fewer packages.

For each Photon OS 4.0 VM that you want to upgrade, complete the following steps:

  1. Back up all existing settings and data for the Photon 4.0 VM.

  2. Stop any services (for example, docker) that are currently running in the VM.

  3. Install photon-upgrade package

    # tdnf -y install photon-upgrade
    
  4. Run the upgrade script

    # photon-upgrade.sh --upgrade-os
    
  5. Answer y to reboot the VM. The upgrade script powers down the Photon OS 4.0 VM and powers it on as a Photon OS 5.0 VM.

After the upgrade, before you deploy into production, test all previous functionality to ensure that everything works as expected.

4.3 - Building Images

You can build an ISO from the source code and other images for Photon OS. This section describes how to build the ISO, build other images, use the cached toolchain and RPMS, and cached sources. You can use this method as an alternative to downloading a pre-built version.

For information on how to install and build a package on Photon OS from the package’s source RPM, see the Photon OS Administration Guide.

4.3.1 - Folder Layout

The structure of the directories on GitHub that contain the source code for Photon OS is as follows:

photon/
├── Makefile
├── README
├── Dockerfile
├── Vagrantfile
├── PUBLISHRPMS_SPECS        # RPM SPEC files
├── SPECS                    # RPM SPEC files
├── common                   # Build, packaging config
├── docs                     # Documentation
├── build.py                 # Package builder
├── config.json              # Package builder
├── support                  # Build scripts
└── tools

4.3.2 - Build Prerequisites

Before you build the ISO, verify that you have the performed the following tasks:

  • Installed a build operating system running the 64-bit version of Ubuntu 14.04 or later version.

  • Downloaded and installed the following packages for Ubuntu: bison gawk g++ createrepo python-aptdaemon genisoimage texinfo python-requests libfuse-dev libssl-dev uuid-dev libreadline-dev kpartx git bc

  • Downloaded and installed the following packages for Photon OS:
    “rsync” “docker-18.09.9” “docker-py3” “python3-pyOpenSSL” “python3-six” “python3-pip” “cdrkit” “createrepo_c” “dosfstools” “openssl-devel” “python3-curses” “zlib-devel” “util-linux-devel”

  • Installed Docker

  • Downloaded the source code from the Photon OS repository on GitHub into $HOME/workspaces/photon.

4.3.3 - Build an ISO from the Source Code for Photon OS

You can build an ISO from the source code for Photon OS. This section describes how to build the ISO, use the cached toolchain and RPMS, and cached sources. You can use this method as an alternative to downloading a pre-built version.

For information on how to install and build a package on Photon OS from the package’s source RPM, see the Photon OS Administration Guide.

4.3.3.1 - Building the ISO

Perform the following steps to install the packages on Ubuntu:

  1. Install the packages:

    sudo apt-get -y install bison gawk g++ createrepo python-aptdaemon genisoimage texinfo python-requests libfuse-dev libssl-dev uuid-dev libreadline-dev kpartx git bc
    
  2. Get Docker:

    wget -qO- https://get.docker.com/ | sh
    
  3. Install pip and docker 2.3.0

    sudo apt install python3-pip
    pip3 install docker==2.3.0
    

    If you encounter an error for LOCALE when you run these commands, then export the following variables in the terminal:

    export LC_ALL="en_US.UTF-8"
    export LC_CTYPE="en_US.UTF-8"
    
  4. The default configuration parameters are available in config.json. If you want to customize them, then the configuration information is available at the following location:

    [https://github.com/vmware/photon/blob/dev/photon-build-config.txt](https://github.com/vmware/photon/blob/dev/photon-build-config.txt)
    
  5. Clone`the Photon project:

    git clone https://github.com/vmware/photon.git cd $HOME/workspaces/photon

  6. Make ISO as follows:

    sudo make iso

  7. Make Minimal ISO as follows:

    sudo make minimal-iso

  8. Make Real-Time ISO as follows:

    sudo make rt-iso

Result

This command first builds all RPMs corresponding to the SPEC files in your Photon repository and then builds a bootable ISO containing those RPMs.

The RPMs thus built are stored under stage/RPMS/ directory within the repository, using the following directory hierarchy:

$HOME/workspaces/photon/stage/:
├──RPMS/:
    ├──noarch/*.noarch.rpm    [Architecture-independent RPMs]
    ├──x86_64/*.x86_64.rpm    [RPMs built for the x86-64 architecture]
    ├──aarch64/*.aarch64.rpm  [RPMs built for the aarch64 (ARM64) architecture]

The ISO is created at $HOME/workspaces/photon/stage/photon.iso.

4.3.4 - Build Other Images for Photon OS

This section describes how to build the cloud images, OVA, and RPM.

For information on how to install and build a package on Photon OS from the package’s source RPM, see the Photon OS Administration Guide.

4.3.4.1 - Building Cloud Images

Perform the following steps to build the cloud images on Ubuntu:

  1. Install the packages:

    sudo apt-get -y install bison gawk g++ createrepo python-aptdaemon genisoimage texinfo python-requests libfuse-dev libssl-dev uuid-dev libreadline-dev kpartx git bc
    
  2. Get Docker:

    wget -qO- https://get.docker.com/ | sh
    
  3. Install pip

    sudo apt install python3-pip
    pip3 install git+https://github.com/vmware/photon-os-installer.git
    git clone https://github.com/vmware/photon.git
    

If you encounter an error for LOCALE when you run these commands, then export the following variables in the terminal:

   `export LC_ALL="en_US.UTF-8"`

export LC_CTYPE="en_US.UTF-8"

  1. Clone`the Photon project:

    git clone https://github.com/vmware/photon.git cd $HOME/workspaces/photon

  2. Make the cloud image for AMI.

    sudo make image IMG_NAME=ami

  3. Make the cloud image for Azure.

    sudo make image IMG_NAME=azure

  4. Make the cloud image for GCE.

    sudo make image IMG_NAME=gce

Result

This command first builds all RPMs corresponding to the SPEC files in your Photon repository and then builds a bootable ISO containing those RPMs.

The RPMs thus built are stored under stage/RPMS/ directory within the repository, using the following directory hierarchy:

$HOME/workspaces/photon/stage/:
├──RPMS/:
    ├──noarch/*.noarch.rpm    [Architecture-independent RPMs]
    ├──x86_64/*.x86_64.rpm    [RPMs built for the x86-64 architecture]
    ├──aarch64/*.aarch64.rpm  [RPMs built for the aarch64 (ARM64) architecture]

The cloud image is created at `$HOME/workspaces/photon.

4.3.4.2 - Building OVA image

Perform the following steps to build OVA on Ubuntu:

  1. Install the packages:

    sudo apt-get -y install bison gawk g++ createrepo python-aptdaemon genisoimage texinfo python-requests libfuse-dev libssl-dev uuid-dev libreadline-dev kpartx git bc
    
  2. Get Docker:

    wget -qO- https://get.docker.com/ | sh
    
  3. Install pip

    sudo apt install python3-pip
    pip3 install git+https://github.com/vmware/photon-os-installer.git
    git clone https://github.com/vmware/photon.git
    
    
    
    If you encounter an error for LOCALE when you run these commands, then export the following variables in the terminal:
    
    
        export LC_ALL="en_US.UTF-8"
    `export LC_CTYPE="en_US.UTF-8"`
    
  4. Clone the Photon project:

    git clone https://github.com/vmware/photon.git
    

    cd $HOME/workspaces/photon

  5. Download latest VDDK from below link:

    https://my.vmware.com/web/vmware/downloads/details?downloadGroup=VDDK670&productId=742

  6. Search for VMware-ovftool in the same site and install it.

    For example:

    ovftool downloaded file:

    VMware-ovftool-4.3.0-13981069-lin.x86_64.bundle

    Add exec permission and run it as sudo:

    $ chmod +x VMware-ovftool-4.3.0-13981069-lin.x86_64.bundle && sudo ./VMware-ovftool-4.3.0-13981069-lin.x86_64.bundle --eulas-agreed --required

  7. For VDDK, if the downloaded file is VMware-vix-disklib-6.7.0-8173251.x86_64.tar.gz, untar the downloaded tarball:

    $ tar xf VMware-vix-disklib-6.7.0-8173251.x86_64.tar.gz

  8. Navigate to extracted directory.

  • Move the header files to /usr/include

    $ sudo mv include/*.h /usr/include

  • Move the shared libs to /usr/lib/vmware $ sudo mkdir -p /usr/lib/vmware && sudo mv lib64/* /usr/lib/vmware && sudo rm /usr/lib/vmware/libstdc++.so*

  1. Export /usr/lib/vmware library path(only for current session). Do this step every time you try to build an ova image.

    $ export LD_LIBRARY_PATH=/usr/lib/vmware

  2. Navigate to your intended Photon source repository and run the following command.

    
    `sudo make image IMG_NAME=ova`
    
  3. Make the image for OVA UEFI

sudo make image IMG_NAME=ova_uefi

Result

This command first builds all RPMs corresponding to the SPEC files in your Photon repository and then builds a bootable ISO containing those RPMs.

The RPMs thus built are stored under stage/RPMS/ directory within the repository, using the following directory hierarchy:

$HOME/workspaces/photon/stage/:
├──RPMS/:
    ├──noarch/*.noarch.rpm    [Architecture-independent RPMs]
    ├──x86_64/*.x86_64.rpm    [RPMs built for the x86-64 architecture]
    ├──aarch64/*.aarch64.rpm  [RPMs built for the aarch64 (ARM64) architecture]

The cloud image is created at `$HOME/workspaces/photon.

4.3.5 - Use the Cached Toolchain and RPMS

When the necessary RPMs are available under the stage/RPMS/ directory, the commands that you use to create any Photon artifact such as, ISO or OVA will reuse those RPMs to create the specified image.

If you already have the Photon RPMs available elsewhere, and not under stage/RPMS/ in the Photon repository, you can build Photon artifacts using those cached RPMs by setting the PHOTON_CACHE_PATH variable to point to the directory containing those RPMs.

For example, if your RPMs are located under $HOME/photon-cache/, then use the following command to build an ISO:

sudo make iso PHOTON_CACHE_PATH=$HOME/photon-cache

The $HOME/photon-cache/ directory should follow the same structure as the stage/RPMS/ directory:

photon-cache/:
├──RPMS/:
    ├──noarch/*.noarch.rpm
    ├──x86_64/*.x86_64.rpm
    ├──aarch64/*.aarch64.rpm

4.3.6 - Use Cached Sources

To use the cached sources, run the following command:

mkdir $HOME/photon-sources
sudo make iso PHOTON_SOURCES_PATH=$HOME/photon-sources

The directory format of PHOTON_SOURCES_PATH is as follows:

photon-sources/
├──src1.tar.gz
├──src2.tar.gz
└──...

4.3.7 - View Build Logs

You can view build logs at the following location:

$HOME/workspaces/photon/stage/LOGS

4.3.8 - Build a Custom ISO from the Source Code of Photon OS Installer

The custom-iso tool allows you to build images as per your requirements.

Overview
Prerequisite
Preparing for Custom Image Generation
Generating a Custom Image

Overview

You can use the custom-iso tool to create images such as a custom ISO, Initrd, and RPM-OSTree. To generate an image, you must provide the necessary inputs in the form of arguments. The custom-iso tool creates images based on the inputs you provide.

You can use the following functions to generate the required images:

  • build-initrd generates a custom Initrd image

  • build-initrd generates a custom ISO image.

  • build-rpm-ostree-iso generates a custom RPM-OSTree ISO.

As an input to the tool, you must provide the list of all the necessary packages for the custom ISO in a JSON file. The tool only uses the minimal list of packages and their dependencies that you specify.

You can customize the following files and configurations:

  • List of packages to install
  • Kickstart file
  • Boot command line
  • Repo to download the packages
  • Installer initrd package list
  • Custom ostree tar archive

Note that when you use the Custom ISO builder to build the ISO and the Installer initrd, the ISO and initrd files are generated with the following naming conventions:

  • ISO: photon-<photon-release-version>.iso

  • Initrd: initrd.img

Prerequisite

To generate a custom ISO, ensure that you provide the following required parameters:

  • List of custom packages in JSON format
  • Photon Release Version
  • Generating Function: For example, build-iso, build-initrd, and build-rpm-ostree-iso
  • Path to OSTree tar archive (required only if function is set to build-rpm-ostree-iso)

Note: You must provide the additional repository if you want to include a package that the Photon OS official repository does not provide.

You can also provide the following optional parameters:

  • Custom Kickstart file
  • Additional repositories
  • Boot command line parameters
  • Custom Initrd package list file
  • Artifact path

Preparing for Custom Image Generation

  1. Install the following prerequisite packages:

    • python3-pip
    • git
    • tar
    • createrepo_c
    • binutils
    • dosfstools
    • cdrkit
    • docker

    i. To install the specified packages on Photon OS, use the following command:

    tdnf install -y python3-pip git tar createrepo_c binutils dosfstools cdrkit
    
  2. Run following command to install photon-os-installer python library:

    pip3 install git+https://github.com/vmware/photon-os-installer.git
    
  3. Enable the following services before you build the custom iso/initrd: docker

    i. To enable the docker service and log in to the docker account, use the following command:

    systemctl start docker.service;
    docker login # To avoid docker pull rate limit
    
  4. Create the file containing the custom package list.

    The following list shows some of the sample custom package files:

    Package list json format-

    {
    "packages": <list-of-pkgs>,
    "packages_x86_64": <x86-specific-pkgs>,
    "packages_aarch64": <aarch64-specific-pkgs>
    }
    

For more details, refer to the following link: https://github.com/vmware/photon-os-installer/blob/master./ks_config.md#packages-optional-if-packagelist_file-set

Note: packages_x86_64 and packages_aarch64 are optional keys. The packages_minimal.json file is a sample file. You can create your own JSON file with the list of custom packages that you want, and provide the directory path for the file in the command to generate the iso/initrd.

Generating a Custom Image

You can use the respective commands to generate the custom images for the following use cases.

Using Package List

Command:

photon-iso-builder -v <photon-release-version> -p <path/to/custom-package-list-json>

Example:

photon-iso-builder -v 5.0 -p /root/packages_custom.json

Note: you can skip the --function invocation because photon-iso-builder sets the default function to build-iso.

Using Package List and Additional Repository

photon-iso-builder -v <photon-release-version> -p <path/to/custom-package-list-json> [-r <path/to/custom-repo-list>]

Example:

photon-iso-builder -v 5.0 -p /root/packages_custom.json -r local.repo -r local2.repo

Note: In order to create your own custom repository, see the following page: Adding a New Repository

Using Custom Kickstart File

Command:

photon-iso-builder -v <photon-release-version> -p <path/to/custom-package-list-json> -k <path-to-kickstart>

Example:

photon-iso-builder -v 5.0 -p /root/packages_custom.json -k /root/custom_kickstart.json

To create a custom kickstart configuration file, see the follow page: Kickstart Configuration

Note: If the Kickstart file is provided while creating the custom ISO, boot command line parameter is not edited to install the ISO through kickstart.

To boot the ISO through the provided kickstart file, you need to create the custom ISO file using the following format:

photon-iso-builder -v <photon-release-version> -p <path/to/custom-package-list-json> -f build-iso -k <path-to-kickstart> -b "ks=cdrom:/isolinux/<kickstart-file-base-name>"

Example:

photon-iso-builder -v 5.0 -p /root/packages_custom.json -k /root/custom_kickstart.json -b "ks=cdrom:/isolinux/custom_kickstart.json"

Using Extra Boot Command Line Parameters

Command:

photon-iso-builder -v <photon-release-version> -p <path/to/custom-package-list-json> -f build-iso -b <extra-boot-parameter>

Example:

photon-iso-builder -v 5.0 -p /root/packages_custom.json -b "ks=http://10.197.102.86:8000/sample_ks.cfg insecure_installation=1"

Using Default Installation as RPM-OStree

Before you generate the custom image using default installation as RPM-OStree, you need to generate ostree tar archive. Perform the following steps to generate the ostree tar archive:

  1. Generate the ostree repo tree as directed here: Creating a Server

  2. Create tarball of the repo tree:

    Command:

	tar -czf </path/to/>ostree-repo.tar.gz -C </path/to/repotree>/repo

Example: repo tree resides inside the following directory my-repo like /root/my-repo/repo

	tar -zcf /root/ostree-repo.tar.gz -C /root/my-repo/repo .

Once the tar archive is generated, generate the custom image. To generate the custom image using default installation as RPM-OStree, execute the following command:

photon-iso-builder -v <photon-release-version> -o <path/to/ostree-tar-archive> -f build-rpm-ostree-iso

Example:

photon-iso-builder -v 5.0 -o /root/ostree-repo.tar.gz -f build-rpm-ostree-iso

Note: You can either provide a local path or a URL for the ostree tar archive. Custom package list json is not required for this case.

Using Custom Artifact Path

Command:

photon-iso-builder -v <photon-release-version> -p <path/to/custom-package-list-json> -a <custom-artifact-path>

Note: Custom artifact path parameter takes parent directory path as the input in which the artifact is placed.

As per the user input, artifact is placed under /root/custom/path in the following example:

photon-iso-builder -v 5.0 -p /root/packages_custom.json -a /root/custom/path

Custom Initrd

Command:

photon-iso-builder -v <photon-release-version> -c <path/to/custom-initrd-pkg-list-file> -f build-initrd

Example:

photon-iso-builder -v 5.0 -c /root/packages_custom_initrd.json -f build-initrd

The default initrd package list file is located in the following directory: https://github.com/vmware/photon/blob/master/common/data/packages_installer_initrd.json

Generating custom ISO through source code:

The following command demonstrate how to generate a custome ISO through the source code:

git clone https://github.com/vmware/photon-os-installer.git
cd photon-os-installer/photon_installer
./isoBuilder -v 5.0 -p packages_minimal.json

4.4 - Building Package or Kernel Modules Using a Script

You can use a script to build a single Photon OS package without the need to setup a complete Photon build workspace. You just need a .spec specification file and the source files. You can place the source files and the specification files in the same folder, or provide a URL for the source file location, and then run the build_spec.sh script.

The script performs the following steps:

  • Creates sandbox using docker
  • Installs build tools and .spec build requirements from the Photon OS repository
  • Runs rpmbuild

Result: You have a native Photon OS RPM package.

The build-spec.sh script is located in the photon/tools/scripts/ folder.

Prerequisites

Before you run the build-spec.sh script, perform the following steps:

  • Ensure you have any Linux OS with a docker daemon running.
  • Place the source and RPM .spec files in the same folder or provide a URL for the source files.

Procedure

Run the script. Provide the RPM .spec file name, including absolute or relative path, as an argument:

./photon/tools/scripts/build_spec.sh <path-to-rpm_spec_file.spec> [$STAGEDIR]

You can specify the staging directory ($STAGEDIR) where you want to store the generated RPM files and build logs. If you do not specify a staging directory, the generated output files are stored in the directory that contains the spec file.

The following topics show examples to build packages based on various use cases.

4.4.1 - Hello World Kernel Module

This example shows how to build a package that provides a hello world kernel module. To build the package, you need to run the script with hello-world.spec as an argument, where hello-world.spec is the RPM specification file.

You can find the source file at the following location:

https://github.com/vmware/photon/tree/<BRANCH>/tools/examples/build_spec/kernel_module_example/hello-world.tar.gz	

To generate the output in the spec-file folder, run the following command:

./photon/tools/scripts/build_spec.sh ./photon/tools/examples/build_spec/kernel_module_example/hello-world.spec

The following are the contents of the hello-world.spec file:

%define linux_esx_ver 6.1.10

Summary:        Hello World Linux module
Name:           hello-world
Version:        1.0
Release:        1%{?dist}
License:        GPLv2
Group:          System Environment/Kernel
Vendor:         VMware, Inc.
Distribution:   Photon
Source0:        hello-world.tar.gz
BuildRequires:  linux-esx-devel = %{linux_esx_ver}
BuildRequires:  kmod
Requires:       linux-esx = %{linux_esx_ver}

%description
Example of building linux module for Photon OS

%prep
%autosetup -n hello-world

%build
make -C `echo /usr/src/linux-headers-%{linux_esx_ver}*` M=`pwd` VERBOSE=1 modules %{?_smp_mflags}

%install
make -C `echo /usr/src/linux-headers-%{linux_esx_ver}*` M=`pwd` INSTALL_MOD_PATH=%{buildroot} modules_install %{?_smp_mflags}
# fix permissins to generate non empty debuginfo
find %{buildroot}/lib/modules -name '*.ko' -print0 | xargs -0 chmod u+x

%ldconfig_scriptlets

%post
/sbin/depmod -a

%files
%defattr(-,root,root)
/lib/modules/*

Build Logs

The following logs indicate the steps that the script performs internally:


0. Build Script Version: 1.1
1. Create sandbox
        Use local build template image OK
2. Prepare build environment
        Create source folder OK
        Copy sources from ./photon/tools/examples/build_spec/kernel_module_example OK
        install createrepo OK
        createrepo  OK
        Create local repo in sandbox OK
        makecache OK
3. Build Binary and Source Package
        Run rpmbuild OK 
        Delete SOURCES OK
4. Destroy sandbox 
        Stop container OK
        Remove container OK
Build completed. RPMS are in './photon/tools/examples/build_spec/kernel_module_example/stage' folder

Verification

You can verify the generated output with the following commands:

  • Command to install the RPM:
rpm -ivh ./photon/tools/examples/build_spec/kernel_module_example/stage/RPMS/x86_64/hello-world-1.0-1.ph5.x86_64.rpm
  • Command to install the kernel module:
modprobe hello-world
  • Command to verify the installed kernel module:
dmesg | grep "Hello World"

4.4.2 - Hello World Binary

This example shows how to build a package that provides a hello world binary. To build the package, you need to run the script with hello-world-user1.spec as an argument, where hello-world-user1.spec is the RPM specification file.

You can find the source file at the following location:

https://github.com/vmware/photon/tree/<BRANCH>/tools/examples/build_spec/user_package_example/hello-world-user1.tar.gz

To generate the output in a staging directory, run the following command:

./photon/tools/scripts/build_spec.sh ./photon/tools/examples/build_spec/user_package_example/hello-world-user1.spec $STAGEDIR

The following are the contents of the hello-world-user1.spec file:

% Summary:      Hello World User Package
Name:           hello-world-user1
Version:        1.0
Release:        1%{?dist}
License:        GPLv2
Group:          System Environment/Kernel
Vendor:         VMware, Inc.
Distribution:   Photon
Source0:        hello-world-user1.tar.gz

%description
Example of building User Package for Photon OS

%prep
%autosetup -n hello-world-user1

%build
make %{?_smp_mflags}

%install
make %{?_smp_mflags} install DESTDIR=%{buildroot}

%ldconfig_scriptlets

%files
%defattr(-,root,root)
/usr/bin/*

Build Logs

The following logs indicate the steps that the script performs internally:

0. Build Script Version: 1.1
1. Create sandbox
        Use local build template image OK
2. Prepare build environment
        Create source folder OK
        Copy sources from ./photon/tools/examples/build_spec/user_package_example OK
        install createrepo OK
        createrepo  OK
        Create local repo in sandbox OK
        makecache OK
        Install build requirements OK
3. Build Binary and Source Package
        Run rpmbuild OK
        Delete SOURCES OK
4. Destroy sandbox
        Stop container OK
        Remove container OK
Build completed. RPMS are in '$STAGEDIR' folder

Verification

You can verify the generated output with the following commands:

  • Command to install the RPM:
rpm -ivh $STAGEDIR/RPMS/x86_64/hello-world-user-1.0-1.ph5.x86_64.rpm
  • Command to verify the installed user package (execute the installed binary of the user package):
root@photon-aab77099dca0root [ ~ ]# /usr/bin/hello-world-user
     Hello World

4.4.3 - Manage a Dependent package

This example shows how to build a dependent package. To build the package, you need to run the script with hello-world-user.spec as an argument, where hello-world-user.spec depends on the RPM build from hello-world-user1.spec (hello-world-user -> hello-world-user1)

You can find the source file at the following location:

https://github.com/vmware/photon/tree/<BRANCH>/tools/examples/build_spec/user_package_example/hello-world-user.tar.gz

To generate the output in a staging directory, run the following command:

./photon/tools/scripts/build_spec.sh ./photon/tools/examples/build_spec/user_package_example/hello-world-user.spec $STAGEDIR

The following are the contents of the hello-world-user.spec file:

Summary:        Hello World User Package
Name:           hello-world-user
Version:        1.0
Release:        1%{?dist}
License:        GPLv2
Group:          System Environment/Kernel
Vendor:         VMware, Inc.
Distribution:   Photon
Source0:        hello-world-user.tar.gz
BuildRequires:  hello-world-user1
BuildRequires:  git
Requires:       hello-world-user1

%description
Example of building User Package for Photon OS

%prep
%autosetup -n hello-world-user

%build
make %{?_smp_mflags}

%install
pwd
make %{?_smp_mflags} install DESTDIR=%{buildroot}

%ldconfig_scriptlets

%files
%defattr(-,root,root)
/usr/bin/*

Build Logs

The following logs indicate the steps that the script performs internally:

0. Build Script Version: 1.1
1. Create sandbox
        Use local build template image OK
2. Prepare build environment
        Create source folder OK
        Copy sources from ./photon/tools/examples/build_spec/user_package_example OK
        install createrepo OK
        createrepo  OK
        Create local repo in sandbox OK
        makecache OK
        Install build requirements OK
3. Build Binary and Source Package
        Run rpmbuild OK
        Delete SOURCES OK
4. Destroy sandbox
        Stop container OK
        Remove container OK
Build completed. RPMS are in '$STAGEDIR' folder.

4.4.4 - Include a patch file

This example shows how to build a package with a patch file. To build the package, you need to run the script with python-M2Crypto.spec as an argument, where python-M2Crypto.spec is the RPM specification file.

You can find the patch file at the following location:

https://github.com/vmware/photon/tree/<BRANCH>/tools/examples/build_spec/user_package_example/0001-openssl-3.0.0-support.patch

To generate the output in the spec-file folder, run the following command:

./photon/tools/scripts/build_spec.sh ./photon/tools/examples/build_spec/user_package_example/python-M2Crypto.spec

The following are the contents of the python-M2Crypto.spec file:

Name:           python3-M2Crypto
Version:        0.36.0
Release:        1%{?dist}
Summary:        Crypto and SSL toolkit for Python
Group:          Development/Languages/Python
License:        MIT
URL:            https://pypi.python.org/pypi/M2Crypto/0.26.0
Source0:        https://pypi.python.org/packages/11/29/0b075f51c38df4649a24ecff9ead1ffc57b164710821048e3d997f1363b9/M2Crypto-%{version}.tar.gz
Vendor:         VMware, Inc.
Distribution:   Photon

BuildRequires:  openssl
BuildRequires:  openssl-devel
BuildRequires:  python3-devel
BuildRequires:  python3-setuptools
BuildRequires:  python3-typing
BuildRequires:  swig
BuildRequires:  python3-xml
Requires:       python3-typing
Requires:       python3
Requires:       openssl
Patch0:         0001-openssl-3.0.0-support.patch

%description
M2Crypto is a crypto and SSL toolkit for Python featuring the following:

RSA, DSA, DH, HMACs, message digests, symmetric ciphers (including
AES). SSL functionality to implement clients and servers. HTTPS
extensions to Python's httplib, urllib, and xmlrpclib. Unforgeable
HMAC'ing AuthCookies for web session management. FTP/TLS client and
server. S/MIME. ZServerSSL: A HTTPS server for Zope. ZSmime: An S/MIME
messenger for Zope.

%prep
# Using autosetup is not feasible
%setup -q -n M2Crypto-%{version}
%patch0 -p1

%build
CFLAGS="%{optflags}" python3 setup.py build --openssl=/usr/include --bundledlls

%install
rm -rf %{buildroot}
python3 setup.py install --prefix=%{_prefix} --root=%{buildroot}

%files
%defattr(-,root,root)
%{python3_sitelib}/*

Build Logs

The following logs indicate the steps that the script performs internally:

0. Build Script Version: 1.1
1. Create sandbox
        Use local build template image OK
2. Prepare build environment
        Create source folder OK
        Copy sources from ./photon/tools/examples/build_spec/user_package_example OK
        Download M2Crypto-0.36.0.tar.gz OK
        install createrepo OK
        createrepo  OK
        Create local repo in sandbox OK
        makecache OK
        Install build requirements OK
3. Build Binary and Source Package
        Run rpmbuild OK
        Delete SOURCES OK
4. Destroy sandbox
        Stop container OK
        Remove container OK
Build completed. RPMS are in './photon/tools/examples/build_spec/user_package_example/stage' folder

4.4.5 - Refer an External Source

This example shows how to build a package that downloads the source files from an external website like GitHub. To build the package, you need to run the script with libdrm.spec as an argument, where libdrm.spec is the RPM specification file.

./photon/tools/scripts/build_spec.sh ./photon/tools/examples/build_spec/user_package_example/libdrm.spec

The following are the contents of the libdrm.spec file:

Summary:        user space library for accessing the DRM.
Name:           libdrm
Version:        2.4.110
Release:        1%{?dist}
License:        MIT
URL:            http://dri.freedesktop.org/
Group:          System Environment/Libraries
Vendor:         VMware, Inc.
Distribution:   Photon

Source0:        https://dri.freedesktop.org/libdrm/%{name}-%{version}.tar.xz

BuildRequires:  meson
BuildRequires:  libpciaccess-devel
Requires:       libpciaccess
Provides:       pkgconfig(libdrm)

%description
libdrm provides a user space library for accessing the DRM, direct rendering manager, on operating systems that support the ioctl interface. libdrm is a low-level library, typically used by graphics drivers such as the Mesa DRI drivers, the X drivers, libva and similar projects.

%package        devel
Summary:        Header and development files
Requires:       %{name} = %{version}-%{release}

%description    devel
libdrm provides a user space library for accessing the DRM, direct rendering manager, on operating systems that support the ioctl interface. libdrm is a low-level library, typically used by graphics drivers such as the Mesa DRI drivers, the X drivers, libva and similar projects.

%prep
%autosetup -p1

%build
CONFIGURE_OPTS=(
        -Dintel=false
        -Dradeon=false
        -Damdgpu=true
        -Dnouveau=false
        -Dvmwgfx=false
        -Dlibkms=false
)

%meson "${CONFIGURE_OPTS[@]}"
meson --prefix=%{_prefix} build

%install
DESTDIR=%{buildroot}/ ninja -C build install

%ldconfig_scriptlets

%files
%defattr(-,root,root)
%{_libdir}/lib*
%{_datadir}/libdrm/*

%files devel
%defattr(-,root,root)
%{_includedir}/*
%{_libdir}/pkgconfig*

Build Logs

The following logs indicate the steps that the script performs internally:

0. Build Script Version: 1.1
1. Create sandbox
        Use local build template image OK
2. Prepare build environment
        Create source folder OK
        Copy sources from ./photon/tools/examples/build_spec/user_package_example OK
        Download libdrm-2.4.110.tar.xz OK
        install createrepo OK
        createrepo  OK
        Create local repo in sandbox OK
        makecache OK
        Install build requirements OK
3. Build Binary and Source Package
        Run rpmbuild OK
        Delete SOURCES OK
4. Destroy sandbox
        Stop container OK
        Remove container OK
Build completed. RPMS are in './photon/tools/examples/build_spec/user_package_example/stage' folder

4.5 - Running Photon OS on vSphere

You can use Photon OS as a virtual machine within VMware vSphere. You can download Photon OS, as an OVA or ISO file, and install the Photon OS distribution on vSphere. After you install Photon OS, you can deploy a containerized application in Docker with a single command.

Note: If you want to upgrade an existing Photon 1.0 VM, see the Upgrade to Photon OS 5.0 section.

4.5.1 - Prerequisites for Running Photon OS on vSphere

Resource requirements and recommendations vary depending on several factors, including the host environment (for example, VMware vSphere and VMware Fusion), the distribution file used (ISO or OVA), and the selected installation settings (for example, full or basic installation).

Before you use Photon OS within VMware vSphere, perform the following prerequisite tasks:

  1. Verify that you have the following resources:

    ResourceDescription
    VMware vSphere installedVMware web client (v6.5) for ESXi hosts (recommended)

    Note: vSphere 6 and vSphere 5.5 (these clients provide limited support; Not all features are available).

    MemoryESXi host with 2GB of free RAM (recommended)
    StorageMinimal Photon install: ESXi host with at least 512MB of free space (minimum); Full Photon install: ESXi host with at least 4GB of free space (minimum); 16GB is recommended; 16GB recommended.
    Distribution FilePhoton OS ISO or OVA file downloaded from [https://packages.vmware.com/photon/](https://packages.vmware.com/photon/).

    Note: The setup instructions in this guide use VMware vSphere 6 and the vSphere web client.

  2. Decide whether to use the OVA or ISO distribution to set up Photon OS.

    • OVA import : Because of the nature of an OVA, you’re getting a pre-installed version of Photon OS. You can choose the hardware version you want (OVA with hardware version 13 or 11). The OVA benefits from a simple import process and some kernel tuning for VMware environments. However, because it’s a pre-installed version, the set of packages that are installed are predetermined. Any additional packages that you need can be installed using tdnf.
    • ISO install : The ISO, on the other hand, allows for a more complete installation or automated installation via kickstart.

    To get Photon OS up and running quickly, use the OVA.

  3. Download Photon OS. Go to the following URL and download the latest release of Photon OS:

    https://packages.vmware.com/photon/

    For instructions, see https://github.com/vmware/photon/wiki/Downloading-Photon-OS.

    Note: For ISO installation, you must upload to a datashare that is attached to the ESXi host, or mount the file share where the ISO resides as a data store.

4.5.2 - Importing the OVA for Photon OS

Using the OVA is a fast and easy way to create a Photon OS VM on VMware vSphere.

After you have downloaded the OVA, log in to your vSphere environment and perform the following steps:

  1. Start the Import Process

    From the Actions pull-down menu, choose Create/Register VM.

    In the Select creation type window, choose Deploy a virtual machine from an OVF or OVA file.

    Create new virtual machine

    Choose Next.

  2. Select the OVA File

    Enter a name for the virtual machine, and select the OVA file.

    OVA file

    Choose Next.

  3. Specify the Target Datastore

    From the Select storage screen, select the target datastore for your VM.

    Target datastore

    Choose Next.

  4. Accept the License Agreement

    Read through the Photon OS License Agreement, and then choose I Agree.

    License

    Choose Next.

  5. Select Deployment Options

    Photon OS is provisioned with a maximum disk size. By default, Photon OS uses only the portion of disk space that it needs, usually much less that the entire disk size ( Thin client). If you want to pre-allocate the entire disk size (reserving it entirely for Photon OS instead), select Thick instead.

    Deployment Options

    Choose Next.

  6. Verify Deployment Settings

    Deployment settings

    Click Finish. vSphere uploads and validates your OVA. Depending on bandwidth, this operation might take a while.

    When finished, vShield powers up a new VM based on your selections.

  7. Change Login Settings

    Login prompt

    After the VM is booted, open the command window. vSphere prompts you to log in.

    Note: Because of limitations within OVA support on vSphere, it was necessary to specify a default password for the OVA option. However, all Photon OS instances that are created by importing the OVA require an immediate password change upon login. The default account credentials are:

     - Username: ``root``
     - Password: ``changeme``
    

    After you provide these credentials, vSphere prompts you to create a new password and type it a second time to verify it.

    Note: For security, Photon OS forbids common dictionary words for the root password.  

    Once logged in, you will see the shell prompt.

    Shell prompt

    Once complete, proceed to Deploying a Containerized Application in Photon OS.

  8. Export the VM as a Template (Optional)

    Consider converting this imported VM into a template (from the Actions menu, choose Export ) so that you have a master Photon OS instance that can be combined with vSphere Guest Customization to enable rapid provisioning of Photon OS instances.

4.5.3 - Installing the ISO Image for Photon OS

After you download the Photon OS ISO image into a folder of your choice, complete the following steps.

  1. Upload the ISO Image

    Upload the ISO image to a datastore that is attached to the host on which you’ll create the Photon OS virtual machine.

  2. Create a new VM

    Log in to your vSphere environment. In the Virtual Machines window, choose Create/Register VM.

    On the Select creation type screen, select Create a new virtual machine.

    Create new virtual machine

    Choose Next.

  3. Configure VM Settings

    Specify a VM name.

    VM name

    Specify a guest operating system.

    • For Compatibility, select ESXi 6.7.
    • For Guest OS family, select Linux.
    • For Guest OS version, select VMware Photon OS (64-bit).

    Guest operating system

    Choose Next.

  4. Select the Target Datastore

    Select the datastore where you want to store the VM.

    Target datastore

    Click Next.

  5. Customize VM Settings

    Customize the virtual machine settings.

    Settings

    For CD/DVD Drive 1, click the drop-down and select Datastore ISO file.

    In the Datastore browser, select the ISO that you want to import.

    Change other settings as applicable.

    • The recommended virtual hardware settings for your Photon VM are heavily dependent upon the container load you intend to run within Photon OS – more containers or more intensive containers will require you to adjust these settings for your application load. VMware suggests 2 vCPU, 1024MB memory, 20GB hard disk. Any unwanted devices should be removed. Be sure to mount the Photon OS ISO on the CD/DVD Drive and put a check in the box next to, Connect At Power On.
    • If you want to configure a secure boot for the Photon OS VM you created, choose the VM Options tab, expand Boot Options, and select EFI from the firmware drop-down. An EFI boot ensures that the ISO content is signed by VMware and that the entire stack is secure.

    Choose Next.

  6. Verify VM Settings

    The installer displays a summary of your selected settings.

    Summary

    Click Finish. vSphere creates the VM.

  7. Power on the VM

    Select the VM and power it on.

    Power on VM

    When you see the Photon Installer boot menu, press Enter on your keyboard to start installing.

  8. Accept the License Agreement

    Read the License Agreement and press the Enter key to accept.

    License Agreement

  9. Configure the Partition

    The installer detects one disk, which should be the 16GB volume configured as part of the virtual machine creation. Choose Auto to have the installer automatically allocate the partition, or choose Custom if you want to configure individual partitions, and then press the Enter key.

    Partition

    Note: If you choose Custom, the installer displays the following screen.

    Custom Partition

    For each custom partition, choose Create New and specify the following information:

    New Partition

    Size - Preallocated size of this partition, in MB.

    Type - One of the following options:

    • ext3 - ext3 file system
    • ext4 - ext4 file system
    • swap - swap partition

    Mountpoint - Mount point for this partition.

    Choose OK and press the Enter key. When you are done defining custom partitions, choose Next and press the Enter key.

    The installer prompts you to confirm that you want to erase the entire disk.

    Erase disk

    Choose Yes and press the Enter key.

  10. Select an Installation Option

    After partitioning the disk, the installer prompts you to select an installation option.

    Installation Option

    Each install option provides a different run-time environment, depending on your requirements.

    OptionDescription
    Photon MinimalPhoton Minimum is a very lightweight version of the container host runtime that is best suited for for devices that have limited compute and memory capabilities. There is sufficient packaging and functionality to allow most common operations around modifying existing containers, as well as being a highly performant and full-featured runtime.

    Photon DeveloperPhoton Developer includes several additional packages to enhance the authoring and packaging of containerized applications and/or system customization. Use Photon Developer for developing and packaging the application that will be run as a container, as well as authoring the container, itself. For testing and validation purposes, Photon Developer includes all components necessary to run containers.
    Photon OSTree HostThis installation profile creates a Photon OS instance that will source its packages from a central rpm-ostree server and continue to have the library and state of packages managed by the definition that is maintained on the central rpm-ostree server.
    Photon Real TimeThis profile is available only for the x86_64 architecture.

    Note: The option you choose determines the disk and memory resources required for your installation.

    Select the option you want and press the Enter key.

  11. The Network Configuration screen appears, select one of the four options to configure your network.

    Network Configuration

    1. Choose Configure network automatically and select Next to configure the network automatically.

    2. To configure network automatically with the DHCP hostname, select Configure network automatically with a DHCP hostname and select Next. Enter the DHCP Hostname and select Next. ../images/DHCP_hostname_for_your_system.png

    3. To configure the network manually, select Configure Network manually. In the window that appears, enter the IP Address, Netmask, Gateway and Nameserver and select OK. ../images/Configure_Network_Manually.png

    4. If your network interface is directly connected to the VLAN trunk port, choose YES on the Configure the network screen. Enter the VLAN ID and select Next. Configure the network.

  12. Select the Linux Kernel

    Select a Linux kernel to install.

    Linux Kernel

    • Hypervisor optimized means that any components that are not needed for running under a VMware hypervisor have been removed for faster boot times.
    • Generic means that all components are included.

    Choose Next and press the Enter key.

  13. Specify the Hostname

    The installer prompts you for a hostname and suggest a randomly generated, unique hostname that you can change if you want.

    Hostname

    Press the Enter key.

  14. Specify the System root Password

    The installer prompts you to enter the system root password.

    Note: Photon OS will not permit commonly used dictionary words to be set as a root password.

    Root password

    Type a password and press the Enter key.

    The installer prompts you to confirm your root password by typing it a second time.

    Password confirmation

    Note: If you have trouble with unintentional repeated characters in the Remote Console, follow VMware KB 196 ( http://kb.vmware.com/kb/196) for a setting to apply to the virtual machine.

    Press the Enter key. The installer proceeds to install the software. Installation times will vary based on the system hardware and installation options you selected. Most installations complete in less than one minute.

  15. Reboot the VM and Log In

    Once finished, the installer displays a confirmation message (which includes how long it took to install Photon OS) and prompts you to press a key on your keyboard to boot the new VM.

    Boot VM

    As the initial boot process begins, the installer displays the Photon splash screen, and then a login prompt.

    Login prompt

    At the login prompt, type root as the username and provide the password chosen during the installation.

    Password

You can now use your container runtime environment and deploy a containerized application.

4.6 - Running Photon OS on Fusion

You can use Photon OS as a virtual machine within VMware Fusion. You can download Photon OS, as an OVA or ISO file, and install the Photon OS distribution on Fusion. After you install Photon OS, you can deploy a containerized application in Docker with a single command.

Note: If you want to upgrade an existing Photon 1.0 VM, refer to the instructions in the Upgrading to Photon OS 5.0 section.

4.6.1 - Prerequisites for Running Photon OS on Fusion

Resource requirements and recommendations vary depending on several factors, including the host environment (for example, VMware Fusion and VMware vSphere), the distribution file used (ISO or OVA), and the selected installation settings (for example, full or basic installation).

Before you use Photon OS within Fusion, perform the following prerequisite tasks:

  1. Verify that you have the following resources:

    ResourceDescription
    VMware FusionVMware Fusion (v7.0 or higher) must be installed. The latest version (v12) is recommended.
    Memory2GB of free RAM (recommended)
    StorageMinimal Photon install : 512MB of free space (minimum); Full Photon install : 4GB of free space (minimum); 8GB recommended.
    Distribution FilePhoton OS ISO or OVA file downloaded from [https://packages.vmware.com/photon/](https://packages.vmware.com/photon/).

    Note: The setup instructions in this guide use VMware Fusion Professional version 8.5.8, as per the following screenshot.

    Fusion version

  2. Decide whether to use the OVA or ISO distribution to set up Photon OS.

    • OVA import : Because of the nature of an OVA, you’re getting a pre-installed version of Photon OS. You can choose the hardware version you want (OVA with hardware version 13 or 11). The OVA benefits from a simple import process and some kernel tuning for VMware environments. However, because it’s a pre-installed version, the set of packages that are installed are predetermined. Any additional packages that you need can be installed using tdnf.
    • ISO install : The ISO, on the other hand, allows for a more complete installation or automated installation via kickstart.

    To get Photon OS up and running quickly, use the OVA.

  3. Download Photon OS. Go to the following URL and download the latest release of Photon OS:

    https://packages.vmware.com/photon/

    For instructions, see Downloading Photon OS.

4.6.2 - Importing the OVA for Photon OS

Using the OVA is a fast and easy way to create a Photon OS VM on Fusion.

After you have downloaded the Photon OS OVA image (OVA with Hardware Version 15) into a folder of your choice, open VMware Fusion and perform the following steps:

  1. Start the Import Process

    From the File menu, choose Import …. Fusion prompts you to choose an existing virtual machine.

    Import process

    Choose the Choose File … button to locate and select the Photon OS OVA, then choose Continue.

    Select OVA

  2. Specify the Name and Storage Location

    Provide the name and storage location for your Photon OS VM, then choose Save.

    Name and storage location

    Review the Photon OS License Agreement, then choose Accept to start the import process.

    License

  3. Configure VM Settings

    After the OVA is imported, Fusion displays a confirmation that the import has completed and a summary of the settings for your Photon OS VM. The following screen shot is an example (your settings may vary).

    VM settings

    Important: Choose Customize Settings to change the operating system (as recognized by the hypervisor) for the newly imported VM.

    Custom settings

    Choose General.

    Click the selection box next to OS, select Linux , and then select VMware Photon 64-bit.

    Operating system

    Close the settings window. Fusion prompts you to verify that you want to change the operating system.

    Confirm settings

    Click Change. Your Photon OS VM is ready to power on.

  4. Power on the VM

    Power on the Photon OS VM. Fusion may ask you whether you want to upgrade this VM.

    Upgrade VM

    How you respond depends on which hardware version (15 or 20) that you want to use. Upgrade if you need to use devices supported only in hardware version 20. Don’t upgrade if you want to be compatible with older tools that are supported in hardware version 15.

  5. Update Login Credentials

    Login prompt

    After the VM is booted, Fusion prompts you to log in.

    Note : Because of limitations within OVA support on Fusion, it was necessary to specify a default password for the OVA option. However, all Photon OS instances that are created by importing the OVA will require an immediate password change upon login. The default account credentials are:

    • Username: root
    • Password: changeme

    After you provide these credentials, Fusion prompts you to create a new password and type it a second time to verify it. For security, Photon OS forbids common dictionary words for the root password. Once logged in, you will see the shell prompt.

Once complete, proceed to Deploying a Containerized Application in Photon OS.

4.6.3 - Installing the ISO Image for Photon OS

After you have downloaded the latest Photon OS ISO image into a folder of your choice, open VMware Fusion.

  1. Start the Installation Process

    From the File menu, choose New.

    Installation

    From the Select the Installation Method dialog, select Install from disc or image, and then choose Continue.

    Installation method

  2. Select the ISO Image

    Drag a disc image onto the window or choose Use another disc or disc image…, choose the ISO file you want, and then choose Continue.

    ISO image

  3. Select the Operating System

    On the Choose Operating System dialog, select Linux in the left-hand column and VMware Photon 64-bit in the right-hand column.

    Operating system

    Choose Continue.

  4. Select the Virtual Disk (Optional)

    If you are using a Fusion version that is older than Fusion 8, you might see the following dialog.

    Virtual disk

    If you see this dialog, unless you’re installing into an existing machine, choose Create a new virtual disk from the Choose a Virtual Disk dialog, and then choose Continue.

    Note: Fusion v8 and later automatically defaults to creating a new 8GB disk and formats it automatically. If you want to use an existing disk, or if you want to pre-allocate all 8GB, go into VM Settings, choose Add Device, and choose either New Hard Disk or Existing Hard Disk. Expand Advanced options and configure whether you want to pre-allocate disk space (disabled by default) or split into multiple files (enabled by default).

  5. Configure VM Settings

    Important: Before you finish creating the Photon OS Virtual Machine, we strongly recommend that you customize the virtual machine and remove any unwanted devices that are not needed for a container run-time environment.

    VM settings

    To remove unnecessary devices, choose Customize Settings.

    First, choose a name for your Virtual Machine, along with the folder into which you create the Virtual Machine (or accept the default folder).

    Custom settings

    Choose Save. The virtual machine will be created. The Settings screen allows you to customize virtual hardware for the new virtual machine. If it does not automatically appear, open Settings from the Virtual Machine menu bar.

    Settings

    You can remove (recommended) the following components that are not used by Photon OS:

    • Select Display and ensure that the Accelerate 3D Graphics option is unchecked (it should be unchecked, by default). Select Show All to return to the VM Settings.
    • Select CD/DVD (IDE) and ensure that the Connect CD/DVD Drive box is checked (it should be checked by default). Select Show All to return to the VM Settings.
    • Select Sound Card, un-check the Connect Sound Card Option, and click Remove Sound Card. Choose Remove to confirm your action. Select Show All to return to the VM Settings.
    • Select USB & Bluetooth and uncheck the Share Bluetooth devices with Linux setting. Select Show All to return to the VM Settings.
    • Select Printer and press the Remove Printer Port button in the bottom left hand corner. Choose Remove to confirm your action. Select Show All to return to the VM Settings.
    • Select Camera and press the Remove Camera button in the bottom left hand corner. Choose Remove to confirm your action. Select Show All to return to the VM Settings.
    • Select Advanced and ensure that the Pass Power Status to VM option is unchecked (it should be unchecked, by default). Select Show All, but do not close the VM Settings window.

    By default, Photon OS is configured with a disk size of 8GB. However, Photon OS uses only the portion of disk space it needs, usually much less that the entire disk size. If you want to pre-allocate the entire disk size (reserving it entirely for Photon OS instead), select Hard Disk, expand Advanced options, and check Pre-allocate disk space (by default, it is unchecked). Select Show All to return to the VM Settings.

  6. Configure a Secure Boot (Optional)

    Note: If you want to configure a secure boot for the Photon OS VM you created, edit its .vmx file and add the following line:

    firmware = “efi”

    The EFI boot ensures that the ISO content is signed by VMware and that the entire stack is secure.

    After you have made the customizations you want, close the Virtual Machine Settings window. You are now ready to boot and begin the installation process.

  7. Power On the VM

    Return to the Fusion main menu, select the Photon OS Virtual Machine, and click Start Up (you can also choose Start Up from the Virtual Machine menu).

    Fusion powers on the host and starts the installation. Within a few seconds, Fusion displays the Photon OS installer boot menu.

    Photon OS installer

    Press the Enter key on your keyboard to start installing.

    License

    Read the License Agreement and press the Enter key to accept.

  8. Configure the Partition

    The Installer will detect one disk, which should be the 8GB volume configured as part of the virtual machine creation.

    Partition

    Choose Auto to have the installer automatically allocate the partition, or choose Custom if you want to configure individual partitions, and then press the Enter key.

    Note: If you choose Custom, the installer displays the following screen.

    Custom partition

    For each custom partition, choose Create New and specify the following information:

    New partition

    Size - Preallocated size of this partition, in MB.

    Type - One of the following options:

    • ext3 - ext3 file system
    • ext4 - ext4 file system
    • swap - swap partition

    Mountpoint - Mount point for this partition.

    Choose OK and press the Enter key. When you are done defining custom partitions, choose Next and press the Enter key.

    The installer prompts you to confirm that you want to erase the entire disk.

    Disk erase

    Choose Yes and press the Enter key to accept and proceed with the installation.

  9. Select an Installation Option

    After partitioning, the installer prompts you to select one of three installation options:

    Installation options

    Each install option provides a different run-time environment. Select the option that best meets your requirements.

    OptionDescription
    Photon MinimalPhoton Minimum is a very lightweight version of the container host runtime that is best suited for container management and hosting. There is sufficient packaging and functionality to allow most common operations around modifying existing containers, as well as being a highly performant and full-featured runtime.

    Photon FullPhoton Full includes several additional packages to enhance the authoring and packaging of containerized applications and/or system customization. For simply running containers, Photon Full will be overkill. Use Photon Full for developing and packaging the application that will be run as a container, as well as authoring the container, itself. For testing and validation purposes, Photon Full will include all components necessary to run containers.
    Photon OSTree ServerThis installation profile will create the server instance that will host the filesystem tree and managed definitions for rpm-ostree managed hosts created with the "Photon OSTree Host" installation profile. Most environments should need only one Photon OSTree Server instance to manage the state of the Photon OSTree Hosts. Use Photon OSTree Server when you are establishing a new repository and management node for Photon OS hosts.

    Note: The option you choose determines the disk and memory resources required for your installation.

    Select the option you want and press the Enter key.

  10. The Network Configuration screen appears, select one of the four options to configure your network. Network Sonfiguration

    1. Choose Configure network automatically and select Next to configure the network automatically.

    2. To configure network automatically with the DHCP hostname, select Configure network automatically with a DHCP hostname and select Next. Enter the DHCP Hostname and select Next. ../images/DHCP_hostname_for_your_system.png

    3. To configure the network manually, select Configure Network manually. In the window that appears, enter the IP Address, Netmask, Gateway and Nameserver and select OK. ../images/Configure_Network_Manually.png

    4. If your network interface is directly connected to the VLAN trunk port, choose YES on the Configure the network screen. Enter the VLAN ID and select Next. Configure the network.

  11. Select the Linux Kernel

    The installer prompts you to select the Linux kernel to install:

    Linux kernel

    • Hypervisor optimized means that any components that are not needed for running under a VMware hypervisor have been removed for faster boot times.
    • Generic means that all components are included.
  12. Specify the Hostname

    The installer prompts you for a hostname and suggest a randomly generated, unique hostname that you can change if you want.

    Hostname

    Press the Enter key.

  13. Specify the System root Password

    Note: Photon OS will not permit commonly used dictionary words to be set as a root password.

    The installer prompts you to enter the system root password. Type the password, and then press the Enter key.

    Password

    Confirm the root password by typing it a second time.

    Password confirmation

    Press the Enter key. The installer proceeds to install the software. Installation times will vary based on the system hardware and installation options you selected. Most installations complete in less than one minute.

    Once finished, the installer displays a confirmation message (which includes how long it took to install Photon OS) and prompts you to press a key on your keyboard to boot the new VM.

    Confirmation

  14. Reboot the VM and Log In

    Press any key on the keyboard and the virtual machine will reboot into Photon OS.

    Reboot

    As the initial boot process begins, the installer displays the Photon splash screen, and then a login prompt.

    At the login prompt, enter root as the username and provide the password chosen during the installation.

    Password

You can now use your container runtime environment and deploy a containerized application.

4.7 - Running Photon OS on Workstation

You can use Photon OS as a virtual machine within VMware Workstation. You can download Photon OS, as an OVA or ISO file, and install the Photon OS distribution on vSphere. After you install Photon OS, you can deploy a containerized application in Docker with a single command.

Note: If you want to upgrade an existing Photon 1.0 VM, refer to the instructions in the Upgrading to Photon OS 5.0 section.

4.7.1 - Prerequisites for Running Photon OS on Workstation

Before you use Photon OS within Workstation, perform the following prerequisite tasks:

  1. Verify that you have the following resources:

    ResourceDescription
    VMware WorkstationVMware Workstation must be installed (Workstation 10 or higher). The latest version is recommended.

    Memory2GB of free RAM (recommended)
    StorageMinimal Photon install: 512MB of free space (minimum); Full Photon install: 4GB of free space (minimum); 8GB is recommended.
    Distribution FilePhoton OS ISO or OVA file downloaded from VMware (https://packages.vmware.com/photon/5.0/GA/).

    Resource requirements and recommendations vary depending on several factors, including the host environment (for example, VMware Workstation and VMware vSphere), the distribution file used (ISO or OVA), and the selected installation settings (for example, full or basic installation).

    Note: The setup instructions in this guide use VMware Workstation Professional version 12.5.7.

    Workstation version

  2. Decide whether to use the OVA or ISO distribution to set up Photon OS.

  • OVA import : Because of the nature of an OVA, you’re getting a pre-installed version of Photon OS. You can choose the hardware version you want (OVA with hardware version 13 or 11). The OVA benefits from a simple import process and some kernel tuning for VMware environments. However, because it’s a pre-installed version, the set of packages that are installed are predetermined. Any additional packages that you need can be installed using tdnf.

  • ISO install : The ISO, on the other hand, allows for a more complete installation or automated installation via kickstart.

To get Photon OS up and running quickly, use the OVA.

  1. Download Photon OS. Go to the following URL and download the latest release of Photon OS:

    https://packages.vmware.com/photon/5.0/GA/

    For instructions, see Downloading Photon OS.

4.7.2 - Importing the OVA for Photon OS

Using the OVA is the easiest way to create a Photon OS VM on VMware Workstation.

After you have downloaded the the OVA file (OVA with Hardware Version 11), perform the following steps:

  1. Start the Import Process

    • Double-click it to start the import process, or
    • Start VMware Workstation and, from the File menu, choose Open.

    OVA file

  2. Specify the Name and Storage Location

    Change the name and storage location, if you want.

    Name and Storage Location

    Choose Import.

    License

    Review the License Agreement and choose Accept.

  3. Configure VM Settings

    Once the OVA is imported, Workstation displays a summary of the settings for your Photon OS VM.

    Settings

    Choose Edit virtual machine settings. Workstation displays the Virtual Machine settings. You can either accept the defaults or change settings as needed.

    OVA settings

    Select the Options tab.

    Options

    Under Guest operating system, select Linux.

    For Version, click the list and select VMWare Photon 64-bit.

    Version

    Note: If you want to configure a secure boot for the Photon OS VM, select Advanced and select (check) Boot with EFI instead of BIOS. The EFI boot ensures that the ISO content is signed by VMware and that the entire stack is secure.

    EFI boot

    Choose OK.

  4. Power on the VM

    From the tab, choose Power on this virtual machine.

    Login prompt

    After the splash screen, Workstation will prompt you to log in.

  5. Update Login Credentials

    Note : Because of limitations within OVA support on Workstation, it was necessary to specify a default password for the OVA option. However, all Photon OS instances that are created by importing the OVA will require an immediate password change upon login. The default account credentials are:

    • Username: root
    • Password: changeme

    After you provide these credentials, Workstation prompts you to create a new password and type it a second time to verify it. For security, Photon OS forbids common dictionary words for the root password. Once logged in, you will see the shell prompt.

    Once complete, proceed to Deploying a Containerized Application in Photon OS.

4.7.3 - Installing the ISO Image for Photon OS

After you have downloaded the latest Photon OS ISO image into a folder of your choice, open VMware Workstation.

  1. Start the Installation Process

    From the File menu, choose New Virtual Machine to create a new virtual machine.

    New virtual machine

    Select Typical or Custom, and then choose Next. These instructions refer to a Typical installation.

    Typical installation

  2. Select the ISO Image

    Select Installer disc image file (iso), choose Browse and select the Photon OS ISO file.

    Photon ISO file

  3. Select the Operating System

    Choose Next. Select the Guest operating system.

    For the Guest operating system, select Linux.

    Click the Version dropdown and select VMware Photon 64-bit from the list.

    Operating System

  4. Specify the VM Name and Location

    Choose Next. Specify a virtual machine name and location.

    VM Name and Location

  5. Specify Disk Options

    Choose Next. Specify the maximum disk size and whether you want to split the virtual disk into multiple files or store it as a single file.

    Disk options

  6. Configure VM Settings

    Choose Next. Workstation displays a summary of your selections.

    Workstation settings

    Important : Before you finish creating the Photon OS Virtual Machine, we strongly recommend that you customize the virtual machine and remove any unwanted devices that are not needed for a container run-time environment. To remove unnecessary devices, choose Customize hardware.

    Customize hardware

    Consider removing the following components, which are not used by Photon OS:

    • Select Sound Card, un-tick the Connect at power on option. Confirm your action and choose Close to return to the VM Settings by .
    • Select USB Controller and ensure that the Share Bluetooth devices with the virtual machine setting is unchecked (it should be unchecked, by default) and then choose Close.
    • Select Display and ensure that the Accelerate 3D Graphics option is unchecked (it should be unchecked, by default) and then choose Close.
    • At this stage we have now made all the necessary customizations and you are ready to select the Photon OS ISO image to boot and begin the installation process.
    • Choose Finish.

    In Workstation, choose Edit virtual machine settings, select CD/DVD (IDE), and verify that Connect at power on is selected.

    CD/DVD

  7. Configure a Secure Boot (Optional)

    Note: If you want to configure a secure boot for the Photon OS VM, in Workstation, choose Edit virtual machine settings, select Options, choose Advanced, and select Boot with EFI instead of BIOS.

    Boot with EFI

    The EFI boot ensures that the ISO content is signed by VMware and that the entire stack is secure.

    Choose OK.

    ISO settings

  8. Power On the VM

    Choose Power on this virtual machine.

    When you see the Photon Installer boot menu, press Enter on your keyboard to start installing.

    Installer

    Review the license agreement.

    License agreement

    Choose Accept and press Enter.

  9. Configure the Partition

    The installer will detect one disk, which should be the 8GB volume configured as part of the virtual machine creation. Choose Auto to have the installer automatically allocate the partition, or choose Custom if you want to configure individual partitions, and then press the Enter key.

    Partition

    Note: If you choose Custom, the installer displays the following screen.

    Custom Partition

    For each custom partition, choose Create New and specify the following information:

    New Partition

    Size - Preallocated size of this partition, in MB.

    Type - One of the following options:

    • ext3 - ext3 file system
    • ext4 - ext4 file system
    • swap - swap partition

    Mountpoint - Mount point for this partition.

    Choose OK and press the Enter key. When you are done defining custom partitions, choose Next and press the Enter key.

    The installer prompts you to confirm that you want to erase the entire disk. Choose Yes and press the Enter key.

    Erase disk

  10. Select an Installation Option

    After partitioning the disk, the installer will prompt you to select an installation option.

    Installation Option

    Each installation option provides a different run-time environment, depending on your requirements.

    OptionDescription
    Photon MinimalPhoton Minimum is a very lightweight version of the container host runtime that is best suited for container management and hosting. There is sufficient packaging and functionality to allow most common operations around modifying existing containers, as well as being a highly performant and full-featured runtime.

    Photon FullPhoton Full includes several additional packages to enhance the authoring and packaging of containerized applications and/or system customization. For simply running containers, Photon Full will be overkill. Use Photon Full for developing and packaging the application that will be run as a container, as well as authoring the container, itself. For testing and validation purposes, Photon Full will include all components necessary to run containers.
    Photon OSTree ServerThis installation profile will create the server instance that will host the filesystem tree and managed definitions for rpm-ostree managed hosts created with the "Photon OSTree Host" installation profile. Most environments should need only one Photon OSTree Server instance to manage the state of the Photon OSTree Hosts. Use Photon OSTree Server when you are establishing a new repository and management node for Photon OS hosts.

    Note: The option you choose determines the disk and memory resources required for your installation.

    Select the option you want and press the Enter key.

  11. The Network Configuration screen appears, select one of the four options to configure your network. Network Sonfiguration

    1. Choose Configure network automatically and select Next to configure the network automatically.

    2. To configure network automatically with the DHCP hostname, select Configure network automatically with a DHCP hostname and select Next. Enter the DHCP Hostname and select Next. ../images/DHCP_hostname_for_your_system.png

    3. To configure the network manually, select Configure Network manually. In the window that appears, enter the IP Address, Netmask, Gateway and Nameserver and select OK. ../images/Configure_Network_Manually.png

    4. If your network interface is directly connected to the VLAN trunk port, choose YES on the Configure the network screen. Enter the VLAN ID and select Next. Configure the network.

  12. Select the Linux Kernel

    Select a Linux kernel to install.

    Linux Kernel

    • Hypervisor optimized means that any components that are not needed for running under a VMware hypervisor have been removed for faster boot times.
    • Generic means that all components are included.

    Choose Next and press the Enter key.

  13. Specify the Hostname

    The installer prompts you for a hostname and suggest a randomly generated, unique hostname that you can change if you want.

    Hostname

    Press the Enter key.

  14. Specify the System root Password

    Note : Photon OS will not permit commonly used dictionary words to be set as a root password.

    The installer prompts you to enter the system root password. Type the password and press the Enter key.

    Root password

    The installer prompts you to confirm the root password by typing it a second time.

    Password confirmation

    Press the Enter key. The installer proceeds to install the software. Installation times will vary based on the system hardware and installation options you selected. Most installations complete in less than one minute.

  15. Reboot the VM and Log In

    Once finished, the installer displays a confirmation message (which includes how long it took to install Photon OS) and prompts you to press a key on your keyboard to boot the new VM.

    Boot VM

    Press any key on the keyboard and the virtual machine will reboot into Photon OS.

    As the initial boot process begins, the installer displays the Photon splash screen, and then a login prompt.

    Login prompt

    At the login prompt, type root as the username and provide the password chosen during the installation.

    Password

You can now use your container runtime environment and deploy a containerized application.

4.8 - Running Photon OS on Amazon Elastic Cloud Compute

You can set up Photon OS on Amazon Web Services Elastic Cloud Compute (EC2), customize it with cloud-init, connect to it with SSH.

After you set up Photon OS, you can run a containerized application.

4.8.1 - Prerequisites for Running Photon OS on AWS EC2

Before you use Photon OS with Amazon Elastic Cloud Compute(AWS EC2), perform the following prerequisite tasks:

  1. Verify that you have the following resources:

    • AWS account. Working with EC2 requires an Amazon account for AWS with valid payment information. Keep in mind that, if you try the examples in this document, you will be charged by Amazon. See Setting Up with Amazon EC2.
    • Amazon tools. The following examples also assume that you have installed and configured the Amazon AWS CLI and the EC2 CLI and AMI tools, including ec2-ami-tools.

    For more information, see Installing the AWS Command Line Interface, Setting Up the Amazon EC2 Command Line Interface Tools on Linux, and Configuring AWS Command-Line Interface. Also see Setting Up the AMI Tools.

    The procedure in this section uses an Ubuntu 14.04 workstation to generate the keys and certificates that AWS requires.

  2. Download the Photon OS image for Amazon.

    VMware packages Photon OS as a cloud-ready Amazon machine image (AMI) that you can download for free from https://packages.vmware.com/photon/.

    Download the Photon OS AMI and save it on your workstation. For more information, see Downloading Photon OS.

    Note: The AMI version of Photon is a virtual appliance with the information and packages that Amazon needs to launch an instance of Photon in the cloud. To build the AMI version, VMware starts with the minimal version of Photon OS and adds the sudo and tar packages to it.

4.8.2 - Set Up Photon OS on EC2

To run Photon OS on EC2, you must use cloud-init with an EC2 data source. The cloud-init service configures the cloud instance of a Linux image. An instance is a virtual server in the Amazon cloud.

The examples in this section show how to generate SSH and RSA keys for your Photon instance, upload the Photon OS .ami image to the Amazon cloud, and configure it with cloud-init. In the examples, replace information with your own paths, account details, or other information from Amazon.

Perform the following steps to set up Photon OS on EC2

  1. Create a key pair.

    Generate SSH keys on, for instance, an Ubuntu workstation:

    ssh-keygen -f ~/.ssh/mykeypair
    

    The command generates a public key in the file with a .pub extension and a private key in a file with no extension. Keep the private key file and remember the name of your key pair. The name is the file name of the two files without an extension. You will need the name later to connect to the Photon instance.

    Change the mode bits of the public key pair file to protect its security. In the command, include the path to the file if you need to.

    chmod 600 mykeypair.pub
    

    Change the mode bits on your private key pair file so that only you can view it:

    chmod 400 mykeypair
    

    To import your public key pair file, but not your private key pair file, connect to the EC2 console at https://console.aws.amazon.com/ec2/ and select the region for the key pair. A key pair works only in one region, and the instance of Photon OS that will be uploaded later must be in the same region as the key pair. Select key pairs under Network & Security, and then import the public key pair file that you generated earlier.

    For more information, see Importing Your Own Key Pair to Amazon EC2.

  2. Generate a certificate.

    When you bundle up an image for EC2, Amazon requires an RSA user signing certificate. You create the certificate by using openssl to first generate a private RSA key and then to generate the RSA certificate that references the private RSA key. Amazon uses the pairing of the private key and the user signing certificate for handshake verification.

  3. On Ubuntu 14.04 or another workstation that includes openssl, run the following command to generate a private key. If you change the name of the key, keep in mind that you will need to include the name of the key in the next command, which generates the certificate.

     openssl genrsa 2048 > myprivatersakey.pem
    

    Make a note of your private key as you will need it again later.

  4. Run the following command to generate the certificate. The command prompts you to provide more information, but because you are generating a user signing certificate, not a server certificate, you can just type Enter for each prompt to leave all the fields blank.

     openssl req -new -x509 -nodes -sha256 -days 365 -key myprivatersakey.pem -outform PEM -out certificate.pem
    

    For more information, see the Create a Private Key and the Create the User Signing Certificate sections of Setting Up the AMI Tools.

  5. Upload to AWS the certificate value from the certificate.pem file that you created in the previous command. Go to the Identity and Access Management console at https://console.aws.amazon.com/iam/, navigate to the name of your user, open the Security Credentials section, click Manage Signing Certificates, and then click Upload Signing Certificate. Open certificate.pem in a text editor, copy and paste the contents of the file into the Certificate Body field, and then click Upload Signing Certificate.

    For more information, see the Upload the User Signing Certificate section of Setting Up the AMI Tools.

  6. Create a security group.

    Create a security group and set it to allow SSH, HTTP, and HTTPS connections over ports 22, 80, and 443, respectively. Connect to the EC2 command-line interface and run the following commands:

     aws ec2 create-security-group --group-name photon-sg --description "My Photon security group"
     {
         "GroupId": "sg-d027efb4"
     }
     aws ec2 authorize-security-group-ingress --group-name photon-sg --protocol tcp --port 22 --cidr 0.0.0.0/0
    

    Make a note of the GroupId that is returned by EC2 as you will need it again later.

    By using 0.0.0.0/0 for SSH ingress on Port 22, you open the port to all IP addresses–which is not a security best practice but a convenience for the examples in this article. For a production instance or other instances that are anything more than temporary machines, you must authorize only a specific IP address or range of addresses. For more information, see Authorizing Inbound Traffic for Linux Instances.

    Repeat the command to allow incoming traffic on Port 80 and on Port 443:

     aws ec2 authorize-security-group-ingress --group-name photon-sg --protocol tcp --port 80 --cidr 0.0.0.0/0
    
     aws ec2 authorize-security-group-ingress --group-name photon-sg --protocol tcp --port 443 --cidr 0.0.0.0/0
    

    Check your update:

     aws ec2 describe-security-groups --group-names photon-sg
    
  7. Extract the tarball.

    Make a directory to store the image and then extract the Photon OS image from its archive by running the following tar command. If required, change the file name to match the version you have.

     mkdir bundled
     tar -zxvf ./photon-ami.tar.gz
    
  8. Bundle the image.

    Run the ec2-bundle-image command to create an instance store-backed Linux AMI from the Photon OS image that you extracted in the previous step. The result of the ec2-bundle-image command is a manifest that describes the machine in an XML file.

    The command uses the certificate path to your PEM-encoded RSA public key certificate file, the path to your PEM-encoded RSA private key file, your EC2 user account ID; the correct architecture for Photon OS, the path to the Photon OS AMI image extracted from its tar file, and the bundled directory from the previous step.

    Replace the values of the certificate path, the private key, and the user account with your own values.

     $ ec2-bundle-image --cert certificate.pem --privatekey myprivatersakey.pem --user <EC2 account id>  --arch x86_64 --image photon-ami.raw --destination ./bundled/
    
  9. Put the bundle in a bucket.

    Make an S3 bucket, replacing <bucket-name> with the name that you want. The command creates the bucket in the region specified in your Amazon configuration file, which should be the same region in which you are using your key pair file:

     $ aws s3 mb s3://<bucket-name>
    

    Upload the bundle to the Amazon S3 cloud. The following command includes the path to the XML file containing the manifest for the Photon OS machine created during the previous step, though you might have to change the file name to match the version you have. The manifest file is typically located in the same directory as the bundle.

    The command also includes the name of the Amazon S3 bucket in which the bundle is to be stored; your AWS access key ID; and your AWS secret access key.

     $ ec2-upload-bundle --manifest ./bundled/photon-ami.manifest.xml --bucket <bucket-name> --access-key <Account Access Key> --secret-key <Account Secret key>
    
  10. Register the Image

    Run the following command to register the image. The command includes a name for the AMI, its architecture, and its virtualization type. The virtualization type for Photon OS is hvm.

     $ ec2-register <bucket-name>/photon-ami.manifest.xml --name photon-ami --architecture x86_64 --virtualization-type hvm
    

    Once the image is registered, you can launch as many new instances as you require.

  11. Run an instance of the image with Cloud-Init.

    In the below command, the user-data-file option instructs cloud-init to import the cloud-config data in user-data.txt.

    Before you run the command, change directories to the directory containing the mykeypair file and add the path to the user-data.txt.

     $ ec2-run-instances <ami-ID> --instance-type m3.medium -g photon-sg --key mykeypair --user-data-file user-data.txt
    

    The command also includes the ID of the AMI, which you can obtain by running ec2-describe-images. Replace the instance type of m3.medium and the name of key pair with your own values to be able to connect to the instance.

    The following are the contents of the user-data.txt file that cloud-init applies to the machine the first time it boots up in the cloud.

     #cloud-config
     hostname: photon-on-01
     groups:
     - cloud-admins
     - cloud-users
     users:
     - default
     - name: photonadmin
        gecos: photon test admin user
        primary-group: cloud-admins
        groups: cloud-users
        lock-passwd: false
        passwd: vmware
     - name: photonuser
        gecos: photon test user
        primary-group: cloud-users
        groups: users
        passwd: vmware
     packages:
     - vim
    
  12. Get the IP address of your image.

    Run the following command to check on the state of the instance that you launched:

     $ ec2-describe-instances
    

    Obtain the external IP address of the instance by running the following query:

     $ aws ec2 describe-instances --instance-ids <instance-id> --query 'Reservations[*].Instances[*].PublicIpAddress' --output=text
    

    Optionally, check the cloud-init output log file on EC2 at /var/log/cloud-init-output.log to see how EC2 handles the settings in the cloud-init data file.

    For more information on using cloud-init user data on EC2, see Running Commands on Your Linux Instance at Launch.

4.8.3 - Deploy a Containerized Application in Photon OS

Connect to the Photon instance by using SSH and to launch a web server by running it in Docker.

  1. Connect with SSH

    Connect to the instance over SSH by specifying the private key (.pem) file and the user name for the Photon machine, which is root:

     ssh -i ~/.ssh/mykeypair root@<public-ip-address-of-instance>
    

    For complete instructions, see Connecting to Your Linux Instance Using SSH.

  2. Run Docker

    On the minimal version of Photon OS, the docker engine is enabled and running by default, which you can see by running the following command:

     systemctl status docker
    
  3. Start the web server

    Note: Please make sure that the proper security policies have been enabled on the Amazon AWS side to enable traffic to port 80 on the VM.

    Since Docker is running, you can run an application in a container–for example, the Nginx Web Server. This example uses the popular open source web server Nginx. The Nginx application has a customized VMware package that the Docker engine can download directly from the Docker Hub.

    To pull Nginx from its Docker Hub and start it, run the following command:

    docker run -p 80:80 vmwarecna/nginx
    

    The Nginx web server should be bound to the public DNS value for the instance of Photon OS, that is, the same address with which you connected over SSH.

  4. Test the web server

    On your local workstation, open a web browser and go to the the public address of the Photon OS instance running Docker. The following screen should appear, showing that the web server is active:

    Nginx

    Stop the Docker container by typing Ctrl+c in the SSH console through which you are connected to EC2.

You can now run other containerized applications from the Docker Hub or your own containerized application on Photon OS in the Amazon cloud.

4.8.4 - Launch the Web Server with Cloud-Init

To eliminate the manual effort of running Docker, you can add docker run and its arguments to the cloud-init user data file by using runcmd:

#cloud-config
hostname: photon-on-01
groups:
- cloud-admins
- cloud-users
users:
- default
- name: photonadmin
   gecos: photon test admin user
   primary-group: cloud-admins
   groups: cloud-users
   lock-passwd: false
   passwd: vmware
- name: photonuser
   gecos: photon test user
   primary-group: cloud-users
   groups: users
   passwd: vmware
packages:
- vim
runcmd:
- docker run -p 80:80 vmwarecna/nginx

To try this addition, run another instance with the new cloud-init data source and then get the public IP address of the instance to check that the Nginx web server is running.

4.8.5 - Terminate the AMI Instance

Because Amazon charges you while the instance is running, you must shut it down when you have finished using it.

  1. Get the ID of the AMI so you can terminate it:
$ ec2-describe-instances
  1. Terminate the Photon OS instance by running the following command:
$ ec2-terminate-instances <instance-id>

Replace the placeholder with the ID that the ec2-describe-images command returned. If you ran a second instance of Photon OS with the cloud-init file that runs docker, terminate that instance as well.

4.9 - Running Photon OS on Microsoft Azure

You can use Photon OS as a run-time environment for Linux containers on Microsoft Azure. You can set up and run the cloud-ready version of Photon OS as an instance of a virtual machine in the Azure cloud. Once Photon OS is running, you can deploy a containerized application in Docker.

Note: These instructions apply to Photon OS 2.0 and 3.0. There is no Photon OS 1.0 distribution image for Microsoft Azure.

4.9.1 - Prerequisites for Running Photon OS on Azure

Before you use Photon OS with Microsoft Azure, perform the following prerequisite tasks:

  1. Verify that you have a Microsoft Azure account. To create an account, see https://azure.microsoft.com

  2. Install the latest version of Azure CLI. See Install Azure CLI and Get started with Azure CLI .

  3. Verify that that you have a pair of SSH public and private keys.

  4. Download and extract the Photon OS VHD file.

    VMware packages Photon OS as an Azure-ready virtual hard disk (VHD file) that you can download for free from the VMware Photon Packages site. This VHD file is a virtual appliance with the information and packages that Azure needs to launch an instance of Photon in the cloud. After you have downloaded the distribution archive, extract the VHD file from it. You will later need to upload this VHD file to Azure, where it will be stored in an Azure storage account. For more information, see Downloading Photon OS.

4.9.2 - Set Up Azure Storage and Uploading the VHD

You can use either the Azure Portal or the Azure CLI to set up your Azure storage space, upload the Photon OS VHD file, and create the Photon OS VM.

Setting Up Using the Azure Portal

You can use the Azure portal to set up Photon OS in the Azure cloud. The following instructions are brief. Refer to the Azure documentation for details.

  1. Log in to the Azure portal at http://portal.azure.com.
  2. Create a resource group. In the toolbar, choose Resource Groups, click +Add , fill in the resource group fields, and choose Create.
  3. Create a storage account. In the toolbar, choose Storage Accounts, click +Add , fill in the storage account fields (and the resource group you just created), and choose Create.
  4. Select the storage account.
  5. Scroll down the storage account control bar, click Containers (below BLOB SERVICE), click +Container , fill in the container fields, and choose Create.
  6. Select the container you just created.
  7. Click Upload and upload the Photon OS VHD image file to this container.
  8. Once the VHD file is uploaded, refer to the Azure documentation for instructions on how to create and manage your Photon OS VM.

Setting Up Using the Azure CLI

You can use the Azure CLI to set up Photon OS.

Note: Except where overridden with parameter values, these commands create objects with default settings.

  1. Create a resource group.

    From the Azure CLI, create a resource group.

    az group create \
     --name <your_resource_group> \
     --location westus
    
  2. Create a storage account

    Create a storage account associated with this resource group.

    az storage account create \
        --resource-group <your_resource_group> \
        --location westus \
        --name <your_account_name> \
        --kind Storage \
        --sku Standard_LRS
    
  3. List the Keys for the Storage Account

    Retrieve the keys associated with your newly created storage account.

    az storage account keys list \
        --resource-group <your_resource_group> \
        --account-name <your_account_name>
    
  4. Create the Storage Container

    Create a storage container associated with your newly created storage account.

    Note: The sample create.sh script, described below, does this for you programmatically.

    az storage container create \
        --account-name <your_account_name> \
        --name <your_container_name>
    
  5. Verify Your Setup in the Azure Portal

    1. Log into the Azure portal using your account credentials.
    2. From the left toolbar, click Storage Accounts. You should see your storage accounts.
    3. Select the storage account.
    4. Scroll down the storage account control bar and click Containers (below BLOB SERVICE). You should see the container you created.
  6. Upload the Photon OS Distribution to Your Storage Container

    The Photon OS distribution for Azure is 16GB. You can download it locally or to a mounted, shared location.

    az storage blob upload \
        --account-name <your_account_name> \
        --account-key <your_account_key> \
        --container-name <your_container_name> \
        --type page \
        --file <vhd_path> \
        --name <vm_name>.vhd
    

Example Setup Script

You can use the following script (create.sh) to upload your VHD file programmatically and create the VM. Before you run it, specify the following settings:

  • resource_group name
  • account_name
  • account_key (public or private)
  • container_name
  • public_key_file
  • vhd_path and and vm_name of the Photon OS VHD distribution file

The following script returns the complete IP address of the newly created VM.

#!/bin/bash
vhd_path=$1
vm_name=$2
export PATH=$PATH:/root/azure_new/bin/az
echo PATH=$PATH
resource_group=""
account_name=""
account_key=""
container_name="mydisks"
url="https://${account_name}.blob.core.windows.net/${container_name}/${vm_name}.vhd"
public_key_file="/root/azure_new/jenkins.pub"
echo "########################"
echo "#   Create container   #"
echo "########################"
/root/azure_new/bin/az storage container create --account-name ${account_name} --name ${container_name}
echo "##################"
echo "#   Upload vhd   #"
echo "##################"
/root/azure_new/bin/az storage blob upload --account-name ${account_name} \
    --account-key ${account_key} \
    --container-name ${container_name} \
    --type page \
    --file ${vhd_path} \
    --name ${vm_name}.vhd
echo "##################"
echo "#   Create vm    #"
echo "##################"
echo "az vm create --resource-group ${resource_group} --location westus --name ${vm_name} --storage-account ${account_name} --os-type linux --admin-username michellew --ssh-key-value ${public_key_file} --image ${url} --use-unmanaged-disk ... ..."
/root/azure_new/bin/az vm create --resource-group ${resource_group} --location westus --name ${vm_name} --storage-account ${account_name} --os-type linux --admin-username michellew --ssh-key-value ${public_key_file} --image ${url} --use-unmanaged-disk

4.9.3 - Remove Photon OS From Azure

You can use the following delete.sh script to programmatically and silently remove the VM instance, VHD file, and container.

Consider deleting idle VMs so that you are not charged when not in use.

Before you run it, specify the following settings:

  • resource_group name (from step 1, above)
  • account_name (from step 2, above)
  • account_key (public or private) (from step 3, above)
  • container_name (from step 4, above)
  • public_key_file
  • vm_name of the Photon OS VHD distribution file

delete.sh

#!/bin/bash
vm_name=$1
resource_group=""
account_name=""
account_key=""
container_name="mydisks"
url="https://${account_name}.blob.core.windows.net/${container_name}/${vm_name}.vhd"
public_key_file="/root/azure_new/jenkins.pub"
exit_code=0
echo "##################"
echo "#   Delete vm    #"
echo "##################"
echo "az vm list  --resource-group ${resource_group} ... ..."
/root/azure_new/bin/az vm list  --resource-group ${resource_group}
echo "az vm delete --resource-group ${resource_group} --name ${vm_name} --yes ... ..."
/root/azure_new/bin/az vm delete --resource-group ${resource_group} --name ${vm_name} --yes
if [$? -ne 0];then
   exit_code=1
fi
echo "az vm list  --resource-group ${resource_group} ... ..."
/root/azure_new/bin/az vm list  --resource-group ${resource_group}
echo "##############$####"
echo "#   Delete vhd    #"
echo "###############$###"
echo "az storage blob list --account-name ${account_name} --container-name ${container_name} ... ..."
/root/azure_new/bin/az storage blob list --account-name ${account_name} --container-name ${container_name}
echo "az storage blob delete --account-name ${account_name} --container-name ${container_name} --name ${vm_name}.vhd ... ..."
/root/azure_new/bin/az storage blob delete --account-name ${account_name} --container-name ${container_name} --name ${vm_name}.vhd
if [$? -ne 0];then
   exit_code=1
fi
echo "az storage blob list --account-name ${account_name} --container-name ${container_name} ... ..."
/root/azure_new/bin/az storage blob list --account-name ${account_name} --container-name ${container_name}
echo "########################"
echo "#   Delete container   #"
echo "########################"
/root/azure_new/bin/az storage container delete --account-name ${account_name} --name ${container_name}
/root/azure_new/bin/az storage container delete --account-name ${account_name} --name vhds
exit ${exit_code}

You can now proceed to Deploying a Containerized Application in Photon OS.

4.10 - Running Photon OS on Google Compute Engine

You can use Photon OS as a virtual machine on Google Compute Engine (GCE). You can download Photon OS, as an OVA or ISO file, and install the Photon OS distribution on vSphere. After you install Photon OS, you can deploy a containerized application in Docker with a single command.

4.10.1 - Prerequisites for Running Photon OS on GCE

Before you use Photon OS within GCE, verify that you have the following resources:

  1. Google Compute Engine account
  2. GCE tools
  3. Photon OS Image

Google Compute Engine Account

Working with GCE requires a Google Compute Engine account with valid payment information. Keep in mind that, if you try the examples in this document, you will be charged by Google. The GCE-ready version of Photon OS is free to use.

GCE Tools

GCE is a service that lets you run virtual machines on Google’s infrastructure. You can customize the virtual machine as much as you want, and you can even install your own custom operating system image. Or, you can adopt one of the public images provided by Google. For any operating system to work with GCE, it must match Google’s infrastructure needs. Google provides tools that VM instances require to work correctly on GCE:

  • Google startup scripts: You can provide some startup script to configure your instances at startup.
  • Google Daemon: Google Daemon creates new accounts and configures ssh to accept public keys using the metadata server.
  • Google Cloud SDK: Command line tools to manage your images, instances and other objects on GCE.

Perform the following tasks to make Photon OS work on GCE:

  1. Install Google Compute Engine Image packages
  2. Install Google Cloud SDK
  3. Change GPT partition table to MBR
  4. Update the Grub config for new MBR and serial console output
  5. Update ssh configuration
  6. Delete ssh host keys
  7. Set the time zone to UTC
  8. Use the Google NTP server
  9. Delete the hostname file.
  10. Add Google hosts /etc/hosts
  11. Set MTU to 1460. SSH will not work without it.
  12. Create /etc/ssh/sshd_not_to_be_run with just the contents “GOOGLE\n”.

For more information see Importing Boot Disk Images to Compute Engine.

For information about upgrading the Photon OS Linux kernel see Upgrading the Kernel Version Requires Grub Changes for AWS and GCE Images

Photon OS Image

VMware recommends that administrators use the Photon OS image for Google Compute Engine (GCE) to create Photon OS instances on GCE. Photon OS bundles the Google startup scripts, daemon, and cloud SDK into a GCE-ready image that has been modified to meet the configuration requirements of GCE. You can download the Photon OS image for GCE from the following URL: https://packages.vmware.com/photon/5.0/GA/gce/

For instructions, see Downloading Photon OS.

Optionally you can customize Photon OS to work with GCE.

Creating Photon image for GCE

Perform the following tasks:

  1. Prepare Photon Disk

    1. Install Photon Minimal on Fusion/Workstation and install some required packages.
    mount /dev/cdrom /media/cdrom
    tdnf install python2-libs ntp sudo wget tar which gptfdisk sed findutils grep gzip -y
    
  2. Convert GPT to MBR and update Grub

    Photon installer installs GPT partition table by default but GCE only accepts an MBR (msdos) type partition table. So, you must convert GPT to MBR and update grub. Use the following commands to update the grub:

    # Change partition table to MBR from GPT
    sgdisk -m 1:2 /dev/sda
    grub2-install /dev/sda
    
    # Enable serial console on grub for GCE.
    cat << EOF >> /etc/default/grub
    GRUB_CMDLINE_LINUX="console=ttyS0,38400n8"
    GRUB_TERMINAL=serial
    GRUB_SERIAL_COMMAND="serial --speed=38400 --unit=0 --word=8 --parity=no --stop=1"
    EOF
    
    # Create new grub.cfg based on the settings in /etc/default/grub
    grub2-mkconfig -o /boot/grub2/grub.cfg
    
  3. Install Google Cloud SDK and GCE Packages

    tdnf install -y google-compute-engine google-compute-engine-services
    cp /usr/lib/systemd/system/google* /lib/systemd/system/
    cd /lib/systemd/system/multi-user.target.wants/
    
    # Create links in multi-user.target to auto-start these scripts and services.
    for i in ../google*; do  ln -s $i `basename $i`; done
    
    cd /tmp/; wget https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz
    tar -xf google-cloud-sdk.tar.gz
    cd google-cloud-sdk
    ./install.sh
    
  4. Update /etc/hosts file with GCE values as follows:

    echo "169.254.169.254 metadata.google.internal metadata" >> /etc/hosts
    
  5. Remove all servers from ntp.conf and add Google’s ntp server.

    sed -i -e "/server/d" /etc/ntp.conf
    cat /etc/ntp.conf
    echo "server 169.254.169.254" >> /etc/ntp.conf
    # Create ntpd.service to auto starting ntp server.
    cat << EOF >> /lib/systemd/system/ntpd.service
    [Unit]
    Description=Network Time Service
    After=network.target nss-lookup.target
    
    [Service]
    Type=forking
    PrivateTmp=true
    ExecStart=/usr/sbin/ntpd -g -u ntp:ntp
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    # Add link in multi-user.target.wants to auto start this service.
    cd /lib/systemd/system/multi-user.target.wants/
    ln -s ../ntpd.service ntpd.service
    
  6. Set UTC timezone

    ln -sf /usr/share/zoneinfo/UTC /etc/localtime
    
  7. Update /etc/resolv.conf

    echo "nameserver 8.8.8.8" >> /etc/resolv.conf
    
  8. Remove ssh host keys and add script to regenerate them at boot time.

    rm /etc/ssh/ssh_host_*
    # Depending on the installation, you may need to purge the following keys
    rm /etc/ssh/ssh_host_rsa_key*
    rm /etc/ssh/ssh_host_dsa_key*
    rm /etc/ssh/ssh_host_ecdsa_key*
    
    sed -i -e "/exit 0/d" /etc/rc.local
    echo "[ -f /etc/ssh/ssh_host_key ] && echo 'Keys found.' || ssh-keygen -A" >> /etc/rc.local
    echo "exit 0" >> /etc/rc.local
    printf "GOOGLE\n" > /etc/ssh/sshd_not_to_be_run
    
    # Edit sshd_config and ssh_config as per instructions on [this link](https://cloud.google.com/compute./tutorials/building-images).
    
  9. Change MTU to 1460 for network interface.

     # Create a startup service in systemd that will change MTU and then exit
    
    cat << EOF >> /lib/systemd/system/eth0.service
    [Unit]
    Description=Network interface initialization
    After=local-fs.target network-online.target network.target
    Wants=local-fs.target network-online.target network.target
    
    [Service]
    ExecStart=/bin/ifconfig eth0 mtu 1460 up
    Type=oneshot
    
    [Install]
    WantedBy=multi-user.target
    EOF
    # Make this service auto-start at boot.
    cd /lib/systemd/system/multi-user.target.wants/
    ln -s ../eth0.service eth0.service
    
  10. Pack and upload to GCE.

    Shut down the Photon VM and copy its disk to THE tmp folder.

    # You will need to install Google Cloud SDK on host machine to upload the image and play with GCE.
    
    cp Virtual\ Machines.localized/photon.vmwarevm/Virtual\ Disk.vmdk /tmp/disk.vmdk
    cd /tmp
    # GCE needs disk to be named as disk.raw with raw format.
    qemu-img convert -f vmdk -O raw disk.vmdk disk.raw
    
    # ONLY GNU tar will work to create acceptable tar.gz file for GCE. MAC's default tar is BSDTar which will not work. 
    # On Mac OS X ensure that you have gtar "GNU Tar" installed. exmaple: gtar -Szcf photon.tar.gz disk.raw 
    
    gtar -Szcf photon.tar.gz disk.raw 
    
    # Upload
    gsutil cp photon.tar.gz gs://photon-bucket
    
    # Create image
    gcloud compute --project "<project name>" images create "photon-beta-vYYYYMMDD" --description "Photon Beta" --source-uri https://storage.googleapis.com/photon-bucket/photon032315.tar.gz
    
    # Create instance on GCE of photon image
    gcloud compute --project "photon" instances create "photon" --zone "us-central1-f" --machine-type "n1-standard-1" --network "default" --maintenance-policy "MIGRATE" --scopes "https://www.googleapis.com/auth/devstorage.read_only" "https://www.googleapis.com/auth/logging.write" --image "https://www.googleapis.com/compute/v1/projects/photon/global/images/photon" --boot-disk-type "pd-standard" --boot-disk-device-name "photon"
    

4.10.2 - Installing Photon OS on Google Compute Engine

You can use either the Google Cloud Platform or the gcloud CLI to upload the Photon OS GCE tar file to the bucket, and create the Image & Photon OS VM instance.

Setting Up Using the Google Cloud Platform

After you download the Photon OS image for GCE, log into GCE and install Photon OS.

Perform the following steps:

  1. Create a New Bucket

    Create a new bucket to store your Photon OS image for GCE.

    gce1

  2. Upload the Photon OS Image

    While viewing the bucket that created, click the Upload files button, navigate to your Photon OS image and click the Choose button.

    When the upload finishes, you can see the Photon OS compressed image in the file list for the bucket that you created.

    gce2

  3. Create a New Image

    To create a new image, click on Images in the Compute category in the left panel and then click on the New Image button.

    Enter a name for the image in the Name field and change the Source to Cloud Storage file using the pull-down menu. Then, in the Cloud Storage file field, enter the bucket name and filename as the path to the Photon OS image for GCE. In this example, where the bucket was named photon_storage, the path is as follows:

     `photon_storage/photon-gce-2.0-tar.gz`
    

    The new image form autopopulates the gs:// file path prefix.*

    Click the Create button to create your image. You must be able to see the Images catalog and your Photon OS image at the top of the list.

  4. Create a New Instance

    To create an instance, check the box next to the Photon OS image and click the Create Instance button.

    On the Create a new instance form, provide a name for this instance, confirm the zone into which this instance is to be deployed and, before clicking Create, check the Allow HTTP traffic and Allow HTTPS traffic options.

    Note: The firewall rules in this example are optional. You can configure the ports according to your requirements.

    gce4

    When the instance is created you will be returned to your list of VM instances. If you click on the instance, the status page for the instance will allow you to SSH into your Photon OS environment using the SSH button at the top of the panel.

    At this point, your instance is running and you are ready to start the Docker engine and run a container workload. For more information, see Deploying a Containerized Application in Photon OS.

Setting Up Using the gcloud CLI

Example Setup Script:
​ You can use the following script (create.sh) to upload your tar file programmatically to the bucket and create the VM. ​

#!/bin/bash
timestamp=$(date +%s)
export PATH=$PATH:/root/gce/google-cloud-sdk/bin
​
# get branch name in order to determine the machine type.
GCE_VM_NAME=$2
branch=`echo ${GCE_VM_NAME} | cut -d '-' -f 1`
​
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
GCE_USERNAME=<gce_username>
GCE_BUCKET=<gs://bucket-name>
​
if [ $# -lt 2 ]
then
  echo "Usage is: create.sh <path_to_gce_image.tar.gz> <vm_name> [(optional) <user-data-file-path>]";
  exit;
fi
​
echo "Uploading gce tar.gz to gce bucket...."
/root/gce/google-cloud-sdk/bin/gsutil cp ${1} $GCE_BUCKET/photon-gce-${timestamp}.tar.gz
if [ ! "$?" -eq 0 ]; then
    echo "Failed: couldn't upload to gce bucket"
    exit 1
fi
​
echo "GCE tar.gz uploaded successfully, proceeding with image creation"
gcloud compute images create ${2}-image --source-uri $GCE_BUCKET/photon-gce-${timestamp}.tar.gz
if [ ! "$?" -eq 0 ]; then
    echo "Failed: couldn't create image successfully"
    exit 1
fi
​
echo "GCE image created successfully. Proceeding with instance creation"
if [[ ( "${branch}" != "one" ) && ( "${branch}" != "two" ) ]];then
    machine_type="n1-standard-1"
else
    machine_type="n1-standard-2"
fi
echo branch=$branch
echo machine_type=$machine_type
​
if [ $# -gt 2 ]
then
    gcloud compute instances create ${2} --machine-type ${machine_type} --image ${2}-image --metadata-from-file=user-data=${3}
else
    gcloud compute instances create ${2} --machine-type ${machine_type} --image ${2}-image
fi
if [ ! "$?" -eq 0 ]; then
    echo "Failed: couldn't create instance successfully"
    exit 1
fi
echo "Photon Instance created successfully on GCE"
​
externalip="$(gcloud compute instances list ${2} --format='value(networkInterfaces[].accessConfigs[].natIP)')"
echo $externalip
GCE_VM_IP=$externalip
echo GCE_VM_IP=$GCE_VM_IP

4.11 - Running Photon OS on Raspberry Pi

You can use Photon OS as a virtual machine on Raspberry Pi (RPi). You can download Photon OS and install the Photon OS distribution on vSphere.

4.11.1 - Prerequisites for Running Photon OS on Raspberry Pi

Before you use Photon OS within RPi, perform the following prerequisite tasks:

  1. Verify that you have the following resources:

    ResourceDescription
    Raspberry Pi 3Raspberry Pi 3 Model B or Model B+ board. This will serve as the target of the installation.
    Raspberry Pi 4Raspberry Pi 4 Model B or Model B+ board. This will serve as the target of the installation.
    Host computer

    A computer equipped with the following:

    1. An SD card reader.

    2. Software utilities to flash an image onto an SD-card (details and instructions provided below).

    Distribution FilePhoton OS RPi image downloaded from URL

    Note: Photon OS RPi image is available only from Photon 3.0 onwards.

    1. Download Photon OS.

      To install Photon OS on a Raspberry Pi, you must download the Photon OS RPi image, which is distributed as a compressed raw disk image with the file extension .raw.xz.

      Note: You cannot use the Photon ISO to install on RPi.

      Go to the following URL and download the latest release of Photon OS image for RPi: https://packages.vmware.com/photon/5.0/GA/rpi/rpi.tar.xz.

      For instructions, see Downloading Photon OS.

4.11.2 - Installing Photon OS on Raspberry Pi

You can get Photon OS up and running on an RPi board, by flashing the Photon RPi image onto the board’s SD card.

Flash Photon OS on Raspberry Pi

After you have downloaded the Photon RPi image with the file extension *.raw.xz, decompress the file to *.raw and then you can choose one of the methods below to flash it onto the RPi SD card.

  1. Flash Photon to RPi using Etcher
  2. Flash Photon to RPi using Linux CLI

Flash Photon to RPi using Etcher

  1. Install Etcher https://etcher.io/, which is a utility to flash SD cards attached to your host computer.
  2. Plug the RPi SD card into your host computer’s SD card reader.
  3. Perform the following steps on the Etcher GUI: Select image -> Select drive -> Flash, by selecting the Photon OS RPi as image and the RPi SD card as drive.

Flash Photon to RPi using Linux CLI

  1. If you have Linux running on your host computer, install the xz package, which provides the xz compression utility and related tools, from your distribution package manager.

  2. Plug the RPi’s SD card into your host computer’s SD card reader.

  3. Identify the device file under /dev that refers to the RPi SD card. For example, /dev/sdc. This file path is used to flash the Photon image onto the RPi in the next step.

    Note: Make sure that you are flashing to the device file that refers to your RPi3 SD card. Running the below command with an incorrect device file will overwrite that device without warning and might result in a corrupted disk. The device file ‘/dev/sdc` is an example and might not be the device file in your case.

  4. Run the following command to flash Photon onto the RPi SD card:

    xzcat <photon-rpi4-image.raw.xz> | sudo dd of=/dev/sdc bs=4M conv=fsync

Boot Photon OS on Raspberry Pi

After you flash Photon OS successfully onto the RPi SD card, eject the card from your host computer and plug it back into the RPi board.

When you power on Raspberry Pi , it boots with Photon OS.

After the splash screen, Photon OS prompts you to log in.

Update login credentials

The Photon OS RPi image is configured with a default password. However, all Photon OS instances that are created using this image will require an immediate password change upon login. The default account credentials are:

  • Username: root
  • Password: changeme

After you provide these credentials, Photon OS prompts you to create a new password and type it a second time to verify it. Photon OS does not allow common dictionary words for the root password. When you are logged in, you will see the shell prompt.

You can now run tdnf list to view all the ARM packages that you can install on Photon OS.

4.11.3 - Enabling Raspberry Pi Interfaces using Device Tree

Photon OS RPI images from Photon OS has Device Tree Overlay support. And these images have compiled Overlays to enable/disable Rpi Interface. Perform the following:

SPI Interface: Execute following commands to enable SPI Interface:

mkdir /sys/kernel/config/device-tree/overlays/

cat /boot/efi/overlays/rpi-enable-spi0.dtbo > /sys/kernel/config/device-tree/overlays/spi/dtbo

Audio Interface: Execute following commands to enable Audio Interface:

mkdir  /sys/kernel/config/device-tree/overlays/audio

cat /boot/efi/overlays/rpi-enable-audio.dtbo >  /sys/kernel/config/device-tree/overlays/audio/dtbo

Note: Ensure that the linux-drivers-sound rpm is installed.

I2C Interface: Execute following command to enable I2C Interface:

modprobe i2c-dev

#Customizing Device Tree Overlay

Photon OS also provides Device Tree Compilers (i.e. dtc), to compile Customised Device Tree Overlays. Execute following command to install dtc on Photon OS:

tdnf install dtc

Execute following command to compile the overlay:

dtc -@ -O dtb -o my_overlay_dt.dtbo my_overlay_dt.dts

For more information about format of Device Tree Overlay, see https://www.kernel.org/doc/Documentation/devicetree/overlay-notes.txt

4.12 - Deploying a Containerized Application in Photon OS

Now that you have your container runtime environment up and running, you can easily deploy a containerized application. For this example, you will deploy the popular open source Web Server Nginx. The Nginx application has a customized VMware package that is published as a dockerfile and can be downloaded, directly, through the Docker module from the Docker Hub.

  1. Run Docker

    To run Docker from the command prompt, enter the following command, which initializes the docker engine:

     systemctl start docker
    

    To ensure Docker daemon service runs on every subsequent VM reboot, enter the following command:

     systemctl enable docker
    
  2. Run the Nginx Web Server

    Now the Docker daemon service is running, it is a simple task to “pull” and start the Nginx Web Server container from Docker Hub. To do this, type the following command:

     docker run -d -p 80:80 vmwarecna/nginx
    

    This pulls the Nginx Web Server files and appropriate dependent container filesystem layers required for this containerized application to run.

    Docker run

    After the docker run process completes, you return to the command prompt. You now have a fully active website up and running in a container!

  3. Test the Web Server

    To test that your Web Server is active, run the ifconfig command to get the IP address of the Photon OS Virtual Machine.

    IP address

    The output displays a list of adapters that are connected to the virtual machine. Typically, the web server daemon will be bound on eth0.

    Start a browser on your host machine and enter the IP address of your Photon OS Virtual Machine. You should see a screen similar to the following example as confirmation that your web server is active.

    Docker confirmation

    You can now run any other containerized application from Docker Hub or your own containerized application within Photon OS.

4.13 - Compatible Cloud Images

The Vmware Photon Packages website contains the following cloud-ready images of Photon OS:

  1. GCE - Google Compute Engine

  2. AMI - Amazon Machine Image

  3. OVA

Because the cloud-ready images of Photon OS are built to be compatible with their corresponding cloud platform or format, you typically do not need to build a cloud image, you can just go to the VMware Packages repo and download the image for the platform that you are working on.

If, however, you want to build your own cloud image, perhaps because you seek to customize the code, see the next section on how to build cloud images.

How to build cloud images

sudo make cloud-image IMG_NAME=image-name

image-name: gce/ami/azure/ova

The output of the build process produces the following file formats:

GCE - A tar file consisting of disk.raw as the raw disk file

AMI - A raw disk file

OVA - An ova file (vmdk + ovf)

If you want, you can build all the cloud images by running the following command:

sudo make cloud-image-all 

How to create running instances in the cloud

The following sections contain some high-level instructions on how to create instances of Photon OS in the Google Compute Engine (GCE) and Amazon Elastic Cloud Compute (EC2). For more information, see the Amazon or Google cloud documentation.

GCE

The tar file can be uploaded to Google’s cloud storage and an instance can be created after creating an image from the tar file. You will need the Google Cloud SDK on your host machine to upload the image and create instances.

####Install Google cloud SDK on host machine

curl https://sdk.cloud.google.com | bash

####Upload the tar file

gsutil cp photon-gce.tar.gz gs://bucket-name

####Create image

gcloud compute --project project-id images create image-name --description description --source-uri https://storage.googleapis.com/bucket-name/photon-gce.tar.gz

####Create instance of GCE

gcloud compute --project project-id instances create instance-name --zone "us-central1-f" --machine-type "n1-standard-1" other-options

(You can also create instances from the Google developer console.)

For more information, see Running a Photon OS Machine on GCE.

AWS EC2

Install the AWS CLI and EC2 CLI tools.

####Bundle the image

ec2-bundle-image -c cert.pem -k private-key.pem -u $AWS_USER_ID --arch x86_64 --image photon-ami.raw --destination directory-name

####Upload the bundle

ec2-upload-bundle --manifest directory-name/photon-ami.raw.manifest.xml --bucket bucket-name --access-key $AWS_ACCESS_KEY --secret-key $AWS_SECRET_KEY

####Register the AMI

ec2-register bucket-name/photon-ami.raw.manifest.xml --name name --architecture x86_64 --virtualization-type hvm

You can now launch instances using the AWS console.

For more information, see Customizing a Photon OS Machine on EC2.

###OVA

The OVA image uses an optimized version of the 4.4.8 Linux kernel. Two ova files are generated from the build: photon-ova.ova, which is the full version of Photon OS, and photon-custom.ova, which is the minimal version of Photon OS. The password for photon-ova.ova should be changed using guest customization options when you upload it to VMware vCenter. Photon-custom.ova comes with the default password set to changeme; you must change it the first time you log in.

OVA Prerequisites

VDDK 6.0

To utilize the VDDK libraries the following procedure may be used, this extracts the libraries and temporarily exports them to the LD_LIBRARY_PATH for the current session. (tested on Ubuntu 1404 & 1604) If you wish to make this permanent and system-wide then you may want to create a config file in /etc/ld.so.conf.d/.

tar -zxf VMware-vix-disklib-6.0.2-3566099.x86_64.tar.gz
cp -r vmware-vix-disklib-distrib/include/* /usr/include/
mkdir /usr/lib/vmware
cp -a ~/vmware-vix-disklib-distrib/lib64/* /usr/lib/vmware/
rm /usr/lib/vmware/libstdc++.so.6
export LD_LIBRARY_PATH=/usr/lib/vmware

OVFTOOL

OVF Tool should be downloaded and installed on the host.

sh VMware-ovftool-4.1.0-2459827-lin.x86_64.bundle --eulas-agreed --required

5 - Administration Guide

The Photon OS Administration Guide describes the fundamentals of administering Photon OS.

The Administration Guide covers the basics of managing packages, controlling services with systemd, setting up networking, initializing Photon OS with cloud-init, running Docker containers, and working with other technologies, such as Kubernetes.

Product version: 5.0

This documentation applies to all 5.0.x releases.

Intended Audiences

This information is intended for Photon OS administrators who install and set up Photon OS.

5.1 - Photon OS Packages

The design of Photon OS simplifies life-cycle management and improves the security of packages. Photon reduces the burden and complexity of managing clusters of Linux machines by providing curated package repositories and by securing packages with GPG signatures.

Photon OS is available in a variety of pre-built packages in binary formats.

5.1.1 - Examining the Packages in the SPECS Directory on Github

The SPECS directory of the GitHub website for Photon OS contains all the packages that can appear in Photon OS repositories. The following is the path to the SPECS directory:

https://github.com/vmware/photon/tree/master/SPECS

To see the version of a package, in the SPECS directory, click the name of the subdirectory of the package that you want to examine, and then click the .spec filename in the subdirectory.

For example, python3.spec appears as follows::

%global VER 3.11
%global with_gdb_hooks 1

Summary:        A high-level scripting language
Name:           python3
Version:        3.11.0
Release:        6%{?dist}
License:        PSF
URL:            http://www.python.org
Group:          System Environment/Programming
Vendor:         VMware, Inc.
Distribution:   Photon

5.1.2 - Looking at the Differences Between the Minimal and the Full Version

The minimal version of Photon OS contains around 50 packages. As it is installed, the number of packages increases to nearly 100 to fulfill dependencies. The full version of Photon OS adds several hundred packages to those in the minimal version to deliver a more fully featured operating system.

You can view a list of the packages that appear in the minimal version by examining the following file:

https://github.com/vmware/photon/blob/master/common/data/packages_minimal.json

You can view a list of the packages that appear in the full (aka “developer”) version by examining the following file:

https://github.com/vmware/photon/blob/master/common/data/packages_full.json

If the minimal or the developer version of Photon OS does not contain a package that you want, you can install it with tdnf, which appears in both the minimal and full versions of Photon OS by default. In the full version of Photon OS, you can also install packages by using yum.

One notable difference between the two versions of Photon OS pertains to OpenJDK, the package that contains not only the Java runtime environment (openjre) but also the Java compiler (javac). The OpenJDK package appears in the full but not the minimal version of Photon OS.

To add support for Java programs to the minimal version of Photon OS, install the Java packages and their dependencies by using the following command:

```console
tdnf install openjdk
Installing:
openjre 	x86_64    1.8.0.92-1.ph1    95.09 M
openjdk 	x86_64    1.8.0.92-1.ph1    37.63 M
```

NOTE: openjdk and openjre are available as openjdk8 and openjre8 in Photon OS 3.0 and later.

For more information about tdnf, see Tiny DNF for Package Management

5.1.3 - The Root Account and the 'sudo' and 'su' Commands

The Photon OS Administration Guide assumes that you are logged in to Photon OS with the root account and running commands as root.

On the minimal version, you must install sudo with tdnf if you want to use it. As an alternative to installing sudo, to run commands that require root privileges you can switch users as needed with the su command.

5.1.4 - Examining Signed Packages

Photon OS signs its packages and repositories with GPG signatures to enhance security. The GPG signature uses keyed-hash authentication method codes, typically the SHA1 algorithm and an RSA Data Security, Inc. MD5 Message Digest Algorithm, to simultaneously verify the integrity of a package. A keyed-hash message authentication code combines a cryptographic hash function with a secret cryptographic key.

In Photon OS, GPG signature verification automatically takes place when you install or update a package with the default package manager, tdnf. The default setting in the tdnf configuration file for checking the GPG is set to 1 for true:

cat /etc/tdnf/tdnf.conf
[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=true
repodir=/etc/yum.repos.d
cachedir=/var/cache/tdnf

On Photon OS, you can view the key with which VMware signs packages by running the following command:

rpm -qa gpg-pubkey*

The command returns the GPG public key:

gpg-pubkey-66fd4949-4803fe57
gpg-pubkey-8a6a826d-596882ca

Once you have the name of the key, you can view information about the key with the rpm -qi command, as the following abridged output demonstrates:

rpm -qi gpg-pubkey-66fd4949-4803fe57
Name        : gpg-pubkey
    Version     : 66fd4949
    Release     : 4803fe57
    Architecture: (none)
    Install Date: Thu Jun 16 11:51:39 2016
    Group       : Public Keys
    Size        : 0
    License     : pubkey
    Signature   : (none)
    Source RPM  : (none)
    Build Date  : Tue Apr 15 01:01:11 2008
    Build Host  : localhost
    Relocations : (not relocatable)
    Packager    : VMware, Inc. -- Linux Packaging Key -- <linux-packages@vmware.com>
    Summary     : gpg(VMware, Inc. -- Linux Packaging Key -- <linux-packages@vmware.                        com>)
    Description :
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: rpm-4.11.2 (NSS-3)
    mI0ESAP+VwEEAMZylR8dOijUPNn3He3GdgM/kOXEhn3uQl+sRMNJUDm1qebi2D5b ...
rpm -qi gpg-pubkey-8a6a826d-596882ca
Name        : gpg-pubkey
Version     : 8a6a826d
Release     : 596882ca
Architecture: (none)
Install Date: Tue 18 Apr 2023 10:17:59 AM UTC
Group       : Public Keys
Size        : 0
License     : pubkey
Signature   : (none)
Source RPM  : (none)
Build Date  : Fri 14 Jul 2017 08:37:30 AM UTC
Build Host  : localhost
Packager    : VMware, Inc. (Linux Packaging Key) <linux-packages@vmware.com>
Summary     : VMware, Inc. (Linux Packaging Key) <linux-packages@vmware.com> public key
Description :
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: rpm-4.18.0

mQINBFlogsoBEACylcZdKvVdq+XZZ5oXyV7+Wk4wYo9ALIy5Y/TlQ7YoJndF3A6d
j3KXLFZ3xLMYuktUwqEiVN24s2loAG3kcS5c8bb7LxiZMFoEfo8bUm8mcfcPKCdy
ZgE0TNwYejn6w9tuEOLtewVtFaP3FrCjzZz2VMXi5c9sNxmIxfrBuuDZP8MLoDKr
fv4Zzif2K6J4nRMBY2t8SSj8Z4zDUCLQ36wYlD2slONdmX8Ufd86rt/ZJ156xsCX
2UgTb62uUVESlWfsuMhv5CBO2JEbbnMBjfZdI5qplwEt54kq34PzP6fRCa8yrLR8
FlZsAQO32A0SDNUWHphDP3d2W64XtttjRJPsWv16IXss1YwyjUd1CBYDpefXvzW2
h8Ca6HDgLRG0eoVZdY8gx1geF64wuGjSA+4gnjTaMeLQSBfeAzm6Pe4eB6bEc/iX
NiZY9KlA1orRcuHxXIzjsHR5f1JCK0Fgl76aNzxnztuU0uRSLZRxUMUpszCOyqy9
ufsbMeklbKtobfVqRulQEJwCXHL99t+Ln14L3PgXKeLqaj/LReIqWlWiFtm6Zgyf
a45z8lf8Z3lRK+orrNJ8fVJr/8T9O/vgpbwwqEZ2bflzqXcUPyWnMl6Cu8SNbtwK
orvZ1bwNkz5T9myW+6pXcr9sB/IiNmyfTS1rXqwUlRN60vwD+a52MpnCGwARAQAB
tD5WTXdhcmUsIEluYy4gKExpbnV4IFBhY2thZ2luZyBLZXkpIDxsaW51eC1wYWNr
YWdlc0B2bXdhcmUuY29tPokCNgQTAQIAIAUCWWiCygIbAwYLCQgHAwIEFQIIAwQW
AgMBAh4BAheAAAoJEHXACeqKaoJtIYIP/3y2+xIZ3ZArdhH6NR3ilMPGSVoe1M2+
10XlL9wydgXPdKrq8IZUNg5/VBEjpOZML82aD9VRkMXI6XdbrdRw+5G2D5ZOtWRp
ha8KPuFxax2YuB8ifRgcrgR0kq4v+p3XHaT88UQxk/gDpJVOMJaLhyn8KNBPVkPq
zJ3IXC/A/rWv6rbDAnyyt20GpCqWuoCJCQDMCbBItyaL42OWY3yk3WlfFOjQU1Sq
zIYCCJGM87rNHpwErHDIanFu0gXCarFB6uRT9ixgyJqg7dtPAyBdydxo0JesH0Fc
t30NYkRiqqeSz6ImWlcvDHZkiDXNvP0D9utyOPQDoIaX+G0gCnf+UpHTgc0eGc6U
+aHIyHMK7Du+cfTXL8W5LAbSw7pTPSPc/sZal1ijDvk1lyMhT6kZ22v2IXYadosp
eA7+9ykSk3Iy9qhjUTQ+qG/KMgUTMVqWUp6IEze80892w3yNFi8tEvdRzORbOHuP
IhyoLek4vQj+ziDm4C1ARrYk8AiW40ioRJuT73DF8RhuzD8hBt1tH6mjeIANz8Lf
1big996JofkxU2eN99MnhUeBxFrOCPef7y9h0rM7UqZHDo1HGxCZxd12COyspWkG
WsFN4VrLxkXhPfa8jc5TBY5e1632JoL+VuWFjKd0CddgtSm2bqfX355BQi6+eJ4A
kJ3L8QRJSNeY
=ogBe
-----END PGP PUBLIC KEY BLOCK-----

#

If you have one of the RPMs from Photon OS on another Linux system, such as Ubuntu, you can use SHA and the RSA Data Security, Inc. MD5 Message Digest Algorithm for the package to verify that it has not been tampered with:

rpm -K GConf-3.2.6-1.ph5.src.rpm
GConf-3.2.6-1.ph5.src.rpm: digests signatures OK

You can view the SHA1 digest and the RSA Data Security, Inc. MD5 Message Digest Algorithm by running the following command:

rpm -Kv GConf-3.2.6-1.ph5.src.rpm
GConf-3.2.6-1.ph5.src.rpm:
    Header V3 RSA/SHA256 Signature, key ID 66fd4949: OK
    Header SHA256 digest: OK
    Header SHA1 digest: OK
    Payload SHA256 digest: OK
    V3 RSA/SHA256 Signature, key ID 66fd4949: OK
    MD5 digest: OK
#

The above examples show that the Kubernetes package has not been tampered with.

5.1.5 - Photon OS Package Repositories

The default installation of Photon OS includes yum-compatible repositories and the repository on the Photon OS ISO when it is available on a CD-ROM drive:

# ls -l /etc/yum.repos.d/
total 24
-rw-r--r-- 1 root root 313 Apr 17 13:19 photon-debuginfo.repo
-rw-r--r-- 1 root root 238 Apr 17 13:19 photon-iso.repo
-rw-r--r-- 1 root root 299 Apr 17 13:19 photon-release.repo
-rw-r--r-- 1 root root 303 Apr 17 13:19 photon.repo
-rw-r--r-- 1 root root 331 Apr 17 13:19 photon-srpms.repo
-rw-r--r-- 1 root root 305 Apr 19 06:00 photon-updates.repo

The Photon ISO repository (photon-iso.repo) contains the installation packages for Photon OS. All the packages that Photon builds and publishes reside in the RPMs directory of the ISO when it is mounted. The RPMs directory contains metadata that lets it act as a yum repository. Mounting the ISO gives you all the packages corresponding to a Photon OS build. If, however, you built Photon OS yourself from the source code, the packages correspond only to your build, though they will typically be the latest. In contrast, the ISO that you obtain from the VMware Photon Packages web site contains only the packages that are in the ISO at the point of publication. As a result, the packages may no longer match those on in the ISO, because they are updated more frequently.

The Photon repository (photon.repo) contains all the rpms released for a particular Photon release. This repository is disabled by default but can be enabled in case the end user wants to install an older version of an rpm.

The Photon Updates repository (photon-updates.repo) contains the latest versions of all the rpms for a particular Photon release. This repository is updated with the new rpm releases. This repository is enabled by default.

The Photon debuginfo repository (photon-debuginfo.repo) contains the debuginfo rpms which can be installed for debugging coredumps or issues. This repository is disabled by default.

The Photon release repository (photon-release.repo) contains the rpms snapped at the major release time. This repository is not updated after GA. This repository is disabled by default.

The Photon SRPM repository (photon-srpms.repo) contains all the source rpms for a particular Photon release. This can be used to extract the source which was used to build the rpm. This repository is disabled by default.

5.1.6 - Building a Package from a Source RPM

This section describes how to install and build a package on the full version of Photon OS from the package’s source RPM. Obtain the source RPMs that Photon OS uses from the VMWare Packages repository: packages.vmware.com/photon

Prerequisites

  • To build a package from its source RPM, or SRPM, Photon OS requires the following packages:

    • rpmbuild. This package is installed by default on the full version of Photon OS, so you should not have to install it.

    • gcc. This package is also installed by default on the full version of Photon OS, so you should not have to install it.

    • make, Cmake, automake, or another make package, depending on the package you are trying to install and build from its source RPM. Cmake is installed by default on Photon OS.

      You can install other make packages by using tdnf or yum.

  • A local unprivileged user account other than the root account. You should build RPMs as an unprivileged user. Do not build a package as root becau–building an RPM with the root account might damage your system.

  • Take a snapshot of your virtual machine before building the package if you are building a package on a virtual machine running Photon OS in VMware vSphere, VMware Workstation, or VMware Fusion.

Procedure

VMware recommends that you install and build packages from their source RPMs on the full version of Photon OS. Do not use the minimal version to work with source RPMs.

Perform the following steps to install and build an example package- sed from its source RPM on Photon OS with an unprivileged account.

  1. check whether rpmbuild is installed by running the following command:

    rpmbuild --version
    

    If it is not installed, install it by running the following command as root:

    tdnf install rpm-build
    
  2. Create the directories for building RPMs under your local user account home directory and not under root:

    mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
    
  3. Create a .rpmmacros file under your home directory and override the default location of the RPM building tree with the new one. This command overwrites an existing .rpmmacros file. Before running the following command, make sure you do not already have a .rpmmacros file. If a .rpmmacros file exists, back it up under a new name in case you want to restore it later.

    echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros
    
  4. Place the source RPM file that you want to install and build in the /tmp directory.

  5. Install the source file, run the following command with your unprivileged user account, replacing the sed example source RPM with the name of the one that you want to install:

    rpm -i /tmp/sed-4.2.2-2.ph1.src.rpm
    

    The above command unpacks the source RPM and places its .spec file in your ~/rpmbuild/SPECS directory. In the next step, the rpmbuild tool uses the .spec file to build the RPM.

  6. Build the RPM, run the following commands with your unprivileged user account. Replace the sed.spec example file with the name of the .spec file that you want to build.

    cd ~/rpmbuild/SPECS
    rpmbuild -ba sed.spec
    

    If successful, the rpmbuild -ba command builds the RPM and generates an RPM package file in your ~/rpmbuild/RPMS/x86_64 directory. For example:

    ls RPMS/x86_64/
    sed-4.2.2-2.x86_64.rpm  sed-debuginfo-4.2.2-2.x86_64.rpm  sed-lang-4.2.2-2.x86_64.rpm
    

    The rpmbuild command also generates a new SRPM file and saves it in your ~/rpmbuild/SRPMS directory. For example:

    ls SRPMS/
    sed-4.2.2-2.src.rpm
    

    If the rpmbuild command is unsuccessful with an error that it cannot find a library, you must install the RPMs for the library that your source RPM depends on before you can successfully build your source RPM. Iterate through installing the libraries that your source RPM relies on until you can successfully build it.

  7. To install the RPM, run the following command with your unprivileged user account:

    rpm -i RPMS/x86_64/sed-4.2.2-2.x86_64.rpm
    

5.1.7 - Compiling C++ Code on the Minimal Version of Photon OS

As a minimalist Linux run-time environment, the minimal version of Photon OS lacks the packages that you need to compile the code for a C++ program. For example, without the requisite packages, trying to compile the file containing the following code with the gcc command will generate errors:

#include <stdio.h>
int main()
{
return 0;
}

The errors appear as follows:

gcc test.c
-bash: gcc: command not found
tdnf install gcc -y
gcc test.c
test.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.

To enable the minimal version of Photon OS to preprocess, compile, assemble, and link C++ code, you must install the following packages as root with tdnf:

  • gcc
  • glibc-devel
  • binutils

To install the packages, use the following the tdnf command:

tdnf install gcc glibc-devel binutils

5.2 - Package Management in Photon OS with 'tdnf'

Photon OS manages packages with an open source, yum-compatible package manager called tdnf, for Tiny Dandified Yum. Tdnf keeps the operating system as small as possible while preserving yum’s robust package-management capabilities.

5.2.1 - Introduction to 'tdnf'

On Photon OS, tdnf is the default package manager for installing new packages. It is a C implementation of the DNF package manager without Python dependencies.

Tdnf appears in the minimal and full versions of Photon OS.

Tdnf implements a subset of the dnf commands as listed in the dnf guide.

5.2.2 - Configuration Files and Repositories

The main configuration files reside in /etc/tdnf/tdnf.conf. The configuration file appears as follows:

cat /etc/tdnf/tdnf.conf
[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=true
repodir=/etc/yum.repos.d
cachedir=/var/cache/tdnf

The cache files for data and metadata reside in /var/cache/tdnf.

The following repositories appear in /etc/yum.repos.d/ with .repo file extensions:

ls /etc/yum.repos.d/
photon-extras.repo
photon-iso.repo
photon-updates.repo
photon.repo 

You can list the the repositories by using the tdnf repolist command. Tdnf filters the results with enabled, disabled, and all. Running the command without specifying an argument returns the enabled repositories:

tdnf repolist
repo id             repo name                               status
photon-updates      VMware Photon Linux 2.0(x86_64)Updates  enabled
photon-extras       VMware Photon Extras 2.0(x86_64)        enabled
photon              VMware Photon Linux 2.0(x86_64)         enabled

The photon-iso.repo, however, does not appear in the list of repositories because it is unavailable on the virtual machine from which these examples are taken. The photon-iso.repo is the default repository and it points to /media/cdrom. The photon-iso.repo appears as follows:

cat /etc/yum.repos.d/photon-iso.repo
[photon-iso]
name=VMWare Photon Linux 2.0(x86_64)
baseurl=file:///mnt/cdrom/RPMS
gpgkey=file:///etc/pki/rpm-gpg/VMWARE-RPM-GPG-KEY
gpgcheck=1
enabled=0
skip_if_unavailable=True

The local cache is populated with data from the repository:

ls -l /var/cache/tdnf/photon
total 8
drwxr-xr-x 2 root root 4096 May 18 22:52 repodata
d-wxr----t 3 root root 4096 May  3 22:51 rpms

You can clear the cache to help troubleshoot a problem, but doing so might slow the performance of tdnf until the cache becomes repopulated with data. To clear the cache, use the following command:

tdnf clean all
Cleaning repos: photon photon-extras photon-updates lightwave
Cleaning up everything

The command purges the repository data from the cache:

ls -l /var/cache/tdnf/photon
total 4
d-wxr----t 3 root root 4096 May  3 22:51 rpms

5.2.3 - Adding a New Repository

On Photon OS, you can add a new repository from which tdnf installs packages. To add a new repository, you create a repository configuration file with a .repo extension and place it in /etc/yum.repos.d. The repository can be on either the Internet or a local server containing your in-house applications.

Be careful if you add a repository that is on the Internet. Installing packages from untrusted or unverified sources might put the security, stability, or compatibility of your system at risk. It might also make your system harder to maintain.

On Photon OS, the existing repositories appear in the /etc/yum.repos.d directory:

ls /etc/yum.repos.d/
photon-extras.repo
photon-iso.repo
photon-updates.repo
photon.repo 

To view the format and information that a new repository configuration file should contain, see one of the .repo files. The following is an example:

[photon-release]
name=VMware Photon Linux $releasever ($basearch)
baseurl=https://packages.vmware.com/photon/$releasever/photon_release_$releasever_$basearch
gpgkey=file:///etc/pki/rpm-gpg/VMWARE-RPM-GPG-KEY
gpgcheck=1
enabled=1
skip_if_unavailable=True

You can configure multiple repositories in one repository configuration file. Configuration for each of the repositories must have a separate section and ID.

The repository settings details are as follows:

  • The minimal information needed to establish a repository is an ID and human-readable name of the repository and its base URL. The ID, which appears in square brackets, must be one word that is unique among the system’s repositories; `.

  • The username setting specifies a username for the repository, if required.

  • The password setting sets a password for the repository, if required.

  • The baseurl is a URL for the repository’s repodata directory. For a repository on a local server that can be accessed directly or mounted as a file system, the base URL can be a file referenced by file://. Example:

    baseurl=file:///server/repo/

    You can also use the following protocols: http: https: ftp: ftps: file: You can add multiple URLs separated by commas. If download fails for one URL, the next URL is used. The URL can contain the variables $releasever and $basearch, which refers to the current release of the distribution (for example, 5.0) and the architecture (for example, x86_64 or aarch64).

  • You can use the metalink file to set hashes and priorities for URLs. To use the metalink feature, the tdnf-metalink plugin must be installed and loaded. A sample metalink file is as follows:

    cat metalink

    <?xml version="1.0" encoding="utf-8"?>
    
    <metalink version="3.0" xmlns="http://www.metalinker.org/" type="dynamic" pubdate="Wed, 05 Feb 2020 08:14:56 GMT" generator="mirrormanager" xmlns:mm0="http://fedorahosted.org/mirrormanager">
    
     <files>
    
      <file name="repomd.xml">
    
       <size>2035</size>
    
       <verification>
    
    <hash type="sha1">478437547dac9f5a73fe905d2ed2a0a5b153ef46</hash>
    
    <hash type="sha512">6c6fbfba288ec90905a8d2220a0bfd2a50e835b7faaefedb6978df6ca59c5bce25cc1ddd33023e305b20bcffc702ee2bd61d0855f4f1b2fd7c8f5109e428a764</hash>
    
       </verification>
    
       <resources maxconnections="1">
    
    <url protocol="http" type="http" location="IN" preference=“100”>https://packages.vmware.com/photon/3.0/photon_updates_3.0_x86_64/repodata/repomd.xml</url>
    
       </resources>
    
      </file>
    
     </files>
    
    </metalink>
    

    In the metalink file, provide the preference for each url, so tdnf first tries to sync the repository data from the mirror which has the highest preference. If it fails for any reason, tdnf will use the next mirror URL.

    Note: Ensure that the shasum for respomd.xml in all the mirrors should be same.

  • The metadata_expire setting specifies the expiry time limit for the downloaded metadata in seconds. After the set limit expires, metadata is refreshed on the next action that requires them. The default value is 172800 seconds.

  • The priority setting specifies the priority of the repositories.

  • The gpgcheck setting specifies whether to check the GPG signature. The default value is true. If you enable this setting, set the gpgkey.

  • The repo_gpgcheck setting allows tdnf to verify the signature of a repository metadata before downloading the repository artifacts. When repo_gpgcheck is set to 1 in the tdnf.conf file, all repositories are checked for the metadata signatures. The default value is 0. To use the repo_gpgcheck feature, the tdnf repogpgcheck plugin must be installed and enabled. If a repository has repo_gpgcheck enabled,a repomd.xml.asc file is downloaded and the API equivalent of gpg --verify repomd.xml.asc repomd.xml is done. If repomd.xml.asc is missing, repository is deactivated. If repomd.xml.asc fails to verify, the repository is deactivated. The public key for verification must be manually installed for the initial implementation.

    Note: Ensure that you have installed libgcrypt for this implementation.

  • The gpgkey setting furnishes the URL for the repository’s ASCII-armored GPG key file. tdnf uses the GPG key to verify a package if its key has not been imported into the RPM database.

    The repository configuration also supports public keys that are remote for the gpgkey option. So, the URLs starting with http, https, or ftp can be used for gpgkey.

    For example: gpgkey=http://build-squid.eng.vmware.com/build/mts/release/bora-16633979/publish/packages/keys/vmware.asc

  • You can use the enabled setting to enable the repository. The default value is false. You can override this setting with --disablerepo, --enablerepo, and --repoid options on the command line.

  • The skip_if_unavailable setting instructs tdnf to continue running if the repository goes offline.

  • The retries setting in the repository configuration specifies the number of retries when downloading a file throws an error. The default is 10.

  • The timeout setting specifies the number of seconds that a download is allowed to take or 0 for no limit. Note that this is an absolute value and may interrupt large file downloads.

  • The minrate setting specifies the limit below which if the download rate falls, tdnf aborts the download. The default value is 0 (no limit).

  • The maxrate setting specifies the maximum download rate (throttle). The default value is 0 (no limit).

  • You can use the skip metadata download settings to skip the download of metadata files for repositories with a lot of packages. When you skip the download of the metadata files, it improves the download time of the packages and the processing time of refreshing the cache.

    The following list describes the benefits and drawbacks of the skip metadata settings:

    • skip_md_filelists: The skip_md_filelists=1 setting deactivates the download of the complete list of files in all packages. The setting improves the download and processing time but affects the repoquery queries for files. The default value is 0.

    • skip_md_other: The skip_md_other=1 setting deactivates the download of miscellaneous data like the changelog data of packages. The setting improves the download and processing time but affects the repoquery queries for changelogs. The default value is 0.

    • skip_md_updateinfo: The skip_md_updateinfo=1 setting deactivates the download of the update info data. The setting improves the download and processing time but affects the output of the updateinfo command. The default value is 0.

  • Other options and variables can appear in the repository file. The variables that are used with some of the options can reduce future changes to the repository configuration files. There are variables to replace the value of the version of the package and to replace the base architecture. For more information, see the man page for yum.conf on the full version of Photon OS: man yum.conf

The following is an example of how to add a new repository for a local server that tdnf polls for packages:

cat > /etc/yum.repos.d/apps.repo << "EOF"
[localapps]
name=Local In-House Applications(x86_64)
baseurl=file:///appserver/apps
enabled=1
skip_if_unavailable=True
EOF

Because this new repository resides on a local server, make sure the Photon OS machine can connect to it by mounting it.

After establishing a new repository, you must run the following command to update the cached binary metadata for the repositories that tdnf polls:

tdnf makecache
Refreshing metadata for: 'VMware Photon Linux 1.0(x86_64)Updates'
Refreshing metadata for: 'VMware Photon Extras 1.0(x86_64)'
Refreshing metadata for: 'Local In-House Applications(x86_64)'
Refreshing metadata for: 'VMware Photon Linux 1.0(x86_64)'
Metadata cache created.

You can also specify the SSL Certificate details in the following settings:

  • sslcacert: Use a string value.
  • sslclientcert: Use a string value.
  • sslclientkey: Use a string value.
  • sslverify: Specify whether to perform the SSL verification. The default value is true.

5.2.4 - Mount the Photon ISO Image for the Photon-ISO Repository

Photon OS comes with a preconfigured repository called photon-iso that resides in \etc\yum.repos.d. If you receive an access error message when working with the photon-iso repository, it is probably because you do not have the Photon OS ISO mounted. Mount the ISO and the run the following command to update the metadata for all known repositories, including photon-iso:

mount /dev/cdrom /media/cdrom
tdnf makecache

Refreshing metadata for: 'VMware Photon Linux 1.0(x86_64)Updates'
Refreshing metadata for: 'VMware Photon Extras 1.0(x86_64)'
Refreshing metadata for: 'VMware Photon Linux 1.0(x86_64)'
Metadata cache created.

5.2.5 - Adding the Dev Repository to Get New Packages from the GitHub Dev Branch

To try out new packages or the latest versions of existing packages as they are merged into the dev branch of the Photon OS GitHub site, add the dev repository to your repository list.

Perform th following steps:

  1. On your Photon OS machine, run the following command as root to create a repository configuration file named photon-dev.repo, place it in /etc/yum.repos.d, and concatenate the repository information into the file:
cat > /etc/yum.repos.d/photon-dev.repo << "EOF" 
    [photon-dev]
    name=VMware Photon Linux Dev(x86_64)
    baseurl=https://packages.vmware.com/photon/dev/photon_dev_$basearch
    gpgkey=file:///etc/pki/rpm-gpg/VMWARE-RPM-GPG-KEY
    gpgcheck=1
    enabled=1
    skip_if_unavailable=True
    EOF
    .
  1. After establishing a new repository, run the following command to update the cached binary metadata for the repositories that tdnf polls:
tdnf makecache

5.2.6 - tdnf-automatic

tdnf-automatic is an alternative Command Line Interface (CLI) to tdnf upgrade/tdnf update with specific features so that it is suitable to be executed automatically and regularly from systemd timers, cron jobs, and so on.

The operation of the tool is usually controlled by the configuration file or the function-specific timer units. The command only accepts a single optional argument pointing to the config file, and some control arguments intended for use by the services that back the timer units. If no configuration file is passed from the command line,then /etc/tdnf/automatic.conf is used.

The tool synchronizes package metadata as needed and then checks for the updates available for the given system and then either exits or shows available updates or downloads and installs the packages.

The outcome of the operation is then reported through stdio.

The systemd timer unit tdnf-automatic.timer behaves as the configuration file specifies whether to download and apply updates. Some other timer units are provided which override the configuration file with some standard behaviors:

* tdnf-automatic-notifyonly

* tdnf-automatic-install

Irrespective of the configuration file settings, the first only notifies of available updates. The second one downloads and installs the updates.

Run tdnf-automatic

You can select one that most closely fits your needs, customize /etc/tdnf/automatic.conf for any specific behaviors, and enable the timer unit.

For example: systemctl enable –now tdnf-automatic-notifyonly.timer

Configuration file format

The configuration file is separated into two sections. This basically gives info on what can be put in /etc/tdnf/automatic.conf. ‘automatic.conf’ is a configuration INI file.

Format

tdnf-automatic help:

tdnf-automatic [{-c|--conf config-file}(optional)] [{-i|--install}] [{-n|--notify}] [{-h|--help}] [{-v|--version}]



-c, --conftdnf-automatic configuration file (Optional argument)

-i, --installOverride automatic.conf apply_updates and install updates

-n, --notifyShow available updates

-h, --helpShow this help message

-v, --versionShow tdnf-automatic version information

Commands

To set the mode of the operation of the program:

  • apply_updates (boolean, default: no) Whether packages comprising the available updates should be applied by tdnf-automatic.timer, i.e. installed via RPM. Note that the other timer units override this setting.

  • show_updates (boolean, default: yes) To just receive updates use tdnf-automatic-notifyonly.timer

  • network_online_timeout (time in seconds, default: 60) Maximum time tdnf-automatic will wait until the system is online. 0 means that network availability detection will be skipped.

  • random_sleep (time in seconds, default: 0) Maximum random delay before downloading. Note that, by default, the systemd timers also apply a random delay of up to 1 hour.

  • upgrade_type (either one of all or security. default: all) Looks at the kind of upgrades. all signals looking for all available updates. security indicates only those with an issued security advisory.

  • tdnf_conf (string, default: /etc/tdnf/tdnf.conf) Configurations to override default tdnf configuration.

Reports

To select how the results should be reported:

  • emit_to_stdio (boolean, default: yes) Report the results through stdio. If no, no report will be shown.

  • system_name (string, default: hostname of the given system) How the system is called in the reports.

  • emit_to_file (string, absolute path of file) If we want to capture the logs in a file

5.2.7 - Install Packages from CLI

You can install the packages from the command line. The package can be a file or a URL. The dependencies are installed automatically.

For example:

  • Using a URL:

      tdnf install https://packages.vmware.com/photon/5.0/photon_release_5.0_x86_64/x86_64/open-vm-tools-11.2.5-1.ph5.x86_64.rpm
    
      open-vm-tools-11.2.5-1.ph5.x86_64.rpm 763014   100%
    
      Installing:
    
      attrx86_642.4.48-1.ph5  photon  88.65k 90778
    
      nss x86_643.57-2.ph5photon  1.69M 1768005
    
      ...
    
      open-vm-tools   x86_6411.2.5-1.ph5  @cmdline2.65M 2779392
    
    
      Total installed size:  91.57M 96019175
    
    
      Upgrading:
    
      nss-libsx86_643.57-2.ph5photon  2.48M 2601790
    
      util-linux-libs x86_642.36-2.ph5photon752.75k 770816
    
      pcre-libs   x86_648.44-2.ph5photon275.60k 282216
    
    
    
      Total installed size:   3.49M 3654822
    
      Is this ok [y/N]: 
    
  • Using a file:

      tdnf install ../lsof-4.91-1.ph5.x86_64.rpm 
    
    
      Installing:
    
      libtirpcx86_641.2.6-1.ph5   photon193.56k 198209
    
      lsofx86_644.91-1.ph5@cmdline  196.10k 200810
    
      Total installed size: 389.67k 399019

5.2.8 - SSL Options

Photon OS offers support for the SSL Options.

You can set the following SSL options in the repository configuration file:

  • sslverify When downloading using https, this option helps to verify the SSL certificate of the server. You can set it to 0 or 1. The default is 1.

  • sslcacert You can use this option to set the path to a certificate file to verify the server.

  • sslclientcert You can use this option to set the path to a client certificate file.

  • sslclientkey You can set this path to the client key file.

5.2.9 - Standard Syntax for tdnf Commands

The standard syntax for tdnf commands is the same as that for DNF and is as follows:

tdnf [options] <command> [<arguments>...]

You can view help information by using the following commands:

tdnf --help
tdnf -h

5.2.9.1 - tdnf Commands

autoremove [pkg-spec]: This command removes a package with its dependencies. This is similar to the erase/remove command. You can use this command to remove the packages that are no longer needed regardless of the clean_requirements_on_remove option.

autoremove without any arguments removes all automatically installed packages that are no longer required.

check: Checks for problems in installed and available packages for all enabled repositories. The command has no arguments. You can use --enablerepo and --disablerepo to control the repos used. Supported in Photon OS 2.0 (only).

check-local: This command resolves dependencies by using the local RPMs to help check RPMs for quality assurance before publishing them. To check RPMs with this command, you must create a local directory and place your RPMs in it. The command, which includes no options, takes the path to the local directory containing the RPMs as its argument. The command does not recursively parse directories. It checks the RPMs only in the directory that you specify. For example, after creating a directory named /tmp/myrpms and placing your RPMs in it, you can run the following command to check them:

tdnf check-local /tmp/myrpms
Checking all packages from: /tmp/myrpms
Found 10 packages
Check completed without issues

check-update: This command checks for updates to packages. It takes no arguments. The tdnf list updates command performs the same function. Here is an example of the check update command:

tdnf check-update
rpm-devel.x86_64 	4.11.2-8.ph1 	photon
yum.noarch      	3.4.3-3.ph1 	photon

clean: This command cleans up temporary files, data, and metadata. It takes the argument all. Example:

tdnf clean all
Cleaning repos: photon photon-extras photon-updates
Cleaning up everything

You can use this command to clean all configured repositories.

You can also use the following sub-commands or arguments to clean specific files:

metadata: This sub-command cleans up downloaded metadata from the repositories.

dbcache: This sub-command cleans up metadata generated from libsolv

packages: This sub-command removes downloaded packages from the cache.

keys: This sub-command removes downloaded keys from the cache.

expire-cache: This sub-command removes the cache expiry marker. This triggers a download of metadata on the next action that needs them.

distro-sync: This command synchronizes the machine’s RPMs with the latest version of all the packages in the repository. The following is an abridged example:

tdnf distro-sync

Upgrading:
zookeeper                             x86_64        3.4.8-2.ph1               3.38 M
yum                                   noarch        3.4.3-3.ph1               4.18 M

Total installed size: 113.01 M

Reinstalling:
zlib-devel                            x86_64        1.2.8-2.ph1             244.25 k
zlib                                  x86_64        1.2.8-2.ph1             103.93 k
yum-metadata-parser                   x86_64        1.1.4-1.ph1              57.10 k

Total installed size: 1.75 G

Obsoleting:
tftp                                  x86_64        5.2-3.ph1                32.99 k

Total installed size: 32.99 k
Is this ok [y/N]:

downgrade: This command downgrades the package that you specify as an argument to the next lower package version. The following is an example:

tdnf downgrade boost
Downgrading:
boost                                 x86_64        1.56.0-2.ph1              8.20 M
Total installed size: 8.20 M
Is this ok [y/N]:y
Downloading:
boost                                  2591470    100%
Testing transaction
Running transaction
Complete!

To downgrade to a version lower than the next one, you must specify it by name, epoch, version, and release, all properly hyphenated. The following is an example:

tdnf downgrade boost-1.56.0-2.ph1 

erase: This command removes the package that you specify as an argument.

To remove a package, run the following command:

tdnf erase pkgname

The following is an example:

tdnf erase vim
Removing:
vim                                   x86_64        7.4-4.ph1                 1.94 M
Total installed size: 1.94 M
Is this ok [y/N]:

You can also erase multiple packages:

tdnf erase docker cloud-init

When you remove a package, by default, tdnf does not remove the dependencies that are no longer used if tdnf installed them as dependencies. To remove the dependencies, modify the clean_requirements_on_remove option in the /etc/tdnf/tdnf.conf file to true, or use the autoremove command.

history: This command allows you to record every transaction (commands that install, update, or remove packages) in a database. You can roll back the transactions to a past state, or undo or redo a range of transactions.

There are five sub-commands or arguments that you can use with the history command:

history init/update: The sub-commands init or update initializes the history database. It is recommended that you use these commands right after tdnf is installed. If the database is not already initialized, any altering commands such as install or erase initializes the database.

If the database is already initialized, the commands have no effect unless an application such as an RPM command adds or removes any packages after the last recorded transaction.

history list: This command lists the history of transactions. Note that this result is similar when you use the history command without an argument or sub-command.

The following example shows the use of the command:

# tdnf history
ID   cmd line                                 date/time             +added / -removed
   1 (set)                                    Thu May 05 2022 19:14 +152 / -0
   2 -y install less                          Thu May 05 2022 19:14 +1 / -0
   3 -y install lsof                          Thu May 05 2022 19:18 +2 / -0

You can specify the following options for this sub-command:

  • --info: Use this option to list a more detailed history that includes added or removed packages.
  • --reverse Use this option to list the history in reverse order.
  • --from <id> and --to <id>: Use this option to list a range of transactions. You can specify the transaction IDs of the range in this option.

The following example shows how to use the options:

# tdnf history --info --from 2 --to 3
ID   cmd line                                 date/time             +added / -removed
   2 -y install less                          Thu May 05 2022 19:14 +1 / -0
added: less-551-2.ph4.aarch64

   3 -y install lsof                          Thu May 05 2022 19:18 +2 / -0
added: libtirpc-1.2.6-2.ph4.aarch64, lsof-4.91-1.ph4.aarch64

history rollback –to trans_id: This command allows you to revert to a previous state. You must specify the ID of the desired state with the --to parameter.

Example:

# tdnf history rollback --to 49

Upgrading:
curl-devel                               aarch64              7.82.0-3.ph4                photon-updates       885.16k 906404
curl                                     aarch64              7.82.0-3.ph4                photon-updates       256.73k 262896
...

Total installed size:   3.52M 3688748
Is this ok [y/N]: y

Downloading:
curl-devel                              793306 100%
curl                                    148725 100%
...
Testing transaction
Running transaction
Installing/Updating: rpm-libs-4.16.1.3-9.ph4.aarch64
Installing/Updating: rpm-4.16.1.3-9.ph4.aarch64
...
Complete!

history undo –from trans_id [–to trans_id]: You can use this command to undo a transaction. The parameter --from is mandatory, and the specified transaction in the parameter is reversed. Optionally, you can specify a range with the parameter --to to reverse all the specified transactions. Note that the range you specify is inclusive. For example, if you specify the range as 2 to 4, the transactions in 2, 3, and 4 are reversed.

history redo –from trans_id [–to trans_id]: You can use this command to redo a transaction. The parameter --from is mandatory, and the specified transaction in the parameter is redone. Optionally, you can specify a range with the parameter --to to redo all the specified transactions. The range you specify in the parameters is inclusive.

NOTE

Deltas: When you make changes using history commands, the changes are resolved based on the total deltas between the start and the target states. For each range of transactions, the intermediate states are irrelevant. For example, in a range of transactions where one transaction installs a package and the last one removes the package, the final installed state of the package remains the same from start to end.

Unresolved Packages: If a package is not found, tdnf fails with an error message. For instance, when you roll back to a state before an update, the system might not find all the required installation packages in the repository. In such a case, you can enable the additional repositories to successfully revert.

Example:

The following example shows how the tdnf fails with an error message for the unavilable packages:

# tdnf history rollback --to 1
The following packages could not be resolved:

curl-libs-7.82.0-1.ph4.aarch64
rpm-libs-4.16.1.3-7.ph4.aarch64
...

The package(s) may have been moved out of the enabled repositories since the
last time they were installed. You may be able to resolve this by enabling
additional repositories.
Error(1011) : No matching packages

The following example shows how you can enable the repository to resolve the issue:

tdnf --enablerepo=photon history rollback --to 1

Downgrading:
curl-devel                               aarch64              7.82.0-1.ph4                photon               885.16k 906404
rpm-build                                aarch64              4.16.1.3-7.ph4              photon               434.00k 444418
...

Total installed size:   4.26M 4463905

Removing:
wget                                     aarch64              1.21.3-1.ph4                @System                3.02M 3168291
tdnf-test-cleanreq-required              aarch64              1.0.1-3                     @System                    0.00b 0
lsof                                     aarch64              4.91-1.ph4                  @System              202.36k 207218
libtirpc                                 aarch64              1.2.6-2.ph4                 @System              193.33k 197970
gdb                                      aarch64              10.1-2.ph4                  @System               12.60M 13214814

Total installed size:  16.01M 16788293
Is this ok [y/N]: 

Transactions outside tdnf: tdnf keeps track of the transactions it performs. However, other tools such as rpm can also add or remove packages. While performing the next transaction, if tdnf detects transactions performed by other tools, it records such transactions as pseudo transactions.

Example:

# tdnf history --info --from 49 --to 49
ID   cmd line                                 date/time.            +added / -removed
  49 (unknown)                                Thu May 05 2022 23:38 +1 / -0
added: gdb-10.1-2.ph4.aarch64

Dependencies: The undo and redo actions might need to install additional depedencies apart from the previously existing packages. For example, when you redo a transaction that installs a single package which was earlier removed along with its depedencies, the command also attempts to install the dependecies.

Note that this is not an issue for the rollback command because the entire set of packages is restored assuming that the dependecies are also satisfied at the state.

info: This command displays information about packages. It can take the name of a package. Or it can take one of the following arguments: all, available, installed, extras, obsoletes, recent, upgrades. The following are examples:

tdnf info ruby
tdnf info obsoletes
tdnf info upgrades

install: This command takes the name of a package as its argument. It then installs the package and its dependencies.

To install a package, run the following command:

tdnf install pkgname

The following are examples:

tdnf install kubernetes

You can also install multiple packages:

tdnf install python-curses lsof audit gettext chkconfig ntsysv bindutils 
	 wget gawk irqbalance lvm2 cifs-utils c-ares distrib-compat

list: This command lists the packages of the package that you specify as the argument. The command can take one of the following arguments: all, available, installed, extras, obsoletes, recent, upgrades.

tdnf list updates

The list of packages might be long. To more easily view it, you can concatenate it into a text file, and then open the text file in a text editor:

tdnf list all > pkgs.txt
vi pkgs.txt

To list enabled repositories, run the following command:

tdnf repolist

makecache: This command updates the cached binary metadata for all known repositories. The following is an example:

tdnf makecache
Refreshing metadata for: 'VMware Lightwave 1.0(x86_64)'
Refreshing metadata for: 'VMware Photon Linux 1.0(x86_64)Updates'
Refreshing metadata for: 'VMware Photon Extras 1.0(x86_64)'
Refreshing metadata for: 'VMware Photon Linux 1.0(x86_64)'
Metadata cache created.

mark install|remove pkg_spec: Mark one or more packages as auto installed (remove) or unmark as auto installed (install), which means it is user-installed. This is used to determine if this package gets removed on autoinstall.

provides: This command finds the packages that provide the package that you supply as an argument. The following is an example:

tdnf provides docker
docker-1.11.0-1.ph1.x86_64 : Docker
Repo     : photon
docker-1.11.0-1.ph1.x86_64 : Docker
Repo     : @System

reinstall: This command reinstalls the packages that you specify. If some packages are unavailable or not installed, the command fails. The following is an example:

tdnf reinstall docker kubernetes

Reinstalling:
kubernetes                            x86_64        1.1.8-1.ph1             152.95 M
docker                                x86_64        1.11.0-1.ph1             57.20 M

Total installed size: 210.15 M

repoquery [args]: The repoquery command allows you to query packages from the repositories and installed packages with different criteria and output options. It can take multiple package specifications as arguments.

Example:

$ tdnf repoquery vim 
vim-8.2.4925-1.ph4.aarch64
vim-8.2.1361-1.ph4.aarch64

$ tdnf repoquery vim*
vim-8.2.4925-1.ph4.aarch64
vim-8.2.1361-1.ph4.aarch64
vim-extra-8.2.4925-1.ph4.aarch64
vim-extra-8.2.1361-1.ph4.aarch64

$ tdnf repoquery --installed vim
vim-8.2.4925-1.ph4.aarch64

$ tdnf repoquery --requires vim
ld-linux-aarch64.so.1()(64bit)
ld-linux-aarch64.so.1(GLIBC_2.17)(64bit)
libc.so.6(GLIBC_2.17)(64bit)
...

The following groups of options are available for repoquery:

  • select option: Use this option to filter the list of packages. You can use the following parameters with the select option:

    • --available: Use this parameter to show available packages in the repositories.

    • --duplicates: Use this parameter to show duplicate installed packages.

    • --extras: Use this parameter to show the packages that are installed but not in any repositories.

    • --file file: Use this parameter to show packages that contain the specified files.

    • --installed: Use this parameter to show the installed packages.

    • --userinstalled: Use this parameter to show the user-installed packages.

    • --whatdepends, --whatenhances, --whatobsoletes, --whatprovides, --whatrecommends, whatrequires, --whatsuggests, --whatsupplements capability: Use these parameters to show packages that have the specified dependency on capability.

      Example:

      $ tdnf repoquery --whatrequires vim
      minimal-0.1-6.ph4.aarch64
      vim-extra-8.2.4925-1.ph4.aarch64
      minimal-0.1-4.ph4.aarch64
      
  • query option: Use this option to control what you want the command to display. The query option lists the selected packages by default. You can use the following parameters to get the required output:

    • --list: Use this parameter to list all files of the selected packages.
    • --depends, --enhances, --obsoletes, --provides, --recommends, requires, requires-pre, --suggests, --supplements: Use these parameters to list specified dependencies.

reoposync: This command synchronizes a remote repository with a local one. By default, all packages are downloaded to a local directory unless they already exist. Optionally, metadata is also downloaded.

You can use the following options with the command:

--delete: Use this option to remove old packages that are not part of the repository any more.

--download-metadata: Use this option to download the metadata. After you download the the metadata, you can use the directory as a repository.

--gpgcheck: Use this option to check the gpg signature. If invalid, the package is deleted.

--norepopath: When you use this option, no subdirectory with the repo name is created. This option is only valid if you configure more than one repository.

--urls: When you use this option, instead of downloading, the URLs of all files are printed to stdout.

--download-path: Use this option to specify the download path. By default, files are downloaded relative to the current directory.

--metadata-path: Use this option to specify the download path. You can download metadata to a different directory.

--arch: Use this option to download specific architectures. You can use this option repeatedly.

--source: Use this option to download only source packages. This option is similar to --arch src. Note that this option is incompatible with the --arch option.

--newest-only: Use this option to download only the latest versions of the repository.

remove: This command removes a package. When removing a package, tdnf by default also removes dependencies that are no longer used if they were was installed by tdnf as a dependency without being explicitly requested by a user. You can modify the dependency removal by changing the clean_requirements_on_remove option in /etc/tdnf/tdnf.conf to false.

tdnf remove packagename

search: This command searches for the attributes of packages. The argument can be the names of packages. The following is an example:

tdnf search docker kubernetes
docker : Docker
docker : Docker
docker-debuginfo : Debug information for package docker
docker : Docker
kubernetes : Kubernetes cluster management
kubernetes : Kubernetes cluster management
kubernetes-debuginfo : Debug information for package kubernetes
kubernetes : Kubernetes cluster management

The argument of the search command can also be a keyword or a combination of keywords and packages:

tdnf search terminal bash
rubygem-terminal-table : Simple, feature rich ascii table generation library
ncurses : Libraries for terminal handling of character screens
mingetty : A minimal getty program for virtual terminals
ncurses : Libraries for terminal handling of character screens
ncurses : Libraries for terminal handling of character screens
bash : Bourne-Again SHell
bash-lang : Additional language files for bash
bash-lang : Additional language files for bash
bash : Bourne-Again SHell
bash-debuginfo : Debug information for package bash
bash : Bourne-Again SHell
bash-lang : Additional language files for bash

updateinfo: This command displays security advisories about packages. The following is an example:

tdnf updateinfo info

Name : unzip-6.0-15.ph3.x86_64.rpm
Update ID : patch:PHSA-2020-3.0-0083
Type : Security
Updated : Fri Apr 24 01:15:03 2020
Needs Reboot: 0
Description : Security fixes for {'CVE-2018-1000035'}
Name : runc-1.0.0.rc9-3.ph3.x86_64.rpm
Update ID : patch:PHSA-2020-3.0-0102
Type : Security
Updated : Tue Jun  9 06:01:28 2020
Needs Reboot: 0
Description : Security fixes for {'CVE-2019-19921'}
Name : ruby-2.5.8-2.ph3.x86_64.rpm
Update ID : patch:PHSA-2020-3.0-0163
Type : Security
Updated : Thu Nov 19 17:21:29 2020
Needs Reboot: 0

upgrade: This command upgrades the package or packages that you specify to an available higher version that tdnf can resolve. If the package is already the latest version, the command returns Nothing to do. The following is an example:

tdnf upgrade boost

Upgrading:
boost                                 x86_64        1.60.0-1.ph1              8.11 M

Total installed size: 8.11 M
Is this ok [y/N]:y

Downloading:
boost                                  2785950    100%
Testing transaction
Running transaction

Complete!

You can also run the upgrade command with the refresh option to update the cached metadata with the latest information from the repositories. The following example refreshes the metadata and then checks for a new version of tdnf but does not find one, so tdnf takes no action:

tdnf upgrade tdnf --refresh
Refreshing metadata for: 'VMware Lightwave 1.0(x86_64)'
Refreshing metadata for: 'VMware Photon Linux 1.0(x86_64)Updates'
Refreshing metadata for: 'VMware Photon Extras 1.0(x86_64)'
Refreshing metadata for: 'VMware Photon Linux 1.0(x86_64)'
Nothing to do.

upgrade-to: This command upgrades to the version of the package that you specify. The following is an example:

tdnf upgrade-to ruby2.3

The commands and options of tdnf are a subset of those of dnf. For more help with tdnf commands, see the DNF documentation.

5.2.9.2 - tdnf Command Options

You can add the following options to tdnf commands. If the option to override a configuration is unavailable in a command, you can add it to the /etc/tdnf/tdnf.conf configuration file.

OPTIONDESCRIPTION
–allowerasingAllow erasing of installed packages to resolve dependencies
–assumenoAnswer no for all questions
–bestTry the best available package versions in transactions
–debugsolverDump data aiding in dependency solver debugging info.
–disablerepo=Disable specific repositories by an id or a glob.
–enablerepo=Enable specific repositories
-h, –helpDisplay help
–refreshSet metadata as expired before running command
–nogpgcheckSkip gpg check on packages
rpmverbosity=<debug level name>Debug level for rpm
–versionDisplays the tdnf version and exit
-y, –assumeyesAnswer yes to all questions
-q, –quietQuiet operation
–downloadonlyEnables you to download the packages and dependencies that are not installed to the cache.
–alldepsEnables you to downloads all dependencies for a package regardless of whether they are installed. This command is valid when used together with –downloadonly command.
–downloaddir=dirDownloads the packages to the specified directory
-C, –cacheonlyDisables downloading metadata, and enables usage of the cached metadata even if it is expired.
–config file, -c fileUse an alternative configuration file
–exclude=package1[,package2[…]]Enables you to list the packages that you want to exclude from the operations.
–disableexcludesDisables excludes even if the excludes option is present in the configuration file.
–disablerepo=patternDisables one or more repositories. You can set it to a repoid or a pattern. You can also use it together with --enablerepo, but it is mutually exclusive with --repo/--repoid. For example, tdnf --disablerepo=* --enablerepo=photon list.
–enablerepo=patternEnables one or more repositories. You can set it to a repoid or a pattern. This command is mutually exclusive with --repo/--repoid.
–downloaddir=directorySpecifies a directory where to download the packages. If the directory is not specified, the package is downloaded in the cache directory. You can only use it together with --downloadonly.
–installroot=directoryAllows you to install packages relative to this directory. Unless you specify with -c or --config, tdnf uses the following configuration file in this directory: etc/tdnf/tdnf.conf. If the configuration file is not present in this directory, tdnf uses the following configuration file in the host: /etc/tdnf/tdnf.conf. This is the same for the repository configurations. The cache directory is relative to the installroot. Note that the cache directory is created, if necessary.
–json, -jEnables you to get the output information in JSON format. Using tdnf with its alias tdnfj is similar to using tdnf with tdnf -j -y.
–noautoremoveDisables automatic removal of orphaned dependencies regardless of the clean_requirements_on_remove option.
–repofrompath=repoid,baseurlAdds a repository with the id repoid and baseurl as the base url. This is equivalent to adding a repository with the repoid and the baseurl. You can reference the repository with the id, for example, with --repoid.

Example: tdnf repofrompath=local,file:///usr/src/photon/RPMS --repoid=local install lsof to install packages from usr/src/photon/RPMS (after using createrepo /usr/src/photon/RPMS).

You can use this multiple times to add multiple repositories.

–repoid id, –repo idEnables you to select a particular repository based on its ID. For example, --repoid=photon is equivalent to --disablerepo=* --enablerepo=photon. You can specify the repository multiple times.
–releaseverEnables you to specify the release version of the distribution. If installed, the version is taken from the package that provides the system-release unless configured otherwise. Setting this is useful while installing the distribution when you use --installroot.
–skip-brokenAllows skipping failures if a package is not available or has broken dependencies.
–testonlyTests RPM transactions. Note that this command does not install anything.

The following is an example that adds the short form of the assumeyes option to the install command:

tdnf -y install gcc
Upgrading:
gcc 	x86_64	5.3.0-1.ph1 	91.35 M

The following is an example for the downloadonly option with the install command:

tdnf install --downloadonly less
    
Installing:
    
lessx86_64551-2.ph4 photon234.35k 239976
       
Total installed size: 234.35k 239976
  
tdnf will only download packages needed for the transaction
   
Is this ok [y/N]: y

Downloading:
   
less117650   100%
    
Complete!
   
Packages have been downloaded to cache.

The following is an example for the downloaddir=dir option with the install command:

tdnf install --downloadonly --downloaddir=/tmp less
 
Installing:

lessx86_64551-2.ph4 photon234.35k 239976
        
Total installed size: 234.35k 239976

tdnf will only download packages needed for the transaction

Is this ok [y/N]: y

Downloading:

less117650   100%

    
Complete!

Packages have been downloaded to /tmp.

root [ /build/build ]# ls -l /tmp/less-551-2.ph4.x86_64.rpm 

-rw-r--r-- 1 root root 117650 Feb 22 18:43 /tmp/less-551-2.ph4.x86_64.rpm

5.2.10 - Configuration Options

You can use the configuration file to set and modify the tdnf configuration. The tdnf configuration file is located in the following directory: /etc/tdnf/tdnf.conf

The following table lists the configuration options that you can set in the tdnf configuration file:

ConfigurationDescription
cachedirType: string
Default value: /var/cache/tdnf
This is the location of the cache directory. The cache directory stores the metadata. After downloading the RPMs, the cache directory also stores the RPMs temporarily.
clean_requirements_on_removeType: boolean
Default value: false
Available from tdnf 3.3.1 onwards.

This option determines whether the automatically installed dependencies are removed when a package is removed.
distroarchpkgType: distroarchpkg
Default value: x86_64

The architecture of the distribution.
distroverpkgType: string
Default value: system-release
excludepkgsType: list
Default value: none

The list of packages that you want to exclude from any operations. Packages in this list are not installed, updated, or downgraded.
gpgcheckType: boolean
Default: false

This option determines whether the packages are checked for their gpg signature.
gpgcheckType: boolean
Default value: false

This option determines whether the packages are checked for their gpg signature.
installonly_limitType: integer
Currently not implemented.
This option limits the number of concurrently install only packages.
keepcacheType: boolean
Default value: false

This option determines whether to keep the downloaded packages after installation.
minversionsType: list
Default: none

This option refers to the list of packages with a minimum version number. When you set the minimum version number, packages are not downgraded below that version.
Example: minversions=tdnf=3.1.5 foo=1.2.3.
This can also be configured with the .conf extension files located in the directory named minversions.d. The directory is the same as the directory of the configuration file (usually, /etc/tdnf/minversions.d).
Example:
mkdir -p /etc/tdnf/minversions.d
echo tdnf=3.1.5 > /etc/tdnf/minversions.d/tdnf.conf
nopluginsWhen you set this option, plugins are disabled.
pluginpathType: string
Default value: /usr/lib/tdnf-plugins (or the modified value at the time of build with SYSTEM_LIBDIR option)

The path for plugins.
pluginconfpathType: string
Default value: /etc/tdnf/pluginconf.d

The path for the plugin configuration.
proxyType: string
Default value: none

Set this to a proxy, if any.
proxy_passwordType: string
Default value: none

The proxy password, if any.
proxy_usernameType: string
Default value: none

The proxy user name, if any.
repodirType: string
Default value: /etc/yum.repos.d

The location where the .repo files reside.

Configuration in sub-directories

There are other configurations that you can set in the subdirectories of /etc/tdnf.

Package Locks

You can configure to lock packages in the following directory: /etc/tdnf/locks.d. You cannot remove, upgrade, or downgrade a locked package. You can create multiple files with multiple lines. Each line can contain a package name.

Note: A locked package is considered locked only after it is installed. If a package is not installed, the features of a locked package do not apply.

Minimal Versions

You can configure a minimum version for a package in the following directory: /etc/tdnf/minversions.d. You can create multiple files with multiple lines in them. Each line can contain a package name. The package name must include a version number, and an = symbol must separate the name and version number.

Example:

# cat /etc/tdnf/minversions.d/rpm.conf 
rpm-libs=4.16.1.3-1

You can also configure this option in the main configuration file as mentioned in the table previously.

5.3 - Managing Services with 'systemd'

Photon OS manages services with systemd. By using systemd, Photon OS adopts a contemporary Linux standard to bootstrap the user space and concurrently start services. This is an architecture that differs from traditional Linux systems such as SUSE Linux Enterprise Server.

A traditional Linux system contains an initialization system called SysVinit. With SLES 11, for instance, the SysVinit-style init programs control how the system starts up and shuts down. Init implements system runlevels. A SysVinit runlevel defines a state in which a process or service runs.

In contrast to a SysVinit system, systemd defines no such runlevels. Instead, systemd uses a dependency tree of targets to determine which services to start when. Combined with the declarative nature of systemd commands, systemd targets reduce the amount of code needed to run a command, leaving you with code that is easier to maintain and probably faster to execute. For an overview of systemd, see systemd System and Service Manager and the man page for systemd.

On Photon OS, you must manage services with systemd and systemctl, its command-line utility for inspecting and controlling the system, and not the deprecated commands of init.d.

For more information, see the index of all the systemd man pages, including systemctl, at https://www.freedesktop.org/software/systemd/man/

5.3.1 - Viewing Services

To view a description of all the loaded and active units, run the systemctl command without any options or arguments:

systemctl

To see all the loaded, active, and inactive units and their description, run the following command:

systemctl --all

To see all the unit files and their current status but no description, run thie following command:

systemctl list-unit-files

The grep command filters the services by a search term, a helpful tactic to recall the exact name of a unit file without looking through a long list of names. Example:

systemctl list-unit-files | grep network
org.freedesktop.network1.busname           static
dbus-org.freedesktop.network1.service      enabled
systemd-networkd-wait-online.service       enabled
systemd-networkd.service                   enabled
systemd-networkd.socket                    enabled
network-online.target                      static
network-pre.target                         static
network.target                             static

5.3.2 - Controlling Services

To control services on Photon OS, use systemctl command.

For example, instead of running the /etc/init.d/ssh script to stop and start the OpenSSH server on a init.d-based Linux system, run the following systemctl commands on Photon OS:

systemctl stop sshd
systemctl start sshd

The systemctl tool includes a range of commands and options for inspecting and controlling the state of systemd and the service manager. For more information, see the systemctl man page.

5.3.3 - Creating a Startup Service

Use systemd to create a startup service.

The following example shows you how to create a systemd startup service that changes the maximum transmission unit (MTU) of the default Ethernet connection, eth0.

  1. Concatenate the following block of code into a file:
cat << EOF >> /lib/systemd/system/eth0.service
	[Unit]
	Description=Network interface initialization
	After=local-fs.target network-online.target network.target
	Wants=local-fs.target network-online.target network.target

	[Service]
	ExecStart=/usr/sbin/ifconfig eth0 mtu 1460 up
	Type=oneshot

	[Install]
	WantedBy=multi-user.target
EOF
  1. Set the service to auto-start when the system boots:
cd /lib/systemd/system/multi-user.target.wants/
	ln -s ../eth0.service eth0.service

5.3.4 - Disabling the Photon OS httpd.service

If your application or appliance includes its own HTTP server, you must turn off and disable the HTTP server that comes with Photon OS so that it does not conflict with your own HTTP server.

To stop it and disable it, run the following commands as root:

systemctl stop httpd.service
systemctl disable httpd.service

5.3.5 - Installing Sendmail

Before you install Sendmail, you should set the fully qualified domain name (FQDN) of your Photon OS machine.

By default, Sendmail is not installed with either the minimal or full version of Photon OS. When you install Sendmail, it provides Photon OS with a systemd service file that typically enables Sendmail. If the service is not enabled after installation, you must enable it.

Sendmail resides in the Photon extras repository. You can install it with tdnf after setting the machine’s FQDN.

Procedure

  1. Check whether the FQDN of the machine is set by running the hostnamectl status command:
hostnamectl status
       Static hostname: photon-d9ee400e194e
             Icon name: computer-vm
               Chassis: vm
            Machine ID: a53b414142f944319bd0c8df6d811f36
               Boot ID: 1f75baca8cc249f79c3794978bd82977
        Virtualization: vmware
      Operating System: VMware Photon/Linux
                Kernel: Linux 4.4.8
          Architecture: x86-64
  1. If the machine does not have an FQDN, set one by running hostnamectl set-hostname new-name, replacing new-name with the FQDN that you want. For example:

    hostnamectl set-hostname photon-d9ee400e194e.corp.example.com
    

    The hostnamectl status command now shows that the machine has an FQDN:

    root@photon-d9ee400e194e [ ~ ]# hostnamectl status
        Static hostname: photon-d9ee400e194e.corp.example.com
                Icon name: computer-vm
                Chassis: vm
                Machine ID: a53b414142f944319bd0c8df6d811f36
                Boot ID: 1f75baca8cc249f79c3794978bd82977
            Virtualization: vmware
        Operating System: VMware Photon/Linux
                    Kernel: Linux 4.4.8
            Architecture: x86-64
    
  2. Install Sendmail:

    tdnf install sendmail
    
  3. Verify if Sendmail is enabled:

    systemctl status sendmail
    
  4. Enable Sendmail if it is disabled and then start it:

    systemctl enable sendmail
    systemctl start sendmail
    

5.3.6 - Auditing System Events with auditd

To manage security on Photon OS, the Linux auditing service auditd is enabled and active by default on the full version of Photon OS.

The following command shows the security status:

systemctl status auditd
	* auditd.service - Security Auditing Service
	   Loaded: loaded (/usr/lib/systemd/system/auditd.service; enabled; vendor preset: enabled)
	   Active: active (running) since Fri 2016-04-29 15:08:50 UTC; 1 months 9 days ago
	 Main PID: 250 (auditd)
	   CGroup: /system.slice/auditd.service
	           `-250 /sbin/auditd -n

To help improve security, the auditd service can monitor file changes, system calls, executed commands, authentication events, and network access. After you implement an audit rule to monitor an event, the aureport tool generates reports to display information about the events.

You can use the auditctl utility to set a rule that monitors the sudoers file for changes:

auditctl -w /etc/sudoers -p wa -k sudoers_changes

This rule specifies that the auditd service must watch (-w) the /etc/sudoers file to log permissions changes (-p) to the write access (w) or attributes (a) of the file and to identify them in logs as sudoers_changes. The auditing logs appear in /var/log/audit/audit.log. You can list the auditing rules as follows:

auditctl -l
-w /etc/sudoers -p wa -k sudoers_changes

For more information on the Linux Audit Daemon, see the auditd man page:

man auditd

For more information on setting auditing rules and options, see the auditctl man page:

man auditctl

For more information on viewing reports on audited events, see the aureport man page:

man aureport

5.3.7 - Analyzing systemd Logs with journalctl

The journalctl tool queries the contents of the systemd journal.

The following command displays the messages that systemd generated the last time the machine started:

journalctl -b

The following command reveals the messages for the systemd service unit specified by the -u option:

journalctl -u auditd

In the above example, auditd is the system service unit.

For more information, see the journalctl man page by running the following command on Photon OS:

man journalctl

5.3.8 - Migrating Scripts to systemd

Although systemd maintains compatibility with init.d scripts, as a best practice, you must adapt the scripts that you want to run on Photon OS to systemd to avoid potential problems.

Such a conversion standardizes the scripts, reduces the footprint of your code, makes the scripts easier to read and maintain, and improves their robustness on a systemd system.

5.4 - Configure Wireless Networking

You can configure wireless networking in Photon OS. Connect to an open network or a WPA2 protected network using wpa_cli and configure systemd-networkd to assign an IP address to the network.

Connect Using wpa_cli

When you connect using wpa_cli, you can scan for available networks and associate the network with a network ID.

Perform the following steps:

  1. Ensure that the wpa_supplicant service is running on the WLAN interface:

    systemctl status wpa_supplicant@<wlan-interface>.service

  2. Connect to wpa_cli:

    wpa_cli -i wlan0

  3. Scan for available networks:

    scan

  4. To see the list of networks, use the following command:

    scan_results

  5. Add the network:

    add_network

    This command returns a network ID.

  6. Associate the network with the network ID.

    set_network <network ID> ssid “<ssid-name>”

  7. For a WPA2 network, set the passphrase:

    set_network <network ID> psk “<passphrase>”

  8. Enable the network:

    enable_network <network ID>

  9. Save the configuration file:

    save_config

    To exit the wpa_cli, type ‘quit`.

Assign IP Address To Network

Configure systemd-networkd to assign IP address to network. Perform the following steps:

  1. Create a /etc/systemd/network/98-dhcp-wlan.network file with the following contents:

    [Match]
    Name=wlan*
    [Network]
    DHCP=yes
    IPv6AcceptRA=no
    
  2. Restart systemd-networkd using:

    systemctl restart systemd-networkd

5.5 - Managing the Network Configuration

The network service, which is enabled by default, starts when the system boots.

5.5.1 - Commands to Manage Network Service

You manage the network service by using systemd commands, such as systemd-networkd, systemd-resolvd, and networkctl.

To check the status of the network service, run the following command:

	systemctl status systemd-networkd

Output

	* systemd-networkd.service - Network Service
	   Loaded: loaded (/usr/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled)
	   Active: active (running) since Fri 2016-04-29 15:08:51 UTC; 6 days ago
	     Docs: man:systemd-networkd.service(8)
	 Main PID: 291 (systemd-network)
	   Status: "Processing requests..."
	   CGroup: /system.slice/systemd-networkd.service
	           `-291 /lib/systemd/systemd-networkd

Because Photon OS relies on systemd to manage services, you must use the systemd suite of commands and not the deprecated init.d commands or other deprecated commands to manage networking.

5.5.2 - Using the Network Configuration Manager

The network-config-manager nmctl allows to configure and introspect the state of the network links as seen by systemd-networkd. nmctl can be used to query and configure links for Address, Routes, Gateways and also hostname, DNS, NTP or Domain. nmctl uses sd-bus, libudev APIs to interact with systemd, systemd-networkd, systemd-resolved, systemd-hostnamed, and systemd-timesyncd via dbus. nmctl uses networkd verbs to explain output. nmctl can generate configurations for required network links from YAML description. It also understands kernel command line specified in dracut network configuration format and can generate systemd-networkd configuration while the system boots and will persist between reboots.

Note: See systemd.network for more information.

nmctl is used to configure:

  • Static IPv4 and IPv6 Address, Routes, Gateway
  • DHCP type (IPv4/IPv6), DHCP4 Client Identifier, UseMTU/UseDNS/UseDomains/UseNTP/UseRoutes. LLDP, Link Local Addressing, IPv4LLRoute, LLMNR
  • DNS, Domains and NTP
  • Link MAC, MTU
  • Create netdevs, vlan, vxlan, bridge, bond, veth, macvlan/macvtap, ipvlap/ipvtap, veth, tunnels(ipip, sit, gre, sit, vti), wireguard
  • Hostname
  • Can delete and view nftables table, chains and rules.

You can use nmctl to generate network configurations from the following:

  • YAML file: nmctl can generate configurations for required network links from YAML description. Configuration written to disk under /etc/systemd/network will persist between reboots. When network-config-manager-yaml-generator.service is enabled it reads YAML files from /etc/network-config-manager/yaml and generates systemd-networkd configuration files.

    nmctl uses similar format as defined by different YAML format.

    nmctl can generate WPA Supplicant configuration from YAML file. When a YAML file with wifi configuration is found, it generates a configuration file found in /etc/network-config-manager/wpa_supplicant_photon_os.conf which is understood by wpa_supplicant.

  • Dracut kernel command line network configuration: nmctl understands kernel command line specified in dracut’s network configuration format and can generate systemd-networkd’s configuration while the system boots and will persist between reboots.

Network
       ip={dhcp|on|any|dhcp6|auto6}
           dhcp|on|any: get ip from dhcp server from all links. If root=dhcp, loop
           sequentially through all links (eth0, eth1, ...) and use the first with a valid
           DHCP root-path.

           auto6: IPv6 autoconfiguration

           dhcp6: IPv6 DHCP

       ip=<link>:{dhcp|on|any|dhcp6|auto6}
           dhcp|on|any|dhcp6: get ip from dhcp server on a specific link

           auto6: do IPv6 autoconfiguration

           This parameter can be specified multiple times.

       ip=<client-IP>:[ <server-id>]:<gateway-IP>:<netmask>:<client_hostname>:<link>:{none|off}
           explicit network configuration.

       ifname=<link>:<MAC>
           Assign network device name <link> (ie eth0) to the NIC with MAC <MAC>. Note
           letters in the MAC-address must be lowercase!  Note: If you use this option you must
           specify an ifname= argument for all links used in ip= or fcoe= arguments.  This
           parameter can be specified multiple times.

       nameserver=<IP>[nameserver=<IP> ...]
           specify nameserver(s) to use

      cat /proc/cmdline
       BOOT_IMAGE=/boot/vmlinuz-4.19.52-2.ph3-esx root=PARTUUID=ebf01b6d-7e9c-4345-93f4-122f44eb2726
       init=/lib/systemd/systemd rcupdate.rcu_expedited=1 rw systemd.show_status=0 quiet noreplace-smp
       cpu_init_udelay=0 net.ifnames=0 plymouth.enable=0 systemd.legacy_systemd_cgroup_controller=yes
       ip=dhcp

network-config-manager-generator.service is a oneshot type systemd service unit which runs while the system boots. It parses the kernel command line and generates networkd config in /etc/systemd/network:

systemctl enable network-config-manager-generator.service

It creates symlink /etc/systemd/system/network.target.wants/network-config-manager-generator.service → /usr/lib/systemd/system/network-config-manager-generator.service.

5.5.3 - Use 'ip' and 'ss' Commands

Use the ip and ss commands to view a list of network interfaces and information for IP addresses.

Although the ifconfig command and the netstat command work on Photon OS, VMware recommends that you use the ip or ss commands. The ipconfig and netstat commands are deprecated.

For example, to display a list of network interfaces, run the ss command instead of netstat. To display information for IP addresses, run the ip addr command instead of ifconfig -a.

Examples are as follows:

USE THIS IPROUTE COMMAND 	INSTEAD OF THIS NET-TOOL COMMAND
ip addr 					ifconfig -a
ss 							netstat
ip route 					route
ip maddr 					netstat -g
ip link set eth0 up 		ifconfig eth0 up
ip -s neigh					arp -v
ip link set eth0 mtu 9000	ifconfig eth0 mtu 9000

Using the ip route version of a command instead of the net-tools version often provides more complete and accurate information on Photon OS. Examples are as follows:

ip neigh
198.51.100.2 dev eth0 lladdr 00:50:56:e2:02:0f STALE
198.51.100.254 dev eth0 lladdr 00:50:56:e7:13:d9 STALE
198.51.100.1 dev eth0 lladdr 00:50:56:c0:00:08 DELAY

arp -a
? (198.51.100.2) at 00:50:56:e2:02:0f [ether] on eth0
? (198.51.100.254) at 00:50:56:e7:13:d9 [ether] on eth0
? (198.51.100.1) at 00:50:56:c0:00:08 [ether] on eth0

5.5.4 - Configuring Network Interfaces

Network configuration files for systemd-networkd reside in /etc/systemd/network and /usr/lib/systemd/network. Example:

root@photon-rc [ ~ ]# ls /etc/systemd/network/
99-dhcp-en.network

By default, when Photon OS starts, it creates a DHCP network configuration file, or rule, which appears in /etc/systemd/network, the highest priority directory for network configuration files with the lowest priority filename:

cat /etc/systemd/network/99-dhcp-en.network
[Match]
Name=e*

[Network]
DHCP=yes

Network configuration files can also appear in the system network directory, /usr/lib/systemd/network, as the results of the following search illustrate:

root@photon-rc [ ~ ]# updatedb
root@photon-rc [ ~ ]# locate systemd/network
/etc/systemd/network
/etc/systemd/network/99-dhcp-en.network
/usr/lib/systemd/network
/usr/lib/systemd/network/80-container-host0.network
/usr/lib/systemd/network/80-container-ve.network
/usr/lib/systemd/network/99-default.link
root@photon-rc [ ~ ]#

In the above search, the /usr/lib/systemd/network directory contains several network configuration files. Photon OS applies the configuration files in lexicographical order specified by the file names without regard for the network configuration directory in which the file resides unless the file name is the same. Photon OS processes files with identical names by giving precedence to files in the /etc directory over the other directory. Thus, the settings in /etc/systemd/network override those in /usr/lib/systemd/network. Once Photon OS matches an interface in a file, Photon OS ignores the interface if it appears in files processed later in the lexicographical order.

Each .network file contains a matching rule and a configuration that Photon OS applies when a device matches the rule. Set the matching rule and the configuration as sections containing vertical sets of key-value pairs according to the information in systemd network configuration.

To configure Photon OS to handle a networking use case, such as setting a static IP address or adding a name server, create a configuration file with a .network extension and place it in the /etc/systemd/network directory.

After you create a network configuration file with a .network extension, you must run the chmod command to set the new file’s mode bits to 644.

Example:

chown systemd-network:systemd-network 10-static-en.network

For Photon OS to apply the new configuration, you must restart the systemd-networkd service by running the following command:

systemctl restart systemd-networkd

For information about network configuration files, their processing order, and their matching rules, sections, and keys, see https://www.freedesktop.org/software/systemd/man/systemd.network.html.

For information about creating virtual network device files (.netdev), see https://www.freedesktop.org/software/systemd/man/systemd.netdev.html.

5.5.5 - Setting a Static IP Address

Before you set a static IP address, obtain the name of your Ethernet link by running the following command:

networkctl
IDX LINK             TYPE               OPERATIONAL SETUP
	1 lo               loopback           carrier     unmanaged
	2 eth0             ether              routable    configured

In the results of the command, you can see the name of an Ethernet link, eth0.

To create a network configuration file that systemd-networkd uses to establish a static IP address for the eth0 network interface, execute the following command as root:

cat > /etc/systemd/network/10-static-en.network << "EOF"

[Match]
Name=eth0

[Network]
Address=198.51.0.2/24
Gateway=198.51.0.1
EOF

Change the new file’s mode bits by running the chmod command:

chmod 644 10-static-en.network

Apply the configuration by running either the first or the second step:

  1. systemctl restart systemd-networkd

  2. networkctl reload networkctl reconfigure *interface_name/index_number*

Note: The advantage of using reload and reconfigure is that the settings of other interfaces are not disturbed and only the settings of the specific interface are reloaded and reconfigured.

For more information, see the man page for systemd-networkd: man systemd.network

5.5.6 - Turning Off DHCP

By default, when Photon OS first starts, it creates a DHCP network configuration file or rule, which appears in /etc/systemd/network, the highest priority directory for network configuration files with the lowest priority filename:

cat /etc/systemd/network/99-dhcp-en.network
[Match]
Name=e*

[Network]
DHCP=yes

To turn off DHCP for all Ethernet interfaces, change the value of DHCP from yes to no, save the changes, and then restart the systemd-networkd service:

	systemctl restart systemd-networkd

Or you can reload and reconfigure the settings:

networkctl reload
networkctl reconfigure <interface_name>/<index_number>`

If you create a configuration file with a higher priority filename (e.g. 10-static-en.network), it is not necessary but still recommended to turn off DHCP.

You can also check the status of a specific interface:

networkctl status <interface_name>/<index_number>

(eth0 is an example)

❯ networkctl status eth0
● 2: eth0
                     Link File: /usr/lib/systemd/network/99-default.link
                  Network File: /etc/systemd/network/50-dhcp-en.network
                         State: routable (configured)
                  Online state: online
                          Type: ether
                          Path: pci-0000:0b:00.0
                        Driver: vmxnet3
                        Vendor: VMware
                         Model: VMXNET3 Ethernet Controller
             Alternative Names: eno1
                                enp11s0
                                ens192
              Hardware Address: 00:50:56:ba:43:98 (VMware, Inc.)
                           MTU: 1500 (min: 60, max: 9000)
                         QDisc: fq_codel
  IPv6 Address Generation Mode: eui64
      Number of Queues (Tx/Rx): 1/1
              Auto negotiation: no
                         Speed: 10Gbps
                        Duplex: full
                          Port: tp
                       Address: 192.168.1.8/24 (DHCPv4 via 192.168.1.1)
                                fe80::250:56ff:feba:4398
                       Gateway: 192.168.1.1
                           DNS: 192.168.1.1
                                192.168.1.2
                                192.168.1.3
                           NTP: 192.168.1.1
                                192.168.1.2
                                192.168.1.3
                                192.168.1.4
             Activation Policy: up
           Required For Online: yes
               DHCP4 Client ID: IAID:0xb6220feb/DUID

May 04 10:37:14 photon systemd-networkd[625]: eth0: found matching network '/etc/systemd/network/50-dhcp-en.network', based on potentially unpredictable interface name.
May 04 10:37:14 photon systemd-networkd[625]: eth0: Configuring with /etc/systemd/network/50-dhcp-en.network.
May 04 10:37:14 photon systemd-networkd[625]: eth0: Link UP
May 04 10:37:14 photon systemd-networkd[625]: eth0: Gained carrier
May 04 10:37:14 photon systemd-networkd[625]: eth0: found matching network '/etc/systemd/network/50-dhcp-en.network', based on potentially unpredictable interface name.

5.5.7 - Adding a DNS Server

Photon OS uses systemd-resolved to resolve domain names, IP addresses, and network names for local applications. The systemd-resolved daemon automatically creates and maintains the /etc/resolv.conf file, into which systemd-resolved places the IP address of the DNS server. You must not modify the /etc/resolv.conf file.

Note: If you want to implement a local resolver like bind instead of systemd-resolved, stop the systemd-resolved service and disable it.

If you open the default /etc/resolv.conf file after you deploy Photon OS, it looks like this:

root@photon-rc [ ~ ]# cat /etc/resolv.conf
# This file is managed by systemd-resolved(8). Do not edit.
#
# Third party programs must not access this file directly, but
# only through the symlink at /etc/resolv.conf. To manage
# resolv.conf(5) in a different way, replace the symlink by a
# static file or a different symlink.

nameserver 198.51.100.2

To add a DNS server, insert a DNS key into the Network section of the static network configuration file, for example, /etc/systemd/network/10-eth0-static.network and set it to the IP address of your DNS server:

[Match]
Name=e*

[Network]
Address=198.51.0.2/24
Gateway=198.51.0.1
DNS=198.51.0.1

Note: To apply the changes made to /etc/systemd/network/*.network files, perform the following:

  • Restart systemd-networkd and systemd-resolved services by running the following commands:

    • systemctl restart systemd-networkd
    • systemctl restart systemd-resolved
  • Or you can reload and reconfigure the settings by running the following commands: networkctl reload networkctl reconfigure *interface_name/index_number*

Note: The advantage of using reload and reconfigure is that the settings of other interfaces are not disturbed and only the settings of the specific interface are reloaded and reconfigured.

If your machine is working with DHCP, you can add a DNS server by modifying the /etc/systemd/resolved.conf--a method.

For more information, see https://www.freedesktop.org/software/systemd/man/resolved.conf.html.

You can optionally activate the local DNS stub resolver of systemd-resolved by adding dns and resolve to the /etc/nsswitch.conf file. To do so, make a backup copy of the /etc/nsswitch.conf file and then execute the following command as root:

sed -i 's/^hosts.*$/hosts: files resolve dns/' /etc/nsswitch.conf

For more information about the systemd-resolved service, see https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html.

5.5.8 - Setting Up Networking for Multiple NICs

If your machine contains multiple NICs, it is recommend that you create a .network configuration file for each network interface. The following scenario demonstrates how to set one wired network interface to use a static IP address and another wired network interface to use a dynamic IP address obtained through DHCP.

Note: The following configurations are examples and you must change the IP addresses and other information to match your network and requirements.

First, create the .network file for the static Ethernet connection in /etc/systemd/network. A best practice is to match the exact name of the network interface, which is eth0 in this example. This example file also includes a DNS server for the static IP address. As a result, the configuration sets the UseDNS key to false in the DHCP column so that Photon OS ignores the DHCP server for DNS for this interface.

cat > /etc/systemd/network/10-eth0-static-en.network << "EOF"
[Match]
Name=eth0

[Network]
Address=10.137.20.11/19
Gateway=10.137.23.253
DNS=10.132.71.1

[DHCP]
UseDNS=false
EOF

Second, create the .network file for the second network interface, which is eth1 in this example. This configuration file sets the eth1 interface to an IP address from DHCP and sets DHCP as the source for DNS lookups. Setting the DHCP key to yes acquires an IP address for IPv4 and IPv6. To acquire an IP address for IPv4 only, set the DHCP key to ipv4.

cat > /etc/systemd/network/50-eth1-dhcp-en.network << "EOF"

[Match]
Name=eth1

[Network]
DHCP=yes  

[DHCP]
UseDNS=true
EOF

How to configure two gateways for two different NIC ?

This is an IP routing policy feature of kernel and is supported by systemd-networkd. You have to add two routes. One is for the subnet so that the IP address can find its gateway. The other route is for specifying the default gateway for that interface. Finally, we add policy route rules for that IP address that we want to use that table. This will not only ensure that the IP address you are trying to communicate with on that one interface can respond properly, but it will also ensure that you do not route information between subnets.

[Match]
Name=eth2
 
[Network]
Address=192.168.60.70/24
DHCP=no
 
[Route]
PreferredSource=192.168.60.70
Destination=192.168.60.0/24
Table=10
 
 
[Route]
Gateway=192.168.60.1
Table=10
 
[RoutingPolicyRule]
Table=10
To=192.168.60.70/24
 
[RoutingPolicyRule]
Table=10
From=192.168.60.70/24

5.5.8.1 - Combining DHCP and Static IP Addresses with IPv4 and IPv6

You can combine DHCP and static IP addresses with both IPv4 and IPv6.

Examples

The following example shows how to use DHCP to allocate both IPv4 and IPv6 addresses:

[Network]
DHCP=yes

The following example shows how to use DHCP to allocate only IPv4 addresses:

[Network]
DHCP=ipv4

The following example shows how to use DHCP to allocate only IPv6 addresses:

[Network]
DHCP=ipv6

The following example shows how to use DHCP for IPv4 addresses and static IP addresses for IPv6 addresses:

[Network]
DHCP=ipv4
Address=fd00::1/48
Gateway=fd00::252

The following example shows how to use DHCP for IPv6 addresses and static IP addresses for IPv4:

[Network]
DHCP=ipv6
Address=10.10.10.1/24
Gateway=10.10.10.253

The following example shows how to use static IP addresses for both IPv4 and IPv6:

[Network]
DHCP=ipv6
Address=10.10.10.1/24
Gateway=10.10.10.253
Address=fd00::1/48
Gateway=fd00::252

5.5.9 - Clearing the Machine ID of a Cloned Instance for DHCP

Photon OS uses the contents of /etc/machine-id to determine the DHCP unique identifier (duid) that is used for DHCP requests. If you use a Photon OS instance as the base system for cloning, to create additional Photon OS instances, you must clear the machine-id with this command:

echo -n > /etc/machine-id

When the value is cleared, machine-id can be regenerated by calling systemd-machine-id-setup.

systemd-machine-id-setup

This command initializes the machine ID stored in /etc/machine-id during installation. For more information on this command, see https://www.freedesktop.org/software/systemd/man/systemd-machine-id-setup.html.

5.5.10 - Using Predictable Network Interface Names

When you run Photon OS on a virtual machine or a bare-metal machine, the Ethernet network interface name might shift from one device to another if you add or remove a card and reboot the machine. For example, a device named eth2 might become eth1 after you remove a NIC and restart the machine.

You can prevent interface names from reordering by turning on predictable network interface names. The naming schemes that Photon OS uses can then assign fixed, predictable names to network interfaces even after you add or remove cards or other firmware and the restart the system.

When you enable predictable network interface names, you can use one of the following options to assign persistent names to network interfaces:

  • Apply the slot name policy to set the name of networking devices in the ens format with a statically assigned PCI slot number.
  • Apply the mac name policy to set the name of networking devices in the enx format a unique MAC address.
  • Apply the path name policy to set the name of networking devices in the enpXsY format derived from a device connector’s physical location.

Though Photon OS supports the onboard name policy to set the name of networking devices from index numbers given by the firmware in the eno format, the policy might result in nonpersistent names.

The option to choose depends on your use case and your unique networking requirements. For example, when you clone virtual machines and require the MAC addresses to be different from one another but the interface name to be the same, consider using ens to keep the slot the same after system reboots.

Alternatively, if the cloning function supports enx, you can use it to set a MAC address which persists after reboots.

Perform the following steps to turn on predictable network interface names:

  1. Make a backup copy of the following file in case you need to restore it later:
cp /boot/grub/grub.cfg /boot/grub/grub.cfg.original
  1. To turn on predictable network interface names, edit /boot/grub/grub.cfg to remove the following string:
net.ifnames=0Item

The string appears near the bottom of the file in the menuentry section:

menuentry "Photon" {
    linux "/boot/"$photon_linux root=$rootpartition net.ifnames=0 $photon_cmdline
    if [ "$photon_initrd" ]; then
        initrd "/boot/"$photon_initrd
    fi
}
# End /boot/grub2/grub.cfg

Edit out net.ifnames=0, but make no other changes to the file, and then save it.

  1. Specify the types of policies that you want to use for predictable interface names by modifying the NamePolicy option in /lib/systemd/network/99-default.link. The file contents are as follows:
cat /lib/systemd/network/99-default.link
[Link]
NamePolicy=kernel database
MACAddressPolicy=persistent

To use the ens or enx option, the slot policy or the mac policy can be added to the space-separated list of policies that follow the NamePolicy option in the default link file, /lib/systemd/network/99-default.link. The order of the policies matters. Photon OS applies the policy listed first before proceeding to the next policy if the first one fails.

For example:

/lib/systemd/network/99-default.link
    [Link]
    NamePolicy=slot mac kernel database
    MACAddressPolicy=persistent

With the name policy specified in the above example, you might still have an Ethernet-style interface name if the two previous policies, slot and mac, fail.

For information on setting name policies, see systemd.link–network device configuration.

5.5.11 - Inspecting the Status of Network Links with 'networkctl'

You can inspect information about network connections by using the networkctl command. This can help you configure networking services and troubleshoot networking problems.

You can progressively add options and arguments to the networkctl command to move from general information about network connections to specific information about a network connection.

networkctl Command Without Options

Run the networkctl command without options to default to the list command:

networkctl
IDX LINK             TYPE               OPERATIONAL  SETUP
  1 lo               loopback           carrier      unmanaged
  2 eth0             ether              routable     configured
  3 docker0          ether              routable     unmanaged
  11 vethb0aa7a6     ether              degraded     unmanaged
  4 links listed.

’networkctl status’ Command

Run networkctl with the status command to display the following information:

root@photon-rc [ ~ ]# > networkctl status
   State: routable
  Address: 10.197.103.56 on eno1
           172.17.0.1 on docker0
           fe80::20c:29ff:fe44:f92c on eno1
  Gateway: 10.197.103.253 (Cisco Systems, Inc) on eno1
      DNS: 10.142.7.1
           10.132.7.1
           10.166.17.90
      NTP: 10.128.152.81
           10.166.1.120
           10.188.26.119
           10.84.55.42

You can see that there are active network links with IP addresses for not only the Ethernet connection but also a Docker container.

You can add a network link, such as the Ethernet connection, as the argument of the status command to show specific information about the link:

	root@photon-rc [ ~ ]# networkctl status ens33
	* 2: ens33
	         Link File: /usr/lib/systemd/network/99-default.link                                      
                  Network File: /usr/lib/systemd/network/10-eth.network                                       
                          Type: ether                                                                         
                         State: routable (configured)                               
             Alternative Names: enp2s1                                                                        
                          Path: pci-0000:02:01.0                                                              
                        Driver: e1000                                                                         
                        Vendor: Intel Corporation                                                             
                         Model: 82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter)
                    HW Address: 00:0c:29:5f:d1:39 (VMware, Inc.)                                              
                           MTU: 1500 (min: 46, max: 16110)                                                    
                         QDisc: fq_codel                                                                      
  IPv6 Address Generation Mode: eui64                                                                         
          Queue Length (Tx/Rx): 1/1                                                                           
              Auto negotiation: yes                                                                           
                         Speed: 1Gbps                                                                         
                        Duplex: full                                                                          
                          Port: tp                                                                            
                       Address: 172.16.85.225 (DHCP4 via 172.16.85.254)                                       
                                fe80::20c:29ff:fe5f:d139                                                      
                       Gateway: 172.16.85.2 (VMware, Inc.)                                                    
                           DNS: 172.16.85.2                                                                   
               DHCP4 Client ID: IAID:0x2b9434c1/DUID                                                          
             DHCP6 Client DUID: DUID-EN/Vendor:0000ab11d258482fc7eee6510000                                   
Feb 26 10:19:44 photon systemd-networkd[650]: ens33: Link UP
Feb 26 10:19:44 photon systemd-networkd[650]: ens33: Gained carrier
Feb 26 10:19:45 photon systemd-networkd[650]: ens33: DHCPv4 address 172.16.85.225/24 via 172.16.85.2
Feb 26 10:19:46 photon systemd-networkd[650]: ens33: Gained IPv6LL

’networkctl status’ Command With Docker Option

You can add a Docker container as the argument of the status command to show specific information about the container:

networkctl status docker0
	* 3: docker0
	       Link File: /usr/lib/systemd/network/99-default.link
	    Network File: n/a
	            Type: ether
	           State: routable (unmanaged)
	          Driver: bridge
	      HW Address: 02:42:f0:f7:bd:81
	             MTU: 1500
	         Address: 172.17.0.1
	                  fe80::42:f0ff:fef7:bd81

In the example above, the state of the Docker container is unmanaged because Docker handles managing the networking for the containers without using systemd-resolved or systemd-networkd. Docker manages the container connection by using its bridge drive.

For more information about networkctl commands and options, see https://www.freedesktop.org/software/systemd/man/networkctl.html.

5.5.12 - Turning On Network Debugging

You can set systemd-networkd to work in debug mode so that you can analyze log files with debugging information to help troubleshoot networking problems.

You can turn on network debugging by adding a drop-in file in /etc/systemd to customize the default systemd configuration in /usr/lib/systemd.

Procedure

  1. Run the following command as root to create a directory with the name systemd-networkd.service.d, including the .d extension:

    systemctl edit systemd-networkd.service
    
  2. Add following configuration in the file override.conf to establish a systemd drop-in unit with a debugging configuration for the network service:

    	[Service]
    	Environment=SYSTEMD_LOG_LEVEL=debug
    
  3. Reload the systemctl daemon and restart the systemd-networkd service for the changes to take effect:

    systemctl daemon-reload
    systemctl restart systemd-networkd
    
  4. Verify your changes:

    systemd-delta --type=extended
    
  5. View the log files by running this command:

    journalctl -u systemd-networkd
    
  6. After debugging the network connections, turn debugging off by deleting the drop-in file:

    rm /etc/systemd/system/systemd-networkd.service.d/10-loglevel-debug.conf
    

5.5.13 - Installing packages for 'tcpdump' and 'netcat'

Photon OS includes the following networking tools:

  • tcpdump. A networking tool that captures and analyzes packets on a network interface. tcpdump is not available with the minimal version of Photon OS but available in the repository. The minimal version includes the iproute2 tools by default.

    You can install tcpdump and its accompanying package libpcap, a C/C++ library for capturing network traffic, by using tdnf:

tdnf install tcpdump
  • netcat. A tool to send data over network connections with TCP or UDP. This tool is not included in either the minimal or the full version of Photon OS. But since netcat furnishes powerful options for analyzing, troubleshooting, and debugging network connections, you might want to install it. To install `netcat’, run the following command:
tdnf install netcat

5.5.14 - Mounting a Network File System

To mount a network file system, Photon OS requires nfs-utils. The nfs-utils package contains the daemon, userspace server, and client tools for the kernel Network File System (NFS). The tools include mount.nfs, umount.nfs, and showmount.

The nfs-utils package is installed by default in the full version of Photon OS but not in the minimal version. To install nfs-utils in the minimal version, run the following command as root:

tdnf install nfs-utils

For instructions on how to use nfs-utils to share files over a network, see Photon OS nfs-utils.

5.5.15 - Configuring a Secondary Network Interface using Cloud-Network

When you add a secondary network interface to a linux instance in the cloud environment, you need to configure the network parameters for the secondary interface in the linux instance. The configuration ensures that you do not face any routing issues while using the secondary network interface. Configuring the secondary network interface involves several manual processes that include configuring a new routing table, setting up rules in the routing table and so on.

cloud-network automates the whole manual process of configuring the secondary network interface. It configures the network parameters required for any network interfaces that you create or add to the linux instance. In a cloud environment, instances are set to public IPs and private IPs. If you add more than one private IP for the secondary network interface, the IP other than the one provided by DHCP cannot be fetched and configured for your virtual machine. The cloud-network project is designed to adapt the cloud-network environments such as Azure, GCP, and Amazon EC2. cloud-network fetches the metadata from the metadata server endpoint, parses the metadata, and then assigns IPs and routes. When cloud-network is installed, it automatically configures network interfaces in the cloud frameworks. It detects the available interfaces using netlink. Additionally, for all the interfaces, including the primary one, it looks for any secondary IP addresses from the metadata server endpoint and configures them on the interface, if any.

A local RESTful JSON server runs on the address 127.0.0.1:5209 and the instance metadata is saved on per link basis in the following directory: /run/cloud-network.

The network parameters in the cloud framework are checked periodically for any changes, and in case of a change, the interface is reconfigured accordingly.

The image below illustrates the communication of cloud-network and the instance metadata server:

Cloud Network tool communicating with the IMDS


Use Case: Making a secondary network interface work in a cloud instance.

This functionality is scattered across different scripts/tools that are cloud provider dependent. cloud-network provides a cloud-agnostic mechanism to retrieve the metadata like network parameters, and configure the interfaces. This means that there is no need to manually edit and update the configuration when there are changes in the network parameters. cloud-network automatically configures the interfaces since it has the metadata information.

The image below illustrates how cloud-network fetches the network parameters to configure the secondary network interface (eth1) in a cloud instance:

Cloud Network tool configuring the secondary network instance


Installing Cloud Network Setup

Type the following command to install cloud network in your system:

tdnf install cloud-network-setup


Configuration

To manage the configuration, use the configuration file named cloud-network.toml located in the following directory: /etc/cloud-network/

[System] Section

You can set values for the following keys in the [System] section:

LogLevel=
Specifies the log level. The key takes one of the following values: Trace, Debug, Info, Warning, Error, Fatal and Panic. Default is info.

LogFormat=
Specifies the log format. The key takes one of the following values: text or JSON. Takes one of text or json, Default is text.

RefreshTimer=
Specifies the time interval. The time interval indicates the amount of time taken to retrieve the data from the metadata endpoint.

[Network] Section

You can set values for the following keys in the [Network] section:

Listen=

Specifies the IP address and the port that the local REST API server listens. You can specify the IP address and the port in the following format ip:port. Defaults is 127.0.0.1:5209.

Supplementary=
A whitespace-separated list of interfaces matching the device name. Specifies the interfaces you want to configure with a default gateway and routing policy rules for each IP address including the primary IP address. No default value is set for this key.

Note When there are multiple interfaces, the secondary interface becomes unreachable. When you set a value for Supplementary= key, the default route and routing policy rules are automatically configured.


The following example shows a sample configuration of the key values in the cloud-network.toml file:

> cat /etc/cloud-network/cloud-network.toml
[System]
RefreshTimer="300s"
LogLevel="info"
LogFormat="text"

[Network]
Listen="127.0.0.1:5209"
Supplementary="eth0"

After you set the configuration, use the sudo systemctl status cloud-network command to check the network status of the cloud-network service. Following example shows the command output of the sudo systemctl status cloud-network command:

❯ > sudo systemctl status cloud-network
● cloud-network.service - Configures network in cloud enviroment
     Loaded: loaded (/usr/lib/systemd/system/cloud-network.service; disabled; vendor preset: enabled)
     Active: active (running) since Mon 2021-05-31 22:54:50 UTC; 3min 31s ago
   Main PID: 19754 (cloud-network)
      Tasks: 5 (limit: 4400)
     Memory: 8.7M
     CGroup: /system.slice/cloud-network.service
             └─19754 /usr/bin/cloud-network

May 31 22:54:50 zeus-final-2 systemd[1]: Started Configures network in cloud enviroment.

cnctl

Use the cnctl CLI tool to view the metadata that is retrieved from the endpoint metadata server. The Following examples show the output of the cnctl status command for the network and system:

❯ cnctl status system
    Cloud provider: aws
             AmiID: ami-005f15863xxxxxxxx  
          Location: 0
BlockDeviceMapping: Ami:xvda Root:/dev/xvda
          Hostname: Zeus.us-west-2.compute.internal
    PublicHostname: Zeuspublic.us-west-2.compute.amazonaws.com
     LocalHostname: Zeus.us-west-2.compute.internal
    InstanceAction: none
    InstanceID: i-0c8c1test
 InstanceLifeCycle: on-demand
      InstanceType: t4g.micro
         Placement: AvailabilityZone:us-west-2d AvailabilityZoneID:usw2-az4 Region:us-west-2
           Profile: default-hvm
       Mac Address: 0e:c5:3f:c5:33:a5
         LocalIpv4: 192.31.63.114
        PublicIpv4: 02:42:8d:4c:0c:cf
   Services Domain: amazonaws.com
Services Partition: aws  

❯ cnctl status network
            Name: ens33
     MAC Address: 00:0c:29:5f:d1:39
       Public IP: 104.42.20.194
      Private IP: 10.0.0.4/24 10.0.0.6/24 10.0.0.7/24
          Subnet: 10.0.0.0

5.5.16 - Using Network Event Broker

network-event-broker is a daemon that configures network and executes scripts on network events such as systemd-networkd’s DBus events, dhclient lease gains, and so on.

network-event-broker also detects the following events:

  • An IP address is added/removed/modified
  • A link is added or removed

In the /etc/network-event-broker directory, network-event-broker creates the link state directories such as carrier.d, configured.d, degraded.d, no-carrier.d, routable.d and manager state directory such as manager.d . You can also keep the executable scripts in these directories.

Use Case: Running command when a new address is acquired via DHCP.

  1. systemd-networkd: systemd-networkd’s scripts are executed when the daemon receives the relevant event from systemd-networkd.

     May 14 17:08:13 Zeus cat[273185]: OperationalState="routable"  
     May 14 17:08:13 Zeus cat[273185]: LINK=ens33
    
  2. dhclient: For dhclient, scripts are executed in the routable.d directory when dhclient modifies the /var/lib/dhclient/dhclient.leases file and lease information is passed to the scripts as environmental arguments.

Environment variables such as LINK, LINKINDEX= and DHCP lease information DHCP_LEASE= are passed to the scripts.

Configuration

To manage the network-event-broker configuration, use the configuration file named network-broker.toml located in the following directory: /etc/network-broker/

[System] section

You can set values for the following keys in the [System] section:

LogLevel=
Specifies the log level. The key takes one of the following values: info, warn, error, debug and fatal. Default is info.

Generator=
Specifies the network event generator source. The key takes one of the following values: systemd-networkd or dhclient. Default is systemd-networkd.

[Network] section

You can set values for the following keys in the [Network] section:

Links=
A whitespace-separated list of links whose events should be monitored. No default value is set for this key.

RoutingPolicyRules=
A whitespace-separated list of links for which you want to configure the routing policy rules per address. When you set this configuration, network-event-broker automatically adds the to and from routing policy rules in another routing table (ROUTE_TABLE_BASE = 9999 + ifindex). When these addresses are removed, the routing policy rules are dropped. No default value is set for this key.

UseDNS=
Specifies whether you want to send the DNS server details to systemd-resolved. The key takes one of the following values: true, false. When set to true, the DNS server details are sent to systemd-resolved via DBus. This is applicable only to the DHClient. Default is false.

UseDomain=
Specifies whether you want to send the DNS domain details to systemd-resolved. The key takes one of the following values: true, false. When set to true, the DNS domain details are sent to systemd-resolved via DBus. This is applicable only to the DHClient. Default is false.

UseHostname=
Specifies whether you want to send the host name to systemd-hostnamed. The key takes one of the following values: true, false. When set to true, the host name is sent to systemd-hostnamed via DBus. This is applicable only to the DHClient. Default is false.

The following example shows a sample configuration of the key values in the network-broker.toml file:

❯ sudo cat /etc/network-broker/network-broker.toml 
[System]
LogLevel="debug"
Generator="dhclient"

[Network]
Links="ens33 ens37"
RoutingPolicyRules="ens33 ens37"
UseDNS="true"
UseDomain="true"

5.5.17 - Configuring a Network Using Network Configuration Manager

You can use network-configuration-manager to configure a network in Photon OS. The YAML-based configuration system in network-config-manager makes the network configuration easy and simple.

The following sections in the document demonstrate the configuration of a network in Photon OS using network-config-manager.

You can find the YAML network configuration files at the following location:

/etc/network-config-manager/yaml/ 

When you install network-configuration-manager, it generates the network-config-manager configuration file for systemd-networkd named 99-dhcp.yaml.example.

Perform the following steps to configure static or dynamic IP addressing in Photon OS:

  1. To find the name of the active network interfaces that you want to configure, execute the following command:
❯ ip a   
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:5f:d1:39 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.1.4/24 metric 1024 brd 192.168.1.255 scope global dynamic ens33
       valid_lft 82465sec preferred_lft 82465sec
    inet6 fe80::20c:29ff:fe5f:d139/64 scope link 
       valid_lft forever preferred_lft forever

Note the name of the interface that you want to configure using network-config-manager.

  1. To find the network-configuration-manager default configuration file, execute the following command:

    ❯ ls /etc/network-config-manager/yaml
    
  2. To view the content of the network-config-manager network configuration file, execute the following command:

    ❯ cat /etc/network-config-manager/yaml/*.yaml
    
  3. Open the configuration file in an editor.
    For example, if you use vim editor, execute the following command to open the configuration file in an editor:

    ❯ sudo vim /etc/network-config-manager/yaml/99-dhcp.yaml
    
  4. Use the following syntax to update the configuration file as per your networking needs:

    network:
    Version: 2
    Renderer: networkd
    ethernets:
       device:
          dhcp4: yes/no
          nameservers:
             addresses: [NAMESERVER, NAMESERVER, ...]
          addresses: [IPADDRESS/PREFIX]
           routes:
          - to: DESTINATION
            via: GATEWAY
    

    Note that for static IP addressing, add the IP address, Gateway, and DNS details. For dynamic IP addressing, you need not add these details as it is fetched from the DHCP server.

    The following table describes the properties used in the syntax to update the configuration file.

    PropertiesDescription
    device: |Name of the interface.
    dhcp4: |yes or no depending upon dynamic or static IP addressing
    addresses: |IP address of the device in prefix notation.
    routes: to: destination via: |gateway IP address to connect to an outside network
    nameservers: |Address of DNS name servers

Note: It is recommended that you use spaces for indentation instead of tabs in the YAML configuration file. If you use a tab instead of spaces for indentation, you might encounter errors.

Configuring static IP address in Photon OS

To manually configure an IP address, use the previously mentioned file syntax in this topic, and add the IP address, Gateway, and DNS server details.

The following is a sample configuration for the static IP addressing:

network:
    ethernets:
        eth0:
            dhcp4: false
            addresses: [192.168.1.202/24]
            nameservers:
              addresses: [8.8.8.8,8.8.4.4,192.168.1.1]
            routes:
            - to: 172.16.0.0/24
              via: 192.168.1.100

Configure Dynamic IP address in Photon OS

To get the IP address from the DHCP server, use the previously mentioned file syntax in this topic. You need not add the IP address, Gateway, and DNS server details here.

The following is a sample configuration for the dynamic IP addressing:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: true

After configuring the IP address, you need to apply the new configuration. Execute the following command as sudo to apply the configuration:

$ sudo nmctl apply

To verify that the configurations are successfully applied, execute the following command and verify the IP address:

❯ nmctl status eth0
                       Flags: UP BROADCAST RUNNING NOARP LOWERUP 
                        Kind: dummy
                        Type: ether
                      Driver: dummy
                   Link File: /usr/lib/systemd/network/99-default.link
                Network File: /etc/systemd/network/10-eth0.network
                       State: routable (configured) 
               Address State: routable
          IPv4 Address State: routable
          IPv6 Address State: degraded
                Online State: online
         Required for Online: yes
           Activation Policy: up
                  HW Address: 56:d3:b9:4f:03:38 ((null))
                         MTU: 1500 (min: 0 max: 0) 
                       QDISC: noqueue 
              Queues (Tx/Rx): 1/1 
             Tx Queue Length: 1000 
IPv6 Address Generation Mode: eui64 
                GSO Max Size: 65536 GSO Max Segments: 65535 
                     Address: fe80::54d3:b9ff:fe4f:338/64
                              192.168.1.202/24
                     Gateway: 192.168.1.100
                         DNS: 8.8.4.4 192.168.1.1 8.8.8.8
           DHCP6 Client DUID: DUID-EN/Vendor:0000ab11d258482fc7eee6510000

To see the routes, execute the following command:

❯ ip r show dev eth0
172.16.0.0/24 via 192.168.1.100 proto static 

5.6 - Prioritize eth0 Route Over WLAN

You can prioritise the eth0 route over the WLAN route. Perform the following steps:

  1. Modify the /etc/systemd/network/99-dhcp-en.network file and add the following content:

    [DHCP]
    RouteMetric=512
    
  2. Restart systemd-networkd.

5.7 - Configuring Photon Real-Time Operating System for Real-Time Applications

Photon Real-Time (RT) Operating System (OS) (and the Linux kernel PREEMPT_RT patchset that it is based on) is optimized to support low-latency real-time scheduling and minimize the OS jitter as observed by real-time applications. However, to get the most out of Photon RT OS, it is must to have a proper system configuration. To run low-latency real time applications effectively, the sources of jitter have to be identified and eliminated across all layers of the underlying system, spanning the BIOS / firmware, the hypervisor, and the guest operating system (Photon RT).

BIOS/Firmware

Tuning a system for real time operation starts from the lowest layers of the software stack, namely the System BIOS or Platform Firmware. The goal is to configure the settings for the following functions:

  • Maximize Performance Ex: Set CPU, memory and device power management modes to maximum performance, disable CPU idle states

  • Minimize Computational Jitter Ex: Disable Turbo Boost, disable Hyper-Threading

  • Minimize System Management Interrupts Ex: Disable options such as Processor Power and Utilization Monitoring, memory Pre-Failure Notification, and so on

Platform vendors often publish low-latency tuning guides for their BIOS/firmware. Refer documentation to learn about the recommended low-latency settings specific to your platform.

Deploying Real-Time Applications on Photon Real-Time Operating System

A general strategy to deploy real-time applications on Photon RT is described as follows:

  • Partition CPUs between the OS and the RT workload: Among the available CPUs in the system, isolate a subset of CPUs, designated to run the RT workload. By default, the Linux scheduler will only run tasks on non-isolated CPUs, leaving the isolated CPUs to those tasks that are explicitly bound to them. Thus, all the housekeeping tasks of the OS will execute on non-isolated CPUs (with a few exceptions, such as per-CPU kernel threads). Then bind the RT workload to the isolated CPUs.

  • Steer unrelated interrupts away from the CPUs running the RT workload: Linux supports the ability to affine most interrupts to specific CPUs in the system. By using this mechanism, interrupts that are not relevant to the real-time workload can be affined to non-isolated CPUs, thus avoiding the jitter caused by interrupt handling latency on the isolated CPUs.

This strategy provides two important benefits:

  1. It limits OS interference with the RT workload.

  2. It protects the OS services from getting starved by the CPU-intensive RT tasks.

This configuration can be achieved using a combination of kernel command-line options, and user space packages, as discussed in the following sections.

Kernel Command-Line Parameters

  • CPU isolation

    isolcpus=X,Y-Z (Ex: isolcpus=2,4-5)

  • Interrupt affinity

    irqaffinity=X,Y-Z (Ex: irqaffinity=0-1,3) [ Usually it is the inverse of isolcpus.]

  • RCU callbacks

rcu_nocbs=X,Y-Z [ Usually it is same as isolcpus. ] rcu_nocb_poll=1

  • NOHZ (Eliminating the periodic timer)

    nohz=on nohz_full=X,Y-Z [ Usually it is same as isolcpus. ]

  • CPU idle

    idle=halt or idle=poll intel_idle.max_cstate=0 cpuidle.off=1

  • CPU frequency

    intel_pstate=disable

  • Lockup detectors

    nosoftlockup nowatchdog nmi_watchdog=0

  • Timer skew detection

      skew_tick=1
      clocksource=tsc
      tsc=reliable
    

The full list of kernel command-line parameters and their descriptions are available at https://www.kernel.org/doc/html/v6.1/admin-guide/kernel-parameters.html

Tuned configuration

Tuned is a system tuning daemon that offers several profiles to tailor the OS to various usecases, including a ‘realtime’ profile for low-latency workloads.

The realtime tuned profile can be applied as shown below:

  • tdnf install tuned

  • systemctl enable tuned

  • systemctl start tuned

Add isolcpus to /etc/tuned/realtime-variables.conf (by uncommenting the isolated_cores= parameter):

$ cat /etc/tuned/realtime-variables.conf

Examples:

# isolated_cores=2,4-7

Note: The cores configured as isolated in tuned should be consistent with isolcpus in the kernel command-line.

tuned-adm profile realtime

Stalld configuration

The stalld daemon monitors the system for starved tasks and revives them by giving them a temporary boost using the SCHED_DEADLINE policy. stalld offers fine-grained controls to give starved tasks a user-specified amount of CPU time.

The stalld configuration file is /etc/sysconfig/stalld.

The key parameters are Starving Threshold (THRESH), Boost Period (BP), Boost Runtime (BR), and Boost Duration (BD).

The mode of operation is as follows:

If a task is starved for at least THRESH seconds, it is scheduled using SCHED_DEADLINE scheduling policy, so that it will run at least BR nanoseconds in every BP nanoseconds time period, and this repeats up to BD seconds, after which the task gets back its original scheduler policy/priority settings.

Real Time Scheduling Policies

The Linux kernel offers several scheduling policies to support various applications, among which the real time policies are highlighted below:

  • SCHED_OTHER (default policy), SCHED_BATCH, SCHED_IDLE (non real-time policies)

  • SCHED_FIFO (First-In First-Out Real Time Scheduling)

  1. Priority Range: 1 to 99 (highest)

  2. Algorithm: The scheduler runs the highest-priority runnable task in the SCHED_FIFO scheduling class, until it yields (blocks/waits) the CPU voluntarily.

  • SCHED_RR (Round-Robin Real Time Scheduling)
  1. Priority Range: 1 to 99 (highest)

  2. Algorithm: The scheduler runs the highest-priority SCHED_RR task, and time-slices between equal-priority SCHED_RR tasks in configurable intervals.

  • SCHED_DEADLINE ( Earliest Deadline First Real Time Scheduling)
  1. Key parameters: Runtime, Period and Deadline, which can be configured on a per-task basis.

  2. Algorithm: The scheduler gives a SCHED_DEADLINE task at least Runtime amount of time on the CPU in every Period time period, before Deadline time is up.

Real Time Throttling

The Linux kernel offers proc file system (procfs) controls to influence real-time task scheduling and throttling.

The RT throttling algorithm is as follows:

  • All real-time tasks are throttled to run up to runtime microseconds, in every period microseconds. The remaining time in period microseconds is used to run non-RT tasks in the system.

  • runtime and period values can be configured by writing to the files listed as follows:

  1. /proc/sys/kernel/sched_rt_runtime_us Default: 95% (950000) Range: -1 to (INT_MAX -1) [ -1 implies no limit, i.e., no throttling ]

  2. /proc/sys/kernel/sched_rt_period_us Default: 1s (1000000) Range: 1 to INT_MAX

Note: See Command Line Reference for the commands for manipulating real-time properties of processes.

5.8 - Containers

A container is a process that runs on the Photon OS host with its own isolated application, file system, and networking.

Photon OS includes the open source version of Docker. With Docker, Photon OS becomes a Linux run-time host for containers, that is, a Linux cloud container.

The full version of Photon OS includes Kubernetes so you can manage clusters of containers.

5.8.1 - Docker Containers

On Photon OS, the Docker daemon is enabled by default. To view the status of the daemon, run the following command:

systemctl status docker

Docker is loaded and running by default on the full version of Photon OS. On the minimal version, it is loaded but not running by default. To start it, run the following command:

systemctl start docker

To obtain information about Docker, run the following command as root:

docker info

After Docker is enabled and started, you can create a container. For example, run the following docker command as root to create a container running Ubuntu 14.04 with an interactive terminal shell:

docker run -i -t ubuntu:14.04 /bin/bash

Photon OS also enables you to run a docker container that runs Photon OS:

docker run -i -t photon /bin/bash

5.8.2 - Docker Rootless Support

Run the Docker daemon as a non-root user (Rootless mode)

The Rootless mode allows you to run the Docker daemon and containers as a non-root user. This mitigates the potential vulnerabilities in the daemon and the container runtime.

As long as the prerequisites are met, rootless mode does not require root privileges even during the installation of the Docker daemon.

After its introduction in Docker Engine v19.03 as an experimental feature, the rootless mode was available in Docker Engine v20.10 as a more stable feature.

This feature is available in Photon OS 4.0 and above versions starting from the docker-20.10.14-1 version (in Ph4).

Prerequisites:

  • You must install newuidmap and newgidmap on the host. - Provided by the shadow package in Photon

  • /etc/subuid and /etc/subgid should contain at least 65,536 subordinate UIDs/GIDs for the user. In the following example, the user called testuser has 65,536 subordinate UIDs/GIDs (100000-165535).

  • You can install the pre-required packages using the following command:

    tdnf install -y shadow fuse slirp4netns libslirp
    
  • Photon 3 or above with docker-20.10.14-1 version (this version is specific to Ph4. For higher versions please refer spec file in the Photon source).

Usage:

You can perform the following tasks with the respective commands for them:

  1. Install docker-rootless using the following command:

    tdnf install -y docker-rootless
    
  2. Use the following command to add a new user:

    useradd -m test_user
    
  3. Use the following command to set a password for the new user:

    passwd test_user
    
  4. Use the following command to log in as the user you created:

    `ssh test_user@localhost`
    
  5. Run the following command:

    dockerd-rootless-setuptool.sh --help`
    

    The above command shows something like the following output:

    test_user@photon [ ~ ]$ dockerd-rootless-setuptool.sh --help
    Usage: /usr/bin/dockerd-rootless-setuptool.sh [OPTIONS] COMMAND
    
    A setup tool for Rootless Docker (dockerd-rootless.sh).
    
    Documentation: https://docs.docker.com/go/rootless/
    
    Options:
    -f, --force Ignore rootful Docker (/var/run/docker.sock)
    --skip-iptables Ignore missing iptables
    
    Commands:
    check Check prerequisites
    install Install systemd unit (if systemd is available) and show how to manage the service
    uninstall Uninstall systemd unit
    
  6. Run the following command, and then check and fix the errors and warnings, if any:

    dockerd-rootless-setuptool.sh`
    

    Run the following commands:

    a. echo "test_user:100000:65536" >> /etc/subuid

    b. echo "test_user:100000:65536" >> /etc/subgid

    c. echo "kernel.unprivileged_userns_clone = 1" >> /etc/sysctl.d/50-rootless.conf

    d. chmod 644 /etc/subuid /etc/subgid /etc/sysctl.d/50-rootless.conf

    e. sysctl --system

    After you run the above commands, the dockerd-rootless-setuptool.sh check shows the following output:

    test_user@photon [ ~ ]$ dockerd-rootless-setuptool.sh check
    
    [INFO] Requirements are satisfied
    
  7. After the Requirements are satisfied message appears, run the following command:

    dockerd-rootless-setuptool.sh install
    
  8. Carefully, go through the output messages of the above command and ensure that everything is fine. Follow the instructions that appear, if any.

  9. Add the following to your .bashrc or .bash_profile:

    export PATH=/usr/bin:$PATH
    export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
    

Now, you can run docker run -it photon as a regular user.

Limitations:

Exposing Network Ports Be aware that port numbers below 1024 are called privileged ports and are not available for rootless users. So, you need to use the unprivileged ports such as 8080, and so on. If you want to run an HTTP server, you need to run docker run -p 8080:80. However, if you really need to expose privileged ports, you can do that by adjusting sysctl /proc/sys/net/ipv4/ip_unprivileged_port_start or by setting CAP_NET_BIND SERVICE capability on the binary rootlesskit.

Limiting Resources such as CPU, Memory

Limiting resources with cgroup-related docker run flags such as --cpus, --memory, --pids-limit is supported only while running with cgroup v2 and systemd.

If docker info shows none as Cgroup Driver, the conditions are not satisfied. When these conditions are not satisfied, rootless mode ignores the cgroup-related docker run flags.

5.8.3 - Kubernetes

The Kubernetes package provides several services: kube-apiserver, kube-scheduler, kube-controller-manager, kubelet, kube-proxy. These services are managed by systemd. Their configuration resides in a central location: /etc/kubernetes.

For more information, see Running Kubernetes on Photon OS.

5.8.4 - Support for distributed builds using Kubernetes

The distributed system using Kubernetes allows the build system to utilize the maximum CPU power across a kubernetes cluster (pods) for faster build process.

Prerequisites

  • Ensure that the NFS server is running
  • Ensure that you have the Kubernetes cluster ready that has access to the NFS server
  • Ensure that you have installed Kubernetes package and have kubeconfig accessible in the build VM.

Triggering Distributed Photon Builds

Perform the following steps in the Photon OS repository:

  1. Update the 'common/data/distributed_build_options.json' configuration file . The following parameters need to be filled:
  • command→ target to run like 'make packages' or 'make packages-minimal' or 'make toolchain-stage-1' or so on. Note: Keep the command with flag 'SCHEDULER_SERVER=enable'.

  • nfs-server-ip→ IP address of the nfs server

  • pods→ number of builder/worker pods you want such as 10 or 20. The default value is 1.

  • nfs-server-path-> path of the nfs mount. For example,/mnt/NFS_PATH/MY_DIR

  1. Run make distributed-build.

Note:

  • This process will make use of the kubeconfig file present under the home directory and start building packages over the specified cluster.
  • It creates one Master pod and multiple worker pods (numbers defined in config.json).
  • The master pod runs the scheduler while the worker or the builder pods build the packages.
  • Distributed Builder monitors the build mob and deletes everything when build has either completed successfully or failed.

The master starts the scheduler server to schedule the packages that have to be built. The worker makes REST calls to scheduler server.get package and notify after the build.

The distributed build also builds cloud images.

5.9 - Changing the Locale

You can change the locale if the default locale does not meet your requirements.

To find the locale, run the the localectl command:

localectl
System Locale: LANG=en_US.UTF-8
   VC Keymap: n/a
  X11 Layout: n/a

To change the locale, choose the languages that you want from /usr/share/locale/locale.alias, add them to /etc/locale-gen.conf, and then regenerate the locale list by running the following command as root:

locale-gen.sh

Finally, run the following command to set the new locale, replacing the example (en_US.UTF-8) with the locale that you require:

localectl set-locale LANG="de_CH.UTF-8" LC_CTYPE="de_CH.UTF-8"

Changing the keyboard layout

See which keymaps are currently available on your system:

localectl list-keymaps

If the response to that command is the all-too-common Couldn't find any console keymaps, install the key tables files and utilities:

tdnf install kbd

You should now be able to find a keymap matching your keyboard. As an example, here I’m searching for the German keyboard layout (so I’m expecting something with de in the name) used in Switzerland:

localectl list-keymaps | grep de
    ...
    de-latin1
    de-latin1-nodeadkeys
    de-mobii
    de_CH-latin1
    de_alt_UTF-8
    ...

de_CH-latin1 seems to be what we’re looking for, so change your current layout to that keymap:

localectl set-keymap de_CH-latin1

and confirm that the change has been made:

localectl
System Locale: LANG=de_CH.UTF-8
   VC Keymap: de_CH-latin1
  X11 Layout: n/a

Note: Photon OS comes with a minimal set of locales by default. If you need a full set of locales, you need to install the glibc-i18n package using the following command:

tdnf install -y glibc-i18n

5.10 - Cloud-Init on Photon OS

The minimal and full versions of Photon OS include the cloud-init service as a built-in component. Cloud-init is a set of Python scripts that initialize cloud instances of Linux machines. The cloud-init scripts configure SSH keys and run commands to customize the machine without user interaction. The commands can set the root password, create a hostname, configure networking, write files to disk, upgrade packages, run custom scripts, and restart the system.

5.10.1 - Cloud-Init Overview

cloud-init is a multi-distribution package that handles early initialization of a cloud instance.

In-depth documentation for cloud-init is available here:

https://cloudinit.readthedocs.org/en/latest/

Supported installations

Both the full version of and the minimal version of Photon OS support cloud-init.

Supported capabilities

Photon OS supports the following cloud-init capabilities:

  • run commands: execute a list of commands with output to console.
  • configure ssh keys: add an entry to ~/.ssh/authorized_keys for the configured user.
  • install package: install additional packages on first boot.
  • configure networking: update /etc/hosts, hostname, etc.
  • write files: write arbitrary files to disk.
  • add tdnf repository: add a tdnf repository to /etc/yum.repos.d.
  • create groups and users: add groups and users to the system and set properties for them.
  • run tdnf upgrade: upgrade all packages.
  • reboot: reboot or power off when done with cloud-init.

Getting Started

The Amazon Machine Image of Photon OS has an ec2 datasource turned on by default so an ec2 configuration is accepted. However, for testing, the following methods provide ways to do cloud-init with a standalone instance of Photon OS.

Using a Seed ISO

This will be using the nocloud data source. In order to initialize the system in this way, an ISO file needs to be created with a meta-data file and an user-data file as shown below:

$ { echo instance-id: iid-local01; echo local-hostname: cloudimg; } > meta-data
$ printf "#cloud-config\nhostname: testhost\n" > user-data
$ genisoimage  -output seed.iso -volid cidata -joliet -rock user-data meta-data

Attach the seed.iso generated above to your machine and reboot for the init to take effect. In this case, the hostname is set to testhost.

Using a Seed Disk File

To init using local disk files, do the following:

mkdir /var/lib/cloud/seed/nocloud
cd /var/lib/cloud/seed/nocloud
$ { echo instance-id: iid-local01; echo local-hostname: cloudimg; } > meta-data
$ printf "#cloud-config\nhostname: testhost\n" > user-data

Reboot the machine and the hostname will be set to testhost.

Frequencies

Cloud-init modules have predetermined frequencies. Based on the frequency setting, multiple runs will yield different results. For the scripts to always run, remove the instances directory before rebooting.

rm -rf /var/lib/cloud/instances

Module Frequency Info

NameFrequency
disable_ec2_metadataAlways
users_groupsInstance
write_filesInstance
update_hostnameAlways
final_messageAlways
resolv_confInstance
growpartAlways
update_etc_hostsAlways
power_state_changeInstance
phone_homeInstance

5.10.2 - Deploy Photon OS With 'cloud-init'

You can deploy Photon OS with cloud-init in the following ways:

  • As a stand-alone Photon machine
  • In Amazon Elastic Compute Cloud, called EC2
  • In the Google cloud through the Google Compute Engine, or GCE
  • In a VMware Vsphere private cloud

When a cloud instance of Photon OS starts, cloud-init requires a data source. The data source can be an EC2 file for Amazon’s cloud platform, a seed.iso file for a stand-alone instance of Photon OS, or the internal capabilities of a system for managing virtual machines, such as VMware vSphere or vCenter. Cloud-init also includes data sources for OpenStack, Apache CloudStack, and OVF. The data source comprises two parts:

  1. Metadata
  2. User data

The metadata gives the cloud service provider instructions on how to implement the Photon OS machine in the cloud infrastructure. Metadata typically includes the instance ID and the local host name.

The user data contains the commands and scripts that Photon OS executes when it starts in the cloud. The user data commonly takes the form of a shell script or a YAML file containing a cloud configuration. The cloud-init overview and cloud-init documentation contains information about the types of data sources and the formats for metadata and user data.

On Photon OS, cloud-init is enabled and running by default. You can use the following command to check the status:

systemctl status cloud-init 

The Photon OS directory that contains the local data and other resources for cloud-init is /var/lib/cloud.

Photon OS stores the logs for cloud-init in the /var/log/cloud-init.log file.

The following sections demonstrate how to use cloud-init to customize a stand-alone Photon OS machine, instantiate a Photon OS machine in the Amazon EC2 cloud, and deploy a virtual machine running Photon OS in vSphere. Each section uses a different combination of the available options for the metadata and the user data that make up the data source. Specifications, additional options, and examples appear in the cloud-init documentation.

5.10.3 - Customizing Guest OS using Cloud-Init

A guest operating system is an operating system that runs inside a virtual machine. You can install a guest operating system in a virtual machine and control guest operating system customization for virtual machines created from vApp templates.

When you customize your guest OS you can set up a virtual machine with the operating system that you want.

Procedure

  1. Perform the following steps before cloning or customizing the guest operating system:
  2. Ensure that disable_vmware_customization is set to false in the /etc/cloud/cloud.cfg file.
  3. Set manage_etc_hosts: true in the /etc/cloud/cloud.cfg file.
  4. Make a backup of the 99-disable-networking-config.cfg file and delete the file from /etc/cloud/cloud.cfg.d folder after backup.
  5. Clone the VM or customize the guest operating system.
  6. After you clone your VM or customize the guest operating system, perform the following steps:
  7. Ensure that disable_vmware_customization is set to true in the /etc/cloud/cloud.cfg file in the newly created VM and the VM from where cloning was initiated.
  8. Remove manage_etc_hosts: true from the /etc/cloud/cloud.cfg file in the newly created VM and the VM from where cloning was initiated.
  9. Add a copy of the backed up file 99-disable-networking-config.cfg to its original folder /etc/cloud/cloud.cfg.d in the newly created VM and the VM from where cloning was initiated.

Note:

  1. The disable_vmware_customization flag in /etc/cloud/cloud.cfg.d file decides which customization workflow to be initiated.
  • Setting this to false invokes the Cloud-Init GOS customization workflow.
  • Setting this to true invokes the traditional GOSC script based customization workflow.
  1. When the manage_etc_hosts flag is set to true, Cloud-Init can edit the /etc/hosts file with the updated values.

    When the flag is set to true Cloud-Init edits the /etc/hosts file, even when there is no cloud config metadata available. Remove this entry once the Cloud-Init GOS customization is done, to stop Cloud-Init from editing /etc/hosts file and set a fallback configuration.

  2. The 99-disable-networking-config.cfg file is packaged as part of Cloud-Init RPM in photon and it prevents Cloud-Init from configuring the network. Delete this file before starting the Cloud-Init customization and then paste the backup of the file in the /etc/cloud/cloud.cfg.d/ folder once the cloud-init workflow is complete. It is important to replace this file after Cloud-Init customization to avoid removal of network configuration in the Cloud-Init instance.

Result

Cloud-Init guest OS customization is now enabled.

5.10.4 - Creating a Stand-Alone Photon Machine With cloud-init

Cloud-init can customize a Photon OS virtual machine by using the nocloud data source. The nocloud data source bundles the cloud-init metadata and user data into an ISO that acts as a seed when you boot the machine. The seed.iso delivers the metadata and the user data without requiring a network connection.

Procedure

  1. Create the metadata file with the following lines in the YAML format and name it meta-data:

    instance-id: iid-local01
       local-hostname: cloudimg
    
  2. Create the user data file with the following lines in YAML and name it user-data:

      #cloud-config
      hostname: testhost
      packages:
       - vim
    
  3. Generate the ISO that will serve as the seed. The ISO must have the volume ID set to cidata. In the following example, the ISO is generated on an Ubuntu 14.04 computer containing the files named meta-data and user-data in the local directory:

    genisoimage -output seed.iso -volid cidata -joliet -rock user-data meta-data
    

    The ISO now appears in the current directory:

    steve@ubuntu:~$ ls
    meta-data seed.iso user-data
    
  4. Optionally, check the ISO that you generated on Ubuntu by transferring the ISO to the root directory of your Photon OS machine and then running the following command:

    cloud-init --file seed.iso --debug init
    

    After running the cloud-init command above, check the cloud-init log file:

    more /var/log/cloud-init.log
    
  5. Attach the ISO to the Photon OS virtual machine as a CD-ROM and reboot it so that the changes specified by seed.iso take effect. In this case, cloud-init sets the hostname and adds the vim package.

5.10.5 - Customizing a Photon OS Machine on EC2

You can upload an ami image of Photon OS to Amazon Elastic Compute Cloud (EC2) and customize the Photon OS machine by using cloud-init with an EC2 data source. The Amazon machine image version of Photon OS is available as a free download at the location packages.vmware.com/photon.

The cloud-init service is commonly used on EC2 to configure the cloud instance of a Linux image. On EC2, cloud-init sets the .ssh/authorized_keys file to let you log in with a private key from another computer, that is, a computer besides the workstation that you are already using to connect with the Amazon cloud.

Example

The cloud-config user-data file that appears in the following example contains abridged SSH authorized keys to show you how to set them.

Prerequisites

Procedure

  1. Upload the Photon OS .ami image to the Amazon cloud and configure it with cloud-init. The correct virtualization type for Photon OS is hvm.
$ mkdir bundled
	$ tar -zxvf ./photon-ami.tar.gz 
	$ ec2-bundle-image -c ec2-certificate.pem -k ec2-privatekey.pem -u <EC2 account id>  --arch x86_64 --image photon-ami.raw --destination ./bundled/
	$ aws s3 mb s3://<bucket-name>
	$ ec2-upload-bundle --manifest ./bundled/photon-ami.manifest.xml --bucket <bucket-name> --access-key <Account Access Key> --secret-key <Account Secret key>
	$ ec2-register <bucket-name>/photon-ami.manifest.xml --name photon-ami --architecture x86_64 --virtualization-type hvm
  1. Import the cloud-config data. In the following command, the --user-data-file option instructs cloud-init to import the cloud-config data in user-data.txt. The command assumes you have uploaded the user-data.txt file and created the keypair mykeypair and the security group photon-sg.
 $ ec2-run-instances <ami-ID> --instance-type m3.medium -g photon-sg --key mykeypair --user-data-file user-data.txt

Describe the instance to see its ID:

$ ec2-describe-instances
  1. Run the following command to obtain its public IP address, which you can use to connect to the instance with SSH:
$ aws ec2 describe-instances --instance-ids <instance-id> --query 'Reservations[*].Instances[*].PublicIpAddress' --output=text
$ ec2-describe-images
  1. Run the following commands to terminate the machine. It is important to shut down the machine because Amazon charges you while the host is running down.
$ ec2-deregister <ami-image-identifier>
$ ec2-terminate-instances <instance-id>

Result

The following are the contents of the user-data.txt file that cloud-init applies to the machine the first time that it boots up in the cloud:

#cloud-config
    hostname: photon-on-01
    groups:
    - cloud-admins
    - cloud-users
    users:
    - default
    - name: photonadmin
       gecos: photon test admin user
       primary-group: cloud-admins
       groups: cloud-users
       lock-passwd: false
       passwd: vmware
    - name: photonuser
       gecos: photon test user
       primary-group: cloud-users
       groups: users
       passwd: vmware
    packages:
    - vim
	ssh_authorized_keys:
	 - ssh-rsa MIIEogIBAAKCAQEAuvHKAjBhpwuomcUTpIzJWRJAe71JyBgAWrwqyN1Mk5N+c9X5
	Ru2fazFA7WxQSD1KyTEvcuf8JzdBfrEJ0v3/nT2x63pvJ8fCl6HRkZtHo8zRu8vY
	KYTZS/sdvM/ruubHfq1ldRpgtYSqbkykoe6PCQIDAQABAoIBAEgveQtjVzHDhLTr
	rmwJmO316ERfkQ/chLaElhi9qwYJG/jqlNIISWFyztqD1b3fxU6m5MOBIujh7Xpg
	... ec3test@example.com 

You can view the cloud-init output log file on EC2 at /var/log/cloud-init-output.log.

For more information on using cloud-init user data on EC2, see Running Commands on Your Linux Instance at Launch.

For more information on how to get Photon OS up and running on EC2 and run a containerized application in the Docker engine, see Running Photon OS on Amazon Elastic Cloud Compute.

With Photon OS, you can also build cloud images on Google Compute Engine and other cloud providers. For more information, see Compatible Cloud Images.

5.10.6 - Running a Photon OS Machine on GCE

Photon OS comes in a preconfigured image ready for Google Cloud Engine.

Example

The example in this section shows how to create a Photon OS instance on Google Cloud Engine with and without cloud-init user data.

Prerequisites

  • You must have set up a GCE account and are ready to pay Google for its cloud services. The GCE-ready version of Photon OS is a free image and is free. You can download Photon OS for GCE from https://packages.vmware.com/photon/5.0/GA/gce/.

    The GCE-ready image of Photon OS contains packages and scripts that prepare it for the Google cloud to save you time as you implement a compute cluster or develop cloud applications. The GCE-ready version of Photon OS adds the following packages to the packages installed with the minimal version:

    sudo, tar, which, google-daemon, google-startup-scripts, kubernetes, perl-DBD-SQLite, perl-DBIx-Simple, perl, ntp
    
  • Verify that you have the gcloud command-line tool. For more information see, https://cloud.google.com/compute./gcloud-compute.

Procedure

  1. Use the following commands to create an instance of Photon OS from the Photon GCE image without using cloud-init. In the commands, you must replace <bucket-name> with the name of your bucket and the path to the Photon GCE tar file.

    $ gcloud compute instances list
    $ gcloud compute images list
    $ gcloud config list
    $ gsutil mb gs://<bucket-name>
    $ gsutil cp <path-to-photon-gce-image.tar.gz> gs://<bucket-name>/photon-gce.tar.gz
    $ gcloud compute images create photon-gce-image --source-uri gs://<bucket-name>/photon-gce.tar.gz 
    $ gcloud compute instances create photon-gce-vm --machine-type "n1-standard-1" --image photon-gce-image
    $ gcloud compute instances describe photon-gce-vm
    
  2. To create a new instance of a Photon OS machine and configure it with a cloud-init user data file, replace the gcloud compute instances create command in the example above with the following command. Before running this command, you must upload your user-data file to Google’s cloud infrastructure and replace <path-to-userdata-file> with its path and file name.

    gcloud compute instances create photon-gce-vm --machine-type "n1-standard-1" --image photon-gce-vm --metadata-from-file=user-data=<path-to-userdata-file>
    

    You can also add a cloud-init user-data file to an existing instance of a Photon OS machine on GCE:

    gcloud compute instances add-metadata photon-gce-vm --metadata-from-file=user-data=<path-to-userdata-file>
    

5.11 - Security Policy

This section describes the security policy of Photon OS.

5.11.1 - Default Firewall Settings

The design of Photon OS emphasizes security. On the minimal and full versions of Photon OS, the default security policy turns on the firewall and drops packets from external interfaces and applications. As a result, you might need to add rules to iptables to permit forwarding, allow protocols like HTTP, and open ports. You must configure the firewall for your applications and requirements.

The default iptables on the full version have the following settings:

iptables --list
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

For more information on how to change the settings, see the man page for iptables.

Although the default iptables policy accepts SSH connections, the sshd configuration file on the full version of Photon OS is set to reject SSH connections. See Permitting Root Login with SSH.

If you are unable to ping a Photon OS machine, check the firewall rules. To verify if the rules allow connectivity for the port and protocol, change the iptables commands by using lsof commands to see the processes listening on ports:

    lsof -i -P -n

5.11.2 - Default Permissions and umask

The umask on Photon OS is set to 0027.

When you create a new file with the touch command as root, the default on Photon OS is to set the permissions to 0640–which translates to read-write for user, read for group, and no access for others. Here’s an example:

touch newfile.md
stat newfile.md
  File: 'newfile.md'
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 801h/2049d      Inode: 316454      Links: 1
Access: (0640/-rw-r-----)  Uid: (    0/    root)   Gid: (    0/    root)

When you create a directory as root, Photon OS sets the permissions to 0750:

mkdir newdir
stat newdir
  File: 'newdir'
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: 801h/2049d      Inode: 316455      Links: 2
Access: (0750/drwxr-x---)  Uid: (    0/    root)   Gid: (    0/    root)

Because the mkdir command uses the umask to modify the permissions placed on newly created files or directories, you can see umask at work in the permissions of the new directory. Its default permissions are set at 0750 after the umask subtracts 0027 from the full set of open permissions, 0777.

Similarly, a new file begins as 0666 if you were to set umask to 0000. But because umask is set by default to 0027, a new file’s permissions are set to 0640.

So be aware of the default permissions on the directories and files that you create. Some system services and applications might require permissions other than the default. The systemd network service, for example, requires user-defined configuration files to be set to 644, not the default of 640. Thus, after you create a network configuration file with a .network extension, you must run the chmod command to set the new file’s mode bits to 644. For example:

chmod 644 10-static-en.network 

For more information on permissions, see the man pages for stat, umask, and acl.

5.11.3 - Disabling TLS 1.0 to Improve Transport Layer Security

Photon OS includes GnuTLS to help secure the transport layer. GnuTLS is a library that implements the SSL and TLS protocols to secure communications.

On Photon OS, SSL 3.0, which contains a known vulnerability, is disabled by default.

However, TLS 1.0, which also contains known vulnerabilities, is enabled by default.

To turn off TLS 1.0, perform the following steps:

  1. Create a directory named /etc/gnutls.
  2. In /etc/gnutls create a file named default-priorities.
  3. In the default-priorities file, specify GnuTLS priority strings that remove TLS 1.0 and SSL 3.0 but retain TLS 1.1 and TLS 1.2.
  4. After adding a new default-priorities file or after modifying it, you must restart all applications, including SSH, with an open TLS session for the changes to take effect.

The following is an example of a default-priorities file that contains GnuTLS priorities to disable TLS 1.0 and SSL 3.0:
console cat /etc/gnutls/default-priorities SYSTEM=NONE:!VERS-SSL3.0:!VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL

In this example, the priority string imposes system-specific policies. The NONE keyword means that no algorithms, protocols, or compression methods are enabled, so that you can enable specific versions individually later in the string. The priority string then specifies that SSL version 3.0 and TLS version 1.0 be removed, as marked by the exclamation point. The priority string then enables, as marked by the plus sign, versions 1.1 and 1.2 of TLS. The cypher is AES-128-CBC. The key exchange is RSA. The MAC is SHA1. And the compression algorithm is COMP-NULL.

On Photon OS, you can verify the system-specific policies in the default-priorities file as follows:

  1. Concatenate the default-priorities file to check its contents:
root@photon-rc [ ~ ]# cat /etc/gnutls/default-priorities
SYSTEM=NONE:!VERS-SSL3.0:!VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL
  1. Run the following command to check the protocols that are enabled for the system:
root@photon-rc [ /etc/gnutls ]# gnutls-cli --priority @SYSTEM -l
Cipher suites for @SYSTEM
TLS_RSA_AES_128_CBC_SHA1                                0x00, 0x2f      SSL3.0

Certificate types: none
Protocols: VERS-TLS1.1, VERS-TLS1.2
Compression: COMP-NULL
Elliptic curves: none
PK-signatures: none

For information about the GnuTLS priority strings, see https://gnutls.org/manual/html_node/Priority-Strings.html.

For information about the vulnerability in SSL 3.0, see SSL 3.0 Protocol Vulnerability and POODLE Attack.

For information about the vulnerabilities in TLS 1.0, see Guidelines for the Selection, Configuration, and Use of Transport Layer Security (TLS) Implementations.

5.12 - Support for zstd Compression

Zstandard (zstd) is a fast compression algorithm that provides high compression ratios. Photon OS offers support for the zstd compression and allows you to define which compression algorithm you want.

By using the zstd compression, the following benefits are seen:

  • Faster installation of RPMs and the overall system

  • Faster builds

  • Reduction in the size of artifacts created

5.13 - Kernel Live Patching

Photon OS supports Kernel Live Patching updates to the kernel in the RT, AWS, and generic kernel flavors. With this feature, you can modify the currently running operating system without rebooting. For example, you can apply security fixes without interrupting or pausing running processes to upgrade the operating system.

Kernel Live Patching is supported on the x86 architecture, but not on the ARM architecture. Kernel Live Patching is also supported on other architectures, such as s390 and ppc64le, which are not compatible with Photon OS.

Kernel Live Patching is supported on the following Photon OS versions:

  • Photon 5.0+ - all versions
  • Photon 4.0 - 5.10.118-2 and later
  • Photon 3.0 - 4.19.247-2 and later

Installing packages

Kernel Live Patching in Photon OS is supported with kpatch. Kernel Live Patching capabilities are split into three subpackages:

  1. kpatch - basic loading, unloading, etc. of livepatch modules only
  2. kpatch-build - manually build livepatch modules
  3. kpatch-utils - tools to automate livepatch module building for Photon OS

You can install all packages by using the tdnf command:

tdnf install kpatch kpatch-build kpatch-utils

Building livepatch modules

To build livepatch modules, first install the kpatch-utils package through tdnf. Livepatch building functionality can be accessed through the auto_livepatch.sh tool. This tool can cross-build livepatch modules for any version of Photon OS, as well as package livepatch modules into rpm packages.

Note: If necessary, you can use kpatch-build alone to build livepatch modules for Photon, but it lacks much of the functionality of the auto_livepatch.sh tool.

Details on how to use the tool are listed below:

auto_livepatch.sh [options] -p [list of patch files]

Options:

  • -k: Specifies the kernel version. If not set, uses uname -r
  • -p: Patch file list. Need at least one patch file listed here
  • -n: Output file name. Will be default if not specified.
  • -o: Output directory. Will be default if not specified.
  • -R: Disable replace flag (replace flag is on by default)
  • –export-debuginfo: Saves debug files after module is built.
  • -d: Use specified file contents as the module’s description field
  • –rpm: Package the module inside of an rpm.
  • –rpm-version: Set the version number for the rpm.
  • –rpm-release: Set the release number for the rpm.
  • –rpm-desc: Set a separate description for the rpm. Input is a file.
  • -h/–help: Prints help message and exits

Examples

The following examples show the syntax for various use case scenarios:

Simplest Usage - Build livepatch for current kernel.

auto_livepatch.sh -p example.patch

Set description.

auto_livepatch.sh -p example.patch -d description.txt

Set non-replace flag and save debug information.

auto_livepatch.sh -p example.patch -R --exportdebuginfo

Multiple patches.

auto_livepatch.sh -p example1.patch example2.patch ... exampleN.patch

Build module for Photon 3.0 aws flavor, with a set name and a set output directory.

auto_livepatch.sh -k 4.19.245-5.ph3-aws -p example.patch -n klp_module.ko -o livepatch_dir

Photon 4.0 rt flavor - All options set.

auto_livepauto_livepatch.sh -p example_patches/example.patch -k 5.10.118-rt67-3.ph4-rt -o test_dir -n test -d description.txt -R --export-debuginfoatch.sh -p example.patch

Package module as RPM - separate descriptions for the module and the rpm.

auto_livepatch.sh -p example_patch -d description.txt -k 5.10.118-3.ph3 --rpm --rpm-version 0.6.9 --rpm-release 3 --rpm-desc rpm_description.txt

Loading, unloading, and installing

You can use the following commands for the loading, unloading, and installing scenarios.

Loading:

kpatch load livepatch_module.ko

Unloading:

kpatch unload livepatch_module

Livepatches will be loaded on boot if they are installed through the kpatch install command:

kpatch install livepatch_module.ko

kpatch install will not load the module into the running kernel though, it will only be loaded on boot. To load a livepatch immediately, you must run kpatch load.

Note: The systemd kpatch service might fail to load livepatch modules on boot. You should verify that the kpatch service ran successfully. You can verify by running the systemctl status kpatch command, or by checking the logs at dmesg/journalctl.

To remove a livepatch from the list of livepatches to be loaded on boot, run:

kpatch uninstall livepatch_module

As livepatches can be packaged into RPMs with auto_livepatch.sh, loading livepatch RPMs is done like any other rpm - with tdnf. Livepatch modules will be both installed (to be loaded on boot) and loaded into the running kernel.

tdnf install livepatch.rpm

Uninstallation works like with any other rpm. You can uninstall by using the tdnf command.

Inspecting livepatch information

You can run the following commands to retrieve useful information:

  • lsmod - list currently loaded kernel modules. Loaded livepatch modules should appear here alongside regular kernel modules.
  • modinfo <module_name> - print module information/description

Management of livepatches - Update strategy

Photon OS (4.0 and later) supports atomic replace/cumulative updates of livepatch modules. This means that when you load in a new livepatch, it disables all of the older livepatch modules and only uses the new code. This is to avoid any conflicts that could arise from multiple livepatches interacting or modifying the same pieces of code. For more information, see https://docs.kernel.org/livepatch/cumulative-patches.html.

Therefore, if you want to load more than one livepatch at one time, all of the patches must be consolidated into a single livepatch module. When loaded, the old module will be disabled and the new one will be enabled.

Note: Photon 3.0 does not automatically disable all older livepatches, so it is recommended to do this manually before loading the new cumulative patch.

5.14 - Photon RPM OSTree: a simple guide

5.14.1 - Introduction

RPM-OSTree Overview

OSTree is a tool to manage bootable, immutable, versioned filesystem trees. Unlike traditional package managers like rpm or dpkg that know how to install, uninstall, configure packages, OSTree has no knowledge of the relationship between files. But when you add rpm capabilities on top of OSTree, it becomes RPM-OSTree, meaning a filetree replication system that is also package-aware.

The idea behind it is to use a client/server architecture to keep your Linux installed machines (physical or VM) in sync with the latest bits, in a predictable and reliable manner. To achieve that, OSTree uses a git-like repository that records the changes to any file and replicate them to any subscriber.

A system administrator or an image builder developer takes a base Linux image, prepares the packages and other configuration on a server box, executes a command to compose a filetree that the host machines will download and then incrementally upgrade whenever a new change has been committed. You may read more about OSTree here.

Why use RPM-OSTree in Photon?

There are several important benefits:

  • Reliable, efficient: The filetree replication is simple, reliable and efficient. It will only transfer deltas over the network. If you have deployed two almost identical bootable images on same box (differing just by several files), it will not take twice the space. The new tree will have a set of hardlinks to the old tree and only the different files will have a separate copy stored to disk.
  • Atomic: the filetree replication is atomic. At the end of a deployment, you are either booting from one deployment, or the other. There is no “partial deployed bootable image”. If anything bad happens during replication or deployment- power loss, network failure, your machine boots from the old image. There is even a tool option to cleanup old deployed (successfully or not) image.
  • Manageable: You are provided simple tools to figure out exactly what packages have been installed, to compare files, configuration and package changes between versions.
  • Predictable, repeatable: A big headache for a system administrator is to maintain a farm of computers with different packages, files and configuration installed in different order, that will result in exponential set of test cases. With RPM-OStree, you get identical, predictable installed systems.

As drawbacks, I would mention:

  • Some applications configured by user on host may have compatibility issues if they save configuration or download into read only directories like /usr.
  • People not used with “read only” file systems will be disappointed that they could no longer use RPM, yum, tdnf to install whatever they want. Think of this as an “enterprise policy”. They may circumvent this by customizing the target directory to a writable directory like /var or using rpm to install packages and record them using a new RPM repository in a writable place.
  • Administrators need to be aware about the directories re-mapping specific to OSTree and plan accordingly.

Photon with RPM-OSTree installation profiles

Photon takes advantage of RPM-OSTree and offers several installation choices:

  • Photon RPM-OSTree server - used to compose customized Photon OS installations and to prepare updates. I will call it for short ‘server’.
  • Photon RPM-OSTree host connected to a default online server repository via http or https, maintained by VMware Photon OS team, where future updates will be published. This will create a minimal installation profile, but with the option to self-upgrade. I will call it for short ‘default host’.
  • Photon RPM-OSTree host connected to a custom server repository. It requires a Photon RPM-OSTree Server installed in advance. I will call it for short ‘custom host’.

Terminology

In this section, the term OSTree refers to the general use of this technology, the format of the repository or replication protocol.

The term RPM-OSTree emphasizes the layer that adds RedHat Package Manager compatibility on both ends - at server and at host. However, since Photon OS is an RPM-based Linux, there are places in the documentation and even in the installer menus where OSTree may be used instead of RPM-OSTree when the distinction is not obvious or does not matter in that context.

When ostree and rpm-ostree are encountered, they refer to the usage of the specific Unix commands.

Finally, Photon RPM-OSTree is the application or implementation of the RPM-OStree system into Photon OS, materialized into two options: Photon Server and Photon Host (or client). Server or Host may be used with or without the Photon and/or RPM-OStree qualifier, but it means the same thing.

Sample code

Codes samples used throughout the book are small commands that can be typed at shell command prompt and do not require downloading additional files. As an alternative, one can remote connect via ssh, so cut & paste sample code from outside sources or copy files via scp will work. See the Photon Administration guide to learn how to enable ssh. The samples assume that the following VMs have been installed - see the steps in the next chapters:

  • A default host VM named photon-host-def.
  • Two server VMs named photon-srv1 and photon-srv2.
  • Two custom host VMs named photon-host-cus1 and photon-host-cus2, connected each to the corresponding server during install.

How to read this document

The RPM OSTree guide is structured to be used both as a sequential read and as a reference documentation.
If you are just interested in deploying a host system and keeping it up to date, then read Installing a Photon RPM-OSTree host against default server repository and Host updating operations.

If you want to install your own server and experiment with customizing packages for your Photon hosts, then read Installing a Photon RPM-OSTree server onwards. There are references to the concepts discussed throughout the book, if you need to understand them better.

RPM OSTree in Photon OS

This section is relevant to RPM OSTree in Photon OS.

Photon OS supports the following features:

  • Upgrade
  • Rollback
  • Remote, compose, and rebase server
  • Installation and uninstallation of packages with URL
  • Installation and uninstallation of packages from default repos
  • Automatic updates

5.14.2 - Installing a host against default server repository

RPM-OSTree Host default server repo installation option in Photon OS will setup a profile similar to Photon Minimal, with the added benefit of being able to self-upgrade.

Who is this for?

The RPM-OSTree ‘default host’ is the easiest way to deploy a Photon RPM-OSTree host from ISO/cdrom, without the need to deploy and maintain an RPM-OSTree server. It is targeted at the user who relies on VMware Photon OS team to keep his or her system up-to-date, configured to get its updates from the official Photon OSTree repository.

This is also the fastest way to install a host, as we’ve included in the ISO/cdrom an identical copy of the Photon “starter” RPM-OSTree repository that is published online by VMware Photon OS team. So rather than pulling from the online repository, the installer pulls the repo from cdrom, which saves bandwidth and also reduces to zero the chances of failing due to a networking problem. After successful installation, any updates are going to be pulled from the official online repository, when Photon OS team will make them available.

Note: It is also possible to install an RPM-OSTree host against the official online repo via PXE boot, without the benefit of fast, local pull from cdrom. This will be covered in the PXE boot/kickstart chapter, as it requires additional configuration.

Installing the ISO

User will first download Photon OS ISO file that contains the installer, which is able to deploy any of the supported Photon installation profiles.

There are some steps common to all Photon installation profiles, starting with adding a VM in VMware Fusion, Workstation or ESXi, selecting the OS family, then customizing for disk size, CPU, memory size, network interface etc. (or leaving the defaults) and selecting the ISO image as cdrom. The installer will launch, that will go through disk partitioning and accepting the license agreement screens, followed by selecting an installation profile. These steps are described at the page linked below, so I won’t repeat them, just that instead of setting up a Photon Minimal profile, we will install a Photon OSTree host:

Running Project Photon on Fusion.

Select the Photon OSTree Host option.

PhotonChooseHost

Continue with setting up a host name like photon1-def and a root password, re-confirm. Then, select “Default OSTree Server” and continue.

PhotonChooseHostDefault

PhotonHostDefaultFinish

When installation is over, the VM will reboot and will show in grub VMWare Photon/Linux 5.0_minimal (ostree), which will reassure that it’s booting from an OSTree image!

PhotonHostFirstRebootGrub

Boot, login and you are ready to use it.

To upgrade your host, see Host updating operations.

5.14.3 - Concepts in Action

Now that we have a fresh installed host (either as default or custom), we can better explain the OStree concepts and see them in action.

Querying the deployed filetrees

The first thing to do is to run a command that tells us what is installed on the machine and when. Since it’s a fresh install from the CD, there is only one bootable filetree image deployed.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree status 
State: idle
Deployments:
● ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2021-02-20T07:15:43Z)
Commit: 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f

Bootable filetree version

5.0_minimal is not the Linux Photon OS release version, nor daily build, but rather a human readable, self-incrementing version associated with every commit that brings file/package updates. Think of this as version 0. The following versions are going to be 5.0_minimal.1, 5.0_minimal.2, 5.0_minimal.3 and so on.

Commit ID

The ID listed is actually the first 5 bytes (10 hex digits) of the commit hash. If you want to see the verbose mode, use the -v option.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree status -v
State: idle
AutomaticUpdates: disabled
Deployments:
● ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2021-02-20T07:15:43Z)
Commit: 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f
└─ photon (2021-02-20T07:11:24Z)
Staged: no
    StateRoot: photon

RPM OStree Options

To see the list of options available with the rpm-ostree command, use the -h option.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree -h
Usage:
    rpm-ostree [OPTION…] COMMAND

Builtin Commands:
    compose  Commands to compose a tree
    cleanup  Clear cached/pending data
    db   Commands to query the RPM database
    deploy   Deploy a specific commit
    rebase   Switch to a different tree
    rollback Revert to the previously booted tree
    status   Get the version of the booted system
    upgrade  Perform a system upgrade
    reload   Reload configuration
    usroverlay   Apply a transient overlayfs to /usr
    cancel   Cancel an active transaction
    initramfsEnable or disable local initramfs regeneration
    install  Overlay additional packages
    uninstallRemove overlayed additional packages
    override Manage base package overrides
    resetRemove all mutations
    refresh-md   Generate rpm repo metadata
    kargsQuery or modify kernel arguments

Help Options:
    -h, --help   Show help options

Application Options:
    --versionPrint version information and exit

OSname

The OS Name identifies the operating system installed. All bootable filetrees for the same OS will share the /var directory, in other words applications installed in one booted image into this directory will be available in all other images.
If a new set of images are created for a different OS, they will receive a fresh copy of /var that is not shared with the previous OS images for the initial OS. In other words, if a machine is dual boot for different operating systems, they will not share each other’s /var content, however they will still merge 3-way /etc.

Refspec

The Refspec is a branch inside the repo, expressed in a hierarchical way. In this case, it’s the default branch that will receive package updates for the Photon OS 1.0 Minimal installation profile on Intel platforms. There could be other branches in the future, for example photon/3.0/x86_64/full that will match the Full installation profile (full set of packages installed).
Think of Refspec as the head of the minimal branch (just like in git) at the origin repo. On the replicated, local repo at the host, minimal is a file that contains the latest commit ID known for that branch.

root@photon-7c2d910d79e9 [ ~ ]# cat /ostree/repo/refs/remotes/photon/photon/5.0/x86_64/minimal
820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88

Why are there two ‘photon’ directory levels in the remotes path? The photon: prefix in the Refspec listed by rpm-ostree status corresponds to the first photon directory in the remotes path and is actually the name given to the remote that the host is connected to, which points to an http or https URL. We’ll talk about remotes later, but for now think of it as a namespace qualifier. The second photon is part of the Refspec path itself.

Deployments

We’ve used so far rpm-ostree. The same information can be obtained running an ostree command:

root@photon-7c2d910d79e9 [ ~ ]# ostree admin status
* photon 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f.0
Version: 5.0_minimal
origin refspec: photon:photon/5.0/x86_64/minimal

But where is this information stored? As you may have guessed, the local repo stores the heads of the deployed trees - the most recent commitment ID, just like Git does:

root@photon-7c2d910d79e9 [ ~ ]# cat /ostree/repo/refs/heads/ostree/0/1/0 
965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f

This also where this command that lists the references (local heads and remotes) takes its data from:

root@photon-7c2d910d79e9 [ ~ ]# ostree refs
photon:photon/5.0/x86_64/minimal
ostree/0/1/0

Based on that, it could find the root of the deployment that it boots from. The actual filetree is deployed right here:

root@photon-7c2d910d79e9 [ ~ ]# ls -l /ostree/deploy/photon/deploy/965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f.0
total 36
lrwxrwxrwx  2 root root7 Feb 23 05:43 bin -> usr/bin
drwxr-xr-x  2 root root 4096 Jan  1  1970 boot
drwxr-xr-x  2 root root 4096 Jan  1  1970 dev
drwxr-xr-x 45 root root 4096 Feb 23 06:08 etc
lrwxrwxrwx  2 root root8 Feb 23 05:43 home -> var/home
lrwxrwxrwx  3 root root7 Feb 23 05:43 lib -> usr/lib
lrwxrwxrwx  3 root root7 Feb 23 05:43 lib64 -> usr/lib
lrwxrwxrwx  2 root root9 Feb 23 05:43 media -> run/media
lrwxrwxrwx  2 root root7 Feb 23 05:43 mnt -> var/mnt
lrwxrwxrwx  2 root root7 Feb 23 05:43 opt -> var/opt
lrwxrwxrwx  2 root root   14 Feb 23 05:43 ostree -> sysroot/ostree
drwxr-xr-x  2 root root 4096 Jan  1  1970 proc
lrwxrwxrwx  2 root root   12 Feb 23 05:43 root -> var/roothome
drwxr-xr-x  2 root root 4096 Jan  1  1970 run
lrwxrwxrwx  2 root root8 Feb 23 05:43 sbin -> usr/sbin
lrwxrwxrwx  2 root root7 Feb 23 05:43 srv -> var/srv
drwxr-xr-x  2 root root 4096 Jan  1  1970 sys
drwxr-xr-x  4 root root 4096 Feb 23 05:44 sysroot
lrwxrwxrwx  2 root root   11 Feb 23 05:43 tmp -> sysroot/tmp
drwxr-xr-x 10 root root 4096 Jan  1  1970 usr
drwxr-xr-x  8 root root 4096 Feb 23 05:44 var

So how is a deployment linked to a specific branch, originating from a remote repo? Well, there is a file next to the deployed filetree root directory with the same name and .origin suffix, that contains exactly this info:

root@photon-7c2d910d79e9 [ ~ ]# cat /ostree/deploy/photon/deploy/965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f.0.origin 
[origin]
refspec=photon:photon/5.0/x86_64/minimal

Fast forwarding a bit, if there is a new deployment due to an upgrade or rebase, a new filetree will be added at the same level, and a new .origin file will tie it to the remote branch it originated from.

The photon directory in the path is the actual OSname. Multiple deployments of same OS will share a writable /var folder.

root@photon-7c2d910d79e9 [ ~ ]# ls -l /ostree/deploy/photon/var/
total 52
drwxr-xr-x   5 root root 4096 Feb 23 05:44 cache
drwxr-xr-x   2 root root 4096 Feb 23 05:44 home
drwxr-xr-x. 17 root root 4096 Feb 23 05:44 lib
drwxr-xr-x   2 root root 4096 Feb 23 05:44 local
lrwxrwxrwx.  1 root root   11 Feb 23 05:44 lock -> ../run/lock
drwxr-xr-x.  4 root root 4096 Feb 23 05:44 log
drwxr-xr-x   2 root root 4096 Feb 23 05:44 mail
drwxr-xr-x   2 root root 4096 Feb 23 05:44 mnt
drwxr-xr-x   4 root root 4096 Feb 23 05:44 opt
drwx------   4 root root 4096 Feb 23 06:09 roothome
lrwxrwxrwx.  1 root root6 Feb 23 05:44 run -> ../run
drwxr-xr-x   3 root root 4096 Feb 23 05:44 spool
drwxr-xr-x   2 root root 4096 Feb 23 05:44 srv
drwxrwxrwt.  5 root root 4096 Feb 23 06:08 tmp
drwxr-xr-x  11 root root 4096 Feb 23 05:44 usrlocal

5.14.4 - Querying for Commit File and Package Metadata

There are several ostree and rpm-ostree commands that list file or package data based on either the Commit ID, or Refspec. If Refspec is passed as a parameter, it’s the same as passing the most recent commit ID (head) for that branch.

Commit history

For a host that is freshly installed, there is only one commit in the history for the only branch.

root@photon-7c2d910d79e9 [ ~ ]# ostree log photon/5.0/x86_64/minimal
commit 820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88
ContentChecksum:  c7956cedc5c1b8c07a06e10789c17364a5b7a4b970daab64f3398b7c42bd97d9
Date:  2020-11-04 02:21:47 +0000
Version: 5.0_minimal
(no subject)

This commit has no parent; if there was an older commit, it would have been listed too. We can get the same listing (either nicely formatted or raw variant data) by passing the Commit ID. Just the first several hex digits will suffice to identify the commit ID. We can either request to be displayed in a pretty format, or raw - the actual C struct.

root@photon-7c2d910d79e9 [ ~ ]# ostree log 820b
commit 820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88
ContentChecksum:  c7956cedc5c1b8c07a06e10789c17364a5b7a4b970daab64f3398b7c42bd97d9
Date:  2020-11-04 02:21:47 +0000
Version: 5.0_minimal
(no subject)
root@photon-7c2d910d79e9 [ ~ ]# ostree log 820b --raw
commit 820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88
({'rpmostree.inputhash': <'1ce3f6d518ec2cbaebc2de2ccb01888e59fc7efb482caba590bc96a604e54f82'>, 'rpmostree.rpmmd-repos': <[{'id': <'photon'>, 'timestamp': <uint64 1604456423>}]>, 'version': <'5.0_minimal'>, 'rpmostree.rpmdb.pkglist': <[('Linux-PAM', '0', '1.4.0', '2.ph5', 'x86_64'), ('attr', '0', '2.4.48', '1.ph5', 'x86_64'), ('audit', '0', '2.8.5', '3.ph5', 'x86_64'), ('autogen-libopts', '0', '5.18.16', '3.ph5', 'x86_64'), ('bash', '0', '5.0', '1.ph5', 'x86_64'), ('bc', '0', '1.07.1', '4.ph5', 'x86_64'), ('bridge-utils', '0', '1.6', '1.ph5', 'x86_64'), ('bubblewrap', '0', '0.4.1', '1.ph5', 'x86_64'), ('bzip2', '0', '1.0.8', '3.ph5', 'x86_64'), ('bzip2-libs', '0', '1.0.8', '3.ph5', 'x86_64'), ('ca-certificates', '0', '20201001', '1.ph5', 'x86_64'), ('ca-certificates-pki', '0', '20201001', '1.ph5', 'x86_64'), ('cloud-init', '0', '20.3', '2.ph5', 'noarch'), ('coreutils-selinux', '0', '8.32', '2.ph5', 'x86_64'), ('cpio', '0', '2.13', '1.ph5', 'x86_64'), ('cracklib', '0', '2.9.7', '1.ph5', 'x86_64'), ('cracklib-dicts', '0', '2.9.7', '1.ph5', 'x86_64'), ('curl', '0', '7.72.0', '2.ph5', 'x86_64'), ('curl-libs', '0', '7.72.0', '2.ph5', 'x86_64'), ('cyrus-sasl', '0', '2.1.27', '3.ph5', 'x86_64'), ('dbus', '0', '1.13.18', '1.ph5', 'x86_64'), ('device-mapper', '0', '2.03.10', '2.ph5', 'x86_64'), ('device-mapper-libs', '0', '2.03.10', '2.ph5', 'x86_64'), ('dhcp-client', '0', '4.4.2', '1.ph5', 'x86_64'), ('dhcp-libs', '0', '4.4.2', '1.ph5', 'x86_64'), ('dracut', '0', '050', '5.ph5', 'x86_64'), ('dracut-tools', '0', '050', '5.ph5', 'x86_64'), ('e2fsprogs', '0', '1.45.6', '2.ph5', 'x86_64'), ('e2fsprogs-libs', '0', '1.45.6', '2.ph5', 'x86_64'), ('elfutils', '0', '0.181', '2.ph5', 'x86_64'), ('elfutils-libelf', '0', '0.181', '2.ph5', 'x86_64'), ('expat', '0', '2.2.9', '2.ph5', 'x86_64'), ('expat-libs', '0', '2.2.9', '2.ph5', 'x86_64'), ('file', '0', '5.39', '1.ph5', 'x86_64'), ('file-libs', '0', '5.39', '1.ph5', 'x86_64'), ('filesystem', '0', '1.1', '4.ph5', 'x86_64'), ('findutils', '0', '4.7.0', '1.ph5', 'x86_64'), ('finger', '0', '0.17', '3.ph5', 'x86_64'), ('flex', '0', '2.6.4', '3.ph5', 'x86_64'), ('fuse', '0', '2.9.9', '1.ph5', 'x86_64'), ('gawk', '0', '5.1.0', '1.ph5', 'x86_64'), ('gc', '0', '8.0.4', '1.ph5', 'x86_64'), ('gdbm', '0', '1.18.1', '1.ph5', 'x86_64'), ('glib', '0', '2.66.1', '1.ph5', 'x86_64'), ('glib-networking', '0', '2.66.0', '1.ph5', 'x86_64'), ('glibc', '0', '2.32', '1.ph5', 'x86_64'), ('glibc-iconv', '0', '2.32', '1.ph5', 'x86_64'), ('gmp', '0', '6.2.0', '1.ph5', 'x86_64'), ('gnupg', '0', '2.2.23', '1.ph5', 'x86_64'), ('gnutls', '0', '3.6.15', '3.ph5', 'x86_64'), ('gobject-introspection', '0', '1.66.0', '1.ph5', 'x86_64'), ('gpgme', '0', '1.14.0', '1.ph5', 'x86_64'), ('grep', '0', '3.4', '1.ph5', 'x86_64'), ('grub2', '0', '2.04', '2.ph5', 'x86_64'), ('grub2-efi', '0', '2.04', '2.ph5', 'x86_64'), ('grub2-efi-image', '0', '2.04', '2.ph5', 'x86_64'), ('grub2-pc', '0', '2.04', '2.ph5', 'x86_64'), ('grub2-theme', '0', '5.0', '1.ph5', 'noarch'), ('grub2-theme-ostree', '0', '5.0', '1.ph5', 'noarch'), ('guile', '0', '2.0.13', '3.ph5', 'x86_64'), ('gzip', '0', '1.10', '1.ph5', 'x86_64'), ('iana-etc', '0', '2.30', '2.ph5', 'noarch'), ('icu', '0', '67.1', '1.ph5', 'x86_64'), ('iproute2', '0', '5.8.0', '1.ph5', 'x86_64'), ('iptables', '0', '1.8.4', '1.ph5', 'x86_64'), ('iputils', '0', '20200821', '1.ph5', 'x86_64'), ('json-c', '0', '0.15', '2.ph5', 'x86_64'), ('json-glib', '0', '1.6.0', '1.ph5', 'x86_64'), ('kmod', '0', '27', '1.ph5', 'x86_64'), ('krb5', '0', '1.17', '4.ph5', 'x86_64'), ('libacl', '0', '2.2.53', '1.ph5', 'x86_64'), ('libarchive', '0', '3.4.3', '3.ph5', 'x86_64'), ('libassuan', '0', '2.5.3', '1.ph5', 'x86_64'), ('libcap', '0', '2.43', '1.ph5', 'x86_64'), ('libcap-ng', '0', '0.8', '1.ph5', 'x86_64'), ('libdb', '0', '5.3.28', '2.ph5', 'x86_64'), ('libdnet', '0', '1.11', '7.ph5', 'x86_64'), ('libffi', '0', '3.3', '1.ph5', 'x86_64'), ('libgcc', '0', '8.4.0', '1.ph5', 'x86_64'), ('libgcrypt', '0', '1.8.6', '2.ph5', 'x86_64'), ('libgpg-error', '0', '1.39', '1.ph5', 'x86_64'), ('libgpg-error-devel', '0', '1.39', '1.ph5', 'x86_64'), ('libksba', '0', '1.4.0', '1.ph5', 'x86_64'), ('libltdl', '0', '2.4.6', '3.ph5', 'x86_64'), ('libmetalink', '0', '0.1.3', '2.ph5', 'x86_64'), ('libmicrohttpd', '0', '0.9.71', '2.ph5', 'x86_64'), ('libmodulemd', '0', '2.9.4', '1.ph5', 'x86_64'), ('libmspack', '0', '0.10.1alpha', '1.ph5', 'x86_64'), ('libnsl', '0', '1.3.0', '1.ph5', 'x86_64'), ('libpsl', '0', '0.21.1', '1.ph5', 'x86_64'), ('libpwquality', '0', '1.4.2', '1.ph5', 'x86_64'), ('librepo', '0', '1.12.1', '3.ph5', 'x86_64'), ('libseccomp', '0', '2.5.0', '2.ph5', 'x86_64'), ('libselinux', '0', '3.1', '1.ph5', 'x86_64'), ('libsemanage', '0', '3.1', '1.ph5', 'x86_64'), ('libsepol', '0', '3.1', '1.ph5', 'x86_64'), ('libsolv', '0', '0.6.35', '5.ph5', 'x86_64'), ('libsoup', '0', '2.72.0', '1.ph5', 'x86_64'), ('libssh2', '0', '1.9.0', '2.ph5', 'x86_64'), ('libstdc++', '0', '8.4.0', '1.ph5', 'x86_64'), ('libtasn1', '0', '4.14', '1.ph5', 'x86_64'), ('libtirpc', '0', '1.2.6', '1.ph5', 'x86_64'), ('libtool', '0', '2.4.6', '3.ph5', 'x86_64'), ('libunistring', '0', '0.9.10', '1.ph5', 'x86_64'), ('libxml2', '0', '2.9.10', '3.ph5', 'x86_64'), ('libxml2-devel', '0', '2.9.10', '3.ph5', 'x86_64'), ('libxslt', '0', '1.1.34', '1.ph5', 'x86_64'), ('libyaml', '0', '0.2.5', '1.ph5', 'x86_64'), ('linux', '0', '5.9.0', '3.ph5', 'x86_64'), ('lua', '0', '5.3.5', '1.ph5', 'x86_64'), ('lz4', '0', '1.9.2', '1.ph5', 'x86_64'), ('m4', '0', '1.4.18', '3.ph5', 'x86_64'), ('motd', '0', '0.1.3', '6.ph5', 'noarch'), ('mozjs', '0', '78.3.1', '1.ph5', 'x86_64'), ('mpfr', '0', '4.1.0', '1.ph5', 'x86_64'), ('ncurses', '0', '6.2', '2.ph5', 'x86_64'), ('ncurses-libs', '0', '6.2', '2.ph5', 'x86_64'), ('ncurses-terminfo', '0', '6.2', '2.ph5', 'x86_64'), ('net-tools', '0', '1.60', '12.ph5', 'x86_64'), ('nettle', '0', '3.6', '1.ph5', 'x86_64'), ('npth', '0', '1.6', '1.ph5', 'x86_64'), ('nspr', '0', '4.29', '1.ph5', 'x86_64'), ('nss', '0', '3.57', '1.ph5', 'x86_64'), ('nss-altfiles', '0', '2.23.0', '1.ph5', 'x86_64'), ('nss-libs', '0', '3.57', '1.ph5', 'x86_64'), ('open-vm-tools', '0', '11.1.5', '4.ph5', 'x86_64'), ('openldap', '0', '2.4.53', '2.ph5', 'x86_64'), ('openssh', '0', '8.4p1', '2.ph5', 'x86_64'), ('openssh-clients', '0', '8.4p1', '2.ph5', 'x86_64'), ('openssh-server', '0', '8.4p1', '2.ph5', 'x86_64'), ('openssl', '0', '1.1.1g', '3.ph5', 'x86_64'), ('ostree', '0', '2020.6', '1.ph5', 'x86_64'), ('ostree-grub2', '0', '2020.6', '1.ph5', 'x86_64'), ('ostree-libs', '0', '2020.6', '1.ph5', 'x86_64'), ('pcre', '0', '8.44', '1.ph5', 'x86_64'), ('pcre-libs', '0', '8.44', '1.ph5', 'x86_64'), ('photon-release', '0', '5.0', '1.ph5', 'noarch'), ('photon-repos', '0', '5.0', '1.ph5', 'noarch'), ('pinentry', '0', '1.1.0', '1.ph5', 'x86_64'), ('pkg-config', '0', '0.29.2', '3.ph5', 'x86_64'), ('policycoreutils', '0', '3.1', '1.ph5', 'x86_64'), ('polkit', '0', '0.118', '1.ph5', 'x86_64'), ('popt', '0', '1.16', '5.ph5', 'x86_64'), ('procps-ng', '0', '3.3.16', '1.ph5', 'x86_64'), ('python3', '0', '3.8.6', '1.ph5', 'x86_64'), ('python3-PyYAML', '0', '5.3.1', '1.ph5', 'x86_64'), ('python3-asn1crypto', '0', '1.4.0', '1.ph5', 'noarch'), ('python3-attrs', '0', '20.2.0', '2.ph5', 'noarch'), ('python3-certifi', '0', '2020.6.20', '1.ph5', 'noarch'), ('python3-cffi', '0', '1.14.3', '2.ph5', 'x86_64'), ('python3-chardet', '0', '3.0.4', '2.ph5', 'noarch'), ('python3-configobj', '0', '5.0.6', '5.ph5', 'noarch'), ('python3-cryptography', '0', '3.1.1', '2.ph5', 'x86_64'), ('python3-gobject-introspection', '0', '1.66.0', '1.ph5', 'x86_64'), ('python3-idna', '0', '2.10', '1.ph5', 'noarch'), ('python3-jinja2', '0', '2.11.2', '1.ph5', 'noarch'), ('python3-jsonpatch', '0', '1.26', '1.ph5', 'noarch'), ('python3-jsonpointer', '0', '2.0', '2.ph5', 'noarch'), ('python3-jsonschema', '0', '3.2.0', '1.ph5', 'noarch'), ('python3-libs', '0', '3.8.6', '1.ph5', 'x86_64'), ('python3-markupsafe', '0', '1.1.1', '1.ph5', 'x86_64'), ('python3-netifaces', '0', '0.10.9', '2.ph5', 'x86_64'), ('python3-oauthlib', '0', '3.1.0', '1.ph5', 'noarch'), ('python3-packaging', '0', '20.4', '2.ph5', 'noarch'), ('python3-prettytable', '0', '0.7.2', '7.ph5', 'noarch'), ('python3-pyOpenSSL', '0', '19.1.0', '2.ph5', 'noarch'), ('python3-pyasn1', '0', '0.4.8', '1.ph5', 'noarch'), ('python3-pycparser', '0', '2.20', '1.ph5', 'noarch'), ('python3-pyparsing', '0', '2.4.7', '1.ph5', 'noarch'), ('python3-pyrsistent', '0', '0.17.3', '1.ph5', 'x86_64'), ('python3-requests', '0', '2.24.0', '1.ph5', 'noarch'), ('python3-setuptools', '0', '3.8.6', '1.ph5', 'noarch'), ('python3-six', '0', '1.15.0', '2.ph5', 'noarch'), ('python3-urllib3', '0', '1.25.10', '2.ph5', 'noarch'), ('python3-xml', '0', '3.8.6', '1.ph5', 'x86_64'), ('readline', '0', '7.0', '3.ph5', 'x86_64'), ('rpcsvc-proto', '0', '1.4.2', '1.ph5', 'x86_64'), ('rpm', '0', '4.14.2', '11.ph5', 'x86_64'), ('rpm-libs', '0', '4.14.2', '11.ph5', 'x86_64'), ('rpm-ostree', '0', '2020.5', '4.ph5', 'x86_64'), ('sed', '0', '4.8', '1.ph5', 'x86_64'), ('selinux-policy', '0', '3.14.7', '1.ph5', 'noarch'), ('shadow', '0', '4.8.1', '2.ph5', 'x86_64'), ('shadow-tools', '0', '4.8.1', '2.ph5', 'x86_64'), ('shim-signed', '0', '15', '1.ph5', 'x86_64'), ('sqlite-libs', '0', '3.33.0', '1.ph5', 'x86_64'), ('sudo', '0', '1.8.30', '2.ph5', 'x86_64'), ('systemd', '0', '245.5', '3.ph5', 'x86_64'), ('tcp_wrappers', '0', '7.6', '7.ph5', 'x86_64'), ('tzdata', '0', '2020a', '1.ph5', 'noarch'), ('util-linux', '0', '2.36', '1.ph5', 'x86_64'), ('util-linux-libs', '0', '2.36', '1.ph5', 'x86_64'), ('vim', '0', '8.2.1361', '1.ph5', 'x86_64'), ('which', '0', '2.21', '6.ph5', 'x86_64'), ('xmlsec1', '0', '1.2.30', '3.ph5', 'x86_64'), ('xz', '0', '5.2.5', '1.ph5', 'x86_64'), ('xz-libs', '0', '5.2.5', '1.ph5', 'x86_64'), ('zchunk', '0', '1.1.7', '1.ph5', 'x86_64'), ('zchunk-libs', '0', '1.1.7', '1.ph5', 'x86_64'), ('zlib', '0', '1.2.11', '2.ph5', 'x86_64'), ('zstd', '0', '1.4.5', '2.ph5', 'x86_64'), ('zstd-libs', '0', '1.4.5', '2.ph5', 'x86_64')]>}, @ay [], @a(say) [], '', '', uint64 1604456507, [byte 0xca, 0x99, 0x35, 0xe5, 0xaa, 0xc6, 0xbd, 0xb3, 0x52, 0xb4, 0x81, 0x62, 0xbb, 0x3f, 0xba, 0x44, 0x0e, 0x3c, 0xa0, 0x00, 0xc8, 0x6f, 0x7c, 0x32, 0xa0, 0xa0, 0x8b, 0xc6, 0xf0, 0xd5, 0x06, 0x0e], [byte 0x44, 0x6a, 0x0e, 0xf1, 0x1b, 0x7c, 0xc1, 0x67, 0xf3, 0xb6, 0x03, 0xe5, 0x85, 0xc7, 0xee, 0xee, 0xb6, 0x75, 0xfa, 0xa4, 0x12, 0xd5, 0xec, 0x73, 0xf6, 0x29, 0x88, 0xeb, 0x0b, 0x6c, 0x54, 0x88])

Listing file mappings

This command lists the file relations between the original source Linux Photon filetree and the deployed filetree. The normal columns include file type type (regular file, directory, link), permissions in chmod octal format, userID, groupID, file size, file name.

root@photon-7c2d910d79e9 [ ~ ]# ostree ls photon/5.0/x86_64/minimal
d00755 0 0  0 /
l00777 0 0  0 /bin -> usr/bin
l00777 0 0  0 /home -> var/home
l00777 0 0  0 /lib -> usr/lib
l00777 0 0  0 /lib64 -> usr/lib
l00777 0 0  0 /media -> run/media
l00777 0 0  0 /mnt -> var/mnt
l00777 0 0  0 /opt -> var/opt
l00777 0 0  0 /ostree -> sysroot/ostree
l00777 0 0  0 /root -> var/roothome
l00777 0 0  0 /sbin -> usr/sbin
l00777 0 0  0 /srv -> var/srv
l00777 0 0  0 /tmp -> sysroot/tmp
d00755 0 0  0 /boot
d00755 0 0  0 /dev
d00755 0 0  0 /proc
d00755 0 0  0 /run
d00755 0 0  0 /sys
d00755 0 0  0 /sysroot
d00755 0 0  0 /usr
d00755 0 0  0 /var

Extra columns can be added like checksum (-C) and extended attributes (-X).

root@photon-7c2d910d79e9 [ ~ ]# ostree ls photon/5.0/x86_64/minimal -C
d00755 0 0  0 ca9935e5aac6bdb352b48162bb3fba440e3ca000c86f7c32a0a08bc6f0d5060e 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /
l00777 0 0  0 389846c2702216e1367c8dfb68326a6b93ccf5703c89c93979052a9bf359608e /bin -> usr/bin
l00777 0 0  0 4344c10bf4931483f918496534f12ed9b50dc6a2cead35e3cd9dd898d6ac9414 /home -> var/home
l00777 0 0  0 f11902ca9d69a80df33918534a3e443251fd0aa7f94b76301e1f55e52aed29dd /lib -> usr/lib
l00777 0 0  0 f11902ca9d69a80df33918534a3e443251fd0aa7f94b76301e1f55e52aed29dd /lib64 -> usr/lib
l00777 0 0  0 75317a3df11447c470ffdd63dde045450ca97dfb2a97a0f3f6a21a5da66f737c /media -> run/media
l00777 0 0  0 97c55dbe24e8f3aecfd3f3e5b3f44646fccbb39799807d37a217e9c871da108b /mnt -> var/mnt
l00777 0 0  0 46b1abbd27a846a9257a8d8c9fc4b384ac0888bdb8ac0d6a2d5de72715bd5092 /opt -> var/opt
l00777 0 0  0 d37269e3f46023fd0275212473e07011894cdf4148cbf3fb5758a7e9471dad8e /ostree -> sysroot/ostree
l00777 0 0  0 6f800e74eed172661278d1e1f09e389a6504dcd3358618e1c1618f91f9d33601 /root -> var/roothome
l00777 0 0  0 e0bead7be9323b06bea05cb9b66eb151839989e3a4e5d1a93e09a36919e91818 /sbin -> usr/sbin
l00777 0 0  0 5d4250bba1ed300f793fa9769474351ee5cebd71e8339078af7ebfbe6256d9b5 /srv -> var/srv
l00777 0 0  0 364fbd62f91ca1e06eb7dbd50c93de8976f2cea633658e2dbe803ce6f7490c09 /tmp -> sysroot/tmp
d00755 0 0  0 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /boot
d00755 0 0  0 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /dev
d00755 0 0  0 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /proc
d00755 0 0  0 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /run
d00755 0 0  0 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /sys
d00755 0 0  0 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /sysroot
d00755 0 0  0 83902b1171980665a74c9ea4d3817add50e9fd3279d3ee92381fb2c0098f7ab0 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /usr
d00755 0 0  0 a3a987e053ea5a116f1e75a31cd7557fc6e57a3ae09e64171d7fea17ef71ec3e 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /var

By default, only the top folders are listed, but -R will list recursively. Instead of listing over 10,000 files, let’s filter to just all files that contain ‘rpm-ostree’, ‘rpmostree’ or ‘RpmOstree’, that must belong to rpm-ostree package itself.

root@photon-7c2d910d79e9 [ ~ ]# ostree ls photon/5.0/x86_64/minimal -R | grep -e '[Rr]pm-\?[Oo]stree'
-00755 0 0 787208 /usr/bin/rpm-ostree
d00755 0 0  0 /usr/bin/rpm-ostree-host
-00644 0 0   1069 /usr/bin/rpm-ostree-host/function.inc
-00755 0 0  10507 /usr/bin/rpm-ostree-host/mk-ostree-host.sh
d00755 0 0  0 /usr/bin/rpm-ostree-server
-00755 0 0   6452 /usr/bin/rpm-ostree-server/mkostreerepo
-00644 0 0209 /usr/etc/rpm-ostreed.conf
l00777 0 0  0 /usr/lib/librpmostree-1.so.1 -> librpmostree-1.so.1.0.0
-00755 0 0 9878248 /usr/lib/librpmostree-1.so.1.0.0
-00644 0 0   2312 /usr/lib/girepository-1.0/RpmOstree-1.0.typelib
-00755 0 0 22 /usr/lib/kernel/install.d/00-rpmostree-skip.install
d00755 0 0  0 /usr/lib/rpm-ostree
-00755 0 0 1846216 /usr/lib/rpm-ostree/libdnf.so.2
-00644 0 0622 /usr/lib/rpm-ostree/rpm-ostree-0-integration.conf
d00755 0 0  0 /usr/lib/sysimage/rpm-ostree-base-db
-00644 0 0 1069056 /usr/lib/sysimage/rpm-ostree-base-db/Basenames
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Conflictname
-00644 0 0 159744 /usr/lib/sysimage/rpm-ostree-base-db/Dirnames
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Enhancename
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Filetriggername
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Group
-00644 0 0  12288 /usr/lib/sysimage/rpm-ostree-base-db/Installtid
-00644 0 0  16384 /usr/lib/sysimage/rpm-ostree-base-db/Name
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Obsoletename
-00644 0 0 4313088 /usr/lib/sysimage/rpm-ostree-base-db/Packages
-00644 0 0 102400 /usr/lib/sysimage/rpm-ostree-base-db/Providename
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Recommendname
-00644 0 0 106496 /usr/lib/sysimage/rpm-ostree-base-db/Requirename
-00644 0 0  24576 /usr/lib/sysimage/rpm-ostree-base-db/Sha1header
-00644 0 0  16384 /usr/lib/sysimage/rpm-ostree-base-db/Sigmd5
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Suggestname
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Supplementname
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Transfiletriggername
-00644 0 0   8192 /usr/lib/sysimage/rpm-ostree-base-db/Triggername
-00644 0 0263 /usr/lib/systemd/system/rpm-ostree-bootstatus.service
-00644 0 0257 /usr/lib/systemd/system/rpm-ostreed-automatic.service
-00644 0 0227 /usr/lib/systemd/system/rpm-ostreed-automatic.timer
-00644 0 0325 /usr/lib/systemd/system/rpm-ostreed.service
-00644 0 0102 /usr/lib/systemd/system-preset/40-rpm-ostree-auto.preset
-00644 0 0622 /usr/lib/tmpfiles.d/rpm-ostree-0-integration.conf
-00644 0 0   1572 /usr/lib/tmpfiles.d/rpm-ostree-1-autovar.conf
-00755 0 0 53 /usr/libexec/rpm-ostreed
-00644 0 0   3049 /usr/share/bash-completion/completions/rpm-ostree
-00644 0 0  17210 /usr/share/dbus-1/interfaces/org.projectatomic.rpmostree1.xml
-00644 0 0133 /usr/share/dbus-1/system-services/org.projectatomic.rpmostree1.service
-00644 0 0   1530 /usr/share/dbus-1/system.d/org.projectatomic.rpmostree1.conf
-00644 0 0   6593 /usr/share/polkit-1/actions/org.projectatomic.rpmostree1.policy
d00755 0 0  0 /usr/share/rpm-ostree
-00644 0 0   1199 /usr/share/rpm-ostree/treefile.json

atomic is really an alias for rpm-ostree command. The last file treefile.json is not installed by the rpm-ostree package, it is actually downloaded from the server, as we will see in the next chapter. For now, let us notice “osname” : “photon”, “ref” : “photon/1.0/x86_64/minimal”, “automatic_version_prefix” : “1.0_minimal”, that matches what we have known so far, and also the “documentation” : false setting, that explains why there are no manual files installed for rpm-ostree, and in fact for any package.

root@photon-host [ /usr/share/rpm-ostree ]# ls -l /usr/share/man/man1 
total 0

Listing configuration changes

To diff the current /etc configuration versus default /etc (from the base image), this command will show the Modified, Added and Deleted files:

root@photon-7c2d910d79e9 [ ~ ]# ostree admin config-diff
M  ssh/sshd_config
M  udev/hwdb.bin
M  fstab
M  machine-id
M  gshadow
M  hosts
M  shadow
A  ssh/ssh_host_rsa_key
A  ssh/ssh_host_rsa_key.pub
A  ssh/ssh_host_dsa_key
A  ssh/ssh_host_dsa_key.pub
A  ssh/ssh_host_ecdsa_key
A  ssh/ssh_host_ecdsa_key.pub
A  ssh/ssh_host_ed25519_key
A  ssh/ssh_host_ed25519_key.pub
A  hostname
A  group-
A  locale.conf
A  .pwd.lock
A  gshadow-
A  shadow-
A  resolv.conf
A  .updated

Listing packages

The following is the rpm-ostree command that lists all the packages for that branch, extracted from RPM database.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree db list photon/5.0/x86_64/minimal
    ostree commit: photon/5.0/x86_64/minimal (820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88)
     Linux-PAM-1.4.0-2.ph5.x86_64
     attr-2.4.48-1.ph5.x86_64
     audit-2.8.5-3.ph5.x86_64
     autogen-libopts-5.18.16-3.ph5.x86_64
     bash-5.0-1.ph5.x86_64
     bc-1.07.1-4.ph5.x86_64
     bridge-utils-1.6-1.ph5.x86_64
     bubblewrap-0.4.1-1.ph5.x86_64
     bzip2-1.0.8-3.ph5.x86_64
     bzip2-libs-1.0.8-3.ph5.x86_64
     ca-certificates-20201001-1.ph5.x86_64
     ca-certificates-pki-20201001-1.ph5.x86_64
     cloud-init-20.3-2.ph5.noarch
     coreutils-selinux-8.32-2.ph5.x86_64
     cpio-2.13-1.ph5.x86_64
     cracklib-2.9.7-1.ph5.x86_64
     cracklib-dicts-2.9.7-1.ph5.x86_64
     curl-7.72.0-2.ph5.x86_64
     curl-libs-7.72.0-2.ph5.x86_64
     cyrus-sasl-2.1.27-3.ph5.x86_64
     dbus-1.13.18-1.ph5.x86_64
     device-mapper-2.03.10-2.ph5.x86_64
     device-mapper-libs-2.03.10-2.ph5.x86_64
     dhcp-client-4.4.2-1.ph5.x86_64
     dhcp-libs-4.4.2-1.ph5.x86_64
     dracut-050-5.ph5.x86_64
     dracut-tools-050-5.ph5.x86_64
     e2fsprogs-1.45.6-2.ph5.x86_64
     e2fsprogs-libs-1.45.6-2.ph5.x86_64
     elfutils-0.181-2.ph5.x86_64
     elfutils-libelf-0.181-2.ph5.x86_64
     expat-2.2.9-2.ph5.x86_64
     expat-libs-2.2.9-2.ph5.x86_64
     file-5.39-1.ph5.x86_64
     file-libs-5.39-1.ph5.x86_64
     filesystem-1.1-4.ph5.x86_64
     findutils-4.7.0-1.ph5.x86_64
     finger-0.17-3.ph5.x86_64
     flex-2.6.4-3.ph5.x86_64
     fuse-2.9.9-1.ph5.x86_64
     gawk-5.1.0-1.ph5.x86_64
     gc-8.0.4-1.ph5.x86_64
     gdbm-1.18.1-1.ph5.x86_64
     glib-2.66.1-1.ph5.x86_64
     glib-networking-2.66.0-1.ph5.x86_64
     glibc-2.32-1.ph5.x86_64
     glibc-iconv-2.32-1.ph5.x86_64
     gmp-6.2.0-1.ph5.x86_64
     gnupg-2.2.23-1.ph5.x86_64
     gnutls-3.6.15-3.ph5.x86_64
     gobject-introspection-1.66.0-1.ph5.x86_64
     gpgme-1.14.0-1.ph5.x86_64
     grep-3.4-1.ph5.x86_64
     grub2-2.04-2.ph5.x86_64
     grub2-efi-2.04-2.ph5.x86_64
     grub2-efi-image-2.04-2.ph5.x86_64
     grub2-pc-2.04-2.ph5.x86_64
     grub2-theme-5.0-1.ph5.noarch
     grub2-theme-ostree-5.0-1.ph5.noarch
     guile-2.0.13-3.ph5.x86_64
     gzip-1.10-1.ph5.x86_64
     iana-etc-2.30-2.ph5.noarch
     icu-67.1-1.ph5.x86_64
     iproute2-5.8.0-1.ph5.x86_64
     iptables-1.8.4-1.ph5.x86_64
     iputils-20200821-1.ph5.x86_64
     json-c-0.15-2.ph5.x86_64
     json-glib-1.6.0-1.ph5.x86_64
     kmod-27-1.ph5.x86_64
     krb5-1.17-4.ph5.x86_64
     libacl-2.2.53-1.ph5.x86_64
     libarchive-3.4.3-3.ph5.x86_64
     libassuan-2.5.3-1.ph5.x86_64
     libcap-2.43-1.ph5.x86_64
     libcap-ng-0.8-1.ph5.x86_64
     libdb-5.3.28-2.ph5.x86_64
     libdnet-1.11-7.ph5.x86_64
     libffi-3.3-1.ph5.x86_64
     libgcc-8.4.0-1.ph5.x86_64
     libgcrypt-1.8.6-2.ph5.x86_64
     libgpg-error-1.39-1.ph5.x86_64
     libgpg-error-devel-1.39-1.ph5.x86_64
     libksba-1.4.0-1.ph5.x86_64
     libltdl-2.4.6-3.ph5.x86_64
     libmetalink-0.1.3-2.ph5.x86_64
     libmicrohttpd-0.9.71-2.ph5.x86_64
     libmodulemd-2.9.4-1.ph5.x86_64
     libmspack-0.10.1alpha-1.ph5.x86_64
     libnsl-1.3.0-1.ph5.x86_64
     libpsl-0.21.1-1.ph5.x86_64
     libpwquality-1.4.2-1.ph5.x86_64
     librepo-1.12.1-3.ph5.x86_64
     libseccomp-2.5.0-2.ph5.x86_64
     libselinux-3.1-1.ph5.x86_64
     libsemanage-3.1-1.ph5.x86_64
     libsepol-3.1-1.ph5.x86_64
     libsolv-0.6.35-5.ph5.x86_64
     libsoup-2.72.0-1.ph5.x86_64
     libssh2-1.9.0-2.ph5.x86_64
     libstdc++-8.4.0-1.ph5.x86_64
     libtasn1-4.14-1.ph5.x86_64
     libtirpc-1.2.6-1.ph5.x86_64
     libtool-2.4.6-3.ph5.x86_64
     libunistring-0.9.10-1.ph5.x86_64
     libxml2-2.9.10-3.ph5.x86_64
     libxml2-devel-2.9.10-3.ph5.x86_64
     libxslt-1.1.34-1.ph5.x86_64
     libyaml-0.2.5-1.ph5.x86_64
     linux-5.9.0-3.ph5.x86_64
     lua-5.3.5-1.ph5.x86_64
     lz4-1.9.2-1.ph5.x86_64
     m4-1.4.18-3.ph5.x86_64
     motd-0.1.3-6.ph5.noarch
     mozjs-78.3.1-1.ph5.x86_64
     mpfr-4.1.0-1.ph5.x86_64
     ncurses-6.2-2.ph5.x86_64
     ncurses-libs-6.2-2.ph5.x86_64
     ncurses-terminfo-6.2-2.ph5.x86_64
     net-tools-1.60-12.ph5.x86_64
     nettle-3.6-1.ph5.x86_64
     npth-1.6-1.ph5.x86_64
     nspr-4.29-1.ph5.x86_64
     nss-3.57-1.ph5.x86_64
     nss-altfiles-2.23.0-1.ph5.x86_64
     nss-libs-3.57-1.ph5.x86_64
     open-vm-tools-11.1.5-4.ph5.x86_64
     openldap-2.4.53-2.ph5.x86_64
     openssh-8.4p1-2.ph5.x86_64
     openssh-clients-8.4p1-2.ph5.x86_64
     openssh-server-8.4p1-2.ph5.x86_64
     openssl-1.1.1g-3.ph5.x86_64
     ostree-2020.6-1.ph5.x86_64
     ostree-grub2-2020.6-1.ph5.x86_64
     ostree-libs-2020.6-1.ph5.x86_64
     pcre-8.44-1.ph5.x86_64
     pcre-libs-8.44-1.ph5.x86_64
     photon-release-5.0-1.ph5.noarch
     photon-repos-5.0-1.ph5.noarch
     pinentry-1.1.0-1.ph5.x86_64
     pkg-config-0.29.2-3.ph5.x86_64
     policycoreutils-3.1-1.ph5.x86_64
     polkit-0.118-1.ph5.x86_64
     popt-1.16-5.ph5.x86_64
     procps-ng-3.3.16-1.ph5.x86_64
     python3-3.8.6-1.ph5.x86_64
     python3-PyYAML-5.3.1-1.ph5.x86_64
     python3-asn1crypto-1.4.0-1.ph5.noarch
     python3-attrs-20.2.0-2.ph5.noarch
     python3-certifi-2020.6.20-1.ph5.noarch
     python3-cffi-1.14.3-2.ph5.x86_64
     python3-chardet-3.0.4-2.ph5.noarch
     python3-configobj-5.0.6-5.ph5.noarch
     python3-cryptography-3.1.1-2.ph5.x86_64
     python3-gobject-introspection-1.66.0-1.ph5.x86_64
     python3-idna-2.10-1.ph5.noarch
     python3-jinja2-2.11.2-1.ph5.noarch
     python3-jsonpatch-1.26-1.ph5.noarch
     python3-jsonpointer-2.0-2.ph5.noarch
     python3-jsonschema-3.2.0-1.ph5.noarch
     python3-libs-3.8.6-1.ph5.x86_64
     python3-markupsafe-1.1.1-1.ph5.x86_64
     python3-netifaces-0.10.9-2.ph5.x86_64
     python3-oauthlib-3.1.0-1.ph5.noarch
     python3-packaging-20.4-2.ph5.noarch
     python3-prettytable-0.7.2-7.ph5.noarch
     python3-pyOpenSSL-19.1.0-2.ph5.noarch
     python3-pyasn1-0.4.8-1.ph5.noarch
     python3-pycparser-2.20-1.ph5.noarch
     python3-pyparsing-2.4.7-1.ph5.noarch
     python3-pyrsistent-0.17.3-1.ph5.x86_64
     python3-requests-2.24.0-1.ph5.noarch
     python3-setuptools-3.8.6-1.ph5.noarch
     python3-six-1.15.0-2.ph5.noarch
     python3-urllib3-1.25.10-2.ph5.noarch
     python3-xml-3.8.6-1.ph5.x86_64
     readline-7.0-3.ph5.x86_64
     rpcsvc-proto-1.4.2-1.ph5.x86_64
     rpm-4.14.2-11.ph5.x86_64
     rpm-libs-4.14.2-11.ph5.x86_64
     rpm-ostree-2020.5-4.ph5.x86_64
     sed-4.8-1.ph5.x86_64
     selinux-policy-3.14.7-1.ph5.noarch
     shadow-4.8.1-2.ph5.x86_64
     shadow-tools-4.8.1-2.ph5.x86_64
     shim-signed-15-1.ph5.x86_64
     sqlite-libs-3.33.0-1.ph5.x86_64
     sudo-1.8.30-2.ph5.x86_64
     systemd-245.5-3.ph5.x86_64
     tcp_wrappers-7.6-7.ph5.x86_64
     tzdata-2020a-1.ph5.noarch
     util-linux-2.36-1.ph5.x86_64
     util-linux-libs-2.36-1.ph5.x86_64
     vim-8.2.1361-1.ph5.x86_64
     which-2.21-6.ph5.x86_64
     xmlsec1-1.2.30-3.ph5.x86_64
     xz-5.2.5-1.ph5.x86_64
     xz-libs-5.2.5-1.ph5.x86_64
     zchunk-1.1.7-1.ph5.x86_64
     zchunk-libs-1.1.7-1.ph5.x86_64
     zlib-1.2.11-2.ph5.x86_64
     zstd-1.4.5-2.ph5.x86_64
     zstd-libs-1.4.5-2.ph5.x86_64

Querying for package details

We are able to use the query option of rpm to make sure any package have been installed properly. The files list should match the previous file mappings in 4.2, so let’s check package rpm-ostree. As we’ve seen, manual files listed here are actually missing, they were not installed.

root@photon-7c2d910d79e9 [ ~ ]# rpm -ql  rpm-ostree
    /etc/rpm-ostreed.conf
    /usr/bin/rpm-ostree
    /usr/bin/rpm-ostree-host
    /usr/bin/rpm-ostree-host/function.inc
    /usr/bin/rpm-ostree-host/mk-ostree-host.sh
    /usr/bin/rpm-ostree-server
    /usr/bin/rpm-ostree-server/mkostreerepo
    /usr/lib/girepository-1.0/RpmOstree-1.0.typelib
    /usr/lib/librpmostree-1.so.1
    /usr/lib/librpmostree-1.so.1.0.0
    /usr/lib/rpm-ostree
    /usr/lib/rpm-ostree/libdnf.so.2
    /usr/lib/rpm-ostree/rpm-ostree-0-integration.conf
    /usr/lib/systemd/system/rpm-ostree-bootstatus.service
    /usr/lib/systemd/system/rpm-ostreed-automatic.service
    /usr/lib/systemd/system/rpm-ostreed-automatic.timer
    /usr/lib/systemd/system/rpm-ostreed.service
    /usr/libexec/rpm-ostreed
    /usr/share/bash-completion/completions/rpm-ostree
    /usr/share/dbus-1/interfaces/org.projectatomic.rpmostree1.xml
    /usr/share/dbus-1/system-services/org.projectatomic.rpmostree1.service
    /usr/share/dbus-1/system.d/org.projectatomic.rpmostree1.conf
    /usr/share/man/man1/rpm-ostree.1.gz
    /usr/share/man/man5/rpm-ostreed.conf.5.gz
    /usr/share/man/man8/rpm-ostreed-automatic.service.8.gz
    /usr/share/man/man8/rpm-ostreed-automatic.timer.8.gz
    /usr/share/polkit-1/actions/org.projectatomic.rpmostree1.policy

Why am I unable to install, upgrade or uninstall packages?

The OSTree host installer needs the server URL or the server repository.

When you perform the installation using the repo, the install packages are located under the layer package. When you install with the URL, the packages are located under the local packages.

You can use the rpm-ostree uninstall command to uninstall only the layered and local packages but not the base packages. To modify the base packages, you can use the rpm-ostree override command.

When you run rpm-ostree upgrade, the command will only upgrade packages based on the commit available in the server.

5.14.5 - Host Updating Operations

Upgrade overview

If you’ve used yum, dnf (and now tdnf for Photon) in RPM systems or apt-get in Debian based Unix, you understand what “install” is for packages and the subtle difference between “update” and “upgrade”.

OSTree and RPM-OSTree don’t distinguish between them and the term “upgrade” has a slightly different meaning - to bring the system in sync with the remote repo, to the top of the Refspec (branch), just like in Git, by pulling the latest changes.

In fact, ostree and rpm-ostree commands support a single “upgrade” verb for a file image tree and a package list in the same refspec (branch). rpm-ostree upgrade will install a package if it doesn’t exist, will not touch it if it has same version in the new image, will upgrade it if the version number is higher and it may actually downgrade it, if the package has been downgraded in the new image. I wish this operation had a different name, to avoid any confusion.

The reverse operation of an upgrade is a “rollback” and fortunately it’s not named “downgrade” because it may upgrade packages in the last case describe above.

As we’ll see in a future chapter, a jump to a different Refspec (branch) is also supported and it’s named “rebase”.

Incremental upgrade

To check if there are any updates available, one would execute:

root@photon-host-def [ ~ ]# rpm-ostree upgrade
Updating from: photon:photon/5.0/x86_64/minimal

No upgrade available.

It is good idea to check periodically for updates.

To check if there are any new updates without actually applying them, we will pass the –check-diff flag, that would list the different packages as added, modified or deleted - if such operations were to happen.

root@photon-host [ ~ ]# rpm-ostree upgrade --check-diff
Updating from: photon:photon/5.0/x86_64/minimal

8 metadata, 13 content objects fetched; 1026 KiB transferred in 0 seconds
+gawk-4.1.3-2.ph1.x86_64
+sudo-1.8.15-3.ph1.x86_64
+wget-1.17.1-2.ph1.x86_64

We like what we see and now let’s upgrade for real. This command will deploy a new bootable filetree.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree upgrade --allow-downgrade
⠂ Receiving metadata objects: 0/(estimating) -/s 0 bytes... 
Receiving metadata objects: 0/(estimating) -/s 0 bytes... done
Staging deployment... done
Downgraded:
  audit 2.8.5-6.ph5 -> 2.8.5-3.ph5
  cloud-init 20.4.1-1.ph5 -> 20.3-2.ph5
  cpio 2.13-3.ph5 -> 2.13-1.ph5
  curl 7.74.0-1.ph5 -> 7.72.0-2.ph5
  curl-libs 7.74.0-1.ph5 -> 7.72.0-2.ph5
  cyrus-sasl 2.1.27-4.ph5 -> 2.1.27-3.ph5
  dhcp-client 4.4.2-2.ph5 -> 4.4.2-1.ph5
  dhcp-libs 4.4.2-2.ph5 -> 4.4.2-1.ph5
  dracut 050-7.ph5 -> 050-5.ph5
  dracut-tools 050-7.ph5 -> 050-5.ph5
  file 5.39-2.ph5 -> 5.39-1.ph5
  file-libs 5.39-2.ph5 -> 5.39-1.ph5
  gdbm 1.19-1.ph5 -> 1.18.1-1.ph5
  glibc 2.32-2.ph5 -> 2.32-1.ph5
  glibc-iconv 2.32-2.ph5 -> 2.32-1.ph5
  gobject-introspection 1.66.0-3.ph5 -> 1.66.0-1.ph5
  grub2-theme 5.0-2.ph5 -> 5.0-1.ph5
  grub2-theme-ostree 5.0-2.ph5 -> 5.0-1.ph5
  iproute2 5.10.0-1.ph5 -> 5.8.0-1.ph5
  iptables 1.8.7-1.ph5 -> 1.8.4-1.ph5
  json-c 0.15-3.ph5 -> 0.15-2.ph5
  libgcc 10.2.0-1.ph5 -> 8.4.0-1.ph5
  libmetalink 0.1.3-3.ph5 -> 0.1.3-2.ph5
  libmodulemd 2.11.0-1.ph5 -> 2.9.4-1.ph5
  librepo 1.12.1-4.ph5 -> 1.12.1-3.ph5
  libsepol 3.1-2.ph5 -> 3.1-1.ph5
  libsolv 0.6.35-7.ph5 -> 0.6.35-5.ph5
  libssh2 1.9.0-3.ph5 -> 1.9.0-2.ph5
  libstdc++ 10.2.0-1.ph5 -> 8.4.0-1.ph5
  libxml2 2.9.10-6.ph5 -> 2.9.10-3.ph5
  libxml2-devel 2.9.10-6.ph5 -> 2.9.10-3.ph5
  libxslt 1.1.34-2.ph5 -> 1.1.34-1.ph5
  linux 5.10.4-15.ph5 -> 5.9.0-3.ph5
  ncurses 6.2-3.ph5 -> 6.2-2.ph5
  ncurses-libs 6.2-3.ph5 -> 6.2-2.ph5
  ncurses-terminfo 6.2-3.ph5 -> 6.2-2.ph5
  nss 3.57-2.ph5 -> 3.57-1.ph5
  nss-libs 3.57-2.ph5 -> 3.57-1.ph5
  open-vm-tools 11.2.5-1.ph5 -> 11.1.5-4.ph5
  openldap 2.4.53-3.ph5 -> 2.4.53-2.ph5
  openssl 1.1.1i-2.ph5 -> 1.1.1g-3.ph5
  pcre 8.44-2.ph5 -> 8.44-1.ph5
  pcre-libs 8.44-2.ph5 -> 8.44-1.ph5
  python3 3.9.1-2.ph5 -> 3.8.6-1.ph5
  python3-PyYAML 5.4.1-1.ph5 -> 5.3.1-1.ph5
  python3-attrs 20.3.0-2.ph5 -> 20.2.0-2.ph5
  python3-cryptography 3.2.1-1.ph5 -> 3.1.1-2.ph5
  python3-gobject-introspection 1.66.0-3.ph5 -> 1.66.0-1.ph5
  python3-libs 3.9.1-2.ph5 -> 3.8.6-1.ph5
  python3-packaging 20.4-3.ph5 -> 20.4-2.ph5
  python3-pyrsistent 0.17.3-2.ph5 -> 0.17.3-1.ph5
  python3-setuptools 3.9.1-2.ph5 -> 3.8.6-1.ph5
  python3-urllib3 1.25.11-1.ph5 -> 1.25.10-2.ph5
  python3-xml 3.9.1-2.ph5 -> 3.8.6-1.ph5
  rpm 4.16.1.2-1.ph5 -> 4.14.2-11.ph5
  rpm-libs 4.16.1.2-1.ph5 -> 4.14.2-11.ph5
  rpm-ostree 2020.5-5.ph5 -> 2020.5-4.ph5
  shadow 4.8.1-3.ph5 -> 4.8.1-2.ph5
  shadow-tools 4.8.1-3.ph5 -> 4.8.1-2.ph5
  sudo 1.9.5-1.ph5 -> 1.8.30-2.ph5
  systemd 247.3-1.ph5 -> 245.5-3.ph5
  util-linux 2.36-2.ph5 -> 2.36-1.ph5
  util-linux-libs 2.36-2.ph5 -> 2.36-1.ph5
Removed:
  libpcap-1.10.0-1.ph5.x86_64
  python3-Pygments-2.7.2-2.ph5.noarch
  python3-alabaster-0.7.12-1.ph5.noarch
  python3-babel-2.8.0-3.ph5.noarch
  python3-docutils-0.16-1.ph5.noarch
  python3-imagesize-1.2.0-2.ph5.noarch
  python3-pytz-2020.4-2.ph5.noarch
  python3-snowballstemmer-2.0.0-1.ph5.noarch
  python3-sphinx-3.3.0-2.ph5.noarch
  python3-sphinxcontrib-applehelp-1.0.2-1.ph5.noarch
  python3-sphinxcontrib-devhelp-1.0.2-1.ph5.noarch
  python3-sphinxcontrib-htmlhelp-1.0.3-1.ph5.noarch
  python3-sphinxcontrib-jsmath-1.0.1-1.ph5.noarch
  python3-sphinxcontrib-qthelp-1.0.3-1.ph5.noarch
  python3-sphinxcontrib-serializinghtml-1.1.4-1.ph5.noarch
  python3-typing-3.7.4.3-1.ph5.noarch
  systemd-libs-247.3-1.ph5.x86_64
  systemd-pam-247.3-1.ph5.x86_64
  systemd-rpm-macros-247.3-1.ph5.noarch
  systemd-udev-247.3-1.ph5.x86_64
Run "systemctl reboot" to start a reboot

By looking at the commit history, notice that the new commit has the original commit as parent.

root@photon-7c2d910d79e9 [ ~ ]# ostree log photon/5.0/x86_64/minimal
commit 820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88
ContentChecksum:  c7956cedc5c1b8c07a06e10789c17364a5b7a4b970daab64f3398b7c42bd97d9
Date:  2020-11-04 02:21:47 +0000
Version: 5.0_minimal
(no subject)

Notice that now we have a new reference, that corresponds to the newly deployed image.

root@photon-7c2d910d79e9 [ ~ ]# ostree refs
ostree/0/1/1
photon:photon/5.0/x86_64/minimal
ostree/0/1/0

Let us look at the status. The new filetree version .1 has the expected Commit ID and a newer timestamp, that is actually the server date/time when the image has been generated, not the time/date when it was downloaded or installed at the host. The old image has a star next to it, showing that’s the image the system is booted currently into.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree status
State: idle
Deployments:
  ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2020-11-04T02:21:47Z)
Commit: 820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88
  Diff: 63 downgraded, 20 removed

● ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2021-02-20T07:15:43Z)
Commit: 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f

Now let’s type reboot. Grub will list the new filetree as the first image, marked with a star, as the default bootable image. If the keyboard is not touched and order is not changed, grub will timeout and will boot into that image.

Grub-dual-boot-1-0

Let’s look again at the status. It’s identical, just that the star is next to the newer image, to show it’s the current image it has booted from.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree status
State: idle
Deployments:
● ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2020-11-04T02:21:47Z)
Commit: 820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88
  Diff: 63 downgraded, 20 removed

  ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2021-02-20T07:15:43Z)
Commit: 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f

Also, the current deployment directory is based on the new commit:

root@photon-7c2d910d79e9 [ ~ ]# ostree admin config-diff --print-current-dir
/ostree/deploy/photon/deploy/820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88.0

A fresh upgrade for a new version will delete the older, original image and bring a new one, that will become the new default image. The previous ‘default’ image will move down one position as the backup image.

Listing file differences

Now we can look at what files have been Added, Modified, Deleted due to the addition of those three packages and switching of the boot directories, by comparing the two commits.

root@photon-7c2d910d79e9 [ ~ ]# ostree diff 820b 965c
M    /usr/bin/VGAuthService
M    /usr/bin/[
M    /usr/bin/asn1Coding
M    /usr/bin/asn1Decoding
M    /usr/bin/asn1Parser
M    /usr/bin/attr
M    /usr/bin/aulast
M    /usr/bin/aulastlog
M    /usr/bin/ausyscall
M    /usr/bin/auvirt
M    /usr/bin/b2sum
M    /usr/bin/base32
M    /usr/bin/base64
M    /usr/bin/basename
M    /usr/bin/basenc
M    /usr/bin/bash
M    /usr/bin/bc
M    /usr/bin/bootctl
M    /usr/bin/bsdcat
M    /usr/bin/bsdcpio
M    /usr/bin/bsdtar
M    /usr/bin/busctl
M    /usr/bin/bwrap
M    /usr/bin/bzip2
M    /usr/bin/bzip2recover
M    /usr/bin/cal
M    /usr/bin/captest
M    /usr/bin/cat
M    /usr/bin/certtool
M    /usr/bin/certutil
M    /usr/bin/chage
M    /usr/bin/chattr
M    /usr/bin/chcon
M    /usr/bin/chfn
M    /usr/bin/chgrp
M    /usr/bin/chmem
M    /usr/bin/chmod
M    /usr/bin/choom
M    /usr/bin/chown
M    /usr/bin/chrt
M    /usr/bin/chsh
M    /usr/bin/cksum
M    /usr/bin/clear
M    /usr/bin/cloud-id
M    /usr/bin/cloud-init
M    /usr/bin/col
M    /usr/bin/colcrt
M    /usr/bin/colrm
M    /usr/bin/column
M    /usr/bin/comm
M    /usr/bin/coredumpctl
M    /usr/bin/cp
M    /usr/bin/cpio
M    /usr/bin/csplit
M    /usr/bin/curl
M    /usr/bin/curl-config
M    /usr/bin/cut
M    /usr/bin/cvtsudoers
M    /usr/bin/date
M    /usr/bin/dbus-cleanup-sockets
M    /usr/bin/dbus-daemon
M    /usr/bin/dbus-launch
M    /usr/bin/dbus-monitor
M    /usr/bin/dbus-run-session
M    /usr/bin/dbus-send
M    /usr/bin/dbus-test-tool
M    /usr/bin/dbus-update-activation-environment
M    /usr/bin/dbus-uuidgen
M    /usr/bin/dc
M    /usr/bin/dd
M    /usr/bin/debuginfod
M    /usr/bin/debuginfod-find
M    /usr/bin/deltainfoxml2solv
M    /usr/bin/derb
M    /usr/bin/df
M    /usr/bin/dir
M    /usr/bin/dircolors
M    /usr/bin/dirmngr
M    /usr/bin/dirmngr-client
M    /usr/bin/dirname
M    /usr/bin/dmesg
M    /usr/bin/du
M    /usr/bin/dumpsexp
M    /usr/bin/dumpsolv
M    /usr/bin/echo
M    /usr/bin/eject
M    /usr/bin/env
M    /usr/bin/eu-addr2line
M    /usr/bin/eu-ar
M    /usr/bin/eu-elfclassify
M    /usr/bin/eu-elfcmp
M    /usr/bin/eu-elfcompress
M    /usr/bin/eu-elflint
M    /usr/bin/eu-findtextrel
M    /usr/bin/eu-nm
M    /usr/bin/eu-objdump
M    /usr/bin/eu-ranlib
M    /usr/bin/eu-readelf
M    /usr/bin/eu-size
M    /usr/bin/eu-stack
M    /usr/bin/eu-strings
M    /usr/bin/eu-strip
M    /usr/bin/eu-unstrip
M    /usr/bin/expand
M    /usr/bin/expiry
M    /usr/bin/expr
M    /usr/bin/factor
M    /usr/bin/faillog
M    /usr/bin/fallocate
M    /usr/bin/false
M    /usr/bin/file
M    /usr/bin/filecap
M    /usr/bin/fincore
M    /usr/bin/find
M    /usr/bin/findmnt
M    /usr/bin/finger
M    /usr/bin/flex
M    /usr/bin/flock
M    /usr/bin/fmt
M    /usr/bin/fold
M    /usr/bin/free
M    /usr/bin/fusermount
M    /usr/bin/gawk
M    /usr/bin/gawk-5.1.0
M    /usr/bin/gdbm_dump
M    /usr/bin/gdbm_load
M    /usr/bin/gdbmtool
M    /usr/bin/genbrk
M    /usr/bin/gencat
M    /usr/bin/gencfu
M    /usr/bin/gencnval
M    /usr/bin/gendict
M    /usr/bin/gendiff
M    /usr/bin/genrb
M    /usr/bin/getconf
M    /usr/bin/getent
M    /usr/bin/getfattr
M    /usr/bin/getopt
M    /usr/bin/gnutls-cli
M    /usr/bin/gnutls-cli-debug
M    /usr/bin/gnutls-serv
M    /usr/bin/gpasswd
M    /usr/bin/gpg
M    /usr/bin/gpg-agent
M    /usr/bin/gpg-connect-agent
M    /usr/bin/gpg-error
M    /usr/bin/gpg-wks-server
M    /usr/bin/gpgconf
M    /usr/bin/gpgparsemail
M    /usr/bin/gpgscm
M    /usr/bin/gpgsm
M    /usr/bin/gpgsplit
M    /usr/bin/gpgtar
M    /usr/bin/gpgv
M    /usr/bin/grep
M    /usr/bin/groups
M    /usr/bin/grub2-editenv
M    /usr/bin/grub2-file
M    /usr/bin/grub2-fstest
M    /usr/bin/grub2-glue-efi
M    /usr/bin/grub2-menulst2cfg
M    /usr/bin/grub2-mkimage
M    /usr/bin/grub2-mklayout
M    /usr/bin/grub2-mknetdir
M    /usr/bin/grub2-mkpasswd-pbkdf2
M    /usr/bin/grub2-mkrelpath
M    /usr/bin/grub2-mkrescue
M    /usr/bin/grub2-mkstandalone
M    /usr/bin/grub2-render-label
M    /usr/bin/grub2-script-check
M    /usr/bin/grub2-syslinux2cfg
M    /usr/bin/gss-client
M    /usr/bin/guile
M    /usr/bin/gzip
M    /usr/bin/hardlink
M    /usr/bin/head
M    /usr/bin/hexdump
M    /usr/bin/hmac256
M    /usr/bin/hostid
M    /usr/bin/hostname
M    /usr/bin/hostnamectl
M    /usr/bin/iconv
M    /usr/bin/icuinfo
M    /usr/bin/id
M    /usr/bin/infocmp
M    /usr/bin/install
M    /usr/bin/installcheck
M    /usr/bin/ionice
M    /usr/bin/ipcmk
M    /usr/bin/ipcrm
M    /usr/bin/ipcs
M    /usr/bin/irqtop
M    /usr/bin/isosize
M    /usr/bin/join
M    /usr/bin/journalctl
M    /usr/bin/js78
M    /usr/bin/json-glib-format
M    /usr/bin/json-glib-validate
M    /usr/bin/kadmin
M    /usr/bin/kbxutil
M    /usr/bin/kdestroy
M    /usr/bin/kernel-install
M    /usr/bin/kill
M    /usr/bin/kinit
M    /usr/bin/klist
M    /usr/bin/kmod
M    /usr/bin/kpasswd
M    /usr/bin/kswitch
M    /usr/bin/ktutil
M    /usr/bin/kvno
M    /usr/bin/last
M    /usr/bin/lastlog
M    /usr/bin/ldapcompare
M    /usr/bin/ldapdelete
M    /usr/bin/ldapexop
M    /usr/bin/ldapmodify
M    /usr/bin/ldapmodrdn
M    /usr/bin/ldappasswd
M    /usr/bin/ldapsearch
M    /usr/bin/ldapurl
M    /usr/bin/ldapwhoami
M    /usr/bin/libtool
M    /usr/bin/link
M    /usr/bin/ln
M    /usr/bin/locale
M    /usr/bin/localectl
M    /usr/bin/localedef
M    /usr/bin/locate
M    /usr/bin/logger
M    /usr/bin/login
M    /usr/bin/loginctl
M    /usr/bin/logname
M    /usr/bin/look
M    /usr/bin/ls
M    /usr/bin/lsattr
M    /usr/bin/lsblk
M    /usr/bin/lscpu
M    /usr/bin/lsipc
M    /usr/bin/lsirq
M    /usr/bin/lslocks
M    /usr/bin/lslogins
M    /usr/bin/lsmem
M    /usr/bin/lsns
M    /usr/bin/lua
M    /usr/bin/luac
M    /usr/bin/lz4
M    /usr/bin/lzmadec
M    /usr/bin/lzmainfo
M    /usr/bin/m4
M    /usr/bin/makeconv
M    /usr/bin/makedb
M    /usr/bin/mcookie
M    /usr/bin/md5sum
M    /usr/bin/mergesolv
M    /usr/bin/mesg
M    /usr/bin/mkdir
M    /usr/bin/mkfifo
M    /usr/bin/mkinitrd
M    /usr/bin/mknod
M    /usr/bin/mktemp
M    /usr/bin/modulemd-validator
M    /usr/bin/more
M    /usr/bin/mount
M    /usr/bin/mountpoint
M    /usr/bin/mpicalc
M    /usr/bin/mt
M    /usr/bin/mv
M    /usr/bin/namei
M    /usr/bin/netcap
M    /usr/bin/netstat
M    /usr/bin/nettle-hash
M    /usr/bin/nettle-lfib-stream
M    /usr/bin/nettle-pbkdf2
M    /usr/bin/networkctl
M    /usr/bin/newgidmap
M    /usr/bin/newgrp
M    /usr/bin/newrole
M    /usr/bin/newuidmap
M    /usr/bin/nice
M    /usr/bin/nl
M    /usr/bin/nohup
M    /usr/bin/nproc
M    /usr/bin/nsenter
M    /usr/bin/numfmt
M    /usr/bin/ocsptool
M    /usr/bin/od
M    /usr/bin/openssl
M    /usr/bin/ostree
M    /usr/bin/passwd
M    /usr/bin/paste
M    /usr/bin/pathchk
M    /usr/bin/pcregrep
M    /usr/bin/pcretest
M    /usr/bin/pgrep
M    /usr/bin/pidof
M    /usr/bin/pinentry-curses
M    /usr/bin/pinentry-tty
M    /usr/bin/ping
M    /usr/bin/pinky
M    /usr/bin/pk-example-frobnicate
M    /usr/bin/pk12util
M    /usr/bin/pkaction
M    /usr/bin/pkcheck
M    /usr/bin/pkcs1-conv
M    /usr/bin/pkexec
M    /usr/bin/pkg-config
M    /usr/bin/pkgdata
M    /usr/bin/pkill
M    /usr/bin/pkttyagent
M    /usr/bin/pmap
M    /usr/bin/portablectl
M    /usr/bin/pr
M    /usr/bin/printenv
M    /usr/bin/printf
M    /usr/bin/prlimit
M    /usr/bin/ps
M    /usr/bin/pscap
M    /usr/bin/psktool
M    /usr/bin/ptx
M    /usr/bin/pwd
M    /usr/bin/pwdx
M    /usr/bin/pwmake
M    /usr/bin/pwscore
M    /usr/bin/pydoc3
M    /usr/bin/python3
M    /usr/bin/readlink
M    /usr/bin/realpath
M    /usr/bin/rename
M    /usr/bin/renice
M    /usr/bin/repo2solv
M    /usr/bin/repomdxml2solv
M    /usr/bin/resolvectl
M    /usr/bin/rev
M    /usr/bin/rm
M    /usr/bin/rmdir
M    /usr/bin/rofiles-fuse
M    /usr/bin/rpcgen
M    /usr/bin/rpm
M    /usr/bin/rpm-ostree
M    /usr/bin/rpm2archive
M    /usr/bin/rpm2cpio
M    /usr/bin/rpmdb
M    /usr/bin/rpmdb2solv
M    /usr/bin/rpmgraph
M    /usr/bin/rpmkeys
M    /usr/bin/rpmmd2solv
M    /usr/bin/rpms2solv
M    /usr/bin/runcon
M    /usr/bin/sclient
M    /usr/bin/scp
M    /usr/bin/script
M    /usr/bin/scriptlive
M    /usr/bin/scriptreplay
M    /usr/bin/secon
M    /usr/bin/sed
M    /usr/bin/seq
M    /usr/bin/setarch
M    /usr/bin/setfattr
M    /usr/bin/setsid
M    /usr/bin/setterm
M    /usr/bin/sexp-conv
M    /usr/bin/sftp
M    /usr/bin/sha1sum
M    /usr/bin/sha224sum
M    /usr/bin/sha256sum
M    /usr/bin/sha384sum
M    /usr/bin/sha512sum
M    /usr/bin/shred
M    /usr/bin/shuf
M    /usr/bin/sim_client
M    /usr/bin/slabtop
M    /usr/bin/sleep
M    /usr/bin/sort
M    /usr/bin/split
M    /usr/bin/srptool
M    /usr/bin/ssh
M    /usr/bin/ssh-add
M    /usr/bin/ssh-agent
M    /usr/bin/ssh-keygen
M    /usr/bin/ssh-keyscan
M    /usr/bin/stat
M    /usr/bin/stdbuf
M    /usr/bin/stty
M    /usr/bin/su
M    /usr/bin/sudo
M    /usr/bin/sudoreplay
M    /usr/bin/sum
M    /usr/bin/sync
M    /usr/bin/systemctl
M    /usr/bin/systemd-analyze
M    /usr/bin/systemd-ask-password
M    /usr/bin/systemd-cat
M    /usr/bin/systemd-cgls
M    /usr/bin/systemd-cgtop
M    /usr/bin/systemd-delta
M    /usr/bin/systemd-detect-virt
M    /usr/bin/systemd-escape
M    /usr/bin/systemd-hwdb
M    /usr/bin/systemd-id128
M    /usr/bin/systemd-inhibit
M    /usr/bin/systemd-machine-id-setup
M    /usr/bin/systemd-mount
M    /usr/bin/systemd-notify
M    /usr/bin/systemd-path
M    /usr/bin/systemd-repart
M    /usr/bin/systemd-run
M    /usr/bin/systemd-socket-activate
M    /usr/bin/systemd-stdio-bridge
M    /usr/bin/systemd-tmpfiles
M    /usr/bin/systemd-tty-ask-password-agent
M    /usr/bin/tabs
M    /usr/bin/tac
M    /usr/bin/tail
M    /usr/bin/taskset
M    /usr/bin/tee
M    /usr/bin/test
M    /usr/bin/testsolv
M    /usr/bin/tic
M    /usr/bin/timedatectl
M    /usr/bin/timeout
M    /usr/bin/tload
M    /usr/bin/toe
M    /usr/bin/top
M    /usr/bin/touch
M    /usr/bin/tput
M    /usr/bin/tr
M    /usr/bin/tracepath
M    /usr/bin/traceroute6
M    /usr/bin/true
M    /usr/bin/truncate
M    /usr/bin/tset
M    /usr/bin/tsort
M    /usr/bin/tty
M    /usr/bin/uconv
M    /usr/bin/udevadm
M    /usr/bin/ul
M    /usr/bin/ulockmgr_server
M    /usr/bin/umount
M    /usr/bin/uname
M    /usr/bin/unexpand
M    /usr/bin/uniq
M    /usr/bin/unlink
M    /usr/bin/unshare
M    /usr/bin/unzck
M    /usr/bin/updateinfoxml2solv
M    /usr/bin/uptime
M    /usr/bin/userdbctl
M    /usr/bin/users
M    /usr/bin/utmpdump
M    /usr/bin/uuclient
M    /usr/bin/uuidgen
M    /usr/bin/uuidparse
M    /usr/bin/vdir
M    /usr/bin/vim
M    /usr/bin/vmhgfs-fuse
M    /usr/bin/vmstat
M    /usr/bin/vmtoolsd
M    /usr/bin/vmware-checkvm
M    /usr/bin/vmware-hgfsclient
M    /usr/bin/vmware-namespace-cmd
M    /usr/bin/vmware-rpctool
M    /usr/bin/vmware-toolbox-cmd
M    /usr/bin/vmware-vgauth-cmd
M    /usr/bin/vmware-vgauth-smoketest
M    /usr/bin/vmware-vmblock-fuse
M    /usr/bin/vmware-xferlogs
M    /usr/bin/w
M    /usr/bin/wall
M    /usr/bin/watch
M    /usr/bin/watchgnupg
M    /usr/bin/wc
M    /usr/bin/wdctl
M    /usr/bin/whereis
M    /usr/bin/which
M    /usr/bin/who
M    /usr/bin/whoami
M    /usr/bin/xargs
M    /usr/bin/xmlcatalog
M    /usr/bin/xmllint
M    /usr/bin/xmlsec1
M    /usr/bin/xmlwf
M    /usr/bin/xsltproc
M    /usr/bin/xz
M    /usr/bin/xzdec
M    /usr/bin/yat2m
M    /usr/bin/yes
M    /usr/bin/zck
M    /usr/bin/zck_delta_size
M    /usr/bin/zck_gen_zdict
M    /usr/bin/zck_read_header
M    /usr/bin/zckdl
M    /usr/bin/zstd
M    /usr/bin/rpm-ostree-server/mkostreerepo
M    /usr/etc/ld.so.cache
M    /usr/etc/photon-release
M    /usr/etc/shadow
M    /usr/etc/sudoers
M    /usr/etc/cloud/cloud.cfg
M    /usr/etc/iproute2/rt_protos
M    /usr/etc/pam.d/vmtoolsd
M    /usr/etc/systemd/journald.conf
M    /usr/etc/systemd/logind.conf
M    /usr/etc/systemd/networkd.conf
M    /usr/etc/systemd/resolved.conf
M    /usr/etc/systemd/system.conf
M    /usr/etc/systemd/user.conf
M    /usr/etc/udev/hwdb.bin
M    /usr/etc/udev/udev.conf
M    /usr/etc/udev/rules.d/99-vmware-hotplug.rules
M    /usr/etc/vmware-tools/tools.conf.example
M    /usr/etc/vmware-tools/vgauth.conf
M    /usr/include/sudo_plugin.h
M    /usr/lib/e2initrd_helper
M    /usr/lib/ld-2.32.so
M    /usr/lib/libBrokenLocale-2.32.so
M    /usr/lib/libDeployPkg.so.0.0.0
M    /usr/lib/libSegFault.so
M    /usr/lib/libacl.so.1.1.2253
M    /usr/lib/libanl-2.32.so
M    /usr/lib/libarchive.so.13.4.3
M    /usr/lib/libasm-0.181.so
M    /usr/lib/libassuan.so.0.8.3
M    /usr/lib/libattr.so.1.1.2448
M    /usr/lib/libaudit.so.1.0.0
M    /usr/lib/libauparse.so.0.0.0
M    /usr/lib/libblkid.so.1.1.0
M    /usr/lib/libbz2.so.1.0.8
M    /usr/lib/libc-2.32.so
M    /usr/lib/libcap-ng.so.0.0.0
M    /usr/lib/libcap.so.2.43
M    /usr/lib/libcom_err.so.2.1
M    /usr/lib/libcord.so.1.4.0
M    /usr/lib/libcrack.so.2.9.0
M    /usr/lib/libcrypt-2.32.so
M    /usr/lib/libcrypto.so.1.1
M    /usr/lib/libcurl.so.4
M    /usr/lib/libdb-5.3.so
M    /usr/lib/libdbus-1.so.3.29.0
M    /usr/lib/libdebuginfod-0.181.so
M    /usr/lib/libdevmapper.so.1.02
M    /usr/lib/libdhcp.a
M    /usr/lib/libdhcpctl.a
M    /usr/lib/libdl-2.32.so
M    /usr/lib/libdnet.1.0.1
M    /usr/lib/libdw-0.181.so
M    /usr/lib/libe2p.so.2.3
M    /usr/lib/libelf-0.181.so
M    /usr/lib/libexpat.so.1.6.11
M    /usr/lib/libexslt.so.0.8.20
M    /usr/lib/libext2fs.so.2.4
M    /usr/lib/libfdisk.so.1.1.0
M    /usr/lib/libffi.so.7.1.0
M    /usr/lib/libfl.so.2.0.0
M    /usr/lib/libformw.so.6.2
M    /usr/lib/libfreebl3.chk
M    /usr/lib/libfreebl3.so
M    /usr/lib/libfreeblpriv3.chk
M    /usr/lib/libfreeblpriv3.so
M    /usr/lib/libfuse.so.2.9.9
M    /usr/lib/libgc.so.1.4.3
M    /usr/lib/libgcc_s.so.1
M    /usr/lib/libgccpp.so.1.4.0
M    /usr/lib/libgcrypt.so.20.2.6
M    /usr/lib/libgdbm.so.6.0.0
M    /usr/lib/libgdbm_compat.so.4.0.0
M    /usr/lib/libgio-2.0.so.0.6600.1
M    /usr/lib/libgirepository-1.0.so.1.0.0
M    /usr/lib/libglib-2.0.so.0.6600.1
M    /usr/lib/libgmodule-2.0.so.0.6600.1
M    /usr/lib/libgmp.so.10.4.0
M    /usr/lib/libgnutls.so.30.28.1
M    /usr/lib/libgnutlsxx.so.28.1.0
M    /usr/lib/libgobject-2.0.so.0.6600.1
M    /usr/lib/libgpg-error.so.0.30.0
M    /usr/lib/libgpgme.so.11.23.0
M    /usr/lib/libgssapi_krb5.so.2.2
M    /usr/lib/libgssrpc.so.4.2
M    /usr/lib/libgthread-2.0.so.0.6600.1
M    /usr/lib/libguestlib.so.0.0.0
M    /usr/lib/libguile-2.0.so.22.8.1
M    /usr/lib/libguilereadline-v-18.so.18.0.0
M    /usr/lib/libhgfs.so.0.0.0
M    /usr/lib/libhistory.so.7.0
M    /usr/lib/libhogweed.so.6.0
M    /usr/lib/libicui18n.so.67.1
M    /usr/lib/libicuio.so.67.1
M    /usr/lib/libicutest.so.67.1
M    /usr/lib/libicutu.so.67.1
M    /usr/lib/libicuuc.so.67.1
M    /usr/lib/libip4tc.so.2.0.0
M    /usr/lib/libip6tc.so.2.0.0
M    /usr/lib/libipq.so.0.0.0
M    /usr/lib/libjson-c.so.5.1.0
M    /usr/lib/libjson-glib-1.0.so.0.600.0
M    /usr/lib/libk5crypto.so.3.1
M    /usr/lib/libkadm5clnt_mit.so.11.0
M    /usr/lib/libkadm5srv_mit.so.11.0
M    /usr/lib/libkdb5.so.9.0
M    /usr/lib/libkmod.so.2.3.5
M    /usr/lib/libkrad.so.0.0
M    /usr/lib/libkrb5.so.3.3
M    /usr/lib/libkrb5support.so.0.1
M    /usr/lib/libksba.so.8.12.0
M    /usr/lib/liblber-2.4.so.2.11.1
M    /usr/lib/libldap-2.4.so.2.11.1
M    /usr/lib/libldap_r-2.4.so.2.11.1
M    /usr/lib/libltdl.so.7.3.1
M    /usr/lib/liblua.so.5.3.4
M    /usr/lib/liblz4.so.1.9.2
M    /usr/lib/liblzma.so.5.2.5
M    /usr/lib/libm-2.32.so
M    /usr/lib/libmagic.so.1.0.0
M    /usr/lib/libmemusage.so
M    /usr/lib/libmenuw.so.6.2
M    /usr/lib/libmetalink.so.3.1.0
M    /usr/lib/libmicrohttpd.so.12.56.0
M    /usr/lib/libmodulemd.so.2
M    /usr/lib/libmount.so.1.1.0
M    /usr/lib/libmozjs-78.so
M    /usr/lib/libmpfr.so.6.1.0
M    /usr/lib/libmspack.so.0.1.0
M    /usr/lib/libmvec-2.32.so
M    /usr/lib/libncursesw.so.6.2
M    /usr/lib/libnettle.so.8.0
M    /usr/lib/libnpth.so.0.1.2
M    /usr/lib/libnsl-2.32.so
M    /usr/lib/libnsl.so.2.0.1
M    /usr/lib/libnspr4.so
M    /usr/lib/libnss3.so
M    /usr/lib/libnss_altfiles.so.2
M    /usr/lib/libnss_compat-2.32.so
M    /usr/lib/libnss_db-2.32.so
M    /usr/lib/libnss_dns-2.32.so
M    /usr/lib/libnss_files-2.32.so
M    /usr/lib/libnss_hesiod-2.32.so
M    /usr/lib/libnss_myhostname.so.2
M    /usr/lib/libnss_mymachines.so.2
M    /usr/lib/libnss_resolve.so.2
M    /usr/lib/libnss_systemd.so.2
M    /usr/lib/libnssckbi-testlib.so
M    /usr/lib/libnssckbi.so
M    /usr/lib/libnssdbm3.chk
M    /usr/lib/libnssdbm3.so
M    /usr/lib/libnsssysinit.so
M    /usr/lib/libnssutil3.so
M    /usr/lib/libomapi.a
M    /usr/lib/libopts.so.25.17.1
M    /usr/lib/libostree-1.so.1.0.0
M    /usr/lib/libpam.so.0.85.1
M    /usr/lib/libpam_misc.so.0.82.1
M    /usr/lib/libpamc.so.0.82.1
M    /usr/lib/libpanelw.so.6.2
M    /usr/lib/libpcre.so.1.2.12
M    /usr/lib/libpcre16.so.0.2.12
M    /usr/lib/libpcre32.so.0.0.12
M    /usr/lib/libpcrecpp.so.0.0.2
M    /usr/lib/libpcreposix.so.0.0.7
M    /usr/lib/libpkcs11testmodule.so
M    /usr/lib/libplc4.so
M    /usr/lib/libplds4.so
M    /usr/lib/libpolkit-agent-1.so.0.0.0
M    /usr/lib/libpolkit-gobject-1.so.0.0.0
M    /usr/lib/libpopt.so.0.0.0
M    /usr/lib/libprocps.so.8.0.2
M    /usr/lib/libpsl.so.5.3.3
M    /usr/lib/libpthread-2.32.so
M    /usr/lib/libpwquality.so.1.0.2
M    /usr/lib/libpython3.so
M    /usr/lib/libreadline.so.7.0
M    /usr/lib/librepo.so.0
M    /usr/lib/libresolv-2.32.so
M    /usr/lib/librpmostree-1.so.1.0.0
M    /usr/lib/librt-2.32.so
M    /usr/lib/libsasl2.so.3.0.0
M    /usr/lib/libseccomp.so.2.5.0
M    /usr/lib/libselinux.so.1
M    /usr/lib/libsemanage.so.1
M    /usr/lib/libsepol.so.1
M    /usr/lib/libsmartcols.so.1.1.0
M    /usr/lib/libsmime3.so
M    /usr/lib/libsoftokn3.chk
M    /usr/lib/libsoftokn3.so
M    /usr/lib/libsolv.so.0
M    /usr/lib/libsolvext.so.0
M    /usr/lib/libsoup-2.4.so.1.11.0
M    /usr/lib/libsoup-gnome-2.4.so.1.11.0
M    /usr/lib/libsqlite3.so.0.8.6
M    /usr/lib/libss.so.2.0
M    /usr/lib/libssh2.so.1.0.1
M    /usr/lib/libssl.so.1.1
M    /usr/lib/libssl3.so
M    /usr/lib/libstdc++.so.6
M    /usr/lib/libsystemd.so.0
M    /usr/lib/libtasn1.so.6.5.6
M    /usr/lib/libthread_db-1.0.so
M    /usr/lib/libtirpc.so.3.0.0
M    /usr/lib/libudev.so.1
M    /usr/lib/libulockmgr.so.1.0.1
M    /usr/lib/libunistring.a
M    /usr/lib/libunistring.so.2.1.0
M    /usr/lib/libutil-2.32.so
M    /usr/lib/libuuid.so.1.3.0
M    /usr/lib/libverto.so.0.0
M    /usr/lib/libvgauth.so.0.0.0
M    /usr/lib/libvmtools.so.0.0.0
M    /usr/lib/libwrap.a
M    /usr/lib/libwrap.so.0.7.6
M    /usr/lib/libxml2.so.2.9.10
M    /usr/lib/libxmlsec1-nss.so.1.2.30
M    /usr/lib/libxmlsec1-openssl.so.1.2.30
M    /usr/lib/libxmlsec1.so.1.2.30
M    /usr/lib/libxslt.so.1.1.34
M    /usr/lib/libxtables.so.12
M    /usr/lib/libyaml-0.so.2.0.9
M    /usr/lib/libz.so.1.2.11
M    /usr/lib/libzck.so.1.1.7
M    /usr/lib/libzstd.so.1.4.5
M    /usr/lib/bash/basename
M    /usr/lib/bash/dirname
M    /usr/lib/bash/fdflags
M    /usr/lib/bash/finfo
M    /usr/lib/bash/head
M    /usr/lib/bash/id
M    /usr/lib/bash/ln
M    /usr/lib/bash/logname
M    /usr/lib/bash/mkdir
M    /usr/lib/bash/mypid
M    /usr/lib/bash/pathchk
M    /usr/lib/bash/print
M    /usr/lib/bash/printenv
M    /usr/lib/bash/push
M    /usr/lib/bash/realpath
M    /usr/lib/bash/rmdir
M    /usr/lib/bash/seq
M    /usr/lib/bash/setpgid
M    /usr/lib/bash/sleep
M    /usr/lib/bash/strftime
M    /usr/lib/bash/sync
M    /usr/lib/bash/tee
M    /usr/lib/bash/truefalse
M    /usr/lib/bash/tty
M    /usr/lib/bash/uname
M    /usr/lib/bash/unlink
M    /usr/lib/bash/whoami
M    /usr/lib/cloud-init/ds-identify
M    /usr/lib/dracut/dracut-install
M    /usr/lib/dracut/dracut-version.sh
M    /usr/lib/dracut/skipcpio
M    /usr/lib/engines-1.1/afalg.so
M    /usr/lib/engines-1.1/capi.so
M    /usr/lib/engines-1.1/padlock.so
M    /usr/lib/gawk/filefuncs.so
M    /usr/lib/gawk/fnmatch.so
M    /usr/lib/gawk/fork.so
M    /usr/lib/gawk/inplace.so
M    /usr/lib/gawk/intdiv.so
M    /usr/lib/gawk/ordchr.so
M    /usr/lib/gawk/readdir.so
M    /usr/lib/gawk/readfile.so
M    /usr/lib/gawk/revoutput.so
M    /usr/lib/gawk/revtwoway.so
M    /usr/lib/gawk/rwarray.so
M    /usr/lib/gawk/time.so
M    /usr/lib/gconv/ANSI_X3.110.so
M    /usr/lib/gconv/ARMSCII-8.so
M    /usr/lib/gconv/ASMO_449.so
M    /usr/lib/gconv/BIG5.so
M    /usr/lib/gconv/BIG5HKSCS.so
M    /usr/lib/gconv/BRF.so
M    /usr/lib/gconv/CP10007.so
M    /usr/lib/gconv/CP1125.so
M    /usr/lib/gconv/CP1250.so
M    /usr/lib/gconv/CP1251.so
M    /usr/lib/gconv/CP1252.so
M    /usr/lib/gconv/CP1253.so
M    /usr/lib/gconv/CP1254.so
M    /usr/lib/gconv/CP1255.so
M    /usr/lib/gconv/CP1256.so
M    /usr/lib/gconv/CP1257.so
M    /usr/lib/gconv/CP1258.so
M    /usr/lib/gconv/CP737.so
M    /usr/lib/gconv/CP770.so
M    /usr/lib/gconv/CP771.so
M    /usr/lib/gconv/CP772.so
M    /usr/lib/gconv/CP773.so
M    /usr/lib/gconv/CP774.so
M    /usr/lib/gconv/CP775.so
M    /usr/lib/gconv/CP932.so
M    /usr/lib/gconv/CSN_369103.so
M    /usr/lib/gconv/CWI.so
M    /usr/lib/gconv/DEC-MCS.so
M    /usr/lib/gconv/EBCDIC-AT-DE-A.so
M    /usr/lib/gconv/EBCDIC-AT-DE.so
M    /usr/lib/gconv/EBCDIC-CA-FR.so
M    /usr/lib/gconv/EBCDIC-DK-NO-A.so
M    /usr/lib/gconv/EBCDIC-DK-NO.so
M    /usr/lib/gconv/EBCDIC-ES-A.so
M    /usr/lib/gconv/EBCDIC-ES-S.so
M    /usr/lib/gconv/EBCDIC-ES.so
M    /usr/lib/gconv/EBCDIC-FI-SE-A.so
M    /usr/lib/gconv/EBCDIC-FI-SE.so
M    /usr/lib/gconv/EBCDIC-FR.so
M    /usr/lib/gconv/EBCDIC-IS-FRISS.so
M    /usr/lib/gconv/EBCDIC-IT.so
M    /usr/lib/gconv/EBCDIC-PT.so
M    /usr/lib/gconv/EBCDIC-UK.so
M    /usr/lib/gconv/EBCDIC-US.so
M    /usr/lib/gconv/ECMA-CYRILLIC.so
M    /usr/lib/gconv/EUC-CN.so
M    /usr/lib/gconv/EUC-JISX0213.so
M    /usr/lib/gconv/EUC-JP-MS.so
M    /usr/lib/gconv/EUC-JP.so
M    /usr/lib/gconv/EUC-KR.so
M    /usr/lib/gconv/EUC-TW.so
M    /usr/lib/gconv/GB18030.so
M    /usr/lib/gconv/GBBIG5.so
M    /usr/lib/gconv/GBGBK.so
M    /usr/lib/gconv/GBK.so
M    /usr/lib/gconv/GEORGIAN-ACADEMY.so
M    /usr/lib/gconv/GEORGIAN-PS.so
M    /usr/lib/gconv/GOST_19768-74.so
M    /usr/lib/gconv/GREEK-CCITT.so
M    /usr/lib/gconv/GREEK7-OLD.so
M    /usr/lib/gconv/GREEK7.so
M    /usr/lib/gconv/HP-GREEK8.so
M    /usr/lib/gconv/HP-ROMAN8.so
M    /usr/lib/gconv/HP-ROMAN9.so
M    /usr/lib/gconv/HP-THAI8.so
M    /usr/lib/gconv/HP-TURKISH8.so
M    /usr/lib/gconv/IBM037.so
M    /usr/lib/gconv/IBM038.so
M    /usr/lib/gconv/IBM1004.so
M    /usr/lib/gconv/IBM1008.so
M    /usr/lib/gconv/IBM1008_420.so
M    /usr/lib/gconv/IBM1025.so
M    /usr/lib/gconv/IBM1026.so
M    /usr/lib/gconv/IBM1046.so
M    /usr/lib/gconv/IBM1047.so
M    /usr/lib/gconv/IBM1097.so
M    /usr/lib/gconv/IBM1112.so
M    /usr/lib/gconv/IBM1122.so
M    /usr/lib/gconv/IBM1123.so
M    /usr/lib/gconv/IBM1124.so
M    /usr/lib/gconv/IBM1129.so
M    /usr/lib/gconv/IBM1130.so
M    /usr/lib/gconv/IBM1132.so
M    /usr/lib/gconv/IBM1133.so
M    /usr/lib/gconv/IBM1137.so
M    /usr/lib/gconv/IBM1140.so
M    /usr/lib/gconv/IBM1141.so
M    /usr/lib/gconv/IBM1142.so
M    /usr/lib/gconv/IBM1143.so
M    /usr/lib/gconv/IBM1144.so
M    /usr/lib/gconv/IBM1145.so
M    /usr/lib/gconv/IBM1146.so
M    /usr/lib/gconv/IBM1147.so
M    /usr/lib/gconv/IBM1148.so
M    /usr/lib/gconv/IBM1149.so
M    /usr/lib/gconv/IBM1153.so
M    /usr/lib/gconv/IBM1154.so
M    /usr/lib/gconv/IBM1155.so
M    /usr/lib/gconv/IBM1156.so
M    /usr/lib/gconv/IBM1157.so
M    /usr/lib/gconv/IBM1158.so
M    /usr/lib/gconv/IBM1160.so
M    /usr/lib/gconv/IBM1161.so
M    /usr/lib/gconv/IBM1162.so
M    /usr/lib/gconv/IBM1163.so
M    /usr/lib/gconv/IBM1164.so
M    /usr/lib/gconv/IBM1166.so
M    /usr/lib/gconv/IBM1167.so
M    /usr/lib/gconv/IBM12712.so
M    /usr/lib/gconv/IBM1364.so
M    /usr/lib/gconv/IBM1371.so
M    /usr/lib/gconv/IBM1388.so
M    /usr/lib/gconv/IBM1390.so
M    /usr/lib/gconv/IBM1399.so
M    /usr/lib/gconv/IBM16804.so
M    /usr/lib/gconv/IBM256.so
M    /usr/lib/gconv/IBM273.so
M    /usr/lib/gconv/IBM274.so
M    /usr/lib/gconv/IBM275.so
M    /usr/lib/gconv/IBM277.so
M    /usr/lib/gconv/IBM278.so
M    /usr/lib/gconv/IBM280.so
M    /usr/lib/gconv/IBM281.so
M    /usr/lib/gconv/IBM284.so
M    /usr/lib/gconv/IBM285.so
M    /usr/lib/gconv/IBM290.so
M    /usr/lib/gconv/IBM297.so
M    /usr/lib/gconv/IBM420.so
M    /usr/lib/gconv/IBM423.so
M    /usr/lib/gconv/IBM424.so
M    /usr/lib/gconv/IBM437.so
M    /usr/lib/gconv/IBM4517.so
M    /usr/lib/gconv/IBM4899.so
M    /usr/lib/gconv/IBM4909.so
M    /usr/lib/gconv/IBM4971.so
M    /usr/lib/gconv/IBM500.so
M    /usr/lib/gconv/IBM5347.so
M    /usr/lib/gconv/IBM803.so
M    /usr/lib/gconv/IBM850.so
M    /usr/lib/gconv/IBM851.so
M    /usr/lib/gconv/IBM852.so
M    /usr/lib/gconv/IBM855.so
M    /usr/lib/gconv/IBM856.so
M    /usr/lib/gconv/IBM857.so
M    /usr/lib/gconv/IBM858.so
M    /usr/lib/gconv/IBM860.so
M    /usr/lib/gconv/IBM861.so
M    /usr/lib/gconv/IBM862.so
M    /usr/lib/gconv/IBM863.so
M    /usr/lib/gconv/IBM864.so
M    /usr/lib/gconv/IBM865.so
M    /usr/lib/gconv/IBM866.so
M    /usr/lib/gconv/IBM866NAV.so
M    /usr/lib/gconv/IBM868.so
M    /usr/lib/gconv/IBM869.so
M    /usr/lib/gconv/IBM870.so
M    /usr/lib/gconv/IBM871.so
M    /usr/lib/gconv/IBM874.so
M    /usr/lib/gconv/IBM875.so
M    /usr/lib/gconv/IBM880.so
M    /usr/lib/gconv/IBM891.so
M    /usr/lib/gconv/IBM901.so
M    /usr/lib/gconv/IBM902.so
M    /usr/lib/gconv/IBM903.so
M    /usr/lib/gconv/IBM9030.so
M    /usr/lib/gconv/IBM904.so
M    /usr/lib/gconv/IBM905.so
M    /usr/lib/gconv/IBM9066.so
M    /usr/lib/gconv/IBM918.so
M    /usr/lib/gconv/IBM921.so
M    /usr/lib/gconv/IBM922.so
M    /usr/lib/gconv/IBM930.so
M    /usr/lib/gconv/IBM932.so
M    /usr/lib/gconv/IBM933.so
M    /usr/lib/gconv/IBM935.so
M    /usr/lib/gconv/IBM937.so
M    /usr/lib/gconv/IBM939.so
M    /usr/lib/gconv/IBM943.so
M    /usr/lib/gconv/IBM9448.so
M    /usr/lib/gconv/IEC_P27-1.so

Listing package differences

We can also look at package differences, as you expect, using the right tool for the job.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree db diff 820b 965c
ostree diff commit from: 820b (820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88)
ostree diff commit to:   965c (965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f)
Upgraded:
audit 2.8.5-3.ph5 -> 2.8.5-6.ph5
cloud-init 20.3-2.ph5 -> 20.4.1-1.ph5
cpio 2.13-1.ph5 -> 2.13-3.ph5
curl 7.72.0-2.ph5 -> 7.74.0-1.ph5
curl-libs 7.72.0-2.ph5 -> 7.74.0-1.ph5
cyrus-sasl 2.1.27-3.ph5 -> 2.1.27-4.ph5
dhcp-client 4.4.2-1.ph5 -> 4.4.2-2.ph5
dhcp-libs 4.4.2-1.ph5 -> 4.4.2-2.ph5
dracut 050-5.ph5 -> 050-7.ph5
dracut-tools 050-5.ph5 -> 050-7.ph5
file 5.39-1.ph5 -> 5.39-2.ph5
file-libs 5.39-1.ph5 -> 5.39-2.ph5
gdbm 1.18.1-1.ph5 -> 1.19-1.ph5
glibc 2.32-1.ph5 -> 2.32-2.ph5
glibc-iconv 2.32-1.ph5 -> 2.32-2.ph5
gobject-introspection 1.66.0-1.ph5 -> 1.66.0-3.ph5
grub2-theme 5.0-1.ph5 -> 4.0-2.ph5
grub2-theme-ostree 5.0-1.ph5 -> 5.0-2.ph5
iproute2 5.8.0-1.ph5 -> 5.10.0-1.ph5
iptables 1.8.4-1.ph5 -> 1.8.7-1.ph5
json-c 0.15-2.ph5 -> 0.15-3.ph5
libgcc 8.4.0-1.ph5 -> 10.2.0-1.ph5
libmetalink 0.1.3-2.ph5 -> 0.1.3-3.ph5
libmodulemd 2.9.4-1.ph5 -> 2.11.0-1.ph5
librepo 1.12.1-3.ph5 -> 1.12.1-4.ph5
libsepol 3.1-1.ph5 -> 3.1-2.ph5
libsolv 0.6.35-5.ph5 -> 0.6.35-7.ph5
libssh2 1.9.0-2.ph5 -> 1.9.0-3.ph5
libstdc++ 8.4.0-1.ph5 -> 10.2.0-1.ph5
libxml2 2.9.10-3.ph5 -> 2.9.10-6.ph5
libxml2-devel 2.9.10-3.ph5 -> 2.9.10-6.ph5
libxslt 1.1.34-1.ph5 -> 1.1.34-2.ph5
linux 5.9.0-3.ph5 -> 5.10.4-15.ph5
ncurses 6.2-2.ph5 -> 6.2-3.ph5
ncurses-libs 6.2-2.ph5 -> 6.2-3.ph5
ncurses-terminfo 6.2-2.ph5 -> 6.2-3.ph5
nss 3.57-1.ph5 -> 3.57-2.ph5
nss-libs 3.57-1.ph5 -> 3.57-2.ph5
open-vm-tools 11.1.5-4.ph5 -> 11.2.5-1.ph5
openldap 2.4.53-2.ph5 -> 2.4.53-3.ph5
openssl 1.1.1g-3.ph5 -> 1.1.1i-2.ph5
pcre 8.44-1.ph5 -> 8.44-2.ph5
pcre-libs 8.44-1.ph5 -> 8.44-2.ph5
python3 3.8.6-1.ph5 -> 3.9.1-2.ph5
python3-PyYAML 5.3.1-1.ph5 -> 5.4.1-1.ph5
python3-attrs 20.2.0-2.ph5 -> 20.3.0-2.ph5
python3-cryptography 3.1.1-2.ph5 -> 3.2.1-1.ph5
python3-gobject-introspection 1.66.0-1.ph5 -> 1.66.0-3.ph5
python3-libs 3.8.6-1.ph5 -> 3.9.1-2.ph5
python3-packaging 20.4-2.ph5 -> 20.4-3.ph5
python3-pyrsistent 0.17.3-1.ph5 -> 0.17.3-2.ph5
python3-setuptools 3.8.6-1.ph5 -> 3.9.1-2.ph5
python3-urllib3 1.25.10-2.ph5 -> 1.25.11-1.ph5
python3-xml 3.8.6-1.ph5 -> 3.9.1-2.ph5
rpm 4.14.2-11.ph5 -> 4.16.1.2-1.ph5
rpm-libs 4.14.2-11.ph5 -> 4.16.1.2-1.ph5
rpm-ostree 2020.5-4.ph5 -> 2020.5-5.ph5
shadow 4.8.1-2.ph5 -> 4.8.1-3.ph5
shadow-tools 4.8.1-2.ph5 -> 4.8.1-3.ph5
sudo 1.8.30-2.ph5 -> 1.9.5-1.ph5
systemd 245.5-3.ph5 -> 247.3-1.ph5
util-linux 2.36-1.ph5 -> 2.36-2.ph5
util-linux-libs 2.36-1.ph5 -> 2.36-2.ph5
Added:
libpcap-1.10.0-1.ph5.x86_64
python3-Pygments-2.7.2-2.ph5.noarch
python3-alabaster-0.7.12-1.ph5.noarch
python3-babel-2.8.0-3.ph5.noarch
python3-docutils-0.16-1.ph5.noarch
python3-imagesize-1.2.0-2.ph5.noarch
python3-pytz-2020.4-2.ph5.noarch
python3-snowballstemmer-2.0.0-1.ph5.noarch
python3-sphinx-3.3.0-2.ph5.noarch
python3-sphinxcontrib-applehelp-1.0.2-1.ph5.noarch
python3-sphinxcontrib-devhelp-1.0.2-1.ph5.noarch
python3-sphinxcontrib-htmlhelp-1.0.3-1.ph5.noarch
python3-sphinxcontrib-jsmath-1.0.1-1.ph5.noarch
python3-sphinxcontrib-qthelp-1.0.3-1.ph5.noarch
python3-sphinxcontrib-serializinghtml-1.1.4-1.ph5.noarch
python3-typing-3.7.4.3-1.ph5.noarch
systemd-libs-247.3-1.ph5.x86_64
systemd-pam-247.3-1.ph5.x86_64
systemd-rpm-macros-247.3-1.ph5.noarch
systemd-udev-247.3-1.ph5.x86_64

Rollback

If we want to go back to the previous image, we can rollback. The order of the images will be changed, so the old filetree will become the default bootable image. If -r option is passed, the rollback will continue with a reboot.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree rollback
Moving '965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f.0' to be first deployment
Transaction complete; bootconfig swap: yes; deployment count change: 0
Upgraded:
  audit 2.8.5-3.ph5 -> 2.8.5-6.ph5
  cloud-init 20.3-2.ph5 -> 20.4.1-1.ph5
  cpio 2.13-1.ph5 -> 2.13-3.ph5
  curl 7.72.0-2.ph5 -> 7.74.0-1.ph5
  curl-libs 7.72.0-2.ph5 -> 7.74.0-1.ph5
  cyrus-sasl 2.1.27-3.ph5 -> 2.1.27-4.ph5
  dhcp-client 4.4.2-1.ph5 -> 4.4.2-2.ph5
  dhcp-libs 4.4.2-1.ph5 -> 4.4.2-2.ph5
  dracut 050-5.ph5 -> 050-7.ph5
  dracut-tools 050-5.ph5 -> 050-7.ph5
  file 5.39-1.ph5 -> 5.39-2.ph5
  file-libs 5.39-1.ph5 -> 5.39-2.ph5
  gdbm 1.18.1-1.ph5 -> 1.19-1.ph5
  glibc 2.32-1.ph5 -> 2.32-2.ph5
  glibc-iconv 2.32-1.ph5 -> 2.32-2.ph5
  gobject-introspection 1.66.0-1.ph5 -> 1.66.0-3.ph5
  grub2-theme 5.0-1.ph5 -> 5.0-2.ph5
  grub2-theme-ostree 5.0-1.ph5 -> 5.0-2.ph5
  iproute2 5.8.0-1.ph5 -> 5.10.0-1.ph5
  iptables 1.8.4-1.ph5 -> 1.8.7-1.ph5
  json-c 0.15-2.ph5 -> 0.15-3.ph5
  libgcc 8.4.0-1.ph5 -> 10.2.0-1.ph5
  libmetalink 0.1.3-2.ph5 -> 0.1.3-3.ph5
  libmodulemd 2.9.4-1.ph5 -> 2.11.0-1.ph5
  librepo 1.12.1-3.ph5 -> 1.12.1-4.ph5
  libsepol 3.1-1.ph5 -> 3.1-2.ph5
  libsolv 0.6.35-5.ph5 -> 0.6.35-7.ph5
  libssh2 1.9.0-2.ph5 -> 1.9.0-3.ph5
  libstdc++ 8.4.0-1.ph5 -> 10.2.0-1.ph5
  libxml2 2.9.10-3.ph5 -> 2.9.10-6.ph5
  libxml2-devel 2.9.10-3.ph5 -> 2.9.10-6.ph5
  libxslt 1.1.34-1.ph5 -> 1.1.34-2.ph5
  linux 5.9.0-3.ph5 -> 5.10.4-15.ph5
  ncurses 6.2-2.ph5 -> 6.2-3.ph5
  ncurses-libs 6.2-2.ph5 -> 6.2-3.ph5
  ncurses-terminfo 6.2-2.ph5 -> 6.2-3.ph5
  nss 3.57-1.ph5 -> 3.57-2.ph5
  nss-libs 3.57-1.ph5 -> 3.57-2.ph5
  open-vm-tools 11.1.5-4.ph5 -> 11.2.5-1.ph5
  openldap 2.4.53-2.ph5 -> 2.4.53-3.ph5
  openssl 1.1.1g-3.ph5 -> 1.1.1i-2.ph5
  pcre 8.44-1.ph5 -> 8.44-2.ph5
  pcre-libs 8.44-1.ph5 -> 8.44-2.ph5
  python3 3.8.6-1.ph5 -> 3.9.1-2.ph5
  python3-PyYAML 5.3.1-1.ph5 -> 5.4.1-1.ph5
  python3-attrs 20.2.0-2.ph5 -> 20.3.0-2.ph5
  python3-cryptography 3.1.1-2.ph5 -> 3.2.1-1.ph5
  python3-gobject-introspection 1.66.0-1.ph5 -> 1.66.0-3.ph5
  python3-libs 3.8.6-1.ph5 -> 3.9.1-2.ph5
  python3-packaging 20.4-2.ph5 -> 20.4-3.ph5
  python3-pyrsistent 0.17.3-1.ph5 -> 0.17.3-2.ph5
  python3-setuptools 3.8.6-1.ph5 -> 3.9.1-2.ph5
  python3-urllib3 1.25.10-2.ph5 -> 1.25.11-1.ph5
  python3-xml 3.8.6-1.ph5 -> 3.9.1-2.ph5
  rpm 4.14.2-11.ph5 -> 4.16.1.2-1.ph5
  rpm-libs 4.14.2-11.ph5 -> 4.16.1.2-1.ph5
  rpm-ostree 2020.5-4.ph5 -> 2020.5-5.ph5
  shadow 4.8.1-2.ph5 -> 4.8.1-3.ph5
  shadow-tools 4.8.1-2.ph5 -> 4.8.1-3.ph5
  sudo 1.8.30-2.ph5 -> 1.9.5-1.ph5
  systemd 245.5-3.ph5 -> 247.3-1.ph5
  util-linux 2.36-1.ph5 -> 2.36-2.ph5
  util-linux-libs 2.36-1.ph5 -> 2.36-2.ph5
Added:
  libpcap-1.10.0-1.ph5.x86_64
  python3-Pygments-2.7.2-2.ph5.noarch
  python3-alabaster-0.7.12-1.ph5.noarch
  python3-babel-2.8.0-3.ph5.noarch
  python3-docutils-0.16-1.ph5.noarch
  python3-imagesize-1.2.0-2.ph5.noarch
  python3-pytz-2020.4-2.ph5.noarch
  python3-snowballstemmer-2.0.0-1.ph5.noarch
  python3-sphinx-3.3.0-2.ph5.noarch
  python3-sphinxcontrib-applehelp-1.0.2-1.ph5.noarch
  python3-sphinxcontrib-devhelp-1.0.2-1.ph5.noarch
  python3-sphinxcontrib-htmlhelp-1.0.3-1.ph5.noarch
  python3-sphinxcontrib-jsmath-1.0.1-1.ph5.noarch
  python3-sphinxcontrib-qthelp-1.0.3-1.ph5.noarch
  python3-sphinxcontrib-serializinghtml-1.1.4-1.ph5.noarch
  python3-typing-3.7.4.3-1.ph5.noarch
  systemd-libs-247.3-1.ph5.x86_64
  systemd-pam-247.3-1.ph5.x86_64
  systemd-rpm-macros-247.3-1.ph5.noarch
  systemd-udev-247.3-1.ph5.x86_64
  Run "systemctl reboot" to start a reboot

In fact, we can repeat the rollback operation as many times as we want before reboot. On each execution, it’s going to change the order. It will not delete any image.
However, an upgrade will keep the current default image and will eliminate the other image, whichever that is. So if Photon installation rolled back to an older build, an upgrade will keep that, eliminate the newer version and will replace it with an even newer version at the next upgrade.

The boot order moved back to original:

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree status
State: idle
Deployments:
  ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2021-02-20T07:15:43Z)
Commit: 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f
  Diff: 63 upgraded, 20 added

● ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2020-11-04T02:21:47Z)
Commit: 820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88

The current bootable image path moved also back to the original value:

root@photon-host-def [ ~ ]# ostree admin config-diff --print-current-dir
/ostree/deploy/photon/deploy/47899767bdd4276266383fce13c4a26a51ca0304ae754609283d75f7d8aad36e.0

Installing Packages

You can add more packages onto the system that are not part of the commit composed on the server.

rpm-ostree install <packages>

Example:

rpm-ostree install https://kojipkgs.fedoraproject.org//packages/wget/1.19.5/5.fc29/x86_64/wget-1.19.5-5.fc29.x86_64.rpm

Uninstalling Packages

To remove layered packages installed from a repository, use

rpm-ostree uninstall <pkg>

To remove layered packages installed from a local package, you must specify the full NEVRA of the package.

For example:

rpm-ostree uninstall ltrace-0.7.91-16.fc22.x86_64

To uninstall a package that is a part of the base layer, use

rpm-ostree override remove <pkg>

For example:

rpm-ostree override remove firefox

Deleting a deployed filetree

It is possible to delete a deployed tree. You won’t need to do that normally, as upgrading to a new image will delete the old one, but if for some reason deploying failed (loss of power, networking issues), you’ll want to delete the partially deployed image.
The only supported index is 1. (If multiple bootable images will be supported in the future, a larger than one, zero-based index of the image to delete will be supported).
You cannot delete the default bootable filetree, so passing 0 will result in an error.

root@photon-host-def [ ~ ]# ostree admin undeploy -v 1
OT: Using bootloader: OstreeBootloaderGrub2
Transaction complete; bootconfig swap: yes deployment count change: -1
Deleted deployment a31a843985e314a9e70bcf09afe8d59f7351817d9fb743c2b6dab84f20833650

root@photon-host-cus1 [ ~ ]# ostree admin undeploy -v 0
OT: Deployment cf357c0f376decb3bae42326737db7e36bcf3568ab901c33dc57800c3718f07b.0 unlocked=0
error: Cannot undeploy currently booted deployment 0

Now, we can see that the newer image is gone, the deployment directory for commit a31a has been removed.

root@photon-host-def [ ~ ]# rpm-ostree status
  State: idle
  AutomaticUpdates: disabled
  Deployments:
  * ostree://photon-2:photon/5.0/x86_64/minimal
      Version: 5.0_minimal (2019-09-18T12:48:03Z)
  Commit: cf357c0f376decb3bae42326737db7e36bcf3568ab901c33dc57800c3718f07b
  
  root@photon-host-cus1 [ ~ ]# ls /ostree/deploy/photon/deploy/
  cf357c0f376decb3bae42326737db7e36bcf3568ab901c33dc57800c3718f07b.0
  cf357c0f376decb3bae42326737db7e36bcf3568ab901c33dc57800c3718f07b.0.origin 

However the commit is still there in the OSTree repo.

root@photon-7c2d910d79e9 [ ~ ]# ostree log 965c
  commit 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f
  ContentChecksum:  9bc85673bd8d5599d61a02a99accce9bc9b72612c7a3cebd35427875f6514288
  Date:  2021-02-20 07:15:43 +0000
  Version: 5.0_minimal
  (no subject)

But there is nothing to rollback to.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree rollback
Moving '820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88.0' to be first deployment
Transaction complete; bootconfig swap: yes; deployment count change: 0
Run "systemctl reboot" to start a reboot

If we were to upgrade again, it would bring these packages back, but let’s just check the differences.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree upgrade --check-diff
  ⠚ Receiving metadata objects: 0/(estimating) -/s 0 bytes... 
  Receiving metadata objects: 0/(estimating) -/s 0 bytes... done
  No updates available.

Version skipping upgrade

Let’s assume that after a while, VMware releases version 2 that removes sudo and adds bison and tar. Now, an upgrade will skip version 1 and go directly to 2. Let’s first look at what packages are pulled (notice sudo missing, as expected), then upgrade with reboot option.

root@photon-host-def [ ~ ]# rpm-ostree upgrade --check-diff
Updating from: photon:photon/5.0/x86_64/minimal

7 metadata, 13 content objects fetched; 1287 KiB transferred in 0 seconds
+bison-3.0.2-2.ph1.x86_64
+gawk-4.1.0-2.ph1.x86_64
+tar-1.27.1-1.ph1.x86_64
+wget-1.15-1.ph1.x86_64

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree upgrade -r
⠒ Receiving metadata objects: 0/(estimating) -/s 0 bytes... 
Receiving metadata objects: 0/(estimating) -/s 0 bytes... done
No upgrade available.

After reboot, let’s check the booting filetrees, the current dir for the current filetree and look at commit differences:

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree status
State: idle
Deployments:
● ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2020-11-04T02:21:47Z)
Commit: 820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88

  ostree://photon:photon/5.0/x86_64/minimal
    Version: 5.0_minimal (2021-02-20T07:15:43Z)
Commit: 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f


root@photon-7c2d910d79e9 [ ~ ]# ostree admin config-diff --print-current-dir
/ostree/deploy/photon/deploy/820b584a6f90bf6b9b8cb6aad8c093064b88d0ab686be8130baa03d68917ad88.0


root@photon-host-cus1 [ ~ ]# rpm-ostree db diff  8b4b e663
ostree diff commit old: rollback deployment (8b4b9d4ec033d1eb816711bfdda595d1013fecbe5cd340f6a619cdc9d83a3bf2)
ostree diff commit new: booted deployment (e663b2872efa01d80e4c34c823431472beb653373af32de83c7d2480316b8a6a)

root@photon-host-cus1 [ ~ ]# rpm-ostree db diff  82bc 092e
error: Refspec '82bc' not found
Interesting fact: The metadata for commit 82bc has been removed from the local repo.

Tracking parent commits

OSTree will display limited commit history - maximum 2 levels, so if you want to traverse the history even though it may not find a commitment by its ID, you can refer to its parent using ‘^’ suffix, grandfather via ‘^^’ and so on. We know that 82bc is the parent of 092e:

root@photon-host-def [ ~ ]# rpm-ostree db diff  092e^ 092e
  error: No such metadata object 82bca728eadb7292d568404484ad6889c3f6303600ca8c743a4336e0a10b3817.commit
  error: Refspec '82cb' not found
  root@photon-host-def [ ~ ]# rpm-ostree db diff  092e^^ 092e
  error: No such metadata object 82bca728eadb7292d568404484ad6889c3f6303600ca8c743a4336e0a10b3817.commit

So commit 092e knows who its parent is, but its metadata is no longer in the local repo, so it cannot traverse further to its parent to find an existing grandfather.

Resetting a branch to a previous commit

We can reset the head of a branch in a local repo to a previous commit, for example corresponding to version 0 (3.0_minimal).

root@photon-7c2d910d79e9 [ ~ ]# ostree reset photon:photon/5.0/x86_64/minimal 965c

Now if we look again at the branch commit history, the head is at version 0.

root@photon-7c2d910d79e9 [ ~ ]# ostree log photon/5.0/x86_64/minimal
commit 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f
ContentChecksum:  9bc85673bd8d5599d61a02a99accce9bc9b72612c7a3cebd35427875f6514288
Date:  2021-02-20 07:15:43 +0000
Version: 5.0_minimal
(no subject)

Note: The outputs listed above are only for reference. The version numbers in the outputs might vary from the actual outputs.

5.14.6 - Creating a Server

Photon OS includes a rpm-ostree-repo package that can be installed on a VM.

This package provides an automated script that creates a repo tree that acts as a server.

Run the following commands to create a server:

tdnf install rpm-ostree-repo

A script is created, which provides options to create a server.

Script to create a Photon OSTree repo Usage:

/usr/bin/rpm-ostree-server/mkostreerepo -r=<repo path> 
/usr/bin/rpm-ostree-server/mkostreerepo -r=<repo path> -p=<json treefile>
/usr/bin/rpm-ostree-server/mkostreerepo -c -r=<repo path> -p=<json treefile>
-r|--repopath   <Provide repo path> 
-p|--jsonfile   <Provide Json file> 
-c|--customrepo <Provide custom repo file inside repo path directory>

Note

  • Use PATH=$PATH:/usr/bin/rpm-ostree-server and then use mkostreerepo from any directory for ease of use.
  • mkostreerepo is used to create the fresh tree for ostree.
  • mkostreerepo is also used to update a new commit to the existing tree.
  • You can also use custom repo as to create/append the tree.

Run the following command to initiate the script, choose different help options to create a server.

mkostreerepo

Manually Composing your OSTree repo

Use the following commands to initialize a new repo and to compose it.

root [ ~ ]# cd /srv/rpm-ostree
root [ /srv/rpm-ostree ]# ostree --repo=repo init --mode=archive-z2
root [ /srv/rpm-ostree ]# rpm-ostree compose tree --repo=repo photon-base.json

You can now deploy a host. For more information, see File oriented server operations and Package oriented server operations to learn how to create your own customized file tree.

5.14.7 - Installing a Photon RPM-OStree host against a custom server repository

Organizations that maintain their own OSTree servers create custom image trees suited to their needs from which hosts can be deployed and upgraded. One single server may make available several branches to install, for example “base”, “minimal” and “full”. Or, if you think in terms of Windows OS SKUs - “Home”, “Professional” or “Enterprise” edition.

So in fact there are two pieces of information the OSTree host installer needs - the server URL and the branch ref. Also, there are two ways to pass this info - manually via keyboard, when prompted and automated, by reading from a config file.

Manual install of a custom host

Installing a Photon RPM-OSTree host that will pull from a server repository of your choice is very similar to the way we installed the host against the default server repo in this document.

We will follow the same steps, selecting “Photon OSTree Host”, and after assigning a host name like photon-host and a root password, this time we will click on “Custom RPM-OSTree Server”.

PhotonHostCustom

An additional screen will ask for the URL of server repo - just enter the IP address or fully qualified domain name of the server installed in the previous step.

PhotonHostCustomURL

Once this is done and the installation finished, reboot and you are ready to use it. You may verify - just like in this document - that you can get an rpm-ostree status. The value for the CommitID should be identical to the host that installed from default repo, if the server has been installed fresh, from the same ISO.

Automated install of a custom host via kickstart

Photon supports automated install that will not interact with the user, in other words installer will display its progress, but will not prompt for any keys to be clicked, and will boot at the end of installation.

If not familiar with the way kickstart works, visit Kickstart Support in Photon OS. The kickstart json config for OSTree is similar to minimal or full, except for these settings that should sound familiar:

    ...
    "type": "ostree_host",
    "ostree_repo_url": "http://192.168.218.249",
    "ostree_repo_ref": "photon/5.0/x86_64/minimal",
    ...

See sample kickstart configuration in sample_ks_ostree_client_from_server file for ostree deployement from official photon-os ostree server.

Or, for default installation

    ....
    "type": "ostree_host",
    "default_repo": true,
    ....

See sample kickstart configuration in sample_ks_ostree_client_from_default file for ostree deployment.

If the server is a future version of Photon OS, say Photon OS 5.0, and the administrator composed trees for the included json files, the ostree_repo_ref will take either value: photon/5.0/x86_64/base, photon/5.0/x86_64/minimal, or photon/5.0/x86_64/full.

In most situations, kickstart file is accessed via http from PXE boot. That enables booting from network and end to end install of hosts from pre-defined server URL and branch without assistance from user.

5.14.8 - Automatic Updates

Automatic updates are disabled by default.

To verify this, run the status command.

root@photon-7c2d910d79e9 [ ~ ]# rpm-ostree status 
State: idle
Deployments:
● ostree://photon:photon/5.0/x86_64/minimal
   Version: 5.0_minimal (2021-02-20T07:15:43Z)
Commit: 965c1abeb048e1a8ff77e9cd34ffccc5e3356176cda3332b4ff0e7a6c66b661f

Enable Automatic Updates

  1. Run the following command:
$ systemctl restart rpm-ostreed
  1. To enable automatic background updates, edit the /etc/rpm-ostreed.conf, and include the below lines in the Daemon section:

    [Daemon]
    AutomaticUpdatePolicy=stage
    #IdleExitTimeout=60
    
  2. Run the following commands:

    $ systemctl reload rpm-ostreed
    $ systemctl enable rpm-ostree-automatic.timer --now  
    $ systemctl restart rpm-ostree-automatic
    
  3. Verify that the automatic update feature has been enabled:

    $ rpm-ostree status -v 
          State: idle
    
          AutomaticUpdates: stage; rpm-ostreed-automatic.timer: last run 16min ago
    
  4. On the server machine, perform another commit on the base tree.

Automatic updates are now enabled and will automatically update the host system.

5.14.9 - File Oriented Server Operations

In this section, we will checkout a filetree into a writable directory structure on disk, make several file changes and commit the changes back into the repository. Then we will download this commit and apply at the host. As you may have guessed, this chapter is mostly about OSTree - the base technology. I’ve not mentioned anything about packages, although it is quite possible to install packages (after all, packages are made of files, right?) and commit without the help of rpm-ostree, but it’s too much of a headache and not worth the effort, since rpm-ostree does it simpler and better.

When would you want to do that? When you want for all your hosts to get an application or configuration customization that is not encapsulated as part of a package upgrade.

Starting a fresh OSTree repo

If you want to start fresh with your own branch and/or versioning scheme, you can delete the OSTree repo created during the Photon 3.0 RPM-OSTree server install and re-create it empty.

root [ /srv/rpm-ostree ]# rm -rf repo/*

root [ /srv/rpm-ostree ]# ostree --repo=repo init --mode=archive-z2

root [ /srv/rpm-ostree ]# ls repo
config  objects  refs  state  tmp  uncompressed-objects-cache

root [ /srv/rpm-ostree ]# cat repo/config
[core]
repo_version=1
mode=archive-z2

Creating summary metadata

A newer ostree feature, available in Photon OS 2.0 and higher, allows the OSTree server admin to create server summary metadata, that includes among other things the list of available branches and the list of static deltas, so they could be discovered by hosts. To create a summary, run this command after you committed for your branches:

root [ /srv/rpm-ostree ]# ostree summary -u "This is BigData's OSTree server, it has three branches"

We will find out later how the hosts query for branches list.

5.14.10 - Package Oriented Server Operations

Now that we have a Photon RPM-OSTree server up and running (if not, see how to install), we will learn how to provide the desired set of packages as input and instruct rpm-ostree to compose a filetree, that will result in creation (or update) of an OSTree repo.
The simplest way to explain is to take a look at the files installed by the Photon RPM-OSTree server during setup.

root [ ~ ]# cd /srv/rpm-ostree/
root [ /srv/rpm-ostree ]# ls -l
total 16
-rw-r--r-- 1 root root 7356 Aug 28 19:06 ostree-httpd.conf
-rw-r--r-- 1 root root 1085 Aug 28 19:06 photon-base.json
lrwxrwxrwx 1 root root   35 Aug 28 19:06 photon-extras-ostree.repo -> /etc/yum.repos.d/photon-extras.repo
lrwxrwxrwx 1 root root   32 Aug 28 19:06 photon-iso-ostree.repo -> /etc/yum.repos.d/photon-iso.repo
lrwxrwxrwx 1 root root   28 Aug 28 19:06 photon-ostree.repo -> /etc/yum.repos.d/photon.repo
lrwxrwxrwx 1 root root   36 Aug 28 19:06 photon-updates-ostree.repo -> /etc/yum.repos.d/photon-updates.repo
drwxr-xr-x 7 root root 4096 Aug 20 22:27 repo

JSON configuration file

How can we tell rpm-ostree what packages we want to include, where to get them from and how to compose the filetree? There is JSON file for that. Let’s take a look at photon-base.json used by the Photon OS team.

root [ /srv/rpm-ostree ]# cat photon-base.json
{
    "comment": "Photon Minimal OSTree",

    "osname": "photon",

    "ref": "photon/5.0/x86_64/minimal",

    "automatic_version_prefix": "5.0_minimal",

    "repos": ["photon"],

    "selinux": false,

    "initramfs-args": ["--no-hostonly"],

    "bootstrap_packages": ["filesystem"],

    "documentation": false,

    "packages": ["glibc", "zlib", "binutils", "gmp", "mpfr", "libgcc", "libstdc++","libgomp",
                "pkg-config", "ncurses", "bash", "bzip2", "cracklib", "cracklib-dicts", "shadow",
                "procps-ng", "iana-etc", "readline", "coreutils", "bc", "libtool", "net-tools",
                "findutils", "xz", "grub2", "grub2-pc", "grub2-efi", "iproute2", "util-linux", "linux",
                "attr", "libcap", "kmod", "expat", "dbus", "file",
                "sed", "grep", "cpio", "gzip",
                "openssl", "ca-certificates", "curl",
                "systemd",
                "openssh", "iptables",
                "photon-release",
                "vim", "photon-repos",
                "docker", "bridge-utils",
                "dracut", "dracut-tools", "rpm-ostree", "nss-altfiles", "which"]
}

There are some mandatory settings, some optional. I’m only going to explain the most important ones for our use case. osname and ref should be familiar, they have been explained in previous sections OSname and Refspec. Basicaly, we are asking rpm-ostree to compose a tree for photon OS and photon/3.0/x86_64/minimal branch.

For more information, see the OS Tree Documentation.

Package addition, removal, upgrade

packages is the list of packages that are to be added, in this case, in the “minimal” installation profile, on top of the packages already included by default. This is not quite the identical set of RPMS you get when you select the minimal profile in the ISO installer, but it’s pretty close and that’s why it’s been named the same. Let’s add to the list three new packages: gawk, sudo and wget using vim photon-base.json

!!!Warning: do not remove any packages from the default list, even an “innocent” one, as it may bring the system to an unstable condition. During my testing, I’ve removed “which”; it turns out it was used to figure out the grub booting roots: on reboot, the system was left hanging at grub prompt.

RPMS repository

But where are these packages located? RPM-OStree uses the same standard RPMS repositories, that yum installs from.

root [ /srv/rpm-ostree ]# ls /etc/yum.repos.d/
photon-debuginfo.repo  photon-extras.repo  photon-iso.repo  photon-updates.repo  photon.repo

Going back to our JSON file, repos is a multi-value setting that tells RPM-OSTree in what RPMS repositories to look for packages. In this case, it looks in the current directory for a “photon” repo configuration file, that is a .repo file starting with a [photon] section. There is such a file: photon-ostree.repo, that is in fact a link to photon.repo in /etc/yum.repos.d directory.

root [ /srv/rpm-ostree ]# cat /etc/yum.repos.d/photon.repo 
[photon]
name=VMware Photon Linux 5.0(x86_64)
baseurl=https://packages.vmware.com/photon/5.0/photon_release_$releasever_$basearch
gpgkey=file:///etc/pki/rpm-gpg/VMWARE-RPM-GPG-KEY
gpgcheck=1
enabled=1
skip_if_unavailable=True

In this case, rpm-ostree is instructed to download its packages in RPM format from the VMware Photon Packages URL, which is the location of an online RPMS repo maintained by the VMware Photon OS team. To ensure those packages can be validated as being genuine and signed by VMware, the signature is checked against the official VMware public key.

So what’s in an RPMS repository? If we point the browser to packages.vmware.com/photon/photon_publish_rpms/, we can see there are three top directories:

  • noarch - where all packages that don’t depend on the architecture reside. Those may contain scripts, platform neutral source files, configuration.
  • x86_64 - platform dependent packages for Intel 32 and 64 bits CPUs.
  • repodata - internal repo management data, like a catalog of all packages, and for every package its name, id, version, architecture and full path file/directory list. There is also a compressed XML file containing the history of changelogs extracted from github, as packages in RPM format were built by Photon OS team members from sources.

Fortunately, in order to compose a tree, you don’t need to download the packages from the online repository (which is time consuming - in the order of minutes), unless there are some new ones or updated versions of them, added by the Photon team after shipping 1.0 version or the 1.0 Refresh. A copy of the starter RPMS repository (as of 1.0 shipping date) has been included on the CD-ROM and you can access it.

root [ /srv/rpm-ostree ]# mount /dev/cdrom
root [ /srv/rpm-ostree ]# ls /mnt/cdrom/RPMS
noarch  repodata  x86_64

All you have to do now is to replace the "repos": ["photon"] entry by "repos": ["photon-iso"], which will point to the RPMS repo on CD-ROM, rather than the online repo. This way, composing saves time, bandwidth and reduces to zero the risk of failure because of a networking issue.

root [ /srv/rpm-ostree ]# cat /etc/yum.repos.d/photon-iso.repo
[photon-iso]
name=VMWare Photon Linux ISO 5.0(x86_64)
baseurl=file:///mnt/cdrom/RPMS
gpgkey=file:///etc/pki/rpm-gpg/VMWARE-RPM-GPG-KEY
gpgcheck=1
enabled=0
skip_if_unavailable=True

There are already in current directory links created to all repositories in /etc/yum.repos.d, so they are found when tree compose command is invoked. You may add any other repo to the list and include packages found in that repo to be part of the image.

Composing a tree

After so much preparation, we can execute a tree compose. We have only added 3 new packages and changed the RPMS repo source. Assuming that the JSON file is editted, run the following:

root [ /srv/rpm-ostree ]# rpm-ostree compose tree --repo=repo photon-base.json
Previous commit: 2940e10c4d90ce6da572cbaeeff7b511cab4a64c280bd5969333dd2fca57cfa8

Downloading metadata [=========================================================================] 100%

Transaction: 117 packages
  Linux-PAM-1.1.8-2.ph5.x86_64
  attr-2.4.47-1.ph5.x86_64
  ...
  gawk-4.1.0-2.ph5.x86_64
  ...
  sudo-1.8.11p1-4.ph5.x86_64
  ...
  wget-1.15-1.ph5.x86_64
  which-2.20-1.ph5.x86_64
  xz-5.0.5-2.ph5.x86_64
  zlib-1.2.8-2.ph5.x86_64
Installing packages [==========================================================================] 100%
Writing '/var/tmp/rpm-ostree.TVO089/rootfs.tmp/usr/share/rpm-ostree/treefile.json'
Preparing kernel
Creating empty machine-id
Executing: /usr/bin/dracut -v --tmpdir=/tmp -f /var/tmp/initramfs.img 4.0.9 --no-hostonly
...
*** Including module: bash ***
*** Including module: kernel-modules ***
*** Including module: resume ***
*** Including module: rootfs-block ***
*** Including module: terminfo ***
*** Including module: udev-rules ***
Skipping udev rule: 91-permissions.rules
Skipping udev rule: 80-drivers-modprobe.rules
*** Including module: ostree ***
*** Including module: systemd ***
*** Including module: usrmount ***
*** Including module: base ***
/etc/os-release: line 1: Photon: command not found
*** Including module: fs-lib ***
*** Including module: shutdown ***
*** Including modules done ***
*** Installing kernel module dependencies and firmware ***
*** Installing kernel module dependencies and firmware done ***
*** Resolving executable dependencies ***
*** Resolving executable dependencies done***
*** Stripping files ***
*** Stripping files done ***
*** Store current command line parameters ***
*** Creating image file ***
*** Creating image file done ***
Image: /var/tmp/initramfs.img: 11M
========================================================================
Version: dracut-041-1.ph5

Arguments: -v --tmpdir '/tmp' -f --no-hostonly

dracut modules:
bash
kernel-modules
resume
rootfs-block
terminfo
udev-rules
ostree
systemd
usrmount
base
fs-lib
shutdown
========================================================================
drwxr-xr-x  12 root     root            0 Sep  1 00:52 .
crw-r--r--   1 root     root       5,   1 Sep  1 00:52 dev/console
crw-r--r--   1 root     root       1,  11 Sep  1 00:52 dev/kmsg
...   (long list of files removed)
========================================================================
Initializing rootfs
Migrating /etc/passwd to /usr/lib/
Migrating /etc/group to /usr/lib/
Moving /usr to target
Linking /usr/local -> ../var/usrlocal
Moving /etc to /usr/etc
Placing RPM db in /usr/share/rpm
Ignoring non-directory/non-symlink '/var/tmp/rpm-ostree.TVO089/rootfs.tmp/var/lib/nss_db/Makefile'
Ignoring non-directory/non-symlink '/var/tmp/rpm-ostree.TVO089/rootfs.tmp/var/cache/ldconfig/aux-cache'
Ignoring non-directory/non-symlink '/var/tmp/rpm-ostree.TVO089/rootfs.tmp/var/log/btmp'
Ignoring non-directory/non-symlink '/var/tmp/rpm-ostree.TVO089/rootfs.tmp/var/log/lastlog'
Ignoring non-directory/non-symlink '/var/tmp/rpm-ostree.TVO089/rootfs.tmp/var/log/wtmp'
Moving /boot
Using boot location: both
Copying toplevel compat symlinks
Adding tmpfiles-ostree-integration.conf
Committing '/var/tmp/rpm-ostree.TVO089/rootfs.tmp' ...
photon/1.0/x86_64/minimal => c505f4bddb4381e8b5213682465f1e5bb150a18228aa207d763cea45c6a81bbe

We’ve omitted a large portion of the logging output, however you can see that the new filetree adds to the top of the previous (initial) commit 2940e10c4d and produces a new commit c505f4bddb. Our packages gawk-4.1.0-2.ph5.x86_64, sudo-1.8.11p1-4.ph5.x86_64 and wget-1.15-1.ph5.x86_64 have been added.

During compose, rpm-ostree checks out the file tree into its uncompressed form, applies the package changes, places the updated RPM repo into /usr/share/rpm and calls ostree to commit its changes back into the OSTree repo. If we were to look at the temp directory during this time:

root [ /srv/rpm-ostree ]# ls /var/tmp/rpm-ostree.TVO089/rootfs.tmp
bin   dev   lib    media  opt     proc  run   srv  sysroot  usr
boot  home  lib64  mnt    ostree  root  sbin  sys  tmp      var

If we repeat the command, and there is no change in the JSON file settings and no change in metadata, rpm-ostree will figure out that nothing has changed and stop. You can force however to redo the whole composition.

root [ /srv/rpm-ostree ]# rpm-ostree compose tree --repo=repo photon-base.json
Previous commit: c505f4bddb4381e8b5213682465f1e5bb150a18228aa207d763cea45c6a81bbe

Downloading metadata [=========================================================================] 100%


No apparent changes since previous commit; use --force-nocache to override

This takes several minutes. Then why is the RPM-OSTree server installing so fast, in 45 seconds on my SSD? The server doesn’t compose the tree, it uses a pre-created OSTree repo that is stored on the CD-ROM. It comes of course at the expense of larger CD-ROM size. This OSTree repo is created from the same set of RPMS on the CD-ROM, so if you compose fresh, you will get the same exact tree, with same commit ID for the “minimal” ref.

Automatic version prefix

If you recall the filetree version explained earlier, this is where it comes into play. When a tree is composed from scratch, the first version (0) associated to the initial commit is going to get that human readable value. Any subsequent compose operation will auto-increment to .1, .2, .3 and so on.
It’s a good idea to start a versioning scheme of your own, so that your customized Photon builds that may get different packages of your choice don’t get the same version numbers as the official Photon team builds coming from VMware’s OSTree Packages repository. There is no conflict, it’s just confusing to have same name for different commits coming from different repos.
So if you work for a company named Big Data Inc., you may want to switch to a new versioning scheme “automatic_version_prefix”: “1.0_bigdata”.

Installing package updates

If you want to provide hosts with the package updates that VMware periodically releases, all that you need to do is to add the photon-updates.repo to the list of repos in photon-base.json and then re-compose the usual way.

"repos": ["photon", "photon-updates"],

Even though you may have not modified the “packages” section in the json file, the newer versions of existing packages will be included in the new image and then downloaded by the host the usual way. Note that upgrading a package shows differently than adding (+) or removing (-). You may still see packages added (or removed) though because they are new dependencies (or no longer dependencies) for the newer versions of other packages, as libssh2 in the example below.

root [ ~ ]# rpm-ostree upgrade --check-diff
Updating from: photon:photon/5.0/x86_64/minimal

8 metadata, 13 content objects fetched; 1002 KiB transferred in 0 seconds
!bridge-utils-1.5-2.ph5.x86_64
=bridge-utils-1.5-3.ph5.x86_64
!bzip2-1.0.6-5.ph5.x86_64
=bzip2-1.0.6-6.ph5.x86_64
!curl-7.47.1-2.ph5.x86_64
=curl-7.51.0-2.ph5.x86_64
!docker-1.11.0-5.ph5.x86_64
=docker-1.12.1-1.ph5.x86_64
...
+libssh2-1.8.0-1.ph5.x86_64
...

root [ ~ ]# rpm-ostree upgrade
Updating from: photon:photon/1.0/x86_64/minimal

258 metadata, 1165 content objects fetched; 76893 KiB transferred in 8 seconds
Copying /etc changes: 6 modified, 0 removed, 14 added
Transaction complete; bootconfig swap: yes deployment count change: 1
Changed:
  bridge-utils 1.5-2.ph5 -> 1.5-3.ph5
  bzip2 1.0.6-5.ph5 -> 1.0.6-6.ph5
  curl 7.47.1-2.ph5 -> 7.51.0-2.ph5
  docker 1.11.0-5.ph5 -> 1.12.1-1.ph5
  ...
Added:
  libssh2-1.8.0-1.ph5.x86_64
Upgrade prepared for next boot; run "systemctl reboot" to start a reboot

Now if we want to see what packages have been updated and what issues have been fixed, just run at the host the command that we learned about in chapter 5.4.

root [ ~ ]# rpm-ostree db diff 56ef 396e
ostree diff commit old: 56e (56ef687f1319604b7900a232715718d26ca407de7e1dc89251b206f8e255dcb4)
ostree diff commit new: 396 (396e1116ad94692b8c105edaee4fa12447ec3d8f73c7b3ade4e955163d517497)
Upgraded:
 bridge-utils-1.5-3.ph5.x86_64
* Mon Sep 12 2016 user1 <user1@vmware.com> 1.5-3
-	Update patch to fix-2.

 bzip2-1.0.6-6.ph5.x86_64
* Fri Oct 21 2016 user2 <user2@vmware.com> 1.0.6-6
-       Fixing security bug CVE-2016-3189.

 curl-7.51.0-2.ph5.x86_64
* Wed Nov 30 2016 user3 <user3@vmware.com> 7.51.0-2
-   Enable sftp support.

* Wed Nov 02 2016 user4 <user4@vmware.com> 7.51.0-1
-   	Upgrade curl to 7.51.0

* Thu Oct 27 2016 user4 <user4@vmware.com> 7.47.1-4
-   	Patch for CVE-2016-5421

* Mon Sep 19 2016 user3 <user3@vmware.com> 7.47.1-3
-   	Applied CVE-2016-7167.patch.

 docker-1.12.1-1.ph5.x86_64
* Wed Sep 21 2016 user3 <user3@vmware.com> 1.12.1-1
-   Upgraded to version 1.12.1

* Mon Aug 22 2016 user1 <user1@vmware.com> 1.12.0-2
-   Added bash completion file

* Tue Aug 09 2016 user4 <user4@vmware.com> 1.12.0-1
-   Upgraded to version 1.12.0

* Tue Jun 28 2016 user4 <user4@vmware.com> 1.11.2-1
-   Upgraded to version 1.11.2
...
Added:
 libssh2-1.8.0-1.ph5.x86_64

Composing for a different branch

RPM-OSTree makes it very easy to create and update new branches, by composing using json config files that include the Refspec as the new branch name, the list of packages and the other settings we are now familiar with. Photon OS RPM-OSTRee Server installer adds two extra files photon-minimal.json and photon-full.json in addition to photon-base.json, that correspond almost identically to the minimal and full profiles installed via tdnf. It also makes ‘photon-base’ a smaller set of starter branch.

Of course, you can create your own config files for your branches with desired lists of packages. You may compose on top of the existing tree, or you can start fresh your own OSTRee repo, using your own customized versioning.

Note: The outputs listed above are only for reference. The version numbers in the outputs might vary from the actual outputs.

5.14.11 - Remotes

In Chapter 3 we talked about the Refspec that contains a photon: prefix, that is the name of a remote. When a Photon host is installed, a remote is added - which contains the URL for an OSTree repository that is the origin of the commits we are going to pull from and deploy filetrees, in our case the Photon RPM-OSTree server we installed the host from. This remote is named photon, which may be confusing, because it’s also the OS name and part of the Refspec (branch) path.

Listing remotes

A host repo can be configured to switch between multiple remotes to pull from, however only one remote is the “active” one at a time. We can list the remotes created so far, which brings back the expected result.

root@photon-7c2d910d79e9 [ ~ ]# ostree remote list
photon

We can inquiry about the URL for that remote name, which for the default host is the expected Photon OS online OSTree repo.

root@photon-host-def [ ~ ]# ostree remote show-url photon
https://<host-name>:8080/repo

But where is this information stored? The repo’s config file has it.

root@photon-host-def [ ~ ]# cat /ostree/repo/config 
[core]
repo_version=1
mode=bare

[remote "photon"]
url=http:<Server-IP-Address:port>/repo
gpg-verify=false

If same command is executed on the custom host we’ve installed, it’s going to reveal the URL of the Photon RPM-OSTree server connected to during setup.

root@photon-7c2d910d79e9 [ ~ ]# ostree remote show-url photon
https://packages.vmware.com/photon/rpm-ostree/base/5.0/x86_64/repo

GPG signature verification

You may wonder what is the purpose of gpg-verify=false in the config file, associated with the specific remote. This will instruct any host update to skip the signing verification for the updates that come from server, resulted from tree composed locally at the server, as they are not signed. Without this, host updating will fail.

There is a whole chapter about signing, importing keys and so on that I will not get into, but the idea is that signing adds an extra layer of security, by validating that everything you download comes from the trusted publisher and has not been altered. That is the case for all Photon OS artifacts downloaded from VMware official site. All OVAs and packages, either from the online RPMS repositories or included in the ISO file - are signed by VMware. We’ve seen a similar setting gpgcheck=1 in the RPMS repo configuration files that tdnf uses to validate or not the signature for all packages downloaded to be installed.

Switching repositories

Since mapping name/url is stored in the repo’s config file, in principle you can re-assign a different URL, connecting the host to a different server. The next upgrade will get the latest commit chain from the new server.
If we edit photon-host-def’s repo config and replace the VMware Photon Packages URL by photon-srv1’s IP address, all original packages in the original 5.0_minimal version will be preserved, but any new package change (addition, removal, upgrade) added after that (in 5.0_minimal.1, 5.0_minimal.2) will be reverted and all new commits from photon-srv1 (that may have same version) will be applied. This is because the two repos are identical copies, so they have the same original commit ID as a common ancestor, but they diverge from there.

If the old and new repo have nothing in common (no common ancestor commit), this will undo even the original commit, so all commits from the new tree will be applied.
A better solution would be to add a new remote that will identify where the commits come from.

Adding and removing remotes

A cleaner way to switch repositories is to add remotes that point to different servers. Let us add another server that we will refer to as photon2, along with (optional) the refspecs for branches that it provides (we will see later that in the newer OSTree versions, we don’t need to know the branch names, they could be queried at run-time).

root@photon-host-cus [ ~ ]# ostree remote add --repo=/ostree/repo -v --no-gpg-verify photon2 http://10.197.103.204:8080 photon/5.0/x86_64/minimal photon/5.0/x86_64/full
root@photon-host-cus [ ~ ]# ostree remote list
photon
photon2
root@photon-host-cus [ ~ ]# ostree remote show-url photon2
http://10.0.0.86

Where is this information stored? There is an extra config file created per each remote:

root@photon-host-cus [ ~ ]# cat /etc/ostree/remotes.d/photon2.conf 
[remote "photon2"]
url=http://10.0.0.86
branches=photon/5.0/x86_64/minimal;photon/5.0/x86_64/full;
gpg-verify=false

You may have guessed what is the effect of --no-gpg-verify option.
Obviously, remotes could also be deleted.

root@photon-host-cus [ ~ ]# ostree remote delete photon2
root@photon-host-cus [ ~ ]# ostree remote list
photon

List available branches

If a host has been deployed from a specific branch and would like to switch to a different one, maybe from a different server, how would it know what branches are available? In git, you would run git remote show origin or git remote -a (although last command would not show all branches, unless you ran git fetch first).

In Photon OS, the hosts are able to query the server, if summary metadata has been generated, as we’ve seen in Creating summary metadata. This command lists all branches available for remote photon2.

root@photon-host-cus [ ~ ]# ostree remote refs photon2 
photon2:photon/5.0/x86_64/base
photon2:photon/5.0/x86_64/full
photon2:photon/5.0/x86_64/minimal

Switching branches (rebasing)

If you have an installed Photon 4.0 that you want to carry to 5.0, you need to rebase it.

See rebasing.

5.14.12 - Running container applications between bootable images

In this chapter, we want to test a docker application and make sure that all the settings and downloads done in one bootable filetree are going to be saved into writable folders and be available in the other image, in other words after reboot from the other image, everything is available exactly the same way.
We are going to do this twice: first, to verify an existing bootable image installed in parallel and then create a new one.

Downloading a docker container appliance

Photon OS comes with docker package installed and configured, but we expect that the docker daemon is inactive (not started). Configuration file /usr/lib/systemd/system/docker.service is read-only (remember /usr is bound as read-only).

root@sample-host-def [ ~ ]# systemctl status docker
* docker.service - Docker Daemon
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled)
   Active: inactive (dead)

root@sample-host-def [ ~ ]# cat /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target

Now let’s enable docker daemon to start at boot time - this will create a symbolic link into writable folder /etc/systemd/system/multi-user.target.wants to its systemd configuration, as with all other systemd controlled services.

root@sample-host-def [ ~ ]# systemctl enable docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service -> /lib/systemd/system/docker.service.

root@sample-host-def [ ~ ]# ls -l /etc/systemd/system/multi-user.target.wants
total 0
lrwxrwxrwx 1 root root 34 Sep 10 10:48 docker.service -> /lib/systemd/system/docker.service
lrwxrwxrwx 1 root root 36 Sep  4 04:59 iptables.service -> /lib/systemd/system/iptables.service
lrwxrwxrwx 1 root root 35 Sep  4 04:59 machines.target -> /lib/systemd/system/machines.target
lrwxrwxrwx 1 root root 36 Sep  4 04:59 remote-fs.target -> /lib/systemd/system/remote-fs.target
lrwxrwxrwx 1 root root 39 Sep  4 04:59 sshd-keygen.service -> /lib/systemd/system/sshd-keygen.service
lrwxrwxrwx 1 root root 32 Sep  4 04:59 sshd.service -> /lib/systemd/system/sshd.service
lrwxrwxrwx 1 root root 44 Sep  4 04:59 systemd-networkd.service -> /lib/systemd/system/systemd-networkd.service
lrwxrwxrwx 1 root root 44 Sep  4 04:59 systemd-resolved.service -> /lib/systemd/system/systemd-resolved.service

To verify that the symbolic link points to a file in a read-only directory, try to make a change in this file using vim and save. you’ll get an error: /usr/lib/systemd/system/docker.service" E166: Can't open linked file for writing.

Finally, let’s start the daemon, check again that is active.

root@sample-host-def [ ~ ]# systemctl start docker

root@sample-host-def [ ~ ]# systemctl status -l docker
* docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2019-09-10 10:54:32 UTC; 14s ago
     Docs: https://docs.docker.com
 Main PID: 2553 (dockerd)
    Tasks: 35 (limit: 4711)
   Memory: 148.2M
   CGroup: /system.slice/docker.service
           |-2553 /usr/bin/dockerd
           `-2566 docker-containerd --config /var/run/docker/containerd/containerd.toml

Sep 10 10:54:31 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:31.421759662Z" level=info msg="pickfirstBalancer: HandleSubConnStateChange: 0xc420312f90, CONNECTING" module=grpc
Sep 10 10:54:31 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:31.421935355Z" level=info msg="pickfirstBalancer: HandleSubConnStateChange: 0xc420312f90, READY" module=grpc
Sep 10 10:54:31 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:31.421980614Z" level=info msg="Loading containers: start."
Sep 10 10:54:31 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:31.886520281Z" level=info msg="Default bridge
(docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address"
Sep 10 10:54:32 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:32.027763113Z" level=info msg="Loading containers: done."
Sep 10 10:54:32 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:32.468277184Z" level=info msg="Docker daemon"
commit=6d37f41 graphdriver(s)=overlay2 version=18.06.2-ce
Sep 10 10:54:32 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:32.468441587Z" level=info msg="Daemon has completed initialization"
Sep 10 10:54:32 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:32.684925824Z" level=warning msg="Could not register builder git source: failed to find git binary: exec: \"git\": executable file not found in $PATH"
Sep 10 10:54:32 photon-76718dd2fa33 dockerd[2553]: time="2019-09-10T10:54:32.691070166Z" level=info msg="API listen on /var/run/docker.sock"
Sep 10 10:54:32 photon-76718dd2fa33 systemd[1]: Started Docker Application Container Engine.

We’ll ask docker to run Ubuntu Linux in a container. Since it’s not present locally, it’s going to be downloaded first from the official docker repository https://hub.docker.com/_/ubuntu/.

root@sample-host-def [ ~ ]# docker ps -a
CONTAINER ID        IMAGE            COMMAND      CREATED           STATUS              PORTS       NAMES

root@sample-host-def [ ~ ]# docker run -it ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
35c102085707: Pull complete
251f5509d51d: Pull complete
8e829fe70a46: Pull complete
6001e1789921: Pull complete
Digest: sha256:d1d454df0f579c6be4d8161d227462d69e163a8ff9d20a847533989cf0c94d90
Status: Downloaded newer image for ubuntu:latest

When downloading is complete, it comes to Ubuntu root prompt with assigned host name 7029a64e7aa3, that is actually the Container ID. Let’s verify it’s indeed the expected OS.

root@sample-host-def [ ~ ]# docker run -it ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
d3a1f33e8a5a: Pull complete
c22013c84729: Pull complete
d74508fb6632: Pull complete
91e54dfb1179: Already exists
library/ubuntu:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:fde8a8814702c18bb1f39b3bd91a2f82a8e428b1b4e39d1963c5d14418da8fba
Status: Downloaded newer image for ubuntu:latest

root@7029a64e7aa3:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.3 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
root@7029a64e7aa3:/#

Now let’s write a file into Ubuntu home directory

echo "Ubuntu file" >> /home/myfile
root@7029a64e7aa3:/home# cat /home/myfile
Ubuntu file

We’ll exit back to the Photon prompt and if it’s stopped, we will re-start it.

root@7029a64e7aa3:/# exit
exit

root@sample-host-def [ ~ ]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
7029a64e7aa3        ubuntu              "/bin/bash"         6 minutes ago       Exited (0) 11 seconds ago                        gifted_dijkstra

root@photon-host-cus1 [ ~ ]# docker start  7029a64e7aa3
7029a64e7aa3

root@photon-host-cus1 [ ~ ]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
7029a64e7aa3        ubuntu              "/bin/bash"         7 minutes ago       Up 21 seconds                                    gifted_dijkstra

Rebooting into an existing image

Now let’s reboot the machine and select the other image. First, we’ll verify that the docker daemon is automatically started.

root@photon-host-cus1 [ ~ ]# systemctl status docker
* docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2019-09-10 10:54:32 UTC; 13min ago
     Docs: https://docs.docker.com
 Main PID: 2553 (dockerd)
    Tasks: 55 (limit: 4711)
   Memory: 261.3M
   CGroup: /system.slice/docker.service
           |-2553 /usr/bin/dockerd
   ...

Next, is the Ubuntu OS container still there?

root@photon-host-cus1 [ ~ ]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
7029a64e7aa3        ubuntu              "/bin/bash"         9 minutes ago       Up 2 minutes                                     gifted_dijkstra

It is, so let’s start it, attach and verify that our file is persisted, then add another line to it and save, exit.

root@photon-host-cus1 [ ~ ]# docker start -i  7029a64e7aa3
root@7029a64e7aa3:/# cat /home/myfile
Ubuntu file
root@7029a64e7aa3:/# echo "booted into existing image" >> /home/myfile
root@7029a64e7aa3:/# exit
exit

Reboot into a newly created image

Let’s upgrade and replace the .0 image by a .4 build that contains git and also perl_YAML (because it is a dependency of git).

root@photon-host-cus1 [ ~ ]# rpm-ostree status
  TIMESTAMP (UTC)         VERSION               ID             OSNAME     REFSPEC
* 2015-09-04 00:36:37     5.0_minimal     092e21d292     photon     photon:photon/x86_64/minimal
  2015-08-20 22:27:43     5.0_minimal       2940e10c4d     photon     photon:photon/x86_64/minimal

root@photon-host-cus1 [ ~ ]# rpm-ostree upgrade
Updating from: photon:photon/tp2/x86_64/minimal

43 metadata, 209 content objects fetched; 19992 KiB transferred in 0 seconds
Copying /etc changes: 5 modified, 0 removed, 19 added
Transaction complete; bootconfig swap: yes deployment count change: 0
Freed objects: 16.2 MB
Added:
  git-2.1.2-1.ph5tp2.x86_64
  perl-YAML-1.14-1.ph5tp2.noarch
Upgrade prepared for next boot; run "systemctl reboot" to start a reboot

root@photon-host-cus1 [ ~ ]# rpm-ostree status
  TIMESTAMP (UTC)         VERSION               ID             OSNAME     REFSPEC
  2015-09-06 18:12:08     5.0_minimal     d16aebd803     photon     photon:photon/x86_64/minimal
* 2015-09-04 00:36:37     5.0_minimal     092e21d292     photon     photon:photon/x86_64/minimal

After reboot from 5.0_minimal. build, let’s check that the 3-way /etc merge succeeded as expected. The docker.service slink is still there, and docker demon restarted at boot.

root@photon-host-cus1 [ ~ ]# ls -l /etc/systemd/system/multi-user.target.wants/docker.service
lrwxrwxrwx 1 root root 38 Sep  6 12:50 /etc/systemd/system/multi-user.target.wants/docker.service -> /usr/lib/systemd/system/docker.service

root@photon-host-cus1 [ ~ ]# systemctl status docker
* docker.service - Docker Daemon
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled)
   Active: active (running) since Sun 2015-09-06 12:56:33 UTC; 1min 27s ago
 Main PID: 292 (docker)
   CGroup: /system.slice/docker.service
           `-292 /bin/docker -d -s overlay
   ...

Let’s revisit the Ubuntu container. Is the container still there? is myfile persisted?

root@photon-host-cus1 [ ~ ]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS               NAMES
7029a64e7aa3        ubuntu              "/bin/bash"         5 days ago          Exited (0) 5 days ago                         gifted_dijkstra
55825c961f95        ubuntu              "/bin/bash"         5 days ago          Exited (127) 5 days ago                       distracted_shannon

root@photon-host-cus1 [ ~ ]# docker start 57dcac5d0490

root@57dcac5d0490:/# cat /home/myfile
Ubuntu file
booted into existing image
root@57dcac5d0490:/# echo "booted into new image" >> /home/myfile

5.14.13 - Install or rebase to Photon OS

Photon OS 5.0 provides full RPM-OSTree functionality, it lets the user drive it, rather than provide a pre-defined solution as part of the installation.

The number of packages included in the RPMS repo in Photon OS 5.0 increased significantly, compared to 1.0. To keep the ISO at reasonable size, the previous versions no longer include the compressed ostree.repo file, that helped optimize both the server and host install in 1.0 or 1.0 Rev2. That decision affected the OSTree features we ship out of the box. Customer could achieve the same results by several additional simple steps, that will be explained in this chapter. In addition, there is a new way to create a host raw image at server.

Composing your own RPM-OSTree Server

You can compose your own RPM-OSTRee server in the following two ways:

  1. By Manually executing the below command:
root [ /srv/rpm-ostree ]# ostree --repo=repo init --mode=archive-z2
root [ /srv/rpm-ostree ]# rpm-ostree compose tree --repo=repo photon-base.json
  1. By installing rpm-ostree-repo package . This provides the script to create the repo tree which act as server by executing a single command.

Installing an RPM-OSTree host

Automated host install is supported, as explained in Automated install of a custom host via kickstart.

Rebasing a host from Photon 1.0 to 5.0

If kickstart sounds too complicated and we still want to go the UI way there is a workaround that requires an extra step. Also, if you have an installed Photon 1.0 or 1.0 Rev2 that you want to carry to 5.0, you need to rebase it. Notice that we didn’t say “upgrade”.

Practically, the OSTree repo will switch to a different branch on a different server, following the new server’s branch versioning scheme. The net result is that the lots of packages will get changed to newer versions listed in the newer OSTree repo, which has been composed from a newer Photon OS 5.0 RPMS repo. Again, we didn’t say “upgraded”, neither the rebase command output, that lists “changed” packages. Some obsolete packages will be removed, new packages will be added, either because they didn’t exist in older repo, or because the new config file includes them.
The OS name is the same (Photon), so the content in /var and /etc will be transferred over.

  1. To install fresh, deploy a Photon OS host default, as described in the section Installing A Host Against the Default Server Repository. Of course, if you already have an existing Photon OS 4.0 host that you want to move to 5.0, skip this step.

  2. Edit /ostree/repo/config and substitute the url, providing the IP address for the Photon OS RPM-OSTree server installed above. This was explained in the “Switching Repositories” section of the Remotes document.
    Ostree should confirm that is the updated server IP for the “photon” remote.

root@ostree-host [ ~ ]# ostree remote show-url photon
http://10.20.30.175:8000/repo
  1. Rebase your host to the new 5.0 server and Refspec.
root@ostree-host [ ~ ]# ostree remote add photon-5 http://10.20.30.204:8000/repo --no-gpg-verify
root@ostree-host [ ~ ]# rpm-ostree rebase photon-5:photon/5.0/x86_64/minimal

Rebasing to photon-5:photon/5.0/x86_64/minimal
⠉ Receiving objects: 99% (1541/1549) 478.3 kB/s 107.1 MB
Receiving objects: 99% (1541/1549) 478.3 kB/s 107.1 MB... done
Staging deployment... done
Upgraded:
  docker 18.06.2-3.ph5 -> 18.06.2-4.ph5
  gmp 6.1.2-2.ph5 -> 6.1.2-3.ph5
  gobject-introspection 1.58.0-2.ph5 -> 1.58.0-3.ph5
  gzip 1.9-1.ph5 -> 1.9-2.ph5
  linux 4.19.65-3.ph5 -> 4.19.69-1.ph5
  mpfr 4.0.1-1.ph5 -> 4.0.1-2.ph5
  ostree 2019.2-1.ph5 -> 2019.2-2.ph5
  ostree-grub2 2019.2-1.ph5 -> 2019.2-2.ph5
  ostree-libs 2019.2-1.ph5 -> 2019.2-2.ph5
  zlib 1.2.11-1.ph5 -> 1.2.11-2.ph5
Added:
  efibootmgr-15-1.ph5.x86_64
  efivar-36-1.ph5.x86_64
  tar-1.30-3.ph5.x86_64
Run "systemctl reboot" to start a reboot
  1. Check the status
root@ostree-host [ ~ ]# rpm-ostree status
State: idle
AutomaticUpdates: disabled
Deployments:
* ostree://photon-1:photon/5.0/x86_64/minimal
                Version: 5.0_minimal (2019-09-18T08:22:15Z)
            BaseCommit: c8f2b116b067d7695f9033bf2a99505198269354e157c0f2d5b78266cb874239
        LayeredPackages: createrepo_c rpm wget

  ostree://photon:photon/5.0/x86_64/minimal
                Version: 5.0_minimal.1 (2017-01-11T02:18:42)
            BaseCommit: 28dc49ecb4604c0bc349e4445adc659491a1874c01198e6253a261f4d59708b7
        LayeredPackages: createrepo_c rpm wget

You may now reboot to the new Photon OS 5.0 image.

Creating a host raw image

It is now possible to run at server a script that is part of RPM-OStree package, to create a host raw mage.

5.15 - Support for SELinux

SELinux is a labelling system to implement MAC(mandatory access control) for subjects(user, process) over objects (files, dirs, sockets) and to protect the confidentiality of objects. It is a policy driven system where rules can be mapped to the labels which have been given to subjects, objects. It is an extra level of security provided on top of Linux normal file ownership/permissions.

Photon OS offersx support for SELinux. The support covers a minimal set of policies for the container runtime case and it is referred to as the default policy. It is a Multi-Category Security (MCS) policy. So the files on the filesystem can be labeled with multiple categories.The MCS policy is actively used by container runtime as runc/containerd/docker/kubernetes to assign the per-container category.

The default policy in Photon OS does not use user, role (RBAC) and level (MLS) fields of the file labels.It operates only with the context and category fields. It consists of several modules loaded with priority as 100. The user-defined policy can overwrite default modules by using the higher priority.

Enabling SELinux

To enable SELinux on Photon OS:

  1. Install default policy and its dependencies. Initial filesystem labeling will be done as RPM post action.

    tdnf install -y selinux-policy

  2. Enable SELinux security model in kernel by adding 2 kernel parameters:

  • security=selinux
  • selinux=1

Ensure that you reboot after adding the kernel parameters.

  1. After reboot, the system runs in SELinux permissive mode. To confirm, check the journal:

    journalctl -b0 | grep -i selinux
    
    Feb 26 21:42:09 photon-machine kernel: SELinux:  Initializing.
    Feb 26 21:42:09 photon-machine kernel: SELinux:  policy capability ...
    Feb 26 21:42:09 photon-machine kernel: audit: type=1403 audit(1589406128.920:2): auid=4294967295 ses=4294967295 lsm=selinux res=1
    Feb 26 21:42:09 photon-machine systemd[1]: Successfully loaded SELinux policy in 322.475ms.
    

Switch SELinux to enforcing mode

The three methods to toggle enforcing mode are as follows:

  1. Run the setenforce 1 command (libselinux-utils rpm), Enforcing mode will be set immediately, but it is not preserved on reboot.
  2. Edit the /etc/selinux/config file to set SELINUX=enforcing and reboot.
  3. Add the enforcing=1 kernel parameter and reboot.

Developing Customized Policy

Photon OS provides an ability to develop customized additional policy on top of existing default policy. The following example is for adding the sys_admin capability policy:

  1. Install policy development packages:

    tdnf install -y selinux-policy-devel semodule-utils
    
  2. Create .te file

    cat getty_local.te
    policy_module(getty_local, 1.0)
    
    gen_require(`
        type getty_t;
          ')
    
    allow getty_t self:capability sys_admin;
    
  3. Compile it into .pp file

    make -f /usr/share/selinux/devel/Makefile getty_local.pp
    
  4. Load it with priority 200. It will permanently alter default policy. And this change will survive reboot cycle.

    semodule -i getty_local.pp -X 200
    
  5. Check result

    sesearch -A -s getty_t -t getty_t -c capability
    allow getty_t getty_t:capability { chown dac_override dac_read_search fowner fsetid setgid sys_admin sys_resource sys_tty_config };
    
  6. List of loaded modules and their priorities

    semodule -lfull
    

Debugging SELinux

Install the debugging tools as follows:

tdnf install -y setools python3-pip

pip3 install networkx

List all actions denied by Selinux using the following command:

journalctl _TRANSPORT=audit -b 0 | grep denied

Feb 26 21:42:43 photon-machine audit[445]: AVC avc:  denied  { sys_admin } for  pid=445 comm="agetty" capability=21
scontext=system_u:system_r:getty_t:s0-s0:c0.c1023 tcontext=system_u:system_r:getty_t:s0-s0:c0.c1023 tclass=capability permissive=0

You can see that the agetty process running in the getty_t context tries to change the capability of getty_t target to obtain sys_admin. To view the capability that getty_t can obtain:

sesearch -A -s getty_t -t getty_t -c capability

allow getty_t getty_t:capability { chown dac_override dac_read_search fowner fsetid setgid sys_resource sys_tty_config };

Important SELinux Files

Here are some of the important SELinux files:

  • SELinux config /etc/selinux/config

  • default policy folder /etc/selinux/default/

  • Binary policy blob to be loaded to kernel on every boot /etc/selinux/default/policy/policy.32

  • List of file labels used by the policy /etc/selinux/default/contexts/files/file_contexts

Troubleshooting Compilation Error

If compilation fails by any reason and it complains on some line number in the .cil file. You can run the pp compiler to get the plain text cil output.

/usr/libexec/selinux/hll/pp getty_local.pp
(roleattributeset cil_gen_require system_r)
(typeattributeset cil_gen_require getty_t)
(allow getty_t self (capability (sys_admin)))

5.16 - pmd-nextgen Overview

The pmd-nextgen package contains the photon-mgmtd tool. photon-mgmtd is a high-performing, open-source, lightweight, pluggable REST API gateway designed with stateless architecture. photon-mgmtd is written in Go and built with performance in mind. It facilitates real-time configuration, performance analysis, and health monitoring of systems, networks, services, and applications.

photon-mgmtd is optimized to provide the following benefits:

  • The proactive monitoring and analytics features help the administrator to efficiently collect analytical data for performance and health management of systems.
  • For remote access, you can use the platform-independent REST APIs via any application on any Operating system. For example, you can use applications such as Curl/Chrome/Postman on any operating system such as Linux/iOS/Android/Windows and so on.
  • Minimal data transfer using JSON.
  • Plugin based architecture for easier operation.

5.16.1 - Features

The following table lists the photon-mgmtd features details:

FeatureDetails
systemdInformation, services (start, stop, restart, status), service properties such as CPUShares
see information from /proc fsnetstat, netdev, memory and much more

5.16.2 - Installing photon-mgmtd

You can install photon-mgmtd using the pmd-nextgen package. The pmd-nextgen package is included in your Photon OS 4.0 Rev 2 distribution. To install pmd-nextgen, run the following command:

# tdnf install pmd-ng
# systemctl start photon-mgmtd.service

5.16.3 - Configuration

To configure photon-mgmtd, use the mgmt.toml file located in the following directory: /etc/photon-mgmt/

You can set values for the following keys in the [System] section:

LogLevel= Specifies the log level. The key takes one of the following: values: Trace, Debug, Info, Warning, Error, Fatal and Panic. Default is info.

UseAuthentication= Specifies whether a user needs authentication. This is a boolean key and takes the following values: true, false. Default is true.

You can set values for the following keys in the [Network] section:

Listen= Specifies the IP address and port that the REST API server listens to. When enabled, the default is 127.0.0.1:5208.

ListenUnixSocket= Specifies whether you want the server to listen on a unix domain socket /run/photon-mgmt/mgmt.sock. This is a boolean key and takes the following values: true, false. Default is true.

Note: When you enable both ListenUnixSocket= and Listen=, server listens on the unix domain socket by default.

❯ sudo cat /etc/photon-mgmt/mgmt.toml
[System]
LogLevel="info"
UseAuthentication="false"

[Network]
ListenUnixSocket="true"


❯ sudo systemctl status photon-mgmtd.service
● photon-mgmtd.service - A REST API based configuration management microservice gateway
     Loaded: loaded (/usr/lib/systemd/system/photon-mgmtd.service; disabled; vendor preset: disabled)
     Active: active (running) since Thu 2022-01-06 16:32:19 IST; 4s ago
   Main PID: 230041 (photon-mgmtd)
      Tasks: 6 (limit: 15473)
     Memory: 2.9M
        CPU: 7ms
     CGroup: /system.slice/photon-mgmtd.service
             └─230041 /usr/bin/photon-mgmtd

Jan 06 16:32:19 Zeus systemd[1]: photon-mgmtd.service: Passing 0 fds to service
Jan 06 16:32:19 Zeus systemd[1]: photon-mgmtd.service: About to execute /usr/bin/photon-mgmtd
Jan 06 16:32:19 Zeus systemd[1]: photon-mgmtd.service: Forked /usr/bin/photon-mgmtd as 230041
Jan 06 16:32:19 Zeus systemd[1]: photon-mgmtd.service: Changed failed -> running
Jan 06 16:32:19 Zeus systemd[1]: photon-mgmtd.service: Job 56328 photon-mgmtd.service/start finished, result=done
Jan 06 16:32:19 Zeus systemd[1]: Started photon-mgmtd.service - A REST API based configuration management microservice gateway.
Jan 06 16:32:19 Zeus systemd[230041]: photon-mgmtd.service: Executing: /usr/bin/photon-mgmtd
Jan 06 16:32:19 Zeus photon-mgmtd[230041]: time="2022-01-06T16:32:19+05:30" level=info msg="photon-mgmtd: v0.1 (built go1.18beta1)"
Jan 06 16:32:19 Zeus photon-mgmtd[230041]: time="2022-01-06T16:32:19+05:30" level=info msg="Starting photon-mgmtd... Listening on unix domain socket='/run/photon-mgmt/mgmt.sock' in HTTP mode pid=103575">

How to Configure Users?

Unix domain socket

When you add users to the photon-mgmt group, they can access the unix socket. Use the following command to add a user: # usermod -a -G photon-mgmt exampleusername

5.16.4 - photon-mgmtd API

Use photon-mgmtd REST-APIs to manage, control, configure, and monitor services remotely.

You can use photon-mgmtd to manage the following:

  • Services
  • System
  • Network
  • User, Group, Host

5.16.4.1 - Service Management

POST Method

To manage the available services and take actions on the services, execute a POST request in the following format:

curl --unix-socket  /run/photon-mgmt/mgmt.sock  --request POST --data '{"action":"{command}”,”unit”:”{unit}"}' http://localhost/api/v1/service/systemd

The following table lists the parameters:

ParameterDescription
UnitThe name of the service you want to manage.
Action CommandsThe action you want to take on the service. Start, stop, restart, try-restart, reload-or-restart, reload, enable, disable, mask, unnmask, kill

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"action":"start","unit":"nginx.service"}' http://localhost/api/v1/service/systemd

Response:

{
   "success":true,
   "message":"",
   "errors":""
}

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"action":"stop","unit":"nginx.service"}' http://localhost/api/v1/service/systemd

Response:

{
   "success":true,
   "message":"",
   "errors":""
}

GET Method:

Status of all the services:

The systemctl list-unit-files command lists all the services available in the system. To fetch the list of services listed in the list-unit files, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/units

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/units

Status of a Specific Service:

To receive the status details of a specific service, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/{unit}/status

The following table lists the parameter:

ParameterDescription
UnitThe name of the service for which you want to get the status.

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost:5208/api/v1/service/systemd/nginx.service/status | jq	% Total % Received % Xferd Average Speed Time Time Time Current	Dload Upload Total Spent Left Speed	100 514 100 514 0 0 38298 0 --:--:-- --:--:-- --:--:-- 39538

Response:

{
   "success":true,
   "message":{
      "Property":"inactive",
      "Unit":"nginx.service",
      "Name":"nginx.service",
      "Description":"Nginx High-performance HTTP server and reverse proxy",
      "MainPid":0,
      "LoadState":"loaded",
      "ActiveState":"inactive",
      "SubState":"dead",
      "Followed":"",
      "Path":"/org/freedesktop/systemd1/unit/nginx_2eservice",
      "JobId":0,
      "JobType":"",
      "JobPath":"/",
      "UnitFileState":"disabled",
      "StateChangeTimestamp":0,
      "InactiveExitTimestamp":0,
      "ActiveEnterTimestamp":0,
      "ActiveExitTimestamp":0,
      "InactiveEnterTimestamp":0
   },
   "errors":""
}

Value of a Specific Property

To fetch the value of a specific property, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/manager/property/Version

The following table lists the parameter:

ParameterDescription
PropertyVersion, Features, Virtualization, Architecture, Tainted.

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://127.0.0.1/api/v1/service/systemd/manager/property/Virtualization

Response:

{
   "success":true,
   "message":{
      "property":"Virtualization",
      "value":"vmware"
   },
   "errors":""
}

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://127.0.0.1/api/v1/service/systemd/manager/property/Architecture

Response:

{
   "success":true,
   "message":{
      "property":"Architecture",
      "value":"x86-64"
   },
   "errors":""
}

Properties of a Specific Service

To fetch the property of a specific service, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/{unit}/property

The following table lists the parameter:

ParameterDescription
UnitThe name of the service for which you want to get the properties.

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/nginx.service/property

Properties of All Services

To fetch all the properties of a service, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/{unit}/propertyall

The following table lists the parameter:

ParameterDescription
UnitThe name of the service for which you want to fetch the properties.

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/nginx.service/propertyall | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 9652 0 9652 0 0 1058k 0 --:--:-- --:--:-- --:--:-- 1178k

Configuration Details

To receive the configuration details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/conf

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/conf

Response:

{
   "success":true,
   "message":{
      "CPUAffinity":"",
      "CapabilityBoundingSe":"",
      "CrashChangeVT":"",
      "CrashReboot":"",
      "CrashShell":"",
      "CtrlAltDelBurstAction":"",
      "DefaultBlockIOAccounting":"",
      "DefaultCPUAccounting":"",
      "DefaultEnvironment":"",
      "DefaultIOAccounting":"",
      "DefaultIPAccounting":"",
      "DefaultLimitAS":"",
      "DefaultLimitCORE":"",
      "DefaultLimitCPU":"",
      "DefaultLimitDATA":"",
      "DefaultLimitFSIZE":"",
      "DefaultLimitLOCKS":"",
      "DefaultLimitMEMLOCK":"",
      "DefaultLimitMSGQUEUE":"",
      "DefaultLimitNICE":"",
      "DefaultLimitNOFILE":"",
      "DefaultLimitNPROC":"",
      "DefaultLimitRSS":"",
      "DefaultLimitRTPRIO":"",
      "DefaultLimitRTTIME":"",
      "DefaultLimitSIGPENDING":"",
      "DefaultLimitSTACK":"",
      "DefaultMemoryAccounting":"",
      "DefaultRestartSec":"",
      "DefaultStandardError":"",
      "DefaultStandardOutput":"",
      "DefaultStartLimitBurst":"",
      "DefaultStartLimitIntervalSec":"",
      "DefaultTasksAccounting":"",
      "DefaultTasksMax":"",
      "DefaultTimeoutStartSec":"",
      "DefaultTimeoutStopSec":"",
      "DefaultTimerAccuracySec":"",
      "DumpCore":"",
      "IPAddressAllow":"",
      "IPAddressDeny":"",
      "JoinControllers":"",
      "LogColor":"",
      "LogLevel":"",
      "LogLocation":"",
      "LogTarget":"",
      "RuntimeWatchdogSec":"",
      "ShowStatus":"",
      "ShutdownWatchdogSec":"",
      "SystemCallArchitectures":"",
      "TimerSlackNSec":""
   },
   "errors":""
}

Configuration Update Details

To fetch the details about the configuration updates, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/conf/update

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/service/systemd/conf/update

Response:

{
   "success":true,
   "message":{
      "CPUAffinity":"",
      "CapabilityBoundingSe":"",
      "CrashChangeVT":"",
      "CrashReboot":"",
      "CrashShell":"",
      "CtrlAltDelBurstAction":"",
      "DefaultBlockIOAccounting":"",
      "DefaultCPUAccounting":"",
      "DefaultEnvironment":"",
      "DefaultIOAccounting":"",
      "DefaultIPAccounting":"",
      "DefaultLimitAS":"",
      "DefaultLimitCORE":"",
      "DefaultLimitCPU":"",
      "DefaultLimitDATA":"",
      "DefaultLimitFSIZE":"",
      "DefaultLimitLOCKS":"",
      "DefaultLimitMEMLOCK":"",
      "DefaultLimitMSGQUEUE":"",
      "DefaultLimitNICE":"",
      "DefaultLimitNOFILE":"",
      "DefaultLimitNPROC":"",
      "DefaultLimitRSS":"",
      "DefaultLimitRTPRIO":"",
      "DefaultLimitRTTIME":"",
      "DefaultLimitSIGPENDING":"",
      "DefaultLimitSTACK":"",
      "DefaultMemoryAccounting":"",
      "DefaultRestartSec":"",
      "DefaultStandardError":"",
      "DefaultStandardOutput":"",
      "DefaultStartLimitBurst":"",
      "DefaultStartLimitIntervalSec":"",
      "DefaultTasksAccounting":"",
      "DefaultTasksMax":"",
      "DefaultTimeoutStartSec":"",
      "DefaultTimeoutStopSec":"",
      "DefaultTimerAccuracySec":"",
      "DumpCore":"",
      "IPAddressAllow":"",
      "IPAddressDeny":"",
      "JoinControllers":"",
      "LogColor":"",
      "LogLevel":"",
      "LogLocation":"",
      "LogTarget":"",
      "RuntimeWatchdogSec":"",
      "ShowStatus":"",
      "ShutdownWatchdogSec":"",
      "SystemCallArchitectures":"",
      "TimerSlackNSec":""
   },
   "errors":""
}

5.16.4.2 - System Management

GET Method

System Information

To fetch the complete system information, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/describe

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/describe | jq	% Total % Received % Xferd Average Speed Time Time Time Current	Dload Upload Total Spent Left Speed	100 5588 0 5588 0 0 42133 0 --:--:-- --:--:-- --:--:-- 42015

CPU Information

To fetch information related to CPU, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/cpuinfo

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/cpuinfo

Disk Usage Details

To fetch the usage details of the disk, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/diskusage

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/diskusage

Response:

{
   "success":true,
   "message":{
      "path":"/",
      "fstype":"ext2/ext3",
      "total":269474643968,
      "free":241944858624,
      "used":13769904128,
      "usedPercent":5.3848686637440935,
      "inodesTotal":16777216,
      "inodesUsed":101362,
      "inodesFree":16675854,
      "inodesUsedPercent":0.6041646003723145
   },
   "errors":""
}

Platform & kernel version details

To fetch the details about the platform and kernel versions on which the system is installed:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/version

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/version

Response:

{
   "success":true,
   "message":{
      "hostname":"photon-4",
      "uptime":10168492,
      "bootTime":1627041016,
      "procs":475,
      "os":"linux",
      "platform":"photon",
      "platformFamily":"",
      "platformVersion":"4.0",
      "kernelVersion":"5.10.46-2.ph4",
      "kernelArch":"x86_64",
      "virtualizationSystem":"",
      "virtualizationRole":"",
      "hostId":"25a54d56-2249-524d-1355-e97b24e3415a"
   },
   "errors":""
}

Miscellaneous Hardware Details

To fetch miscellaneous harware details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/misc

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/misc

Response:

{
   "success":true,
   "message":{
      "175":"agpgart",
      "183":"hw_random",
      "228":"hpet",
      "229":"fuse",
      "231":"snapshot",
      "235":"autofs",
      "237":"loop-control",
      "60":"vsock",
      "61":"vmci",
      "62":"cpu_dma_latency",
      "63":"vga_arbiter"
   },
   "errors":""
}

User Details

To fetch the user details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/userstat

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/userstat

Virtual Memory Details

To fetch the details of the virtual memory, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/virtualmemory

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/virtualmemory

Response:

{
   "success":true,
   "message":{
      "total":16810287104,
      "available":15859195904,
      "used":519139328,
      "usedPercent":3.0882240427438687,
      "free":9925554176,
      "active":4017090560,
      "inactive":2234974208,
      "wired":0,
      "laundry":0,
      "buffers":171372544,
      "cached":6194221056,
      "writeBack":0,
      "dirty":0,
      "writeBackTmp":0,
      "shared":9539584,
      "slab":440422400,
      "sreclaimable":370315264,
      "sunreclaim":70107136,
      "pageTables":6144000,
      "swapCached":0,
      "commitLimit":8405143552,
      "committedAS":1310273536,
      "highTotal":0,
      "highFree":0,
      "lowTotal":0,
      "lowFree":0,
      "swapTotal":0,
      "swapFree":0,
      "mapped":126369792,
      "vmallocTotal":35184372087808,
      "vmallocUsed":46546944,
      "vmallocChunk":0,
      "hugePagesTotal":0,
      "hugePagesFree":0,
      "hugePageSize":2097152
   },
   "errors":""
}

Kernel Module Details

To fetch the details about the kernel module, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/modules

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/modules

Network ARP Details

To fetch the network ARP details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/net/arp

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/net/arp

Response:

{
   "success":true,
   "message":[
      {
         "IPAddress":"",
         "HWType":"",
         "Flags":"",
         "HWAddress":"",
         "Mask":"",
         "Device":""
      },
      {
         "IPAddress":"10.197.103.253",
         "HWType":"0x1",
         "Flags":"0x2",
         "HWAddress":"00:00:0c:9f:f4:28",
         "Mask":"*",
         "Device":"eth0"
      },
      {
         "IPAddress":"10.197.103.162",
         "HWType":"0x1",
         "Flags":"0x2",
         "HWAddress":"00:0c:29:b1:e6:16",
         "Mask":"*",
         "Device":"eth0"
      },
      {
         "IPAddress":"10.197.103.251",
         "HWType":"0x1",
         "Flags":"0x2",
         "HWAddress":"00:35:1a:9d:b8:e3",
         "Mask":"*",
         "Device":"eth0"
      },
      {
         "IPAddress":"10.197.103.174",
         "HWType":"0x1",
         "Flags":"0x2",
         "HWAddress":"00:0c:29:d3:c7:00",
         "Mask":"*",
         "Device":"eth0"
      },
      {
         "IPAddress":"10.197.103.252",
         "HWType":"0x1",
         "Flags":"0x2",
         "HWAddress":"00:f2:8b:e1:b0:13",
         "Mask":"*",
         "Device":"eth0"
      },
      {
         "IPAddress":"10.197.103.91",
         "HWType":"0x1",
         "Flags":"0x2",
         "HWAddress":"00:0c:29:41:07:8b",
         "Mask":"*",
         "Device":"eth0"
      }
   ],
   "errors":""
}

Partition Details

To fetch the partition details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/partitions

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/partitions

Platform Details

To fetch the details of the platform on which the system is installed, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/platform

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/platform

Respose:

{
   "success":true,
   "message":{
      "Platform":"photon",
      "Family":"",
      "Version":"4.0"
   },
   "errors":""
} 

Swap Memory Details

To fetch the swap memory details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/swapmemory

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/swapmemory

Response:

{
   "success":true,
   "message":{
      "total":0,
      "used":0,
      "free":0,
      "usedPercent":0,
      "sin":0,
      "sout":0,
      "pgIn":0,
      "pgOut":0,
      "pgFault":0,
      "pgMajFault":0
   },
   "errors":""
}

Input/Output Details of all Disk Partitions

To fetch the input/output (read/write) details of all the disk partition, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/iocounters

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/proc/iocounters

Response:

{
   "success":true,
   "message":{
      "loop0":{
         "readCount":16407,
         "mergedReadCount":0,
         "writeCount":0,
         "mergedWriteCount":0,
         "readBytes":3999833088,
         "writeBytes":0,
         "readTime":6294,
         "writeTime":0,
         "iopsInProgress":0,
         "ioTime":9088,
         "weightedIO":6294,
         "name":"loop0",
         "serialNumber":"",
         "label":""
      },
      "sda":{
         "readCount":85357,
         "mergedReadCount":13672,
         "writeCount":212568,
         "mergedWriteCount":783168,
         "readBytes":5029398016,
         "writeBytes":44981511680,
         "readTime":54628,
         "writeTime":17939082,
         "iopsInProgress":0,
         "ioTime":301572,
         "weightedIO":17993710,
         "name":"sda",
         "serialNumber":"",
         "label":""
      },
      "sda1":{
         "readCount":351,
         "mergedReadCount":0,
         "writeCount":0,
         "mergedWriteCount":0,
         "readBytes":1437696,
         "writeBytes":0,
         "readTime":33,
         "writeTime":0,
         "iopsInProgress":0,
         "ioTime":152,
         "weightedIO":33,
         "name":"sda1",
         "serialNumber":"",
         "label":""
      },
      "sda2":{
         "readCount":128,
         "mergedReadCount":23,
         "writeCount":1,
         "mergedWriteCount":0,
         "readBytes":916480,
         "writeBytes":512,
         "readTime":38,
         "writeTime":0,
         "iopsInProgress":0,
         "ioTime":56,
         "weightedIO":38,
         "name":"sda2",
         "serialNumber":"",
         "label":""
      },
      "sda3":{
         "readCount":84806,
         "mergedReadCount":13649,
         "writeCount":212567,
         "mergedWriteCount":783168,
         "readBytes":5025352192,
         "writeBytes":44981511168,
         "readTime":54540,
         "writeTime":17939082,
         "iopsInProgress":0,
         "ioTime":301444,
         "weightedIO":17993623,
         "name":"sda3",
         "serialNumber":"",
         "label":""
      },
      "sr0":{
         "readCount":7,
         "mergedReadCount":0,
         "writeCount":0,
         "mergedWriteCount":0,
         "readBytes":1024,
         "writeBytes":0,
         "readTime":0,
         "writeTime":0,
         "iopsInProgress":0,
         "ioTime":12,
         "weightedIO":0,
         "name":"sr0",
         "serialNumber":"",
         "label":""
      }
   },
   "errors":""
}

sysctl Configuration Details Using pmctl Tool

You can use the pmctl tool to fetch the sysctl configuration details. The following section lists the commands related to various use cases of sysctl configuration.

sysctl Configuration Details

To fetch all the sysctl configuration details in the system, use the following command in the pmctl tool:

pmctl status sysctl

Specific Variable Configuration in sysctl

To fetch a specific variable configuration in the sysctl configuration, use the following command in the pmctl tool:

pmctl status sysctl k <InputKey>

or

pmctl status sysctl key <InputKey>

Example:

>pmctl status sysctl k fs.file-max
fs.file-max: 9223372036854775807

Variable Configuration in sysctl

To fetch all the variable configuration in the sysctl configuration based on the input pattern, use the following command in the pmctl tool:

pmctl status sysctl p <InputPatern>

or

pmctl status sysctl pattern <InputPatern>

Example:

pmctl status sysctl p net.ipv6.route.gc{
   "net.ipv6.route.gc_elasticity":"9",
   "net.ipv6.route.gc_interval":"30",
   "net.ipv6.route.gc_min_interval":"0",
   "net.ipv6.route.gc_min_interval_ms":"500",
   "net.ipv6.route.gc_thresh":"1024",
   "net.ipv6.route.gc_timeout":"60"
}

Add or Update Variable Configuration in sysctl

To add or Update a variable configuration in the sysctl configuration, use the following command in the pmctl tool.

pmctl sysctl u -k <InputKey> -v <InputValue> -f <InputFile>

or

pmctl sysctl update key <InputKey> value <InputValue> filename <InputFile>

Examples:

pmctl sysctl u -k fs.file-max -v 65566 -f 99-sysctl.conf

pmctl sysctl u -k fs.file-max -v 65566

Remove Variable Configuration in sysctl

To remove a variable configuration in the sysctl configuration, use the following command in the pmctl tool:

pmctl sysctl r -k <InputKey> -f <InputFile>

or

pmctl sysctl remove key <InputKey> filename <InputFile>

Examples:

pmctl sysctl r -k fs.file-max -f 99-sysctl.conf

pmctl sysctl r -k fs.file-max

Load sysctl Configuration Files

To Load sysctl configuration files, use the following command in the pmctl tool:

pmctl sysctl l -f <InputfileList>

or

pmctl sysctl load files <InputFileList>

Examples:

pmctl sysctl l -f 99-sysctl.conf,70-sysctl.conf

pmctl sysctl l -f

sysctl Configuration Details Using Curl Command

sysctl Configuration

To fetch the sysctl configuration, execute a GET request in the following JSON format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/sysctl/statusall

Example:

>curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/sysctl/statusall

Specific Variable Configuration in sysctl

To fetch a specific variable configuration from sysctl configuration, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET --data '{"key":"<keyName>"}' http://localhost/api/v1/system/sysctl/status

Example:

>curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET --data '{"key":"fs.file-max"}' http://localhost/api/v1/system/sysctl/status

Variable Configuration in sysctl

To fetch all the variable configuration in sysctl, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET --data '{"pattern":"<Pattern>"}' http://localhost/api/v1/system/sysctl/statuspattern


>curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET --data '{"pattern":"fs.file"}' http://localhost/api/v1/system/sysctl/statuspattern

Add or Update Variable Configuration in sysctl Confiiguration

To add or update a variable configuration in the sysctl configuration, execute a POST request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"apply":true,"key":"<keyName>","value":"<Value>","filename":"<fileName>"}' http://localhost/api/v1/system/sysctl/update

Example:

>curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"apply":true,"key":"fs.file-max","value":"65409","filename":"99-sysctl.conf"}' http://localhost/api/v1/system/sysctl/update

Remove a Variable Configuration in sysctl Configuration

To remove a variable configuration from the sysctl configuration, execute a DELETE request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request DELETE --data '{"apply":true,"key":"<keyName>","filename":"<fileName>"}' http://localhost/api/v1/system/sysctl/remove

Example:

>curl --unix-socket /run/photon-mgmt/mgmt.sock --request DELETE --data '{"apply":true,"key":"fs.file-max","filename":"99-sysctl.conf"}' http://localhost/api/v1/system/sysctl/remove

Load sysctl Configuration Files

To load sysctl configuration files, execute a POST request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"apply":true,"files":["<fileName>","<fileName>"]}' http://localhost/api/v1/system/sysctl/load

Example:

>curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"apply":true,"files":["99-sysctl.conf","75-sysctl.conf"]}' http://localhost/api/v1/system/sysctl/load

5.16.4.3 - Network Management

GET Method

Network Details

To fetch complete network details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/network/describe | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 5238 0 5238 0 0 88919 0 --:--:-- --:--:-- --:--:-- 90310

Response:

{
   "success":true,
   "message":{
      "NetworDescribe":{
         "AddressState":"routable",
         "CarrierState":"carrier",
         "OperationalState":"routable",
         "OnlineState":"",
         "IPv4AddressState":"",
         "IPv6AddressState":"",
         "DNS":[
            "10.142.7.1",
            "10.132.7.1",
            "10.166.17.90"
         ],
         "Domains":null,
         "RouteDomains":null,
         "NTP":[
            "10.128.152.81",
            "10.166.1.120",
            "10.188.26.119",
            "10.84.55.42"
         ]
      },
      "LinksDescribe":{
         "Interfaces":[
            {
               "AddressState":"off",
               "AlternativeNames":null,
               "CarrierState":"carrier",
               "Driver":"",
               "IPv4AddressState":"",
               "IPv6AddressState":"",
               "Index":1,
               "LinkFile":"",
               "Model":"",
               "Name":"lo",
               "OnlineState":"",
               "OperationalState":"carrier",
               "Path":"",
               "SetupState":"unmanaged",
               "Type":"loopback",
               "Vendor":"",
               "Manufacturer":""
            },
            {
               "AddressState":"routable",
               "AlternativeNames":null,
               "CarrierState":"carrier",
               "Driver":"vmxnet3",
               "IPv4AddressState":"",
               "IPv6AddressState":"",
               "Index":2,
               "LinkFile":"",
               "Model":"VMXNET3 Ethernet Controller",
               "Name":"eth0",
               "OnlineState":"",
               "OperationalState":"routable",
               "Path":"pci-0000:0b:00.0",
               "SetupState":"configured",
               "Type":"ether",
               "Vendor":"VMware",
               "Manufacturer":"",
               "NetworkFile":"/etc/systemd/network/99-dhcp-en.network"
            }
         ]
      },
      "links":[
         {
            "Index":1,
            "MTU":65536,
            "TxQLen":1000,
            "Name":"lo",
            "AlternativeNames":"",
            "HardwareAddr":"",
            "Flags":"up|loopback",
            "RawFlags":65609,
            "ParentIndex":0,
            "MasterIndex":0,
            "Namespace":"",
            "Alias":"",
            "Statistics":{
               "RxPackets":168,
               "TxPackets":168,
               "RxBytes":17146,
               "TxBytes":17146,
               "RxErrors":0,
               "TxErrors":0,
               "RxDropped":0,
               "TxDropped":0,
               "Multicast":0,
               "Collisions":0,
               "RxLengthErrors":0,
               "RxOverErrors":0,
               "RxCrcErrors":0,
               "RxFrameErrors":0,
               "RxFifoErrors":0,
               "RxMissedErrors":0,
               "TxAbortedErrors":0,
               "TxCarrierErrors":0,
               "TxFifoErrors":0,
               "TxHeartbeatErrors":0,
               "TxWindowErrors":0,
               "RxCompressed":0,
               "TxCompressed":0
            },
            "Promisc":0,
            "Xdp":{
               "Fd":0,
               "Attached":false,
               "Flags":0,
               "ProgId":0
            },
            "EncapType":"loopback",
            "Protinfo":"",
            "OperState":"unknown",
            "NetNsID":0,
            "NumTxQueues":1,
            "NumRxQueues":1,
            "GSOMaxSize":65536,
            "GSOMaxSegs":65535,
            "Group":0,
            "Slave":""
         },
         {
            "Index":2,
            "MTU":1500,
            "TxQLen":1000,
            "Name":"eth0",
            "AlternativeNames":"",
            "HardwareAddr":"00:0c:29:68:ed:d8",
            "Flags":"up|broadcast|multicast",
            "RawFlags":69699,
            "ParentIndex":0,
            "MasterIndex":0,
            "Namespace":"",
            "Alias":"",
            "Statistics":{
               "RxPackets":179491,
               "TxPackets":25306,
               "RxBytes":281174090,
               "TxBytes":2339627,
               "RxErrors":0,
               "TxErrors":0,
               "RxDropped":120,
               "TxDropped":0,
               "Multicast":0,
               "Collisions":0,
               "RxLengthErrors":0,
               "RxOverErrors":0,
               "RxCrcErrors":0,
               "RxFrameErrors":0,
               "RxFifoErrors":0,
               "RxMissedErrors":0,
               "TxAbortedErrors":0,
               "TxCarrierErrors":0,
               "TxFifoErrors":0,
               "TxHeartbeatErrors":0,
               "TxWindowErrors":0,
               "RxCompressed":0,
               "TxCompressed":0
            },
            "Promisc":0,
            "Xdp":{
               "Fd":0,
               "Attached":false,
               "Flags":0,
               "ProgId":0
            },
            "EncapType":"ether",
            "Protinfo":"",
            "OperState":"up",
            "NetNsID":0,
            "NumTxQueues":8,
            "NumRxQueues":8,
            "GSOMaxSize":65536,
            "GSOMaxSegs":65535,
            "Group":0,
            "Slave":""
         }
      ],
      "Addresses":[
         {
            "Name":"lo",
            "Ifindex":1,
            "OperState":"unknown",
            "Mac":"",
            "MTU":65536,
            "Addresses":[
               {
                  "IP":"127.0.0.1",
                  "Mask":8,
                  "Label":"lo",
                  "Flags":128,
                  "Scope":254,
                  "Peer":"",
                  "Broadcast":"",
                  "PreferedLft":4294967295,
                  "ValidLft":4294967295
               },
               {
                  "IP":"::1",
                  "Mask":128,
                  "Label":"",
                  "Flags":128,
                  "Scope":254,
                  "Peer":"",
                  "Broadcast":"",
                  "PreferedLft":4294967295,
                  "ValidLft":4294967295
               }
            ]
         },
         {
            "Name":"eth0",
            "Ifindex":2,
            "OperState":"up",
            "Mac":"00:0c:29:68:ed:d8",
            "MTU":1500,
            "Addresses":[
               {
                  "IP":"10.197.103.42",
                  "Mask":23,
                  "Label":"eth0",
                  "Flags":0,
                  "Scope":0,
                  "Peer":"",
                  "Broadcast":"10.197.103.255",
                  "PreferedLft":3927,
                  "ValidLft":3927
               },
               {
                  "IP":"fe80::20c:29ff:fe68:edd8",
                  "Mask":64,
                  "Label":"",
                  "Flags":128,
                  "Scope":253,
                  "Peer":"",
                  "Broadcast":"",
                  "PreferedLft":4294967295,
                  "ValidLft":4294967295
               }
            ]
         }
      ],
      "Routes":[
         {
            "LinkName":"eth0",
            "LinkIndex":2,
            "ILinkIndex":0,
            "Scope":0,
            "Dst":{
               "IP":"",
               "Mask":0
            },
            "Src":"10.197.103.42",
            "Gw":"10.197.103.253",
            "MultiPath":"",
            "Protocol":16,
            "Priority":1024,
            "Table":254,
            "Type":1,
            "Tos":0,
            "Flags":null,
            "MPLSDst":"",
            "NewDst":"",
            "Encap":"",
            "MTU":0,
            "AdvMSS":0,
            "Hoplimit":0
         },
         {
            "LinkName":"eth0",
            "LinkIndex":2,
            "ILinkIndex":0,
            "Scope":253,
            "Dst":{
               "IP":"10.197.102.0",
               "Mask":23
            },
            "Src":"10.197.103.42",
            "Gw":"",
            "MultiPath":"",
            "Protocol":2,
            "Priority":0,
            "Table":254,
            "Type":1,
            "Tos":0,
            "Flags":null,
            "MPLSDst":"",
            "NewDst":"",
            "Encap":"",
            "MTU":0,
            "AdvMSS":0,
            "Hoplimit":0
         },
         {
            "LinkName":"eth0",
            "LinkIndex":2,
            "ILinkIndex":0,
            "Scope":253,
            "Dst":{
               "IP":"10.197.103.253",
               "Mask":32
            },
            "Src":"10.197.103.42",
            "Gw":"",
            "MultiPath":"",
            "Protocol":16,
            "Priority":1024,
            "Table":254,
            "Type":1,
            "Tos":0,
            "Flags":null,
            "MPLSDst":"",
            "NewDst":"",
            "Encap":"",
            "MTU":0,
            "AdvMSS":0,
            "Hoplimit":0
         },
         {
            "LinkName":"lo",
            "LinkIndex":1,
            "ILinkIndex":0,
            "Scope":0,
            "Dst":{
               "IP":"::1",
               "Mask":128
            },
            "Src":"",
            "Gw":"",
            "MultiPath":"",
            "Protocol":2,
            "Priority":256,
            "Table":254,
            "Type":1,
            "Tos":0,
            "Flags":null,
            "MPLSDst":"",
            "NewDst":"",
            "Encap":"",
            "MTU":0,
            "AdvMSS":0,
            "Hoplimit":0
         },
         {
            "LinkName":"eth0",
            "LinkIndex":2,
            "ILinkIndex":0,
            "Scope":0,
            "Dst":{
               "IP":"fe80::",
               "Mask":64
            },
            "Src":"",
            "Gw":"",
            "MultiPath":"",
            "Protocol":2,
            "Priority":256,
            "Table":254,
            "Type":1,
            "Tos":0,
            "Flags":null,
            "MPLSDst":"",
            "NewDst":"",
            "Encap":"",
            "MTU":0,
            "AdvMSS":0,
            "Hoplimit":0
         }
      ],
      "Dns":[
         {
            "Link":"eth0",
            "Family":2,
            "Dns":"10.142.7.1"
         },
         {
            "Link":"eth0",
            "Family":2,
            "Dns":"10.132.7.1"
         },
         {
            "Link":"eth0",
            "Family":2,
            "Dns":"10.166.17.90"
         }
      ],
      "Domains":null,
      "NTP":{
         "ServerName":"",
         "Family":0,
         "ServerAddress":"",
         "SystemNTPServers":null,
         "LinkNTPServers":[
            "10.128.152.81",
            "10.166.1.120",
            "10.188.26.119",
            "10.84.55.42"
         ]
      }
   },
   "errors":""
}

Route Details

To fetch the route details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/network/netlink/route

Example:

root@photon [ ~/4.0/photon ]# curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/network/netlink/route | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1407 100 1407 0 0 996k 0 --:--:-- --:--:-- --:--:-- 1374k

Response:

{
   "success":true,
   "message":[
      {
         "LinkName":"eth0",
         "LinkIndex":2,
         "ILinkIndex":0,
         "Scope":0,
         "Dst":{
            "IP":"",
            "Mask":0
         },
         "Src":"10.197.103.42",
         "Gw":"10.197.103.253",
         "MultiPath":"",
         "Protocol":16,
         "Priority":1024,
         "Table":254,
         "Type":1,
         "Tos":0,
         "Flags":null,
         "MPLSDst":"",
         "NewDst":"",
         "Encap":"",
         "MTU":0,
         "AdvMSS":0,
         "Hoplimit":0
      },
      {
         "LinkName":"eth0",
         "LinkIndex":2,
         "ILinkIndex":0,
         "Scope":253,
         "Dst":{
            "IP":"10.197.102.0",
            "Mask":23
         },
         "Src":"10.197.103.42",
         "Gw":"",
         "MultiPath":"",
         "Protocol":2,
         "Priority":0,
         "Table":254,
         "Type":1,
         "Tos":0,
         "Flags":null,
         "MPLSDst":"",
         "NewDst":"",
         "Encap":"",
         "MTU":0,
         "AdvMSS":0,
         "Hoplimit":0
      },
      {
         "LinkName":"eth0",
         "LinkIndex":2,
         "ILinkIndex":0,
         "Scope":253,
         "Dst":{
            "IP":"10.197.103.253",
            "Mask":32
         },
         "Src":"10.197.103.42",
         "Gw":"",
         "MultiPath":"",
         "Protocol":16,
         "Priority":1024,
         "Table":254,
         "Type":1,
         "Tos":0,
         "Flags":null,
         "MPLSDst":"",
         "NewDst":"",
         "Encap":"",
         "MTU":0,
         "AdvMSS":0,
         "Hoplimit":0
      },
      {
         "LinkName":"lo",
         "LinkIndex":1,
         "ILinkIndex":0,
         "Scope":0,
         "Dst":{
            "IP":"::1",
            "Mask":128
         },
         "Src":"",
         "Gw":"",
         "MultiPath":"",
         "Protocol":2,
         "Priority":256,
         "Table":254,
         "Type":1,
         "Tos":0,
         "Flags":null,
         "MPLSDst":"",
         "NewDst":"",
         "Encap":"",
         "MTU":0,
         "AdvMSS":0,
         "Hoplimit":0
      },
      {
         "LinkName":"eth0",
         "LinkIndex":2,
         "ILinkIndex":0,
         "Scope":0,
         "Dst":{
            "IP":"fe80::",
            "Mask":64
         },
         "Src":"",
         "Gw":"",
         "MultiPath":"",
         "Protocol":2,
         "Priority":256,
         "Table":254,
         "Type":1,
         "Tos":0,
         "Flags":null,
         "MPLSDst":"",
         "NewDst":"",
         "Encap":"",
         "MTU":0,
         "AdvMSS":0,
         "Hoplimit":0
      }
   ],
   "errors":""
}

To fetch all the interfaces links details (such as interface, mac address, and transaction), execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/network/netlink/link

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock http://localhost/api/v1/network/netlink/link

Response:

{
   "success":true,
   "message":[
      {
         "Index":1,
         "MTU":65536,
         "TxQLen":1000,
         "Name":"lo",
         "AlternativeNames":"",
         "HardwareAddr":"",
         "Flags":"up|loopback",
         "RawFlags":65609,
         "ParentIndex":0,
         "MasterIndex":0,
         "Namespace":"",
         "Alias":"",
         "Statistics":{
            "RxPackets":168,
            "TxPackets":168,
            "RxBytes":17146,
            "TxBytes":17146,
            "RxErrors":0,
            "TxErrors":0,
            "RxDropped":0,
            "TxDropped":0,
            "Multicast":0,
            "Collisions":0,
            "RxLengthErrors":0,
            "RxOverErrors":0,
            "RxCrcErrors":0,
            "RxFrameErrors":0,
            "RxFifoErrors":0,
            "RxMissedErrors":0,
            "TxAbortedErrors":0,
            "TxCarrierErrors":0,
            "TxFifoErrors":0,
            "TxHeartbeatErrors":0,
            "TxWindowErrors":0,
            "RxCompressed":0,
            "TxCompressed":0
         },
         "Promisc":0,
         "Xdp":{
            "Fd":0,
            "Attached":false,
            "Flags":0,
            "ProgId":0
         },
         "EncapType":"loopback",
         "Protinfo":"",
         "OperState":"unknown",
         "NetNsID":0,
         "NumTxQueues":1,
         "NumRxQueues":1,
         "GSOMaxSize":65536,
         "GSOMaxSegs":65535,
         "Group":0,
         "Slave":""
      },
      {
         "Index":2,
         "MTU":1500,
         "TxQLen":1000,
         "Name":"eth0",
         "AlternativeNames":"",
         "HardwareAddr":"00:0c:29:68:ed:d8",
         "Flags":"up|broadcast|multicast",
         "RawFlags":69699,
         "ParentIndex":0,
         "MasterIndex":0,
         "Namespace":"",
         "Alias":"",
         "Statistics":{
            "RxPackets":226492,
            "TxPackets":25740,
            "RxBytes":289546384,
            "TxBytes":2689948,
            "RxErrors":0,
            "TxErrors":0,
            "RxDropped":120,
            "TxDropped":0,
            "Multicast":0,
            "Collisions":0,
            "RxLengthErrors":0,
            "RxOverErrors":0,
            "RxCrcErrors":0,
            "RxFrameErrors":0,
            "RxFifoErrors":0,
            "RxMissedErrors":0,
            "TxAbortedErrors":0,
            "TxCarrierErrors":0,
            "TxFifoErrors":0,
            "TxHeartbeatErrors":0,
            "TxWindowErrors":0,
            "RxCompressed":0,
            "TxCompressed":0
         },
         "Promisc":0,
         "Xdp":{
            "Fd":0,
            "Attached":false,
            "Flags":0,
            "ProgId":0
         },
         "EncapType":"ether",
         "Protinfo":"",
         "OperState":"up",
         "NetNsID":0,
         "NumTxQueues":8,
         "NumRxQueues":8,
         "GSOMaxSize":65536,
         "GSOMaxSegs":65535,
         "Group":0,
         "Slave":""
      }
   ],
   "errors":""
}

Network DNS Status

To fetch the network DNS status, use the following command in pmctl:

>pmctl status network dns
Global

        DNS: 8.8.8.1 8.8.8.2 
DNS Domains: test3.com test4.com . localdomain . localdomain 
Link 2 (ens33)
Current DNS Server:  172.16.61.2
       DNS Servers:  172.16.61.2

Link 3 (ens37)
Current DNS Server:  172.16.61.2
       DNS Servers:  172.16.61.2

Network iostat Status

To fetch the network iostat status, use the following command in pmctl:

> pmctl status network iostat
            Name: lo
Packets received: 7510
  Bytes received: 7510
      Bytes sent: 7510
         Drop in: 7510
        Drop out: 0
        Error in: 0
       Error out: 0
         Fifo in: 0
        Fifo out: 0

            Name: ens33
Packets received: 46014
  Bytes received: 19072
      Bytes sent: 19072
         Drop in: 19072
        Drop out: 0
        Error in: 0
       Error out: 0
         Fifo in: 0
        Fifo out: 0

            Name: ens37
Packets received: 9682
  Bytes received: 10779
      Bytes sent: 10779
         Drop in: 10779
        Drop out: 0
        Error in: 0
       Error out: 0
         Fifo in: 0
        Fifo out: 0

Network interfaces status

To fetch the network status of the network interfaces, use the following command in pmctl:

> pmctl status network interfaces
            Name: lo
           Index: 1
             MTU: 65536
           Flags: up loopback
Hardware Address: 
       Addresses: 127.0.0.1/8 ::1/128

            Name: ens33
           Index: 2
             MTU: 1500
           Flags: up broadcast multicast
Hardware Address: 00:0c:29:7c:6f:84
       Addresses: 172.16.61.128/24 fe80::c099:2598:cc4c:14d1/64

            Name: ens37
           Index: 3
             MTU: 1500
           Flags: up broadcast multicast
Hardware Address: 00:0c:29:7c:6f:8e
       Addresses: 172.16.61.134/24 fe80::be9:7746:7729:3e2/64

You can configure the network links using pmctl command. The following section lists the commands you can use to configure network links.

Configure Network dhcp

pmctl network set-dhcp <deviceName> <DHCPMode>

Example:

>pmctl network set-dhcp ens37 ipv4

Configure network linkLocalAddressing

pmctl network set-link-local-addr <deviceName> <linkLocalAddressingMode>

Example:

>pmctl network set-link-local-addr ens37 ipv4

Configure network multicastDNS

pmctl network set-multicast-dns <deviceName> <MulticastDNSMode>

Example:

>pmctl network set-multicast-dns ens37 resolve

Configure network address

pmctl network add-link-address <deviceName> address <Address> peer <Address> label <labelValue> scope <scopeValue>

Example:

>pmctl network add-link-address ens37 address 192.168.0.15/24 peer 192.168.10.10/24 label ipv4 scope link

Configure network route

pmctl network add-route dev <deviceName> gw <Gateway> gwonlink <GatewayOnlink> src <Source> dest <Destination> prefsrc <preferredSource> table <Table> scope <Scope>

Example:

>pmctl network add-route dev ens33 gw 192.168.1.0 gwonlink no src 192.168.1.15/24 dest 192.168.10.10/24 prefsrc 192.168.8.9 table 1234 scope link

Configure network dns

pmctl network add-dns dev <deviceName> dns <dnslist>

Example:

>pmctl network add-dns dev ens37 dns 8.8.8.8,8.8.4.4,8.8.8.1,8.8.8.2

Configure network domains

pmctl network add-domain dev <deviceName> domains <domainlist>

Example:

>pmctl network add-domain dev ens37 domains test1.com,test2.com,test3.com,test4.com

Configure network ntp

pmctl network add-ntp dev <deviceName> ntp <ntplist>

Example:

>pmctl network add-ntp dev ens37 ntp 198.162.1.15,test3.com

Configure network ipv6AcceptRA

pmctl network set-ipv6-accept-ra <deviceName> <IPv6AcceptRA>

Example:

>pmctl network set-ipv6-accept-ra ens37 false
pmctl network set-link-mode dev <device> mode <unmanagedValue> arp <arpValue> mc <multicastValue> amc <allmulticastValue> pcs <PromiscuousValue> rfo <RequiredForOnline>

Example:

>pmctl network set-link-mode dev ens37 arp 1 mc no amc true pcs yes rfo on
pmctl network set-mtu <deviceName> <mtubytesValue>

Example:

>pmctl network set-mtu ens37 2048
pmctl network set-mac <deviceName> <MACAddress>

Example:

>pmctl network set-gmac ens37 00:a0:de:63:7a:e6
pmctl network set-group <deviceName> <groupValue>

Example:

>pmctl network set-group ens37 2147483647
pmctl network set-rf-online <deviceName> <familyValue>

Example:

>pmctl network set-rf-online ens37 ipv4
pmctl network set-active-policy <deviceName> <policyValue>

Example:

>pmctl network set-active-policy ens37 always-up

Configure network routingPolicyRule

pmctl network add-rule dev <deviceName> tos <TypeOfService> from <Address> to <Address> fwmark <FirewallMark> table <Table> prio <Priority> iif <IncomingInterface> oif <OutgoingInterface> srcport <SourcePort> destport <DestinationPort> ipproto <IPProtocol> invertrule <InvertRule> family <Family> usr <User> suppressprefixlen <SuppressPrefixLength> suppressifgrp <SuppressInterfaceGroup> type <Type>

Example:

>pmctl network add-rule dev ens37 tos 12 from 192.168.1.10/24 to 192.168.2.20/24 fwmark 7/255 table 8 prio 3 iif ens37 oif ens37 srcport 8000-8080 destport 9876 ipproto 17 invertrule yes family ipv4 usr 1001 suppressprefixlen 128 suppressifgrp 2098 type prohibit

Remove network routingPolicyRule

pmctl network delete-rule dev <deviceName> tos <TypeOfService> from <Address> to <Address> fwmark <FirewallMark> table <Table> prio <Priority> iif <IncomingInterface> oif <OutgoingInterface> srcport <SourcePort> destport <DestinationPort> ipproto <IPProtocol> invertrule <InvertRule> family <Family> usr <User> suppressprefixlen <SuppressPrefixLength> suppressifgrp <SuppressInterfaceGroup> type <Type>

Example:

>pmctl network delete-rule dev ens37 tos 12 from 192.168.1.10/24 to 192.168.2.20/24 fwmark 7/255 table 8 prio 3 iif ens37 oif ens37 srcport 8000-8080 destport 9876 ipproto 17 invertrule yes family ipv4 usr 1001 suppressprefixlen 128 suppressifgrp 2098 type prohibit

Configure network DHCPv4 id’s

pmctl network set-dhcpv4-id dev <deviceName> clientid <ClientIdentifier> vendorclassid <VendorClassIdentifier> iaid <IAID>

Example:

>pmctl network set-dhcpv4-id dev ens37 clientid duid vendorclassid 101 iaid 201

Configure network DHCPv4 duid

pmctl network set-dhcpv4-duid dev <deviceName> duidtype <DUIDType> duidrawdata <DUIDRawData>

Example:

>pmctl network set-dhcpv4-duid dev ens37 duidtype vendor duidrawdata af:03:ff:87

Configure network DHCPv4 use options

pmctl network set-dhcpv4-use dev <deviceName> usedns <UseDNS> usentp <UseNTP> usesip <UseSIP> usemtu <UseMTU> usehostname <UseHostname> usedomains <UseDomains> useroutes <UseRoutes> usegateway <UseGateway> usetimezone <UseTimezone>

Example:

>pmctl network set-dhcpv4-use dev ens37 usedns false usentp false usesip false usemtu yes usehostname true usedomains yes useroutes no usegateway yes usetimezone no

Configure network DHCPv6

pmctl network set-dhcpv6 dev <deviceName> mudurl <MUDURL> userclass <UserClass> vendorclass <VendorClass> prefixhint <IPV6ADDRESS> withoutra <WithoutRA>

Example:

>pmctl network set-dhcpv6 dev ens37 mudurl https://example.com/devB userclass usrcls1,usrcls2 vendorclass vdrcls1 prefixhint 2001:db1:fff::/64 withoutra solicit

Configure network DHCPv6 id’s

pmctl network set-dhcpv6-id dev <deviceName> iaid <IAID> duidtype <DUIDType> duidrawdata <DUIDRawData>

Example:

>pmctl network set-dhcpv6-id dev ens37 iaid 201 duidtype vendor duidrawdata af:03:ff:87

Configure network DHCPv6 Use

pmctl network set-dhcpv6-use dev <deviceName> useaddr <UseAddress> useprefix <UsePrefix> usedns <UseDNS> usentp <UseNTP> usehostname <UseHostname> usedomains <UseDomains>

Example:

>pmctl network set-dhcpv6-use dev ens37 useaddr yes useprefix no usedns false usentp false usehostname true usedomains yes

Configure network DHCPv6 Options

pmctl network set-dhcpv6-option dev <deviceName> reqopt <RequestOptions> sendopt <SendOption> sendvendoropt <SendVendorOption>

Example:

>pmctl network set-dhcpv6-option dev ens37 reqopt 10,198,34 sendopt 34563 sendvendoropt 1987653,65,ipv6address,af:03:ff:87

Configure network DHCPServer

pmctl network add-dhcpv4-server dev <Devicename> pool-offset <poolOffset> pool-size <PoolSize> default-lease-time-sec <DefaultLeaseTimeSec> max-lease-time-sec <MaxLeaseTimeSec> dns <DNS> emit-dns <EmitDNS> emit-ntp <EmitNTP> emit-router <EmitRouter>

Example:

>pmctl network add-dhcpv4-server dev ens37 pool-offset 100 pool-size 200 default-lease-time-sec 10 max-lease-time-sec 30 dns 192.168.1.2,192.168.10.10,192.168.20.30 emit-dns yes emit-ntp no emit-router yes

Remove network DHCPServer

pmctl network remove-dhcpv4-server <Devicename>

Example:

>pmctl network remove-dhcpv4-server ens37

Configure network IPv6SendRA

pmctl network add-ipv6ra dev <deviceName> rt-pref <RouterPreference> emit-dns <EmitDNS> dns <DNS> emit-domains <EmitDomains> domains <Domains> dns-lifetime-sec <DNSLifetimeSec> prefix <Prefix> pref-lifetime-sec <PreferredLifetimeSec> valid-lifetime-sec <ValidLifetimeSec> assign <Assign> route <Route> lifetime-sec <LifetimeSec>

Example:

>pmctl network add-ipv6ra dev ens37 rt-pref medium emit-dns yes dns 2002:da8:1::1,2002:da8:2::1 emit-domains yes domains test1.com,test2.com dns-lifetime-sec 100 prefix 2002:da8:1::/64 pref-lifetime-sec 100 valid-lifetime-sec 200 assign yes route 2001:db1:fff::/64 lifetime-sec 1000

Remove network IPv6SendRA

pmctl network remove-ipv6ra <Devicename>

Example:

>pmctl network remove-ipv6ra ens37

Configure Network Device using pmctl

You can configure the network devices using pmctl command. Use the following commands to configure network devices.

Configure VLan

pmctl network create-vlan <vlanName> dev <device> id <vlanId>

Example:

>pmctl network create-vlan vlan1 dev ens37 id 101

Configure Bond

pmctl network create-bond <bondName> dev <device> mode <modeType> thp <TransmitHashPolicyType> ltr <LACPTransmitRateType> mms <MIIMonitorSecTime>

Example:

>pmctl network create-bond bond1 dev ens37,ens38 mode 802.3ad thp layer2+3 ltr slow mms 1s

Configure Bond with default

Example:

>pmctl network create-bond bond1 dev ens37,ens38

Configure Bridge with default

pmctl network create-bridge <bridgeName> dev <device list>

Example:

>pmctl network create-bridge br0 dev ens37,ens38

Configure MacVLan

pmctl network create-macvlan <macvlanName> dev <device> mode <modeName>

Example:

>pmctl network create-macvlan macvlan1 dev ens37 mode private 

Configure IpVLan

pmctl network create-ipvlan <ipvlanName> dev <device> mode <modeName> flags <flagsName>

Example:

>pmctl network create-ipvlan ipvlan1 dev ens37 mode l2 flags vepa

Configure IpVLan with default

Example:

>pmctl network create-ipvlan ipvlan1 dev ens38

Configure VxLan

pmctl network create-vxlan <vxlanName> dev <device> remote <RemoteAddress> local <LocalAddress> group <GroupAddress> destport <DestinationPort> independent <IndependentFlag>

Example:

>pmctl network create-vxlan vxlan1 dev ens37 vni 16777215 remote 192.168.1.3 local 192.168.1.2 group 192.168.0.0 destport 4789 independent no 

Configure WireGuard

pmctl network create-wg <wireguardName> dev <device> skey <privateKey> pkey<publicKey> endpoint <address:Port> port <listenport> ips <allowedIPs>

Example:

>pmctl network create-wg wg1 dev ens37 skey wCmc/74PQpRoxTgqGircVFtdArZFUFIiOoyQY8kVgmI= pkey dSanSzExlryduCwNnAFt+rzpI5fKeHuJx1xx2zxEG2Q= endpoint 10.217.69.88:51820 port 51822 ips fd31:bf08:57cb::/48,192.168.26.0/24

Configure WireGuard with default

Example:

>pmctl network create-wg wg1 dev ens37 skey wCmc/74PQpRoxTgqGircVFtdArZFUFIiOoyQY8kVgmI= pkey dSanSzExlryduCwNnAFt+rzpI5fKeHuJx1xx2zxEG2Q= endpoint 10.217.69.88:51820

Remove Network Device Using pmctl

To remove a network device, use the following command in pmctl:

pmctl network remove-netdev <kindDeviceName> kind <kindType>

Example:

>pmctl network remove-netdev ipvlan1 dev ens37 kind ipvlan

Use the following commands to configure links using the pmctl command.

pmctl link set-mac dev <deviceName> macpolicy <MACAddressPolicy> macaddr <MACAddress>

Example:

>pmctl link set-mac dev eth0 macpolicy none macaddr 00:a0:de:63:7a:e6
pmctl link set-name dev <deviceName> namepolicy <NamePolicy> name <Name>

Example:

>pmctl link set-name dev ens37 namepolicy mac,kernel,database,onboard,keep,slot,path
pmctl link set-name dev <deviceName> altnamespolicy <AlternativeNamesPolicy> altname <AlternativeName>

Example:

>pmctl link set-alt-name dev ens37 altnamespolicy mac,database,onboard,slot,path
pmctl link set-csum-offload dev <deviceName> rco <ReceiveCheksumOffload> tco <TransmitChecksumOffload>

Example:

>pmctl link set-csum-offload dev ens37 rxco true txco true
pmctl link set-tcp-offload dev <deviceName> tcpso <TCPSegmentationOffload> tcp6so <TCP6SegmentationOffload>

Example:

>pmctl link set-tcp-offload dev ens37 tcpso true tcp6so true
pmctl link set-generic-offload dev <deviceName> gso <GenericSegmentationOffload> gro <GenericReceiveOffload> grohw <GenericReceiveOffloadHardware> gsomaxbytes <GenericSegmentOffloadMaxBytes> gsomaxseg <GenericSegementOffloadMaxSegments>

Example:

>pmctl link set-generic-offload dev ens37 gso true gro true grohw false gsomaxbytes 65536 gsomaxseg 65535
pmctl link set-vlan-tags dev <deviceName> rxvlanctaghwacl <ReceiveVLANCTAGHardwareAcceleration> txvlanctaghwacl <TransmitVLANCTAGHardwareAcceleration> rxvlanctagfilter <ReceiveVLANCTAGFilter> txvlanstaghwacl <TransmitVLANSTAGHardwareAcceleration>

Example:

>pmctl link set-vlan-tags dev ens37 rxvlanctaghwacl true txvlanctaghwacl false rxvlanctagfilter true txvlanstaghwacl true

Configure Link Channels

pmctl link set-channel dev <deviceName> rxch <RxChannels> txch <TxChannels> oth <OtherChannels> coch <CombinedChannels>

Example:

>pmctl link set-channel dev ens37 rxch 1024 txch 2045 och 45678 coch 32456
pmctl link set-buffer dev <deviceName> rxbufsz <RxBufferSize> rxmbufsz <RxMiniBufferSize> rxjbufsz <RxJumboBufferSize> txbufsz <TxBufferSize>

Example:

>pmctl link set-buffer dev ens37 rxbufsz 100009 rxmbufsz 1998 rxjbufsz 10999888 txbufsz 83724
pmctl link set-queue dev <deviceName> rxq <ReceiveQueues> txq <TransmitQueues> txqlen <TransmitQueueLength>

Example:

>pmctl link set-queue dev ens37 rxq 4096 txq 4096 txqlen 4294967294
pmctl link set-flow-ctrl dev <deviceName> rxfctrl <RxFlowControl> txfctrl <TxFlowControl> anfctrl <AutoNegotiationFlowControl>

Example:

>pmctl link set-flow-ctrl dev ens37 rxfctrl true txfctrl true anfctrl true
pmctl link set-adpt-coalesce dev <deviceName> uarxc <UseAdaptiveRxCoalesce> uatxc <UseAdaptiveTxCoalesce>

Example:

>pmctl link set-adpt-coalesce dev ens37 uarxc true uatxc true
pmctl link set-rx-coalesce dev <deviceName> rxcs <RxCoalesceSec> rxcsirq <RxCoalesceIrqSec> rxcslow <RxCoalesceLowSec> rxcshigh <RxCoalesceHighSec>

Example:

>pmctl link set-rx-coalesce dev ens37 rxcs 23 rxcsirq 56 rxcslow 5 rxcshigh 76788
pmctl link set-tx-coalesce dev <deviceName> txcs <TxCoalesceSec> txcsirq <TxCoalesceIrqSec> txcslow <TxCoalesceLowSec> txcshigh <TxCoalesceHighSec>

Example:

>pmctl link set-tx-coalesce dev ens37 txcs 23 txcsirq 56 txcslow 5 txcshigh 76788
pmctl link set-rx-coald-frames dev <deviceName> rxcmf <RxMaxCoalescedFrames> rxcmfirq <RxMaxCoalescedIrqFrames> rxcmflow <RxMaxCoalescedLowFrames> rxcmfhigh <RxMaxCoalescedHighFrames>

Example:

>pmctl link set-rx-coald-frames dev ens37 rxmcf 23 rxmcfirq 56 rxmcflow 5 rxmcfhigh 76788
pmctl link set-tx-coald-frames dev <deviceName> txcmf <TxMaxCoalescedFrames> txcmfirq <TxMaxCoalescedIrqFrames> txcmflow <TxMaxCoalescedLowFrames> txcmfhigh <TxMaxCoalescedHighFrames>

Example:

>pmctl link set-tx-coald-frames dev ens37 txmcf 23 txmcfirq 56 txmcflow 5 txmcfhigh 76788
pmctl link set-coalesce-pkt dev <deviceName> cprlow <CoalescePacketRateLow> cprhigh <CoalescePacketRateHigh> cprsis <CoalescePacketRateSampleIntervalSec>

Example:

>pmctl link set-coalesce-pkt dev ens37 cprlow 1000 cprhigh 32456 cprsis 102

You can configure links for Alias, Description, port, duplex, and so on.

pmctl link set-link dev ens37 alias <Alias> desc <Description> mtub <MTUBytes> bits <BitsPerSecond> duplex <Duplex> auton <AutoNegotiation> wol <WakeOnLan> wolpassd <WakeOnLanPassword> port <Port> advertise <Advertise> lrxo <LargeReceiveOffload> ntf <NTupleFilter> ssbcs <StatisticsBlockCoalesceSec>

Example:

>pmctl link set-link dev ens37 alias ifalias desc configdevice mtub 10M bits 5G duplex full auton no wol phy,unicast,broadcast,multicast,arp,magic,secureon wolpassd cb:a9:87:65:43:21  port mii advertise 10baset-half,10baset-full,20000basemld2-full lrxo true ntf true ssbcs 1024

Ethtool status

To fetch the Ethtool Status, use the following command:


\#Get Ethtool all status 

	pmctl status ethtool <LINK>

Example: 

	>pmctl status ethtool ens37

\#Get Ethtool status based on action

	pmctl status ethtool <LINK> <ACTION>

Example:

	>pmctl status ethtool ens37 bus

5.16.4.4 - User, Group, and Host Management

POST Method

Add a Group

To add a group, execute a POST request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"Name":"photon","Gid":"1125"}' http://localhost/api/v1/system/group/add

The following table lists the parameter:

ParameterDescription
GidID of the group that you want to add.
NameName of the group that you want to add.

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"Name":"photon","Gid":"1125"}' http://localhost/api/v1/system/group/add

Response:

{
   "success":true,
   "message":"group added",
   "errors":""
}

Add a User

To add a user, execute a POST request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"Name":"photon1"}' http://localhost/api/v1/system/user/add

The following table lists the parameter:

ParameterDescription
NameName of the user you want to add.

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request POST --data '{"Name":"photon1"}' http://localhost/api/v1/system/user/add

DELETE Method

Remove a Group

To remove a group, execute a DELETE request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request DELETE --data '{"Name":"photon","Gid":"1125"}' http://localhost/api/v1/system/group/remove

The following table lists the parameters:

ParameterDescription
NameName of the group you want to delete.
GidID of the group that you want to delete.

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request DELETE --data '{"Name":"photon22"}' http://localhost/api/v1/system/group/remove

Response:

{
   "success":true,
   "message":"group removed",
   "errors":""
}

Remove a User

To remove a user, execute a DELETE request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request DELETE --data '{"Name":"photon1"}' http://localhost/api/v1/system/user/remove

Response

{
   "success":true,
   "message":"user removed",
   "errors":""
}

PUT Method

Modify Group

To modify the name of a group, execute a PUT request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request PUT --data '{"Name":"photon6","NewName":"photon33"}' http://localhost/api/v1/system/group/modify

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request PUT --data '{"Name":"photon6","NewName":"photon33"}' http://localhost/api/v1/system/group/modify

GET Method

Host Details

To fetch the details of the host, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/hostname/describe

Example:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/hostname/describe | jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 585 100 585 0 0 8374 0 --:--:-- --:--:-- --:--:-- 8478

Login Status

You can use the pmctl tool to get login details of users. The following section lists the commands you can use to get the user details.

List Users

To list all the logged in users, use the following command in the pmctl tool:

>pmctl status login user

List Sessions

To list all the logged in sessions, use the following command in the pmctl tool:

>pmctl status login session

Get User based on UID

To get the status of users based on user ID, use pmctl command in the following format:

pmctl status login user <UID>

Example:

>pmctl status login user 2

Get Session based on ID

To get the status of logged in sessions based on the users ID, use the pmctl command in the following format:

pmctl status login session <ID>

Example:

>pmctl status login session 1000

Group Details Using pmctl tool

You can get the group details using commands in pmctl tools. The following section lists the commands you can use in the pmctl tool to get various group details.

Get all Group Details

To fetch all the group details, use the following command in the the pmctl tool.

>pmctl status group
             Gid: 0
            Name: root

             Gid: 1
            Name: daemon

             Gid: 2
            Name: bin

             Gid: 3
            Name: sys

             Gid: 4
            Name: adm
		    .
            .
            .
             Gid: 1001
            Name: photon-mgmt

Get specific Group Details

To fetch specific group details, use the following commands in the pmctl tool:

pmctl status group <GroupName>

or

pmctl status group <GroupName>

Example:

>pmctl status group photon-mgmt
             Gid: 1001
            Name: photon-mgmt

Add a new Group

To add a new group, use the following command in the pmctl tool:

pmctl group add <GroupName> <Gid>

or

pmctl group add <GroupName>

Remove a Group

To remove a group, us the followong command in the omctl tool:

pmctl group remove <GroupName> <Gid>

or

pmctl group remove <GroupName>

Group Details Using cURL command

The following section list the cURL commands that you can use to fetch the groups details.

Get all Group information

To fetch the group details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/group/view

Get particuller Group information.

To fetch a specific group details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/group/view/<GroupName>

User Details Using pmctl Tool

You can use the pmctl tool to get the user details. The following section lists the commands to get the user details.

Get all User Details

To get all the user details, use the following command in the pmctl tool:

>pmctl status user
          User Name: root
                Uid: 0
                Gid: 0
              GECOS: root
     Home Directory: /root

          User Name: daemon
                Uid: 1
                Gid: 1
              GECOS: daemon
     Home Directory: /usr/sbin

          User Name: bin
                Uid: 2
                Gid: 2
              GECOS: bin
     Home Directory: /bin

          User Name: sys
                Uid: 3
                Gid: 3
              GECOS: sys
     Home Directory: /dev

          User Name: photon-mgmt
                Uid: 1001
                Gid: 1001
     Home Directory: /home/photon-mgmt

Add a New User

To add a new user, use the following command in the pmctl tool:

pmctl user add <UserName> home-dir <HomeDir> groups <groupsList> uid <Uid> gid <Gid> shell <Shell> password <xxxxxxx>

or

pmctl user a <UserName> -d <HomeDir> -grp <groupsList> -u <Uid> -g <Gid> -s <Shell> -p <xxxxxxx>

Remove a User

To remove a user, use the following command in the pmctl tool:

pmctl user remove <UserName>

or

pmctl user r <UserName>

GET User Details

To fetch user details, execute a GET request in the following format:

curl --unix-socket /run/photon-mgmt/mgmt.sock --request GET http://localhost/api/v1/system/user/view

5.16.4.5 - Package Management

You can use the pmctl commands to manage the available packages and perform various actions on the packages. The following section lists the pmctl commands for various services related to package management.

List all packages

To list all the packages, use the following command in pmctl:

pmctl pkg list

Example:

>pmctl pkg list

List specific packages

To list a specific package, use the following command in pmctl:

pmctl pkg list <pkg>

Example:

>pmctl pkg list lsof

Package Details

To get the details of a specific package, use the following command in pmctl:

pmctl pkg info <pkg>

Example:

pmctl pkg info lsof

Download metadata

To download the package metadata, use the following command in pmctl:

pmctl pkg makecache

Example:

>pmctl pkg makecache

Clean cache

To clean the package cache, use the following command in pmctl:

pmctl pkg clean

Example:

>pmctl pkg clean

List repositories

To list the repositories, use the following command in pmctl:

pmctl pkg repolist

Example:

pmctl pkg repolist

Search packages

To search a specific package, use the following command in pmctl:

pmctl pkg search <pattern>

Example:

pmctl pkg search lsof

Get update info

To get the update details of the packages, use the following commands in pmctl:

> pmctl pkg updateinfo
> pmctl pkg updateinfo --list
> pmctl pkg updateinfo --info

Install a package

To install a specific package, use the following command in pmctl:

pmctl pkg install <pkg>

Example:

>pmctl install lsof

Update a package

To update a specific package, use the following command in pmctl:

pmctl pkg update <pkg>

Example:

pmctl pkg update lsof

Remove a package

To remove a specific package, use the following command in pmctl:

pmctl pkg remove <pkg>

Example:

pmctl pkg remove lsof

Update all

To update all the packages, use th following command in pmctl:

pmctl pkg update

Example:

pmctl pkg update

Common options

In pmctl, run commands in the following format to use other common options:

> pmctl pkg [--allowerasing][--best][--cacheonly][--config=<file>][--disablerepo=<pattern>[,..]]
	[--disableexcludes][--downloaddir=<dir>][--downloadonly][--enablerepo=<pattern>[,..]]
	[--exclude=<pkg>][--installroot=<dir>][--noautoremove][--nogpgcheck][--noplugins]
	[--rebootrequired][--refresh][--releaserver=<release>][--repoid=<repo>]
	[--repofrompath=<repo>,<dir>][--security][--secseverity=<sev>][--setopt=<key=value>[,..]]
	[--skipconflicts][--skipdigest][--skipobsletes][--skipsignature]
pmctl pkg --repoid=photon-debuginfo list lsof*

5.16.4.6 - Firewall nftables Management

Use pmctl command to manage the firewall nftables. The following section lists the command that you can use to manage the nftables.

Add nftable

To add an nftable, use the following command in pmctl:

pmctl network add-nft-table name <TABLE> family <FAMILY>

Example:

>pmctl network add-nft-table name test99 family inet

Delete nftable

To delete an nftable, use the following command in pmctl:

pmctl network delete-nft-table name <TABLE> family <FAMILY>

Example:

>pmctl network delete-nft-table name test99 family inet

Show nftable

To show an nftable, use the following command in pmctl:

pmctl network show-nft-table name <TABLE> family <FAMILY>

Example:

>pmctl network show-nft-table name test99 family inet

Show all nftables

To show all the nftables, use the following command in pmctl:

>pmctl network show-nft-table

Add nftable chain

To add an nftable chain, use the following command in pmctl:

pmctl network add-nft-chain name <CHAIN> table <TABLE> family <FAMILY> hook <HOOK> priority <PRIORITY> type <TYPE> policy <POLICY>

Example:

>pmctl network add-nft-chain name chain1 table test99 family inet hook input priority 300 type filter policy drop

Delete nft chain

To delete an nftable chain, use the following command in pmctl:

pmctl network delete-nft-chain name <CHAIN> table <TABLE> family <FAMILY>

Example:

>pmctl network delete-nft-chain name chain1 table test99 family inet

Show nft chain

To show an nftable chain, use the following command in pmctl:

pmctl network show-nft-chain name <CHAIN> table <TABLE> family <FAMILY>

Example:

>pmctl network show-nft-chain name chain1 table test99 family inet

Show all nft chain

To show all nftable chains, use the following command in pmctl:

>pmctl network show-nft-chain

Save all nftables

To save all nftables, use the following command in pmctl:

>pmctl network nft-save

Run nft commands

To run the nftables command, use the following command in pmctl:

pmctl network nft-run <COMMAND>

Examples:

>pmctl network nft-run nft add table inet test99


>pmctl network nft-run nft add chain inet test99 my_chain '{ type filter hook input priority 0; }'


>pmctl network nft-run nft add rule inet test99 my_chain tcp dport {telnet, http, https} accept


>pmctl network nft-run nft delete rule inet test99 my_chain handle 3


>pmctl network nft-run nft delete chain inet test99 my_chain


>pmctl network nft-run nft delete table inet test99

5.16.4.7 - Process Details and Configuration Management

Net device property status

To get the status of the network device property, use the following command in pmctl:

pmctl status proc net path <PATH> property <PROPERTY>

Example:

pmctl status proc net path ipv6 property calipso_cache_bucket_size

Response:

                 Path: ipv6
             Property: calipso_cache_bucket_size
                Value: 10

Net device property configuration

To get the network device property configuration details, use the following command in pmctl:

pmctl proc net path <PATH> property <PROPERTY> value <VALUE>

Example:

>pmctl proc net path ipv6 property calipso_cache_bucket_size value 12

To get the status of the network device link, use the following command in pmctl:

pmctl status proc net path <PATH> dev <LINK> property <PROPERTY>

Example:

>pmctl status proc net path ipv6 dev ens37 property mtu

Response:

                 Path: ipv6
                 Link: ens37
             Property: mtu
                Value: 1300

To get the configuration details of the network device link, use the following command in pmctl:

pmctl proc net path <PATH> dev <LINK> property <PROPERTY> value <VALUE>

Example:

>pmctl proc net path ipv6 dev ens37 property mtu value 1500

VM property status

To get the property status of the virtual machine, use the following command in pmctl:

pmctl status proc vm <PROPERTY>

Example:

>pmctl status proc vm page-cluster

Response:

             Property: page-cluster
                Value: 3

VM property configuration

To get the property configuration details, use the following command in pmctl:

pmctl proc vm <PROPERTY> <VALUE>

Example:

pmctl proc vm page-cluster 5

System property status

To get system property details, use the following command in pmctl:

pmctl status proc system <PROPERTY>

Example:

>pmctl status proc system cpuinfo

ARP status

To get the ARP status details, use the following command in pmctl:

pmctl status proc arp

Example:

>pmctl status proc arp

Response:

         IPAddress: 172.16.61.254
            HWType: 0x1
             Flags: 0x2
         HWAddress: 00:50:56:f3:5d:48
              Mask: *
            Device: ens37

         IPAddress: 172.16.61.254
            HWType: 0x1
             Flags: 0x2
         HWAddress: 00:50:56:f3:5d:48
              Mask: *
            Device: ens33

         IPAddress: 172.16.61.2
            HWType: 0x1
             Flags: 0x2
         HWAddress: 00:50:56:f4:e7:22
              Mask: *
            Device: ens33

         IPAddress: 172.16.61.2
            HWType: 0x1
             Flags: 0x2
         HWAddress: 00:50:56:f4:e7:22
              Mask: *
            Device: ens37

Netstat Details

To get the netstat details, use the following command in pmctl:

pmctl status proc netstat <PROTOCOL>

Example:

>pmctl status proc netstat tcp

Process status

To get the process status details, use the following command in pmctl:

pmctl status proc process <PID> <PROPERTY>

Example:

>pmctl status proc process 88157 pid-memory-percent

Protopidstat status

To get the protopidstat status details, use the following command in pmctl:

pmctl status proc protopidstat <PID> <PROTOCOL>

Example:

>pmctl status proc protopidstat 89502 tcp

5.16.5 - Writing a Plugin

photon-mgmtd is designed with a robust plugin-based architecture in mind. You can easily add and remove modules to photon-mgmtd. The plugins are separate modules with well-defined interfaces that make implementing application features easier. You can create custom versions of an application with minimal source code modifications.

You can perform the following steps to write a plugin:

  1. Choose a namespace under plugins directory (systemd, system, proc) where you want to put your module.
  2. Write the sub router. For example, plugins/systemd/
  3. Write your module: module.go and module_router.go
  4. Write RegisterRouterModule
  5. Register RegisterRouterModule with the parent router. For example, for login registered with RegisterRouterSystem under system namespace, write login.RegisterRouterLogin.

You can use the pmctl tool to view and configure system, network, and service status. The following example illustrates how to view the status:

Service status:

❯ pmctl service status nginx.service
                  Name: nginx.service 
           Description: The nginx HTTP and reverse proxy server 
               MainPid: 45732 
             LoadState: loaded 
           ActiveState: active 
              SubState: running 
         UnitFileState: disabled 
  StateChangeTimeStamp: Sun Oct 31 12:02:02 IST 2021 
  ActiveEnterTimestamp: Sun Oct 31 12:02:02 IST 2021 
 InactiveExitTimestamp: Sun Oct 31 12:02:02 IST 2021 
   ActiveExitTimestamp: 0 
 InactiveExitTimestamp: Sun Oct 31 12:02:02 IST 2021 
                Active: active (running) since Sun Oct 31 12:02:02 IST 2021

System status:

❯ pmctl status  system
              System Name: Zeus
                   Kernel: Linux (5.14.0-0.rc7.54.fc36.x86_64) #1 SMP Mon Aug 23 13:55:32 UTC 2021
                  Chassis: vm
           Hardware Model: VMware Virtual Platform
          Hardware Vendor: VMware, Inc.
             Product UUID: 979e4d56b63718b18534e112e64cb18
         Operating System: VMware Photon OS/Linux
Operating System Home URL: https://vmware.github.io/photon/
          Systemd Version: v247.10-3.ph4
             Architecture: x86-64
           Virtualization: vmware
            Network State: routable (carrier)
     Network Online State: online
                      DNS: 172.16.130.2
                  Address: 172.16.130.132/24 on link ens33
                           172.16.130.131/24 on link ens33
                           fe80::3279:c56d:55f9:aed7/64 on link ens33
                           172.16.130.138/24 on link ens37
                  Gateway: 172.16.130.2 on link ens37
                           172.16.130.2 on link ens33
                   Uptime: Running Since (2 days, 3 hours, 8 minutes) Booted (Wed Dec 22 15:57:24 IST 2021) Users (9) Proc (284)
                   Memory: Total (13564788736) Used (13564788736) Free (589791232) Available (9723891712)

Network status:

❯ pmctl status network -i ens33
             Name: ens33
Alternative Names: enp2s1
            Index: 2
        Link File: /usr/lib/systemd/network/99-default.link
     Network File: /etc/systemd/network/10-ens33.network
             Type: ether
            State: routable (configured)
           Driver: e1000
           Vendor: Intel Corporation
            Model: 82545EM Gigabit Ethernet Controller (Copper) (PRO/1000 MT Single Port Adapter)
             Path: pci-0000:02:01.0
    Carrier State: carrier
     Online State: online
IPv4Address State: routable
IPv6Address State: degraded
       HW Address: 00:0c:29:5f:d1:39
              MTU: 1500
        OperState: up
            Flags: up|broadcast|multicast
        Addresses: 172.16.130.132/24 172.16.130.131/24 fe80::3279:c56d:55f9:aed7/64
          Gateway: 172.16.130.2
              DNS: 172.16.130.2

5.17 - Photon OS Installer Overview

The Photon OS Installer is an initiative that aims to separate out installer source code from the Photon project and use it as a python library. You can use this Photon OS Installer project to create a photon-installer binary that can install Photon OS when invoked with the appropriate arguments.

Features

You can use the Photon OS Installer to perform the following tasks:

  • Generate Photon Installer executable
  • Create Photon Images (ISO, GCE, AMI, AZURE, OVA, and so on)
  • Make Photon Installer Source code installable through the pip interface and use it as a python library.

Dependencies

The Photon OS installer has the following dependencies:

Build Dependecies:

  • python3
  • python3-pyinstaller
  • python3-setuptools
  • python3-devel
  • python3-requests
  • python3-cracklib
  • python3-curses

Run time dependecies:

  • dosfstools
  • efibootmgr
  • glibc
  • gptfdisk
  • grub2
  • kpartx
  • lvm2
  • zlib
  • cdrkit
  • findutils

Note: If the architecture is x86, then we need to add grub2-pc also in runtime dependency.

Building from source

To build the Photon OS Installer executable on Photon OS, run the following commands:

➜  ~ tdnf install -y python3 python3-setuptools python3-pyinstaller
➜  ~ git clone https://github.com/vmware/photon-os-installer.git
➜  ~ cd photon-os-installer
➜  ~ pyinstaller --onefile photon-installer.spec

To build the Photon Installer executable on other distros, run the following commands:

➜  ~ pip3 install setuptools pyinstaller
➜  ~ git clone https://github.com/vmware/photon-os-installer.git
➜  ~ cd photon-os-installer
➜  ~ pyinstaller --onefile photon-installer.spec

You can find the generated executable in the dist directory created.

Presently, you can build the following images with the Photon OS Installer:

x86_64arm64
isoiso
ovaova
ova_uefiova_uefi
minimal-iso
rt-iso
ami
gce
azure
rpi3

To build Photon Cloud images using Photon OS Installer, run the following commands:

➜  ~ pip3 install git+https://github.com/vmware/photon-os-installer.git
➜  ~ git clone https://github.com/vmware/photon.git
➜  ~ cd photon
➜  ~ make image IMG_NAME=ami

To use Photon OS Installer as a python library, run the following commands:

import photon_installer
from photon_installer.installer import Installer
import json
with open('path_to_file/config.json') as f:
    install_config = json.load(f)
installer = Installer(working_directory='/root/photon/stage/ova', repo_paths='/root/photon/stage/RPMS', log_path='/root/photon/stage/LOGS')
installer.configure(install_config)
installer.execute()

You can refer to the sample installation configuration files on the following page: Sample Kickstart Files

Developers or contributors can refer to the Photon OS Installer project here: Photo OS Installer

6 - User Guide

The Photon OS User Guide provides information about how to use Photon OS as a developer.

The User Guide covers the basics of setting up a Network PXE Boot Server, working with Kickstart and Kubernetes, and mounting remote file systems.

Product version: 5.0

This documentation applies to all 5.0.x releases.

Intended Audiences

This information is intended for Photon OS developers who use Photon OS.

6.1 - Setting Up Network PXE Boot

Photon OS supports the Preboot Execution Environment, or PXE, over a network connection. This document describes how to set up a PXE boot server to install Photon OS.

Server Setup

To set up a PXE server, you will need to have the following:

  • A DHCP server to allow hosts to get an IP address.
  • A TFTP server, which is a file transfer protocol similar to FTP with no authentication.
  • Optionally, an HTTP server. The HTTP server will serve the RPMs yum repo, or you can use the official VMware Photon Packages repo. Also, this HTTP server can be used if you want to provide a kickstart config for unattended installation.

The instructions to set up the servers assume you have an Ubuntu 14.04 machine with a static IP address of 172.16.78.134.

DHCP Setup

  • Install the DHCP server:

    sudo apt-get install isc-dhcp-server  
    
  • Edit the Ethernet interface in /etc/default/isc-dhcp-server to INTERFACES="eth0"

  • Edit the DHCP configuration in /etc/dhcp/dhcpd.conf to allow machines to boot and get an IP address via DHCP in the range 172.16.78.230 - 172.16.78.250, for example:

    subnet 172.16.78.0 netmask 255.255.255.0 {
      range 172.16.78.230 172.16.78.250;
      option subnet-mask 255.255.255.0;
      option routers 172.16.78.134;
      option broadcast-address 172.16.78.255;
      filename "pxelinux.0";
      next-server 172.16.78.134;
    }
    
  • Restart the DHCP server:

    sudo service isc-dhcp-server restart
    

TFTP Setup

  • Install the TFTP server:

    sudo apt-get install tftpd-hpa
    
  • Enable the boot service and restart the service:

    sudo update-inetd --enable BOOT
    sudo service tftpd-hpa restart
    

Optional: HTTP server setup

This step is only needed if you are planning to serve the ks (kickstart) config file through this server; refer to Kickstart support for details.

  • Serving your local yum repo.

You can install apache http web server:

sudo apt-get install apache2

Mount the Photon iso to get the RPMS repo and sample ks config file:

mkdir /mnt/photon-iso
sudo mount <photon_iso> /mnt/photon-iso/

Copy the RPMS repo:

cp -r /mnt/photon-iso/RPMS /var/www/html/

To support ks, you can copy the sample config file from the iso and edit it; refer to Kickstart support for details.

cp /mnt/photon-iso/isolinux/sample_ks.cfg /var/www/html/my_ks.cfg

PXE boot files setup

  • Mount photon.iso to get Linux and initrd images:
mkdir /mnt/photon-iso
sudo mount <photon_iso> /mnt/photon-iso/
  • Setting the PXE boot files:
wget https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz
tar -xvf syslinux-6.03.tar.gz
pushd /var/lib/tftpboot
cp -r /mnt/photon-iso/isolinux/* .
cp ~/syslinux-6.03/bios/com32/elflink/ldlinux/ldlinux.c32 .
cp ~/syslinux-6.03/bios/com32/lib/libcom32.c32 .
cp ~/syslinux-6.03/bios/com32/libutil/libutil.c32 .
cp ~/syslinux-6.03/bios/com32/menu/vesamenu.c32 .
cp ~/syslinux-6.03/bios/core/pxelinux.0 .
mkdir pxelinux.cfg
mv isolinux.cfg pxelinux.cfg/default
  • Update repo param to point to http yum repo; you may pass official photon packages repo.
sed -i "s/append/append repo=http:\/\/172.16.78.134\/RPMS/g" menu.cfg
popd

6.2 - Kickstart Support in Photon OS

Photon OS works with kickstart for unattended and automated installations. The kickstart configuration file can be served through an HTTP server. You can also provide the kickstart configuration file through a secondary device or a CD-ROM attached to the host.

Kickstart also allows you to configure the installer and deploy virtual machines.

Ways to Provide Kickstart File

You can provide the path to the kickstart file in the following way:

Remote kickstart

To provide a remote path for the kickstart file, use the following format:

ks=http://<kickstart-link>

Kickstart from CD-ROM attached with ISO

To provide a path for the kickstart file in a CD-ROM with ISO, use the following format:

ks=cdrom:/isolinux/sample_ks.cfg

Secondary Device Kickstart

To provide a secondary device path for the kickstart file, use the following format:

ks=<device-path>:<path-referential-to-device>
Example:
ks=/dev/sr1:/isolinux/sample_ks.cfg

Kickstart Capabilities

On Photon OS, you can configure many settings such as the hostname, password, disk to install, post installation script, and so on.

To find out more about the Kickstart capabilities and the permitted JSON parameters in Kickstart, see the following page: Kickstart Features

Sample Configuration File

Example kickstart configuration file:

{
    "hostname": "photon-machine",
    "password":
        {
            "crypted": false,
            "text": "changeme"
        },
    "disk": "/dev/sda",
    "partitions":[
		{
			"mountpoint":"/",
			"size":0,
			"filesystem":"ext4"
		},
		{
			"mountpoint":"/boot",
			"size":128,
			"filesystem":"ext4"
		},
		{
			"mountpoint":"/root",
			"size":128,
			"filesystem":"ext4"
		},
		{
			"size":128,
			"filesystem":"swap"
		}
		],
	"bootmode": "bios",
    "packagelist_file": "packages_minimal.json",
    "additional_packages": [
		"vim"
		],
    "postinstall": [
		"#!/bin/sh",
        "echo \"Hello World\" > /etc/postinstall"
        ],
    "public_key": "<ssh-key-here>",
    "linux_flavor": "linux",
    "network": {
        "type": "dhcp"
    }    
}

To see more such sample Kickstart configuration files, see the following page: Kickstart Sample Configuration Files

Installing Root Partition as LVM

In the kickstart file modify the partitions field to mount root partition as LVM.

For example:

"disk":"/dev/sda"
"partitions":[
   {
      "mountpoint":"/",
      "size":0,
      "filesystem":"ext4",
      "lvm":{
         "vg_name":"vg1",
         "lv_name":"rootfs"
      }
   },
   {
      "mountpoint":"/boot",
      "size":128,
      "filesystem":"ext4"
   },
   {
      "mountpoint":"/root",
      "size":128,
      "filesystem":"ext4",
      "lvm":{
         "vg_name":"vg1",
         "lv_name":"root"
      }
   },
   {
      "size":128,
      "filesystem":"swap",
      "lvm":{
         "vg_name":"vg2",
         "lv_name":"swap"
      }
   }
]

Note:

  • vg_name : Volume Group Name
  • lv_name : Logical Volume Name

In above example rootfs, root are logical volumes in the volume group vg1 and swap is logical volume in volume group vg2, physical volumes are part of disk /dev/sda.

Multiple disks are also supported. For example:

"disk": "/dev/sda"
"partitions":[
   {
      "mountpoint":"/",
      "size":0,
      "filesystem":"ext4",
      "lvm":{
         "vg_name":"vg1",
         "lv_name":"rootfs"
      }
   },
   {
      "mountpoint":"/boot",
      "size":128,
      "filesystem":"ext4"
   },
   {
      "disk":"/dev/sdb",
      "mountpoint":"/root",
      "size":128,
      "filesystem":"ext4",
      "lvm":{
         "vg_name":"vg1",
         "lv_name":"root"
      }
   },
   {
      "size":128,
      "filesystem":"swap",
      "lvm":{
         "vg_name":"vg1",
         "lv_name":"swap"
      }
   }
]

If disk name is not specified, the physical volumes will be part of the default disk: dev/sda.

In above example rootfs,root and swap are logical volumes in volume group vg1, physical volumes are in the disk /dev/sdb and partitions are present in /dev/sda.

Note: Mounting /boot partition as LVM is not supported.

Unattended Installation Through Kickstart

For an unattended installation, you pass the ks=<config_file> parameter to the kernel command. To pass the config file, there are three options:

  1. Provide it in the ISO through a CD-ROM attached to the host.
  2. Provide it in the ISO through a specified secondary device.
  3. Serving it from an HTTP server.

The syntax to pass the configuration file to the kernel through the CD-ROM takes the following form:

ks=cdrom:/<config_file_path>

For example:

ks=cdrom:/isolinux/ks.cfg

The syntax to pass the configuration file to the kernel through a secondary device takes the following form:

ks=<device-path>:<path-referential-to-device>

For example:

ks=/dev/sr1:/isolinux/sample_ks.cfg

The syntax to serve the configuration file to the kernel from a HTTPS server takes the following form:

ks=https://<server>/<config_file_path>

To use HTTP path or self-signed HTTPS path, you have to enable insecure_installation by using insecure_installation=1 along with defining the ks path. The kernel command line argument, insecure_installation, acts as a flag that user can set to 1 to allow some operations that are not normally allowed due to security concerns. This is disabled by default and it is up to the user to the ensure security when this options is enabled.

HTTP example:

ks=http://<server>/<config_file_path> insecure_installation=1

HTTPS (self-signed) example:

ks=https://<server>/<config_file_path> insecure_installation=1

Building an ISO with a Kickstart Config File

Here’s an example of how to add a kickstart config file to the Photon OS ISO by mounting the ISO on an Ubuntu machine and then rebuilding the ISO. The following example assumes you can adapt the sample kickstart configuration file that comes with the Photon OS ISO to your needs. You can obtain the Photon OS ISO for free from VMware at the following URL:

https://packages.vmware.com/photon

Once you have the ISO, mount it.

mkdir /tmp/photon-iso
sudo mount photon.iso /tmp/photon-iso

Then copy the content of the ISO to a writable directory and push it into the directory stack:

mkdir /tmp/photon-ks-iso
cp -r /tmp/photon-iso/* /tmp/photon-ks-iso/
pushd /tmp/photon-ks-iso/

Next, copy the sample kickstart configuration file that comes with the Photon OS ISO and modify it to suit your needs. In the ISO, the sample kickstart config file appears in the isolinux directory and is named sample_ks.cfg. The name of the directory and the name of the file might be in all uppercase letters.

cp isolinux/sample_ks.cfg isolinux/my_ks.cfg
nano isolinux/my_ks.cfg

With a copy of the sample kickstart config file open in nano, make the changes that you want.

Now add a new item to the installation menu by modifying isolinux/menu.cfg and boot/grub2/grub.cfg:

cat >> isolinux/menu.cfg << EOF
label my_unattended
	menu label ^My Unattended Install
	menu default
	kernel vmlinuz
	append initrd=initrd.img root=/dev/ram0 ks=<ks_path>/my_ks.cfg loglevel=3 photon.media=cdrom
EOF


cat >> boot/grub2/grub.cfg << EOF
set default=0
set timeout=3
loadfont ascii
set gfxmode="1024x768"
gfxpayload=keep
set theme=/boot/grub2/themes/photon/theme.txt
terminal_output gfxterm
probe -s photondisk -u ($root)

menuentry "Install" {
    linux /isolinux/vmlinuz root=/dev/ram0 ks=<ks_path>/my_ks.cfg loglevel=3 photon.media=UUID=$photondisk
    initrd /isolinux/initrd.img
}
EOF 

Following is an example of the ks path:

`ks_path=cdrom:/isolinux`

Note: You can specify any mount media through which you want to boot Photon OS. To specify the mount media, specify the path of the mount media device in the photon.media field. You can specify the path as shown in the following syntax:

photon.media=/dev/<path of the Photon OS ISO>

Finally, rebuild the ISO so that it includes your kickstart config file:

mkisofs -R -l -L -D -b isolinux/isolinux.bin -c isolinux/boot.cat \
                -no-emul-boot -boot-load-size 4 -boot-info-table \
                -eltorito-alt-boot --eltorito-boot boot/grub2/efiboot.img -no-emul-boot \
                -V "PHOTON_$(date +%Y%m%d)" . > <new_iso_path>.iso


popd

6.3 - Packer Examples for Photon OS

Packer is an open source tool that enables you to create identical machine images for multiple platforms.

VMware maintains two GitHub projects with that include examples for creating Photon OS machine images using Packer.

All examples are authored in the HashiCorp Configuration Language (“HCL2”).

vSphere Virtual Machine Images

GitHub Project: vmware-samples/packer-examples-for-vsphere

This project provides examples to automate the creation of virtual machine images and their guest operating systems on VMware vSphere using Packer and the Packer Plugin for VMware vSphere (vsphere-iso). This project includes Photon OS as one of the guest operating systems.

Vagrant Boxes

GitHub Project: vmware/photon-packer-templates

This project provides examples to automate the creation of Photon OS machine images as Vagrant boxes using Packer and the Packer Plugins for VMware (vmware-iso) and Virtualbox (virtualbox).

The Vagrant boxes included in the project can be run on the following providers:

  • VMware Fusion (vmware_desktop)
  • VMware Workstation Pro (vmware_desktop)
  • VirtualBox (virtualbox)

This project is also used to generate the offical vmware/photon Vagrant boxes.

6.4 - Kubernetes on Photon OS

You can use Kubernetes with Photon OS. The instructions in this section present a manual configuration that gets one worker node running to help you understand the underlying packages, services, ports, and so forth.

The Kubernetes package provides several services: kube-apiserver, kube-scheduler, kube-controller-manager, kubelet, kube-proxy. These services are managed by systemd. Their configuration resides in a central location: /etc/kubernetes.

6.4.1 - Prerequisites

You need two or more machines with version 3.0 “GA” or later of Photon OS installed. It is recommended to use the latest GA version.

6.4.2 - Running Kubernetes on Photon OS

The procedure describes how to break the services up between the hosts.

The first host, photon-master, is the Kubernetes master. This host runs the kube-apiserver, kube-controller-manager, and kube-scheduler. In addition, the master also runs etcd. Although etcd is not needed on the master if etcd runs on a different host, this guide assumes that etcd and the Kubernetes master run on the same host. The remaining host, photon-node, is the node and runs kubelet, proxy, and docker.

6.4.2.1 - System Information

Hosts:

photon-master = 192.168.121.9
photon-node = 192.168.121.65

6.4.2.2 - Prepare the Hosts

The following packages have to be installed. If the tdnf command returns “Nothing to do,” the package is already installed.

  • Install Kubernetes on all hosts (both photon-master and photon-node).

    tdnf install kubernetes
    
  • Install iptables on photon-master and photon-node:

    tdnf install iptables
    
  • Open the tcp port 8080 (api service) on the photon-master in the firewall

    iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
    
  • Open the tcp port 10250 (api service) on the photon-node in the firewall

    iptables -A INPUT -p tcp --dport 10250 -j ACCEPT
    
  • Install Docker on photon-node:

    tdnf install docker
    
  • Add master and node to /etc/hosts on all machines (not needed if the hostnames are already in DNS). Make sure that communication works between photon-master and photon-node by using a utility such as ping.

    echo "192.168.121.9	photon-master
    192.168.121.65	photon-node" >> /etc/hosts
    
  • Edit /etc/kubernetes/config, which will be the same on all the hosts (master and node), so that it contains the following lines:

    # Comma separated list of nodes in the etcd cluster
    KUBE_MASTER="--master=http://photon-master:8080"
    
    # logging to stderr routes it to the systemd journal
    KUBE_LOGTOSTDERR="--logtostderr=true"
    
    # journal message level, 0 is debug
    KUBE_LOG_LEVEL="--v=0"
    
    # Should this cluster be allowed to run privileged docker containers
    KUBE_ALLOW_PRIV="--allow_privileged=false"
    

6.4.2.3 - Configure Kubernetes Services on the Master

Perform the following steps to configure Kubernetes services on the master:

  1. Edit /etc/kubernetes/apiserver to appear as such. The service_cluster_ip_range IP addresses must be an unused block of addresses, not used anywhere else. They do not need to be routed or assigned to anything.

    # The address on the local server to listen to.
    KUBE_API_ADDRESS="--address=0.0.0.0"
    
    # Comma separated list of nodes in the etcd cluster
    KUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:4001"
    
    # Address range to use for services
    KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
    
    # Add your own
    KUBE_API_ARGS=""
    
  2. Start the appropriate services on master:

    for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do
    	systemctl restart $SERVICES
    	systemctl enable $SERVICES
    	systemctl status $SERVICES
    done
    
  3. To add the other node, create the following node.json file on the Kubernetes master node:

    {
        "apiVersion": "v1",
        "kind": "Node",
        "metadata": {
            "name": "photon-node",
            "labels":{ "name": "photon-node-label"}
        },
        "spec": {
            "externalID": "photon-node"
        }
    }
    
  4. Create a node object internally in your Kubernetes cluster by running the following command:

    $ kubectl create -f ./node.json
    
    $ kubectl get nodes
    NAME                LABELS              STATUS
    photon-node         name=photon-node-label     Unknown
    

Note: The above example only creates a representation for the node photon-node internally. It does not provision the actual photon-node. Also, it is assumed that photon-node (as specified in name) can be resolved and is reachable from the Kubernetes master node.

6.4.2.4 - Configure the Kubernetes services on Node

Perform the following steps to configure the kubelet on the node:

  1. Edit /etc/kubernetes/kubelet to appear like this:

    ###
    # Kubernetes kubelet (node) config
    
    # The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
    KUBELET_ADDRESS="--address=0.0.0.0"
    
    # You may leave this blank to use the actual hostname
    KUBELET_HOSTNAME="--hostname_override=photon-node"
    
    # location of the api-server
    KUBELET_API_SERVER="--kubeconfig=/etc/kubernetes/kubeconfig"
    
    # Add your own
    #KUBELET_ARGS=""
    
  2. Make sure that the api-server end-point located in /etc/kubernetes/kubeconfig, targets the api-server in the master node and does not fall into the loopback interface:

    apiVersion: v1
    clusters:
    - cluster:
        server: <ip_master_node>:8080
    
  3. Start the appropriate services on the node (photon-node):

    for SERVICES in kube-proxy kubelet docker; do 
        systemctl restart $SERVICES
        systemctl enable $SERVICES
        systemctl status $SERVICES 
    done
    
  4. Check to make sure that the cluster can now see the photon-node on photon-master and that its status changes to Ready.

    kubectl get nodes
    NAME                LABELS              STATUS
    photon-node          name=photon-node-label     Ready
    

    If the node status is NotReady, verify that the firewall rules are permissive for Kubernetes.

    • Deletion of nodes: To delete photon-node from your Kubernetes cluster, one should run the following on photon-master (please do not do it, it is just for information):
    kubectl delete -f ./node.json
    

Result

You should have a functional cluster. You can now launch a test pod. For an introduction to working with Kubernetes, see Kubernetes documentation.

6.4.3 - Kubernetes-Kubeadm Cluster on Photon OS

This section of the document describes how to set up Kubernetes-Kubeadm Cluster on Photon OS. You need to configure the following two nodes:

  • Master Photon OS VM
  • Worker Photon OS VM

The following sections in the document describe how to configure the master and worker nodes, and then run a sample application.

6.4.3.1 - Configuring a Master Node

This section describes how to configure a master node with the following details:

Node Name: kube-master
Node IP Address: 10.197.103.246

Host Names

Change the host name on the VM using the following command:

hostnamectl set-hostname kube-master

To ensure connectivity with the future working node, kube-worker, modify the file /etc/hosts as follows:

cat /etc/hosts
# Begin /etc/hosts (network card version)
10.197.103.246 kube-master
10.197.103.232 kube-worker
  
::1         ipv6-localhost ipv6-loopback
127.0.0.1   localhost.localdomain
127.0.0.1   localhost
127.0.0.1   photon-machine
# End /etc/hosts (network card version)

System Tuning

IP Tables

Run the following iptables commands to open the required ports for Kubernetes to operate.

Save the updated set of rules so that they become available the next time you reboot the VM.

Firewall Settings
# ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
  
# etcd
iptables -A INPUT -p tcp -m tcp --dport 2379:2380 -j ACCEPT
  
# kubernetes
iptables -A INPUT -p tcp -m tcp --dport 6443 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 10250:10252 -j ACCEPT
  
# calico
iptables -A INPUT -p tcp -m tcp --dport 179 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 4789 -j ACCEPT
  
# save rules
iptables-save > /etc/systemd/scripts/ip4save

Kernel Configuration

You need to enable IPv4 IP forwarding and iptables filtering on the bridge devices. Create the file /etc/sysctl.d/kubernetes.conf as follows:

# Load br_netfilter module to facilitate traffic between pods
modprobe br_netfilter
 
 
cat /etc/sysctl.d/kubernetes.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net/bridge/bridge-nf-call-arptables = 1

Apply the new sysctl setttings as follows:

sysctl --system
...
 
* Applying /etc/sysctl.d/kubernetes.conf ...
.........
/proc/sys/net/ipv4/ip_forward = 1
/proc/sys/net/bridge/bridge-nf-call-ip6tables = 1
/proc/sys/net/bridge/bridge-nf-call-iptables = 1
/proc/sys/net/bridge/bridge-nf-call-arptables = 1

Containerd Runtime Configuration

Use the following command to install crictl and use containerd as runtime endpoint:

#install crictl
tdnf install -y cri-tools
 
#modify crictl.yaml
cat /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: false
pull-image-on-create: false
disable-pull-on-run: false

Use systemd as cgroup for containerd as shown in the followng command:

Configuration File
cat /etc/containerd/config.toml
#disabled_plugins = ["cri"]
 
#root = "/var/lib/containerd"
#state = "/run/containerd"
#subreaper = true
#oom_score = 0
version = 2
 
#[grpc]
#  address = "/run/containerd/containerd.sock"
#  uid = 0
#  gid = 0
 
[plugins."io.containerd.grpc.v1.cri"]
enable_selinux = true
  [plugins."io.containerd.grpc.v1.cri".containerd]
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          runtime_type = "io.containerd.runc.v2"
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            SystemdCgroup = true
 
#[debug]
#  address = "/run/containerd/debug.sock"
#  uid = 0
#  gid = 0
#  level = "info"

Use the following command to check if containerd is running with systemd cgroup:

Restart containerd service
systemctl daemon-reload
systemctl restart containerd
systemctl enable containerd.service
systemctl status containerd
 
crictl info | grep -i cgroup | grep true
            "SystemdCgroup": true

Kubeadm

Install kubernetes-kubeadm and other packages on the master node, and then use Kubeadm to install and configure Kubernetes.

Installing Kubernetes

Run the following commands to install kubeadm, kubectl, kubelet, and apparmor-parser:

tdnf install -y kubernetes-kubeadm apparmor-parser
systemctl enable --now kubelet

Pull the Kubernetes images using the following commands:

kubeadm config images pull

Run Kubeadm

Use the following commands to run Kubeadm and initialize the system:

kubeadm init
#For Flannel/Canal
kubeadm init --pod-network-cidr=10.244.0.0/16
 
 
I0420 05:45:08.440671    2794 version.go:256] remote version is much newer: v1.27.1; falling back to: stable-1.26
[init] Using Kubernetes version: v1.26.4
..........
..........
 
Your Kubernetes control-plane has initialized successfully!
 
To start using your cluster, you need to run the following as a regular user:
 
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
 
Alternatively, if you are the root user, you can run:
 
  export KUBECONFIG=/etc/kubernetes/admin.conf
 
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io./concepts/cluster-administration/addons/
 
Then you can join any number of worker nodes by running the following on each as root:
 
kubeadm join 10.197.103.246:6443 --token bf9mwy.vhs88r1g2vlwprsg \
    --discovery-token-ca-cert-hash sha256:be5f76dde01285a6ec9515f20abc63c4af890d9741e1a6e43409d1894043c19b
 
 
#For Calico
kubeadm init --pod-network-cidr=192.168.0.0/16

If everything goes well, the kubeadm init command should end with a message as displayed above.

Note: Copy and save the sha256 token value at the end. You need to use this token for the worker node to join the cluster.

The --pod-network-cidr parameter is a requirement for Calico. The 192.168.0.0/16 network is Calico’s default. For Flannel/Canal, it is 10.244.0.0/16.

You need to export the kubernetes configuration. For any new session, this step of export is repeated.

Also, untaint the control plane VM to schedule pods on the master VM.

Use the following command to export the Kubernetes configuration and untaint the control plane VM:

export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

The Network Plugin

Install the Canal network plugin using the following command:

#canal
curl https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/canal.yaml -o canal.yaml
 
# Alternatively if using flannel
curl https://raw.githubusercontent.com/flannel-io/flannel/v0.21.4/Documentation/kube-flannel.yml -o flannel.yaml
# Alternatively if using calico
curl  https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml -o calico.yaml

Get cni images for the network policy to work:

tdnf install -y docker
systemctl restart docker
docker login -u $username
 
docker pull calico/cni:v3.25.0
docker pull calico/node:v3.25.0
docker pull flannelcni/flannel:v0.16.3
docker pull calico/kube-controllers:v3.25.0

Note: Here we are proceeding with the downloading images required by canal.

Use the following command to apply the network policy:

#Apply network plugin configuration
kubectl apply -f canal.yaml

The Kubernetes master node should be up and running now. Try the following commands to verify the state of the cluster:

kubectl cluster-info
Kubernetes control plane is running at https://10.197.103.246:6443
CoreDNS is running at https://10.197.103.246:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
 
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
 
kubectl get nodes
NAME          STATUS   ROLES           AGE   VERSION
kube-master   Ready    control-plane   10m   v1.26.1
 
kubectl get pods --all-namespaces
NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-57b57c56f-qxz4s   1/1     Running   0          6m54s
kube-system   canal-w4d5r                               1/2     Running   0          6m54s
kube-system   coredns-787d4945fb-nnll2                  1/1     Running   0          10m
kube-system   coredns-787d4945fb-wfv8j                  1/1     Running   0          10m
kube-system   etcd-kube-master                          1/1     Running   1          11m
kube-system   kube-apiserver-kube-master                1/1     Running   1          11m
kube-system   kube-controller-manager-kube-master       1/1     Running   1          11m
kube-system   kube-proxy-vjwwr                          1/1     Running   0          10m
kube-system   kube-scheduler-kube-master                1/1     Running   1          11m

6.4.3.2 - Configure a Worker Node

This section describes how to configure a worker node with the following details:

Node Name: kube-worker Node IP Address: 10.197.103.232

Install the worker VM using the same Photon OS image.

Note: The VM configuration is similar to that of the master node, just with a different IP address.

Host Names

Change the hostname on the VM using the following command:

hostnamectl set-hostname kube-worker

To ensure connectivity with the future working node, kube-worker, modify the file /etc/hosts as follows:

cat /etc/hosts
# Begin /etc/hosts (network card version)
10.197.103.246 kube-master
10.197.103.232 kube-worker
  
::1         ipv6-localhost ipv6-loopback
127.0.0.1   localhost.localdomain
127.0.0.1   localhost
127.0.0.1   photon-machine
# End /etc/hosts (network card version)

System Tuning

IP Tables

Run the following iptables commands to open the required ports for Kubernetes to operate. Save the updated set of rules so that they become available the next time you reboot the VM.

Firewall settings
# ping
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
  
# kubernetes
iptables -A INPUT -p tcp -m tcp --dport 10250:10252 -j ACCEPT
  
# workloads
iptables -A INPUT -p tcp -m tcp --dport 30000:32767 -j ACCEPT
  
# calico
iptables -A INPUT -p tcp -m tcp --dport 179 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 4789 -j ACCEPT
  
# save rules
iptables-save > /etc/systemd/scripts/ip4save

Kernel Configuration

You need to enable IPv4 IP forwarding and iptables filtering on the bridge devices. Create the file /etc/sysctl.d/kubernetes.conf as follows:

# Load br_netfilter module to facilitate traffic between pods
modprobe br_netfilter
 
 
cat /etc/sysctl.d/kubernetes.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net/bridge/bridge-nf-call-arptables = 1

Apply the new sysctl settings as follows:

sysctl --system
...
 
* Applying /etc/sysctl.d/kubernetes.conf ...
.........
/proc/sys/net/ipv4/ip_forward = 1
/proc/sys/net/bridge/bridge-nf-call-ip6tables = 1
/proc/sys/net/bridge/bridge-nf-call-iptables = 1
/proc/sys/net/bridge/bridge-nf-call-arptables = 1

Containerd Runtime Configuration

Use the following command to install crictl and use containerd as the runtime endpoint:

#install crictl
tdnf install -y cri-tools
 
#modify crictl.yaml
cat /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: false
pull-image-on-create: false
disable-pull-on-run: false

Use systemd as cgroup for containerd as shown in the following command:

Configuration File
cat /etc/containerd/config.toml
#disabled_plugins = ["cri"]
 
#root = "/var/lib/containerd"
#state = "/run/containerd"
#subreaper = true
#oom_score = 0
version = 2
 
#[grpc]
#  address = "/run/containerd/containerd.sock"
#  uid = 0
#  gid = 0
 
[plugins."io.containerd.grpc.v1.cri"]
enable_selinux = true
  [plugins."io.containerd.grpc.v1.cri".containerd]
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          runtime_type = "io.containerd.runc.v2"
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            SystemdCgroup = true
 
#[debug]
#  address = "/run/containerd/debug.sock"
#  uid = 0
#  gid = 0
#  level = "info"

Use the following command to check if containerd is running with systemd cgroup:

Restart containerd service
systemctl daemon-reload
systemctl restart containerd
systemctl enable containerd.service
systemctl status containerd
 
crictl info | grep -i cgroup | grep true
            "SystemdCgroup": true

Kubeadm

Install kubernetes-kubeadm and other packages on the worker node, and then use Kubeadm to install and configure Kubernetes.

Installing Kubernetes

Run the following commands to install kubeadm, kubectl, kubelet, and apparmor-parser:

tdnf install -y kubernetes-kubeadm apparmor-parser
systemctl enable --now kubelet

Pull the Kubernetes images using the following commands:

kubeadm config images pull

Join the Cluster

Use Kubeadm to join the cluster with the token you got after running the kubeadm init command on the master node. Use the following command to join the cluster:

Join the master
kubeadm join 10.197.103.246:6443 --token eaq5cl.gqnzgmqj779xtym7 \
    --discovery-token-ca-cert-hash sha256:90b9da1b34de007c583aec6ca65f78664f35b3ff03ceffb293d6ec9332142d05

Use the following command to get cni images for network policy pods to work:

Pull required docker images
tdnf install -y docker
systemctl restart docker
docker login -u $username
 
docker pull calico/cni:v3.25.0
docker pull calico/node:v3.25.0
docker pull flannelcni/flannel:v0.16.3
docker pull calico/kube-controllers:v3.25.0

Cluster Test

The Kubernetes worker node should be up and running now. Run the following command from the kube-master node to verify the state of the cluster:

kubectl get nodes
NAME          STATUS   ROLES           AGE     VERSION
kube-master   Ready    control-plane   21m     v1.26.1
kube-worker   Ready    <none>          6m26s   v1.26.1

It takes a few seconds for the kube-worker node to appear and display the ready status.

6.4.3.3 - Run a Hello-World Application

Run a hello-world application to verify that the new two-node cluster works properly. All commands in this section must be executed from kube-master.

Create a pod with the name “hello” to print “Hello Kubernetes”.

Use the following command to create a pod with the name “hello”:

cat hello.yaml
 
apiVersion: v1
kind: Pod
metadata:
  name: hello
spec:
  restartPolicy: Never
  containers:
  - name: hello
    image: projects.registry.vmware.com/photon/photon4:latest
    command: ["/bin/bash"]
    args: ["-c", "echo Hello Kubernetes"]

Use the following command to create a hello Kubernetes application:

kubectl apply -f hello.yaml
#check status
kubectl get pods
#check logs
kubectl logs hello | grep "Hello Kubernetes"

You have successfully set up the two VM Kubernetes Kubeadm Cluster.

6.5 - Photon NFS Utilities for Mounting Remote File Systems

This document describes how to mount a remote file system on Photon OS by using nfs-utils, a commonly used package that contains tools to work with the Network File System protocol (NFS).

Check a Remote Server

showmount  -e nfs-servername or ip

Example:

showmount -e eastern-filer.eng.vmware.com
showmount -e 10.109.87.129

Mount a Remote File System in Photon Full

The nfs-utils package is installed by default in the full version of Photon OS. Here is how to mount a directory through NFS on Photon OS:

mount -t nfs nfs-ServernameOrIp:/exportfolder /mnt/folder

Example:

mount -t nfs eastern-filer.eng.vmware.com:/export/filer /mnt/filer
mount -t nfs 10.109.87.129:/export /mnt/export

Mount a Remote File System in Photon Minimal

The nfs-utils package is not installed in the minimal version of Photon OS. You install it by running the following command:

tdnf install nfs-utils

For more information on installing packages with the tdnf command, see the Photon OS Administration Guide.

Once nfs-utils is installed, you can mount a file system by running the following commands, replacing the placeholders with the path of the directory that you want to mount:

mount nfs
mount -t nfs nfs-ServernameOrIp:/exportfolder /mnt/folder

6.6 - Seamless Update with A/B Partition System

You can seamlessly update or roll back Photon OS with the support for A/B partition system. You can create a shadow partition set of the system and maintain the two partition sets. For example, an active set of partitions (partition A) and an inactive set of partitions (shadow partition or partition B).

The two partition sets ensure that the working system runs seamlessly on the active partition set while the update is performed on the inactive partition set. After the inactive partition set is updated, you can execute a kexec to boot quickly into the updated partition set. If the updated partition set does not work, the system can reboot and roll back to the previously working state on partition A.

Note: The kexec boot is executed with the abupdate switch command. The kexec boot does not modify the EFI boot manager (or MBR in the case of BIOS).

6.6.1 - Configuring A/B Partition System

You need to create a shadow partition set and configure the A/B partition system to use it for Photon OS updates and modifications.

To use the A/B partition system, ensure the following prerequisites:

  • If you boot with BIOS, only a root filesystem pair is needed. If you boot with UEFI, an EFI partition pair is also needed.

  • In the kickstart configuration file, when you create a partition, set the value of the ab parameter as true to create a shadow partition of the user-defined partition.

    To know more about the kickstart configuration, see the following page: Kickstart Support in Photon OS

    The following example shows how to create a shadow partition mounted at /:

    {
      "partitions": [
                      {
                        "disk": "/dev/sda",
                        "mountpoint": "/",
                        "size": 0,
                        "filesystem": "ext4",
                        "ab": true
                      },
                      {
                        "disk": "/dev/sda",
                        "mountpoint": "/sda",
                        "size": 100,
                        "filesystem": "ext4"
                      }
                    ]
    }
    
  • Configure the system details of the partitions for A/B update in the following configuration file: /etc/abupdate.conf

    The following template shows how a configuration file looks like:

    # either UEFI, BIOS, or BOTH
    # BOOT_TYPE=<boot type>
    
    # automatically switch to other partition set after update?
    # AUTO_SWITCH=NO
    
    # automatically finalize the update after a switch?
    # AUTO_FINISH=no
    
    # can choose to either use tdnf or rpm as a package manager
    # if not specified, tdnf is used
    # PACKAGE_MANAGER=tdnf
    
    # Provide information about partition sets
    # PartUUID info can be found with the "blkid" command
    #
    # EFI is needed if booting with UEFI
    # Format: PARTUUID A, PARTUUID B, mount point
    #
    # Example: HOME=("PARTUUID A" "PARTUUID B" "/home")
    
    # Note that the / partition should be labeled as _ROOT
    # EFI=("PARTUUID A" "PARTUUID B" "/boot/efi")
    # _ROOT=("PARTUUID A" "PARTUUID B" "/")
    
    # List of all partition sets
    # SETS=( "ROOT" )
    
    # exclude the following directories/files from being synced
    # note that these directory paths are absolute, not relative to current working directory
    #
    # Format: <set name>_EXCLUDE=( "/dir1/" "/dir2" "/dir3/subdir/file" ... "/dirN/" )
    #
    # Example:
    # HOME_EXCLUDE=( "/mnt" "lost+found" )
    

You can use the abupdate init command to auto-populate all the fields. However, it is recommended that you manually enter the fields for better accuracy.

Note: Persistent or shared partitions that exist outside the active and inactive partition sets are also supported in the A/B partition system. You need not specify the persistent or shared partitions in the configuration files.

6.6.2 - Executing Update and Rollback Using A/B Partition System

To modify or rollback Photon OS updates using A/B partition system, perform the following workflow:

  1. Edit the files on the inactive partition set. You can use the command options like mount, update, and deploy to mount and edit the files based on your requirements.

  2. Switch to an inactive partition set using the abupdate switch command.

  3. If you are not satisfied with the update, execute abupdate switch or reboot to roll back to the old active partition set.

  4. If you are satisfied with the update on the inactive partition set, finalize the switch with the abupdate finish command. Note: Once you execute the abupdate finish command, a reboot does not roll back to the previous partition set.

To know more about the commands for various operations, visit the following topic: Commands for Operations

6.6.3 - Commands for Operations

You can perform various operations in the A/B partition system using the following commands:

  • abupdate mount/unmount: Use this command to mount or unmount the inactive partition set. The partition set is mounted as a tree at the following location: /mnt/abupdate/. After you mount the partition set, the files are accessible for modifications.

  • abupdate update: Use this command to automatically upgrade the packages on the inactive partition set. This command supports tdnf and rpm as the package managers.

  • abupdate sync: Use this command to synchronize the active partition set with the inactive partition set. Note that this command eliminates the ability to rollback to a safe system anymore as both becomes mirrored partition sets after the command is executed.

  • abupdate clean: Use this command to erase everything on the inactive partition set.

  • abupdate deploy <tar.gz>: Use this command to erase and clean the inactive partition set, mount the inactive partition set, and then install or unpack the specified OS image in the inactive partition set from a tar file.

  • abupdate check: Use this command to run checks on the inactive partition set from the active partition set. Execute this command before you execute the switch command to ensure that the inactive partition set is not broken. This command also runs checks on tools needed to update or switch from the active partition set.

  • abupdate switch: Use this command to switch from the active partition set to the inactive partition set. Note that this command does not modify the EFI boot manager (or MBR in case of BIOS), and hence, any subsequent reboot rolls back to the previously active partition set.

    If the AUTO_SWITCH parameter is set to yes in the configuration file, then the system automatically switches into the updated partition set after the update is complete.

  • abupdate finish: Use this command to finalize the update. This command modifies the EFI boot manager (or MBR in case of BIOS). After you execute this command, the subsequent reboots load this partition set instead of rolling back to the previous partition set.

    Note: If the AUTO_FINISH parameter is set to yes in the configuration file, then the system automatically finalizes the switch with the finish command.

  • abupdate help: Use this command to print the help menu.

7 - Command-Line Reference

The Photon OS Command-Line Reference provides information about the command-line interfaces available in Photon OS.

Product version: 5.0

This documentation applies to all 5.0.x releases.

Intended Audiences

This information is intended for Photon OS administrators and users.

7.1 - Command-line Interfaces

Photon OS includes the following command-line utilities:

7.1.1 - Photon Network Config Manager Command-line Interface (nmctl)

You can use network-config-manager (nmctl) to configure and introspect the state of the network links as seen by systemd-networkd. nmctl can be used to query and configure devices for Addresses, Routes, Gateways, DNS, NTP, Domain, and hostname. You can also use nmctl to create virtual NetDevs (VLAN, VXLAN, Bridge, Bond, and so on). You can configure various configuration of links such as WakeOnLanPassword, Port, BitsPerSecond, Duplex and Advertise, and so on. nmctl uses sd-bus, sd-device APIs to interact with systemd, systemd-networkd, systemd-resolved, systemd-hostnamed, and systemd-timesyncd via dbus. nmctl uses networkd verbs to explain output. nmctl can generate configurations that persist between reboots.

The following example shows the system status:

❯ nmctl
         System Name: zeus
              Kernel: Linux (5.10.152-3.ph4)
     systemd version: v252-1
        Architecture: x86-64
      Virtualization: vmware
    Operating System: VMware Photon OS/Linux
          Machine ID: aa6e4cb92bee4c1aa8b304eafe28166c
        System State: routable
        Online State: partial
           Addresses: fe80::982e:b0ff:fe07:cc12/64   on device cni-podman0
                      fe80::20c:29ff:fe64:cb18/64    on device eth0
                      172.16.130.145/24              on device eth1
                      172.16.130.144/24              on device eth0
                      127.0.0.1/8                    on device lo
                      fe80::20c:29ff:fe5f:d143/64    on device eth1
                      ::1/128                        on device lo
                      fe80::c027:acff:fe19:d741/64   on device vethe8dc6ac9
                      10.88.0.1/16                   on device cni-podman0
             Gateway: 172.16.130.2	                 on device eth1
                      172.16.130.2	                 on device eth0
                 DNS: 172.16.130.2 172.16.130.1 172.16.130.126
                 NTP: 10.128.152.81 10.166.1.120 10.188.26.119 10.84.55.42`

The following example shows the network status:

❯ nmctl status eth0
           Alternative names: eno1 enp11s0 ens192
                       Flags: UP BROADCAST RUNNING MULTICAST LOWERUP
                        Type: ether
                        Path: pci-0000:0b:00.0
                      Driver: vmxnet3
                      Vendor: VMware
                       Model: VMXNET3 Ethernet Controller
                   Link File: /usr/lib/systemd/network/99-default.link
                Network File: /etc/systemd/network/99-dhcp-en.network
                       State: routable (configured)
               Address State: routable
          IPv4 Address State: routable
          IPv6 Address State: degraded
                Online State: online
         Required for Online: yes
           Activation Policy: up
                  HW Address: 00:0c:29:64:cb:18 (VMware, Inc.)
                         MTU: 1500 (min: 60 max: 9000)
                      Duplex: full
                       Speed: 10000
                       QDISC: mq
              Queues (Tx/Rx): 2/2
             Tx Queue Length: 1000
IPv6 Address Generation Mode: eui64
                GSO Max Size: 65536 GSO Max Segments: 65535
                     Address: 10.197.103.228/23 (DHCPv4 via 10.142.7.86) lease time: 7200 seconds T1: 3600 seconds T2: 6300 seconds
                              fe80::20c:29ff:fe64:cb18/64
                     Gateway: 172.16.130.2
                         DNS: 172.16.130.3 172.16.130.4 172.16.130.5
                         NTP: 172.16.130.6 172.16.130.7 172.16.130.8 172.16.130.9
           DHCP6 Client DUID: DUID-EN/Vendor:0000ab119a69db91b911f3180000

To add DNS, use the following command:

nmctl add-dns dev eth0 dns 192.168.1.45 192.168.1.46

To set mtu, use the following command:

nmctl set-mtu dev eth0 mtu 1400

To set mac, use the following command:

nmctl set-mac dev eth0 mac 00:0c:29:3a:bc:11

To set link options, use the following command:

nmctl set-link-option dev eth0 arp yes mc yes amc no pcs no

To add a static address, use the following command:

nmctl add-addr dev eth0 a 192.168.1.45/24

To add a default gateway, use the following command:

nmctl add-default-gw dev eth0 gw 192.168.1.1 onlink  yes

The following example shows how to create VLAN via nmctl The following command creates .netdev and .network and assigns them to the underlying device. It sets all these file permissions to systemd-network automatically.

❯ nmctl create-vlan [VLAN name] dev [MASTER DEVICE] id [ID INTEGER] proto [PROTOCOL {802.1q|802.1ad}] Creates vlan netdev and network file

❯ sudo nmctl create-vlan vlan-95 dev eth0 id 19

The following example shows how to create VXLAN via nmctl:

❯ sudo nmctl create-vxlan vxlan-98 vni 32 local 192.168.1.2 remote 192.168.1.3 port 7777 independent yes

The following example shows how to create virtual routing and forwarding (VRF):

❯ sudo nmctl create-vrf test-vrf table 555                                                                                               
❯ ip -d link show test-vrf
4: test-vrf: <NOARP,MASTER,UP,LOWER_UP> mtu 65575 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 86:ad:9b:50:83:1f brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 1280 maxmtu 65575 
    vrf table 555 addrgenmode none numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535  

The following example shows how to remove a virtual netdev:

❯ sudo nmctl remove-netdev vlan-95                                                                                         
❯ ip -d link show vlan-95 
Device "vlan-95" does not exist.

Note: nmctl not only removes the .netdev and .network files but also removes the virtual netdev.

7.1.1.1 - Configuring WireGuard using Network Configuration Manager

WireGuard is a lightweight, simple, fast, and secure VPN that is built into Linux kernel 5.6 and above. This topic provides sample WireGuard configurations for systemd-networkd using network-config-manager on Photon OS, a Linux-based operating system.

To generate the required configuration, you need to install WireGuard tools. You can download the WireGuard tools or install the WireGuard tools using tdnf.

To install the WireGuard tools using tdnf, run the following command:

❯ sudo tdnf install wireguard-tools -y

To configure WireGuard VPN, you need to create a pair of keys on both the sites between which you want to establish the VPN connection. Each site needs the public key of the other site. To create the pair of keys, use the following command:

❯ wg genkey | tee wg-private.key | wg pubkey > wg-public.key

You also need to change the permission of the files to make them readable for systemd-network users as shown in the following example:

❯ chown root:systemd-network wg-privatge.key wg-public.key

The following examples show the configurations of the two sites:

Site 1

❯ nmctl
         System Name: photon
              Kernel: Linux (5.10.152-6.ph4)
     systemd version: v247.11-4.ph4
        Architecture: x86-64
      Virtualization: vmware
    Operating System: VMware Photon OS/Linux
          Machine ID: 5103175aac7f4967acbdf97946c27ca3
        System State: routable
           Addresses: fe80::20c:29ff:fe3c:d58f/64    on device eth0
                      fe80::20c:29ff:fe3c:d599/64    on device eth1
                      127.0.0.1/8                    on device lo
                      192.168.1.10/24                on device eth0
                      192.168.1.9/24                 on device eth1
                      ::1/128                        on device lo
             Gateway: 192.168.1.1                    on device eth0
                      192.168.1.1                    on device eth1
                 DNS: 125.99.61.254 116.72.253.254



❯ cat wg-public.key 
d0AR4V68TJPA65ddKADmyTBbEgPTo75Xq/EVE1nsVFA=y

Site 2

❯ nmctl        
         System Name: Zeus
              Kernel: Linux (6.1.10-8.ph5)
     systemd version: v253-1
        Architecture: x86-64
      Virtualization: vmware
    Operating System: VMware Photon OS/Linux
          Machine ID: d4f740d7e70d423cb46c8b1def547701
        System State: routable
        Online State: partial
           Addresses: fe80::20c:29ff:fe5f:d139/64    on device ens33
                      fe80::20c:29ff:fe5f:d143/64    on device ens37
                      127.0.0.1/8                    on device lo
                      ::1/128                        on device lo
                      192.168.1.8/24                 on device ens33
                      192.168.1.7/24                 on device ens37
             Gateway: 192.168.1.1                    on device ens33
                      192.168.1.1                    on device ens37
                 DNS: 125.99.61.254 116.72.253.254


➜ cat wg-public.key lhR9C3iZGKC+CIibXsOxDql8m7YulZA5I2tqgU2PnhM=y

To generate the WireGuard configuration using nmctl for Site 1, use the following command:

➜ nmctl create-wg wg99 private-key-file /etc/systemd/network/wg-private.key listen-port 34966 public-key lhR9C3iZGKC+CIibXsOxDql8m7YulZA5I2tqgU2PnhM= endpoint 192.168.1.11:34966 allowed-ips 10.0.0.2/32

➜ nmctl add-addr dev wg99 a 10.0.0.1/24

The following configuration is generated for systemd-networkd:

❯ cat 10-wg99.netdev

[NetDev]
Name=wg99
Kind=wireguard


[WireGuard]
PrivateKeyFile=/etc/systemd/network/wg-private.key
ListenPort=34966


[WireGuardPeer]
# Public key of Site #2
PublicKey=lhR9C3iZGKC+CIibXsOxDql8m7YulZA5I2tqgU2PnhM=
Endpoint=192.168.1.11:34966
AllowedIPs=10.0.0.2/32

❯ cat 10-wg99.network
[Match]
Name=wg99


[Address]
Address=10.0.0.1/24

➜  ~ nmctl status wg99
    Flags: UP RUNNING NOARP LOWERUP 
                        Kind: wireguard
                        Type: wireguard
                      Driver: wireguard
                   Link File: /usr/lib/systemd/network/99-default.link
                Network File: /etc/systemd/network/10-wg99.network
                       State: routable (configured) 
               Address State: routable
          IPv4 Address State: routable
          IPv6 Address State: off
                Online State: online
         Required for Online: yes
           Activation Policy: up
                         MTU: 1420 (min: 0 max: 2147483552) 
                       QDISC: noqueue 
              Queues (Tx/Rx): 1/1 
             Tx Queue Length: 1000 
IPv6 Address Generation Mode: eui64 
                GSO Max Size: 65536 GSO Max Segments: 65535 
                     Address: 10.0.0.2/24

The following output is generated for WireGuard:

➜  wg

interface: wg99
  public key: lhR9C3iZGKC+CIibXsOxDql8m7YulZA5I2tqgU2PnhM=
  private key: (hidden)
  listening port: 34966

peer: d0AR4V68TJPA65ddKADmyTBbEgPTo75Xq/EVE1nsVFA=
  endpoint: 192.168.1.7:34966
  allowed ips: 10.0.0.1/32
  latest handshake: 20 minutes, 36 seconds ago
  transfer: 57.70 KiB received, 58.37 KiB sent

To generate the WireGuard configuration using nmctl for Site 2, use the following command:

➜ nmctl create-wg wg99 private-key-file /etc/systemd/network/wg-private.key listen-port 34966 public-key d0AR4V68TJPA65ddKADmyTBbEgPTo75Xq/EVE1nsVFA= endpoint 192.168.1.7:34966 allowed-ips 10.0.0.1/32

➜ nmctl add-addr dev wg99 a 10.0.0.2/242

The following configuration is generated for systemd-networkd:

➜ cat 10-wg99.netdev 
                 
[NetDev]
Name=wg99
Kind=wireguard


[WireGuard]
PrivateKeyFile=/etc/systemd/network/wg-private.key
ListenPort=34966


[WireGuardPeer]
# Public key of Site #1
PublicKey=d0AR4V68TJPA65ddKADmyTBbEgPTo75Xq/EVE1nsVFA=
Endpoint=192.168.1.7:34966
AllowedIPs=10.0.0.1/32


➜ network cat 10-wg99.network
[Match]
Name=wg99


[Address]
Address=10.0.0.2/24


❯ nmctl status wg99
                       Flags: UP RUNNING NOARP LOWERUP 
                        Kind: wireguard
                        Type: wireguard
                      Driver: wireguard
                   Link File: /usr/lib/systemd/network/99-default.link
                Network File: /etc/systemd/network/wg99.network
                       State: routable (configured) 
               Address State: routable
          IPv4 Address State: routable
          IPv6 Address State: off
                Online State: online
         Required for Online: yes
           Activation Policy: up
                         MTU: 1420 (min: 0 max: 2147483552) 
                       QDISC: noqueue 
              Queues (Tx/Rx): 1/1 
             Tx Queue Length: 1000 
IPv6 Address Generation Mode: eui64 
                GSO Max Size: 65536 GSO Max Segments: 65535 
                     Address: 10.0.0.2/24
                                                

➜ wg

interface: wg9
  public key: lhR9C3iZGKC+CIibXsOxDql8m7YulZA5I2tqgU2PnhM=
  private key: (hidden)
  listening port: 34966


peer: d0AR4V68TJPA65ddKADmyTBbEgPTo75Xq/EVE1nsVFA=
  endpoint: 192.168.1.7:34966
  allowed ips: 10.0.0.1/32
  latest handshake: 23 minutes, 57 seconds ago
  transfer: 57.70 KiB received, 58.37 KiB sent9

To verify the connectivity of Site 1, use the following command to ping and confirm the connectivity:

❯ ip a show wg99

Response:

25: wg99: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state 
UNKNOWN group default qlen 1000link/none 
    inet 10.0.0.1/24 brd 10.0.0.255 scope global wg99
       valid_lft forever preferred_lft forever

❯ ping 10.0.0.2

PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=4.90 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=3.77 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=23.0 ms

To verify the connectivity of Site 2, use the following command to ping and confirm the connectivity:

➜  ip a show wg

Response:

209: wg99: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000 link/none     inet 10.0.0.2/24 scope global wg99       valid_lft forever preferred_lft forever

➜  ping 10.0.0.1

PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=1.92 ms99

7.1.1.2 - Configure SR-IOV using Network Configuration Manager

SR-IOV technology enables multiple virtual machines to share a single PCIe device. SR-IOV allows a single PCIe device to appear as multiple and separate PCIe interfaces. This enables direct connection of multiple virtual machines to the PCIe devices. PCI-SIG (Peripheral Component Interconnect Special Interest Group) defines the standard interface and requirements in the SR-IOV specification to promote interoperability of the SR-IOV enabled devices.

SR-IOV introduces the concept of Physical Functions (PFs) and Virtual Functions (VFs). PFs refer to full-featured PCIe functions. VFs refer to the lightweight functions that lack certain configuration resources.

You can configure SR-IOV on Photon OS using the Network Configuration Manager (nmctl). Note that the systemd-networkd also supports SR-IOV.

You can use kernel module netdevsim to configure and test it as shown in the following example:

➜  ~  modprobe netdevsim                                                                                                                    
➜  ~  lsmod | grep netdevsim 
netdevsim             102400  0
psample                20480  1 netdevsim

➜  ~  echo "10 1" > /sys/bus/netdevsim/new_device 

➜  ~ sudo echo "99 1" > /sys/bus/netdevsim/new_device

➜  ~ ip -d link show eni99np1
287: eni99np1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether ca:28:ff:4e:73:2a brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 portname p1 switchid 82ae398327c5db81a27dc2756c43f00315f442de1779fcfbfc582bbb3e62cb parentbus netdevsim parentdev netdevsim99 

➜  ~ echo "3" > /sys/bus/netdevsim/devices/netdevsim99/sriov_numvfs

➜  ~ ip -d link show eni99np1                                      
287: eni99np1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether ca:28:ff:4e:73:2a brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 portname p1 switchid 82ae398327c5db81a27dc2756c43f00315f442de1779fcfbfc582bbb3e62cb parentbus netdevsim parentdev netdevsim99 
    vf 0     link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff, spoof checking off, link-state auto, trust off, query_rss off
    vf 1     link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff, spoof checking off, link-state auto, trust off, query_rss off
    vf 2     link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff, spoof checking off, link-state auto, trust off, query_rss off

To configure SR-IOV using nmctl, use the command as shown in the following example:

➜  ~ nmctl add-sr-iov dev eni99np1 vf 0 vlanid 5 qos 1 macspoofck yes qrss True trust yes linkstate yes macaddr 00:11:22:33:44:55

➜  ~ ip -d link show eni99np1                                                                                                
287: eni99np1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether ca:28:ff:4e:73:2a brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 portname p1 switchid 82ae398327c5db81a27dc2756c43f00315f442de1779fcfbfc582bbb3e62cb parentbus netdevsim parentdev netdevsim99 
    vf 0     link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff, vlan 5, qos 1, spoof checking on, link-state enable, trust on, query_rss on


➜  ~ sudo cat /etc/systemd/network/10-eni99np1.network
[Match]
Name=eni99np1


[SR-IOV]
VirtualFunction=0
VLANId=5
QualityOfService=1
MACSpoofCheck=yes
QueryReceiveSideScaling=yes
Trust=yes
LinkState=yes
MACAddress=00:11:22:33:44:55

The nmctl generates the SR-IOV configuration in the systemd-networkd format. Since nmctl reloads the configuration, systemd-networkd also configures the VF.

To configure the other VFs, use the command as shown in the following example:

➜  ~ nmctl add-sr-iov dev eni99np1 vf 1 vlanid 6 qos 2 macspoofck yes qrss True trust yes linkstate yes macaddr 00:11:22:33:44:56
➜  ~ nmctl add-sr-iov dev eni99np1 vf 1 vlanid 6 qos 2 macspoofck yes qrss True trust yes linkstate yes macaddr 00:11:22:33:44:5

➜  ~ ip -d link show eni99np1                                                                                                
287: eni99np1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether ca:28:ff:4e:73:2a brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535 addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536 portname p1 switchid 82ae398327c5db81a27dc2756c43f00315f442de1779fcfbfc582bbb3e62cb parentbus netdevsim parentdev netdevsim99 
    vf 0     link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ff, vlan 5, qos 1, spoof checking on, link-state enable, trust on, query_rss on
    vf 1     link/ether 00:11:22:33:44:56 brd ff:ff:ff:ff:ff:ff, vlan 6, qos 2, spoof checking on, link-state enable, trust on, query_rss on
    vf 2     link/ether 00:11:22:33:44:57 brd ff:ff:ff:ff:ff:ff, vlan 7, qos 3, spoof checking on, link-state enable, trust on, query_rss on

nmctl generates the .network:

➜  ~ cat /etc/systemd/network/10-eni99np1.network
[Match]
Name=eni99np1


[SR-IOV]
VirtualFunction=0
VLANId=5
QualityOfService=1
MACSpoofCheck=yes
QueryReceiveSideScaling=yes
Trust=yes
LinkState=yes
MACAddress=00:11:22:33:44:55


[SR-IOV]
VirtualFunction=1
VLANId=6
QualityOfService=2
MACSpoofCheck=yes
QueryReceiveSideScaling=yes
Trust=yes
LinkState=yes
MACAddress=00:11:22:33:44:56


[SR-IOV]
VirtualFunction=2
VLANId=7
QualityOfService=3
MACSpoofCheck=yes
QueryReceiveSideScaling=yes
Trust=yes
LinkState=yes
MACAddress=00:11:22:33:44:57

7.1.2 - Photon Real-Time Operating System Command-line Interface

Photon Real-Time Operating System provides commands for manipulating real-time properties of processes.

tuna

The tuna utility can be used to view and modify process priorities, CPU isolation and other real time characteristics in the system.

Examples:

View processes and their RT scheduling policies and priorities: $ tuna -P

                 thread    ctxt_switches

pid   SCHED_rtpri  affinity   voluntary    nonvoluntary                    cmd

  1    OTHER    0         0       1211           917                     systemd 

  2    OTHER     0        0       281             0                      kthreadd 

  3    OTHER     0        0         3             1                         rcu_gp

  4    OTHER     0        0         2             1                    rcu_par_gp

  6    OTHER     0        0         8             1            kworker/0:0H-kblockd

 13    FIFO      1        0       317             1                     rcu_sched

 16    FIFO     99        0         3             2                posixcputmr/0 

 17    FIFO     99        0         6             2                    migration/0

679    FIFO     50        0     1647541           1                irq/58-eth0-rxt

The following tasks are performed by using the tuna command:

  • Isolate a set of CPUs

    $ tuna -c <cpulist> -i (where <cpulist> can be X,Y-Z)

  • See the list of processes running on the specific CPUs before and after isolation

      $ tuna -c <cpulist> --show_threads
      $ tuna -c <cpulist> -i --show_threads
    

taskset

The taskset command can be used to get/set CPU affinity of tasks:

  • Run a program bound to a set of CPUs

    $ taskset -c <cpulist> ./program (where <cpulist> can be X,Y-Z)

  • Move a running task to a set of CPUs $ taskset -c p <cpulist> <pid>

  • View the CPU affinity settings of a running task $ taskset -c -p <pid>

chrt

The chrt command can be used to get or set the real-time scheduling policies and priorities of processes:

  • Modify the scheduling policy and priority of a running task

$ chrt -f -p <priority> <pid> (sets the task with pid to SCHED_FIFO policy with priority )

  • View the current scheduling policy and priority of a running task

    $ chrt -p <pid>

ps

The ps command can be used to list processes with their scheduling policies and priorities:

$ ps -eo cmd,pid,cpu,pri,cls


 `CMD `                                              ` PID  CPU   PRI    CLS`

`/lib/systemd/systemd --swit `                       ` 1     -    19    TS`

`[kthreadd]`                                         ` 2     -    19    TS`

8 - Troubleshooting Guide

The Photon OS Troubleshooting Guide provides solutions for common problems that you might encounter while using Photon OS.

Product version: 5.0

This documentation applies to all 5.0.x releases.

Intended Audiences

This information is intended for Photon OS administrators who install and set up Photon OS.

8.1 - Introduction

The Troubleshooting Guide covers the basics of troubleshooting systemd, packages, network interfaces, services such as SSH and Sendmail, the file system, and the Linux kernel. The guide also includes information about the tools that you can use for troubleshooting with examples, how to access the logs, and best practices.

8.1.1 - Systemd and TDNF

By using systemd, Photon OS adopts a contemporary Linux standard to bootstrap the user space and concurrently start services, an architecture that differs from traditional Linux systems such as SUSE Linux Enterprise Server 11.

A traditional Linux system contains an initialization system called SysVinit. With SLES 11, for instance, SysVinit-style init programs control how the system starts up and shuts down. Init implements system runlevels. A SysVinit runlevel defines a state in which a process or service runs. In contrast to a SysVinit system, systemd defines no such runlevels. Instead, systemd uses a dependency tree of targets to determine which services to start when.

Because the systemd commands differ from those of an init.d-based Linux system, a section later in this guide illustrates how to troubleshoot by using systemctl commands instead of init.d-style commands.

Tdnf keeps the operating system as small as possible while preserving yum’s robust package-management capabilities. On Photon OS, tdnf is the default package manager for installing new packages. Since troubleshooting with tdnf differs from using yum, a later section of this guide describes how to solve problems with packages and repositories by using tdnf commands.

8.1.2 - The Root Account and the `sudo` and `su` Commands

The Troubleshooting Guide assumes that you are logged in to Photon OS with the root account and running commands as root. The sudo program comes with the full version of Photon OS. On the minimal version, you must install sudo with tdnf if you want to use it. As an alternative to installing sudo on the minimal version, you can switch users as needed with the su command to run commands that require root privileges.

8.1.3 - Checking the Version and Build Number

To check the version and build number of Photon OS, concatenate /etc/photon-release.

Example:

cat /etc/photon-release
VMware Photon Linux 1.0
PHOTON_BUILD_NUMBER=a6f0f63

The build number in the results maps to the commit number on the VMware Photon OS GitHub commits page.

8.1.4 - General Best Practices

When troubleshooting, it is recommended that you follow some general best practices:

  • Take a snapshot. Before you do anything to a virtual machine running Photon OS, take a snapshot of the VM so that you can restore it if need be.

  • Make a backup copy. Before you change a configuration file, make a copy of the original file. For example: cp /etc/tdnf/tdnf.conf /etc/tdnf/tdnf.conf.orig

  • Collect logs. Save the log files associated with a Photon OS problem. Include not only the log files on the guest but also the vmware.log file on the host. The vmware.log file is in the host’s directory that contains the VM.

  • Know what is in your toolbox. View the man page for a tool before you use it so that you know what your options are. The options can help focus the command’s output on the problem you’re trying to solve.

  • Understand the system. The more you know about the operating system and how it works, the better you can troubleshoot.

8.1.5 - Photon OS Logs

On Photon OS, all the system logs except the installation logs and the cloud-init logs are written into the systemd journal. The journalctl command queries the contents of the systemd journal.

The installation log files and the cloud-init log files reside in /var/log. If Photon OS is running on a virtual machine in a VMware hypervisor, the log file for the VMware tools, vmware-vmsvc.log, also resides in /var/log.

##Journalctl Journalctl is a utility to query and display logs from journald and systemd’s logging service. Since journald stores log data in a binary format instead of a plain text format, journalctl is the standard way of reading log messages processed by journald.

Journald is a service provided by systemd. To see the staus of the daemon, run the following commands:

# systemctl status systemd-journald
● systemd-journald.service - Journal Service
Loaded: loaded (/lib/systemd/system/systemd-journald.service; static; vendor preset: enabled)
Active: active (running) since Tue 2020-04-07 14:33:41 CST; 2 days ago
Docs: man:systemd-journald.service(8)
man:journald.conf(5)
Main PID: 943 (systemd-journal)
Status: "Processing requests..."
Tasks: 1 (limit: 4915)
Memory: 18.0M
CGroup: /system.slice/systemd-journald.service
└─943 /lib/systemd/systemd-journald



Apr 07 14:33:41 photon-4a0e7f2307d4 systemd-journald[943]: Journal started
Apr 07 14:33:41 photon-4a0e7f2307d4 systemd-journald[943]: Runtime journal (/run/log/journal/b8cebc61a6cb446a968ee1d4c5bbbbd5) is 8.0M, max 1.5G, 1.5G free.
Apr 07 14:33:41 photon-4a0e7f2307d4 systemd-journald[943]: Time spent on flushing to /var is 88.263ms for 1455 entries.
Apr 07 14:33:41 photon-4a0e7f2307d4 systemd-journald[943]: System journal (/var/log/journal/b8cebc61a6cb446a968ee1d4c5bbbbd5) is 40.0M, max 4.0G, 3.9G free.
root@photon-4a0e7f2307d4 [ ~ ]#

The following command are related to journalctl:

  • journalctl : This command displays all the logs after the system has booted up. journalctl splits the results into pages, similar to the less command in Linux. You can navigate using the arrow keys, the Page Up, Page Down keys or the Space bar. To quit navigation, press the q key.
  • journalctl -b : This command displays the logs for the current boot.

The following commands pull logs based on a time range:

  • journalctl --since "1 hour ago" : This command displays the journal logs from the past 1 hour.
  • journalctl --since "2 days ago" : This command displays the logs generated in the past 2 days.
  • journalctl --since "2020-03-25 00:00:00" --until "2020-04-09 00:00:00" : This command displays the logs generated between the mentioned time frame.

To traverse for logs in the reverse order, run the following command:

  • journalctl -r : This command displays the logs in reverse order.

Note: If you add -r at the end of a command, the logs are displayed in the reverse order. For example: journalctl -u unit.service -r

To pull logs related to a particular daemon, run the following command:

  • journalctl -u unit.service : This command displays logs for a specific service. mention the name of the service instead of unit. This command helps when a service is not behaving properly or when there are crash/core dumps.

To see Journal logs by their priority, run the following command:

  • journalctl -p "emerg".."crit : This command displays logs emerg to critical. For example: core dumps.

Journalctl can print log messages to the console as they are added, like the Linux tail command. Add the -f switch to follow a specific service or daemon.

journalctl -u unit.service -f

To list the boots of the system, run the following command:

journalctl --list-boots

You can maintain the journalctl logs manually, by running the following vacuum commands:

  • journalctl --vacuum-time=2d : This command retains the logs from the last 2 days.
  • journalctl --vacuum-size=500M : This command helps retain logs with a maximum size of 500 MB.

You can configure Journald using the conf file located at /etc/systemd/journald.conf. Run the following command to configure the file:

# cat /etc/systemd/journald.conf
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See journald.conf(5) for details.

[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=10000
#SystemMaxUse=
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
#MaxFileSec=1month
#ForwardToSyslog=no
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48K
root@photon-4a0e7f2307d4 [ ~ ]#

By default rotate is disabled in Photon. Once the changes are made to the conf file, for the changes to take effect you must restart the systemd-journald by running the systemctl restart systemd-journald command.

Cloud-init Logs

Cloud-init is the industry standard multi-distribution method for cross-platform cloud instance initialisation.

If there are with the Cloud-init behaviour, we can debug them by looking at the logs. Run the following command to look at Cloud-init logs:

journalctl -u cloud-init

For better understanding/debugging, You can also look at logs from the following locations:

  • /var/log/cloud-init.log : This log contains information from each stage of Cloud-init.
  • /var/log/cloud-init-output.log : This log contains errors, warnings, etc..

Syslog

Syslog is the general standard for logging system and program messages in the Linux environment.

Photon provides the following two packages to support syslog:

  • syslog-ng : syslog-ng is syslog with some advanced next gen features. It supports TLS encryption, TCP for transport with other existing features. Configurations can be added to the /etc/syslog-ng/syslog-ng.conf file.
  • rsyslog : The official RSYSLOG website defines the utility as “the rocket-fast system for log processing”. rsyslog supports some advanced features like relp, imfile, omfile, gnutls protocols. Configurations can be added to the /etc/rsyslog.conf file. You can configure the required TLS certificates by editing the conf file.

Logs for RPMS on Photon

Logs for a particular RPM can be checked in the following ways:

  • If the RPM provides a daemon, we can see the status of daemon by running systemctl command and check logs using journactl -u <service name> command.
  • For additional logs, check if a conf file is provided by the RPM by running the rpm -ql <rpm name> | grep conf command and find the file path of the log file. You can also check the /var/log folder.

8.1.6 - Troubleshooting Progression

If you encounter a problem running an application or appliance on Photon OS and you suspect it involves the operating system, you can troubleshoot by proceeding as follows.

  1. Check the services running on Photon OS:

    systemctl status

  2. Check your application log files for errors. For VMware applications, see Location of Log Files for VMware Products.)

  3. Check the service controller or service monitor for your application or appliance.

  4. Check the network interfaces and other aspects of the network service with systemd-network commands.

  5. Check the operating system log files:

    journalctl

    Next, run the following commands to view all services according to the order in which they were started:

    systemd-analyze critical-chain

  6. Use the troubleshooting tool that you think is most likely to help with the issue at hand. For example, use strace to identify the location of the failure.

8.2 - Solutions to Common Problems

This section describes solutions to problems that you might encounter when using or managing Photon OS.

8.2.1 - Boot in Emergency Mode

If you encounter problems during normal boot, you can boot in Emergency Mode.

Perform the following steps to boot in Emergency Mode:

  1. Restart the Photon OS machine or the virtual machine running Photon OS.

    When the Photon OS splash screen appears, as it restarts, type the letter e quickly.

  2. Append emergency to the kernel command line.

  3. Press F10 to proceed with the boot.

  4. At the command prompt, provide the root password to log in to Emergency Mode.

    By default, / is mounted as read-only.

    To make modifications, run the following command to remount with write access:

    mount -o remount,rw /

8.2.2 - Resetting a Lost Root Password

Perform the following steps to rest a lost password:

  1. Restart the Photon OS machine or the virtual machine running Photon OS.

    When the Photon OS splash screen appears as it restarts, type the letter e to go to the GNU GRUB edit menu quickly. Because Photon OS reboots so quickly, you won’t have much time to type e. Remember that in vSphere and Workstation, you might have to give the console focus by clicking in its window before it will register input from the keyboard.

Second, in the GNU GRUB edit menu, go to the end of the line that starts with linux, add a space, and then add the following code exactly as it appears below:

rw init=/bin/bash

After you add this code, the GNU GRUB edit menu should look exactly like this:

The modified GNU GRUB edit menu

Now type F10.

At the command prompt, type passwd and then type (and re-enter) a new root password that conforms to the password complexity rules of Photon OS. Remember the password.

Next, type the following command:

umount /

Finally, type the following command. You must include the -f option to force a reboot; otherwise, the kernel enters a state of panic.

reboot -f

This sequence of commands should look like this:

The series of commands to reset the root password

After the Photon OS machine reboots, log in with the new root password.

Resetting the failed logon count

Resetting the root password will not reset the failed logon count, if you’ve had to many failed attempts, you may not be able to logon after resetting the password.

You will know if this is the case, if you see Account locked due to X failed logins at the photon console.

To reset the count, before you unmount the filesystem, run the following…

/sbin/pam_tally2 --reset --user root

8.2.3 - Fixing Permissions on Network Config Files

When you create a new network configuration file as root user, the network service might be unable to process it until you set the file mode bits (i.e. chmod) to 644.

If you query the journal with journalctl -u systemd-networkd, you might see the following error message along with an indication that the network service did not start:

could not load configuration files. permission denied

The permissions on the network files might cause this problem. Without the correct permissions, networkd-systemd cannot parse and apply the settings, and the network configuration that you created will not be loaded.

After you create a network configuration file with a .network extension, you must run the chmod command to set the new file’s mode bits to 644. Example:

chmod 644 10-static-en.network

For Photon OS to apply the new configuration, you must restart the systemd-networkd service by running the following command:

systemctl restart systemd-networkd

8.2.4 - Permitting Root Login with SSH

The full version of Photon OS prevents root login with SSH by default. To permit root login over SSH, open /etc/ssh/sshd_config with the vim text editor and set PermitRootLogin to yes.

Vim is the default text editor available in Photon OS. The developer version also contains Nano. After you modify the SSH daemon’s configuration file, you must restart the sshd daemon for the changes to take effect.

Example:

vim /etc/ssh/sshd_config
# override default of no subsystems
Subsystem       sftp    /usr/libexec/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#       X11Forwarding no
#       AllowTcpForwarding no
#       PermitTTY no
#       ForceCommand cvs server
PermitRootLogin yes
UsePAM yes

Save your changes in vim and then restart the sshd daemon:

systemctl restart sshd

You can then connect to the Photon OS machine with the root account over SSH:

user@ubuntu:~$ ssh root@10.0.0.131

8.2.5 - Fixing Sendmail

If Sendmail is not behaving as expected or hangs during installation, it might be because FQDN is not set.

Perform the following steps:

  1. Set an FQDN for your Photon OS machine.

  2. Run the following commands in the order below:

    echo $(hostname -f) > /etc/mail/local-host-names
    
        cat > /etc/mail/aliases << "EOF"
            postmaster: root
            MAILER-DAEMON: root
            EOF
    
        /bin/newaliases
    
        cd /etc/mail
    
        m4 m4/cf.m4 sendmail.mc > sendmail.cf
    
        chmod 700 /var/spool/clientmqueue
    
        chown smmsp:smmsp /var/spool/clientmqueue
    

8.3 - Photon OS General Troubleshooting

The section includes general troubleshooting instruction for Photon OS.

8.3.1 - Photon Code

Photon is an RPM based Linux distribution similar to variants like CentOS and Fedora. With RPM based distributions granular updates as opposed to updating the whole OS image is possible.

##SPEC File The “Recipe” for creating an RPM package is a spec file. The Photon code base’s SPECS folder hast the following directory structure:

SourceRoot

       SPECS
            linux
                patch1
                patch2
                linux.spec

Check if a package is signed

Run the following commands to check if the package is signed:

#check if a package is signed
rpm -q linux --qf '%{NAME}-%{VERSION}-%{RELEASE} %{SIGPGP:pgpsig} %{SIGGPG:pgpsig}\n'
linux-4.19.79-2.ph3 RSA/SHA1, Thu 31 Oct 2019 10:05:05 AM UTC, Key ID c0b5e0ab66fd4949 (none)
 
#or
rpm -qi linux | grep "Signature"
Signature   : RSA/SHA1, Thu 31 Oct 2019 10:05:05 AM UTC, Key ID c0b5e0ab66fd4949
 
#Last 8 chars of Key ID: 66fd4949
#See if it matches the version of any of the gpg keys installed.
rpm -qa | grep gpg-pubkey | xargs -n1 rpm -q --queryformat "%{NAME} %{VERSION} %{PACKAGER}\n"
gpg-pubkey 66fd4949 VMware, Inc. -- Linux Packaging Key -- linux-packages@vmware.com
gpg-pubkey 3e1ba8d5 Google Cloud Packages RPM Signing Key gc-team@google.com

Check if an image has vulnerabilities

Use the security scanners to find security issues. Alternatively The tdnf updateinfo info command displays all the applicable security updates the host needs.

Check if a CVE is Fixed

The Photon team fixes vulnerabilities and publishes advisories to https://github.com/vmware/photon/wiki/Security-Advisories.

To Check if Security Updates are Available

Use the tdnf updateinfo info, tdnf update --security or tdnf update ---sec-severity <level> commands to check if security updates are available. For example:

Check if there are any security updates

root@photon [ ~ ]# tdnf updateinfo
70 Security notice(s)

Check if there are security updates for libssh2. note this is relative to what is installed in local

root@photon[ ~ ]# tdnf updateinfo list libssh2
patch:PHSA-2020-3.0-0047 Security libssh2-1.9.0-2.ph3.x86_64.rpm
patch:PHSA-2019-3.0-0025 Security libssh2-1.9.0-1.ph3.x86_64.rpm
patch:PHSA-2019-3.0-0009 Security libssh2-1.8.2-1.ph3.x86_64.rpm
patch:PHSA-2019-3.0-0008 Security libssh2-1.8.0-2.ph3.x86_64.rpm

Show details of all the libssh2 updates root@photon [ ~ ]# tdnf updateinfo info libssh2 Name : libssh2-1.9.0-2.ph3.x86_64.rpm Update ID : patch:PHSA-2020-3.0-0047 Type : Security Updated : Wed Jan 15 10:48:25 2020 Needs Reboot: 0 Description : Security fixes for {‘CVE-2019-17498’} Name : libssh2-1.9.0-1.ph3.x86_64.rpm Update ID : patch:PHSA-2019-3.0-0025 Type : Security Updated : Sat Aug 17 16:14:35 2019 Needs Reboot: 0 Description : Security fixes for {‘CVE-2019-13115’} Name : libssh2-1.8.2-1.ph3.x86_64.rpm Update ID : patch:PHSA-2019-3.0-0009 Type : Security Updated : Sat Apr 13 03:34:22 2019 Needs Reboot: 0 Description : Security fixes for {‘CVE-2019-3859’, ‘CVE-2019-3862’, ‘CVE-2019-3861’, ‘CVE-2019-3857’, ‘CVE-2019-3858’, ‘CVE-2019-3863’, ‘CVE-2019-3860’, ‘CVE-2019-3856’} Name : libssh2-1.8.0-2.ph3.x86_64.rpm Update ID : patch:PHSA-2019-3.0-0008 Type : Security Updated : Fri Mar 29 16:04:18 2019 Needs Reboot: 0 Description : Security fixes for {‘CVE-2019-3855’}

 
install all security updates >= score 9.0 (CVSS_v3.0_Severity)

```console
root@photon [ ~ ]# tdnf update --sec-severity 9.0
Upgrading:
apache-tomcat                  noarch          8.5.50-1.ph3         photon-updates    9.00M 9440211
bash                           x86_64          4.4.18-2.ph3         photon-updates    3.16M 3315720
bzip2                          x86_64          1.0.8-1.ph3          photon-updates  124.99k 127990
bzip2-libs                     x86_64          1.0.8-1.ph3          photon-updates   74.31k 76096
file                           x86_64          5.34-2.ph3           photon-updates   43.02k 44056
file-libs                      x86_64          5.34-2.ph3           photon-updates    5.21M 5458536
git                            x86_64          2.23.1-2.ph3         photon-updates   24.34M 25519969
glib                           x86_64          2.58.0-4.ph3         photon-updates    3.11M 3265152
libseccomp                     x86_64          2.4.0-2.ph3          photon-updates  315.79k 323368
libssh2                        x86_64          1.9.0-2.ph3          photon-updates  238.41k 244136
linux-esx                      x86_64          4.19.97-2.ph3        photon-updates   12.68M 13299655
 
Total installed size:  58.28M 61114889

8.3.2 - Package Management

TDNF is the default package manager for Photon OS. The standard syntax for tdnf commands is the same as that for DNF and YUM. TDNF reads YUM repositories from /etc/yum.repos.d/.

To find the main configuration file and see its contents, run the following command:

cat /etc/tdnf/tdnf.conf
[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=true
repodir=/etc/yum.repos.d
cachedir=/var/cache/tdnf

Repositories have a .repo file extension, The following repositories are available in /etc/yum.repos.d/ :

ls /etc/yum.repos.d/
photon-extras.repo
photon-iso.repo
photon-updates.repo
photon.repo

Use the tdnf repolist command to list the repositories. Tdnf filters the results by their status enabled, disabled, and all. Running the tdnf repolist command without arguments displays the enabled repositories.

#tdnf repolist

repo id repo name status
photon-extras        VMware Photon Extras 3.0(x86_64) enabled
photon-debuginfo VMware Photon Linux debuginfo 3.0(x86_64)enabled
photon                    VMware Photon Linux 3.0(x86_64) enabled
photon-updates     VMware Photon Linux 3.0(x86_64) Updates enabled
root@photon-75829bfd01d0 [ ~ ]#

The following repositories are important for Photon:

  • photon-updates : This repo contains RPM updates for CVE/version and updates/others fixes.
  • photon-debuginfo : This repo contains information about RPMs with debug symbols.
  • photon : This repo generally contains the RPM versions packaged with the released ISO.

To check the local cache data from the repository, run the following command:

# ls -l /var/cache/tdnf/photon
total 12
-r--r----- 1 root root 0 Apr 3 22:34 lastrefresh
drwxr-x--- 2 root root 4096 Apr 3 22:34 repodata
drwxr-x--- 4 root root 4096 Feb 4 14:31 rpms
drwxr-x--- 2 root root 4096 Apr 3 22:34 solvcache

##Usage The tdnf command can be used in the following ways:

#tdnf repolist --refresh : This command is used to refresh the repolist. Generally there is a cache of the repo data stored in the local VM.

#tdnf install <rpm name> : This command is used to install a RPM. This command installs the latest version of the RPM.

#tdnf install <pkg-name>-<verison>-<release>.<photon-release> : This command is used to install a particular RPM version. For example, run # tdnf install systemd-239-11.ph3.

#tdnf list systemd : This command is used to list the available RPM versions in the repository.

#tdnf makecache : This command updates the cached binary metadata for all known repositories.

tdnf clean all : This command cleans up temporary files, data, and metadata. It takes the argument all.

#tdnf list systemd

Refreshing metadata for: 'VMware Photon Linux 3.0(x86_64)'

systemd.x86_64                                                                       239-15.ph3                                            @System

systemd.x86_64                                                                       239-11.ph3                                     photon-updates

systemd.x86_64                                                                       239-12.ph3                                     photon-updates

systemd.x86_64                                                                       239-13.ph3                                     photon-updates

systemd.x86_64                                                                       239-14.ph3                                     photon-updates

systemd.x86_64                                                                       239-15.ph3                                     photon-updates

systemd.x86_64                                                                       239-17.ph3                                     photon-updates

systemd.x86_64                                                                       239-18.ph3                                     photon-updates

systemd.x86_64                                                                       239-19.ph3                                     photon-updates

systemd.x86_64                                                                       239-10.ph3                                             photon

systemd.x86_64                                                                       239-10.ph3                                             photon

root@photon-4a0e7f2307d4 [ /WS/photon-dev/photon ]#

Here, @System indicates that the particular RPM is installed in the VM.

To upgrade/downgrade RPMs run the following commands:

#tdnf upgrade <pkg-name>

#tdnf downgrade <pkg-name>

After upgrade/downgrade the dependent packages must be manually upgraded/downgraded as well. Use the #tdnf remove <pkg-name> command to remove packages and # tdnf clean all to clear cached packages, metadata, dbcache, plugins and expire-cache.

#RPM RPM is an open source package management system capable of building software from source into easily distributable packages. It is used for installing, updating and uninstalling packaged software. RPM can also be used to query detailed information about the packaged software and to check if a particular package is installed or not.

You can do the following operation using the RPM binaries:

  • Install/Upgrade/Downgrade/Remove RPMs from a virtual machine.
  • Check the version of the packages installed.
  • Check the package contents.
  • Check the dependencies of a package.
  • Find the source package of a file.

To find the package that contains a particular binary, run rpm -q —whatprovides <binary/file path> command.

##Usage The rpm command can be used in the following ways:

  • rpm -ivh <rpm file path> : This command installs the RPM in a virtual machine.
  • rpm -Uvh <rpm file path> : This command is used to upgrade/downgrade the RPM.
  • rpm -e <rpm file path> : This command uninstalls the RPM from the virtual machine.
  • rpm -qp <rpm file path> --provides : This displays the libraries provided by the RPM.
  • rpm -qp <rpm file path> --requires : This displays the binaries/libraries required to install a particular rpm.
  • rpm -qa : This displays a list of all installed packages.
  • rpm -ql <package file.rpm> : This command lists all files in the package file.

8.3.3 - Network Configuration

systemd-networkd is a system daemon that manages network configurations. It detects and configures network devices as they appear. It can also create virtual network devices.

##Configuration Examples All configurations are stored as foo.network in the /etc/systemd/network/, /lib/systemd/network/ and /run/systemd/network/ folder. Use the networkctl list command to list all the devices on the system.

After making changes to a configuration file, restart the systemd-networkd.service if version is < 245, for other version run the following commands:

root@photon [ /home/sus ]# networkctl reload
root@photon [ /home/sus ]# networkctl reconfigure eth0

Note:

  • The options mentioned in the configuration files are case sensitive.
  • Set DHCP=yes to accept IPv4 and IPv6 DHCP requests.
  • Set DHCP=ipv4 to accept IPv4 DHCP requests.
  • Set LinkLocalAddressing=no to disable IPv6. Please do not disable IPv6 via sysctl. When LinkLocalAddressing=no in the .network file, the kernel drops addresses starting with fe80, for example fe80::20c:29ff:fe4c:7eca. If IPv6LL address is not available networkd will not start IPv6 configurations.

To link network configurations using DHCPv4 (IPv6 disabled), run the following command:

/etc/systemd/network/20-eth0.network
[Match]
Name=eth0

[Network]
LinkLocalAddressing=no

DHCP=ipv4

To link network configurations using DHCPv6, run the following command:

/etc/systemd/network/20-eth0.network
[Match]
Name=eth0

[Network]
IPv6AcceptRA=yes

DHCP=ipv6

To link network configurations using a static IP address, run the following command:

/etc/systemd/network/20-wired.network
[Match]
Name=enp1s0

[Network]
Address=10.1.10.9/24
Gateway=10.1.10.1
DNS=10.1.10.1

Here Address= can be used more than once to configure multiple IPv4 or IPv6 addresses.

A .link file can be used to rename an interface. For example, set a predictable interface name for a Ethernet adapter based on its MAC address by running the following command:

/etc/systemd/network/10-test0.link
[Match]
MACAddress=12:34:56:78:90:ab

[Link]
Description=my custom name
Name=test123

##Configuration Files Configuration files are located in /usr/lib/systemd/network/ folder, the volatile runtime network directory in /run/systemd/network/ folder and the local administration network directory in /etc/systemd/network/ folder. Configuration files in /etc/systemd/network/ folder have the highest priority.

There are three types of configuration files and they use a format similar to systemd unit files.

  • .network : These files apply a network configuration to a matching device.

  • .netdev : These files are used to create a virtual network device for a matching environment.

  • .link : When a network device appears, udev looks for the first matching .link file. These link files follow the following rules:

  • Only if all conditions in the [Match] section are matched, the profile will be activated.

  • An empty [Match] section means the profile can apply to any case (can be compared to the * wild card)

  • All configuration files are collectively sorted and processed in lexical order, regardless of the directory it resides in.

  • Files with identical names replace each other.

##Duplicate Matches If we have multiple configuration files matching an interface, the first (in lexical order) network file matching a given device is applied. All other files are ignored even if they match. The following is an example of matching configuration files:

builder@localhost [ ~ ]$ cat /etc/systemd/network/10-eth0.network
[Match]
Name=eth0
[Network]
DHCP=yes
  
builder@localhost [ ~ ]$ cat /etc/systemd/network/99-dhcp-en.network
[Match]
Name=e*
 
[Network]
DHCP=yes
IPv6AcceptRA=no

##Network Files These files are used to set network configuration variables for servers and containers. .network files have the following sections:

###[Match]

ParameterDescriptionAccepted Values
Name=Matches device names. For example: en*. By using ! prefix the list can be inverted.Device names separated by a white space, logical negation (!).
MACAddress=Matches MAC addresses. For example: MACAddress=01:23:45:67:89:ab 00-11-22-33-44-55 AABB.CCDD.EEFFMAC addresses with full colon-, hyphen- or dot-delimited hexadecimal separated by a white space.
Host=Matches the host name or the machine ID of the host.Hostname string or Machine ID
Virtualization=Checks whether the system is running in a virtual environment. Virtualization=false will only match your host machine, while Virtualization=true matches containers or VMs. It is also possible to check for a specific virtualization type or implementation.boolean, logical negation (!), type (vm, container), implementation (qemu, kvm, zvm, vmware, microsoft, oracle, xen, bochs, uml, bhyve, qnx, openvz, lxc, lxc-libvirt, systemd-nspawn, docker, podman, rkt, wsl, acrn)

###[Link]

  • MACAddress= : Used to spoof MAC address.
  • MTUBytes= : Setting a larger MTU value (For example: when using jumbo frames) can significantly speed up your network transfers.
  • Multicast : Enables the use of multicast on interface(s).

###[Network]

ParameterDescriptionAccepted ValuesDefault Value
DHCP=Controls DHCPv4 and/or DHCPv6 client support.Boolean, ipv4, ipv6false
DHCPServer=If enabled, a DHCPv4 server will be started.Booleanfalse
MulticastDNS=Enables multicast DNS support. When set to resolve, only resolution is enabled.Boolean, resolvefalse
DNSSEC=Controls the DNSSEC DNS validation support on the link. When set to allow-downgrade, compatibility with non-DNSSEC capable networks is increased, by automatically turning off DNSSEC.Boolean, allow-downgradefalse
DNS=Configures static DNS addresses. can be specified more than once.inet_pton
Domains=Indicates domains which must be resolved using the DNS servers.domain name, optionally prefixed with a ~
IPForward=If enabled, incoming packets on any network interface will be forwarded to any other interfaces according to the routing table.Boolean, ipv4, ipv6false
IPMasquerade=If enabled, packets forwarded from the network interface appear as if they are coming from the local host.Booleanfalse
IPv6PrivacyExtensions=Configures use of stateless temporary addresses that change over time. When set to prefer-public, the privacy extensions are enabled, but prefers public addresses over temporary addresses. When set to kernel, the kernel’s default setting will be left in place.Boolean, prefer-public, kernelfalse

###[Address] Address= option is mandatory unless DHCP is used.

###[Route]

  • Gateway= option is mandatory unless DHCP is used.
  • Destination= option defines the destination prefix of the route, possibly followed by a slash and the prefix length. If Destination is not present in [Route] section it is treated as a default route. Note: You can add the Address= and Gateway= keys in the [Network] section as a short-hand, if the [Address] section contains only an Address key and [Route] section contains only a Gateway key.

###DHCP

ParameterDescriptionAccepted ValuesDefault Value
UseDNS=Defines the DHCP server to be used.Booleantrue
Anonymize=When set to true, the options sent to the DHCP server will follow RFC7844 (Anonymity Profiles for DHCP Clients) to minimize disclosure of identifying information.Booleanfalse
UseDomains=Defines the DHCP server to be used as the DNS search domain. If set to route, the domain name received from the DHCP server will be used for routing DNS queries only and not for searching. This option can sometimes fix local name resolving when using systemd-resolved.Boolean, routefalse

###[DHCPServer] The following is an example of a DHCP server configuration which works well with hostapd to create a wireless hotspot. IPMasquerade adds the firewall rules for NAT and IPForward enables packet forwarding.

/etc/systemd/network/wlan0.network
[Match]
Name=wlan0

[Network]
Address=10.1.1.1/24
DHCPServer=true
IPMasquerade=true
IPForward=true

[DHCPServer]
PoolOffset=100
PoolSize=20
EmitDNS=yes
DNS=9.9.9.9

##Netdev Files These files create virtual network devices. They have the following two sections:

###[Match]

  • Host= : The host name.
  • Virtualization= : Checks if it is running in a virtual environment.

###[NetDev]

  • Name= : The interface’s name. This is a mandatory field.
  • Kind= : For example: bridge, bond, vlan, veth, sit, etc. This is a mandatory field.

##Link Files These files are an alternative to custom udev rules and will be applied by udev as the device appears. They have the following two sections:

###[Match]

  • MACAddress= : The MAC address.
  • Host= : The host name.
  • Virtualization= : Checks if it is running in a virtual environment.
  • Type= : the device type. For example: vlan.

###[Link]

  • MACAddressPolicy= : Persistent or random addresses.
  • MACAddress= : The MAC address. Note: The system /usr/lib/systemd/network/99-default.link file is sufficient for most cases.

##Debugging Systemd-networkd The log can be generated by creating a drop-in config. For example:

# /etc/systemd/system/systemd-networkd.service.d/override.conf
[Service]
Environment=SYSTEMD_LOG_LEVEL=debug

8.3.4 - Cloud-init

Cloud-init is mixture of Python and Shell scripts that initialize cloud instances of Linux machines. Cloud-init performs boot time configuration of a system. We can configure users, hostname, host network, write files to disk, manage packages, run custom scripts and so on.

##DataSources Datasource is the source of configuration data for cloud-init that is typically given by a user (For example: userdata) or obtained from the cloud that created the configuration drive (For example: metadata). Userdata includes files, YAML configuration files and shell scripts. Metadata includes server name, instance id, display name and other cloud specific details.

Currently there are two datasources used in Photon OS, it’s usage is described in the following sections:

  • DataSourceOVF - Used for GuestOS customization in vSphere.
  • VMwareGuestInfo - Used to read meta, user, and vendor data from VMware vSphere’s GuestInfo interface and initialize the system.

###DataSourceOVF The OVF (Open Virtualization Format) Datasource provides a datasource for reading data from an OVF transport ISO. The vmtoolsd service extracts the customization spec cab file from the OVF and calls either cloud-init or the GuestOS customization scripts. The disable_vmware_customization flag in /etc/cloud/cloud.cfg file determines if GOSC scripts or cloud-init is used.

  • disable_vmware_customization: false : Cloud-init is used for Guest OS customization
  • disable_vmware_customization: true : GuestOS customization scripts is used for Guest OS customization

Note: The default value for disable_vmware_customization is set to true in the /etc/cloud/cloud.cfg file

###VMwareGuestInfo VMwareGuestInfo data source is configured by setting guestinfo properties on a VM. This can be set by performing one of the following:

  • Using the vmware-rpctool provided by open-vmtools.
  • Modifying the vmx file to set the guestinfo properties.

##Debugging Cloud-init Failures Cloud-init has four services which are started in the following sequence:

  1. cloud-init-local - This service locates local data sources and applies networking configurations provided n the metadata (If there is no metadata it applies Fallback). Use $ systemctl status cloud-init-local command to check its status.
  2. cloud-init - This service processes any user-data that is found and runs the cloud_init_modules in /etc/cloud/cloud.cfg. Use $ systemctl status cloud-init command to check its status.
  3. cloud-config - This service runs the cloud_config_modules in /etc/cloud/cloud.cfg file. Use $ systemctl status cloud-config command to check its status.
  4. cloud-final - This service runs any script that a user is accustomed to running after logging into a system (For example: package installations, configs, user-scripts) and runs cloud_final_modules in /etc/cloud/cloud.cfg file. Use $ systemctl status cloud-final command to check its status.

Cloud-init logs are available in the /var/log/cloud-init.log file. Logs for GuestOS customization using DataSourceOVF are available in the /var/log/vmware-imc/toolsDeployPkg.log and /var/log/cloud-init.log files.

To analyze the cloud-init boot time performance, run the following commands:

  • $ cloud-init analyze blame - The blame command prints in descending order, the units that took the longest to run. This output is useful for observe where cloud-init is spending its time during execution.
  • $ cloud-init analyze show - The show command prints a list of units, the time they started and how long they took to complete. It also prints a summary of total time per boot.
  • $ cloud-init analyze dump - The dump command dumps the cloud-init logs for the analyze modules and displays a list of dictionaries that can be consumed for other reporting needs.
  • $ cloud-init status - To know the overall status of clouf-init.

Cloud-init doesn’t configure the network if /etc/cloud/cloud.cfg.d/99-disable-networking-config.cfg file is present and has the following content:

  • network:Item
  • config: disabled

Take a backup of /etc/cloud/cloud.cfg.d/99-disable-networking-config.cfg file and remove it from it’s location. Reconfigure the machine using metadata, userdata and vendordata. Once the configurations are done copy the backup file to the same location. Cloud-init will push it’s fallback configuration when service is restarted or rebooted and there is no local datasource to configure. To avoid this /etc/cloud/cloud.cfg.d/99-disable-networking-config.cfg file is required.

##Run Cloud-init Manually To run cloud-init manually, run the following commands:

/usr/bin/cloud-init -d init  (-d for debug)
/usr/bin/cloud-init -d modules (run all modules)
/usr/bin/cloud-init --file <config-yaml-file-path> init (if you want to run cloud-init with a configuration yaml file)

When cloud-init is running, to force it to run with all configs engaged run the following command:

rm -rf /var/lib/cloud/*

For more information about cloud-init, see https://cloudinit.readthedocs.io/en/latest/index.htmlhttps://cloudinit.readthedocs.io/en/latest/index.html

For more information about cloud-init CLI, see https://cloudinit.readthedocs.io/en/latest/topics/cli.htmlhttps://cloudinit.readthedocs.io/en/latest/topics/cli.html

Note:Include the cloud-init log tarball and the vmtoolsd logs when you raise an issue.

  1. Collect cloud-init log tarball by running the cloud-init collect-logs command.
  2. Collect the vmtoolsd logs from /var/log/vmware-imc/toolsDeployPkg.log file.
  3. Attach the collected logs to the issue ticket.

8.3.5 - Open-vm-tools/Vmtoolsd

Vmtoolsd is a systemd service, using which we can set guestinfo properties metadata, userdata and vendordata etc., which in turn are consumed by cloud-init. VMwareGuestInfo Datasource uses this guestinfo properties and applies them to the system.

vmware-rpctool is a utility provided by open-vm-tools to set metadata, userdata and vendordata. vmware-rpctool provides info.set and info.get options to set and get the guestinfo properties respectively.

##Debugging To check the status of the vmtoolsd service (vmtoolsd is dependant on vgauthd), run the following commands:

$ systemctl status vmtoolsd vgauthd

$ journalctl -u vmtoolsd

$ journalctl -u vgauthd

To set and get metadata, userdata and vendordata, run the following commands:

$ /usr/bin/vmware-rpctool 'info-get guestinfo.metadata'

$ /usr/bin/vmware-rpctool 'info-get guestinfo.userdata'

$ /usr/bin/vmware-rpctool 'info-get guestinfo.vendordata'

A YAML file can be used as input to the rpctool using following commands:

vmware-rpctool "info-set guestinfo.userdata.encoding base64"
vmware-rpctool "info-set guestinfo.metadata.encoding base64"

vmware-rpctool "info-set guestinfo.metadata ${metadata file contents}"

vmware-rpctool "info-set guestinfo.userdata ${userdata file contents}"

Note:Include the cloud-init log tarball and the vmtoolsd logs when you raise an issue.

  1. Collect cloud-init log tarball by running the cloud-init collect-logs command.
  2. Collect the vmtoolsd logs from /var/log/vmware-imc/toolsDeployPkg.log file.
  3. Attach the logs collected to the issue ticket.

8.3.6 - Secure Boot with FIPS

You can boot Photon 5 with FIPS either enabled or not enabled.

Booting without FIPS

When you boot Photon 5 with FIPS not enabled, the kernel log (dmesg) should contain messages in the following format:

[    0.343113] integrity: Loading X.509 certificate: UEFI:db
[    0.347625] integrity: Loaded X.509 cert 'VMware, Inc.: 4ad8ba0472073d28127706ddc6ccb9050441bbc7'
[    0.347626] integrity: Loading X.509 certificate: UEFI:db
[    0.347716] integrity: Loaded X.509 cert 'VMware, Inc.: VMware Secure Boot Signing: 04597f3e1ffb240bba0ff0f05d5eb05f3e15f6d7'
[    0.347716] integrity: Loading X.509 certificate: UEFI:db
[    0.347724] integrity: Loaded X.509 cert 'Microsoft Corporation UEFI CA 2011: 13adbf4309bd82709c8cd54f316ed522988a1bd4'
[    0.347724] integrity: Loading X.509 certificate: UEFI:db
[    0.347731] integrity: Loaded X.509 cert 'Microsoft Windows Production PCA 2011: a92902398e16c49778cd90f99e4f9ae17c55af53'

Booting with FIPS

When you boot Photon 5 with UEFI Secure Boot and FIPS is enabled, the kernel log (dmesg) should contain messages in the following format:

[ 0.736035] Loading compiled-in X.509 certificates
[ 0.792067] Loaded X.509 cert 'Build time autogenerated kernel key: c657689bcab17fee6288accb79f857def89a5851'
[ 0.792233] Loaded X.509 cert 'VMware, Inc.,O=VMware, Inc.,L=Palo Alto,S=California,C=US: 5f079edaaa7376133f045b9ad72997ddf3777858'
[ 0.792833] integrity: Loading X.509 certificate: UEFI:db
[ 0.792851] integrity: Problem loading X.509 certificate -22
[ 0.793030] integrity: Loading X.509 certificate: UEFI:db
[ 0.793193] integrity: Loaded X.509 cert 'VMware, Inc.: VMware Secure Boot Signing: 04597f3e1ffb240bba0ff0f05d5eb05f3e15f6d7'
[ 0.793194] integrity: Loading X.509 certificate: UEFI:db
[ 0.793216] integrity: Loaded X.509 cert 'Microsoft Corporation UEFI CA 2011: 13adbf4309bd82709c8cd54f316ed522988a1bd4'
[ 0.793217] integrity: Loading X.509 certificate: UEFI:db
[ 0.793236] integrity: Loaded X.509 cert 'Microsoft Windows Production PCA 2011: a92902398e16c49778cd90f99e4f9ae17c55af53'
[ 4.241463] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 4.242182] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'

You can safely ignore the error message for the first key ‘VMware, Inc.: 4ad8ba0472073d28127706ddc6ccb9050441bbc7’ because its replacement key ‘VMware, Inc.: VMware Secure Boot Signing: 04597f3e1ffb240bba0ff0f05d5eb05f3e15f6d7’ is already in place.

The error appears due to a change in the FIPS standard to 140-3 which enforces RSA public key exponent to be in a particular range.

8.4 - Troubleshooting Tools

Photon OS includes tools that help troubleshoot problems. These tools are installed by default on the full version of Photon OS. On the minimal version of Photon OS, you might have to install a tool before you can use it.

There is a man page on Photon OS for all the tools covered in this section. The man pages provide more information about each tool’s commands, options, and output. To view a tool’s man page, on the Photon OS command line, type man and then the name of the tool. Example:

man strace

8.4.1 - Common Tools

The following are some tools that you can use to troubleshoot:

Note: Some of the examples in this section are marked as abridged with ellipsis (...).

top

The top tool monitors system resources, workloads, and performance. It can unmask problems caused by processes or applications overconsuming CPUs, time, or RAM.

To view a textual display of resource consumption, run the top command:

top

Use can use ’top’ to kill a runaway or stalled process by typing k followed by its process ID (PID).

Top on Photon OS

If the percent of CPU utilization is consistently high with little idle time, there might be a runaway process overconsuming CPUs. Restarting the service might solve the problem.

To troubleshoot an unknown issue, run Top in the background in batch mode to write its output to a file and collect data about performance:

top d 120 b >> top120second.output

For a list of options that filter top output and other information, see the man page for top.

ps

The ps tool shows the processes running on the machine. The ps tool derives flexibility and power from its options, all of which are covered in the tool’s Photon OS man page:

man ps

You can use the following options of ps for troubleshooting:

  • Show processes by user: ps aux

  • Show processes and child processes by user: ps auxf

  • Show processes containing the string ssh: ps aux | grep ssh

  • Show processes and the command and options with which they were started: ps auxww

Example abridged output:

ps auxww
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.9  32724  3300 ?        Ss   07:51   0:32 /lib/systemd/systemd --switched-root --system --deserialize 22

netstat

The netstat command can identify bottlenecks causing performance issues. It lists network connections, listening sockets, port information, and interface statistics for different protocols. Examples:

netstat --statistics
netstat --listening

find

Use the find command to troubleshoot a Photon OS machine that has stopped working. The following command lists the files in the root directory that have changed in the past day:

find / -mtime -1 

See the find manual. Take note of the security considerations listed in the find manual if you are using find to troubleshoot an appliance running on Photon OS.

locate

The locate command is a fast way to find files and directories you onlay have a keyword. This command is similar to find and part of the same findutils package preinstalled on the full version of Photon OS by default. It finds file names in the file names database.

Before you can use locate accurately, update its database:

updatedb

Then run locate to quickly find a file, such as any file name containing .network, which can be helpful to see all the system’s .network configuration files. The following is an abridged example:

locate .network
/etc/dbus-1/system.d/org.freedesktop.network1.conf
/etc/systemd/network/10-dhcp-en.network
/usr/lib/systemd/network/80-container-host0.network
/usr/lib/systemd/network/80-container-ve.network
/usr/lib/systemd/system/busnames.target.wants/org.freedesktop.network1.busname
/usr/lib/systemd/system/dbus-org.freedesktop.network1.service
/usr/lib/systemd/system/org.freedesktop.network1.busnname
/usr/share/dbus-1/system-services/org.freedesktop.network1.service

The locate command is also a quick way to see whether a troubleshooting tool is installed on Photon OS. Examples:

locate strace
/usr/bin/strace
/usr/bin/strace-graph
/usr/bin/strace-log-merge
/usr/share/man/man1/strace.1.gz
/usr/share/vim/vim74/syntax/strace.vim

locate traceroute

In this example, the strace tool is installed but traceroute is not.

You can install traceroute from the Photon OS repository:

tdnf install traceroute

df

The df command reports the disk space available on the file system. Running out of disk space can lead an application to fail and a quick check of the available space makes sense as an early troubleshooting step:

df -h

The -h option prints out the available and used space in human-readable sizes. After checking the space, you should also check the number of available inodes. Too few available inodes can lead to difficult-to-diagnose problems:

df -i

md5sum

The md5sum tool calculates 128-bit RSA Data Security, Inc. MD5 Message Digest Algorithm hashes (a message digest, or digital signature, of a file) to uniquely identify a file and verify its integrity after file transfers, downloads, or disk errors when the security of the file is not in question.

md5sum can help troubleshooting installation issues by verifying that the version of Photon OS being installed matches the version on the public VMware Photon Packages download page. If, for instance, bytes were dropped during the download, the checksums will not match. Try downloading it again.

sha256sum

The sha256sum tool calculates the authenticity of a file to prevent tampering when security is a concern. Photon OS also includes shasum, sha1sum, sha384sum, and sha512sum. See the man pages for md3sum, sha256sum, and the other SHA utilities.

strace

The strace utility follows system calls and signals as they are executed so that you can see what an application, command, or process is doing. strace can trace failed commands, identify where a process obtains its configuration, monitor file activity, and find the location of a crash.

By tracing system calls, strace can help troubleshoot a broad range of problems, including issues with input-output, memory, interprocess communication, network usage, and application performance.

For troubleshooting a problem that gives off few or no clues, the following command displays every system call:

strace ls -al

With strace commands, you can route the output to a file to make it easier to analyze:

strace -o output.txt ls -al

strace can reveal the files that an application tries to open with the -eopen option. This combination can help troubleshoot an application that is failing because it is missing files or being denied access to a file it needs. If, for example, you see “No such file or directory” in the results of strace -eopen, something might be wrong:

strace -eopen sshd
open("/usr/lib/x86_64/libpam.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/libpam.so.0", O_RDONLY|O_CLOEXEC) = 3

The results above indicate that the first file is missing because it is found in the next line. In other cases, the application might be unable to open one of its configuration files or it might be reading the wrong one. If the results say “permission denied” for one of the files, check the permissions of the file with ls -l or stat.

When troubleshooting with strace, you can include the process ID in its commands. Here’s an example of how to find a process ID:

ps -ef | grep apache

You can then use strace to examine the file a process is working with:

strace -e trace=file -p 1719

A similar command can trace network traffic:

strace -p 812 -e trace=network

If an application is crashing, use strace to trace the application and then analyze what happens right before the application crashes.

You can also trace the child processes that an application spawns with the fork system call, and you can do so with systemctl commands that start a process to identify why an application crashes immediately or fails to start:

strace -f -o output.txt systemctl start httpd

Example: If journalctl is showing that networkd is failing, you can run strace to troubleshoot:

strace -o output.txt systemctl restart systemd-networkd

Then grep inside the results for something, such as exit or error:

grep exit output.txt

If the results indicate systemd-resolved is going wrong, you can then strace it:

strace -f -o output.txt systemctl restart systemd-resolved

file

The file command determines the file type, which can help troubleshoot problems when an application mistakes one type of file for another, leading it to errors. Example:

file /usr/sbin/sshd
/usr/sbin/sshd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, stripped

stat

The stat command can help troubleshoot problems with files or the file system by showing the last date it was modified and other information. Example:

stat /dev/sda1
File: '/dev/sda1'
Size: 0               Blocks: 0          IO Block: 4096   block special file
Device: 6h/6d   Inode: 6614        Links: 1     Device type: 8,1
Access: (0660/brw-rw----)  Uid: (    0/    root)   Gid: (    8/    disk)
Access: 2016-09-02 12:23:56.135999936 +0000
Modify: 2016-09-02 12:23:52.879999981 +0000
Change: 2016-09-02 12:23:52.879999981 +0000
Birth: -

On Photon OS, stat is handy to show permissions for a file or directory in both their absolute octal notation and their read-write-execute abbreviation; truncated example:

chmod 777 tester.md
stat tester.md
	File: 'tester.md'
	Size: 0               Blocks: 0          IO Block: 4096   regular empty file
	Device: 801h/2049d      Inode: 316385      Links: 1
	Access: (0777/-rwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)

watch

The watch utility runs a command at regular intervals so you can observe how its output changes over time. watch can help dynamically monitor network links, routes, and other information when you are troubleshooting networking or performance issues. Examples:

watch -n0 --differences ss
watch -n1 --differences ip route

The following is an example with a screenshot of the output. This command monitors the traffic on your network links. The highlighted numbers are updated every second so you can see the traffic fluctuating:

watch -n1 --differences ip -s link show up

The dynamic output of the watch utility

vmstat and fdisk

The vmstat tool displays statistics about virtual memory, processes, block input-output, disks, and CPU activity. This tool can help diagnose performance problems, especially system bottlenecks.

Its output on a Photon OS virtual machine running in VMware Workstation 12 Pro without a heavy load looks like this:

vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
	r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
	0  0      0   5980  72084 172488    0    0    27    44  106  294  1  0 98  1  0

These codes are explained in the vmstat man page.

  • If r, the number of runnable processes, is higher than 10, the machine is under stress; consider intervening to reduce the number of processes or to distribute some of the processes to other machines. In other words, the machine has a bottleneck in executing processes.
  • If cs, the number of context switches per second, is really high, there may be too many jobs running on the machine.
  • If in, the number of interrupts per second, is relatively high, there might be a bottleneck for network or disk IO.

You can investigate disk IO further by using vmstat’s -d option to report disk statistics. The following is an abridged example on a machine with little load:

vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
		total merged sectors      ms  total merged sectors      ms    cur    sec
ram0       0      0       0       0      0      0       0       0      0      0
ram1       0      0       0       0      0      0       0       0      0      0
loop0      0      0       0       0      0      0       0       0      0      0
loop1      0      0       0       0      0      0       0       0      0      0
sr0        0      0       0       0      0      0       0       0      0      0
sda    22744    676  470604   12908  72888  24949  805224  127692      0    130

The -D option summarizes disk statistics:

vmstat -D
    26 	disks
     2	partitions
 22744 	total reads
   676 	merged reads
470604  read sectors
 12908 	milli reading
 73040 	writes
 25001 	merged writes
806872  written sectors
127808  milli writing
     0	inprogress IO
   130 	milli spent IO

You can also get statistics about a partition. First, run the fdisk -l command to list the machine’s devices. Then run vmstat -p with the name of a device to view its stats:

fdisk -l
Disk /dev/ram0: 4 MiB, 4194304 bytes, 8192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
...
Device        Start      End  Sectors Size Type
/dev/sda1      2048 16771071 16769024   8G Linux filesystem
/dev/sda2  16771072 16777182     6111   3M BIOS boot

vmstat -p /dev/sda1
sda1          reads   read sectors  writes    requested writes
				22579     473306      78510     866088

See the vmstat man page for more options.

lsof

The lsof command lists open files. The tool’s definition of an open file includes directories, libraries, streams, domain sockets, and Internet sockets. THis enables it to identify the files a process is using. Because a Linux system like Photon OS uses files to do its work, you can run lsof as root to see how the system is using them and to see how an application works.

If you cannot unmount a disk because it is in use, you can run lsof to identify the files on the disk that are being used.

The following is an example that shows the processes that are using the root directory:

lsof /root
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
bash       879 root  cwd    DIR    8,1     4096 262159 /root
bash      1265 root  cwd    DIR    8,1     4096 262159 /root
sftp-serv 1326 root  cwd    DIR    8,1     4096 262159 /root
gdb       1351 root  cwd    DIR    8,1     4096 262159 /root
bash      1395 root  cwd    DIR    8,1     4096 262159 /root
lsof      1730 root  cwd    DIR    8,1     4096 262159 /root

You can do the same with an application or virtual appliance by running lsof with the user name or process ID of the app. The following example lists the open files used by the Apache HTTP Server:

lsof -u apache

Running the command with the -i option lists all the open network and Internet files, which can help troubleshoot network problems:

lsof -i

See the Unix socket addresses of a user like zookeeper:

lsof -u zookeeper -U

The following example shows the processes running on Ports 1 through 80:

lsof -i TCP:1-80
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd    403   root    3u  IPv6  10733      0t0  TCP *:http (LISTEN)
httpd    407 apache    3u  IPv6  10733      0t0  TCP *:http (LISTEN)
httpd    408 apache    3u  IPv6  10733      0t0  TCP *:http (LISTEN)
httpd    409 apache    3u  IPv6  10733      0t0  TCP *:http (LISTEN)
sshd     820   root    3u  IPv4  11336      0t0  TCP *:ssh (LISTEN)
sshd     820   root    4u  IPv6  11343      0t0  TCP *:ssh (LISTEN)
sshd    1258   root    3u  IPv4  48040      0t0  TCP 198.51.100.143:ssh->198.51.100.1:49759 (ESTABLISHED)
sshd    1319   root    3u  IPv4  50866      0t0  TCP 198.51.100.143:ssh->198.51.100.1:51054 (ESTABLISHED)
sshd    1388   root    3u  IPv4  56438      0t0  TCP 198.51.100.143:ssh->198.51.100.1:60335 (ESTABLISHED)

You can also inspect the files opened by a process ID. The following example queries the files open by the systemd network service:

lsof -p 1917
COMMAND    PID            USER   FD      TYPE             DEVICE SIZE/OFF   NODE NAME
systemd-n 1917 systemd-network  cwd       DIR                8,1     4096      2 /
systemd-n 1917 systemd-network  txt       REG                8,1   887896 272389 /usr/lib/systemd/systemd-networkd
systemd-n 1917 systemd-network  mem       REG                8,1   270680 262267 /usr/lib/libnss_files-2.22.so
systemd-n 1917 systemd-network    0r      CHR                1,3      0t0   5959 /dev/null
systemd-n 1917 systemd-network    1u     unix 0x0000000000000000      0t0  45734 type=STREAM
systemd-n 1917 systemd-network    3u  netlink                         0t0   6867 ROUTE
systemd-n 1917 systemd-network    4u     unix 0x0000000000000000      0t0  45744 type=DGRAM
systemd-n 1917 systemd-network    9u  netlink                         0t0  45754 KOBJECT_UEVENT
systemd-n 1917 systemd-network   12u  a_inode               0,11        0   5955 [timerfd]
systemd-n 1917 systemd-network   13u     IPv4             104292      0t0    UDP 198.51.100.143:bootpc

fuser

The fuser command identifies the process IDs of processes using files or sockets. The term process is, in this case, synonymous with user. To identify the process ID of a process using a socket, run fuser with its namespace option and specify tcp or udp and the name of the process or port. Examples:

fuser -n tcp ssh
ssh/tcp:               940  1308
fuser -n tcp http
http/tcp:              592   594   595   596
fuser -n tcp 80
80/tcp:                592   594   595   596

ldd

By revealing the shared libraries that a program depends on, ldd can help troubleshoot an application that is missing a library or finding the wrong one.

For example, if you get a “file not found” output, check the path to the library.

ldd /usr/sbin/sshd
linux-vdso.so.1 (0x00007ffc0e3e3000)
libpam.so.0 => (file not found)
libcrypto.so.1.0.0 => /usr/lib/libcrypto.so.1.0.0 (0x00007f624e570000)

You can also use the objdump command to show dependencies for a program’s object files; example:

objdump -p /usr/sbin/sshd | grep NEEDED

gdb

The gdb tool is the GNU debugger. It lets you see inside a program while it executes or when it crashes so that you can catch errors as they occur. The gdb tool is typically used to debug programs written in C and C++. On Photon OS, gdb can help you determine why an application crashed. See the man page for gdb for instructions on how to run it.

For an extensive example on how to use gdb to troubleshoot Photon OS running on a VM when you cannot login to Photon OS, see the section on troubleshooting boot and logon problems.

8.4.2 - Troubleshooting Tools Installed by Default

The following troubleshooting tools are included in the full version of Photon OS:

  • grep. Searches files for patterns.
  • ping. Tests network connectivity.
  • strings. Displays the characters in a file to identify its contents.
  • lsmod. Lists loaded modules.
  • ipcs. Shows data about the inter-process communication (IPC) resources to which a process has read access. This data includes shared memory segments, message queues, and semaphore arrays.
  • nm. Lists symbols from object files.
  • diff. Compares files side by side. This tool is useful to compare configuration files of two versions when one version works and the other does not.

8.4.3 - Installing Tools from Repositories

You can install several troubleshooting tools from the Photon OS repositories by using the default package management system, tdnf.

If a tool you require is not installed, search the repositories to see if it is available.

For example, the traceroute tool is not installed by default. You can search for it in the repositories as follows:

tdnf search traceroute
traceroute : Traces the route taken by packets over an IPv4/IPv6 network

The results of the above command show that traceroute exists in the repository. You install it with tdnf:

tdnf install traceroute

The following tools are not installed by default but are in the repository and can be installed with tdnf:

  • net-tools. Networking tools.

  • ltrace. Tool for intercepting and recording dynamic library calls. It can identify the function an application was calling when it crashed, making it useful for debugging.

  • nfs-utils. Client tools for the kernel Network File System, or NFS, including showmount. These are installed by default in the full version of Photon OS but not in the minimal version.

  • pcstat. A tool that inspects which pages of a file or files are being cached by the Linux kernel.

  • sysstat and sar. Utilities to monitor system performance and usage activity. Installing sysstat also installs sar.

  • systemtap and crash. The systemtap utility is a programmable instrumentation system for diagnosing problems of performance or function. Installing systemtap also installs crash, which is a kernel crash analysis utility for live systems and dump files.

  • dstat. Tool for viewing and analyzing statistics about system resources.

    The dstat tool can help troubleshoot system performance. The tool shows live, running list of statistics about system resources:

      dstat
      You did not select any stats, using -cdngy by default.
      ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
      usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
        1   0  98   1   0   0|4036B   42k|   0     0 |   0     0 |  95   276
        1   0  98   1   0   0|   0    64k|  60B  940B|   0     0 | 142   320
        1   1  98   0   0   0|   0    52k|  60B  476B|   0     0 | 149   385
    

8.4.4 - Linux Troubleshooting Tools

The following Linux troubleshoot tools are neither installed on Photon OS by default nor available in the Photon OS repositories:

  • iostat
  • telnet (use SSH instead)
  • Iprm
  • hdparm
  • syslog (use journalctl instead)
  • ddd
  • ksysmoops
  • xev
  • GUI tools (because Photon OS has no GUI)

8.5 - Systemd

Photon OS manages services with systemd and systemctl, its command-line utility for inspecting and controlling the system. It does not use the deprecated commands of init.d.

Basic system administration commands on Photon OS differ from those on operating systems that use SysVinit. Since Photon OS uses systemd instead of SysVinit, you must use systemd commands to manage services.

For example, instead of running the /etc/init.d/ssh script to stop and start the OpenSSH server on a init.d-based Linux system, you control the service by running the following systemctl commands on Photon OS:

systemctl stop sshd
systemctl start sshd

For an overview of systemd, see systemd System and Service Manager and the man page for systemd. The systemd man pages are listed at https://www.freedesktop.org/software/systemd/man/.

8.5.1 - Enabling 'systemd' Debug Shell During Boot

To diagnose systemd related boot issues, you can enable early shell access during boot.

Perform the following steps to enable early shell access:

  1. Restart the Photon OS machine or the virtual machine running Photon OS.

    When the Photon OS splash screen appears, as it restarts, type the letter e quickly.

  2. Append systemd.debug-shell=1 to the kernel command line.

    Optionally, to change logging level to debug, you can append systemd.log_level=debug.

  3. Press F10 to proceed with the boot.

  4. Press Alt+Ctrl+F9 to switch to tty9 to access the debug shell.

8.5.2 - Troubleshooting Services With 'systemctl'

To view a description of all the active, loaded units, execute the systemctl command without any options or arguments:

systemctl

To see all the loaded, active, and inactive units and their description, run this command:

systemctl --all

To see all the unit files and their current status but no description, run this command:

systemctl list-unit-files

The grep command filters the services by a search term, a helpful tactic to recall the exact name of a unit file without looking through a long list of names. Example:

systemctl list-unit-files | grep network
org.freedesktop.network1.busname           static
dbus-org.freedesktop.network1.service      enabled
systemd-networkd-wait-online.service       enabled
systemd-networkd.service                   enabled
systemd-networkd.socket                    enabled
network-online.target                      static
network-pre.target                         static
network.target  

For example, to list all the services that you can manage on Photon OS, you run the following command instead of ls /etc/rc.d/init.d/:

systemctl list-unit-files --type=service

Similarly, to check whether the sshd service is enabled, on Photon OS you run the following command instead of chkconfig sshd:

systemctl is-enabled sshd

The chkconfig --list command that shows which services are enabled for which runlevel on a SysVinit computer becomes substantially different on Photon OS because there are no runlevels, only targets:

ls /etc/systemd/system/*.wants

You can also display similar information with the following command:

systemctl list-unit-files --type=service

The following is list of some of the systemd commands that take the place of SysVinit commands on Photon OS:

USE THIS SYSTEMD COMMAND 	INSTEAD OF THIS SYSVINIT COMMAND
systemctl start sshd 		service sshd start
systemctl stop sshd 		service sshd stop
systemctl restart sshd 		service sshd restart
systemctl reload sshd 		service sshd reload
systemctl condrestart sshd 	service sshd condrestart
systemctl status sshd 		service sshd status
systemctl enable sshd 		chkconfig sshd on
systemctl disable sshd 		chkconfig sshd off
systemctl daemon-reload		chkconfig sshd --add

8.5.3 - Analyzing System Logs with 'journalctl'

The journalctl tool queries the contents of the systemd journal. On Photon OS, all the system logs except the installation log and the cloud-init log are written into the systemd journal.

When you run the journalctl command without any parameters, it displays all the contents of the journal, beginning with the oldest entry.

To display the output in reverse order with new entries first, include the -r option in the command:

journalctl -r

The journalctl command includes many options to filter its output. For help troubleshooting systemd, two journalctl queries are particularly useful:

  • Showing the log entries for the last boot.

    The following command displays the messages that systemd generated during the last time the machine started:

journalctl -b
  • Showing the log entries for a systemd service unit.Item

    The following command reveals the messages for only the systemd service unit specified by the -u option, which in the following example is the auditing service:

journalctl -u auditd

You can look at the messages for systemd itself or for the network service:

journalctl -u systemd
journalctl -u systemd-networkd

Example:

root@photon-1a0375a0392e [ ~ ]# journalctl -u systemd-networkd
-- Logs begin at Tue 2016-08-23 14:35:50 UTC, end at Tue 2016-08-23 23:45:44 UTC. --
Aug 23 14:35:52 photon-1a0375a0392e systemd[1]: Starting Network Service...
Aug 23 14:35:52 photon-1a0375a0392e systemd-networkd[458]: Enumeration completed
Aug 23 14:35:52 photon-1a0375a0392e systemd[1]: Started Network Service.
Aug 23 14:35:52 photon-1a0375a0392e systemd-networkd[458]: eth0: Gained carrier
Aug 23 14:35:53 photon-1a0375a0392e systemd-networkd[458]: eth0: DHCPv4 address 198.51.100.1
Aug 23 14:35:54 photon-1a0375a0392e systemd-networkd[458]: eth0: Gained IPv6LL
Aug 23 14:35:54 photon-1a0375a0392e systemd-networkd[458]: eth0: Configured

For more information, see journalctl or the journalctl man page by running this command: man journalctl

8.5.4 - Inspecting Services with 'systemd-analyze'

The systemd-analyze command reveals performance statistics for boot times, traces system services, and verifies unit files. It can help troubleshoot slow system boots and incorrect unit files. See the man page for a list of options.

Examples:

systemd-analyze blame

systemd-analyze dump

8.5.5 - Inspecting Services with 'systemd-analyze'

systemd is a suite of basic building blocks for a Linux system. It provides a system and service manager that runs as Process ID 1 and starts the rest of the system.

To manage the services run the following commands:

  • systemctl or systemctl list-units : This command lists the running units.
  • systemctl --failed : This command lists failed units.
  • systemctl list-unit-files : This command lists all the installed unit files. The unit files are usually present in /usr/lib/systemd/system/ and /etc/systemd/system/.
  • systemctl status pid : This command displays the cgroup slice, memory and parent for a PID.
  • systemctl start unit : This command starts a unit immediately.
  • systemctl stop unit : This command stops a unit.
  • systemctl restart unit : This command restarts a unit.
  • systemctl reload unit : This command asks a unit to reload its configuration.
  • systemctl status unit : This command displays the status of a unit.
  • systemctl enable unit : This command enables a unit to run on startup.
  • systemctl enable --now unit : This command enables a unit to run on startup and start immediately.
  • systemctl disable unit : This command disables a unit and removes it from the startup program.
  • systemctl mask unit : This command masks a unit to make it impossible to start.
  • systemctl unmask unit : This command unmasks a unit.

To get an overview of the system boot-up time, run the following command:

systemd-analyze

To view a list of all running units, sorted by the time they took to initialize (highest time on top), run the following command:

systemd-analyze blame

8.6 - Network Troubleshooting

Use the systemd suite of commands and not deprecated init.d commands or other deprecated commands, to manage networking.

For information about tcpdump and netcat, see Installing the Packages for tcpdump and netcat with tdnf

8.6.1 - Managing the Network Configuration

The network service, which is enabled by default, starts when the system boots. You manage the network service by using systemd commands, such as systemd-networkd, systemd-resolvd, and networkctl.

You can check the status of the network service by running the following command:

systemctl status systemd-networkd

The following is a result of the command:

* systemd-networkd.service - Network Service
   Loaded: loaded (/usr/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2016-04-29 15:08:51 UTC; 6 days ago
     Docs: man:systemd-networkd.service(8)
 Main PID: 291 (systemd-network)
   Status: "Processing requests..."
   CGroup: /system.slice/systemd-networkd.service
           `-291 /lib/systemd/systemd-networkd

8.6.2 - Inspecting IP Addresses

VMware recommends that you use the ip or ss commands as the ifconfig and netstat commands are deprecated.

To display a list of network interfaces, run the ss command. Similarly, to display information for IP addresses, run the ip addr command.

Examples:

USE THIS IPROUTE COMMAND 	INSTEAD OF THIS NET-TOOL COMMAND
ip addr 					ifconfig -a
ss 							netstat
ip route 					route
ip maddr 					netstat -g
ip link set eth0 up 		ifconfig eth0 up
ip -s neigh					arp -v
ip link set eth0 mtu 9000	ifconfig eth0 mtu 9000

Use the ip route version of a command instead of the net-tools to get accurate information:

ip neigh
198.51.100.2 dev eth0 lladdr 00:50:56:e2:02:0f STALE
198.51.100.254 dev eth0 lladdr 00:50:56:e7:13:d9 STALE
198.51.100.1 dev eth0 lladdr 00:50:56:c0:00:08 DELAY

arp -a
? (198.51.100.2) at 00:50:56:e2:02:0f [ether] on eth0
? (198.51.100.254) at 00:50:56:e7:13:d9 [ether] on eth0
? (198.51.100.1) at 00:50:56:c0:00:08 [ether] on eth0

Important: If you modify an IPv6 configuration or add an IPv6 interface, you must restart systemd-networkd. Traditional methods of using ifconfig commands will be inadequate to register the changes. Run the following command instead:

systemctl restart systemd-networkd

8.6.3 - Inspecting the Status of Network Links with 'networkctl'

The networkctl command displays information about network connections that helps you configure networking services and troubleshoot networking problems.

You can progressively add options and arguments to the networkctl command to move from general information about network connections to specific information about a network connection.

Running networkctl without options defaults to the list command:

networkctl
IDX LINK             TYPE               OPERATIONAL SETUP
  1 lo               loopback           carrier     unmanaged
  2 eth0             ether              routable    configured
  3 docker0          ether              routable    unmanaged
 11 vethb0aa7a6      ether              degraded    unmanaged
 4 links listed.

Run the networkctl with the status command to display active network links with IP addresses for not only the Ethernet connection, but also the Docker container.

root@photon-rc [ ~ ]# networkctl status
*      State: routable
     Address: 198.51.100.131 on eth0
              172.17.0.1 on docker0
              fe80::20c:29ff:fe55:3ca6 on eth0
              fe80::42:f0ff:fef7:bd81 on docker0
              fe80::4c84:caff:fe76:a23f on vethb0aa7a6
     Gateway: 198.51.100.2 on eth0
         DNS: 198.51.100.2

You can add a network link, such as the Ethernet connection, as the argument of the status command to show specific information about the link:

root@photon-rc [ ~ ]# networkctl status eth0
* 2: eth0
       Link File: /usr/lib/systemd/network/99-default.link
    Network File: /etc/systemd/network/10-dhcp-en.network
            Type: ether
           State: routable (configured)
            Path: pci-0000:02:01.0
          Driver: e1000
      HW Address: 00:0c:29:55:3c:a6 (VMware, Inc.)
             MTU: 1500
         Address: 198.51.100.131
                  fe80::20c:29ff:fe55:3ca6
         Gateway: 198.51.100.2
             DNS: 198.51.100.2
        CLIENTID: ffb6220feb00020000ab116724f520a0a77337

You can add a Docker container as follows:

networkctl status docker0
* 3: docker0
       Link File: /usr/lib/systemd/network/99-default.link
    Network File: n/a
            Type: ether
           State: routable (unmanaged)
          Driver: bridge
      HW Address: 02:42:f0:f7:bd:81
             MTU: 1500
         Address: 172.17.0.1
                  fe80::42:f0ff:fef7:bd81

In the example above, the output indicates that state of the Docker container is unmanaged. Docker uses the bridge drive to handle managing the networking for the containers and not systemd-resolved or systemd-networkd.

For more information about networkctl commands and options, see https://www.freedesktop.org/software/systemd/man/networkctl.html.

8.6.4 - Network Debugging

You can set systemd-networkd to work in debug mode so that you can analyze log files with debugging information to help troubleshoot networking problems.

The following procedure turns on network debugging by adding a drop-in file in /etc/systemd to customize the default systemd configuration in /usr/lib/systemd.

  1. Run the following command as root to create a directory with this exact name, including the .d extension:

    mkdir -p /etc/systemd/system/systemd-networkd.service.d/
    
  2. Run the following command as root to establish a systemd drop-in unit with a debugging configuration for the network service:

    cat > /etc/systemd/system/systemd-networkd.service.d/10-loglevel-debug.conf << "EOF"
    \[Service\]
    Environment=SYSTEMD_LOG_LEVEL=debug
    EOF
    
  3. Reload the systemctl daemon and restart the systemd-networkd service for the changes to take effect:

    systemctl daemon-reload
    systemctl restart systemd-networkd
    
  4. Verify that your changes took effect:

    systemd-delta --type=extended
    
  5. View the log files by running this command:

    journalctl -u systemd-networkd
    
  6. After debugging the network connections, turn debugging off by deleting the drop-in file:

    rm /etc/systemd/system/systemd-networkd.service.d/10-loglevel-debug.conf
    

8.6.5 - Checking Firewall Rules

The design of Photon OS emphasizes security. On the minimal and full versions of Photon OS, the default security policy turns on the firewall and drops packets from external interfaces and applications. As a result, you might need to add rules to iptables to permit forwarding, allow protocols like HTTP, and open ports. In other words, you must configure the firewall for your applications and requirements.

The default iptables settings on the full version look like this:

iptables --list
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

To find out how to adjust the settings, see the man page for iptables.

Although the default iptables policy accepts SSH connections, the sshd configuration file on the full version of Photon OS is set to reject SSH connections. See Permitting Root Login with SSH.

If you are unable to ping a Photon OS machine, check the firewall rules. Verify if the rules allow connectivity for the port and protocol.

You can supplement the iptables commands by using lsof to, for instance, see the processes listening on ports:

	lsof -i -P -n

8.6.6 - Inspect Network Settings with 'netmgr'

If you are running a VMware appliance on Photon OS and the VAMI module has problems or if there are networking issues, you can use the Photon OS netmgr utility to inspect the networking settings. Make sure that the IP addresses for the DNS server and other infrastructure are correct. Use tcpdump to analyze the issues.

The error code that you get from netmgr is a standard Unix error code. Enter it into a search engine to obtain more information on the error.

8.7 - File System Troubleshooting

Photon OS includes commands to check and troubleshoot file systems.

8.7.1 - Checking Disk Space

One of the first simple steps to take while troubleshooting is to check how much disk space is available by running the df command:

df -h

8.7.2 - Adding a Disk and Partitioning It

If the df command shows that the file system is indeed nearing capacity, you can add a new disk on the fly and partition it to increase capacity.

  1. Add a new disk.

    For example, you can add a new disk to a virtual machine by using the VMware vSphere Client. After adding a new disk, check for the new disk by using fdisk. In the following example, the new disk is named /dev/sdb:

    fdisk -l
    Device        Start      End  Sectors Size Type
    /dev/sda1      2048 16771071 16769024   8G Linux filesystem
    /dev/sda2  16771072 16777182     6111   3M BIOS boot
    
    Disk /dev/sdb: 1 GiB, 1073741824 bytes, 2097152 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    
  2. Partition it with the parted wizard.

    The command to partition the disk on Photon OS is as follows:

    parted /dev/sdb
    

    Use the parted wizard to create it as follows:

    mklabel gpt
    mkpart ext3 1 1024
    
  3. Create a file system on the partition:

    mkfs -t ext3 /dev/sdb1
    
  4. Make a directory where you will mount the new file system:

    mkdir /newdata
    
  5. Open /etc/fstab and add the new file system with the options that you require:

    #system mnt-pt  type    options dump    fsck
    /dev/sda1       /       ext4    defaults,barrier,noatime,noacl,data=ord$
    /dev/cdrom      /mnt/cdrom      iso9660 ro,noauto       0       0
    /dev/sdb1       /newdata        ext3    defaults        0		0
    
  6. Mount it using the following command:

    mount /newdata
    

    Verify the results:

    df -h
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/root       7.8G  4.4G  3.1G  59% /
    devtmpfs        172M     0  172M   0% /dev
    tmpfs           173M     0  173M   0% /dev/shm
    tmpfs           173M  664K  172M   1% /run
    tmpfs           173M     0  173M   0% /sys/fs/cgroup
    tmpfs           173M   36K  173M   1% /tmp
    tmpfs            35M     0   35M   0% /run/user/0
    /dev/sdb1       945M  1.3M  895M   1% /newdata
    

8.7.3 - Expanding Disk Partition

If you require more space, you can expand the last partition of your disk after resizing the disk.

The commands in this section assume sda as disk device.

  1. After the disk is resized in the virtual machine, use the following command to enable the system to recognize the new disk ending boundary without rebooting:
echo 1 > /sys/class/block/sda/device/rescan
  1. Install the parted package to resize the disk partition by running the following command to install it:
tdnf install parted.
parted /dev/sda

GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
  1. List all partitions available to fix the GPT and check the last partition number:
(parted) print

Warning: Not all of the space available to /dev/sda appears to be used, you can
fix the GPT to use all of the space (an extra 4194304 blocks) or continue with
the current setting? 
Fix/Ignore?

Press `f` to fix the GPT layout.

Model: VMware Virtual disk (scsi)
Disk /dev/sda: 34.4GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name  Flags
1      1049kB  3146kB  2097kB                     bios_grub
2      3146kB  8590MB  8587MB  ext4

In this case we have the partition 2 as last, then we extend the partition to 100% of the remaining size:

(parted) resizepart 2 100%
  1. Expand the filesystem to the new size:
resize2fs /dev/sda2
	resize2fs 1.42.13 (17-May-2015)
	Filesystem at /dev/sda2 is mounted on /; on-line resizing required
	old_desc_blocks = 1, new_desc_blocks = 2
	The filesystem on /dev/sda2 is now 8387835 (4k) blocks long.

The new space is already available in the system:

df -h
	Filesystem      Size  Used Avail Use% Mounted on
	/dev/root        32G  412M   30G   2% /
	devtmpfs       1001M     0 1001M   0% /dev
	tmpfs          1003M     0 1003M   0% /dev/shm
	tmpfs          1003M  252K 1003M   1% /run
	tmpfs          1003M     0 1003M   0% /sys/fs/cgroup
	tmpfs          1003M     0 1003M   0% /tmp
	tmpfs           201M     0  201M   0% /run/user/0

8.7.4 - List Disk Partitions with 'fdisk'

The fdisk command manipulates the disk partition table. You can, for example, use fdisk to list the disk partitions so that you can identify the root Linux file system.

The following example shows /dev/sda1 to be the root Linux partition:

fdisk -l
	Disk /dev/ram0: 4 MiB, 4194304 bytes, 8192 sectors
	Units: sectors of 1 * 512 = 512 bytes
	Sector size (logical/physical): 512 bytes / 4096 bytes
	I/O size (minimum/optimal): 4096 bytes / 4096 bytes

	...
	
	Disk /dev/sda: 8 GiB, 8589934592 bytes, 16777216 sectors
	Units: sectors of 1 * 512 = 512 bytes
	Sector size (logical/physical): 512 bytes / 512 bytes
	I/O size (minimum/optimal): 512 bytes / 512 bytes
	Disklabel type: gpt
	Disk identifier: 3CFA568B-2C89-4290-8B52-548732A3972D

	Device        Start      End  Sectors Size Type
	/dev/sda1      2048 16771071 16769024   8G Linux filesystem
	/dev/sda2  16771072 16777182     6111   3M BIOS boot

8.7.5 - File System Consistency Check Tool

You can manually check the file system by using the file system consistency check tool, fsck, after you unmount the file system.

The Photon OS file system includes btrfs and ext4. The default root file system is ext4, which you can see by looking at the file system configuration file, /etc/fstab:

cat /etc/fstab
	#system mnt-pt  type    options dump    fsck
	/dev/sda1       /       ext4    defaults,barrier,noatime,noacl,data=ordered     1       1
	/dev/cdrom      /mnt/cdrom      iso9660 ro,noauto       0       0

The 1 in the fifth column, under fsck, indicates that fsck checks the file system when the system boots.

You can also perform a read-only check without unmounting it:

fsck -nf /dev/sda1
	fsck from util-linux 2.27.1
	e2fsck 1.42.13 (17-May-2015)
	Warning!  /dev/sda1 is mounted.
	Warning: skipping journal recovery because doing a read-only filesystem check.
	Pass 1: Checking inodes, blocks, and sizes
	Pass 2: Checking directory structure
	Pass 3: Checking directory connectivity
	Pass 4: Checking reference counts
	Pass 5: Checking group summary information
	Free blocks count wrong (1439651, counted=1423942).
	Fix? no
	Free inodes count wrong (428404, counted=428397).
	Fix? no
	/dev/sda1: 95884/524288 files (0.3% non-contiguous), 656477/2096128 blocks

The inodes count might be wrong because the file system is mounted and in use.

To fix errors, you must first unmount the file system and then run fsck again:

umount /dev/sda1
umount: /: target is busy

You can find information about processes that use the device by using lsof or fuser.

lsof | grep ^jbd2/sd
	jbd2/sda1   99                root  cwd       DIR                8,1     4096          2 /
	jbd2/sda1   99                root  rtd       DIR                8,1     4096          2 /
	jbd2/sda1   99                root  txt   unknown                                        /proc/99/exe

The above example indicates that file system is in use.

8.7.6 - Fixing File System Errors When fsck Fails

Sometimes when fsck runs during startup, it encounters an error that prevents the system from fully booting until you fix the issue by running fsck manually. This error might occur when Photon OS is the operating system for a VM running an appliance.

If fsck fails when the computer boots and an error message says to run fsck manually, you can troubleshoot by restarting the VM, altering the GRUB edit menu to enter emergency mode before Photon OS fully boots, and running fsck.

Perform the following steps:

  1. Take a snapshot of the virtual machine.

  2. Restart the virtual machine running Photon OS.

    When the Photon OS splash screen appears as it restarts, type the letter e quickly to go to the GNU GRUB edit menu.

    Note: You must type e quickly as Photon OS reboots quickly. Also, in VMware vSphere or VMware Workstation Pro, you might have to give the console focus by clicking in its window before it will register input from the keyboard.

  3. In the GNU GRUB edit menu, go to the end of the line that starts with linux, add a space, and then add the following code exactly as it appears below:

    systemd.unit=emergency.target

  4. Type F10.

  5. In the bash shell, run one of the following commands to fix the file system errors, depending on whether sda1 or sda2 represents the root file system:

    e2fsck -y /dev/sda1

    or

    e2fsck -y /dev/sda2

  6. Restart the virtual machine. If the virtual machine fails to boot and finds any error then follow the steps below to recover.

  7. Log in to the root shell: Command>shell root@vc701-w4#

  8. To know about the error, execute the following command: journalctl -b 0 | grep -i “failed to start”

    Below is output of above command:

Output for the journalctl -b 0 | grep -i “failed to start” command

  1. Referring to the Failed to start the file system check on /dev/log_vg/log error in the screenshot above, if the partition type is logical volume, then the device mapper modules create a device-special file /dev/dm-X to which symbolic links with the original names points to /dev/mapper/log_vg-log or /dev/log_vg/log. Here log_vg is volume group and log is logical volume name.

  2. Execute the lsblk command to confirm the device type. Below is the output of lsblk command. Here log_vg-log is associated with the device sde and type lvm. Also, note that it is not mounted.

lsblk command output

  1. Execute the following command to fix the file system errors: e2fsck /dev/log_vg/log

  2. Restart the virtual machine.

8.8 - Troubleshooting Packages

On Photon OS, tdnf is the default package manager. The standard syntax for tdnf commands is the same as that for DNF and Yum:

tdnf [options] <command> [<arguments>...]

The main configuration files reside in /etc/tdnf/tdnf.conf. The repositories appear in /etc/yum.repos.d/ with .repo file extensions. For more information, see the Photon OS Administration Guide.

The cache files for data and metadata reside in /var/cache/tdnf. The local cache is populated with data from the repository:

ls -l /var/cache/tdnf/photon
total 8
-r--r--r-- 1 root root    0 Apr 20 13:32 lastrefresh
drwxr-xr-x 2 root root 4096 Apr 20 13:32 repodata
drwxr-xr-x 2 root root 4096 Apr 20 13:32 solvcache

You can clear the cache to help troubleshoot a problem, but doing so might slow the performance of tdnf until the cache becomes repopulated with data. Cleaning the cache can remove stale information. Clear the cache as follows:

tdnf clean all
cleaning photon-iso: metadata dbcache packages keys expire-cache
cleaning photon-release: metadata dbcache packages keys expire-cache
cleaning photon-updates: metadata dbcache packages keys expire-cache
cleaning photon: metadata dbcache packages keys expire-cache
cleaning photon-debuginfo: metadata dbcache packages keys expire-cache
cleaning photon-srpms: metadata dbcache packages keys expire-cache
Done.

Some tdnf commands can help you troubleshoot problems with packages:

  • makecache

    This command updates the cached binary metadata for all known repositories. You can run it after you clean the cache to make sure you are working with the latest repository data as you troubleshoot.

    Example:

    tdnf makecache
    Refreshing metadata for: 'VMware Photon Linux 5.0 (x86_64) Updates'
    Refreshing metadata for: 'VMware Photon Linux 5.0 (x86_64)'
    Metadata cache created.                   3107 100%
    
  • tdnf check-local

    This command resolves dependencies by using the local RPMs to help check RPMs for quality assurance before publishing them. To check RPMs with this command, you must create a local directory and place your RPMs in it. The command, which includes no options, takes the path to the local directory containing the RPMs as its argument. The command does not, however, recursively parse directories; it checks the RPMs only in the directory that you specify.

    For example, after creating a directory named /tmp/myrpms and placing your RPMs in it, you can run the following command to check them:

    tdnf check-local /tmp/myrpms
    Checking all packages from: /tmp/myrpms
    Found 10 packages
    Check completed without issues
    
  • tdnf provides

    This command finds the packages that provide the package that you supply as an argument. If you are used to a package name for another system, you can use tdnf provides to find the corresponding name of the package on Photon OS.

    Example:

    tdnf provides docker
    docker-23.0.2-1.ph5.x86_64 : Docker
    Repo     : photon
    docker-23.0.1-2.ph5.x86_64 : Docker
    Repo     : photon-updates
    docker-23.0.2-1.ph5.x86_64 : Docker
    Repo     : @System
    

    For a file, you must provide the full path. Example:

    tdnf provides /usr/include/stdio.h
    [using file list match for '/usr/include/stdio.h']
    glibc-devel-2.36-4.ph5.x86_64 : Header files for glibc
    Repo     : photon
    glibc-devel-2.36-3.ph5.x86_64 : Header files for glibc
    Repo     : photon-updates
    

    The following example shows you how to find the package that provides a pluggable authentication module, which you might need to find if the system is mishandling passwords.

    tdnf provides /etc/pam.d/system-account
    [using file list match for '/etc/pam.d/system-account']
    shadow-4.13-3.ph5.x86_64 : Programs for handling passwords in a secure way
    Repo     : photon
    shadow-4.13-3.ph5.x86_64 : Programs for handling passwords in a secure way
    Repo     : photon-updates
    shadow-4.13-3.ph5.x86_64 : Programs for handling passwords in a secure way
    Repo     : @System
    

    For more commands see the Photon OS Administration Guide.

  • tdnf reinstall

    If a package that is installed is not working, try re-installing it. Example:

    tdnf reinstall shadow
    Reinstalling:
    shadow                   x86_64             4.13-3.ph5               photon-updates       1.87M           368.07k
    
    Total installed size:   1.87M
    Total download size: 368.07k
    Is this ok [y/N]: y
    shadow                                  376905 100%
    Testing transaction
    Running transaction
    Installing/Updating: shadow-4.13-3.ph5.x86_64
    Removing: shadow-4.13-3.ph5.x86_64
    

8.9 - Kernel Problems and Boot and Login Errors

Photon OS includes commands to troubleshoot kernel problems and boot and login errors.

8.9.1 - Kernel Overview

You can use dmesg command to troubleshooting kernel errors. The dmesg command prints messages from the kernel ring buffer.

The following command, for example, presents kernel messages in a human-readable format:

dmesg --human --kernel

To examine kernel messages as you perform actions, such as reproducing a problem, in another terminal, you can run the command with the --follow option, which waits for new messages and prints them as they occur:

dmesg --human --kernel --follow

The kernel buffer is limited in memory size. As a result, the kernel cyclically overwrites the end of the information in the buffer from which dmesg pulls information. The systemd journal, however, saves the information from the buffer to a log file so that you can access older information.

To view it, run the following command:

journalctl -k

If required, you can check the modules that are loaded on your Photon OS machine by running the lsmod command. For example:

lsmod
Module                  Size  Used by
xt_conntrack           16384  2
nft_compat             20480  2
nf_tables             204800  39 nft_compat
nfnetlink              20480  2 nft_compat,nf_tables
xt_LOG                 16384  0
nf_log_syslog          20480  0
nf_conntrack          114688  1 xt_conntrack
nf_defrag_ipv6         20480  1 nf_conntrack
nf_defrag_ipv4         16384  1 nf_conntrack
af_packet              45056  2
vmwgfx                294912  1
psmouse               110592  0
drm_ttm_helper         16384  1 vmwgfx
ttm                    53248  2 vmwgfx,drm_ttm_helper
vfat                   24576  1
drm_kms_helper        118784  1 vmwgfx
fat                    69632  1 vfat
syscopyarea            16384  1 drm_kms_helper
sysfillrect            16384  1 drm_kms_helper
sysimgblt              16384  1 drm_kms_helper
fb_sys_fops            16384  1 drm_kms_helper
evdev                  20480  2
mousedev               20480  0
button                 16384  0
sch_fq_codel           20480  2
drm                   368640  5 vmwgfx,drm_kms_helper,drm_ttm_helper,ttm
fuse                  114688  1
i2c_core               49152  2 drm_kms_helper,drm
dm_mod                131072  0
loop                   28672  0
backlight              16384  1 drm
configfs               36864  1
dmi_sysfs              16384  0
hid_generic            16384  0
usbhid                 28672  0
hid                   114688  2 usbhid,hid_generic
xhci_pci               16384  0
xhci_hcd              167936  1 xhci_pci
uhci_hcd               40960  0
ehci_pci               16384  0
crc32c_intel           24576  2
ehci_hcd               69632  1 ehci_pci
usbcore               217088  6 xhci_hcd,ehci_pci,usbhid,ehci_hcd,xhci_pci,uhci_hcd
sr_mod                 24576  0
cdrom                  49152  1 sr_mod
usb_common             16384  4 xhci_hcd,usbcore,ehci_hcd,uhci_hcd
rdrand_rng             16384  0
rng_core               20480  1 rdrand_rng
efivarfs               20480  1
ipv6                  450560  270
autofs4                36864  2

8.9.2 - Boot Process Overview

When a Photon OS machine boots, the BIOS initializes the hardware and uses a boot loader to start the kernel. After the kernel starts, systemd takes over and boots the rest of the operating system.

The BIOS checks the memory and initializes the keyboard, the screen, and other peripherals. When the BIOS finds the first hard disk, the boot loader–GNU GRUB 2.02–takes over. From the hard disk, GNU GRUB loads the master boot record (MBR) and initializes the root partition of the random-access memory by using initrd. The device manager, udev, provides initrd with the drivers it needs to access the device containing the root file system. Here’s what the GNU GRUB edit menu looks like in Photon OS with its default commands to load the boot record and initialize the RAM disk:

The GNU GRUB edit menu in Photon OS

At this point, the Linux kernel in Photon OS, which is kernel version 4.4.8, takes control. Systemd kicks in, initializes services in parallel, mounts the rest of the file system, and checks the file system for errors.

8.9.3 - Blank Screen on Reboot

If the Photon OS kernel enters a state of panic during a reboot and all you see is a blank screen, note the name of the virtual machine running Photon OS and then power off the VM.

In the host, open the vmware.log file for the VM. When a kernel panics, the guest VM prints the entire kernel log in vmware.log in the host directory containing the VM. This log file contains the output of the dmesg command from the guest, and you can analyze it to help identify the cause of the boot problem.

Example

After searching for Guest: in the following abridged vmware.log, this line appears, identifying the root cause of the reboot problem:

2016-08-30T16:02:43.220-07:00| vcpu-0| I125: Guest: 
	<0>[1.125804] Kernel panic - not syncing: 
	VFS: Unable to mount root fs on unknown-block(0,0)

Further inspection finds the following lines:

2016-08-30T16:02:43.217-07:00| vcpu-0| I125: Guest: 
<4>[    1.125782] VFS: Cannot open root device "sdc1" or unknown-block(0,0): error -6
2016-08-30T16:02:43.217-07:00| vcpu-0| I125: Guest: 
<4>[    1.125783] Please append a correct "root=" boot option; 
here are the available partitions: 
2016-08-30T16:02:43.217-07:00| vcpu-0| I125: Guest: 
<4>[    1.125785] 0100            4096 ram0  (driver?)
...
0800         8388608 sda  driver: sd
2016-08-30T16:02:43.220-07:00| vcpu-0| I125: Guest: 
<4>[    1.125802]   0801         8384512 sda1 611e2d9a-a3da-4ac7-9eb9-8d09cb151a93
2016-08-30T16:02:43.220-07:00| vcpu-0| I125: Guest: 
<4>[    1.125803]   0802            3055 sda2 8159e59c-b382-40b9-9070-3c5586f3c7d6

In this unlikely case, the GRUB configuration points to a root device named sdc1 instead of the correct root device, sda1. You can resolve the problem by restoring the GRUB GNU edit screen and the GRUB configuration file (/boot/grub/grub.cfg) to their original configurations.

8.9.4 - Investigating Unexpected Behavior

If you rebooted to address unexpected behavior before the reboot or if you encountered unexpected behavior during the reboot but have reached the shell, you must analyze what happened since the previous boot.

  1. Run the following command to check the logs:

    journalctl

  2. Run the following command to look at what happened since the penultimate reboot:

    journalctl --boot=-1

    Look at the log from the reboot:

    journalctl -b

  3. If required, examine the logs for the kernel:

    journalctl -k

  4. Check which kernel is in use:

    uname -r

    The kernel version of Photon OS in the full version is 6.1.10-8. The kernel version of in the OVA version is 6.1.10-8.ph5-esx. With the ESX version of the kernel, some services might not start.

  5. Run this command to check the overall status of services:

    systemctl status

    If a service is in red, check it:

     systemctl status service-name
    

    Start it if required:

     systemctl start service-name
    
  6. If looking at the journal and checking the status of services does not resolve your error, run the following systemd-analyze commands to examine the boot time and the speed with which services start.

    systemd-analyze time
    systemd-analyze blame
    systemd-analyze critical-chain
    

Note: The output of these commands might be misleading because one service might just be waiting for another service to finish initializing.

8.9.5 - Investigating the Guest Kernel

If a VM running Photon OS and an application or virtual appliance is behaving preventing you from logging in to the machine, you can troubleshoot by extracting the kernel logs from the guest’s memory and analyzing them with gdb.

This advanced troubleshooting method works when you are running Photon OS as the operating system for an application or appliance on VMware Workstation, Fusion, or ESXi. The procedure in this section assumes that the virtual machine running Photon OS is functioning normally.

The process to use this troubleshooting method varies by environment. The examples in this section assume that the troublesome Photon OS virtual machine is running in VMware Workstation 12 Pro on a Microsoft Windows 8 Enterprise host. The examples also use an additional, fully functional Photon OS virtual machine running in Workstation.

You can use other hosts, hypervisors, and operating systems–but you will have to adapt the example process below to them. Directory paths, file names, and other aspects might be different on other systems.

Prerequisites

Verify that you have the following resources:

  • Root access to a Linux machine other than the one you are troubleshooting. It can be another Photon OS machine, Ubuntu, or another Linux variant.
  • The vmss2core utility from VMware. It is installed by default in VMware Workstation and some other VMware products. If your system doesn’t already contain it, you can download it for free from https://labs.vmware.com/flings/vmss2core.
  • A local copy of the Photon OS ISO of the exact same version and release number as the Photon OS machine that you are troubleshooting.

Procedure Overview

The process to apply this troubleshooting method is as follows:

  • On a local computer, you open a file on the Photon OS ISO that contains Linux debugging information. Then you suspend the troublesome Photon OS VM and extract the kernel memory logs from the VMware hypervisor running Photon OS.
  • Next, you use the vmss2core tool to convert the memory logs into core dump files. The vmss2core utility converts VMware checkpoint state files into formats that third-party debugging tools understand. It can handle both suspend (.vmss) and snapshot (.vmsn) checkpoint state files (hereafter referred to as a vmss file) as well as monolithic and non-monolithic (separate .vmem file) encapsulation of checkpoint state data. See Debugging Virtual Machines with the Checkpoint to Core Tool.
  • Finally, you prepare to run the gdb tool by using the debug info file from the ISO to create a .gdbinit file, which you can then analyze with the gdb shell on your local Linux machine.

All three components must be in the same directory on a Linux machine.

Procedure

  1. Obtain a local copy of the Photon OS ISO of the exact same version and release number as the Photon OS machine that you are troubleshooting and mount the ISO on a Linux machine (or open it on a Windows machine):

    mount /mnt/cdrom
    
  2. Locate the following file. (If you opened the Photon OS ISO on a Windows computer, copy the following file to the root folder of a Linux machine.)

    /RPMS/x86_64/linux-debuginfo-4.4.8-6.ph1.x86_64.rpm
    
  3. On a Linux machine, run the following rpm2cpio command to convert the RPM file to a cpio file and to extract the contents of the RPM to the current directory:

    rpm2cpio /mnt/cdrom/RPMS/x86_64/linux-debuginfo-4.4.8-6.ph1.x86_64.rpm | cpio -idmv
    
  4. From the extracted files, copy the following file to your current directory:

    cp usr/lib/debug/lib/modules/4.4.8/vmlinux-4.4.8.debug
    
  5. Run the following command to download the dmesg functions that will help extract the kernel log from the coredump:

    wget https://www.kernel.org/doc/Documentation/kdump/gdbmacros.txt
    wget https://github.com/vmware/photon/blob/master/tools/scripts/gdbmacros-for-linux.txt
    
  6. Move the file as follows:

    mv gdbmacros-for-linux.txt .gdbinit
    
  7. Switch to your host machine so you can get the kernel memory files from the VM. Suspend the troublesome VM and locate the .vmss and .vmem files in the virtual machine’s directory on the host.

    Example:

    C:\Users\tester\Documents\Virtual Machines\VMware Photon 64-bit (7)>dir
    	 Volume in drive C is Windows
    	 Directory of C:\Users\tester\Documents\Virtual Machines\VMware Photon 64-bit
    	 (7)
    	09/20/2016  12:22 PM    <DIR>          .
    	09/20/2016  12:22 PM    <DIR>          ..
    	09/19/2016  03:39 PM       402,653,184 VMware Photon 64-bit (7)-f6b070cd.vmem
    	09/20/2016  12:11 PM         5,586,907 VMware Photon 64-bit (7)-f6b070cd.vmss
    	09/20/2016  12:11 PM     1,561,001,984 VMware Photon 64-bit (7)-s001.vmdk
    	...
    	09/20/2016  12:11 PM           300,430 vmware.log
    	...
    
  8. Now that you have located the .vmss and .vmem files, convert them to one or more core dump files by using the vmss2core tool that comes with Workstation. Here is an example of how to run the command. Be careful with your pathing, escaping, file names, and so forth–all of which might be different from this example on your Windows machine.

    
    	C:\Users\shoenisch\Documents\Virtual Machines\VMware Photon 64-bit (7)>C:\"Program Files (x86)\VMware\VMware Workstation"\vmss2core.exe "VMware Photon 64-bit (7)-f6b070cd.vmss" "VMware Photon 64-bit (7)-f6b070cd.vmem"
    
    The result of this command is one or more files with a `.core` extension plus a digit. Truncated example: 
    
    	C:\Users\tester\Documents\Virtual Machines\VMware Photon 64-bit (7)>dir
    	 Directory of C:\Users\tester\Documents\Virtual Machines\VMware Photon 64-bit(7)
    	09/20/2016  12:22 PM       729,706,496 vmss.core0
    
  9. Copy the .core file or files to the your current directory on the Linux machine where you so that you can analyze it with gdb.

    Run the following gdb command to enter the gdb shell attached to the memory core dump file. You might have to change the name of the vmss.core file in the example to match your .core file:

gdb vmlinux-4.4.8.debug vmss.core0

	GNU gdb (GDB) 7.8.2
	Copyright (C) 2014 Free Software Foundation, Inc.
	License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
	This is free software: you are free to change and redistribute it. 
	There is NO WARRANTY, to the extent permitted by law. ...
	Type "show configuration" for configuration details.
	For bug reporting instructions, please see:
	<http://www.gnu.org/software/gdb/bugs/>.
	Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>.
	For help, type "help".
	Type "apropos word" to search for commands related to "word"...
	Reading symbols from vmlinux-4.4.8.debug...done.
	warning: core file may not match specified executable file.
	[New LWP 12345]
	Core was generated by `GuestVM'.
	Program terminated with signal SIGSEGV, Segmentation fault.
	#0  0xffffffff813df39a in insb (count=0, addr=0xffffc90000144000, port=<optimized out>)
	    at arch/x86/include/asm/io.h:316
	316     arch/x86/include/asm/io.h: No such file or directory.
	(gdb)

Result

In the results above, the (gdb) of the last line is the prompt of the gdb shell. You can now analyze the core dump by using commands like bt, to perform a backtrace, and dmesg, to view the Photon OS kernel log and see Photon OS kernel error messages.

8.9.6 - Kernel Log Replication with VProbes

Replicating the Photon OS kernel logs on the VMware ESXi host is an advanced but powerful method of troubleshooting a kernel problem.

Replication Method

This method is applicable when the virtual machine running Photon OS is hanging or inaccessible because, for instance, the hard disk has failed.

As a prerequisite, you must have preemptively enabled the VMware VProbes facility on the VM before an error rendered it inaccessible. You must also create a VProbes script on the ESXi host, but you can do that after the error.

The method is useful in analyzing kernel issues when testing an application or appliance that is running on Photon OS.

There are two similar ways in which you can replicate the Photon OS kernel logs on ESXi by using VProbes.

  • The first modifies the VProbes script so that it works only for the VM that you set. It uses a hard-coded address.

  • The second uses an abstraction instead of a hard-coded address so that the same VProbes script can be used for any VM on an ESXi host that you have enabled for VProbe and copied its kernel symbol table (kallsyms) to ESXi.

For more information on VMware VProbes, see VProbes: Deep Observability Into the ESXi Hypervisor and the VProbes Programming Reference.

Using VProbes Script with a Hard-Coded Address

Perform the following steps to set a VProbe for an individual VM:

  1. Power off the VM so that you can turn on the VProbe facility.

    Edit the .vmx configuration file for the VM. The file resides in the directory that contains the VM in the ESXi data store. Add the following line of code to the .vmx file and then power the VM on:

     vprobe.enable = "TRUE"
    

    When you edit the .vmx file to add the above line of code, you must first turn off the VM–otherwise, your changes will not persist.

  2. Obtain the kernel log_store function address by connecting to the VM with SSH and running the following commands as root.

    Photon OS uses the kptr_restrict setting to place restrictions on the kernel addresses exposed through /proc and other interfaces. This setting hides exposed kernel pointers to prevent attackers from exploiting kernel write vulnerabilities. When you are done using VProbes, you should return kptr_restrict to the original setting of 2 by rebooting.)

     echo 0 > /proc/sys/kernel/kptr_restrict
     grep log_store /proc/kallsyms
    

    The output of the grep command will look similar to the following string. The first set of characters (without the t) is the log_store function address:

     ffffffff810bb680 t log_store
    
  3. Connect to the ESXi host with SSH so that you can create a VProbes script.

    Below is the template for the script. log_store in the first line is a placeholder for the VM’s log_store function address:

    GUEST:ENTER:log_store {
               string dst;
               getgueststr(dst, getguest(RSP+16) & 0xff, getguest(RSP+8));
               printf("%s\n", dst);
            }
    

    On the ESXi host, create a new file, add the template to it, and then change log_store to the function address that was the output from the grep command on the VM.

  4. Add a 0x prefix to the function address. In this example, the modified template looks like this:

    GUEST:ENTER:0xffffffff810bb680 {
           string dst;
           getgueststr(dst, getguest(RSP+16) & 0xff, getguest(RSP+8));
           printf("%s\n", dst);
        }
    
  5. Save your VProbes script as console.emt in the /tmp directory. (The file extension for VProbe scripts is .emt.)

    While still connected to the ESXi host with SSH, run the following command to obtain the ID of the virtual machine that you want to troubleshoot:

    vim-cmd vmsvc/getallvms

    This command lists all the VMs running on the ESXi host. Find the VM you want to troubleshoot in the list and make a note of its ID.

  6. Run the following command to print all the kernel messages from Photon OS in your SSH console; replace <VM ID> with the ID of your VM:

    vprobe -m <VM ID> /tmp/console.emt

    When you’re done, type Ctrl-C to stop the loop.

A Reusable VProbe Script Using the kallsyms File

Perform the following steps to create one VProbe script and use for all the VMs on your ESXi host.

  1. Power off the VM and turn on the VProbe facility on each VM that you want to be able to analyze.

    Add vprobe.enable = "TRUE" to the VM’s .vmx configuration file. See the instructions above.

  2. Power on the VM, connect to it with SSH, and run the following command as root:

    echo 0 > /proc/sys/kernel/kptr_restrict

  3. Connect to the ESXi host with SSH to create the following VProbes script and save it as /tmp/console.emt:

    GUEST:ENTER:log_store {
           string dst;
           getgueststr(dst, getguest(RSP+16) & 0xff, getguest(RSP+8));
           printf("%s\n", dst);
        }
    
  4. From the ESXi host, run the following command to copy the VM’s kallysms file to the tmp directory on the ESXi host:

    scp root@<vm ip address>:/proc/kallsyms /tmp

    While still connected to the ESXi host with SSH, run the following command to obtain the ID of the virtual machine that you want to troubleshoot:

    vim-cmd vmsvc/getallvms

    This command lists all the VMs running on the ESXi host. Find the VM you want to troubleshoot in the list and make a note of its ID.

  5. Run the following command to print all the kernel messages from Photon OS in your SSH console.

    Replace <VM ID> with the ID of your VM. When you’re done, type Ctrl-C to stop the loop.

    vprobe -m <VM ID> -k /tmp/kallysyms /tmp/console.emt

    You can use a directory other than tmp if you want.

8.9.7 - Linux Kernel

The Linux kernel is the main component of Photon OS and is the core interface between a computer’s hardware and its processes. It communicates between the two, managing resources as efficiently as possible.

Kernel Flavours and Versions

The following list contains the different Linux kernel flavours available:

  • linux - A generic kernel designed to run everywhere and support everything.
  • linux-esx - Optimized to run only on VMware hypervisor (ESXi, WS, Fusion). It has minimal set of device drivers to support VMware virtual devices. uname -r displays Linux . For additional features switch to the generic flavour.
  • linux-secure - Security hardened variant of the generic kernel. uname -r displays -secure suffix.
  • linux-rt - This is a Photon Real Time kernel. uname -r displays -rt suffix.
  • linux-aws - Optimized for AWS hypervisor kernel. uname -r displays -aws suffix.

To see the version of kernel installed, run the following command:

# rpm -qa | grep -e "^linux\(\|-esx\|-secure\|rt\|aws\)-[[:digit:]]"
linux-4.9.111-1.ph2.x86_64
linux-esx-4.9.111-1.ph2.x86_64

To see the version of the Kernel that is running currently, run the following command:

# uname -r
4.9.107-1.ph2-esx

From the output, you can see that the kernel running currently doesn’t match the installer. This happens when linux-* rpms were updated but was not restarted. Restart is required.

Configuration

To find the configurations of the installed Kernel, check the /boot directory by running the following command:

# ls /boot/config-*
config-4.9.111-1.ph2 config-4.9.111-1.ph2-esx

To get a copy of the kernel configuration (Not all flavours support this feature), run the zcat /proc/config.gz command.

Boot Parameters and initrd

Several kernel flavors can be installed on the system, but only one is used during boot. /boot/photon.cfg symlink points to the kernel which is used for boot.

# ls -l /boot/photon.cfg
lrwxrwxrwx 1 root root 23 Jun 12  2018 /boot/photon.cfg -> linux-4.9.111-1.ph2.cfg

Its contents can be checked by running the following command:

# cat /boot/photon.cfg

# GRUB Environment Block

photon_cmdline=init=/lib/systemd/systemd ro loglevel=3 quiet no-vmw-sta

photon_linux=vmlinuz-4.9.111-1.ph2

photon_initrd=initrd.img-4.9.111-1.ph2

Where:

  • photon_cmdline - Kernel parameters. This list will be extended by values from /boot/systemd.cfg file and the values are hardcoded to /boot/grub2/grub.cfg file (For example: root=).
  • photon_linux - Kernel image to boot.
  • photon_initrd - Initrd to use at boot.

Parameters of the kernel loading currently can be found by running the /proc/cmdline command:

# cat /proc/cmdline

BOOT_IMAGE=/boot/vmlinuz-4.9.107-1.ph2-esx root=PARTUUID=29194d05-4a6e-4e0c-b1f4-5020e5e8472c net.ifnames=0 init=/lib/systemd/systemd ro loglevel=3 quiet no-vmw-sta

Dmesg

To view message buffer of the kernel run the dmesg command.

Sysctl State

To view a list of all active units run the systemctl list-units command.

Kernel Statistics

The kernel statistics can be found by running the following commands:

  • procfs
  • sysfs
  • debugfs

Kernel Modules

To view the kernel log buffer run the journalctl -k command.

To view a list of available kernel modules run the lsmod command.

To view detailed information about all connected PCI buses run the lspci command.

8.10 - Performance Issues

Performance issues can be difficult to troubleshoot because so many variables play a role in overall system performance. Interpreting performance data often depends on the context and the situation. To better identify and isolate variables and to gain insight into performance data, you can use the troubleshooting tools on Photon OS to diagnose the system.

8.10.1 - General Performance Guidelines

If you have no indication what the cause of a performance degradation might be, start by getting a high-level picture of the system’s state. Then look for signs in the data that might point to a cause.

Use the following guidelines to gain insight into performance data:

  • Start with the systemd journal.

  • The top tool can unmask problems caused by processes or applications overconsuming CPUs, time, or RAM. If the percent of CPU utilization is consistently high with little idle time, for example, there might be a runaway process. Restart it.

  • The netstat --statistics command can identify bottlenecks causing performance issues. It lists interface statistics for different protocols.

  • If top and netstat reveal no errors, run the strace ls -al to view every system call.

  • The watch command can help dynamically monitor a command to help troubleshoot performance issues:

    watch -n0 --differences <command>

    You can also combine watch with the vmstat command to dig deeper into statistics about virtual memory, processes, block input-output, disks, and CPU activity. Are there any bottlenecks?

  • You can use the dstat utility to see the live, running list of statistics about system resources.

  • The systemd-analyze reveals performance statistics for boot time and can help troubleshoot slow system boots and incorrect unit files.

The additional tools that you select depend on the clues that your initial investigation reveals. The following tools can also help troubleshoot performance: sysstat, sar, systemtap, and crash.

8.10.2 - Throughput Performance

Throughput performance over TCP might be reduced.

This might occur because timestamps are enabled by default and the parameter net.ipv4.tcp_timestamps has a value of 1.

Setting a value of 1 or 2 for this parameter may impact performance. Setting a value of 0 or 2 for this parameter might cause a security vulnerability.

8.11 - Photon 4.0 to Photon 5.0 Migration and PostgreSQL Upgrade

We assume that PostgreSQL v10, v13, or v14 is installed in Photon OS 4.0 before the upgrade. This leads to multiple scenarios during Photon OS 4.0 to Photon OS 5.0 upgrade as follows:

  • PostgreSQL (v10 in Ph4) → PostgreSQL (v13/v14/v15 in Ph5) - This is not supported using pg_upgrade, user has to take a pg_dump of the DB and do a pg_restore after the upgrade as PostgreSQL 10 is EOL in 2022. It is recommended that you migrate to PostgreSQL v13 or v14 in Photon OS 4.0 before migrating to Photon OS 5.0. PostgreSQL 10’s sole purpose is to help migrate from Photon OS 3.0 to Photon OS 4.0, and to convert PostgreSQL DB to a higher and supported version of PostgreSQL.

  • PostgreSQL (v13 in Photon OS 4.0) → PostgreSQL (v13/v14/v15 in Photon 5.0)

  • PostgreSQL (v14 in Photon OS 4.0) → PostgreSQL (v14/v15 in Photon OS 5.0)

Assuming that you use PostgreSQL v13 or a higher version in Photon OS 4.0, PostgreSQL is upgraded to the same version in Photon OS 5.0.

If you need a higher version of PostgreSQL, install the available newer version manually and migrate the DB with caution.

By default, PostgreSQL binaries and libraries point to the most recent version of PostgreSQL available in the system.

Note that it is possible to install and use multiple versions of PostgreSQL at the same time in Photon OS. For example, if you have v13, v14, v15 of PostgreSQL installed altogether, by default, the binaries and libraries used are from PostgreSQL v15.

Perform the following steps to keep using a lower version of PostgreSQL when you have a higher version of PostgreSQL installed in the same system.

PostgreSQL (v13 in Photon 4.0) → PostgreSQL (v13/v14/v15 in Photon 5.0)

In this case, we need to install postgresql v13 in Photon OS 5.0 manually, and then migrate DB to PostgreSQL v14 or PostgreSQL v15 or keep using PostgreSQL v13.

To keep using PostgreSQL v13 in Photon OS 5.0, execute the following command:

$ sudo tdnf install -y postgresql13

Set PATH & LD_LIBRARY_PATH to the right locations to keep using PostgreSQL v13.

$ export PATH=/usr/pgsql/13/bin:$PATH
$ export LD_LIBRARY_PATH=/usr/pgsql/13/lib:$LD_LIBRARY_PATH

To migrate to PostgreSQL v14 or PostgreSQL v15, execute the following commands:

$ initdb -D <pgsql14/pgsql15-data-dir>
$ pg_upgrade --old-datadir <pgsql13-data-dir> --new-datadir <pgsql14/pgsql15-data-dir> --old-bindir /usr/pgsql/13/bin/ --new-bindir /usr/bin

PostgreSQL (v14 in Photon 4.0) → PostgreSQL (v14/v15 in Photon 5.0)

In this case, we need to install PostgreSQL v13 in Photon 5.0 manually, and then migrate DB to PostgreSQL v15 or keep using PostgreSQL v14.

To keep using PostgreSQL v14 in Photon 5.0, execute the following command:

$ sudo tdnf install -y postgresql14

Set PATH & LD_LIBRARY_PATH to right locations to keep using PostgreSQL v14.

$ export PATH=/usr/pgsql/14/bin:$PATH
$ export LD_LIBRARY_PATH=/usr/pgsql/14/lib:$LD_LIBRARY_PATH

To migrate to PostgreSQL v14 or PostgreSQL v15, execute the following commands:

$ initdb -D <pgsql15-data-dir>
$ pg_upgrade --old-datadir <pgsql14-data-dir> --new-datadir <pgsql15-data-dir> --old-bindir /usr/pgsql/14/bin/ --new-bindir /usr/bin

Note: If you chose the pg_upgrade method, you can remove the older version of PostgreSQL once DB is migrated. Do not forget to take a backup of your DB data, and take VM snapshot before making changes to DB or your VM.

8.12 - Photon OS Installation Issue

When you try to install Photon OS 5.0 as a guest operating system on a virtual machine with an installation medium connected to an IDE interface, the installation might fail with the following error:

Cannot proceed with the installation because the installation medium is not readable...

The issue occurs because Photon OS do not supports the IDE interface from version 5.0 onwards.

Workaround:

To install Photon OS on a virtual machine, ensure that you select an installation medium connected to a SATA interface, and then install the Photon OS as the guest operating system.

9 - Security Advisories

Security Advisories can be found at: https://github.com/vmware/photon/wiki/Security-Advisories

In Photon OS version 4.0 onwards, the security advisories for the updated RPMs are available in the respective repositories. To see more details about all the published security advisories, use the updateinfo option in the tdnf command. To see the entire list of the security advisories, enable both the repositories.  

Notes: The number of security advisories that you see in the message of the day is only for the enabled repository and might not refer to the total number of advisories.