diff --git a/doc/html/_images/create_vswitch_flow.jpg b/doc/html/_images/create_vswitch_flow.jpg new file mode 100644 index 000000000..aa5c7fea8 Binary files /dev/null and b/doc/html/_images/create_vswitch_flow.jpg differ diff --git a/doc/html/_images/openstack_zcc.jpg b/doc/html/_images/openstack_zcc.jpg new file mode 100644 index 000000000..176a84cd3 Binary files /dev/null and b/doc/html/_images/openstack_zcc.jpg differ diff --git a/doc/html/_images/spawn_flow.jpg b/doc/html/_images/spawn_flow.jpg new file mode 100644 index 000000000..1d5fea0e5 Binary files /dev/null and b/doc/html/_images/spawn_flow.jpg differ diff --git a/doc/html/_images/zcc_internal.jpg b/doc/html/_images/zcc_internal.jpg new file mode 100644 index 000000000..5409ca5ee Binary files /dev/null and b/doc/html/_images/zcc_internal.jpg differ diff --git a/doc/html/_sources/architecture.rst.txt b/doc/html/_sources/architecture.rst.txt new file mode 100644 index 000000000..46984ec0e --- /dev/null +++ b/doc/html/_sources/architecture.rst.txt @@ -0,0 +1,29 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +Introduction +************ + +What is Feilong +=============== + +Feilong is a Software Development Kit (SDK) for managing z/VM resources. +It provides a set of APIs to operate these resources, including guest, image, +network, volume etc. It comes with a python client library, +but can be used from other languages. + +Integration Examples +==================== + +* Example 1: integration with OpenStack + +.. image:: ./images/openstack_zcc.jpg + + +Internal Architecture +===================== + +Here is an internal component list of Feilong: + +.. image:: ./images/zcc_internal.jpg diff --git a/doc/html/_sources/change.rst.txt b/doc/html/_sources/change.rst.txt new file mode 100644 index 000000000..fe5c75a6e --- /dev/null +++ b/doc/html/_sources/change.rst.txt @@ -0,0 +1,129 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +.. _`Change log`: + +Release Notes +************* + +Release 1.4.0 +------------- + +New features released with zVMCLoudConnector 1.4.0: + +* Attach/detach volume to inactive guest. + +* Support set hostname without cloud-init. + +Release 1.3.0 +------------- +New features released with zVMCloudConnector 1.3.0: + +* Support upload image through octet stream. + +* Guest live migrate, support live migrate in z/VM SSI cluster. + +* Live resize guest memory, and static resize guest memory. + +* Attach/detach volume to active guest. + +Release 1.2.1 +------------- +zVMCloudConnector 1.2.1 includes one change: + +* Support "application/json,utf-8" context type in restclient. + +Release 1.2.0 +------------- +Following new features released with zVMCloudConnector 1.2.0: + +* Dedicate OSA device to guest. If osa_device specified when invoking + z/VM Cloud Connector restful API to create network interface, the OSA device + will be dedicated to the guest. + +* Resize CPUs of guest. Resize guest CPU count by updating static definition. + +* Live resize CPUs of guest. Currently only increasing CPU count is supported, + decreasing is not supported. + +Release 1.1.0 +------------- +zVMCloudConnector 1.1.0 is mainly includes the change: + +* Switch config drive format from tgz to iso9660 + + Config drive in iso9660 format is commonly used by cloud-init. + +Release 1.0.1 +------------- + +zVMCloudConnector 1.0.1 release mainly adapts to the SMAPI changes in z/VM 6.4 +APAR VM66120 1Q 2018. If the z/VM 6.4 has been applied APAR VM66120, must +upgrade z/VM Cloud Connector to 1.0.1 . + +Release 1.0.0 +------------- + +zVMCloudConnector 1.0.0 release includes many basic features that enables +z/VM Cloud management through zVMCloudConnector APIs. + +**Supported features** + +* Host(hypervisor) management + + get host information and get host disk pool information. + +* Guests(virtual machines) management + + - Provisoning: create, delete guest definition; capture, deploy guests; + create, delete, configure disks; create, delete, couple, uncouple vnics to + vswitch; configure vnics and network interfaces. + + - Power actions including start, stop, softstop, reboot, reset, pause, + unpause and get power state. + + - Query information: get guest information, guest list, get guest definition + information, get console outputs, get nic information. + +* Image management + + Support import, export, delete images; query image information, get image + root disk size. + +* Network features + + - vswitch: create, delete vswitch; grant, revoke vswitch access, + get vswitch list, query vswitch information, set user vlan id. + + - Hot plug/unplug network interfaces to live guest. + +* Monitoring + + Inspect virtual machine cpu, memory and vnic stats. + +* RESTful API + + zVMCloudConnector provides standard RESTful API, which makes it easier to + integrate with other cloud platforms. zVMCloudConnector RESTful API supports + to be configured in a HTTP or HTTPS server. + +* Authorization mechanism + + Support token based validation mechanism to make sure all zVMCloudConnector + RESTful API requests are authorized. + +* IUCV management channel + + zVMCloudConnector manages virtual machines through z/VM IUCV communication + channel, which does not require network connection. + +* Monitoring data cache + + Implement a cache layer in zVMCloudConnector to improve performance of getting + monitoring data. + +Release 0.3.2 +------------- + +Beta release since Dec 4, 2017 diff --git a/doc/html/_sources/configuration.rst.txt b/doc/html/_sources/configuration.rst.txt new file mode 100644 index 000000000..54bc240e3 --- /dev/null +++ b/doc/html/_sources/configuration.rst.txt @@ -0,0 +1,10 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +.. _`configuration options`: + +Configuration Options +********************* + +.. literalinclude:: ./zvmsdk.conf.sample diff --git a/doc/html/_sources/errorcodemsg.rst.txt b/doc/html/_sources/errorcodemsg.rst.txt new file mode 100644 index 000000000..0c4ebe480 --- /dev/null +++ b/doc/html/_sources/errorcodemsg.rst.txt @@ -0,0 +1,15 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +Error Codes and Messages +************************ + +This is a reference to Feilong API error codes +and messages. + +.. csv-table:: + :header: "overallRC";"modID";"rc";"rs";"errmsg" + :delim: ; + :widths: 20,10,5,5,65 + :file: errcode.csv diff --git a/doc/html/_sources/faq.rst.txt b/doc/html/_sources/faq.rst.txt new file mode 100644 index 000000000..6d9f80412 --- /dev/null +++ b/doc/html/_sources/faq.rst.txt @@ -0,0 +1,32 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +General info +************ + +This section provides answers to frequent asked questions. + +FAQ +=== + +Change default NIC address +-------------------------- + +For NIC address on to be created VM, the default value 1000 is defined by +Feilong configuration file, generally it is defined by ``default_nic_vdev`` +item of ``zvm`` section in ``/etc/zvmsdk/zvmsdk.conf``. + +If you want to create a VM with different value, change it to any integer you +want and make sure no conflict to other address then restart the Feilong service. + +Log on through 3270 or PCOM terminal +------------------------------------ + +Currently, Feilong doesn't support to set a password for virtual machine +(the definition in user directory), it is designed from a security perspective. +Only the administrator has the authority to logon the virtual machine through x3270 +or PCOM, the common user is only allowed to connect to guest through network +(ssh with id and password) + +Refer to ``default_admin_userid`` configuration in ``zvm`` section for more detail info. diff --git a/doc/html/_sources/generalinfo.rst.txt b/doc/html/_sources/generalinfo.rst.txt new file mode 100644 index 000000000..5e641e867 --- /dev/null +++ b/doc/html/_sources/generalinfo.rst.txt @@ -0,0 +1,73 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +General info +************ + +Content of this package +======================== + +Feilong (also known as python-zvm-sdk) is a client library written in Python +that interacts with `z/VM`_ SMAPI (System management API) of `IBM Z`_ or +`LinuxONE`_ machines. The goal of this package is to make the z/VM SMAPI easy +to be consumed by upper layer programmers and provide a set of APIs to be +called through RESTful interfaces. + +.. _IBM Z: https://www.ibm.com/z +.. _LinuxONE: https://www.ibm.com/linuxone +.. _z/VM: https://www.ibm.com/products/zvm + +The z/VM SMAPI is the access point for any external tools to +manage the z/VM running on IBM Z or LinuxONE platform. It supports management of +lifecycle and configuration of various platform resources, such as guest, +CPU, memory, virtual switches, disk storage, and more. + +Version +======= + +This documentation applies to version |release| of the Feilong package (python-zvm-sdk). +You can also see that version in the top left corner of this page. + +The Feilong package (python-zvm-sdk) uses the rules of `Semantic Versioning 2.0.0`_ for +its version. + +.. _Semantic Versioning 2.0.0: http://semver.org/spec/v2.0.0.html + +Compatibility +============= + +In this package, compatibility is always seen from the perspective of the user +of the package. Thus, a backwards compatible new version of this package means +that the user can safely upgrade to that new version without encountering +compatibility issues. + +This package uses the rules of `Semantic Versioning 2.0.0`_ for compatibility +between package versions, and for :ref:`deprecations `. + +Violations of these compatibility rules are described in section +:ref:`Change log`. + +.. _`Deprecations`: + +Deprecations +============ + +Deprecated functionality is marked accordingly in this documentation and in the +:ref:`Change log` + +Bug reporting and questions +=========================== + +If you encounter any problem with this package, please open a bug against +`Feilong issue tracker`_ or ask question `Feilong question`_ + +.. _Feilong issue tracker: https://bugs.launchpad.net/python-zvm-sdk/+bug +.. _Feilong question: https://answers.launchpad.net/python-zvm-sdk/ + +License +======= + +This package is licensed under the `Apache 2.0 License`_. + +.. _Apache 2.0 License: https://raw.githubusercontent.com/zhmcclient/python-zhmcclient/master/LICENSE diff --git a/doc/html/_sources/index.rst.txt b/doc/html/_sources/index.rst.txt new file mode 100644 index 000000000..29168ca82 --- /dev/null +++ b/doc/html/_sources/index.rst.txt @@ -0,0 +1,30 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +============================================ +Welcome to the Feilong Document +============================================ + +.. toctree:: + :maxdepth: 2 + :numbered: + + generalinfo + architecture + quickstart + setuphttpd + makeimage + sample + restapi + errorcodemsg + configuration + resize + faq + change + +---- + +.. image:: https://i.creativecommons.org/l/by/4.0/80x15.png + +This documentation is under `Creative Commons Attribution 4.0 International License `_ diff --git a/doc/html/_sources/makeimage.rst.txt b/doc/html/_sources/makeimage.rst.txt new file mode 100644 index 000000000..db2c494cd --- /dev/null +++ b/doc/html/_sources/makeimage.rst.txt @@ -0,0 +1,1054 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +Image and cloud-init Configuration +********************************** + +This section discusses setting up the Linux on System z(zLinux) that is the +target of the initial image capture, after capturing this zLinux, an image will +be generated, it can be used to import into Feilong's image +repository or Openstack glance for later deployment. + +Image Requirements +================== + +These are the requirements for an image to be captured and deployed by Feilong: + +1. The supported Linux distributions are: + +- RHEL 6.x +- RHEL 7.x +- RHEL 8.1 +- SLES 11.x +- SLES 12.x +- SELS 15 +- Ubuntu 16.04 +- Ubuntu 20.04 + +Where x is the zLinux's minor release number + +**Note**: FBA as root disk type is not supported for RHEL 8.1 + +2. The supported root disk type for capture/deploy are: + +- FBA +- ECKD + +**NOTE**: An image deployed via Feilong must match the disk type +configured by disk_pool in /etc/zvmsdk/zvmsdk.conf, only either FBA or ECKD image +can be deployed in zvmsdk, but not both at the same time. If you wish to switch +image types, you need to change the disk_pool configuration option and restart +sdkserver to make the changes take effect. + +3. If you capture a zLinux with root disk size greater than 5GB, or if you deploy + an image to an root disk larger than 5G in size, please modify the timeout value + for httpd service to make it work expected. Please refer to :ref:`Configure Apache` + section in this document for reference. + +4. The zLinux that used as the source of the captured image should meet the + following criteria: + + a. The root file system must not be on a logical volume + + b. The minidisk on which the root file system resides should be a minidisk of + the same type as desired for a subsequent deploy (for example, an ECKD disk + image should be captured for a subsequent deploy to an ECKD disk), and it should + not be a full-pack minidisk, since cylinder 0 on full-pack minidisks is reserved. + + c. If the source image is captured from minidisk with virtual address 0100, it must + be deployed to the virtual address 0100 of target Virtual Machine(VM) , otherwise, the deployed vm + will failed to start up. The root disk's vdev can be configured with user_root_vdev + option under zvm section in /etc/zvmsdk/zvmsdk.conf. The recommendation vdev of root + disk is 0100, this is also the default value. + + d. The root disk should have a single partition + + e. Feilong only support deploy an image to a disk larger or equal than + the source image's root disk size , otherwise, it would result in loss of data. + The image's root disk size can be got by command. + + .. code-block:: text + + hexdump -C -n 64 + +Make a Deployable Image for Feilong +=================================== + +Install Linux on z Systems(zLinux) in a Virtual Machine +------------------------------------------------------- + +1. Prepare a Linux on z Systems virtual server in the z/VM system. You will + have to make adjustments to the procedures that are documented in the below cook + book in order to keep the resulting virtual server within the bounds of the above + image requirements. + +- For RHEL6.4 and SLES 11 SP3 installation, see http://www.vm.ibm.com/pubs/redbooks/sg248147/files/24814700.pdf +- For RHEL 7 installation, see http://www.redbooks.ibm.com/abstracts/sg248303.html?Open +- For SLES 12 installation, see http://www.redbooks.ibm.com/abstracts/sg248890.html?Open +- For Ubuntu 16.04 installation, see http://www.redbooks.ibm.com/redbooks/pdfs/sg248354.pdf + +2. Install the mkisofs and openssl modules on it. + +3. Make sure SELinux is disabled and the SSH connection (default port number is 22) + can pass the firewall. + +4. Set UseDNS no in /etc/ssh/sshd_config file in order to improve the inventory + collection efficiency. + +5. For Ubuntu 16.04, you must enable root ssh access. By default, root ssh access + is not enabled. + +Installation and Configuration of IUCV service in zLinux +-------------------------------------------------------- + +Feilong manages the deployed VM via IUCV channel. IUCV service +should be configured on zLinux before capture it to make image. Following the below +steps to install and configure IUCV service. + +1. Logon your BYOL(Bring Your Own Linux, which will be used to represent the Linux + on which the Feilong will be run), and copy the following files + to target VM + + .. code-block:: text + + scp -r /opt/zthin/bin/IUCV/ root@:/root/ + + Where: is the ip address of zLinux + +2. Logon zLinux, install and configure IUCV service by commands: + + .. code-block:: text + + cd /root/IUCV + ./iucvserverdaemoninstaller.sh -a + + Where: auth_userid is the userid of the BYOL that can talk to zLinux via + IUCV channel, case insensitive, for example: + + .. code-block:: text + + ./iucvserverdaemoninstaller.sh -a OPNCLOUD + Setting the authorized client userid to be: OPNCLOUD + IUCV server daemon is configured and started successfully + + you may get the detail usage of iucvserverdaemoninstaller.sh by command: + + .. code-block:: text + + ./iucvserverdaemoninstaller.sh -h + +3. Logon your BYOL, run a simple command to check the if the iucv + channel is set up correctly by commands: + + .. code-block:: text + + /opt/zthin/bin/IUCV/iucvclnt date + + Where: is the userid of zLinux. + +If above commands execute successfully, you may continue to next steps. +Otherwise, stop here and re-check the configuration. + + +Configuration of cloud-init in zLinux +------------------------------------- +To do useful work with the user data, the zLinux image must be configured to +run a service that retrieves the user data passed from the Feilong +and then takes some actions based on the contents of that data. This task can +be done by cloud-init. + +For zLinux images that deployed by Feilong, zvmguestconfigure must +be installed and started before cloud-init. +These steps of configuration zvmguestconfigure and cloud-init are described in subsequent sections. + +Configuration of zvmguestconfigure in zLinux +-------------------------------------------- +The zvmguestconfigure script/service must be installed in the zLinux so it +can process the request files transmitted by Feilong to the +reader of the zLinux as a class X file. zvmguestconfigure also act as the bridge +between the zLinux and higher layer of zVM Cloud. Take spawning a VM via Openstack +nova-zvm-driver for example, the image uses cloud-init. +If customer spawn a new VM with some customized data to initialize +the VM via nova boot command. The overall work flow of the customized data is +listed as below: + +1. Openstack nova-zvm-driver generate the cfgdrive.iso file which is iso9660 format + and with label 'config-2', this file is used to customize the target VM + +2. nova-zvm-driver then call Feilong to punch the cfgdrive.iso file to + target VM's reader + +3. When target VM start up, the installed zvmguestconfigure will download cfgdrive.iso + file and then mount it as loop device + +4. When cloud-init run, it will automatically find the proper configure drive data source + via command ``blkid -t TYPE=iso9660 -o device``, then consume the data provided + by cfgdrive.iso to customize the VM + +The Feilong supports initiating changes to zLinux while it is shut +down or the virtual machine is logged off. The changes to zLinux are implemented +using zvmguestconfigure that is run when Linux is booted the next time. The steps +of how to install zvmguestconfigure is described in subsequent sections. + +Configuration of zvmguestconfigure on RHEL6.x and SLES11.x +.......................................................... + +Perform the following steps: + +1. Log on your BYOL, and copy the zvmguestconfigure script that is located at + /python-zvm-sdk/tools/share/zvmguestconfigure to your + zLinux, where zvmsdk_path can be found at section z/VM SDK install + +2. Logon on your zLinux, change the script to specify the authorizedSenders in + zvmguestconfigure file. It is recommended that this be set to a list of user IDs + which are allowed to transmit changes to the machine. At a minimum, this list + should include the userid of BYOL, which is usually OPNCLOUD. (It can be set + to '*', which indicates any virtual machine on the same LPAR may + send configuration requests to it) + +3. zvmguestconfigure is configured to run with run level 2, 3 and 5. It is not + configured to run as part of custom run level 4. If that run level is going to + be used, then the # Default-Start: line at the beginning of the file should be + updated to specify run level 4 in addition to the current run levels. + +4. Copy the zvmguestconfigure file to /etc/init.d and make it executable + +5. Add the zvmguestconfigure as a service by issuing: + + .. code-block:: text + + chkconfig --add zvmguestconfigure + +6. Activate the script by issuing: + + .. code-block:: text + + chkconfig zvmguestconfigure on + + If you wish to run with custom run level 4, then add 4 to the list of levels: + + .. code-block:: text + + chkconfig --level 2345 zvmguestconfigure on + +7. Verify that you installed the correct version of zvmguestconfigure on the + target machine. Do this by issuing the following service command: + + .. code-block:: text + + service zvmguestconfigure version + zvmguestconfigure version: 1.0 + +8. Verify that zvmguestconfigure on the target machine is configured to handle + requests from the server specified at step 2. Do this by issuing the following + service command: + + .. code-block:: text + + service zvmguestconfigure status + zvmguestconfigure is enabled to accept configuration reader files from: OPNCLOUD + + If zvmguestconfigure is not enabled to accept configuration reader files then verify + that you followed Step 2. + +Configuration of zvmguestconfigure on RHEL 7.x and SLES 12.x +............................................................ + +Perform the following steps: + +1. Log on your BYOL, and copy the zvmguestconfigure and zvmguestconfigure.service + script that are located at /python-zvm-sdk/tools/share/ folder + to your zLinux, where zvmsdk_path can be found at the section z/VM SDK install. + +2. Logon on your zLinux, change the script to specify the authorizedSenders in + zvmguestconfigure file. It is recommended that this be set to a list of user IDs + which are allowed to transmit changes to the machine. At a minimum, this list + should include the userid of BYOL, which is usually OPNCLOUD. (It can be set + to '*', which indicates any virtual machine on the same LPAR may send configuration requests to it). + +3. Copy the zvmguestconfigure script to the /usr/bin/ folder and make it executable. + +4. Install the zvmguestconfigure.service in the target zLinux: + +- If the target Linux machine is RHEL7.x, copy the zvmguestconfigureconf4z.service file to: /lib/systemd/system + +- If the target Linux machine is SLES12.x and SLES15, copy the zvmguestconfigure.service file to: /usr/lib/systemd/system + and it is recommended that you change the NetworkManager.service to be wicked.service in the zvmguestconfigure.service + +5. Enable the zvmguestconfigure service by issuing: + + .. code-block:: text + + systemctl enable zvmguestconfigure.service + +6. Start the zvmguestconfigure service by issuing: + + .. code-block:: text + + systemctl start zvmguestconfigure.service + +Configuration of zvmguestconfigure on Ubuntu 16.04 and Ubuntu 20.04 +................................................................... + +1. Logon your BYOL, and copy the zvmguestconfigure and zvmguestconfigure.service + script that are located at /python-zvm-sdk/tools/share/zvmguestconfigure + to your zLinux, where zvmsdk_path can be found at the section z/VM SDK install + +2. Logon your zLinux, change the script to specify the authorizedSenders in + zvmguestconfigure file. It is recommended that this be set to a list of user IDs + which are allowed to transmit changes to the machine. At a minimum, this list + should include the userid of BYOL. (It can be set to '*', which indicates any + virtual machine on the same LPAR may send configuration requests to it) + +3. On zLinux, copy the zvmguestconfigure script to the /usr/bin/ folder and make + it executable. + +4. Install the zvmguestconfigure.service in the target Ubuntu machine, tailor the + zvmguestconfigure.service file for an Ubuntu 16.04 image by modifying the file + contents as follows: + + .. code-block:: text + + [Unit] + Description=Activation engine for configuring z/VM when it starts + Wants=local-fs.target + After=local-fs.target + Before=cloud-init-local.service network-pre.target + [Service] + Type=oneshot + ExecStart=/usr/bin/zvmguestconfigure start + StandardOutput=journal+console + [Install] + WantedBy=multi-user.target + + After that, copy the zvmguestconfigure.service file to /lib/systemd/system. If the + target Linux machine is Ubuntu 20.04, copy the zvmguestconfigure.service.ubuntu file + to: /lib/systemd/system, and rename to zvmguestconfigure.service. + +5. Enable the zvmguestconfigure service by issuing: + + .. code-block:: text + + systemctl enable zvmguestconfigure.service + +6. Start the zvmguestconfigure service by issuing: + + .. code-block:: text + + systemctl start zvmguestconfigure.service + +Installation and Configuration of cloud-init +-------------------------------------------- + +Please note that if customer won't pass customize data via openstack configdrive, +cloud-init will not need to be installed. In this case, the steps in this section +can be ignored. + +OpenStack uses cloud-init as its activation engine.Some distributions include +cloud-init either already installed or available to be installed. +If your distribution does not include cloud-init, you can download the code +from https://launchpad.net/cloud-init/+download. After +installation, if you issue the following shell command and no errors occur, +cloud-init is installed correctly. + +.. code-block:: text + + cloud-init init --local + +Installation and configuration of cloud-init differs among different Linux +distributions, and cloud-init source code may change. This section provides +general information, but you may have to tailor cloud-init to meet the needs +of your Linux distribution. You can find a community-maintained list of +dependencies at http://ibm.biz/cloudinitLoZ. + +The z/VM OpenStack support has been tested with cloud-init 0.7.4 and 0.7.5 for +RHEL6.x and SLES11.x, 0.7.6 for RHEL7.x and SLES12.x, and 18.4 for SLES15, and +18.5 for RHEL8.1, and 0.7.8 for Ubuntu 16.04. + +If you are using a different version of cloud-init, you should change your +specification of the indicated commands accordingly.During cloud-init +installation, some dependency packages may be required. You can use yum/zypper +and python setuptools to easily resolve these dependencies. +See https://pypi.python.org/pypi/setuptools for more information. + +Installation and Configuration of cloud-init on RHEL 6.x +........................................................ + +1. Download the cloud-init tar file from Init scripts for use on cloud images + https://launchpad.net/cloud-init/+download + +2. Using the file cloud-init-0.7.5 as an example, + untar this file by issuing the following command: + + .. code-block:: text + + tar -zxvf cloud-init-0.7.5.tar.gz + +3. Issue the following to install cloud-init: + + .. code-block:: text + + cd ./cloud-init-0.7.5 + python setup.py build + python setup.py install + cp ./sysvinit/redhat/* /etc/init.d + +4. Update /etc/init.d/cloud-init-local to ensure that it starts after the + zvmguestconfigure and sshd services. On RHEL 6, change the # Required-Start + line in the ### BEGIN INIT INFO section from: + + .. code-block:: text + + ### BEGIN INIT INFO + # Provides: cloud-init-local + # Required-Start: $local_fs $remote_fs + # Should-Start: $time + # Required-Stop: + + to: + + .. code-block:: text + + ### BEGIN INIT INFO + # Provides: cloud-init-local + # Required-Start: $local_fs $remote_fs zvmguestconfigure sshd + # Should-Start: $time + # Required-Stop: + +5. The default configuration file /etc/cloud/cloud.cfg is for ubuntu, not RHEL. + To tailor it for RHEL: + + a. Replace distro:ubuntu with distro:rhel at around line 79. + + b. Change the default user name, password and gecos as you wish, at around lines 82 to 84 + + c. Change the groups tag to remove user groups that are not available for this distribution. + After the change, the groups tag at around line 85 should appear similar to the following: + groups: [adm, audio, cdrom, dialout, floppy, video, dip] + + For more information on how to configure cloud-init, please check the cloud-init documentation + http://cloudinit.readthedocs.org/. + +6. Cloud-init will try to add user syslog to group adm. This needs to be + changed. RHEL does not have a syslog user by default, so issue: + + .. code-block:: text + + useradd syslog + +7. Add the cloud-init related service with the following commands: + + .. code-block:: text + + chkconfig --add cloud-init-local + chkconfig --add cloud-init + chkconfig --add cloud-config + chkconfig --add cloud-final + +8. Then start them with the following sequence: + + .. code-block:: text + + chkconfig cloud-init-local on + chkconfig cloud-init on + chkconfig cloud-config on + chkconfig cloud-final on + + You can issue ls -l /etc/rc5.d/ | grep -e xcat -e cloud to find the services. + (Make sure that zvmguestconfigure starts before any cloud-init service.) + + .. code-block:: text + + lrwxrwxrwx. 1 root root 22 Jun 13 04:39 S50xcatconfinit -> ../init.d/zvmguestconfigure + lrwxrwxrwx. 1 root root 26 Jun 13 04:39 S51cloud-init-local -> ../init.d/cloud-init-local + lrwxrwxrwx. 1 root root 20 Jun 13 04:39 S52cloud-init -> ../init.d/cloud-init + lrwxrwxrwx. 1 root root 22 Jun 13 04:39 S53cloud-config -> ../init.d/cloud-config + lrwxrwxrwx. 1 root root 21 Jun 13 04:39 S54cloud-final -> ../init.d/cloud-final + +9. To verify cloud-init configuration, issue: cloud-init init --local + + .. code-block:: text + + cloud-init init --local + + Make sure that no errors occur. The following warning messages can be ignored: + + /usr/lib/python2.6/site-packages/Cheetah-2.4.4-py2.6.egg/Cheetah/Compiler.py:1509: UserWarning: + You don’t have the C version of NameMapper installed! I’m disabling Cheetah’s useStackFrames + option as it is painfully slow with the Python version of NameMapper. You should get a copy + of Cheetah with the compiled C version of NameMapper. You don’t have the C version of NameMapper installed! + +10. Issue following command, if this file exists, or cloud-init will not work after reboot. + + .. code-block:: text + + rm -rf /var/lib/cloud + +Installation and Configuration of cloud-init on SLES11.x +........................................................ + +1. Download the cloud-init tar file from https://launchpad.net/cloud-init/+download. + +2. Using the file cloud-init-0.7.5 as an example, untar this file by issuing + the following command: + + .. code-block:: text + + tar -zxvf cloud-init-0.7.5.tar.gz + + +3. Issue the following commands to install cloud-init: + + .. code-block:: text + + cd ./cloud-init-0.7.5 + python setup.py build + python setup.py install + + **NOTE:**: After you issue the command tar -zxvf cloud-init-0.7.5.tar.gz, + the directory ./sysvinit/sles/ does not exist. So you have to copy the + cloud-init related services from ./sysvinit/redhat/* to /etc/init.d/: + + .. code-block:: text + + cp ./sysvinit/redhat/* /etc/init.d + + You will find that four scripts, cloud-init-local, cloud-init, cloud-config, + and cloud-final are added to /etc/init.d/. Modify each of them by replacing + the variable: + + .. code-block:: text + + cloud_init="/usr/bin/cloud-init" + + with: + + .. code-block:: text + + cloud_init="/usr/local/bin/cloud-init" + +4. Update /etc/init.d/cloud-init-local to ensure that it starts after the + zvmguestconfigure service. On SLES, change the # Required-Start line in the + ### BEGIN INIT INFO section from: + + .. code-block:: text + + ### BEGIN INIT INFO + # Provides: cloud-init-local + # Required-Start: $local_fs $remote_fs + # Should-Start: $time + # Required-Stop: + + to: + + .. code-block:: text + + ### BEGIN INIT INFO + # Provides: cloud-init-local + # Required-Start: $local_fs $remote_fs zvmguestconfigure + # Should-Start: $time + # Required-Stop: + +5. The default configuration file /etc/cloud/cloud.cfg is for ubuntu, not SLES. To tailor it for SLES: + + a. Replace distro:ubuntu with distro:sles at around line 79. + + b. Change the default user name, password and gecos as you wish, at around lines 82 to 84. + + c. Change the groups at around line 85: groups: [adm, audio, cdrom, dialout, floppy, video, dip] + + d. Cloud-init will try to add user syslog to group adm. This needs to be changed. For SLES, issue the following commands: + + .. code-block:: text + + useradd syslog + groupadd adm + + For more information on changing these values, see the cloud-init documentation http://cloudinit.readthedocs.org/ + +6. Start the cloud-init related services with the following commands, + ignoring the error “insserv: Service network is missed in the runlevels 4 + to use service cloud-init” if it occurs: + + .. code-block:: text + + insserv cloud-init-local + insserv cloud-init + insserv cloud-config + insserv cloud-final + + At this point, you should find that the services in /etc/init.d/rcX.d appear as + you would expect (make sure that zvmguestconfigure starts before any cloud-init service): + + .. code-block:: text + + lrwxrwxrwx. 1 root root 22 Jun 13 04:39 S50xcatconfinit -> ../init.d/zvmguestconfigure + lrwxrwxrwx. 1 root root 26 Jun 13 04:39 S51cloud-init-local -> ../init.d/cloud-init-local + lrwxrwxrwx. 1 root root 20 Jun 13 04:39 S52cloud-init -> ../init.d/cloud-init + lrwxrwxrwx. 1 root root 22 Jun 13 04:39 S53cloud-config -> ../init.d/cloud-config + lrwxrwxrwx. 1 root root 21 Jun 13 04:39 S54cloud-final -> ../init.d/cloud-final + +7. To verify cloud-init configuration, issue: + + .. code-block:: text + + cloud-init init --local + + Make sure that no errors occur. The following warning messages can be ignored: + /usr/lib/python2.6/site-packages/Cheetah-2.4.4-py2.6.egg/Cheetah/Compiler.py:1509: + UserWarning: + You don’t have the C version of NameMapper installed! I’m disabling Cheetah’s useStackFrames + option as it is painfully slow with the Python version of NameMapper. You should get a copy + of Cheetah with the compiled C version of NameMapper. + You don’t have the C version of NameMapper installed! + +8. Issue following command, if this file exists, or cloud-init will not work after reboot. + + .. code-block:: text + + rm -rf /var/lib/cloud + +Installation and Configuration of cloud-init on RHEL 7.x and SLES 12.x +...................................................................... + +1. Download cloud-init0.7.6 from https://launchpad.net/cloud-init/+download. + +2. Untar it with this command: + + .. code-block:: text + + tar -zxvf cloud-init-0.7.6.tar.gz + +3. Issue the following commands to install cloud-init: + + .. code-block:: text + + cd ./cloud-init-0.7.6 + python setup.py build + python setup.py install --init-system systemd + +4. OpenStack on z/VM uses ConfigDrive as the data source during the installation + process. You must add the following lines to the default + configuration file, /etc/cloud/cloud.cfg: + + .. code-block:: text + + # Example datasource config + # datasource: + # Ec2: + # + # metadata_urls: [ ’blah.com’ ] + # + # timeout: 5 # (defaults to 50 seconds) + # + # max_wait: 10 # (defaults to 120 seconds) + datasource_list: [ ConfigDrive, None ] + datasource: + ConfigDrive: + dsmode: local + + **NOTE:** please pay attention to the indentation, otherwise, cloud-init may not + work as expected. + +5. In order to work well with other products, the service start up sequence + for cloud-init-local and cloud-init should be changed to the following. + (The cloud-init related service files are located in the folder + /lib/systemd/system/ for RHEL7.x and in /usr/lib/systemd/system/ for SLES12.x) + + .. code-block:: text + + cat /lib/systemd/system/cloud-init-local.service + [Unit] + Description=Initial cloud-init job (pre-networking) + Wants=local-fs.target sshd.service sshd-keygen.service + After=local-fs.target sshd.service sshd-keygen.service + [Service] + Type=oneshot + ExecStart=/usr/bin/cloud-init init --local + RemainAfterExit=yes + TimeoutSec=0 + # Output needs to appear in instance console output + StandardOutput=journal+console + [Install] + WantedBy=multi-user.target + + # cat /lib/systemd/system/cloud-init.service + [Unit] + Description=Initial cloud-init job (metadata service crawler) + After=local-fs.target network.target cloud-init-local.service + Requires=network.target + Wants=local-fs.target cloud-init-local.service + [Service] + Type=oneshot + ExecStart=/usr/bin/cloud-init init + RemainAfterExit=yes + TimeoutSec=0 + # Output needs to appear in instance console output + StandardOutput=journal+console + [Install] + WantedBy=multi-user.target + +6. Manually create the cloud-init-tmpfiles.conf file: + + .. code-block:: text + + touch /etc/tmpfiles.d/cloud-init-tmpfiles.conf + + Insert comments into the file by issuing the following command: + + .. code-block:: text + + echo "d /run/cloud-init 0700 root root - -" > /etc/tmpfiles.d/cloud-init-tmpfiles.conf + +7. Because RHEL does not have a syslog user by default, you have to add it manually: + + .. code-block:: text + + useradd syslog + +8. In /etc/cloud/cloud.cfg, remove the ubuntu-init-switch, growpart and + resizefs modules from the cloud_init_modules section. Here is the + cloud_init_modules section after the change: + + .. code-block:: text + + # The modules that run in the ’init’ stage + cloud_init_modules: + - migrator + - seed_random + - bootcmd + - write-files + - set_hostname + - update_hostname + - update_etc_hosts + - ca-certs + - rsyslog + - users-groups + - ssh + +9. In /etc/cloud/cloud.cfg, remove the emit_upstart, ssh-import-id, + grub-dpkg, apt-pipelining, apt-config, landscape, and byobu modues + from the cloud_config section. Here is the cloud_config_modules section + after the change: + + .. code-block:: text + + cloud_config_modules: + # Emit the cloud config ready event + # this can be used by upstart jobs for ’start on cloud-config’. + - disk_setup + - mounts + - locale + - set-passwords + - package-update-upgrade-install + - timezone + - puppet + - salt-minion + - mcollective + - disable-ec2-metadata + - runcmd + +10. The default /etc/cloud/cloud.cfg file is for ubuntu, + and must be updated for RHEL and SLES. To tailor this file for RHEL and SLES: + + a. Change the disable_root: true line to: disable_root: false + + b. In the system_info section, replace distro:ubuntu with distro:rhel or distro:sles according to + the distribution you will use. + + c. Change the default user name, password, and gecos under default_user configuration section as needed for your installation. + + d. Change the groups tag to remove the user groups that are not available on this distribution. When cloud-init starts up at first time, it will create the specified users and groups. The following is a sample configuration for SLES: + + .. code-block:: text + + system_info: + # This will affect which distro class gets used + distro: sles + # Default user name + that default user’s groups (if added/used) + default_user: + name: sles + lock_passwd: false + plain_text_passwd: ’sles’ + gecos: sles12user + groups: users + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + shell: /bin/bash + + For more information on cloud-init configurations, see: http://cloudinit.readthedocs.org/en/latest/topics/examples.html + +11. Enable and start the cloud-init related services by issuing the following commands: + + .. code-block:: text + + systemctl enable cloud-init-local.service + systemctl start cloud-init-local.service + systemctl enable cloud-init.service + systemctl start cloud-init.service + systemctl enable cloud-config.service + systemctl start cloud-config.service + systemctl enable cloud-final.service + systemctl start cloud-final.service + + If you experience problems the first time you start cloud-config.service and + cloud-final.service, try starting them again. + +12. Ensure all cloud-init services are in active status by issuing the following commands: + + .. code-block:: text + + systemctl status cloud-init-local.service + systemctl status cloud-init.service + systemctl status cloud-config.service + systemctl status cloud-final.service + +13. Optionally, you can start the multipath service: + + .. code-block:: text + + systemctl enable multipathd + systemctl start multipathd + systemctl status multipathd + +14. Remove the /var/lib/cloud directory (if it exists), so that cloud-init will + not run after a reboot: + + .. code-block:: text + + rm -rf /var/lib/cloud + +Installation and Configuration of cloud-init on RHEL8.1 and SLES15 +.................................................................. + +Enable the system repositories of the RHEL8.1 and SLES15 to ensure that they can install software via yum and zypper. + +1. Install cloud-init by the command: + + a. For the RHEL8.1: + + .. code-block:: text + + yum install cloud-init + + b. For the SLES15: + + .. code-block:: text + + zypper install cloud-init + +2. OpenStack on z/VM uses ConfigDrive as the data source during the + installation process. You must add the following lines to the + default configuration file, /etc/cloud/cloud.cfg. Remember to disable network + configuration because network configuration is done by zvmguestconfigure. + + .. code-block:: text + + # Example datasource config + # datasource: + # Ec2: + # + # metadata_urls: [ ’blah.com’ ] + # + # timeout: 5 # (defaults to 50 seconds) + # + # max_wait: 10 # (defaults to 120 seconds) + datasource_list: [ ConfigDrive, None ] + datasource: + ConfigDrive: + dsmode: local + network: {config: disabled} + + **NOTE:** please pay attention to the indentation, otherwise, cloud-init may not + work as expected. + +3. Optionally, enable root login by configuring the /etc/cloud/cloud.cfg file: + + .. code-block:: text + + disable_root: false + +4. Enable and start the cloud-init related services by issuing the following commands: + + .. code-block:: text + + systemctl enable cloud-init-local.service + systemctl start cloud-init-local.service + systemctl enable cloud-init.service + systemctl start cloud-init.service + systemctl enable cloud-config.service + systemctl start cloud-config.service + systemctl enable cloud-final.service + systemctl start cloud-final.service + + If you experience problems the first time you start cloud-config.service and + cloud-final.service, try starting them again. + +5. Ensure all cloud-init services are in active status by issuing the following commands: + + .. code-block:: text + + systemctl status cloud-init-local.service + systemctl status cloud-init.service + systemctl status cloud-config.service + systemctl status cloud-final.service + +6. Remove the /var/lib/cloud directory (if it exists), so that cloud-init will + not run after a reboot: + + .. code-block:: text + + rm -rf /var/lib/cloud + +Installation and Configuration of cloud-init on Ubuntu 16.04 and Ubuntu 20.04 +............................................................................. + +For Ubuntu 16.04, cloud-init0.7.8 or higher is required. The examples in this +section use cloud-init0.7.8. + +For Ubuntu 20.04, cloud-init20.1-10 is installed by default, can ignore below step1-2. + +1. Download cloud-init0.7.8 from https://launchpad.net/cloud-init/+download. + Untar it with this command: + + .. code-block:: text + + tar -zxvf cloud-init-0.7.8.tar.gz + +2. Issue the following commands to install cloud-init: + + .. code-block:: text + + cd ./cloud-init-0.7.8 + python3 setup.py build + python3 setup.py install --init-system systemd + + **NOTE:** You might have to install all the dependencies that cloud-init + requires according to your source z/VM environment. For example, you might + have to install setuptools before installing cloud-init. For more information, + see https://pypi.python.org/pypi/setuptools. + +3. OpenStack on z/VM uses ConfigDrive as the data source during the + installation process. You must add the following lines to the + default configuration file, /etc/cloud/cloud.cfg: + + .. code-block:: text + + # Example datasource config + # datasource: + # Ec2: + # + # metadata_urls: [ ’blah.com’ ] + # + # timeout: 5 # (defaults to 50 seconds) + # + # max_wait: 10 # (defaults to 120 seconds) + datasource_list: [ ConfigDrive, None ] + datasource: + ConfigDrive: + dsmode: local + + **NOTE:** please pay attention to the indentation, otherwise, cloud-init may not + work as expected. + +4. Enable root login by configuring the /etc/cloud/cloud.cfg file: + + .. code-block:: text + + disable_root: false + +5. Optionally, you can tailor the modules that run during the cloud-config + stage or the cloud-final stage by modifying cloud_config_modules or + cloud_final_modules in /etc/cloud/cloud.cfg file. + Enable and start the cloud-init related services by issuing the following commands: + + .. code-block:: text + + ln -s /usr/local/bin/cloud-init /usr/bin/cloud-init + systemctl enable cloud-init-local.service + systemctl start cloud-init-local.service + systemctl enable cloud-init.service + systemctl start cloud-init.service + systemctl enable cloud-config.service + systemctl start cloud-config.service + systemctl enable cloud-final.service + systemctl start cloud-final.service + +6. Ensure all cloud-init services are in active status by issuing the following commands: + + .. code-block:: text + + systemctl status cloud-init-local.service + systemctl status cloud-init.service + systemctl status cloud-config.service + systemctl status cloud-final.service + +7. If you intend to use persistent disks, start the multipath service: + + .. code-block:: text + + systemctl enable multipathd + systemctl start multipathd + systemctl status multipathd + +8. Remove the /var/lib/cloud directory (if it exists), so that cloud-init will + not run after a reboot: + + .. code-block:: text + + rm -rf /var/lib/cloud + +Capture the zLinux to Generate the Image +======================================== + +After zLinux is well configured for capture, shut down it and logoff the userid, +then perform the following steps to generate the image: + +Logon your BYOL, type the command: + +.. code-block:: text + + /opt/zthin/bin/creatediskimage + +Where: + is the userid of the zLinux, + is the device number for capture, + is the image's store location + + +Import the Images to Feilong +============================ + +If you want to import the image to Feilong, you can use REST API. +Type the following command: + +.. code-block:: text + + # curl http://1.2.3.4:8080/images -H "Content-Type:application/json" -H 'X-Auth-Token:' -X POST -d '{"image": {"url": "file:///var/lib/zvmsdk/images/0100", "image_meta": {"os_version": "rhel6.7"}, "image_name": "0100", "remote_host": "root@6.7.8.9"}}' + {"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": "", "errmsg": ""} + +Please note that if the source image is located at same server as BYOL, there is no need +to specify the remote_host parameter in data field. And please refer to :ref:`TokenUsage` to get +your token to fill in the request area ````. + +Verify the import result by command: + +.. code-block:: text + + # curl http://127.0.0.1:8080/images?imagename=0100 -X GET -H "Content-Type:application/json" -H 'X-Auth-Token:' + {"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": [{"image_size_in_bytes": "236435482", "disk_size_units": "1100:CYL", "md5sum": "26ddd19301d4f9c8a85e812412164bb8", "comments": null, "imagename": "0100", "imageosdistro": "rhel6.7", "type": "rootonly"}], "errmsg": ""} + +During image import you may meet following error: + +.. code-block:: text + + {u'rs': 10, u'overallRC': 300, u'modID': 40, u'rc': 300, u'output': u'', 'errmsg': u"Image import error: + Copying image file from remote filesystem failed with error Warning: Permanently added '6.7.8.9' (ECDSA) + to the list of known hosts.\r\nPermission denied, please try again.\r\nPermission denied, please try again. + \r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n"} + +If similar error happens, you need to configure the ssh authentication between +your BYOL server and the server that source image located. You need to append the +public key of the owner that running sdkserver to the .ssh/authorized_keys file of +the user where your source image located. Please refer to :ref:`ssh_key` for reference. + diff --git a/doc/html/_sources/quickstart.rst.txt b/doc/html/_sources/quickstart.rst.txt new file mode 100644 index 000000000..918edfa77 --- /dev/null +++ b/doc/html/_sources/quickstart.rst.txt @@ -0,0 +1,643 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +Quick Start +*********** + +This is the document that describes the installation, configuration, +and basic usages of Feilong. + +Pre-requirements +================ + +1. Feilong depends on the under-layer z/VM SMAPI support to manage +the z/VM objects. For the Feilong to work normally, the managed z/VM +system should be updated to the latest level with APARs listed in the +`z/VM service Information`_ installed. + +.. _z/VM service Information: http://www.vm.ibm.com/sysman/osmntlvl.html + +.. note:: + please make sure you applied http://www-01.ibm.com/support/docview.wss?uid=isg1VM66120 + if z/VM 6.4 is used. + +2. Feilong has to be installed inside a Linux running on z/VM. +Currently supported distros include the most current supported versions: + + - SUSE Linux Enterprise Server 15 SP6 + - Red Hat Enterprise Linux 9.4 + - Ubuntu 24.04 LTS + + From now on, BYOL (Bring Your Own Linux) will be used to represent + the Linux on which the Feilong will be run. + + For the Feilong to run, the BYOL must have enough free disk space (>100M). + And besides that, the following updates need to be made to the BYOL. + +Preparation on BYOL +------------------- + +1. Authorize BYOL user for z/VM SMAPI call. + + VSMWORK1 AUTHLIST needs to be updated in order to make the BYOL + machine be able to issue SMAPI call. Refer to `z/VM Systems Management + Application Programming`_ for how to make it. + +.. note:: + It is recommend to consider increase the SMAPI long call server and DIRMAINT + DATAMOVE machine if heavy concurrent workload is going to be run through Feilong. + See `z/VM Systems Management Application Programming`_ for how to make it. + +2. Update BYOL definition for spawning guests. + + Assume BYOL has its definition on z/VM, it needs to have following statement in + its User Directory in order to link disk during stage of spawning guests. + + .. code-block:: text + + OPTION LNKNOPAS + + If under RACF, RACF command need to be executed like below while the ``BYOL`` + is the name of the virtual machine which is going to run Feilong service. + + .. code-block:: text + + RAC PERMIT BYOL CLASS(VMRDR) ID(VSMWORK1) ACCESS(UPDATE) + +.. note:: + Please note when under RACF (ESM of z/VM) is used, additional setup for SMAPI is needed + to make the BYOL able to work. + + See `z/VM Systems Management Application Programming`_ for how to make it. + +3. Update BYOL definition about IUCV + + Assume BYOL has its definition on z/VM, it needs to have following entry in + its User Directory in order to communicate with the managed guests by the IUCV + channel + + .. code-block:: text + + IUCV ANY + + See `z/VM Systems Management Application Programming`_ for how to make it. + +.. _z/VM Systems Management Application Programming: https://www.ibm.com/support/knowledgecenter/SSB27U_6.4.0/com.ibm.zvm.v640.dmse6/toc.htm + +4. Enable reader device + + In order to get console output of target vm, BYOL's reader device needs to + be enabled to receive console output spool files send from target vm + + Use the following command on BYOL itself to achieve that: + + .. code-block:: text + + [root@xxxx ~]# cio_ignore -r 000c + [root@xxxx ~]# chccwdev -e 000c + Setting device 0.0.000c online + Done + + If something like 'is already online' is returned, it means reader already + online and feel free to ignore the warning. + +5. Enable punch device + + In order to spawn guest, BYOL needs to be able to punch files to spawned + guests' reader, so the punch device on BYOL needs to be enabled. + + Use the following command on BYOL itself to achieve that: + + .. code-block:: text + + [root@xxxx ~]# cio_ignore -r 000d + [root@xxxx ~]# chccwdev -e 000d + Setting device 0.0.000d online + Done + + If something like 'is already online' is returned, it means punch already + online and feel free to ignore the warning. + +.. note:: + Preparation step 2 and step 3 require to logoff then re-logon the + BYOL to make the updates become effective. + +Installation Requirements +------------------------- + +The supported Python version includes: + +- Python 2.7 +- Python 3+ + +Installation using OBS Packages +=============================== + +The Open Build Service (OBS) is a generic system to build and distribute binary packages from sources in an automatic, consistent and reproducible way. +OBS builds and provides an installable version of the zthin and zvmsdk packages for each of the distributions (RHEL, SLES, Ubuntu). + +RPM for RHEL/Alma/Rocky +----------------------- + +SSH onto the BYOL as root user, and then follow the following steps: + +1. Add the feilong AlmaLinux repository from OBS + + .. code-block:: text + + # dnf config-manager --add-repo=https://download.opensuse.org/repositories/Virtualization:/feilong/AlmaLinux_9/ + +2. Disable gpgkeycheck flag + + Add the flag `gpgkeycheck=0` to the + `/etc/yum.repos.d/download.opensuse.org_repositories_Virtualization_feilong_AlmaLinux_9_.repo` file. + +3. Disable SELinux + + Update the config file `/etc/selinux/config` and set `SELINUX=disabled`. + Make sure you reboot to ensure the changes are reflected and SELinux is disabled. + + We are considering writing SELinux policies for Feilong that would enable to not disable SELinux as a whole. + +4. Install the Extra Packages for Enterprise Linux. + + Packages in EPEL are dependencies for the feilong packages installation. + Make sure you add both the EPEL and the EPEL-Next repos. + +5. Install the zthin and zvmsdk packages + + .. code-block:: text + + # dnf install zthin zvmsdk + +6. Skip to the SSH key authentication between consumer and BYOL section to continue. + +RPM for SLES +------------ + +SSH onto the BYOL as root user, and then follow the following steps: + +1. Register to the SUSE Package Hub using SUSEConnect and refresh the available repos list. + + Packages in the PackageHub are dependencies for the feilong package installation + + .. code-block:: text + + # SUSEConnect --product PackageHub/15.5/s390x + +2. Add the feilong SUSE repository from OBS + + .. code-block:: text + + # zypper ar https://download.opensuse.org/repositories/Virtualization:/feilong/SLE_15_SP5/ feilong + # zypper refresh + +3. Install the zthin and zvmsdk packages + + .. code-block:: text + + # zypper in zthin zvmsdk + +4. Skip to the SSH key authentication between consumer and BYOL section to continue. + +DEB for Ubuntu +----------------- + +SSH onto the BYOL as root user, and then follow the following steps: + +1. Add the feilong Ubuntu repository from OBS + + .. code-block:: text + + # bash -c "echo 'deb http://download.opensuse.org/repositories/home:/Aazam:/feilong/xUbuntu_24.04/ /' > /etc/apt/sources.list.d/feilong.list" + # wget http://download.opensuse.org/repositories/Virtualization:/feilong/xUbuntu_24.04/Release.key + # mv Release.key /etc/apt/trusted.gpg.d/feilong.asc + +2. Update the apt repository list + + .. code-block:: text + + # apt update + +3. Disable SELinux + + Update the config file `/etc/selinux/config` and set `SELINUX=disabled`. + Make sure you reboot to ensure the changes are reflected and SELinux is disabled. + + We are considering writing SELinux policies for Feilong that would enable to not disable SELinux as a whole. + +5. Install the zthin and zvmsdk packages + + .. code-block:: text + + # apt-get install zthin zvmsdk + +6. Skip to the SSH key authentication between consumer and BYOL section to continue. + + +Manual Installation +=================== + +z/VM zthin install +------------------ + +zthin is a library written in C that works as part of the Feilong. +It mainly focuses on socket connection from BYOL to z/VM SMAPI(System Management API). +Feilong requires zthin as the backend to communicate with z/VM SMAPI, +thus it needs to be installed before installing Feilong. + +SSH onto the BYOL as root user, and then follow the following steps: + +1. Clone build project from github + + .. code-block:: text + + # git clone https://github.com/mfcloud/build-zvmsdk.git + # cd build-zvmsdk + +2. Trigger the build tool + + The build tool depends on the following commands: *rpmbuild*, *gcc*, so you should make + sure these commands are usable on BYOL before running the following build. + + For building on RHEL + + .. code-block:: text + + # /usr/bin/bash buildzthinrpm_rhel master + + For building on SLES + + .. code-block:: text + + # /usr/bin/bash buildzthinrpm_sles master + + If this build finishes successfully, the resulting rpm package will be generated + in the /root/zthin-build/RPMS/s390x/ directory named in the format + *zthin-version-snapdate.s390x.rpm* where *version* is the zthin version + number and *date* is the build date. + + For building on Debian, make sure you have *dpkg-dev* available. + + .. code-block:: text + + # /usr/bin/bash buildzthindeb master + + If the build finishes successfully, the resulting deb package will be generated + in the /root/build-zvmsdk/feilong directory named in the format + *zthin-version.s390x.deb* where *version* is the zthin version + number and *date* is the build date. + +3. Install the rpm or deb generated in last step + + .. code-block:: text + + # rpm -ivh /root/zthin-build/RPMS/s390x/zthin-3.1.0-snap201710300123.s390x.rpm + + Be sure to replace the *zthin-3.1.0-snap201710300123.s390x.rpm* with the correct version name. + + .. code-block:: text + + # dpkg -i /root/build-zvmsdk/feilong/zthin-3.1.2.s390x.deb + + Be sure to replace the *zthin-3.1.2.s390x.deb* with the correct version name. + +4. Verify zthin can work + + .. code-block:: text + + # /opt/zthin/bin/smcli Image_Query_DM -T opncloud + + If all things went well, this smcli command should be + able to return the directory entry of user OPNCLOUD. + + If this command failed, you need to check the following items: + + * The BYOL user is successfully authorized to issue SMAPI call. + * The SMAPI server on this z/VM host is working normally. + * The zthin rpm is installed without any error. + +5. Optionally, Consider to add ``/opt/zthin/bin/`` into $PATH so you can use ``smcli`` command directly. + +z/VM SDK install +---------------- + +z/VM SDK is the upper transition layer of Feilong. It implements the +supported SDK APIs by communicating with the zthin backend. + +1. Install z/VM sdk + + Please ensure to update your setuptools to the latest version before doing this step, + the following installation step would rely on it to automatically install the depended + python packages. + + .. code-block:: text + + # git clone https://github.com/mfcloud/build-zvmsdk.git + # cd build-zvmsdk + +2. Trigger the build tool + + The build tool depends on the following commands: *rpmbuild*, *gcc*, so you should make + sure these commands are usable on BYOL before running the following build. + + For building on RHEL + + .. code-block:: text + + # /usr/bin/bash buildzvmdsdkrpm_rhel master + + For building on SLES + + .. code-block:: text + + # /usr/bin/bash buildzvmsdkrpm_sles master + + If this build finishes successfully, the resulting rpm package will be generated + in the /root/zvmsdk-build/RPMS/s390x/ directory named in the format + *zvmsdk-version-snapdate.s390x.rpm* where *version* is the zvmsdk version + number and *date* is the build date. + + For building on Debian, make sure you have *dpkg-dev* available. + + .. code-block:: text + + # /usr/bin/bash buildzvmsdkdeb master + + If the build finishes successfully, the resulting deb package will be generated + in the /root/build-zvmsdk/ directory named in the format + *zvmsdk-version.s390x.deb* where *version* is the zthin version + number and *date* is the build date. + +3. Install the rpm or deb generated in last step + + .. code-block:: text + + # rpm -ivh /root/zvmsdk/RPMS/s390x/zvmsdk-1.4.0-snap201710300123.s390x.rpm + + Be sure to replace the *zvmsdk-1.4.0-snap201710300123.s390x.rpm* with the correct version name. + + .. code-block:: text + + # dpkg -i /root/build-zvmsdk/feilong/zvmsdk-1.4.0.s390x.deb + + Be sure to replace the *zvmsdk-1.4.0.s390x.deb* with the correct version name. + +Upgrade z/VM SDK +---------------- + +If the z/VM SDK was installed via ``python setup.py install``, you can fetch and +checkout to new version, then upgrade it by issue ``python setup.py install`` again. + +.. note:: + If you upgrade from a version equal or lower than 1.6.2 to **1.6.3** or newer version, + you have to add two new columns - **wwpn_npiv** and **wwpn_phy** into fcp table in + sdk_fcp database with type **`varchar(16)`**, which is located at + ``/var/lib/zvmsdk/databases/sdk_fcp.sqlite``, for example, by sqlite3 command: + ``ALTER TABLE fcp ADD COLUMN wwpn_npiv varchar(16)`` and + ``ALTER TABLE fcp ADD COLUMN wwpn_phy varchar(16)`` + +.. _`ssh_key`: + +Configuration Sample +==================== + +After z/VM SDK is installed, a file named 'zvmsdk.conf.sample' is generated +under the /etc/zvmsdk/ folder. It contains all the supported configurations +for z/VM SDK. You can refer to it to create your own configuration file which +should be named as zvmsdk.conf. + +Here's a sample configuration in which several options marked as 'required' +should be customized according to your environment. + +.. code-block:: text + + [database] + dir=/var/lib/zvmsdk/databases/ + + [image] + sdk_image_repository=/var/lib/zvmsdk/images + + [logging] + log_level=INFO + log_dir=/var/log/zvmsdk/ + + [network] + # IP address of the Linux machine which is running SDK on. + # This config option is required + my_ip=127.0.0.1 + + [sdkserver] + bind_addr=127.0.0.1 + bind_port=2000 + max_worker_count=64 + + [wsgi] + auth=none + + [zvm] + # zVM disk pool and type for root/ephemeral disks. + # This config option is required + disk_pool=ECKD:eckdpool + + # PROFILE name to use when creating a z/VM guest. + # This config option is required + user_profile=osdflt + + # The default maximum number of virtual processers the user can define. + user_default_max_cpu=32 + + # The default maximum size of memory the user can define. + user_default_max_memory=64G + +For the details of all configuration options, please refer to +:ref:`configuration options`. + +Setup for z/VM SDK Daemon +========================= + +The Feilong is designed to be run inside a daemon. The daemon server is bond to +the configured socket for receiving requests and then call the requested SDK API. + +The daemon server would be run with user 'zvmsdk' and group 'zvmsdk', the following user and folder +setup should be made on BYOL for the z/VM SDK daemon to run. + +* Create 'zvmsdk' user and group + + .. code-block:: text + + # useradd -d /var/lib/zvmsdk/ -m -U -p PASSWORD zvmsdk + + Replace the *PASSWORD* with your own password for the new created user. + +* Configure sudo access for 'zvmsdk' user (optional) + + If Feilong is installed from source code ``python setup.py install`` or from package install + such as deb or rpm, then you can skip this step as it's already done during install stage. + + The z/VM SDK Daemon relies on some privileged commands for the management of the z/VM host, so you + need to grant the 'zvmsdk' user to run following commands with sudo without password: + + * /usr/sbin/vmcp + * /opt/zthin/bin/smcli + * /usr/sbin/chccwdev + * /usr/sbin/cio_ignore + * /usr/sbin/fdasd + * /usr/sbin/fdisk + * /usr/sbin/vmur + * /usr/bin/mount + * /usr/bin/umount + * /usr/sbin/mkfs + * /usr/sbin/mkfs.xfs + * /usr/sbin/dasdfmt + * /opt/zthin/bin/unpackdiskimage + * /opt/zthin/bin/creatediskimage + * /opt/zthin/bin/linkdiskandbringonline + * /opt/zthin/bin/offlinediskanddetach + + A sample is given in the following block, copy the content to /etc/sudoers.d/zvmsdk: + + .. code-block:: text + + # cat /etc/sudoers.d/zvmsdk + zvmsdk ALL = (ALL) NOPASSWD:/usr/sbin/vmcp, /opt/zthin/bin/smcli, /usr/sbin/chccwdev, /usr/sbin/cio_ignore, /usr/sbin/fdasd, /usr/sbin/fdisk, /usr/sbin/vmur, /usr/bin/mount, /usr/bin/umount, /usr/sbin/mkfs, /usr/sbin/mkfs.xfs, /usr/sbin/dasdfmt, /opt/zthin/bin/unpackdiskimage, /opt/zthin/bin/creatediskimage, /opt/zthin/bin/linkdiskandbringonline, /opt/zthin/bin/offlinediskanddetach + +* Setup home directory + + .. code-block:: text + + # mkdir -p /var/lib/zvmsdk + # chown -R zvmsdk:zvmsdk /var/lib/zvmsdk + # chmod -R 755 /var/lib/zvmsdk + +* Setup log directory + + The folder to which the z/VM SDK log would be written to can be configured with the 'log_dir' + option in 'default' section. By default, the log folder is '/var/log/zvmsdk'. If you have customized + the 'log_dir' value, you need to change the folder in following commands accordingly. + + .. code-block:: text + + # mkdir -p /var/log/zvmsdk + # chown -R zvmsdk:zvmsdk /var/log/zvmsdk + # chmod -R 755 /var/log/zvmsdk + +* Setup configuration directory + + .. code-block:: text + + # mkdir -p /etc/zvmsdk + # chown -R zvmsdk:zvmsdk /etc/zvmsdk + # chmod -R 755 /etc/zvmsdk + # ls -l /etc/zvmsdk + + A file named zvmsdk.conf should be found under /etc/zvmsdk folder and contains at least all the required + options before the z/VM SDK daemon can be started. + +SSH key authentication between consumer and BYOL server +======================================================= + +For image import/export function, BYOL's running user(eg zvmsdk) needs to be +authorized by the user of the consumer (eg nova-compute) if they are not in +same host. For example, if you want to import/export image from/to nova +compute server,please make ensure you can ssh nova@nova-compute-ip without +password from zvmsdk user on BYOL server. Refer to the following steps to +configure it: + +Logon to the nova-compute server and change the nova user’s right to be +able to log in, and make sure port 22 is open. + +.. code-block:: text + + ssh root@nova-compute-ip + usermod -s /bin/bash nova + +where: +nova-compute-ip: is the IP address of the nova compute node. + +Change to nova user and inject the zvmsdk server's public key into it. + +.. code-block:: text + + su - nova + scp zvmsdk@zvmsdk-ip:/var/lib/zvmsdk/.ssh/id_rsa.pub $HOME mkdir -p $HOME/.ssh + mv $HOME/id_rsa.pub $HOME/.ssh/authorized_keys + +where: +zvmsdk: is the user on the BYOL server that runs the z/VM SDK. +zvmsdk-ip: is the IP address of the BYOL server +Note: If the $HOME/.ssh/authorized_keys file already exists, +you just need to append the BYOL’s public key to it. + +Ensure that the file mode under the $HOME/.ssh folder is 644. + +.. code-block:: text + + chmod -R 644 $HOME/.ssh/* + +Issue the following command to determine if SELinux is enabled on the system. + +.. code-block:: text + + getenforce + +If SELinux is enabled then set SELinux contexts on the nova home directory. + +.. code-block:: text + + su - + chcon -R -t ssh_home_t nova_home + +where: +nova_home:is the home directory for the nova user on the nova compute server. +You can obtain nova_home by issuing: echo ~nova + +**NOTE:** If the host key of nova-compute server changed, please run +the following command on zvmsdk server to clean the cached host key of +nova-compute server from zvmsdk server's known_hosts file + +.. code-block:: text + + ssh-keygen -R nova-compute-ip + +Start z/VM SDK Daemon +===================== + +Configure the sdkserver service to start automatically at boot by command: +.. code-block:: text + + # systemctl enable sdkserver + +The z/VM SDK Daemon can be started via the following command: + +.. code-block:: text + + # systemctl start sdkserver + +And make sure the sdkserver service status is 'active (running)' as following: + +.. code-block:: text + + # systemctl status sdkserver + ● sdkserver.service - zVM SDK API server + Loaded: loaded (/usr/lib/systemd/system/sdkserver.service; disabled; vendor preset: disabled) + Active: active (running) since Mon 2017-11-20 00:47:18 EST; 3s ago + Main PID: 5779 (sdkserver) + CGroup: /system.slice/sdkserver.service + └─5779 /usr/bin/python /usr/bin/sdkserver + + Nov 20 00:47:18 0822rhel7 systemd[1]: Started zVM SDK API server. + Nov 20 00:47:18 0822rhel7 systemd[1]: Starting zVM SDK API server... + Nov 20 00:47:18 0822rhel7 sdkserver[5779]: INFO: [MainThread] SDK server now listening + +Verification +============ + +You can verify that the process is listenning on the configured port. +For example: + +.. code-block:: text + + # netstat -anp | grep 2000 + tcp 0 0 127.0.0.1:2000 0.0.0.0:* LISTEN 56434/python diff --git a/doc/html/_sources/resize.rst.txt b/doc/html/_sources/resize.rst.txt new file mode 100644 index 000000000..edc0be18d --- /dev/null +++ b/doc/html/_sources/resize.rst.txt @@ -0,0 +1,131 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +Resize Image to a Bigger Size +***************************** + +This section provides info on how resize an image to a bigger size disk +during deploy process was performed. + +The following sample describes: + +1. Create a 3390 disk with 2300 cylinders. + +2. Capture the disk and make it a deployable image. + +3. Deploy the image (this sample use openstack) to larger number cylinders, this sample using 10G disk size, which is 14564 cylinders. + +4. After deploy, the new spawned guest has 10G disk size. + +5. Note only the size of last partition has been enlarged. + +.. note:: + Following test result only tested on SLES12SP4 for now. + +Flow of resize +-------------- + +Create a 3390 disk with 2300 cylinders has 2 partitions. + + .. code-block:: text + + q v dasd + 00: DASD 0100 3390 JM6013 R/W 2300 CYL ON DASD 6013 SUBCHANNEL = 0001 + + # lsdasd + Bus-ID Status Name Device Type BlkSz Size Blocks + ============================================================================== + 0.0.0100 active dasda 94:0 ECKD 4096 1617MB 414000 + + # fdasd --table /dev/dasda + WARNING: Your DASD '/dev/dasda' is in use. + If you proceed, you can heavily damage your system. + If possible exit all applications using this disk + and/or unmount it. + + reading volume label ..: VOL1 + reading vtoc ..........: ok + + Disk /dev/dasda: + cylinders ............: 2300 + tracks per cylinder ..: 15 + blocks per track .....: 12 + bytes per block ......: 4096 + volume label .........: VOL1 + volume serial ........: 0X0100 + max partitions .......: 3 + + ------------------------------- tracks ------------------------------- + Device start end length Id System + /dev/dasda1 2 4267 4266 1 Linux native + /dev/dasda2 4268 34499 30232 2 Linux native + exiting... + + # parted /dev/dasda print + Model: IBM S390 DASD drive (dasd) + Disk /dev/dasda: 1696MB + Sector size (logical/physical): 512B/4096B + Partition Table: dasd + Disk Flags: + + Number Start End Size File system Flags + 1 98.3kB 210MB 210MB ext2 + 2 210MB 1696MB 1486MB ext4 + +The disk size of the guest where the sles12 sp4 image was deployed using openstack.: + + .. code-block:: text + + # openstack flavor list + | ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public | + | d80df349-e277-4c08-a578-10dd8ff5ba02 | zvm-small | 2048 | 10 | 0 | 2 | True | + + # openstack server show s124-2part-ext4 + | flavor | zvm-small (d80df349-e277-4c08-a578-10dd8ff5ba02) | + + s124-2part-ext4:~ # vmcp q v dasd + DASD 0100 3390 JM601B R/W 14564 CYL ON DASD 601B SUBCHANNEL = 0003 + + s124-2part-ext4:~ # lsdasd + Bus-ID Status Name Device Type BlkSz Size Blocks + ============================================================================== + 0.0.0100 active dasda 94:0 ECKD 4096 10240MB 2621520 + + s124-2part-ext4:~ # fdasd --table /dev/dasda + + WARNING: Your DASD '/dev/dasda' is in use. + If you proceed, you can heavily damage your system. + If possible exit all applications using this disk + and/or unmount it. + + reading volume label ..: VOL1 + reading vtoc ..........: ok + + Disk /dev/dasda: + cylinders ............: 14564 + tracks per cylinder ..: 15 + blocks per track .....: 12 + bytes per block ......: 4096 + volume label .........: VOL1 + volume serial ........: 0X0100 + max partitions .......: 3 + + ------------------------------- tracks ------------------------------- + Device start end length Id System + /dev/dasda1 2 4267 4266 1 Linux native + /dev/dasda2 4268 218459 214192 2 Linux native + exiting... + + s124-2part-ext4:~ # parted /dev/dasda print + Model: IBM S390 DASD drive (dasd) + Disk /dev/dasda: 10.7GB + Sector size (logical/physical): 512B/4096B + Partition Table: dasd + Disk Flags: + + Number Start End Size File system Flags + 1 98.3kB 210MB 210MB ext2 + 2 210MB 10.7GB 10.5GB ext4 + +The last partition on dasda was the partition that was expanded to fill the remainder of the ECKD disk . diff --git a/doc/html/_sources/restapi.rst.txt b/doc/html/_sources/restapi.rst.txt new file mode 100644 index 000000000..917b66786 --- /dev/null +++ b/doc/html/_sources/restapi.rst.txt @@ -0,0 +1,2170 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +RESTful APIs +************ + +This is a reference for the Feilong RESTful API. + +Response Data Definition +======================== + +The following table gives a reference of general response data definition +of each Feilong RESTful API. In case of encountering an error, +those information will be helpful to report bug/issue. + +.. restapi_parameters:: parameters.yaml + + - overallRC: ret_overallrc + - rc: ret_rc + - rs: ret_rs + - errmsg: ret_errmsg + - modID: ret_modID + - output: ret_output + +The following detail API description will only cover ``output`` part as +it's different for each API. +(This document is a beta version now) + +Version +======= +Lists version of this API. + +Get Feilong version +------------------------------- + +**GET /** + +* Request: + + No parameters needed. + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + Return the version of the zvm cloud connect API. + +.. restapi_parameters:: parameters.yaml + + - output : ret_output + - api_version: api_version_sdk + - min_version: min_version_sdk + - max_version: max_version_sdk + - version: version_sdk + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_version.tpl + :language: javascript + +Token +===== + +Create token +------------ + +**POST /token** + +Get a valid token to perform further request by using Admin-Token which +you can think as a combination of username and password. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - X-Admin-Token: token_admin + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - X-Auth-Token: auth_token + +* Response sample: + + Please refer to :ref:`TokenUsage` to get more details. + +SMAPI Health +============ + +Report health of SMAPI +---------------------- + +**GET /smapi_health** + +Get health status of the SMAPI. + +* Request: + + None + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: smapi_health_report + - totalSuccess: totalSuccess + - totalFail: totalFail + - lastSuccess: lastSuccess + - lastFail: lastFail + - continuousFail: continuousFail + - healthy: healthy + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_smapi_health.tpl + :language: javascript + +* Note: + + Old API call **GET /smapi-healthy** is deprecated. + +Guest(s) +======== + +Lists, creates, shows details for, updates, and deletes guests. + +List Guests +----------- + +**GET /guests** + +List names of all the guests created by Feilong. + +* Request: + + None + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: guest_list + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guests_list.tpl + :language: javascript + +Create Guest +------------ + +**POST /guests** + +Create a vm in z/VM + +* Request: + +.. restapi_parameters:: parameters.yaml + + - guest: guest_dict + - userid: userid_create + - vcpus: guest_vcpus + - memory: guest_memory + - user_profile: user_profile_guest + - disk_list: disk_list_guest + - size: size_disk + - format: format_disk + - is_boot_disk: is_boot_disk + - vdev: add_mdisk_disk_vdev + - disk_pool: disk_pool_guest + - max_cpu: guest_max_cpu + - max_mem: guest_max_mem + - ipl_from: guest_ipl_from + - ipl_param: guest_ipl_param + - ipl_loadparam: guest_ipl_loadparam + - dedicate_vdevs: guest_dedicate_vdevs + - loaddev: guest_loaddev + - account: guest_account + - comment_list: guest_comment_list + + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_create.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: disk_list_output + - vdev: vdev_disk + - size: size_output + - format: format_disk + - is_boot_disk: is_boot_disk + - disk_pool: disk_pool_output + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_disk_output.tpl + :language: javascript + +Get guest minidisks info +------------------------ + +**GET /guests/{userid}/disks** + +List characteristics of all disks of a guest + +* Request: + + None + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - minidisks: minidisks_guest + - vdev: get_mdisk_disk_vdev + - rdev: rdev_disk + - access_type: access_type + - device_size: size_no_unit + - device_units: device_units + - volume_label: volume_label + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_disk_info_output.tpl + :language: javascript + +Guest add disks +--------------- + +**POST /guests/{userid}/disks** + +Add disks for a guest + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - disk_info: disk_info + - disk_list: disk_list_guest + - size: size_disk + - format: format_disk + - is_boot_disk: is_boot_disk + - vdev: add_mdisk_disk_vdev + - disk_pool: disk_pool_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_add_disks.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: disk_list_output + - vdev: vdev_disk + - size: size_output + - format: format_disk + - is_boot_disk: is_boot_disk + - disk_pool: disk_pool_output + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_disk_output.tpl + :language: javascript + +Guest configure disks +--------------------- + +**PUT /guests/{userid}/disks** + +Configure additional disks for a guest + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - disk_info: disk_info + - disk_list: additional_disk_guest + - vdev: disk_vdev + - format: format_disk_required + - mntdir: disk_mountpoint + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_config_disks.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No Response + +Guest delete disks +------------------ + +**DELETE /guests/{userid}/disks** + +Delete disks form a guest that in shutdown state + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - vdev_info: vdev_info + - vdev_list: disk_vdev_list + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_delete_disks.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No Response + +.. note:: + + Not support delete disks when guest is active + +Attach Volume +------------- + +**POST /guests/volumes** + +Attach volume to a vm in z/VM + +* Request: + +.. restapi_parameters:: parameters.yaml + + - info: volume_info + - connection: volume_conn + - assigner_id: assigner_id + - zvm_fcp: fcp_list + - target_wwpn: volume_wwpn + - target_lun: volume_lun + - os_version: guest_os_version + - multipath: guest_multipath + - mount_point: mount_point + - is_root_volume: root_volume + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_volume_attach_detach.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No Response + +Detach Volume +------------- + +**DELETE /guests/volumes** + +Detach volume from a vm in z/VM + +* Request: + +.. restapi_parameters:: parameters.yaml + + - info: volume_info + - connection: volume_conn + - assigner_id: assigner_id + - zvm_fcp: fcp_list + - target_wwpn: volume_wwpn + - target_lun: volume_lun + - os_version: guest_os_version + - multipath: guest_multipath + - mount_point: mount_point + - is_root_volume: root_volume + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_volume_attach_detach.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No Response + +Get Guests stats including cpu and memory +----------------------------------------- + +**GET /guests/stats** + +Get guests cpu, memory information. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: userid_list_guest + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: stats_guest + - guest_cpus: guest_cpus + - used_cpu_time_us: used_cpu_time_us + - elapsed_cpu_time_us: elapsed_cpu_time_us + - min_cpu_count: min_cpu_count + - max_cpu_limit: max_cpu_limit + - samples_cpu_in_use: samples_cpu_in_use + - samples_cpu_delay: samples_cpu_delay + - used_mem_kb: used_mem_kb + - max_mem_kb: max_mem_kb + - min_mem_kb: min_mem_kb + - shared_mem_kb: shared_mem_kb + - total_memory: total_memory + - available_memory: available_memory + - free_memory: free_memory + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guests_get_stats.tpl + :language: javascript + +Get Guests interface stats +-------------------------- + +**GET /guests/interfacestats** + +Get guests network interface statistics. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: userid_list_guest + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: guest_vnics + - vswitch_name: vswitch_name_opt + - nic_vdev: nic_interface + - nic_fr_rx: nic_fr_rx + - nic_fr_tx: nic_fr_tx + - nic_fr_rx_dsc: nic_fr_rx_dsc + - nic_fr_tx_dsc: nic_fr_tx_dsc + - nic_fr_rx_err: nic_fr_rx_err + - nic_fr_tx_err: nic_fr_tx_err + - nic_rx: nic_rx + - nic_tx: nic_tx + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guests_get_interface_stats.tpl + :language: javascript + +Get Guests nic info +--------------------- + +**GET /guests/nics** + +Get guests nic information, including userid, nic number, vswitch, nic id and comments. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid_opt + - nic_id: nic_id_opt + - vswitch: vswitch_name_opt + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: guests_nic_info + - userid: nic_userid + - interface: nic_interface + - switch: vswitch_name_body + - port: nic_port + - comments: nic_comments + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guests_get_nic_info.tpl + :language: javascript + +Show Guest definition +--------------------- + +**GET /guests/{userid}** + +Display the user direct by the given userid. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: user_direct_guest + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_get.tpl + :language: javascript + +Delete Guest +------------ + +**DELETE /guests/{userid}** + +Delete a guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No Response + + +Get Guest power state from hypervisor +-------------------------------------- + +**GET /guests/{userid}/power_state_real** + +Get power state of the guest from hypervisor directly, + +no matter the guest is in zcc database or not. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: power_status_guest + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_get_power_state_real.tpl + :language: javascript + + +Get Guest info +-------------- + +**GET /guests/{userid}/info** + +Get running information of guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: guest_info + - max_mem_kb: guest_memory_kb_max + - num_cpu: num_cpu_guest + - cpu_time_us: cpu_time_us_guest + - power_state: power_status_guest + - mem_kb: guest_memory_kb + - online_cpu_num: online_cpu_num_guest + - os_distro: os_distro_guest + - kernel_info: kernel_info_guest + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_get_info.tpl + :language: javascript + + +Get Guest user direct +--------------------- + +**GET /guests/{userid}/user_direct** + +Get the user directory info of the given userid from hypervisor. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: user_direct_guest + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_get_user_direct.tpl + :language: javascript + + +Get Guest adapters info +----------------------- + +**GET /guests/{userid}/adapters** + +Get adapters information of running guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: adapters_info_output + - lan_owner: guest_userid + - lan_name: vswitch_name + - adapter_address: vdev_number + - adapter_status: adapter_status + - mac_address: mac_address + - mac_ip_address: ip_address + - mac_ip_version: ip_version + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_get_adapters_info.tpl + :language: javascript + +Create Guest nic +---------------- + +**POST /guests/{userid}/nic** + +Create a virtual nic on giving guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - nic: nic_set_info + - vdev: vdev_number_orNone + - nic_id: nic_identifier + - mac_addr: mac_address + - active: active_flag + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_create_nic.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Create network interface +------------------------ + +**POST /guests/{userid}/interface** + +Create one or more network interfaces on giving guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - interface: network_interface_info + - os_version: guest_os_version + - guest_networks: guest_networks_list + - active: active_flag + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_create_network_interface.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Delete network interface +------------------------ + +**DELETE /guests/{userid}/interface** + +Delete one network interface on giving guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - interface: network_interface_info + - os_version: guest_os_version + - vdev: nic_interface + - active: active_flag + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_delete_network_interface.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Start guest +----------- + +Start a guest. + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_start_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_start_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Stop guest +---------- + +Stop a guest. + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_stop_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_stop_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Softstop guest +-------------- + +Stop a guest gracefully, it will firstly shutdown the os on vm, then stop the vm. + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_softstop_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_softstop_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Pause guest +----------- + +Pause a guest. + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_pause_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_pause_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Unpause guest +------------- + +Unpause a guest. + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_unpause_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_unpause_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Reboot guest +------------ + +Reboot a guest, this will use 'reboot' command on the +given guest. + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_reboot_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_reboot_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Reset guest +----------- + +Reset a guest, this will first gracefully logoff the guest from +z/VM it is running on, then log on the guest and IPL. + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_reset_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_reset_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Get guest console output +------------------------ + +**POST /guests/{userid}/action** + +Get console output of guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_get_console_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_get_console_output_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + - output: console_output + +.. note:: + + In order to retrieve the console log from guest vm, you must add user direct + statment "COMMAND SP CONS * START" to the profile that used to deploy guest + vm, otherwise no console log collected for the guest vm. + +Live migration of guest +----------------------- + +**POST /guests/{userid}/action** + +Live migrate guest in z/VM SSI cluster. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_live_migrate_guest + - dest_zcc_userid: dest_zcc_userid + - destination: lgr_destination + - parms: lgr_parms + - lgr_action: lgr_action + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_live_migrate.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Guest register +-------------- + +**POST /guests/{userid}/action** + +Register guest to be managed by Feilong. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_register_guest + - meta: guest_register_meta + - net_set: guest_register_net_set + - port: guest_register_port_macs + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_register.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Guest deregister +---------------- + +**POST /guests/{userid}/action** + +Deregister guest to be managed by Feilong. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_deregister_guest + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_deregister.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Live resize CPUs of guest +------------------------- + +**POST /guests/{userid}/action** + +Live resize CPUs of guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_live_resize_cpus_of_guest + - cpu_cnt: cpu_cnt + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_live_resize_cpus_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. note:: + + - Currently only increasing CPU count is supported, decreasing is not supported. + - The guest to be live resized must be active and managed by Feilong. + - If live resize finished successfully, both the active CPU number and the number of + defined CPUs in user directory would be updated to the requested so that the CPU + count would persist even after the guest is restarted. + - If requested CPU count is smaller than the current active CPU count, then the API + would return error immediately since lively decrease CPU count is not supported. + - If requested CPU count is larger than the defined CPU number in user directory, + this API would increase the CPU number in user directory to requested count. + Otherwise, this API would decrease the CPU number in user directory to the requested + count. + - To live resize a guest, the guest must have maximum CPU count defined in user + directory entry with "MACHINE ESA xx" where 'xx' is the maximum CPU count. The + resize CPU count can't exceed the maximum CPU count. + - For guests created by Feilong after version 1.2.0, the maximum CPU + count is defined when the guest is created. The maximum CPU count is set by the configuration + "user_default_max_cpu" in [zvm] section and can be overriden by the parameter "max_cpu" when + creating the guest. e.g, the following configuration would define the default maximum CPU count + as 64. + + .. code-block:: text + + [zvm] + user_default_max_cpu=64 + +Resize CPUs of guest +------------------------- + +**POST /guests/{userid}/action** + +Resize CPUs of guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_resize_cpus_of_guest + - cpu_cnt: cpu_cnt + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_resize_cpus_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. note:: + + - Both increasing and decreasing CPU count are supported. + - The target guest can be in either 'on' or 'off' status, the definition change would + take into effects after logoff and re-logon (reset). + +Live resize memory of guest +--------------------------- + +**POST /guests/{userid}/action** + +Live resize memory of guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_live_resize_mem_of_guest + - size: mem_size + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_live_resize_mem_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. note:: + + - Currently only increasing memory size is supported, decreasing is not supported. + - The guest to be live resized must be active and managed by Feilong. + - If live resize finished successfully, both the active memory and the initial memory + defined in user directory would be updated to the requested size so that the change + would persist even after the guest is restarted. + - If requested memory size is smaller than the current active memory, then the API + would return error immediately since lively decrease memory size is not supported. + - If requested memory size is larger than the defined initial memory in user directory, + this API would increase the initial memory defined in user directory to requested size. + Otherwise, this API would decrease the memory in user directory to the requested + size. + - The resize memory size can't exceed the maximum memory defined in user directory. + - The maximum memory size is defined when the guest is created. It is set by the configuration + "user_default_max_memory" in [zvm] section and can be overriden by the parameter "max_mem" when + creating the guest. e.g, the following configuration would define the default maximum memory size + as 64G. + + .. code-block:: text + + [zvm] + user_default_max_memory=64g + +Resize memory of guest +---------------------- + +**POST /guests/{userid}/action** + +Resize memory of guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_resize_mem_of_guest + - size: mem_size + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_resize_mem_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. note:: + + - Both increasing and decreasing memory size are supported. + - The target guest can be in either 'on' or 'off' status, the definition change would + take into effects after logoff and re-logon (reset). + +Deploy guest +------------ + +**POST /guests/{userid}/action** + +After guest created, deploy image onto the guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_deploy_guest + - image: image_name + - transportfiles: transportfiles + - remotehost: remotehost_transportfiles + - vdev: deploy_vdev + - hostname: deploy_hostname + - skipdiskcopy: deploy_skipdiskcopy + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_deploy_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Capture guest +------------- + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_capture_guest + - image: image_name + - capture_type: capture_type + - compress_level: compress_level + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_capture_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Grow root volume of guest +------------------------- + +**POST /guests/{userid}/action** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - action: action_grow_root_volume_guest + - os_version: guest_os_version + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_grow_root_volume_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +Get Guest power state +--------------------- + +**GET /guests/{userid}/power_state** + +Get power state of the guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + +* Response code: + + HTTP status code 200 on success. + HTTP status code 404 if guest is not in zcc database + or it is in zcc database but its user directory does not exist. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: power_status_guest + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_get_power_state.tpl + :language: javascript + +Update Guest nic +---------------- + +**PUT /guests/{userid}/nic/{vdev}** + +Couple or uncouple nic with vswitch on the guest. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - vdev: vdev_guest + - info: couple_info + - couple: couple_action + - active: active_flag + - vswitch: vswitch_name_body_opt + - vlan_id: vlan_id + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_guest_couple_uncouple_nic.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +Delete Guest nic +---------------- + +**DELETE /guests/{userid}/nic/{vdev}** + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - vdev: vdev_guest + - active: active_flag + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +Host +==== + +Get guests list, info from host (hypervisor) running on. + +Get Guests List +--------------- + +**GET /host/guests** + +List names of all the guests on the host. + +* Request: + + None + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: guest_list + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_host_get_guest_list.tpl + :language: javascript + +Get info from host (hypervisor) running on. + +Get Host Info +------------- + +**GET /host** + +Get host information. + +* Request: + + No parameters needed. + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: host_info + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_host_info.tpl + :language: javascript + +Get Host disk pool info +----------------------- + +**GET /host/diskpool** + +Get disk pool information(or the free space among all volumes in the disk pool) on the host. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - poolname: disk_pool + - details: details + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - disk_available: disk_info_available + - disk_total: disk_info_total + - disk_used: disk_info_used + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_host_disk_info.tpl + :language: javascript +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_host_disk_details_info.tpl + :language: javascript + +Get host disk pool volume names +------------------------------- + +**GET /host/diskpool_volumes** + +Get volume list of the diskpool on the host. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - poolname: disk_pool + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - diskpool_volumes: diskpool_volumes + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_host_disk_volumes.tpl + :language: javascript + +Get host volume info +------------------------------- + +**GET /host/volume** + +Get the volume info on the host. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - volumename: volume + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - volume_type: volume_type + - volume_size: volume_size + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_host_volume.tpl + :language: javascript + +Get Host SSI Cluster Info +------------------------- + +**GET /host/ssi** + +Get the SSI(Single System Image) cluster information of the host. + +* Request: + + No parameters needed. + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: host_ssi_info + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_host_ssi_info.tpl + :language: javascript + +Image(s) +======== + +Lists, creates, shows details for, updates, and deletes images. + +List images +----------- + +**GET /images** + +Get the list of image info in image repository. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - imagename: imagename + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: image_info + - imagename: image_name + - imageosdistro: guest_os_version + - md5sum: image_md5sum + - disk_size_units: root_disk_size_image + - image_size_in_bytes: physical_disk_size_image + - type: image_type + - comments: image_comments + - last_access_time: last_access_time + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_image_query.tpl + :language: javascript + +Create image +------------ + +**POST /images** + +Import an image into image repository + +* Request: + +.. restapi_parameters:: parameters.yaml + + - image: image_dict + - image_name: image_name + - url: image_import_url + - image_meta: image_metadata + - remote_host: remotehost_image_import + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_image_create_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +Export image +------------ + +**PUT /images/{name}** + +Export the image to the specified location. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: image_name_path + - location: image_export_location + - dest_url: image_export_url + - remote_host: remotehost_image_export + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_image_export_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: export_image_dict + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_image_export_res.tpl + :language: javascript + +Get root disk size of image +--------------------------- + +**GET /images/{name}/root_disk_size** + +Get the root disk size of the image. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: image_name_path + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: root_disk_size_image + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_image_get_root_disk_size.tpl + :language: javascript + +Delete image +------------ + +**DELETE /images/{name}** + +Delete an image. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: image_name_path + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +VSwitch +======= + +Lists, creates, updates, and deletes vswitch. + +Create vswitch +-------------- + +**POST /vswitches** + +Create a new vswitch. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: vswitch_name_body + - rdev: rdev_vswitch + - controller: controller_vswitch + - connection: connection_vswitch + - network_type: network_type_vswitch + - router: router_vswitch + - vid: vid_vswitch + - port_type: port_type_vswitch + - gvrp: gvrp_vswitch + - queue_mem: queue_mem_vswitch + - native_vid: native_vid_vswitch + - persist: persist_option_vswitch + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_vswitch_create.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +List vswitches +-------------- + +**GET /vswitches** + +Get the list of vswitch name on the host + +* Request: + + No parameter needed. + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: vswitch_list + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_vswitch_get.tpl + :language: javascript + +GET vswitch details +------------------- + +**GET /vswitches/{name}** + +Get the details of a vswitch + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: vswitch_name + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: vswitch_details + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_vswitch_query.tpl + :language: javascript + +Grant user to vswitch +--------------------- + +**PUT /vswitches/{name}** + +Grant an user to access vswitch + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: vswitch_name + - vswitch: vswitch_info + - grant_userid: grant_userid + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_vswitch_update_req.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +Revoke user from vswitch +------------------------ + +**PUT /vswitches/{name}** + +Revoke the user access from vswitch + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: vswitch_name + - vswitch: vswitch_info + - revoke_userid: grant_userid + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_vswitch_update_revoke.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +Set user VLANID to vswitch +-------------------------- + +**PUT /vswitches/{name}** + +Set vlan id for user when connecting to the vswitch + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: vswitch_name + - vswitch: vswitch_info + - user_vlan_id: user_vlan_id + - userid: grant_userid + - vlanid: vlan_id + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_vswitch_set_vlan.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +Delete vswitch +-------------- + +**DELETE /vswitches/{name}** + +Delete a vswitch by using given name. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - name: vswitch_name + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +Volume(s) +========= + +Handling of volumes and FCP devices. + +Refresh Volume Bootmap Info +--------------------------- + +**PUT /volumes/volume_refresh_bootmap** + +Refresh a volume's bootmap info. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - fcpchannel: fcp_list + - wwpn: wwpn_list + - lun: lun + - transportfiles: transportfiles + - guest_networks: guest_networks + +* Request sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_refresh_bootmap.tpl + :language: javascript + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_refresh_bootmap_response.tpl + :language: javascript + +Get Volume Connector +-------------------- + +**GET /volumes/conn/{userid}** + +Get volume connector for z/VM. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - userid: guest_userid + - reserve: fcp_reserve + +* Response code: + + HTTP status code 200 on success. + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_get_volume_connector.tpl + :language: javascript + +Get FCP Usage +-------------------- + +**GET /volumes/fcp/{fcp_id}** + +Get the FCP usage in database for z/VM. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - fcp_id: fcp_id + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: fcp_usage + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_get_fcp_usage.tpl + +Set FCP Usage +------------- + +**PUT /volumes/fcp/{fcp_id}** + +Set the FCP usage in database for z/VM. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - fcp_id: fcp_id + - userid: fcp_userid + - reserved: fcp_reserve + - connections: fcp_connections + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + + No response. + +Files +===== +Imports and exports raw file data. + +These operations may be restricted to Feilong administrators. + +Import file +----------- + +**PUT /files** + +Import binary file data to Feilong. Internal use Only.Please set +the Content-Type of the request header to application/octet-stream. The body +contains the binary data. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - Content-type: file_request_header + +* Example call: + + curl http://192.168.99.3:8888/files -i -X PUT -H "X-Auth-Token: $token" -H + "Content-Type: application/octet-stream" --data-binary @/root/testfile + +* Response code: + + HTTP status code 200 on success. + +* Response contents: + +.. restapi_parameters:: parameters.yaml + + - output: file_import_output + - dest_url: file_import_dest_url + - filesize_in_bytes: imported_file_size + - md5sum: file_md5sum + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_file_import_res.tpl + :language: javascript + + +Export file +----------- + +**POST /files** + +Export file from Feilong, internal use only. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - source_file: export_source_file + +* Response code: + + HTTP status code 200 on success. + +The response body contains the raw binary data that represents the actual file. +The Content-Type header contains the application/octet-stream value. + + +Get Switch information based on port id +--------------------------------------- + +**GET /switch** + +Get Switch information based on port id. + +* Request: + +.. restapi_parameters:: parameters.yaml + + - portid: port_id + +* Response code: + + HTTP status code 200 on success. + +* Response sample: + +.. literalinclude:: ../../zvmsdk/tests/fvt/api_templates/test_get_switch_record.tpl + :language: javascript + diff --git a/doc/html/_sources/sample.rst.txt b/doc/html/_sources/sample.rst.txt new file mode 100644 index 000000000..720946cd2 --- /dev/null +++ b/doc/html/_sources/sample.rst.txt @@ -0,0 +1,111 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +Basic Usage +*********** + +This section introduces the basics of using Feilong to manage z/VM host, and gives some usage examples. + +Workflow description +==================== + +Spawning a virtual machine +-------------------------- + +.. image:: ./images/spawn_flow.jpg + +1) Image import from external image repository into Feilong; for one image, this only needs to be done once +2) Store the information into DB record +3) Call from upper layer to create a guest +4) SMAPI calls DIRMAINT to define a user direct +5) Call from upper layer to deploy a guest +6) Feilong then starts to copy disk contents from image to the disks allocated in step 3 +7) Post deploy actions such as network setup, and send customized files from Feilong to the newly deployed VM +8) Start the VM +9) During first power on of the VM, set up the network and utilize the customized files to update network, hostname etc (by default, using cloud-init) + +Creating a vswitch +------------------ + +.. image:: ./images/create_vswitch_flow.jpg + +1) Call from upper layer to trigger the Vswitch create call +2) HTTP service (Feilong REST API) gets the request and handles it to Feilong server +3) SMAPI is then called and handles the VSWITCH create command, this will include persistent definition of Vswitch and define it in z/VM CP +4) CP is called to create vswitch on the fly + +Usage Examples +============== + +The following examples show how to spawn a new VM, both in bash and in python. + +Note: other language bindings exist, for example for golang. + +In these examples, the Feilong connector runs at the IP address 1.2.3.4. + +From the command line +--------------------- + +* Create a parameters file named "create-guest-id001.json": + + .. code-block:: text + + { + "guest": + { + "userid": "myguest", + "vcpus": 2, + "memory": 2048, + "user_profile": "osdflt", + "disk_list": [ + { + "size": "5g", + "is_boot_disk": true, + "disk_pool": "ECKD:vmpool" + } ], + "max_cpu": 4, + "max_mem": "4G" + } + } + +* Call "curl" command, referring to this parameters file: + + .. code-block:: text + + $ curl -s -X POST \ + -H "Content-Type: application/json" \ + -d @create-guest-id001.json \ + http://1.2.3.4/guests | jq + +From python language +-------------------- + + .. code-block:: text + + from zvmconnector import connector + + userid = 'myguest' + vcpus = 2 + memory = 2048 + user_profile = 'osdflt' + disk_list = [ + { + 'size': "5g", + 'is_boot_disk': True, + 'disk_pool': 'ECKD:vmpool' + } ] + max_cpu = 4 + max_mem = '4G' + + client = connector.ZVMConnector( + connection_type = 'rest', ip_addr = '1.2.3.4', port = '80') + + guest_create_info = client.send_request( + 'guest_create', userid, vcpus, memory, + disk_list = disk_list, user_profile = user_profile, max_cpu = max_cpu, max_mem = max_mem) + + if guest_create_info['overallRC']: + raise RuntimeError('Failed to create guest: ' + guest_create_info['errmsg']) + + print('Guest created') diff --git a/doc/html/_sources/setuphttpd.rst.txt b/doc/html/_sources/setuphttpd.rst.txt new file mode 100644 index 000000000..600b5fb66 --- /dev/null +++ b/doc/html/_sources/setuphttpd.rst.txt @@ -0,0 +1,427 @@ +.. + Copyright Contributors to the Feilong Project. + SPDX-License-Identifier: CC-BY-4.0 + +.. _`Setup web server for running RESTful API`: + +Setup web server for running RESTful API +**************************************** + +Introduction +============ + +Each Feilong API is exposed through a RESTful interface, higher level +systems can manage z/VM by consuming these RESTful APIs directly. + +This chapter describes how to setup a web server for hosting the Feilong RESTful APIs. + +The recommended deployment for Feilong is to have a web server such as +Apache httpd or nginx handle the HTTP connections and proxy requests to the independent +z/VM SDK server running under a wsgi container such as uwsgi +or directly connected via Apache's wsgi module. + +The detailed setup steps for each type of web server is out of this document's range, +you can refer to the specific guide of your chosen web server. This guide walks you through +the deployment process, either: + + * with premade packages (which use the mod_wsgi method); + * manually, with uwsgi; + * or manually, with Apache's mod_wsgi. + +This matrix represents the successful setup of different web servers across three Linux distributions. +The last section of this chapter details about using tokens to enhance security. + +====================== ================= ================= ================= +Tested RHEL 9.4 SLES 15 SP6 Ubuntu 24.04 +====================== ================= ================= ================= +Apache2 + uwsgi ✓ ✓ +Apache2 + mod_wsgi ✓ ✓ ✓ +nginx + uwsgi ✓ +====================== ================= ================= ================= + +Installing from packages +======================== + +Redhat Enterprise Linux +----------------------- + +The following instructions are for RHEL 9.4. +The RPM packages can be downloaded from https://download.opensuse.org/repositories/Virtualization:/feilong/AlmaLinux_9/ . + +Install the downloaded packages `zthin` and `zvmsdk` using the `yum` or `dnf` command +If not already done, enable the automatic startup of the Apache server, and then start it: + +..code-block:: text + + # systemctl enable httpd + # systemctl start httpd + +Finally, you can verify if the installation works as intended by making a curl request from your workstation + +..code-block:: text + + $ curl http://:8080/ + +By default, Feilong will listen on port 8080. +To change that, you need to modify both Apache configuration and firewall rules. + +SUSE Linux Enterprise Server +---------------------------- + +The following instructions are for SLES15 SP6. +The RPM packages can be downloaded from https://download.opensuse.org/repositories/Virtualization:/feilong/SLE_15_SP5/ + +Install the downloaded packages using the `zypper` command +If not already done, enable the automatic startup of the Apache server, and then start it: + +..code-block:: text + + # systemctl enable apache2 + # systemctl start apache2 + +Finally, you can verify if the installation works as intended by making a curl request from your workstation + +..code-block:: text + + $ curl http://:8080/ + +By default, Feilong will listen on port 8080. +To change that, you need to modify both Apache configuration and firewall rules. + +Ubuntu +------ + +The following instructions are for Ubuntu 24.04. +The RPM packages can be downloaded from https://download.opensuse.org/repositories/Virtualization:/feilong/xUbuntu_24.04/ + +Install the downloaded packages using the `apt` command +If not already done, enable the automatic startup of the Apache server, and then start it: + +..code-block:: text + + # systemctl enable apache2 + # systemctl start apache2 + +Finally, you can verify if the installation works as intended by making a curl request from your workstation + +..code-block:: text + + $ curl http://:8080/ + +By default, Feilong will listen on port 8080. +To change that, you need to modify both Apache configuration and firewall rules. + + +Apache2 + uwsgi +=============== + +Installation +------------ +The following packages need to be installed: + +* Apache httpd server +* Apache modules: mod_proxy_uwsgi +* uwsgi +* uwsgi plugin for python: uwsgi-plugin-python + +Configure uwsgi +--------------- + +Usually the configuration can be placed at /etc/uwsgi.d/ folder, for example, named as +/etc/uwsgi.d/your_config.ini. Update the file to match your system configuration. + +The sample below indicated the uwsgi service will be running at port 35000 +so apache server can connect port 35000 and communicate with it + +.. literalinclude:: ../../data/uwsgi-zvmsdk.conf + +Start Feilong in uwsgi +---------------------- + +* Create a uwsgi service + + Use following sample to create a uwsgi service for running the Feilong. + For RHEL7.2, put this file as /usr/lib/systemd/system/zvmsdk-wsgi.service. + + .. code-block:: text + + [Unit] + Description=Feilong uwsgi + After=syslog.target network.target httpd.service + + [Service] + Type=simple + ExecStart=/usr/sbin/uwsgi --ini /etc/uwsgi.d/your_config.ini + ExecReload=/usr/sbin/uwsgi --reload /etc/uwsgi.d/your_config.ini + ExecStop=/usr/sbin/uwsgi --stop /etc/uwsgi.d/your_config.ini + + [Install] + WantedBy=multi-user.target + +* Enable zvmsdk uwsgi service + + .. code-block:: text + + #systemctl enable zvmsdk-wsgi.service + +* Start zvmsdk uwsgi service + + .. code-block:: text + + #systemctl start zvmsdk-wsgi.service + +* Verify zvmsdk uwsgi service status + + Verify the zvmsdk uwsgi service is started normally and the status is active (running) + in the following command output. + + .. code-block:: text + + [root@0822rhel7 ~]# systemctl status zvmsdk-wsgi.service + ● zvmsdk-wsgi.service - Feilong uwsgi + Loaded: loaded (/usr/lib/systemd/system/zvmsdk-wsgi.service; disabled; vendor preset: disabled) + Active: active (running) since Tue 2017-11-21 21:58:06 EST; 13min ago + Main PID: 7227 (uwsgi) + CGroup: /system.slice/zvmsdk-wsgi.service + ├─7227 /usr/sbin/uwsgi --ini /etc/uwsgi.d/zvmsdk-wsgi.ini + ├─7229 /usr/sbin/uwsgi --ini /etc/uwsgi.d/zvmsdk-wsgi.ini + └─7230 /usr/sbin/uwsgi --ini /etc/uwsgi.d/zvmsdk-wsgi.ini + + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: your server socket listen backlog is limited to 100 connections + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: your mercy for graceful operations on workers is 60 seconds + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: mapped 402621 bytes (393 KB) for 2 cores + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: *** Operational MODE: preforking *** + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: *** uWSGI is running in multiple interpreter mode *** + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: spawned uWSGI master process (pid: 7227) + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: spawned uWSGI worker 1 (pid: 7229, cores: 1) + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: spawned uWSGI worker 2 (pid: 7230, cores: 1) + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: *** no app loaded. going in full dynamic mode *** + Nov 21 21:58:06 0822rhel7 uwsgi[7227]: *** no app loaded. going in full dynamic mode *** + + And the uwsgi process is listenning on port 35000: + + .. code-block:: text + + # netstat -anp | grep 35000 + tcp 0 0 127.0.0.1:35000 0.0.0.0:* LISTEN 7227/uwsgi + + # curl -v http://127.0.0.1:35000/ + * About to connect() to 127.0.0.1 port 35000 (#0) + * Trying 127.0.0.1... + * Connected to 127.0.0.1 (127.0.0.1) port 35000 (#0) + > GET / HTTP/1.1 + > User-Agent: curl/7.29.0 + > Host: 127.0.0.1:35000 + > Accept: */* + > + * Empty reply from server + * Connection #0 to host 127.0.0.1 left intact + curl: (52) Empty reply from server + +.. _`Configure Apache`: + +Configure Apache +---------------- + +Use the following sample as a start for apache to proxy requests to Feilong +wsgi service, copy the content to /etc/httpd/conf.d/zvmsdk.conf and update the file to match +your system and requirements. + +.. note:: + Sometimes the REST API call will takes some time to complete while the default timeout + is not enough to complete the handle of the request, for example, `Apache Timeout`_ + shows the default timeout value of Apache httpd server is 60, administrator need to + set a bigger value (for example 3600) to avoid time out error. + +.. _Apache Timeout: https://httpd.apache.org/docs/2.4/mod/core.html#timeout + +Under this sample's configuration settings, the httpd server will listen on port 8080 +and any incoming request on it will be redirected to zvmsdk wsgi which is listening +at port 35000 + +.. code-block:: text + + LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so + + Listen 8080 + + + ProxyPass / uwsgi://127.0.0.1:35000/ + + +SSL is strongly recommended for security considerations. Refer to the specific web server +documentation on how to enable SSL. + +Start Apache service +-------------------- + +.. code-block:: text + + #systemctl start httpd.service + +Verification +------------ + +Verify your settings after restart httpd servers (assume you are using above +configurations), if are you able to see similar output below, it means the zvmsdk +http service is running well. + +.. code-block:: text + + # curl http://localhost:8080/ + {"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": {"min_version": "1.0", "version": "1.0", "max_version": "1.0"}, "errmsg": ""} + + +Apache2 + mod_wsgi +================== + +Installation +------------ +The following packages need to be installed: + +* apache2 +* libapache2-mod-wsgi + +Configuration +------------- + +Create a vhost for Feilong in Apache. Copy the following content to +/etc/apache2/sites-available/zvmsdk_wsgi.conf and update the file to match your system and requirements. + +Then execute command "a2ensite zvmsdk_wsgi" to enable the site. + +.. code-block:: text + + Listen 8080 + + WSGIDaemonProcess zvmsdkwsgi user=zvmsdk group=zvmsdk processes=2 threads=5 + WSGIProcessGroup zvmsdkwsgi + + WSGIScriptAlias / /usr/bin/zvmsdk-wsgi + + Require all granted + + + + + Require all granted + + + + +SSL is strongly recommended for security considerations. Refer to the specific web server +documentation on how to enable SSL. + +* Start Apache service + + .. code-block:: text + + #systemctl start apache2.service + +Verification +------------ + +Verify your settings after restart httpd servers (assume you are using above +configurations), if are you able to see similar output below, it means the zvmsdk +http service is running well. + +.. code-block:: text + + # curl http://localhost:8080/ + {"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": {"min_version": "1.0", "version": "1.0", "max_version": "1.0"}, "errmsg": ""} + + +.. _`TokenUsage`: + + +Securing Connections with Tokens +================================ + +When you sending requests, you can use token authenticaion to enhance security of the connection between client and server. +Feilong use admin-token to authicate the safety of the connection instead of username&password. +In other words, admin-token is what you can think as a combination of traditional username&password. + +On client side, users should use this admin-token to request for a temporary token first. Then users can use +this temporary token to send requests. + +On server side, admninistrators are responsible for creating admin-token file. The admin-token will be stored +in this file. Users can get admin-token by contacting administrator. + +Setup Server Side +----------------- + +* Create admin-token file + + Administrators can use zvmsdk-gentoken tool to create admin-token file. + + Fox example, initialize one token file: + + .. code-block:: text + + # /usr/bin/zvmsdk-gentoken + + zvmsdk-gentoken use **/etc/zvmsdk/token.dat** as default path of token file. You can also specify your own token file path: + + .. code-block:: text + + # /usr/bin/zvmsdk-gentoken /new/path/of/token/file + + The commands above will initialize one token file and write a random admin-token into it. + + This tool can also help you update the content of token file: + + .. code-block:: text + + # /usr/bin/zvmsdk-gentoken -u + + If you don't assign a file path, zvmsdk-gentoken will update the file of default token path. You can update specified + file by this way: + + .. code-block:: text + + # /usr/bin/zvmsdk-gentoken -u /new/path/of/token/file + + **NOTE:** please remember to change token file's owner to user **zvmsdk** after operating it. + +* Update Configuration file + + After creating admin-token file, configuration should be updated to let the server know the path of token file. + + In configuration file, you can assign token file path by change the value of ``token_path`` which is in wsgi section. + + What's more, you should let server know we have changed the way of authentication by setting value of ``auth`` item + in the wsgi section to ``token``, just like ``auth=token``. + + If you want to disable token authentication, just change ``auth`` to value ``none``. + +Setup Client Side +----------------- + + On client side, you need to get the admin-token stored in the admin-token file. Just As what we have talked above, + admin-token file is generated on server side. Users should contact the administrator for admin-token before sending + requests. Then users can put the admin_token into the ``X-Admin-Token`` field in headers of request object for + passing the authentication. + + An example to request for a token: + + .. code-block:: text + + # curl http://localhost:8080/token -X POST -i -H "Content-Type:application/json" -H "X-Admin-Token:1234567890123456789012345678901234567890" + HTTP/1.0 200 OK + Date: Wed, 06 Dec 2017 06:11:22 GMT + Server: WSGIServer/0.1 Python/2.7.5 + Content-Type: text/html; charset=UTF-8 + Content-Length: 0 + X-Auth-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTI1NDQyODJ9.TVlcQb_QuUPJ37cRyzZqroR6kLZ-5zH2-tliIkhsQ1A + cache-control: no-cache + + You can see the temporary token is in the ``X-Auth-Token`` field. + + Then you can send normal RESTful requests using this temporary token to pass the authentication. + + For example: + + .. code-block:: text + + # curl http://localhost:8080/ -H "Content-Type:application/json" -H 'X-Auth-Token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTI1NDQyODJ9.TVlcQb_QuUPJ37cRyzZqroR6kLZ-5zH2-tliIkhsQ1A' + {"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": {"min_version": "1.0", "version": "1.0", "max_version": "1.0"}, "errmsg": ""} diff --git a/doc/html/_static/basic.css b/doc/html/_static/basic.css new file mode 100644 index 000000000..7ebbd6d07 --- /dev/null +++ b/doc/html/_static/basic.css @@ -0,0 +1,914 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/doc/html/_static/classic.css b/doc/html/_static/classic.css new file mode 100644 index 000000000..8851cb721 --- /dev/null +++ b/doc/html/_static/classic.css @@ -0,0 +1,262 @@ +/* + * Sphinx stylesheet -- classic theme. + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +html { + /* CSS hack for macOS's scrollbar (see #1125) */ + background-color: #FFFFFF; +} + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + display: flex; + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + + + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:visited { + color: #551a8b; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +nav.contents, +aside.topic, +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: unset; + color: unset; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +code { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th, dl.field-list > dt { + background-color: #ede; +} + +.warning code { + background: #efc2c2; +} + +.note code { + background: #d6d6d6; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + +div.code-block-caption { + color: #efefef; + background-color: #1c4e63; +} \ No newline at end of file diff --git a/doc/html/_static/doctools.js b/doc/html/_static/doctools.js new file mode 100644 index 000000000..0398ebb9f --- /dev/null +++ b/doc/html/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/doc/html/_static/documentation_options.js b/doc/html/_static/documentation_options.js new file mode 100644 index 000000000..893fd45a7 --- /dev/null +++ b/doc/html/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '1.6.7', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/doc/html/_static/file.png b/doc/html/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/doc/html/_static/file.png differ diff --git a/doc/html/_static/language_data.js b/doc/html/_static/language_data.js new file mode 100644 index 000000000..c7fe6c6fa --- /dev/null +++ b/doc/html/_static/language_data.js @@ -0,0 +1,192 @@ +/* + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/doc/html/_static/minus.png b/doc/html/_static/minus.png new file mode 100644 index 000000000..d96755fda Binary files /dev/null and b/doc/html/_static/minus.png differ diff --git a/doc/html/_static/plus.png b/doc/html/_static/plus.png new file mode 100644 index 000000000..7107cec93 Binary files /dev/null and b/doc/html/_static/plus.png differ diff --git a/doc/html/_static/pygments.css b/doc/html/_static/pygments.css new file mode 100644 index 000000000..0d49244ed --- /dev/null +++ b/doc/html/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/doc/html/_static/searchtools.js b/doc/html/_static/searchtools.js new file mode 100644 index 000000000..2c774d17a --- /dev/null +++ b/doc/html/_static/searchtools.js @@ -0,0 +1,632 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/doc/html/_static/sidebar.js b/doc/html/_static/sidebar.js new file mode 100644 index 000000000..ac7b39eed --- /dev/null +++ b/doc/html/_static/sidebar.js @@ -0,0 +1,64 @@ +/* + * This script makes the Sphinx sidebar collapsible. + * + * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds + * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton + * used to collapse and expand the sidebar. + * + * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden + * and the width of the sidebar and the margin-left of the document + * are decreased. When the sidebar is expanded the opposite happens. + * This script saves a per-browser/per-session cookie used to + * remember the position of the sidebar among the pages. + * Once the browser is closed the cookie is deleted and the position + * reset to the default (expanded). + * + */ + +const initialiseSidebar = () => { + + + + + // global elements used by the functions. + const bodyWrapper = document.getElementsByClassName("bodywrapper")[0] + const sidebar = document.getElementsByClassName("sphinxsidebar")[0] + const sidebarWrapper = document.getElementsByClassName('sphinxsidebarwrapper')[0] + const sidebarButton = document.getElementById("sidebarbutton") + const sidebarArrow = sidebarButton.querySelector('span') + + // for some reason, the document has no sidebar; do not run into errors + if (typeof sidebar === "undefined") return; + + const flipArrow = element => element.innerText = (element.innerText === "»") ? "«" : "»" + + const collapse_sidebar = () => { + bodyWrapper.style.marginLeft = ".8em"; + sidebar.style.width = ".8em" + sidebarWrapper.style.display = "none" + flipArrow(sidebarArrow) + sidebarButton.title = _('Expand sidebar') + window.localStorage.setItem("sidebar", "collapsed") + } + + const expand_sidebar = () => { + bodyWrapper.style.marginLeft = "" + sidebar.style.removeProperty("width") + sidebarWrapper.style.display = "" + flipArrow(sidebarArrow) + sidebarButton.title = _('Collapse sidebar') + window.localStorage.setItem("sidebar", "expanded") + } + + sidebarButton.addEventListener("click", () => { + (sidebarWrapper.style.display === "none") ? expand_sidebar() : collapse_sidebar() + }) + + if (!window.localStorage.getItem("sidebar")) return + const value = window.localStorage.getItem("sidebar") + if (value === "collapsed") collapse_sidebar(); + else if (value === "expanded") expand_sidebar(); +} + +if (document.readyState !== "loading") initialiseSidebar() +else document.addEventListener("DOMContentLoaded", initialiseSidebar) \ No newline at end of file diff --git a/doc/html/_static/sphinx_highlight.js b/doc/html/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/doc/html/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/doc/html/architecture.html b/doc/html/architecture.html new file mode 100644 index 000000000..3fa43268f --- /dev/null +++ b/doc/html/architecture.html @@ -0,0 +1,138 @@ + + + + + + + + 2. Introduction — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

2. Introduction

+
+

2.1. What is Feilong

+

Feilong is a Software Development Kit (SDK) for managing z/VM resources. +It provides a set of APIs to operate these resources, including guest, image, +network, volume etc. It comes with a python client library, +but can be used from other languages.

+
+
+

2.2. Integration Examples

+
    +
  • Example 1: integration with OpenStack

  • +
+_images/openstack_zcc.jpg +
+
+

2.3. Internal Architecture

+

Here is an internal component list of Feilong:

+_images/zcc_internal.jpg +
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/change.html b/doc/html/change.html new file mode 100644 index 000000000..321c198f3 --- /dev/null +++ b/doc/html/change.html @@ -0,0 +1,223 @@ + + + + + + + + 12. Release Notes — Feilong 1.6.7 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

12. Release Notes

+
+

12.1. Release 1.4.0

+

New features released with zVMCLoudConnector 1.4.0:

+
    +
  • Attach/detach volume to inactive guest.

  • +
  • Support set hostname without cloud-init.

  • +
+
+
+

12.2. Release 1.3.0

+

New features released with zVMCloudConnector 1.3.0:

+
    +
  • Support upload image through octet stream.

  • +
  • Guest live migrate, support live migrate in z/VM SSI cluster.

  • +
  • Live resize guest memory, and static resize guest memory.

  • +
  • Attach/detach volume to active guest.

  • +
+
+
+

12.3. Release 1.2.1

+

zVMCloudConnector 1.2.1 includes one change:

+
    +
  • Support “application/json,utf-8” context type in restclient.

  • +
+
+
+

12.4. Release 1.2.0

+

Following new features released with zVMCloudConnector 1.2.0:

+
    +
  • Dedicate OSA device to guest. If osa_device specified when invoking +z/VM Cloud Connector restful API to create network interface, the OSA device +will be dedicated to the guest.

  • +
  • Resize CPUs of guest. Resize guest CPU count by updating static definition.

  • +
  • Live resize CPUs of guest. Currently only increasing CPU count is supported, +decreasing is not supported.

  • +
+
+
+

12.5. Release 1.1.0

+

zVMCloudConnector 1.1.0 is mainly includes the change:

+
    +
  • Switch config drive format from tgz to iso9660

    +
    +

    Config drive in iso9660 format is commonly used by cloud-init.

    +
    +
  • +
+
+
+

12.6. Release 1.0.1

+

zVMCloudConnector 1.0.1 release mainly adapts to the SMAPI changes in z/VM 6.4 +APAR VM66120 1Q 2018. If the z/VM 6.4 has been applied APAR VM66120, must +upgrade z/VM Cloud Connector to 1.0.1 .

+
+
+

12.7. Release 1.0.0

+

zVMCloudConnector 1.0.0 release includes many basic features that enables +z/VM Cloud management through zVMCloudConnector APIs.

+

Supported features

+
    +
  • Host(hypervisor) management

    +

    get host information and get host disk pool information.

    +
  • +
  • Guests(virtual machines) management

    +
      +
    • Provisoning: create, delete guest definition; capture, deploy guests; +create, delete, configure disks; create, delete, couple, uncouple vnics to +vswitch; configure vnics and network interfaces.

    • +
    • Power actions including start, stop, softstop, reboot, reset, pause, +unpause and get power state.

    • +
    • Query information: get guest information, guest list, get guest definition +information, get console outputs, get nic information.

    • +
    +
  • +
  • Image management

    +

    Support import, export, delete images; query image information, get image +root disk size.

    +
  • +
  • Network features

    +
      +
    • vswitch: create, delete vswitch; grant, revoke vswitch access, +get vswitch list, query vswitch information, set user vlan id.

    • +
    • Hot plug/unplug network interfaces to live guest.

    • +
    +
  • +
  • Monitoring

    +

    Inspect virtual machine cpu, memory and vnic stats.

    +
  • +
  • RESTful API

    +

    zVMCloudConnector provides standard RESTful API, which makes it easier to +integrate with other cloud platforms. zVMCloudConnector RESTful API supports +to be configured in a HTTP or HTTPS server.

    +
  • +
  • Authorization mechanism

    +

    Support token based validation mechanism to make sure all zVMCloudConnector +RESTful API requests are authorized.

    +
  • +
  • IUCV management channel

    +

    zVMCloudConnector manages virtual machines through z/VM IUCV communication +channel, which does not require network connection.

    +
  • +
  • Monitoring data cache

    +

    Implement a cache layer in zVMCloudConnector to improve performance of getting +monitoring data.

    +
  • +
+
+
+

12.8. Release 0.3.2

+

Beta release since Dec 4, 2017

+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/configuration.html b/doc/html/configuration.html new file mode 100644 index 000000000..320203a28 --- /dev/null +++ b/doc/html/configuration.html @@ -0,0 +1,707 @@ + + + + + + + + 9. Configuration Options — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

9. Configuration Options

+
[database]
+
+# 
+# Directory to store database.
+# 
+# SDK databases are used to store a set of tables which contain the
+# information of network, volume, image, etc. This option is used to
+# tell SDK where to store the database files, make sure the process
+# running SDK is able to read write and execute the directory.
+# 
+# This param is optional
+#dir=/var/lib/zvmsdk/databases/
+
+
+[file]
+
+# 
+# Directory to store sdk imported or exported files.
+# 
+# SDK file repository to store the imported files and the files that will be
+# exported, the imported files will be put into <file_repository>/imported
+# the files to be exported will be put into <file_repository>/exported
+#     
+# This param is optional
+#file_repository=/var/lib/zvmsdk/files
+
+
+[guest]
+
+# 
+# The maximum allowed console log size, in kilobytes.
+# 
+# Console logs might be transferred to sdk user, this option controls how
+# large each file can be. A smaller size may mean more calls will be needed
+# to transfer large consoles, which may not be desirable for performance reasons.
+#     
+# This param is optional
+#console_log_size=100
+
+
+# 
+# Whether to automatically extend the partition and filesystem of guest.
+# 
+# If set to True, when deploying an image to a larger disk, zvmsdk
+# automatically extends the last partition and the file system to
+# use up the whole disk.
+# 
+# If do not want to do the extend action automaictly, you must set this option
+# to be False.
+#     
+# This param is optional
+#extend_partition_fs=True
+
+
+# 
+# The maximum time waiting until the guest reachable after started.
+# 
+# When starting a guest, specify the timeout value will check the guest status
+# until it becomes reachable or timeout.
+#     
+# This param is optional
+#reachable_timeout=180
+
+
+# 
+# The interval time between 2 retries, in seconds.
+# 
+# This will take effect only when you set softstop_retries item.
+# What's more, the value of softstop_timeout/softstop_interval is
+# the times retried.
+#     
+# This param is optional
+#softstop_interval=10
+
+
+# 
+# The maximum time waiting until the guest shut down.
+# 
+# Sometimes, the shutdown action will take a bit lone time to complete.
+# If you want to make sure the guest in shut-down status after executing action
+# of softstop, this will help.
+#     
+# This param is optional
+#softstop_timeout=120
+
+
+[image]
+
+# 
+# Default compress level for captured image.
+# 
+# This param is optional
+#default_compress_level=6
+
+
+# 
+# Directory to store sdk images.
+# 
+# SDK image repository to store the imported images and the staging images that
+# is in snapshotting. Once snapshot finished, the image will be removed to the
+# netboot directory accordingly. Two kinds of image repository looks like:
+# /var/lib/zvmsdk/images/netboot/<image_osversion>/<imagename>
+# /var/lib/zvmsdk/images/staging/<image_osversion>/<imagename>
+#     
+# This param is optional
+#sdk_image_repository=/var/lib/zvmsdk/images
+
+
+[logging]
+
+# 
+# Directory where log file to be put into.
+# 
+# SDK has a set of logs to help administrator to debug
+# and audit actions performed through SDK. Edit this option
+# if you want to put logs into specified place.
+# 
+# Please ensure the service running on the consume which
+# consumes SDK has the authorization to write to the path.
+#     
+# This param is optional
+#log_dir=/var/log/zvmsdk/
+
+
+# 
+# Level of the log.
+# 
+# SDK utilize python logging package to help admin debug
+# or analyze issues. it's recommend to set this value
+# to logging.DEBUG to get more detailed logs and set it to
+# logging.INFO(default) in normal situation.
+# 
+# recommend values:
+# logging.ERROR: level above ERROR will be written to log file.
+# logging.WARNINS: level above WARNING(ERROR, WARNING)
+#                  will be written to log file.
+# logging.INFO: level above INFO(ERROR, WARNING, INFO)
+#               will be written to log file.
+# logging.DEBUG: All log level (ERROR, WARNING, INFO, DEBUG)
+#                will be written to log file.
+#     
+# This param is optional
+#log_level=logging.INFO
+
+
+[monitor]
+
+# 
+# Cached monitor data update interval
+# 
+# This is used to prevent excessive effort spent retrieving the
+# monitor data by calling the SDK backend utilities. When this cache
+# is enabled, a inspect call will only call the SDK backend utilities
+# when the inspected guest's info does not exist in the cache or
+# when the cache data is expired. And when an cache update is needed,
+# all the existing guests' data will be retrieved in a single call to
+# the backend.
+# 
+# When this value is below or equal to zero, the cache
+# will be disabled and each inspect call will need to call the backend
+# utilities to get the inspected guest's monitor data.
+#         
+# This param is optional
+#cache_interval=300
+
+
+[network]
+
+# 
+# IP address of the Linux machine which is running SDK on.
+# 
+# Some remote copy operations need to be performed during guest creation,
+# this option tell the SDK the host ip which can be used to perform copy
+# from and copy to operations.
+#     
+# This param is required
+#my_ip=None
+
+
+[sdkserver]
+
+# 
+# The IP address that the SDK server is listening on.
+# 
+# When the SDK server deamon starts, it will try to bind to
+# this address and port bind_port, and wait for the SDK client
+# connection to handle API request.
+# 
+# This param is optional
+#bind_addr=127.0.0.1
+
+
+# 
+# The port that the SDK server is listening on.
+# 
+# This will work as a pair with bind_addr when the SDK server daemon
+# starts, more info can be found in that configuration description.
+# 
+# This param is optional
+#bind_port=2000
+
+
+# 
+# The maximum number of worker thread in SDK server to handle client requests.
+# 
+# These worker threads would work concurrently to handle requests from client.
+# This value should be adjusted according to the system resource and workload.
+# 
+# This param is optional
+#max_worker_count=64
+
+
+# 
+# The size of request queue in SDK server.
+# 
+# SDK server maintains a queue to keep all the accepted but not handled requests,
+# and the SDK server workers fetch requests from this queue.
+# To some extent, this queue size decides the max socket opened in SDK server.
+# This value should be adjusted according to the system resource.
+# 
+# This param is optional
+#request_queue_size=128
+
+
+[volume]
+
+# 
+# fcp pair selection algorithm
+# 
+# fcp_list example:
+# fa00-fa02; fb00-fb02
+# 
+# If use get_fcp_pair_with_same_index,
+# then fcp pair is randomly selected from below combinations.
+# [fa00,fb00],[fa01,fb01],[fa02,fb02]
+# 
+# If use get_fcp_pair,
+# then fcp pair is randomly selected from below combinations.
+# [fa00,fb00],[fa01,fb00],[fa02,fb00]
+# [fa00,fb01],[fa01,fb01],[fa02,fb01]
+# [fa00,fb02],[fa01,fb02],[fa02,fb02]
+# 
+# Possible value:
+# 0 : use get_fcp_pair. this is the default
+# 1 : use get_fcp_pair_with_same_index
+# 
+# This param is optional
+#get_fcp_pair_with_same_index=0
+
+
+# 
+# The timeout value for waiting attach/detach punch scripts
+# execution, in seconds.
+# 
+# The default value is 1800 seconds, if the execution of punch scripts
+# reached the timeout, the attach/detach will fail.
+# 
+# This param is optional
+#punch_script_execution_timeout=1800
+
+
+# 
+# The timeout value for waiting refresh_bootmap execution, in seconds.
+# 
+# The default value is 1200 seconds, if the execution of refresh_bootmap
+# reached the timeout, the process of refresh_bootmap will be stopped.
+# 
+# This param is optional
+#refresh_bootmap_timeout=1200
+
+
+[wsgi]
+
+# 
+# Whether auth will be used.
+# 
+# When sending http request from outside to running zvmsdk,
+# Client will be requested to input username/password in order
+# to authorize the call.
+# Set this to 'none' indicated no auth will be used and 'auth'
+# means username and password need to be specified.
+# 
+# Possible value:
+# 'none': no auth will be required
+# 'auth': need auth, currently pyjwt is used to return a token
+#         to caller if the username and password is correct.
+# 
+# This param is optional
+#auth=none
+
+
+# 
+# The max total number of concurrent deploy and capture requests allowed in a
+# single z/VM Cloud Connector process.
+# 
+# If more requests than this value are revieved concurrently, the z/VM Cloud
+# Connector would reject the requests and return error to avoid resource
+# exhaustion.
+# .
+# 
+# This param is optional
+#max_concurrent_deploy_capture=20
+
+
+# 
+# file path that contains admin-token to access sdk http server.
+# 
+# Admin-token in order to get a user-token from zvm sdk, and the user-token
+# will be used to validate request before user-token expire.
+# 
+# This param is optional
+#token_path=/etc/zvmsdk/token.dat
+
+
+# 
+# How long the token is valid.
+# 
+# If a token auth is used, the token return to user will be
+# expired after the period passed. This ensure an user who
+# get this token will not be authorized all the time, a new
+# token need to be recreated after certain time period.
+# 
+# This param is optional
+#token_validation_period=3600
+
+
+[zvm]
+
+# 
+# Only used for SMAPIOUT is not ready.
+# 
+# This param is optional
+#bypass_smapiout=True
+
+
+# 
+# Default LOGONBY userid(s) for the cloud.
+# 
+# This is a set of z/VM userid(s) which are allowed to logon using the LOGONBY
+# keyword to the guests created by the z/VM SDK solution, compatible with
+# the LBYONLY keyword of the user directory statement. This value is only used
+# when a guest is created. If you change this value, existing guests' directory
+# entries are not automatically updated with the new value.
+# When an ESM is installed, this parameter only governs when the ESM
+# defers to CP's processing.
+# 
+# Usage note:
+#     The default is empty string with nothing set.
+#     '' is an invalid value and it will cause VM deploying failed.
+#     Thus, DO NOT set default_admin_userid=''.
+#     When a non-empty string is provided, blank chars will be used as delimiter,
+#     you can use LOGONBY xxx command to log on the guest using the corresponding
+#     admin userid's password.
+# 
+#     For example, when you set this value to 'oper1 oper2 oper3 jones', it means
+#     you can use any one of 'oper1', 'oper2', 'oper3', 'jones' as an admin user.
+# 
+#     see the z/VM CP Planning and Administration for additional information.
+# 
+# Possible values:
+#     A maximum of 8 blank-delimited strings. Each non-blank string must be a
+#     valid z/VM userid.
+#     e.g  'oper1 oper2' is a valid value.
+#          'o1 o2 o3 o4 o5 o6 o7 o8 o9' is NOT a valid value.
+#     
+# This param is optional
+#default_admin_userid=None
+
+
+# 
+# Virtual device number for default NIC address.
+# 
+# This value is the first NIC virtual device number,
+# each NIC needs 3 numbers for control/read/write, so by default
+# the first NIC's address is 1000, the second one is 1003 etc.
+# 
+# Possible values:
+#     An integer value in hex format, between 0 and 65536 (x'FFFF').
+#     It should not conflict with other device numbers in the z/VM guest's
+#     configuration, for example device numbers of the root or ephemeral or
+#     persistent disks.
+# 
+# Sample NIC definitions in the z/VM user directory:
+#     NICDEF 1000 TYPE QDIO LAN SYSTEM <vswitch1> MACID <macid1>
+#     NICDEF 1003 TYPE QDIO LAN SYSTEM <vswitch2> MACID <macid2>
+#         
+# This param is optional
+#default_nic_vdev=1000
+
+
+# 
+# zVM disk pool and type for root/ephemeral disks.
+# 
+# The option is combined by 2 parts and use : as separator.
+# 
+# The first part is the type of disks in the disk pool.
+# The disks in one disk pool must in same type (ECKD or FBA).
+# Possible values of the disk pool type:
+#     A string, either ECKD or FBA.
+# 
+# The second part is the volume group name defined in your directory manager
+# on your z/VM system, which will be used for allocating disks for
+# new guest. A dollar sign ($) is not allowed in the name.
+# 
+# Sample disk_pool values:
+#     ECKD:diskpo1
+#     FBA:testpool
+#     
+# This param is optional
+#disk_pool=None
+
+
+# 
+# Virtual device number for capture function.
+# 
+# This value identity the virtual device number for capture
+# image when z/VM guest is power off.
+# 
+# Possible values:
+#     An string value identify disk number like '0100'.
+#     If this value has been configured, capture image function will use
+#     this value as disk info to capture with first priority when z/VM
+#     guest is power off.
+#     This value don't work if z/VM guest status is power on.
+# Sample root disk in user directory:
+#     MDISK 0100 <disktype> <start> <end> <volumelabel> <readwrite>
+# 
+# This param is optional
+#force_capture_disk=None
+
+
+# 
+# The name of a list containing names of virtual servers to be queried. The list
+# which contains the userid list by default is named: VSMWORK1 NAMELIST, see
+# DMSSICNF COPY key: NameListFileIdAny. The list has to be accessible to the
+# SMAPI servers.
+# 
+# The length of namelist must no longer than 64.
+# 
+# This param is optional
+#namelist=None
+
+
+# 
+# The port number of remotehost sshd.
+# 
+# This param is optional
+#remotehost_sshd_port=22
+
+
+# 
+# The timeout value for a long-duration SMAPI socket is specified in seconds.
+# 
+# The default value is 900 seconds.
+# 
+# SMAPIs are socket-based systems management application programming interfaces.
+# If the SMAPI socket connection of a long-duration operation exceeds this timeout,
+# the SMAPI long-duration operation will fail.
+# 
+# This param is optional
+#smapi_socket_long_call_timeout_seconds=900
+
+
+# 
+# The timeout value for a general SMAPI socket is specified in seconds.
+# 
+# The default value is 240 seconds.
+# 
+# SMAPIs are socket-based systems management application programming interfaces.
+# If the SMAPI socket connection exceeds this timeout, the SMAPI operation will fail.
+# 
+# This param is optional
+#smapi_socket_timeout_seconds=240
+
+
+# 
+# If configure the dasd group, the user can configure `swap_default_with_mdisk`
+# to create swap device with MDISK or VDISK, the default value `True` means create
+# the swap device with MDISK, if `False`, create the swap device with VDISK.
+# 
+# This param is optional
+#swap_default_with_mdisk=True
+
+
+# 
+# For swap disk to create from mdisk instead of vdisk only for the below boot from
+# volume case. In boot from volume case, there might be no disk pool at all, then
+# the only choice is to use vdisk (or using FCP LUN which is complicated),
+# if customer doesn't want vdisk, then set this value to `True` so
+# VDISK will not be used and in turn it will fail check. If the customer wants
+# to use MDISK to create swap device, he need configure dasd group and set
+# `swap_default_with_mdisk` to `True` which is the default value.
+# 
+# This param is optional
+#swap_force_mdisk=False
+
+
+# 
+# The default maximum number of virtual processers the user can define.
+# This value is used as the default value for maximum vcpu number when
+# create a guest with no max_cpu specified.
+# 
+# The number must be a decimal value between 1 and 64.
+# 
+# This param is optional
+#user_default_max_cpu=32
+
+
+# 
+# The default maximum size of memory the user can define.
+# This value is used as the default value for maximum memory size when
+# create a guest with no max_mem specified.
+# The value can be specified by 1-4 bits of number suffixed by either
+# M (Megabytes) or G (Gigabytes) and the number must be a whole number,
+# values such as 4096.8M or 32.5G are not supported.
+# 
+# The value should be adjusted based on your system capacity.
+# 
+# This param is optional
+#user_default_max_memory=64G
+
+
+# 
+# The default maximum size of reserved memory in a vm's direct entry.
+# This value is used as the default value for maximum reserved memory
+# size for a guest.
+# The value can be specified by 1-4 bits of number suffixed by either
+# M (Megabytes) or G (Gigabytes) and the number must be a whole number,
+# values such as 4096.8M or 32.5G are not supported.
+# 
+# The value should be adjusted based on your system capacity.
+# 
+# This param is optional
+#user_default_max_reserved_memory=64G
+
+
+# This param is optional
+#user_default_password=None
+
+
+# 
+# The default SHARE settings configuration.
+# 
+# The recommend value of SHARE. From z/VM doc, SHARE is relative value of
+# virtual machine and if you set SHARE to 100 while virtual CPUs are 4,
+# then each vCPU get 25 entitlement.
+# 
+# So the mechanism currently is:
+# 
+# 1) If a share is given, set SHARE value to the VM
+# 2) If no SHARE is given during creation, check user_default_share_unit
+# 3) If user_default_share_unit is 0, do nothing
+# 4) If user_default_share_unit it not 0(current default is 100),
+# then insert statement `SHARE RELATIVE user_default_share_unit*vCPU`
+# into user direct, for example, with user_default_share_unit=100,
+# 4 vCPU will create `SHARE RELATIVE 400`.
+# 
+# This align the best practice of z/VM recommendation.
+# 
+# This param is optional
+#user_default_share_unit=100
+
+
+# 
+# PROFILE name to use when creating a z/VM guest.
+# 
+# When SDK deploys an guest on z/VM, it can include some
+# common statements from a PROFILE definition.
+# This PROFILE must already be included in your z/VM user directory.
+# 
+# Possible values:
+#     An 8 character name of a PROFILE that is already defined in the z/VM
+#     user directory.
+#     
+# This param is required
+#user_profile=None
+
+
+# 
+# Virtual device number for root disk.
+# 
+# When SDK deploys an guest, it creates a root disk and potentially
+# several data disks. This value is the virtual device number of the root
+# disk.
+# 
+# Possible values:
+#     An integer value in hex format, between 0 and 65536 (x'FFFF').
+#     It should not conflict with other device numbers in the z/VM guest's
+#     configuration, for example device numbers of the NICs or ephemeral or
+#     persistent disks.
+# 
+# Sample root disk in user directory:
+#     MDISK 0100 <disktype> <start> <end> <volumelabel> <readwrite>
+# 
+# This param is optional
+#user_root_vdev=0100
+
+
+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/errorcodemsg.html b/doc/html/errorcodemsg.html new file mode 100644 index 000000000..98c8a0d77 --- /dev/null +++ b/doc/html/errorcodemsg.html @@ -0,0 +1,1208 @@ + + + + + + + + 8. Error Codes and Messages — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

8. Error Codes and Messages

+

This is a reference to Feilong API error codes +and messages.

+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

overallRC

modID

rc

rs

errmsg

Invalid API Input

100

400

100

1

Invalid API arg count, API: %(api)s, %(expected)d expected while %(provided)d provided.

100

400

100

2

Invalid API arg type, API: %(api)s, expected types: ‘%(expected)s’, input types: ‘%(inputtypes)s’

100

400

100

3

Invalid API arg format, error: %(msg)s

100

400

100

4

Missing required option: %(msg)s

Operation on Guest failed

300

10

300

1

Database operation failed, error: %(msg)s

300

10

300

2

Failed to add mdisks when creating guest, error: %(msg)s

300

10

300

3

Failed to deploy image to userid: ‘%(userid)s’, unpackdiskimage failed with rc: %(unpack_rc)d, error: %(err)s

300

10

300

4

Failed to deploy image to userid: ‘%(userid)s’, copy configure drive failed: %(err_info)s

300

10

300

5

Failed to capture userid %(userid)s to generate image, error: %(msg)s

300

10

300

6

Failed to resize cpus of guest: ‘%(userid)s’, error: update cpu definition in user entry failed with smt error: ‘%(err)s’.

300

10

300

7

Failed to live resize cpus of guest: ‘%(userid)s’, error: define new cpu to active failed with smt error: ‘%(err)s’.

300

10

300

8

Failed to live resize cpus of guest: ‘%(userid)s’, error: rescan cpus to hot-plug new defined cpus failed: ‘%(err)s’.

300

10

300

9

Failed to resize memory of guest: ‘%(userid)s’, error: lock user entry failed with smt error: ‘%(err)s’.

300

10

300

10

Failed to resize memory of guest: ‘%(userid)s’, error: replace user entry failed with smt error: ‘%(err)s’.

300

10

300

11

Failed to live resize memory of guest: ‘%(userid)s’, error: define standby memory failed with smt error: ‘%(err)s’.

300

10

300

12

Failed to deploy image to userid: ‘%(userid)s’, get unpackdiskimage cmd failed: %(err)s

300

10

300

13

Failed to deploy image to userid: ‘%(userid)s’, ignition file is required when deploying RHCOS image

300

10

300

14

Failed to deploy image to userid: ‘%(userid)s’, %(msg)s

300

10

300

15

Failed to live resize cpus of guest: ‘%(userid)s’, error: enable new defined cpus failed: ‘%(err)s’.

300

10

300

16

Failed to start the guest: ‘%(userid)s’, %(msg)s

300

10

300

17

Failed to live resize memory of guest: ‘%(userid)s’, error: chmem command failed: ‘%(err)s’.

Operation on Network failed

300

20

300

1

Database operation failed, error: %(msg)s

300

20

300

2

ZVMSDK network error: %(msg)s

300

20

300

3

Failed to couple nic %(nic)s to vswitch %(vswitch)s on the active guest system, error: %(couple_err)s, and failed to revoke user direct’s changes, error: %(revoke_err)s

300

20

300

4

Failed to create nic %(nic)s for %(userid)s on the active guest system, error: %(create_err)s, and failed to revoke user direct’s changes, error: %(revoke_err)s

300

20

300

5

Failed to actively change network setting for user %(userid)s, error: %(msg)s

Operation on Volume failed

300

30

300

1

Database operation failed, error: %(msg)s

300

30

300

3

Volume %(vol)s has already been attached on instance %(inst)s

300

30

300

4

Volume %(vol)s is not attached on instance %(inst)s

300

30

300

5

Refresh bootmap fails, error code: %(errcode)s and reason: %(errmsg)s

300

30

300

6

IUCV failed to get authorization from instance %(userid)s with reason %(msg)s

300

30

300

7

Refresh bootmap timeout with reason %(msg)s

300

30

300

8

Failed to attach volume to instance %(userid)s with reason %(msg)s

300

30

300

9

Failed to detach volume from instance %(userid)s with reason %(msg)s

300

30

300

10

Failed to refresh bootmap for RHCOS: transportfiles are required

300

30

300

11

Failed to get volume connector of %(userid)s: %(msg)s

300

30

300

12

PCHIDs info missing: %(msg)s

Operation on Image failed

300

40

300

1

Database operation failed, error: %(msg)s

300

40

300

2

No image schema found for %(schema)s

300

40

300

3

Image import error: Failed to calculate the md5sum of the image

300

40

300

4

Image import error: The md5sum after import is not same as source image, it is possible that the image has been broken during import

300

40

300

5

Image import error: Failed to get the root disk size units of the image via hexdump

300

40

300

6

Image import error: The header of image does not contain built-in disk size units

300

40

300

7

Image import error: The image’s disk type is not valid. Currently only FBA or CKD type image is supported

300

40

300

8

Image import error: Failed to get the physical size of image in bytes

300

40

300

9

Import image from http server failed with reason %(err)s

300

40

300

10

Image import error: Copying image file from remote filesystem failed with error %(err)s

300

40

300

11

The specified remote_host %(rh)s format invalid

300

40

300

12

Import image from local file system failed with error %(err)s

300

40

300

13

Image import error: image name %(img)s already exist in image database

300

40

300

14

Image import error: %(msg)s

300

40

300

20

The image record of %(img)s does not exist

300

40

300

21

Image Export error: Failed to copy image file to remote host with reason: %(msg)s

300

40

300

22

Export image to local file system failed: %(err)s

300

40

300

23

Image file of %(img)s does not exist, so failed to get its timestamp.

Operation on Monitor failed

300

50

300

1

Database operation failed, error: %(msg)s

REST API Request error

400

120

400

1

Invalid request

The operated object does not exist

404

None

404

1

%(obj_desc)s does not exist.

404

None

404

2

Not found error: ‘%(msg)s’

404

None

404

3

%(obj_desc)s does not exist in directory although it is in DB. The guest could have been deleted out of z/VM Cloud Connector.

The operated object status conflict

409

None

409

1

Guest ‘%(userid)s’ is not in active status.

409

None

409

2

Failed to live resize cpus of guest: ‘%(userid)s’, error: current active cpu count: ‘%(active)i’ is greater than requested count: ‘%(req)i’.

409

None

409

3

Failed to resize cpus of guest: ‘%(userid)s’, error: maximum number of cpus is not defined in user directory.

409

None

409

4

Failed to resize cpus of guest: ‘%(userid)s’, error: the requested number of cpus: ‘%(req)i’ exceeds the maximum number of cpus allowed: ‘%(max)i’.

409

None

409

5

Failed to set vswitch %(vsw)s, error: %(msg)s

409

None

409

6

Failed to create nic %(vdev)s for guest %(userid)s, error: %(msg)s

409

None

409

7

Failed to create nic %(vdev)s for guest %(userid)s, error: %(obj)s is locked

409

None

409

8

Failed to delete nic %(vdev)s for guest %(userid)s, error: %(msg)s

409

None

409

9

Failed to delete nic %(vdev)s for guest %(userid)s, error: %(obj)s is locked

409

None

409

10

Failed to couple nic %(vdev)s of guest %(userid)s with vswitch %(vsw)s, error: %(msg)s

409

None

409

11

Failed to couple nic %(vdev)s of guest %(userid)s with vswitch %(vsw)s, error: %(obj)s is locked

409

None

409

12

Failed to uncouple nic %(vdev)s of guest %(userid)s error: %(msg)s

409

None

409

13

Failed to uncouple nic %(vdev)s of guest %(userid)s error: %(obj)s is locked

409

None

409

14

Failed to dedicate OSA %(osa)s to guest %(userid)s error: %(msg)s

409

None

409

15

Failed to dedicate OSA %(osa)s to guest %(userid)s error: %(obj)s is locked

409

None

409

16

Failed to delete dedicated device from guest %(userid)s %(vdev)s, error: %(msg)s

409

None

409

17

Failed to delete dedicated device from guest %(userid)s %(vdev)s, error: %(obj)s is locked

409

None

409

18

Failed to live resize memory of guest: ‘%(userid)s’, error: current active memory size: ‘%(active)i’m is greater than requested size: ‘%(req)i’m.

409

None

409

19

Failed to resize memory of guest: ‘%(userid)s’, error: user definition is not in expected format, cann’t get the defined/max/reserved storage.

409

None

409

20

Failed to resize memory of guest: ‘%(userid)s’, error: the requested memory size: ‘%(req)im’ exceeds the maximum memory size defined: ‘%(max)im’.

409

None

409

21

Failed to live resize memory of guest: %(userid)s, error: the memory size to be increased: ‘%(inc)im’ is greater than the maximum reserved memory size: ‘%(max)im’.

409

None

409

22

Failed to delete FCP Multipath Template, error: %(msg)s

409

None

409

23

Failed to create or update FCP Multipath Template, error: %(msg)s

409

None

409

24

Failed to edit FCP Multipath Template, error: %(msg)s

The operated object is deleted

410

None

410

The operated object is deleted

ZVM SDK Internal Error

500

None

500

1

Unexpected internal error in ZVM SDK, error: %(msg)s

z/VM Cloud Connector service is unavailable

503

120

503

1

Max concurrent deploy/capture requests received, request is rejected. %(req)s

smt errors

2

1

2

99

ULTSMP0311E On USERID, command sent through IUCV failed, rc in response string is not an integer. cmd: CMD, rc: RC, out: OUTPUT

2

1

2

99

ULTSMP0312E On USERID, command sent through IUCV failed, reason code in response string is not an integer. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

2

1

1

None

ULTSMP0313E On USERID, command sent through IUCV was not authorized or a generic Linux error occurred. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

2

1

2

None

ULTSMP0314E IUCV client parameter error sending command to USERID. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

2

1

4

None

ULTSMP0315E IUCV socket error sending command to USERID. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

2

1

8

None

ULTSMP0316E On USERID, command sent through IUCV failed. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

2

1

16

None

ULTSMP0317E File transport failure while processing command for USERID. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

2

1

32

None

ULTSMP0318E On USERID, IUCV server file was not found. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

2

1

None

None

ULTSMP0319E Unrecognized IUCV client error encountered while sending a command through IUCV to USERID. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

3

1

64

None

ULTSMP0320E On USERID, command sent through IUCV failed because timeout. cmd: CMD, rc: RC, rs: RS, out: OUTPUT

3

1

415

None

ULTGUT0415E Command failed: ‘CMD’, rc: RC out: OUTPUT

4

1

4

1

ULTRQH0001E FUNCTION_NAME SUBFUNCTION_NAME subfunction’s operand at position OPERAND_POSITION (OPERAND) is not an integer: OPERAND_VALUE

4

1

4

2

ULTRQH0002E FUNCTION_NAME’s SUBFUNCTION_NAME subfunction is missing positional operand (OPERAND) at position OPERAND_POSITION.

4

1

4

3

ULTRQH0003E FUNCTION_NAME’s SUBFUNCTION_NAME subfunction KEYWORD keyword operand is missing a value.

4

1

4

4

ULTRQH0004E FUNCTION_NAME’s SUBFUNCTION_NAME subfunction KEYWORD keyword operand is not an integer: KEYWORD_VALUE

4

1

4

5

ULTRQH0005E FUNCTION_NAME’s SUBFUNCTION_NAME subfunction does not recognize keyword: KEYWORD

4

1

4

6

ULTRQH0006E FUNCTION_NAME’s SUBFUNCTION_NAME subfunction encountered an unknown operand: OPERAND

4

1

4

7

ULTRQH0007E Unrecognized function: FUNCTION_NAME

4

1

4

8

ULTRQH0008E Specified function is not ‘HELP’ or ‘VERSION’: SPECIFIED_FUNCTION

4

1

4

9

ULTRQH0009E Too few arguments specified.

4

1

4

10

ULTRQH0010E Userid is missing

4

1

4

11

ULTRQH0011E Subfunction is missing. It should be one of the following: VALID_SUBFUNCTIONS

4

1

4

12

ULTRQH0012E The request data is not one of the supported types of list or string: REQUEST_DATA_TYPE

4

1

4

13

ULTRQH0010E The desired state was: DESIRED_STATS. Valid states are: VALID_STATS

4

1

4

14

ULTRQH0014E The option OPTION1 was specified but the option OPTION2 was not specified. These options must both be specified.

4

1

4

15

ULTRQH0015E The file system was not ‘ext2’, ‘ext3’, ‘ext4’, ‘xfs’ or ‘swap’: FILE_SYSTEM

4

1

4

16

ULTRQH0016E The scp Data Type was not ‘hex’, ‘ebcdic’, or ‘delete’: DATA_TYPE

4

1

4

17

ULTRQH0017W The maxwait time MAX_WAIT sec is not evenly divisible by the poll interval POLL_INTERVAL sec. Maximum wait time will be RECOMMEND_MAX_WAIT sec or RECOMMEND_POLL_INTERVAL poll intervals.

4

1

4

200

ULTGUT0200E The size of the disk is not valid: DISK_SIZE

4

1

4

201

ULTGUT0201E Failed to convert DISK_SIZE to a number of blocks.

4

1

4

202

ULTGUT0202E NUM_BLOCKS is not an integer size of blocks.

4

1

4

203

ULTGUT0203E Failed to convert DISK_SIZE to a number of cylinders.

4

1

4

204

ULTGUT0204E DISK_SIZE is not an integer size of cylinders.

4

1

4

205

ULTMVM0205E memory size did not end with suffix ‘G’ or ‘M’.

4

1

4

206

ULTMVM0206E Max memory size MAX_MEM_SIZE specified is less than initial memory size INIT_MEM_SIZE.

4

1

4

207

ULTMVM0207E VDISK Size (swap disk) is greater than 2G.

4

1

4

400

ULTGUT0400E The worker script SCRIPT_NAME does not exist.

4

1

7

401

ULTGUT0401E Failed to punch FILE_LOCATION file to guest: USERID, out: OUTPUT

4

1

5

402

ULTGUT0402E No information was found for the specified pool(s): DISK_POOL

4

1

99

403

ULTGUT0403E Failed to purge reader file SPOOL_ID, out: OUTPUT

4

1

8

404

ULTGUT0404E Failed to spool the punch to the specified class SPOOL_CLASS, out:OUTPUT

4

1

6

405

ULTGUT0405E Unable to obtain information related to: KEYWORD. Command used was: CMD. Output was: OUTPUT

4

1

9

406

ULTGUT0406E Failed to punch FILE_LOCATION because of VMUR timeout

4

1

4

407

ULTGUT0407W Unable to spool reader to all classes, it is possible that there may be additional console files available that are not listed in the response. Response from CMD is OUTPUT

4

1

4

408

ULTGUT0408E Error getting list of files in the reader to search for logs from user USERID. Response from CMD is OUTPUT

4

1

4

409

ULTGUT0409E Unable to get console log for user USERID. The userid is either: not logged on, not spooling its console, or has not created any console output. Error rc=rs=8 returned from Image_Console_Get.

4

1

4

410

ULTGUT0410E Unable to get console log for user USERID no spool files were found in our reader from this user, it is possible another process has already received them.

4

1

4

411

ULTGUT0411E Unable to receive console output file. Reader not online. /sys/bus/ccw/drivers/vmur/0.0.000c/online = 0

4

1

4

412

ULTGUT0412E Malformed reply from SMAPI, unable to fill in performance information, exception: EXCEPTION, details: EXCEPTION_DETAILS, Response: OUTPUT

4

1

4

423

ULTGUT0423W Unable to spool reader to all classes, it is possible that there may be additional console files available that are not listed in the response. Command: CMD, exception EXCEPTION, details EXCEPTION_DETAILS. Will attempt to continue processing.

4

1

4

424

ULTGUT0424E Failed to transfer FILE_LOCATION file to guest: USERID, out: OUTPUT

5

1

1

501

ULTGUT0501E Timeout Exception recevied on an attempt to execute a cmd: CMD, exception: EXCEPTION, details: EXCEPTION_DETAILS

8

1

None

None

ULTSMP0300E SMAPI API failed: API_NAME, overall rc: OVERALLRC, rc: RC, rs: RS, errno: ERRNO, cmd: CMD, out: OUTPUT

25

1

301

0

ULTSMP0301E SMAPI API failed: API_NAME, response header does not have the expected 3 values before the (details) string. cmd: CMD, response header: HEADER, out: OUTPUT

25

1

302

0

ULTSMP0302E SMAPI API failed: API_NAME, word 1 in the response header is not an integer or in the range of expected values. word 1: WORD1, cmd: CMD, response header: HEADER, out: OUTPUT

25

1

303

0

ULTSMP0303E SMAPI API failed: API_NAME, word 2 in the response header is not an integer. word 2: WORD2, cmd: CMD, response header: HEADER, out: OUTPUT

25

1

304

0

ULTSMP0304E SMAPI API failed: API_NAME, word 3 in the response header is not an integer. word 3: WORD3, cmd: CMD, response header: HEADER, out: OUTPUT

99

1

305

0

ULTSMP0305E Exception received on an attempt to communicate with SMAPI, cmd: CMD, exception: EXCEPTION, details: EXCEPTION_DETAILS

99

1

99

413

ULTGUT0413E Userid ‘USERID’ did not enter the expected operating system state of ‘DESIRED_STATE’ in MAX_WAIT seconds.

99

1

99

414

ULTGUT0414E Userid ‘USERID’ did not enter the expected virtual machine state of ‘DESIRED_STATE’ in MAX_WAIT seconds.

99

1

99

416

ULTGUT0416E Command returned a response containing ‘KEYWORD’ but did not have at least NUM words following it. cmd: ‘CMD’, out: ‘OUTPUT’

99

1

99

417

ULTGUT0417E Command did not return the expected response containing ‘KEYWORD’, cmd: ‘CMD’, out: ‘OUTPUT’

99

1

99

418

ULTGUT0418E Userid USERID is not logged on to this system.

99

1

99

419

ULTGUT0419E A relocation is not in progress for userid USERID.

99

1

99

420

ULTGUT0420E An error occurred issuing a CMD for userid USERID. Please look up message(s): ERROR_CODE in the CP Messages book for more information.

99

1

421

0

ULTGUT0421E Exception received on an attempt to execute a cmd: CMD, exception: EXCEPTION, details: EXCEPTION_DETAILS

99

1

422

0

ULTGUT0422W Exception received on an attempt to execute a cmd: CMD, exception: EXCEPTION, details: EXCEPTION_DETAILS. Will attempt to continue processing.

client errors

101

110

101

1

Request to zVM Cloud Connector failed: %(error)s

101

110

101

2

Token file not found: %(error)s

101

110

101

3

Request to url: %(url)s got unexpected response: status_code: %(status)s, reason: %(reason)s, text: %(text)s

101

110

101

4

Get Token failed: %(error)s

101

110

101

1

Failed to create client socket, error: %(error)s

101

110

101

2

Failed to connect SDK server %(addr)s:%(port)s, error: %(error)s

101

110

101

3

Failed to send all API call data to SDK server, only %(sent)d bytes sent. API call: %(api)s

101

110

101

4

Client receive empty data from SDK server

101

110

101

5

Client got socket error when sending API call to SDK server, error: %(error)s

101

110

101

6

Client got socket error when receiving response from SDK server, error: %(error)s

400

110

400

1

Invalid API name, ‘%(msg)s’

503

110

503

2

Service is unavailable. reason: %(reason)s, text: %(text)s

+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/faq.html b/doc/html/faq.html new file mode 100644 index 000000000..3323d0e05 --- /dev/null +++ b/doc/html/faq.html @@ -0,0 +1,142 @@ + + + + + + + + 11. General info — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

11. General info

+

This section provides answers to frequent asked questions.

+
+

11.1. FAQ

+
+

11.1.1. Change default NIC address

+

For NIC address on to be created VM, the default value 1000 is defined by +Feilong configuration file, generally it is defined by default_nic_vdev +item of zvm section in /etc/zvmsdk/zvmsdk.conf.

+

If you want to create a VM with different value, change it to any integer you +want and make sure no conflict to other address then restart the Feilong service.

+
+
+

11.1.2. Log on through 3270 or PCOM terminal

+

Currently, Feilong doesn’t support to set a password for virtual machine +(the definition in user directory), it is designed from a security perspective. +Only the administrator has the authority to logon the virtual machine through x3270 +or PCOM, the common user is only allowed to connect to guest through network +(ssh with id and password)

+

Refer to default_admin_userid configuration in zvm section for more detail info.

+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/generalinfo.html b/doc/html/generalinfo.html new file mode 100644 index 000000000..2d898c44d --- /dev/null +++ b/doc/html/generalinfo.html @@ -0,0 +1,166 @@ + + + + + + + + 1. General info — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

1. General info

+
+

1.1. Content of this package

+

Feilong (also known as python-zvm-sdk) is a client library written in Python +that interacts with z/VM SMAPI (System management API) of IBM Z or +LinuxONE machines. The goal of this package is to make the z/VM SMAPI easy +to be consumed by upper layer programmers and provide a set of APIs to be +called through RESTful interfaces.

+

The z/VM SMAPI is the access point for any external tools to +manage the z/VM running on IBM Z or LinuxONE platform. It supports management of +lifecycle and configuration of various platform resources, such as guest, +CPU, memory, virtual switches, disk storage, and more.

+
+
+

1.2. Version

+

This documentation applies to version 1.6.7 of the Feilong package (python-zvm-sdk). +You can also see that version in the top left corner of this page.

+

The Feilong package (python-zvm-sdk) uses the rules of Semantic Versioning 2.0.0 for +its version.

+
+
+

1.3. Compatibility

+

In this package, compatibility is always seen from the perspective of the user +of the package. Thus, a backwards compatible new version of this package means +that the user can safely upgrade to that new version without encountering +compatibility issues.

+

This package uses the rules of Semantic Versioning 2.0.0 for compatibility +between package versions, and for deprecations.

+

Violations of these compatibility rules are described in section +Release Notes.

+
+
+

1.4. Deprecations

+

Deprecated functionality is marked accordingly in this documentation and in the +Release Notes

+
+
+

1.5. Bug reporting and questions

+

If you encounter any problem with this package, please open a bug against +Feilong issue tracker or ask question Feilong question

+
+
+

1.6. License

+

This package is licensed under the Apache 2.0 License.

+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/genindex.html b/doc/html/genindex.html new file mode 100644 index 000000000..e1b156cdc --- /dev/null +++ b/doc/html/genindex.html @@ -0,0 +1,78 @@ + + + + + + + Index — Feilong 1.6.7 documentation + + + + + + + + + + + + +
+
+
+
+ + +

Index

+ +
+ +
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/index.html b/doc/html/index.html new file mode 100644 index 000000000..90c2a7246 --- /dev/null +++ b/doc/html/index.html @@ -0,0 +1,182 @@ + + + + + + + + Welcome to the Feilong Document — Feilong 1.6.7 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

Welcome to the Feilong Document

+ +
+https://i.creativecommons.org/l/by/4.0/80x15.png +

This documentation is under Creative Commons Attribution 4.0 International License

+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/makeimage.html b/doc/html/makeimage.html new file mode 100644 index 000000000..18b3e110c --- /dev/null +++ b/doc/html/makeimage.html @@ -0,0 +1,1084 @@ + + + + + + + + 5. Image and cloud-init Configuration — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

5. Image and cloud-init Configuration

+

This section discusses setting up the Linux on System z(zLinux) that is the +target of the initial image capture, after capturing this zLinux, an image will +be generated, it can be used to import into Feilong’s image +repository or Openstack glance for later deployment.

+
+

5.1. Image Requirements

+

These are the requirements for an image to be captured and deployed by Feilong:

+
    +
  1. The supported Linux distributions are:

  2. +
+
    +
  • RHEL 6.x

  • +
  • RHEL 7.x

  • +
  • RHEL 8.1

  • +
  • SLES 11.x

  • +
  • SLES 12.x

  • +
  • SELS 15

  • +
  • Ubuntu 16.04

  • +
  • Ubuntu 20.04

  • +
+

Where x is the zLinux’s minor release number

+

Note: FBA as root disk type is not supported for RHEL 8.1

+
    +
  1. The supported root disk type for capture/deploy are:

  2. +
+
    +
  • FBA

  • +
  • ECKD

  • +
+

NOTE: An image deployed via Feilong must match the disk type +configured by disk_pool in /etc/zvmsdk/zvmsdk.conf, only either FBA or ECKD image +can be deployed in zvmsdk, but not both at the same time. If you wish to switch +image types, you need to change the disk_pool configuration option and restart +sdkserver to make the changes take effect.

+
    +
  1. If you capture a zLinux with root disk size greater than 5GB, or if you deploy +an image to an root disk larger than 5G in size, please modify the timeout value +for httpd service to make it work expected. Please refer to Configure Apache +section in this document for reference.

  2. +
  3. The zLinux that used as the source of the captured image should meet the +following criteria:

  4. +
+
+
    +
  1. The root file system must not be on a logical volume

  2. +
  3. The minidisk on which the root file system resides should be a minidisk of +the same type as desired for a subsequent deploy (for example, an ECKD disk +image should be captured for a subsequent deploy to an ECKD disk), and it should +not be a full-pack minidisk, since cylinder 0 on full-pack minidisks is reserved.

  4. +
  5. If the source image is captured from minidisk with virtual address 0100, it must +be deployed to the virtual address 0100 of target Virtual Machine(VM) , otherwise, the deployed vm +will failed to start up. The root disk’s vdev can be configured with user_root_vdev +option under zvm section in /etc/zvmsdk/zvmsdk.conf. The recommendation vdev of root +disk is 0100, this is also the default value.

  6. +
  7. The root disk should have a single partition

  8. +
  9. Feilong only support deploy an image to a disk larger or equal than +the source image’s root disk size , otherwise, it would result in loss of data. +The image’s root disk size can be got by command.

  10. +
+
+
hexdump -C -n 64 <image_path>
+
+
+
+
+
+
+

5.2. Make a Deployable Image for Feilong

+
+

5.2.1. Install Linux on z Systems(zLinux) in a Virtual Machine

+
    +
  1. Prepare a Linux on z Systems virtual server in the z/VM system. You will +have to make adjustments to the procedures that are documented in the below cook +book in order to keep the resulting virtual server within the bounds of the above +image requirements.

  2. +
+ +
    +
  1. Install the mkisofs and openssl modules on it.

  2. +
  3. Make sure SELinux is disabled and the SSH connection (default port number is 22) +can pass the firewall.

  4. +
  5. Set UseDNS no in /etc/ssh/sshd_config file in order to improve the inventory +collection efficiency.

  6. +
  7. For Ubuntu 16.04, you must enable root ssh access. By default, root ssh access +is not enabled.

  8. +
+
+
+

5.2.2. Installation and Configuration of IUCV service in zLinux

+

Feilong manages the deployed VM via IUCV channel. IUCV service +should be configured on zLinux before capture it to make image. Following the below +steps to install and configure IUCV service.

+
    +
  1. Logon your BYOL(Bring Your Own Linux, which will be used to represent the Linux +on which the Feilong will be run), and copy the following files +to target VM

    +
    scp -r /opt/zthin/bin/IUCV/ root@<zLinux_ip>:/root/
    +
    +
    +

    Where: <zLinux_ip> is the ip address of zLinux

    +
  2. +
  3. Logon zLinux, install and configure IUCV service by commands:

    +
    cd /root/IUCV
    +./iucvserverdaemoninstaller.sh -a <auth_userid>
    +
    +
    +

    Where: auth_userid is the userid of the BYOL that can talk to zLinux via +IUCV channel, case insensitive, for example:

    +
    ./iucvserverdaemoninstaller.sh -a OPNCLOUD
    +Setting the authorized client userid to be: OPNCLOUD
    +IUCV server daemon is configured and started successfully
    +
    +
    +

    you may get the detail usage of iucvserverdaemoninstaller.sh by command:

    +
    ./iucvserverdaemoninstaller.sh -h
    +
    +
    +
  4. +
  5. Logon your BYOL, run a simple command to check the if the iucv +channel is set up correctly by commands:

    +
    /opt/zthin/bin/IUCV/iucvclnt <zLinux_userid> date
    +
    +
    +

    Where: <zLinux_userid> is the userid of zLinux.

    +
  6. +
+

If above commands execute successfully, you may continue to next steps. +Otherwise, stop here and re-check the configuration.

+
+
+

5.2.3. Configuration of cloud-init in zLinux

+

To do useful work with the user data, the zLinux image must be configured to +run a service that retrieves the user data passed from the Feilong +and then takes some actions based on the contents of that data. This task can +be done by cloud-init.

+

For zLinux images that deployed by Feilong, zvmguestconfigure must +be installed and started before cloud-init. +These steps of configuration zvmguestconfigure and cloud-init are described in subsequent sections.

+
+
+

5.2.4. Configuration of zvmguestconfigure in zLinux

+

The zvmguestconfigure script/service must be installed in the zLinux so it +can process the request files transmitted by Feilong to the +reader of the zLinux as a class X file. zvmguestconfigure also act as the bridge +between the zLinux and higher layer of zVM Cloud. Take spawning a VM via Openstack +nova-zvm-driver for example, the image uses cloud-init. +If customer spawn a new VM with some customized data to initialize +the VM via nova boot command. The overall work flow of the customized data is +listed as below:

+
    +
  1. Openstack nova-zvm-driver generate the cfgdrive.iso file which is iso9660 format +and with label ‘config-2’, this file is used to customize the target VM

  2. +
  3. nova-zvm-driver then call Feilong to punch the cfgdrive.iso file to +target VM’s reader

  4. +
  5. When target VM start up, the installed zvmguestconfigure will download cfgdrive.iso +file and then mount it as loop device

  6. +
  7. When cloud-init run, it will automatically find the proper configure drive data source +via command blkid -t TYPE=iso9660 -o device, then consume the data provided +by cfgdrive.iso to customize the VM

  8. +
+

The Feilong supports initiating changes to zLinux while it is shut +down or the virtual machine is logged off. The changes to zLinux are implemented +using zvmguestconfigure that is run when Linux is booted the next time. The steps +of how to install zvmguestconfigure is described in subsequent sections.

+
+

5.2.4.1. Configuration of zvmguestconfigure on RHEL6.x and SLES11.x

+

Perform the following steps:

+
    +
  1. Log on your BYOL, and copy the zvmguestconfigure script that is located at +<zvmsdk_path>/python-zvm-sdk/tools/share/zvmguestconfigure to your +zLinux, where zvmsdk_path can be found at section z/VM SDK install

  2. +
  3. Logon on your zLinux, change the script to specify the authorizedSenders in +zvmguestconfigure file. It is recommended that this be set to a list of user IDs +which are allowed to transmit changes to the machine. At a minimum, this list +should include the userid of BYOL, which is usually OPNCLOUD. (It can be set +to ‘*’, which indicates any virtual machine on the same LPAR may +send configuration requests to it)

  4. +
  5. zvmguestconfigure is configured to run with run level 2, 3 and 5. It is not +configured to run as part of custom run level 4. If that run level is going to +be used, then the # Default-Start: line at the beginning of the file should be +updated to specify run level 4 in addition to the current run levels.

  6. +
  7. Copy the zvmguestconfigure file to /etc/init.d and make it executable

  8. +
  9. Add the zvmguestconfigure as a service by issuing:

    +
    chkconfig --add zvmguestconfigure
    +
    +
    +
  10. +
  11. Activate the script by issuing:

    +
    chkconfig zvmguestconfigure on
    +
    +
    +

    If you wish to run with custom run level 4, then add 4 to the list of levels:

    +
    chkconfig --level 2345 zvmguestconfigure on
    +
    +
    +
  12. +
  13. Verify that you installed the correct version of zvmguestconfigure on the +target machine. Do this by issuing the following service command:

    +
    service zvmguestconfigure version
    +zvmguestconfigure version: 1.0
    +
    +
    +
  14. +
  15. Verify that zvmguestconfigure on the target machine is configured to handle +requests from the server specified at step 2. Do this by issuing the following +service command:

    +
    service zvmguestconfigure status
    +zvmguestconfigure is enabled to accept configuration reader files from: OPNCLOUD
    +
    +
    +

    If zvmguestconfigure is not enabled to accept configuration reader files then verify +that you followed Step 2.

    +
  16. +
+
+
+

5.2.4.2. Configuration of zvmguestconfigure on RHEL 7.x and SLES 12.x

+

Perform the following steps:

+
    +
  1. Log on your BYOL, and copy the zvmguestconfigure and zvmguestconfigure.service +script that are located at <zvmsdk_path>/python-zvm-sdk/tools/share/ folder +to your zLinux, where zvmsdk_path can be found at the section z/VM SDK install.

  2. +
  3. Logon on your zLinux, change the script to specify the authorizedSenders in +zvmguestconfigure file. It is recommended that this be set to a list of user IDs +which are allowed to transmit changes to the machine. At a minimum, this list +should include the userid of BYOL, which is usually OPNCLOUD. (It can be set +to ‘*’, which indicates any virtual machine on the same LPAR may send configuration requests to it).

  4. +
  5. Copy the zvmguestconfigure script to the /usr/bin/ folder and make it executable.

  6. +
  7. Install the zvmguestconfigure.service in the target zLinux:

  8. +
+
    +
  • If the target Linux machine is RHEL7.x, copy the zvmguestconfigureconf4z.service file to: /lib/systemd/system

  • +
  • If the target Linux machine is SLES12.x and SLES15, copy the zvmguestconfigure.service file to: /usr/lib/systemd/system +and it is recommended that you change the NetworkManager.service to be wicked.service in the zvmguestconfigure.service

  • +
+
    +
  1. Enable the zvmguestconfigure service by issuing:

    +
    systemctl enable zvmguestconfigure.service
    +
    +
    +
  2. +
  3. Start the zvmguestconfigure service by issuing:

    +
    systemctl start zvmguestconfigure.service
    +
    +
    +
  4. +
+
+
+

5.2.4.3. Configuration of zvmguestconfigure on Ubuntu 16.04 and Ubuntu 20.04

+
    +
  1. Logon your BYOL, and copy the zvmguestconfigure and zvmguestconfigure.service +script that are located at <zvmsdk_path>/python-zvm-sdk/tools/share/zvmguestconfigure +to your zLinux, where zvmsdk_path can be found at the section z/VM SDK install

  2. +
  3. Logon your zLinux, change the script to specify the authorizedSenders in +zvmguestconfigure file. It is recommended that this be set to a list of user IDs +which are allowed to transmit changes to the machine. At a minimum, this list +should include the userid of BYOL. (It can be set to ‘*’, which indicates any +virtual machine on the same LPAR may send configuration requests to it)

  4. +
  5. On zLinux, copy the zvmguestconfigure script to the /usr/bin/ folder and make +it executable.

  6. +
  7. Install the zvmguestconfigure.service in the target Ubuntu machine, tailor the +zvmguestconfigure.service file for an Ubuntu 16.04 image by modifying the file +contents as follows:

    +
    [Unit]
    +Description=Activation engine for configuring z/VM when it starts
    +Wants=local-fs.target
    +After=local-fs.target
    +Before=cloud-init-local.service network-pre.target
    +[Service]
    +Type=oneshot
    +ExecStart=/usr/bin/zvmguestconfigure start
    +StandardOutput=journal+console
    +[Install]
    +WantedBy=multi-user.target
    +
    +
    +

    After that, copy the zvmguestconfigure.service file to /lib/systemd/system. If the +target Linux machine is Ubuntu 20.04, copy the zvmguestconfigure.service.ubuntu file +to: /lib/systemd/system, and rename to zvmguestconfigure.service.

    +
  8. +
  9. Enable the zvmguestconfigure service by issuing:

    +
    systemctl enable zvmguestconfigure.service
    +
    +
    +
  10. +
  11. Start the zvmguestconfigure service by issuing:

    +
    systemctl start zvmguestconfigure.service
    +
    +
    +
  12. +
+
+
+
+

5.2.5. Installation and Configuration of cloud-init

+

Please note that if customer won’t pass customize data via openstack configdrive, +cloud-init will not need to be installed. In this case, the steps in this section +can be ignored.

+

OpenStack uses cloud-init as its activation engine.Some distributions include +cloud-init either already installed or available to be installed. +If your distribution does not include cloud-init, you can download the code +from https://launchpad.net/cloud-init/+download. After +installation, if you issue the following shell command and no errors occur, +cloud-init is installed correctly.

+
cloud-init init --local
+
+
+

Installation and configuration of cloud-init differs among different Linux +distributions, and cloud-init source code may change. This section provides +general information, but you may have to tailor cloud-init to meet the needs +of your Linux distribution. You can find a community-maintained list of +dependencies at http://ibm.biz/cloudinitLoZ.

+

The z/VM OpenStack support has been tested with cloud-init 0.7.4 and 0.7.5 for +RHEL6.x and SLES11.x, 0.7.6 for RHEL7.x and SLES12.x, and 18.4 for SLES15, and +18.5 for RHEL8.1, and 0.7.8 for Ubuntu 16.04.

+

If you are using a different version of cloud-init, you should change your +specification of the indicated commands accordingly.During cloud-init +installation, some dependency packages may be required. You can use yum/zypper +and python setuptools to easily resolve these dependencies. +See https://pypi.python.org/pypi/setuptools for more information.

+
+

5.2.5.1. Installation and Configuration of cloud-init on RHEL 6.x

+
    +
  1. Download the cloud-init tar file from Init scripts for use on cloud images +https://launchpad.net/cloud-init/+download

  2. +
  3. Using the file cloud-init-0.7.5 as an example, +untar this file by issuing the following command:

    +
    tar -zxvf cloud-init-0.7.5.tar.gz
    +
    +
    +
  4. +
  5. Issue the following to install cloud-init:

    +
    cd ./cloud-init-0.7.5
    +python setup.py build
    +python setup.py install
    +cp ./sysvinit/redhat/* /etc/init.d
    +
    +
    +
  6. +
  7. Update /etc/init.d/cloud-init-local to ensure that it starts after the +zvmguestconfigure and sshd services. On RHEL 6, change the # Required-Start +line in the ### BEGIN INIT INFO section from:

    +
    ### BEGIN INIT INFO
    +# Provides: cloud-init-local
    +# Required-Start: $local_fs $remote_fs
    +# Should-Start: $time
    +# Required-Stop:
    +
    +
    +

    to:

    +
    ### BEGIN INIT INFO
    +# Provides: cloud-init-local
    +# Required-Start: $local_fs $remote_fs zvmguestconfigure sshd
    +# Should-Start: $time
    +# Required-Stop:
    +
    +
    +
  8. +
  9. The default configuration file /etc/cloud/cloud.cfg is for ubuntu, not RHEL. +To tailor it for RHEL:

  10. +
+
+
    +
  1. Replace distro:ubuntu with distro:rhel at around line 79.

  2. +
  3. Change the default user name, password and gecos as you wish, at around lines 82 to 84

  4. +
  5. Change the groups tag to remove user groups that are not available for this distribution. +After the change, the groups tag at around line 85 should appear similar to the following: +groups: [adm, audio, cdrom, dialout, floppy, video, dip]

  6. +
+
+

For more information on how to configure cloud-init, please check the cloud-init documentation +http://cloudinit.readthedocs.org/.

+
+
+
    +
  1. Cloud-init will try to add user syslog to group adm. This needs to be +changed. RHEL does not have a syslog user by default, so issue:

    +
    useradd syslog
    +
    +
    +
  2. +
  3. Add the cloud-init related service with the following commands:

    +
    chkconfig --add cloud-init-local
    +chkconfig --add cloud-init
    +chkconfig --add cloud-config
    +chkconfig --add cloud-final
    +
    +
    +
  4. +
  5. Then start them with the following sequence:

    +
    chkconfig cloud-init-local on
    +chkconfig cloud-init on
    +chkconfig cloud-config on
    +chkconfig cloud-final on
    +
    +
    +

    You can issue ls -l /etc/rc5.d/ | grep -e xcat -e cloud to find the services. +(Make sure that zvmguestconfigure starts before any cloud-init service.)

    +
    lrwxrwxrwx. 1 root root 22 Jun 13 04:39 S50xcatconfinit -> ../init.d/zvmguestconfigure
    +lrwxrwxrwx. 1 root root 26 Jun 13 04:39 S51cloud-init-local -> ../init.d/cloud-init-local
    +lrwxrwxrwx. 1 root root 20 Jun 13 04:39 S52cloud-init -> ../init.d/cloud-init
    +lrwxrwxrwx. 1 root root 22 Jun 13 04:39 S53cloud-config -> ../init.d/cloud-config
    +lrwxrwxrwx. 1 root root 21 Jun 13 04:39 S54cloud-final -> ../init.d/cloud-final
    +
    +
    +
  6. +
  7. To verify cloud-init configuration, issue: cloud-init init –local

    +
    cloud-init init --local
    +
    +
    +

    Make sure that no errors occur. The following warning messages can be ignored:

    +

    /usr/lib/python2.6/site-packages/Cheetah-2.4.4-py2.6.egg/Cheetah/Compiler.py:1509: UserWarning: +You don’t have the C version of NameMapper installed! I’m disabling Cheetah’s useStackFrames +option as it is painfully slow with the Python version of NameMapper. You should get a copy +of Cheetah with the compiled C version of NameMapper. You don’t have the C version of NameMapper installed!

    +
  8. +
  9. Issue following command, if this file exists, or cloud-init will not work after reboot.

    +
    rm -rf /var/lib/cloud
    +
    +
    +
  10. +
+
+
+

5.2.5.2. Installation and Configuration of cloud-init on SLES11.x

+
    +
  1. Download the cloud-init tar file from https://launchpad.net/cloud-init/+download.

  2. +
  3. Using the file cloud-init-0.7.5 as an example, untar this file by issuing +the following command:

    +
    tar -zxvf cloud-init-0.7.5.tar.gz
    +
    +
    +
  4. +
  5. Issue the following commands to install cloud-init:

    +
    cd ./cloud-init-0.7.5
    +python setup.py build
    +python setup.py install
    +
    +
    +

    NOTE:: After you issue the command tar -zxvf cloud-init-0.7.5.tar.gz, +the directory ./sysvinit/sles/ does not exist. So you have to copy the +cloud-init related services from ./sysvinit/redhat/* to /etc/init.d/:

    +
    cp ./sysvinit/redhat/* /etc/init.d
    +
    +
    +

    You will find that four scripts, cloud-init-local, cloud-init, cloud-config, +and cloud-final are added to /etc/init.d/. Modify each of them by replacing +the variable:

    +
    cloud_init="/usr/bin/cloud-init"
    +
    +
    +

    with:

    +
    cloud_init="/usr/local/bin/cloud-init"
    +
    +
    +
  6. +
  7. Update /etc/init.d/cloud-init-local to ensure that it starts after the +zvmguestconfigure service. On SLES, change the # Required-Start line in the +### BEGIN INIT INFO section from:

    +
    ### BEGIN INIT INFO
    +# Provides: cloud-init-local
    +# Required-Start: $local_fs $remote_fs
    +# Should-Start: $time
    +# Required-Stop:
    +
    +
    +

    to:

    +
    ### BEGIN INIT INFO
    +# Provides: cloud-init-local
    +# Required-Start: $local_fs $remote_fs zvmguestconfigure
    +# Should-Start: $time
    +# Required-Stop:
    +
    +
    +
  8. +
  9. The default configuration file /etc/cloud/cloud.cfg is for ubuntu, not SLES. To tailor it for SLES:

  10. +
+
+
    +
  1. Replace distro:ubuntu with distro:sles at around line 79.

  2. +
  3. Change the default user name, password and gecos as you wish, at around lines 82 to 84.

  4. +
  5. Change the groups at around line 85: groups: [adm, audio, cdrom, dialout, floppy, video, dip]

  6. +
  7. Cloud-init will try to add user syslog to group adm. This needs to be changed. For SLES, issue the following commands:

    +
    useradd syslog
    +groupadd adm
    +
    +
    +
  8. +
+

For more information on changing these values, see the cloud-init documentation http://cloudinit.readthedocs.org/

+
+
    +
  1. Start the cloud-init related services with the following commands, +ignoring the error “insserv: Service network is missed in the runlevels 4 +to use service cloud-init” if it occurs:

    +
    insserv cloud-init-local
    +insserv cloud-init
    +insserv cloud-config
    +insserv cloud-final
    +
    +
    +

    At this point, you should find that the services in /etc/init.d/rcX.d appear as +you would expect (make sure that zvmguestconfigure starts before any cloud-init service):

    +
    lrwxrwxrwx. 1 root root 22 Jun 13 04:39 S50xcatconfinit -> ../init.d/zvmguestconfigure
    +lrwxrwxrwx. 1 root root 26 Jun 13 04:39 S51cloud-init-local -> ../init.d/cloud-init-local
    +lrwxrwxrwx. 1 root root 20 Jun 13 04:39 S52cloud-init -> ../init.d/cloud-init
    +lrwxrwxrwx. 1 root root 22 Jun 13 04:39 S53cloud-config -> ../init.d/cloud-config
    +lrwxrwxrwx. 1 root root 21 Jun 13 04:39 S54cloud-final -> ../init.d/cloud-final
    +
    +
    +
  2. +
  3. To verify cloud-init configuration, issue:

    +
    cloud-init init --local
    +
    +
    +

    Make sure that no errors occur. The following warning messages can be ignored: +/usr/lib/python2.6/site-packages/Cheetah-2.4.4-py2.6.egg/Cheetah/Compiler.py:1509: +UserWarning: +You don’t have the C version of NameMapper installed! I’m disabling Cheetah’s useStackFrames +option as it is painfully slow with the Python version of NameMapper. You should get a copy +of Cheetah with the compiled C version of NameMapper. +You don’t have the C version of NameMapper installed!

    +
  4. +
  5. Issue following command, if this file exists, or cloud-init will not work after reboot.

    +
    rm -rf /var/lib/cloud
    +
    +
    +
  6. +
+
+
+

5.2.5.3. Installation and Configuration of cloud-init on RHEL 7.x and SLES 12.x

+
    +
  1. Download cloud-init0.7.6 from https://launchpad.net/cloud-init/+download.

  2. +
  3. Untar it with this command:

    +
    tar -zxvf cloud-init-0.7.6.tar.gz
    +
    +
    +
  4. +
  5. Issue the following commands to install cloud-init:

    +
    cd ./cloud-init-0.7.6
    +python setup.py build
    +python setup.py install --init-system systemd
    +
    +
    +
  6. +
  7. OpenStack on z/VM uses ConfigDrive as the data source during the installation +process. You must add the following lines to the default +configuration file, /etc/cloud/cloud.cfg:

    +
    # Example datasource config
    +# datasource:
    +#   Ec2:
    +#
    +# metadata_urls: [ ’blah.com’ ]
    +#
    +# timeout: 5 # (defaults to 50 seconds)
    +#
    +#     max_wait: 10 # (defaults to 120 seconds)
    +datasource_list: [ ConfigDrive, None ]
    +datasource:
    +  ConfigDrive:
    +    dsmode: local
    +
    +
    +

    NOTE: please pay attention to the indentation, otherwise, cloud-init may not +work as expected.

    +
  8. +
  9. In order to work well with other products, the service start up sequence +for cloud-init-local and cloud-init should be changed to the following. +(The cloud-init related service files are located in the folder +/lib/systemd/system/ for RHEL7.x and in /usr/lib/systemd/system/ for SLES12.x)

    +
    cat /lib/systemd/system/cloud-init-local.service
    +[Unit]
    +Description=Initial cloud-init job (pre-networking)
    +Wants=local-fs.target sshd.service sshd-keygen.service
    +After=local-fs.target sshd.service sshd-keygen.service
    +[Service]
    +Type=oneshot
    +ExecStart=/usr/bin/cloud-init init --local
    +RemainAfterExit=yes
    +TimeoutSec=0
    +# Output needs to appear in instance console output
    +StandardOutput=journal+console
    +[Install]
    +WantedBy=multi-user.target
    +
    +# cat /lib/systemd/system/cloud-init.service
    +[Unit]
    +Description=Initial cloud-init job (metadata service crawler)
    +After=local-fs.target network.target cloud-init-local.service
    +Requires=network.target
    +Wants=local-fs.target cloud-init-local.service
    +[Service]
    +Type=oneshot
    +ExecStart=/usr/bin/cloud-init init
    +RemainAfterExit=yes
    +TimeoutSec=0
    +# Output needs to appear in instance console output
    +StandardOutput=journal+console
    +[Install]
    +WantedBy=multi-user.target
    +
    +
    +
  10. +
  11. Manually create the cloud-init-tmpfiles.conf file:

    +
    touch /etc/tmpfiles.d/cloud-init-tmpfiles.conf
    +
    +
    +

    Insert comments into the file by issuing the following command:

    +
    echo "d /run/cloud-init 0700 root root - -" > /etc/tmpfiles.d/cloud-init-tmpfiles.conf
    +
    +
    +
  12. +
  13. Because RHEL does not have a syslog user by default, you have to add it manually:

    +
    useradd syslog
    +
    +
    +
  14. +
  15. In /etc/cloud/cloud.cfg, remove the ubuntu-init-switch, growpart and +resizefs modules from the cloud_init_modules section. Here is the +cloud_init_modules section after the change:

    +
    # The modules that run in the ’init’ stage
    +cloud_init_modules:
    + - migrator
    + - seed_random
    + - bootcmd
    + - write-files
    + - set_hostname
    + - update_hostname
    + - update_etc_hosts
    + - ca-certs
    + - rsyslog
    + - users-groups
    + - ssh
    +
    +
    +
  16. +
  17. In /etc/cloud/cloud.cfg, remove the emit_upstart, ssh-import-id, +grub-dpkg, apt-pipelining, apt-config, landscape, and byobu modues +from the cloud_config section. Here is the cloud_config_modules section +after the change:

    +
    cloud_config_modules:
    +# Emit the cloud config ready event
    +# this can be used by upstart jobs for ’start on cloud-config’.
    + - disk_setup
    + - mounts
    + - locale
    + - set-passwords
    + - package-update-upgrade-install
    + - timezone
    + - puppet
    + - salt-minion
    + - mcollective
    + - disable-ec2-metadata
    + - runcmd
    +
    +
    +
  18. +
  19. The default /etc/cloud/cloud.cfg file is for ubuntu, +and must be updated for RHEL and SLES. To tailor this file for RHEL and SLES:

  20. +
+
+
    +
  1. Change the disable_root: true line to: disable_root: false

  2. +
  3. In the system_info section, replace distro:ubuntu with distro:rhel or distro:sles according to +the distribution you will use.

  4. +
  5. Change the default user name, password, and gecos under default_user configuration section as needed for your installation.

  6. +
  7. Change the groups tag to remove the user groups that are not available on this distribution. When cloud-init starts up at first time, it will create the specified users and groups. The following is a sample configuration for SLES:

  8. +
+
system_info:
+# This will affect which distro class gets used
+distro: sles
+ # Default user name + that default user’s groups (if added/used)
+default_user:
+ name: sles
+ lock_passwd: false
+ plain_text_passwd: ’sles’
+ gecos: sles12user
+ groups: users
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
+ shell: /bin/bash
+
+
+

For more information on cloud-init configurations, see: http://cloudinit.readthedocs.org/en/latest/topics/examples.html

+
+
    +
  1. Enable and start the cloud-init related services by issuing the following commands:

    +
    systemctl enable cloud-init-local.service
    +systemctl start cloud-init-local.service
    +systemctl enable cloud-init.service
    +systemctl start cloud-init.service
    +systemctl enable cloud-config.service
    +systemctl start cloud-config.service
    +systemctl enable cloud-final.service
    +systemctl start cloud-final.service
    +
    +
    +
  2. +
+
+

If you experience problems the first time you start cloud-config.service and +cloud-final.service, try starting them again.

+
+
    +
  1. Ensure all cloud-init services are in active status by issuing the following commands:

    +
    systemctl status cloud-init-local.service
    +systemctl status cloud-init.service
    +systemctl status cloud-config.service
    +systemctl status cloud-final.service
    +
    +
    +
  2. +
  3. Optionally, you can start the multipath service:

    +
    systemctl enable multipathd
    +systemctl start multipathd
    +systemctl status multipathd
    +
    +
    +
  4. +
  5. Remove the /var/lib/cloud directory (if it exists), so that cloud-init will +not run after a reboot:

    +
    rm -rf /var/lib/cloud
    +
    +
    +
  6. +
+
+
+

5.2.5.4. Installation and Configuration of cloud-init on RHEL8.1 and SLES15

+

Enable the system repositories of the RHEL8.1 and SLES15 to ensure that they can install software via yum and zypper.

+
    +
  1. Install cloud-init by the command:

  2. +
+
+
    +
  1. For the RHEL8.1:

    +
    yum install cloud-init
    +
    +
    +
  2. +
  3. For the SLES15:

    +
    zypper install cloud-init
    +
    +
    +
  4. +
+
+
    +
  1. OpenStack on z/VM uses ConfigDrive as the data source during the +installation process. You must add the following lines to the +default configuration file, /etc/cloud/cloud.cfg. Remember to disable network +configuration because network configuration is done by zvmguestconfigure.

    +
    # Example datasource config
    +# datasource:
    +#   Ec2:
    +#
    +# metadata_urls: [ ’blah.com’ ]
    +#
    +# timeout: 5 # (defaults to 50 seconds)
    +#
    +#     max_wait: 10 # (defaults to 120 seconds)
    +datasource_list: [ ConfigDrive, None ]
    +datasource:
    +  ConfigDrive:
    +    dsmode: local
    +network: {config: disabled}
    +
    +
    +

    NOTE: please pay attention to the indentation, otherwise, cloud-init may not +work as expected.

    +
  2. +
  3. Optionally, enable root login by configuring the /etc/cloud/cloud.cfg file:

    +
    disable_root: false
    +
    +
    +
  4. +
  5. Enable and start the cloud-init related services by issuing the following commands:

    +
    systemctl enable cloud-init-local.service
    +systemctl start cloud-init-local.service
    +systemctl enable cloud-init.service
    +systemctl start cloud-init.service
    +systemctl enable cloud-config.service
    +systemctl start cloud-config.service
    +systemctl enable cloud-final.service
    +systemctl start cloud-final.service
    +
    +
    +

    If you experience problems the first time you start cloud-config.service and +cloud-final.service, try starting them again.

    +
  6. +
  7. Ensure all cloud-init services are in active status by issuing the following commands:

    +
    systemctl status cloud-init-local.service
    +systemctl status cloud-init.service
    +systemctl status cloud-config.service
    +systemctl status cloud-final.service
    +
    +
    +
  8. +
  9. +
    Remove the /var/lib/cloud directory (if it exists), so that cloud-init will

    not run after a reboot:

    +
    +
    +
    rm -rf /var/lib/cloud
    +
    +
    +
  10. +
+
+
+

5.2.5.5. Installation and Configuration of cloud-init on Ubuntu 16.04 and Ubuntu 20.04

+

For Ubuntu 16.04, cloud-init0.7.8 or higher is required. The examples in this +section use cloud-init0.7.8.

+

For Ubuntu 20.04, cloud-init20.1-10 is installed by default, can ignore below step1-2.

+
    +
  1. Download cloud-init0.7.8 from https://launchpad.net/cloud-init/+download. +Untar it with this command:

    +
    tar -zxvf cloud-init-0.7.8.tar.gz
    +
    +
    +
  2. +
  3. Issue the following commands to install cloud-init:

    +
    cd ./cloud-init-0.7.8
    +python3 setup.py build
    +python3 setup.py install --init-system systemd
    +
    +
    +

    NOTE: You might have to install all the dependencies that cloud-init +requires according to your source z/VM environment. For example, you might +have to install setuptools before installing cloud-init. For more information, +see https://pypi.python.org/pypi/setuptools.

    +
  4. +
  5. OpenStack on z/VM uses ConfigDrive as the data source during the +installation process. You must add the following lines to the +default configuration file, /etc/cloud/cloud.cfg:

    +
    # Example datasource config
    +# datasource:
    +#   Ec2:
    +#
    +# metadata_urls: [ ’blah.com’ ]
    +#
    +# timeout: 5 # (defaults to 50 seconds)
    +#
    +#     max_wait: 10 # (defaults to 120 seconds)
    +datasource_list: [ ConfigDrive, None ]
    +datasource:
    +  ConfigDrive:
    +    dsmode: local
    +
    +
    +

    NOTE: please pay attention to the indentation, otherwise, cloud-init may not +work as expected.

    +
  6. +
  7. Enable root login by configuring the /etc/cloud/cloud.cfg file:

    +
    disable_root: false
    +
    +
    +
  8. +
  9. Optionally, you can tailor the modules that run during the cloud-config +stage or the cloud-final stage by modifying cloud_config_modules or +cloud_final_modules in /etc/cloud/cloud.cfg file. +Enable and start the cloud-init related services by issuing the following commands:

    +
    ln -s /usr/local/bin/cloud-init /usr/bin/cloud-init
    +systemctl enable cloud-init-local.service
    +systemctl start cloud-init-local.service
    +systemctl enable cloud-init.service
    +systemctl start cloud-init.service
    +systemctl enable cloud-config.service
    +systemctl start cloud-config.service
    +systemctl enable cloud-final.service
    +systemctl start cloud-final.service
    +
    +
    +
  10. +
  11. Ensure all cloud-init services are in active status by issuing the following commands:

    +
    systemctl status cloud-init-local.service
    +systemctl status cloud-init.service
    +systemctl status cloud-config.service
    +systemctl status cloud-final.service
    +
    +
    +
  12. +
  13. If you intend to use persistent disks, start the multipath service:

    +
    systemctl enable multipathd
    +systemctl start multipathd
    +systemctl status multipathd
    +
    +
    +
  14. +
  15. Remove the /var/lib/cloud directory (if it exists), so that cloud-init will +not run after a reboot:

    +
    rm -rf /var/lib/cloud
    +
    +
    +
  16. +
+
+
+
+
+

5.3. Capture the zLinux to Generate the Image

+

After zLinux is well configured for capture, shut down it and logoff the userid, +then perform the following steps to generate the image:

+

Logon your BYOL, type the command:

+
/opt/zthin/bin/creatediskimage <zLinux_userid> <vdev> <image_location>
+
+
+

Where: +<zLinux_userid> is the userid of the zLinux, +<vdev> is the device number for capture, +<image_location> is the image’s store location

+
+
+

5.4. Import the Images to Feilong

+

If you want to import the image to Feilong, you can use REST API. +Type the following command:

+
# curl http://1.2.3.4:8080/images -H "Content-Type:application/json" -H 'X-Auth-Token:<your token>' -X POST -d '{"image": {"url": "file:///var/lib/zvmsdk/images/0100", "image_meta": {"os_version": "rhel6.7"}, "image_name": "0100", "remote_host": "root@6.7.8.9"}}'
+{"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": "", "errmsg": ""}
+
+
+

Please note that if the source image is located at same server as BYOL, there is no need +to specify the remote_host parameter in data field. And please refer to Securing Connections with Tokens to get +your token to fill in the request area <your token>.

+

Verify the import result by command:

+
# curl http://127.0.0.1:8080/images?imagename=0100 -X GET -H "Content-Type:application/json" -H 'X-Auth-Token:<your token>'
+{"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": [{"image_size_in_bytes": "236435482", "disk_size_units": "1100:CYL", "md5sum": "26ddd19301d4f9c8a85e812412164bb8", "comments": null, "imagename": "0100", "imageosdistro": "rhel6.7", "type": "rootonly"}], "errmsg": ""}
+
+
+

During image import you may meet following error:

+
{u'rs': 10, u'overallRC': 300, u'modID': 40, u'rc': 300, u'output': u'', 'errmsg': u"Image import error:
+Copying image file from remote filesystem failed with error Warning: Permanently added '6.7.8.9' (ECDSA)
+to the list of known hosts.\r\nPermission denied, please try again.\r\nPermission denied, please try again.
+\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n"}
+
+
+

If similar error happens, you need to configure the ssh authentication between +your BYOL server and the server that source image located. You need to append the +public key of the owner that running sdkserver to the .ssh/authorized_keys file of +the user where your source image located. Please refer to Configuration Sample for reference.

+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/objects.inv b/doc/html/objects.inv new file mode 100644 index 000000000..1cb53616d --- /dev/null +++ b/doc/html/objects.inv @@ -0,0 +1,9 @@ +# Sphinx inventory version 2 +# Project: Feilong +# Version: 1.6.7 +# The remainder of this file is compressed using zlib. +xڕTKo +6W*[^rHSXM`hcgi13;U@C$,# +ЇAe = +RP#x_m@p_#bSY씌rlWˆ{7柵-誒ME~Rؚ{ qCElf_'rxPhevѫL98xYˬ3z +F[djez-/%lRQ坈 ],=#m6?Ps; 4Ϩ5^Y4 G5@/2綹Q0eTh[2XJ-6s?dC5ꧨp}~]C4}di5M 腒FghV_wèx>cp/@ ++M>cb_]HM9߼N;K.f6ҽWK MmmuH,L7MGo,ţ$|AUC/%! \ No newline at end of file diff --git a/doc/html/quickstart.html b/doc/html/quickstart.html new file mode 100644 index 000000000..0617e2983 --- /dev/null +++ b/doc/html/quickstart.html @@ -0,0 +1,707 @@ + + + + + + + + 3. Quick Start — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

3. Quick Start

+

This is the document that describes the installation, configuration, +and basic usages of Feilong.

+
+

3.1. Pre-requirements

+

1. Feilong depends on the under-layer z/VM SMAPI support to manage +the z/VM objects. For the Feilong to work normally, the managed z/VM +system should be updated to the latest level with APARs listed in the +z/VM service Information installed.

+
+

Note

+

please make sure you applied http://www-01.ibm.com/support/docview.wss?uid=isg1VM66120 +if z/VM 6.4 is used.

+
+

2. Feilong has to be installed inside a Linux running on z/VM. +Currently supported distros include the most current supported versions:

+
+
    +
  • SUSE Linux Enterprise Server 15 SP6

  • +
  • Red Hat Enterprise Linux 9.4

  • +
  • Ubuntu 24.04 LTS

  • +
+

From now on, BYOL (Bring Your Own Linux) will be used to represent +the Linux on which the Feilong will be run.

+

For the Feilong to run, the BYOL must have enough free disk space (>100M). +And besides that, the following updates need to be made to the BYOL.

+
+
+

3.1.1. Preparation on BYOL

+
    +
  1. Authorize BYOL user for z/VM SMAPI call.

    +

    VSMWORK1 AUTHLIST needs to be updated in order to make the BYOL +machine be able to issue SMAPI call. Refer to z/VM Systems Management +Application Programming for how to make it.

    +
  2. +
+
+

Note

+

It is recommend to consider increase the SMAPI long call server and DIRMAINT +DATAMOVE machine if heavy concurrent workload is going to be run through Feilong. +See z/VM Systems Management Application Programming for how to make it.

+
+
    +
  1. Update BYOL definition for spawning guests.

    +

    Assume BYOL has its definition on z/VM, it needs to have following statement in +its User Directory in order to link disk during stage of spawning guests.

    +
    OPTION LNKNOPAS
    +
    +
    +

    If under RACF, RACF command need to be executed like below while the BYOL +is the name of the virtual machine which is going to run Feilong service.

    +
    RAC PERMIT BYOL CLASS(VMRDR) ID(VSMWORK1) ACCESS(UPDATE)
    +
    +
    +
  2. +
+
+

Note

+

Please note when under RACF (ESM of z/VM) is used, additional setup for SMAPI is needed +to make the BYOL able to work.

+

See z/VM Systems Management Application Programming for how to make it.

+
+
    +
  1. Update BYOL definition about IUCV

    +

    Assume BYOL has its definition on z/VM, it needs to have following entry in +its User Directory in order to communicate with the managed guests by the IUCV +channel

    +
    IUCV ANY
    +
    +
    +

    See z/VM Systems Management Application Programming for how to make it.

    +
  2. +
+
    +
  1. Enable reader device

    +

    In order to get console output of target vm, BYOL’s reader device needs to +be enabled to receive console output spool files send from target vm

    +

    Use the following command on BYOL itself to achieve that:

    +
    [root@xxxx ~]# cio_ignore -r 000c
    +[root@xxxx ~]# chccwdev -e 000c
    +Setting device 0.0.000c online
    +Done
    +
    +
    +

    If something like ‘is already online’ is returned, it means reader already +online and feel free to ignore the warning.

    +
  2. +
  3. Enable punch device

    +

    In order to spawn guest, BYOL needs to be able to punch files to spawned +guests’ reader, so the punch device on BYOL needs to be enabled.

    +

    Use the following command on BYOL itself to achieve that:

    +
    [root@xxxx ~]# cio_ignore -r 000d
    +[root@xxxx ~]# chccwdev -e 000d
    +Setting device 0.0.000d online
    +Done
    +
    +
    +

    If something like ‘is already online’ is returned, it means punch already +online and feel free to ignore the warning.

    +
  4. +
+
+

Note

+

Preparation step 2 and step 3 require to logoff then re-logon the +BYOL to make the updates become effective.

+
+
+
+

3.1.2. Installation Requirements

+

The supported Python version includes:

+
    +
  • Python 2.7

  • +
  • Python 3+

  • +
+
+
+
+

3.2. Installation using OBS Packages

+

The Open Build Service (OBS) is a generic system to build and distribute binary packages from sources in an automatic, consistent and reproducible way. +OBS builds and provides an installable version of the zthin and zvmsdk packages for each of the distributions (RHEL, SLES, Ubuntu).

+
+

3.2.1. RPM for RHEL/Alma/Rocky

+

SSH onto the BYOL as root user, and then follow the following steps:

+
    +
  1. Add the feilong AlmaLinux repository from OBS

    +
    +
    # dnf config-manager --add-repo=https://download.opensuse.org/repositories/Virtualization:/feilong/AlmaLinux_9/
    +
    +
    +
    +
  2. +
  3. Disable gpgkeycheck flag

    +
    +

    Add the flag gpgkeycheck=0 to the +/etc/yum.repos.d/download.opensuse.org_repositories_Virtualization_feilong_AlmaLinux_9_.repo file.

    +
    +
  4. +
  5. Disable SELinux

    +
    +

    Update the config file /etc/selinux/config and set SELINUX=disabled. +Make sure you reboot to ensure the changes are reflected and SELinux is disabled.

    +

    We are considering writing SELinux policies for Feilong that would enable to not disable SELinux as a whole.

    +
    +
  6. +
  7. Install the Extra Packages for Enterprise Linux.

    +
    +

    Packages in EPEL are dependencies for the feilong packages installation. +Make sure you add both the EPEL and the EPEL-Next repos.

    +
    +
  8. +
  9. Install the zthin and zvmsdk packages

    +
    +
    # dnf install zthin zvmsdk
    +
    +
    +
    +
  10. +
  11. Skip to the SSH key authentication between consumer and BYOL section to continue.

  12. +
+
+
+

3.2.2. RPM for SLES

+

SSH onto the BYOL as root user, and then follow the following steps:

+
    +
  1. Register to the SUSE Package Hub using SUSEConnect and refresh the available repos list.

    +
    +

    Packages in the PackageHub are dependencies for the feilong package installation

    +
    # SUSEConnect --product PackageHub/15.5/s390x
    +
    +
    +
    +
  2. +
  3. Add the feilong SUSE repository from OBS

    +
    +
    # zypper ar https://download.opensuse.org/repositories/Virtualization:/feilong/SLE_15_SP5/ feilong
    +# zypper refresh
    +
    +
    +
    +
  4. +
  5. Install the zthin and zvmsdk packages

    +
    +
    # zypper in zthin zvmsdk
    +
    +
    +
    +
  6. +
  7. Skip to the SSH key authentication between consumer and BYOL section to continue.

  8. +
+
+
+

3.2.3. DEB for Ubuntu

+

SSH onto the BYOL as root user, and then follow the following steps:

+
    +
  1. Add the feilong Ubuntu repository from OBS

    +
    +
    # bash -c "echo 'deb http://download.opensuse.org/repositories/home:/Aazam:/feilong/xUbuntu_24.04/ /' > /etc/apt/sources.list.d/feilong.list"
    +# wget http://download.opensuse.org/repositories/Virtualization:/feilong/xUbuntu_24.04/Release.key
    +# mv Release.key /etc/apt/trusted.gpg.d/feilong.asc
    +
    +
    +
    +
  2. +
  3. Update the apt repository list

    +
    +
    # apt update
    +
    +
    +
    +
  4. +
  5. Disable SELinux

    +
    +

    Update the config file /etc/selinux/config and set SELINUX=disabled. +Make sure you reboot to ensure the changes are reflected and SELinux is disabled.

    +

    We are considering writing SELinux policies for Feilong that would enable to not disable SELinux as a whole.

    +
    +
  6. +
+
    +
  1. Install the zthin and zvmsdk packages

    +
    +
    # apt-get install zthin zvmsdk
    +
    +
    +
    +
  2. +
  3. Skip to the SSH key authentication between consumer and BYOL section to continue.

  4. +
+
+
+
+

3.3. Manual Installation

+
+

3.3.1. z/VM zthin install

+

zthin is a library written in C that works as part of the Feilong. +It mainly focuses on socket connection from BYOL to z/VM SMAPI(System Management API). +Feilong requires zthin as the backend to communicate with z/VM SMAPI, +thus it needs to be installed before installing Feilong.

+

SSH onto the BYOL as root user, and then follow the following steps:

+
    +
  1. Clone build project from github

    +
    # git clone https://github.com/mfcloud/build-zvmsdk.git
    +# cd build-zvmsdk
    +
    +
    +
  2. +
  3. Trigger the build tool

    +

    The build tool depends on the following commands: rpmbuild, gcc, so you should make +sure these commands are usable on BYOL before running the following build.

    +

    For building on RHEL

    +
    # /usr/bin/bash buildzthinrpm_rhel master
    +
    +
    +

    For building on SLES

    +
    # /usr/bin/bash buildzthinrpm_sles master
    +
    +
    +

    If this build finishes successfully, the resulting rpm package will be generated +in the /root/zthin-build/RPMS/s390x/ directory named in the format +zthin-version-snapdate.s390x.rpm where version is the zthin version +number and date is the build date.

    +

    For building on Debian, make sure you have dpkg-dev available.

    +
       # /usr/bin/bash buildzthindeb master
    +
    +If the build finishes successfully, the resulting deb package will be generated
    +in the /root/build-zvmsdk/feilong directory named in the format
    +*zthin-version.s390x.deb* where *version* is the zthin version
    +number and *date* is the build date.
    +
    +
    +
  4. +
  5. Install the rpm or deb generated in last step

    +
    # rpm -ivh /root/zthin-build/RPMS/s390x/zthin-3.1.0-snap201710300123.s390x.rpm
    +
    +
    +

    Be sure to replace the zthin-3.1.0-snap201710300123.s390x.rpm with the correct version name.

    +
    # dpkg -i /root/build-zvmsdk/feilong/zthin-3.1.2.s390x.deb
    +
    +
    +

    Be sure to replace the zthin-3.1.2.s390x.deb with the correct version name.

    +
  6. +
  7. Verify zthin can work

    +
    # /opt/zthin/bin/smcli Image_Query_DM -T opncloud
    +
    +
    +

    If all things went well, this smcli command should be +able to return the directory entry of user OPNCLOUD.

    +

    If this command failed, you need to check the following items:

    +
      +
    • The BYOL user is successfully authorized to issue SMAPI call.

    • +
    • The SMAPI server on this z/VM host is working normally.

    • +
    • The zthin rpm is installed without any error.

    • +
    +
  8. +
  9. Optionally, Consider to add /opt/zthin/bin/ into $PATH so you can use smcli command directly.

  10. +
+
+
+

3.3.2. z/VM SDK install

+

z/VM SDK is the upper transition layer of Feilong. It implements the +supported SDK APIs by communicating with the zthin backend.

+
    +
  1. Install z/VM sdk

    +
    +

    Please ensure to update your setuptools to the latest version before doing this step, +the following installation step would rely on it to automatically install the depended +python packages.

    +
    # git clone https://github.com/mfcloud/build-zvmsdk.git
    +# cd build-zvmsdk
    +
    +
    +
    +
  2. +
  3. Trigger the build tool

    +

    The build tool depends on the following commands: rpmbuild, gcc, so you should make +sure these commands are usable on BYOL before running the following build.

    +

    For building on RHEL

    +
    # /usr/bin/bash buildzvmdsdkrpm_rhel master
    +
    +
    +

    For building on SLES

    +
    # /usr/bin/bash buildzvmsdkrpm_sles master
    +
    +
    +

    If this build finishes successfully, the resulting rpm package will be generated +in the /root/zvmsdk-build/RPMS/s390x/ directory named in the format +zvmsdk-version-snapdate.s390x.rpm where version is the zvmsdk version +number and date is the build date.

    +

    For building on Debian, make sure you have dpkg-dev available.

    +
    # /usr/bin/bash buildzvmsdkdeb master
    +
    +
    +

    If the build finishes successfully, the resulting deb package will be generated +in the /root/build-zvmsdk/ directory named in the format +zvmsdk-version.s390x.deb where version is the zthin version +number and date is the build date.

    +
  4. +
  5. Install the rpm or deb generated in last step

    +
    # rpm -ivh /root/zvmsdk/RPMS/s390x/zvmsdk-1.4.0-snap201710300123.s390x.rpm
    +
    +
    +

    Be sure to replace the zvmsdk-1.4.0-snap201710300123.s390x.rpm with the correct version name.

    +
    # dpkg -i /root/build-zvmsdk/feilong/zvmsdk-1.4.0.s390x.deb
    +
    +
    +

    Be sure to replace the zvmsdk-1.4.0.s390x.deb with the correct version name.

    +
  6. +
+
+
+

3.3.3. Upgrade z/VM SDK

+

If the z/VM SDK was installed via python setup.py install, you can fetch and +checkout to new version, then upgrade it by issue python setup.py install again.

+
+

Note

+

If you upgrade from a version equal or lower than 1.6.2 to 1.6.3 or newer version, +you have to add two new columns - wwpn_npiv and wwpn_phy into fcp table in +sdk_fcp database with type `varchar(16)`, which is located at +/var/lib/zvmsdk/databases/sdk_fcp.sqlite, for example, by sqlite3 command: +ALTER TABLE fcp ADD COLUMN wwpn_npiv varchar(16) and +ALTER TABLE fcp ADD COLUMN wwpn_phy varchar(16)

+
+
+
+
+

3.4. Configuration Sample

+

After z/VM SDK is installed, a file named ‘zvmsdk.conf.sample’ is generated +under the /etc/zvmsdk/ folder. It contains all the supported configurations +for z/VM SDK. You can refer to it to create your own configuration file which +should be named as zvmsdk.conf.

+

Here’s a sample configuration in which several options marked as ‘required’ +should be customized according to your environment.

+
[database]
+dir=/var/lib/zvmsdk/databases/
+
+[image]
+sdk_image_repository=/var/lib/zvmsdk/images
+
+[logging]
+log_level=INFO
+log_dir=/var/log/zvmsdk/
+
+[network]
+# IP address of the Linux machine which is running SDK on.
+# This config option is required
+my_ip=127.0.0.1
+
+[sdkserver]
+bind_addr=127.0.0.1
+bind_port=2000
+max_worker_count=64
+
+[wsgi]
+auth=none
+
+[zvm]
+# zVM disk pool and type for root/ephemeral disks.
+# This config option is required
+disk_pool=ECKD:eckdpool
+
+# PROFILE name to use when creating a z/VM guest.
+# This config option is required
+user_profile=osdflt
+
+# The default maximum number of virtual processers the user can define.
+user_default_max_cpu=32
+
+# The default maximum size of memory the user can define.
+user_default_max_memory=64G
+
+
+

For the details of all configuration options, please refer to +Configuration Options.

+
+
+

3.5. Setup for z/VM SDK Daemon

+

The Feilong is designed to be run inside a daemon. The daemon server is bond to +the configured socket for receiving requests and then call the requested SDK API.

+

The daemon server would be run with user ‘zvmsdk’ and group ‘zvmsdk’, the following user and folder +setup should be made on BYOL for the z/VM SDK daemon to run.

+
    +
  • Create ‘zvmsdk’ user and group

    +
    # useradd -d /var/lib/zvmsdk/ -m -U -p PASSWORD zvmsdk
    +
    +
    +

    Replace the PASSWORD with your own password for the new created user.

    +
  • +
  • Configure sudo access for ‘zvmsdk’ user (optional)

    +

    If Feilong is installed from source code python setup.py install or from package install +such as deb or rpm, then you can skip this step as it’s already done during install stage.

    +

    The z/VM SDK Daemon relies on some privileged commands for the management of the z/VM host, so you +need to grant the ‘zvmsdk’ user to run following commands with sudo without password:

    +
      +
    • /usr/sbin/vmcp

    • +
    • /opt/zthin/bin/smcli

    • +
    • /usr/sbin/chccwdev

    • +
    • /usr/sbin/cio_ignore

    • +
    • /usr/sbin/fdasd

    • +
    • /usr/sbin/fdisk

    • +
    • /usr/sbin/vmur

    • +
    • /usr/bin/mount

    • +
    • /usr/bin/umount

    • +
    • /usr/sbin/mkfs

    • +
    • /usr/sbin/mkfs.xfs

    • +
    • /usr/sbin/dasdfmt

    • +
    • /opt/zthin/bin/unpackdiskimage

    • +
    • /opt/zthin/bin/creatediskimage

    • +
    • /opt/zthin/bin/linkdiskandbringonline

    • +
    • /opt/zthin/bin/offlinediskanddetach

    • +
    +

    A sample is given in the following block, copy the content to /etc/sudoers.d/zvmsdk:

    +
    # cat /etc/sudoers.d/zvmsdk
    +zvmsdk ALL = (ALL) NOPASSWD:/usr/sbin/vmcp, /opt/zthin/bin/smcli, /usr/sbin/chccwdev, /usr/sbin/cio_ignore, /usr/sbin/fdasd, /usr/sbin/fdisk, /usr/sbin/vmur, /usr/bin/mount, /usr/bin/umount, /usr/sbin/mkfs, /usr/sbin/mkfs.xfs, /usr/sbin/dasdfmt, /opt/zthin/bin/unpackdiskimage, /opt/zthin/bin/creatediskimage, /opt/zthin/bin/linkdiskandbringonline, /opt/zthin/bin/offlinediskanddetach
    +
    +
    +
  • +
  • Setup home directory

    +
    # mkdir -p /var/lib/zvmsdk
    +# chown -R zvmsdk:zvmsdk /var/lib/zvmsdk
    +# chmod -R 755 /var/lib/zvmsdk
    +
    +
    +
  • +
  • Setup log directory

    +

    The folder to which the z/VM SDK log would be written to can be configured with the ‘log_dir’ +option in ‘default’ section. By default, the log folder is ‘/var/log/zvmsdk’. If you have customized +the ‘log_dir’ value, you need to change the folder in following commands accordingly.

    +
    # mkdir -p /var/log/zvmsdk
    +# chown -R zvmsdk:zvmsdk /var/log/zvmsdk
    +# chmod -R 755 /var/log/zvmsdk
    +
    +
    +
  • +
  • Setup configuration directory

    +
    # mkdir -p /etc/zvmsdk
    +# chown -R zvmsdk:zvmsdk /etc/zvmsdk
    +# chmod -R 755 /etc/zvmsdk
    +# ls -l /etc/zvmsdk
    +
    +
    +

    A file named zvmsdk.conf should be found under /etc/zvmsdk folder and contains at least all the required +options before the z/VM SDK daemon can be started.

    +
  • +
+
+
+

3.6. SSH key authentication between consumer and BYOL server

+

For image import/export function, BYOL’s running user(eg zvmsdk) needs to be +authorized by the user of the consumer (eg nova-compute) if they are not in +same host. For example, if you want to import/export image from/to nova +compute server,please make ensure you can ssh nova@nova-compute-ip without +password from zvmsdk user on BYOL server. Refer to the following steps to +configure it:

+

Logon to the nova-compute server and change the nova user’s right to be +able to log in, and make sure port 22 is open.

+
ssh root@nova-compute-ip
+usermod -s /bin/bash nova
+
+
+

where: +nova-compute-ip: is the IP address of the nova compute node.

+

Change to nova user and inject the zvmsdk server’s public key into it.

+
su - nova
+scp zvmsdk@zvmsdk-ip:/var/lib/zvmsdk/.ssh/id_rsa.pub $HOME mkdir -p $HOME/.ssh
+mv $HOME/id_rsa.pub $HOME/.ssh/authorized_keys
+
+
+

where: +zvmsdk: is the user on the BYOL server that runs the z/VM SDK. +zvmsdk-ip: is the IP address of the BYOL server +Note: If the $HOME/.ssh/authorized_keys file already exists, +you just need to append the BYOL’s public key to it.

+

Ensure that the file mode under the $HOME/.ssh folder is 644.

+
chmod -R 644 $HOME/.ssh/*
+
+
+

Issue the following command to determine if SELinux is enabled on the system.

+
getenforce
+
+
+

If SELinux is enabled then set SELinux contexts on the nova home directory.

+
su -
+chcon -R -t ssh_home_t nova_home
+
+
+

where: +nova_home:is the home directory for the nova user on the nova compute server. +You can obtain nova_home by issuing: echo ~nova

+

NOTE: If the host key of nova-compute server changed, please run +the following command on zvmsdk server to clean the cached host key of +nova-compute server from zvmsdk server’s known_hosts file

+
ssh-keygen -R nova-compute-ip
+
+
+
+
+

3.7. Start z/VM SDK Daemon

+

Configure the sdkserver service to start automatically at boot by command: +.. code-block:: text

+
+

# systemctl enable sdkserver

+
+

The z/VM SDK Daemon can be started via the following command:

+
# systemctl start sdkserver
+
+
+

And make sure the sdkserver service status is ‘active (running)’ as following:

+
# systemctl status sdkserver
+● sdkserver.service - zVM SDK API server
+   Loaded: loaded (/usr/lib/systemd/system/sdkserver.service; disabled; vendor preset: disabled)
+   Active: active (running) since Mon 2017-11-20 00:47:18 EST; 3s ago
+ Main PID: 5779 (sdkserver)
+   CGroup: /system.slice/sdkserver.service
+           └─5779 /usr/bin/python /usr/bin/sdkserver
+
+Nov 20 00:47:18 0822rhel7 systemd[1]: Started zVM SDK API server.
+Nov 20 00:47:18 0822rhel7 systemd[1]: Starting zVM SDK API server...
+Nov 20 00:47:18 0822rhel7 sdkserver[5779]: INFO: [MainThread] SDK server now listening
+
+
+
+
+

3.8. Verification

+

You can verify that the process is listenning on the configured port. +For example:

+
# netstat -anp | grep 2000
+tcp        0      0 127.0.0.1:2000          0.0.0.0:*               LISTEN      56434/python
+
+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/resize.html b/doc/html/resize.html new file mode 100644 index 000000000..591677ff7 --- /dev/null +++ b/doc/html/resize.html @@ -0,0 +1,237 @@ + + + + + + + + 10. Resize Image to a Bigger Size — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

10. Resize Image to a Bigger Size

+

This section provides info on how resize an image to a bigger size disk +during deploy process was performed.

+

The following sample describes:

+
    +
  1. Create a 3390 disk with 2300 cylinders.

  2. +
  3. Capture the disk and make it a deployable image.

  4. +
  5. Deploy the image (this sample use openstack) to larger number cylinders, this sample using 10G disk size, which is 14564 cylinders.

  6. +
  7. After deploy, the new spawned guest has 10G disk size.

  8. +
  9. Note only the size of last partition has been enlarged.

  10. +
+
+

Note

+

Following test result only tested on SLES12SP4 for now.

+
+
+

10.1. Flow of resize

+

Create a 3390 disk with 2300 cylinders has 2 partitions.

+
+
q v dasd
+00: DASD 0100 3390 JM6013 R/W       2300 CYL ON DASD  6013 SUBCHANNEL = 0001
+
+# lsdasd
+Bus-ID     Status      Name      Device  Type  BlkSz  Size      Blocks
+==============================================================================
+0.0.0100   active      dasda     94:0    ECKD  4096   1617MB    414000
+
+# fdasd --table /dev/dasda
+WARNING: Your DASD '/dev/dasda' is in use.
+If you proceed, you can heavily damage your system.
+If possible exit all applications using this disk
+and/or unmount it.
+
+reading volume label ..: VOL1
+reading vtoc ..........: ok
+
+Disk /dev/dasda:
+  cylinders ............: 2300
+  tracks per cylinder ..: 15
+  blocks per track .....: 12
+  bytes per block ......: 4096
+  volume label .........: VOL1
+  volume serial ........: 0X0100
+  max partitions .......: 3
+
+------------------------------- tracks -------------------------------
+             Device      start      end   length   Id  System
+        /dev/dasda1          2     4267     4266    1  Linux native
+        /dev/dasda2       4268    34499    30232    2  Linux native
+exiting...
+
+# parted /dev/dasda print
+Model: IBM S390 DASD drive (dasd)
+Disk /dev/dasda: 1696MB
+Sector size (logical/physical): 512B/4096B
+Partition Table: dasd
+Disk Flags:
+
+Number  Start   End     Size    File system  Flags
+ 1      98.3kB  210MB   210MB   ext2
+ 2      210MB   1696MB  1486MB  ext4
+
+
+
+

The disk size of the guest where the sles12 sp4 image was deployed using openstack.:

+
+
# openstack flavor list
+| ID                                   | Name       |   RAM | Disk | Ephemeral | VCPUs | Is Public |
+| d80df349-e277-4c08-a578-10dd8ff5ba02 | zvm-small  |  2048 |   10 |         0 |     2 | True      |
+
+# openstack server show s124-2part-ext4
+| flavor                              | zvm-small (d80df349-e277-4c08-a578-10dd8ff5ba02)          |
+
+s124-2part-ext4:~ # vmcp q v dasd
+DASD 0100 3390 JM601B R/W      14564 CYL ON DASD  601B SUBCHANNEL = 0003
+
+s124-2part-ext4:~ # lsdasd
+Bus-ID     Status      Name      Device  Type  BlkSz  Size      Blocks
+==============================================================================
+0.0.0100   active      dasda     94:0    ECKD  4096   10240MB   2621520
+
+s124-2part-ext4:~ # fdasd --table /dev/dasda
+
+WARNING: Your DASD '/dev/dasda' is in use.
+         If you proceed, you can heavily damage your system.
+         If possible exit all applications using this disk
+         and/or unmount it.
+
+reading volume label ..: VOL1
+reading vtoc ..........: ok
+
+Disk /dev/dasda:
+  cylinders ............: 14564
+  tracks per cylinder ..: 15
+  blocks per track .....: 12
+  bytes per block ......: 4096
+  volume label .........: VOL1
+  volume serial ........: 0X0100
+  max partitions .......: 3
+
+------------------------------- tracks -------------------------------
+  Device      start      end   length   Id  System
+  /dev/dasda1          2     4267     4266    1  Linux native
+  /dev/dasda2       4268   218459   214192    2  Linux native
+  exiting...
+
+s124-2part-ext4:~ # parted /dev/dasda print
+Model: IBM S390 DASD drive (dasd)
+Disk /dev/dasda: 10.7GB
+Sector size (logical/physical): 512B/4096B
+Partition Table: dasd
+Disk Flags:
+
+Number  Start   End     Size    File system  Flags
+ 1      98.3kB  210MB   210MB   ext2
+ 2      210MB   10.7GB  10.5GB  ext4
+
+
+
+

The last partition on dasda was the partition that was expanded to fill the remainder of the ECKD disk .

+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/restapi.html b/doc/html/restapi.html new file mode 100644 index 000000000..e1eebe08f --- /dev/null +++ b/doc/html/restapi.html @@ -0,0 +1,5335 @@ + + + + + + + + 7. RESTful APIs — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

7. RESTful APIs

+

This is a reference for the Feilong RESTful API.

+
+

7.1. Response Data Definition

+

The following table gives a reference of general response data definition +of each Feilong RESTful API. In case of encountering an error, +those information will be helpful to report bug/issue.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

overallRC

body

integer

The overall return code for API request.

rc

body

integer

The return code for API request.

rs

body

integer

The reason code for API request.

errmsg

body

string

The error message returned for API request. It can be empty +if no error occur.

modID

body

integer

The module ID that causes the error to occur.

output

body

dict

The return data from API request.

+

The following detail API description will only cover output part as +it’s different for each API. +(This document is a beta version now)

+
+
+

7.2. Version

+

Lists version of this API.

+
+

7.2.1. Get Feilong version

+

GET /

+
    +
  • Request:

    +

    No parameters needed.

    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    Return the version of the zvm cloud connect API.

    +
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

The return data from API request.

api_version

header

string

API version of Feilong.

min_version

header

string

Min version of Feilong.

max_version

header

string

Max version of Feilong.

version

header

string

Version of Feilong.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output":
+    {
+        "api_version": "1.0.",
+        "min_version": "1.0",
+        "max_version": "1.0",
+        "version": "1.0.0"
+    }
+}
+
+
+
+
+
+

7.3. Token

+
+

7.3.1. Create token

+

POST /token

+

Get a valid token to perform further request by using Admin-Token which +you can think as a combination of username and password.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

X-Admin-Token

header

string

Admin-token, which is stored in /etc/zvmsdk/token.dat. +You need put this into header to request for a auth-token. +Then you can send a request with this auth-token.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

X-Auth-Token

header

string

The token returned to client if authorized.

+ +
+
+
+

7.4. SMAPI Health

+
+

7.4.1. Report health of SMAPI

+

GET /smapi_health

+

Get health status of the SMAPI.

+
    +
  • Request:

    +

    None

    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

SMAPI health report

totalSuccess

body

integer

The total success calls for SMAPI.

totalFail

body

integer

The total fail calls for SMAPI.

lastSuccess

body

string

The last success call for SMAPI.

lastFail

body

string

The last fail call for SMAPI.

continuousFail

body

integer

The count of continuous fail.

healthy

body

boolean

Whether SMAPI is healthy.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {
+        "totalSuccess": 0,
+        "totalFail": 0,
+        "lastSuccess": "",
+        "lastFail": "",
+        "continuousFail": 0,
+        "healthy": True
+    }
+}
+
+
+
    +
  • Note:

    +

    Old API call GET /smapi-healthy is deprecated.

    +
  • +
+
+
+
+

7.5. Guest(s)

+

Lists, creates, shows details for, updates, and deletes guests.

+
+

7.5.1. List Guests

+

GET /guests

+

List names of all the guests created by Feilong.

+
    +
  • Request:

    +

    None

    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

Guests list

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": ["v1", "v2"]
+}
+
+
+
+
+

7.5.2. Create Guest

+

POST /guests

+

Create a vm in z/VM

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

guest

body

dict

Guest dict

userid

body

string

The userid of the guest to be created

vcpus

body

integer

vcpus count.

memory

body

integer

Memory size of the guest, in MBytes.

user_profile (Optional)

body

string

Profile of guest, null is also allowed.

disk_list (Optional)

body

list

A list of disks info for the guest +It has one dictionary that contain some of the below keys for +each disk, the root disk should be the first element in the +list.

size

body

string

size of disk, case insensitive, the unit can be in Megabytes (M), +Gigabytes (G), or number of cylinders/blocks, for example, please +use 512M, 1g or just 2000.

format (Optional)

body

string

Format of disk, can be ext2, ext3, ext4, swap, xfs, none. +The file system none means there is no need to create a file system, +and in turn no format and partition table will be created, this usually +used for some system such as z/OS.

is_boot_disk (Optional)

body

bool

is boot disk or not. For the root disk, this key must be set to +indicate the image that will be deployed on this disk.

vdev (Optional)

body

string

when adding mdisk (either add after create or during create guest) +use this param to specify the virtual device number. +e.g. add this param to dist list as vdev: 0123 will result user +direct has something like MDISK 0123

disk_pool (Optional)

body

string

disk pool, if not specified, the disk will be created by using +the value from configure file, the format is +ECKD:eckdpoolname or FBA:fbapoolname.

max_cpu (Optional)

body

integer

The maximum number of virtual cpus this user can define. +The value should be a decimal value between 1 and 64.

max_mem (Optional)

body

string

The maximum size of memory the user can define. +The value should be specified by 1-4 digits suffixed by +either M (Megabytes) or G (Gigabytes). And the number should be +a whole number, eg. 512M, 4G.

ipl_from (Optional)

body

string

where the guest IPL from, by default it’s ipl from +CONF.zvm.user_root_vdev, and if this value is not empty, +the IPL will from given param, for example IPL CMS will IPL +from CMS instead of device number.

ipl_param (Optional)

body

string

The param to add to IPL command, e.g. IPL xxx PARM <guest_ipl_param>

ipl_loadparam (Optional)

body

string

The loadparam to add to IPL command, e.g. IPL xxx LOADPARM <guest_ipl_loadparam>

dedicate_vdevs (Optional)

body

list

A list of device vdevs to dedicate to the guest。

loaddev (Optional)

body

dict

The loaddev parms to add in the guest directory.Current supported key includes ‘portname’, +‘lun’ and ‘alterdev’. Both the ‘portname’ and ‘lun’ can specify only one one- to +eight-byte hexadecimal value in the range of 0-FFFFFFFFFFFFFFFF. There is ‘alterdev’ added +only when the compute node z/VM supports multipath IPL feature.

account (Optional)

body

string

account of guest, useful for guest billing.

comment_list (Optional)

body

list

comment of the user direct.

+
    +
  • Request sample:

  • +
+
{
+  "guest":
+  {
+      "userid": "id001",
+      "vcpus": 1,
+      "memory": 1024,
+      "user_profile": "",
+      "disk_list":[
+      {
+          "size": "1g",
+          "is_boot_disk": True,
+          "disk_pool": "ECKD:eckdpool1"
+      },
+      {
+          "size": "200000",
+          "disk_pool": "FBA:fbapool1",
+          "format": "ext3"
+      }],
+      "max_cpu": 10,
+      "max_mem": "32G"
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

A list of created disks info for the guest +It has one dictionary that contain some of the below keys for +each disk.

vdev

body

string

Device number of the disk, 1- to 4- hexadecimal digits.

size

body

string

size of disk, case insensitive, the unit can be in Megabytes (M), +Gigabytes (G), for example, please 512M, 1g.

format (Optional)

body

string

Format of disk, can be ext2, ext3, ext4, swap, xfs, none. +The file system none means there is no need to create a file system, +and in turn no format and partition table will be created, this usually +used for some system such as z/OS.

is_boot_disk (Optional)

body

bool

is boot disk or not. For the root disk, this key must be set to +indicate the image that will be deployed on this disk.

disk_pool

body

string

disk pool, the format is ECKD:eckdpoolname or FBA:fbapoolname.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": [{"vdev": "0100",
+                "size": "1g",
+                "is_boot_disk": True,
+                "disk_pool": "ECKD:eckdpool1"},
+               {"vdev": "0101",
+                "size": "100M",
+                "disk_pool": "FBA:fbapool1",
+                "format": "ext3"}]
+}
+
+
+
+
+

7.5.3. Get guest minidisks info

+

GET /guests/{userid}/disks

+

List characteristics of all disks of a guest

+
    +
  • Request:

    +

    None

    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

minidisks (Optional)

body

list

A list of disks info for the guest. +Each entry in this list describes a minidisk and is a dictionary +that contains some of the below keys.

vdev

body

string

the virtual device number of the disk.

rdev

body

string

the real device number of the disk.

access_type

body

string

type of access to the disk, either R/O or R/W.

device_size

body

integer

the size of the disk, without unit.

device_units

body

string

the unit for the size of the disk, for example Cylinders.

volume_label

body

string

the volume label of the disk.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {
+        "minidisks": [{'vdev': '0100',
+                       'rdev': '6018',
+                       'access_type': 'R/W',
+                       'device_type': '3390',
+                       'device_size': 29128,
+                       'device_units': 'Cylinders',
+                       'volume_label': 'VM6018'}]
+
+    }
+}
+
+
+
+
+

7.5.4. Guest add disks

+

POST /guests/{userid}/disks

+

Add disks for a guest

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

disk_info

body

dict

A dict to describe disk info.

disk_list (Optional)

body

list

A list of disks info for the guest +It has one dictionary that contain some of the below keys for +each disk, the root disk should be the first element in the +list.

size

body

string

size of disk, case insensitive, the unit can be in Megabytes (M), +Gigabytes (G), or number of cylinders/blocks, for example, please +use 512M, 1g or just 2000.

format (Optional)

body

string

Format of disk, can be ext2, ext3, ext4, swap, xfs, none. +The file system none means there is no need to create a file system, +and in turn no format and partition table will be created, this usually +used for some system such as z/OS.

is_boot_disk (Optional)

body

bool

is boot disk or not. For the root disk, this key must be set to +indicate the image that will be deployed on this disk.

vdev (Optional)

body

string

when adding mdisk (either add after create or during create guest) +use this param to specify the virtual device number. +e.g. add this param to dist list as vdev: 0123 will result user +direct has something like MDISK 0123

disk_pool (Optional)

body

string

disk pool, if not specified, the disk will be created by using +the value from configure file, the format is +ECKD:eckdpoolname or FBA:fbapoolname.

+
    +
  • Request sample:

  • +
+
{
+  "disk_info":
+  {
+      "disk_list":[
+      {
+          "size": "1g",
+          "is_boot_disk": True,
+          "disk_pool": "ECKD:eckdpool1"
+      },
+      {
+          "size": "200000",
+          "disk_pool": "FBA:fbapool1",
+          "format": "ext3"
+      }]
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

A list of created disks info for the guest +It has one dictionary that contain some of the below keys for +each disk.

vdev

body

string

Device number of the disk, 1- to 4- hexadecimal digits.

size

body

string

size of disk, case insensitive, the unit can be in Megabytes (M), +Gigabytes (G), for example, please 512M, 1g.

format (Optional)

body

string

Format of disk, can be ext2, ext3, ext4, swap, xfs, none. +The file system none means there is no need to create a file system, +and in turn no format and partition table will be created, this usually +used for some system such as z/OS.

is_boot_disk (Optional)

body

bool

is boot disk or not. For the root disk, this key must be set to +indicate the image that will be deployed on this disk.

disk_pool

body

string

disk pool, the format is ECKD:eckdpoolname or FBA:fbapoolname.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": [{"vdev": "0100",
+                "size": "1g",
+                "is_boot_disk": True,
+                "disk_pool": "ECKD:eckdpool1"},
+               {"vdev": "0101",
+                "size": "100M",
+                "disk_pool": "FBA:fbapool1",
+                "format": "ext3"}]
+}
+
+
+
+
+

7.5.5. Guest configure disks

+

PUT /guests/{userid}/disks

+

Configure additional disks for a guest

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

disk_info

body

dict

A dict to describe disk info.

disk_list

body

list

A list of additional disks info for the guest +It has one dictionary that contain some of the below keys for +each disk

vdev (Optional)

body

string

The device number of the disk, if not specified, zvmsdk will use the next vdev +of CONF.zvm.user_root_vdev as the additional disk’s vdev, eg. if CONF.zvm.user_root_vdev +is 0100, zvmsdk will use 0101 as the vdev for first additional disk in disk_info, 0102 as +the second additional disk’s vdev

format

body

string

Format of disk, can be ext2, ext3, ext4, swap, xfs. +The file system none means there is no need to create a file system, +and in turn no format and partition table will be created, this usually +used for some system such as z/OS.

mntdir (Optional)

body

string

The directory on guest to which the additional disk will be mounted, if not specified, +zvmsdk will use /mnt/ephemeral0 as the mount point of first additional disk, /mnt/ephemeral1 +as the mount point of second additional disk

+
    +
  • Request sample:

  • +
+
{
+  "disk_info":
+  {
+      "disk_list":[
+      {
+          "vdev": "0101",
+          "format": "ext3",
+          "mntdir": "/mnt/0101"
+      },
+      {
+          "vdev": "0102",
+          "format": "ext4",
+          "mntdir": "/mnt/0102"
+      }]
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No Response

    +
  • +
+
+
+

7.5.6. Guest delete disks

+

DELETE /guests/{userid}/disks

+

Delete disks form a guest that in shutdown state

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

vdev_info

body

dict

A dict to describe vdev list to be deleted.

vdev_list

body

list

Disk vdev list of guest +It has one list contains the vdev for delete, +for example, ['0101','0102']

+
    +
  • Request sample:

  • +
+
{
+  "vdev_info":
+  {
+      "vdev_list":['0101', '0102']
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No Response

    +
  • +
+
+

Note

+

Not support delete disks when guest is active

+
+
+
+

7.5.7. Attach Volume

+

POST /guests/volumes

+

Attach volume to a vm in z/VM

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

info

body

dict

A dict to describe connection info of the volume

connection

body

dict

A dict to describe info of the volume to be operated

assigner_id

body

string

The userid of the guest that the volume will be attached to or detached from.

zvm_fcp

body

list

FCP devices list.

target_wwpn

body

string

World Wide Port Number, must start with 0x, for example 0x50050763050b073d

target_lun

body

string

Logical Unit Number, must start with 0x, for example 0x4020400100000000

os_version

body

string

Operating system version, the valid alues are: rhel6.x, rhel7.x, rhel8.x, +rhel9.x, sles11.x, sles12.x, sles15.x, ubuntu16.x, ubuntu20.x, ubuntu22.x, rhcos4.x, +all case insensitive. Please contact your cloud administrator if you don’t know +the guest’s OS version.

multipath

body

bool

Multipath service is open or not

mount_point (Optional)

body

string

The symbol link name of the volume device. If not assigned, will be assigned by the os in vm.

is_root_volume (Optional)

body

bool

Volume is bootable or not

+
    +
  • Request sample:

  • +
+
{
+  "info":
+  {
+      "connection":
+      {
+        "assigner_id": "username",
+        "zvm_fcp": "1fc5",
+        "target_wwpn": "0x50050763050b073d",
+        "target_lun": "0x4020400100000000",
+        "os_version": "redhat7",
+        "multipath": True,
+        "mount_point": "/dev/sdz",
+        "is_root_volume": False
+      }
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No Response

    +
  • +
+
+
+

7.5.8. Detach Volume

+

DELETE /guests/volumes

+

Detach volume from a vm in z/VM

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

info

body

dict

A dict to describe connection info of the volume

connection

body

dict

A dict to describe info of the volume to be operated

assigner_id

body

string

The userid of the guest that the volume will be attached to or detached from.

zvm_fcp

body

list

FCP devices list.

target_wwpn

body

string

World Wide Port Number, must start with 0x, for example 0x50050763050b073d

target_lun

body

string

Logical Unit Number, must start with 0x, for example 0x4020400100000000

os_version

body

string

Operating system version, the valid alues are: rhel6.x, rhel7.x, rhel8.x, +rhel9.x, sles11.x, sles12.x, sles15.x, ubuntu16.x, ubuntu20.x, ubuntu22.x, rhcos4.x, +all case insensitive. Please contact your cloud administrator if you don’t know +the guest’s OS version.

multipath

body

bool

Multipath service is open or not

mount_point (Optional)

body

string

The symbol link name of the volume device. If not assigned, will be assigned by the os in vm.

is_root_volume (Optional)

body

bool

Volume is bootable or not

+
    +
  • Request sample:

  • +
+
{
+  "info":
+  {
+      "connection":
+      {
+        "assigner_id": "username",
+        "zvm_fcp": "1fc5",
+        "target_wwpn": "0x50050763050b073d",
+        "target_lun": "0x4020400100000000",
+        "os_version": "redhat7",
+        "multipath": True,
+        "mount_point": "/dev/sdz",
+        "is_root_volume": False
+      }
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No Response

    +
  • +
+
+
+

7.5.9. Get Guests stats including cpu and memory

+

GET /guests/stats

+

Get guests cpu, memory information.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

A string that contains single userid or userids delimited by comma, like id1, id2, id3

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

CPU and memory statistics of guests, as a dictionary where the +key is the userid and the value is the CPU and memory statistics.

guest_cpus

body

integer

The count of virtual CPUs for the guest.

used_cpu_time_us

body

integer

The CPU time used in microseconds.

elapsed_cpu_time_us

body

integer

The CPU time elapsed in microseconds.

min_cpu_count

body

integer

The minimal count of virtual CPUs allowed.

max_cpu_limit

body

integer

The maximal count of virtual CPUs allowed.

samples_cpu_in_use

body

integer

Samples CPU in use.

samples_cpu_delay

body

integer

Samples CPU delay.

used_mem_kb

body

integer

Memory size used by the guest, in KBytes.

max_mem_kb

body

integer

The maximum memory in KBytes that can be allocated for this guest.

min_mem_kb

body

integer

The maximum memory in KBytes that can be allocated for this guest.

shared_mem_kb

body

integer

Shared memory in KBytes.

total_memory

body

integer

Total memory.

available_memory

body

integer

Available memory.

free_memory

body

integer

Free memory.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {
+        "MYGUEST": {
+            "guest_cpus": 2,
+            "used_cpu_time_us": 509530870,
+            "elapsed_cpu_time_us": 260788896874,
+            "min_cpu_count": 2,
+            "max_cpu_limit": 10000,
+            "samples_cpu_in_use": 335,
+            "samples_cpu_delay": 116,
+            "used_mem_kb": 396232,
+            "max_mem_kb": 2097152,
+            "min_mem_kb": 0,
+            "shared_mem_kb": 396232,
+            "total_memory": 2030428,
+            "available_memory": 892136,
+            "free_memory": 791368
+        }
+    }
+}
+
+
+
+
+

7.5.10. Get Guests interface stats

+

GET /guests/interfacestats

+

Get guests network interface statistics.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

A string that contains single userid or userids delimited by comma, like id1, id2, id3

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

vNIC statistics of guests, as a dictionary where the key is +the userid and the value is a list of vNIC statistics.

vswitch_name (Optional)

path

string

vswitch name.

nic_vdev

body

string

the device number of the nic.

nic_fr_rx

body

integer

Number of received frames.

nic_fr_tx

body

integer

Number of transmitted frames.

nic_fr_rx_dsc

body

integer

Number of received frames that have been discarded.

nic_fr_tx_dsc

body

integer

Number of transmitted frames that have been discarded.

nic_fr_rx_err

body

integer

Number of received frames that were in error.

nic_fr_tx_err

body

integer

Number of transmitted frames that were in error.

nic_rx

body

integer

Number of received bytes.

nic_tx

body

integer

Number of transmitted bytes.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {
+        "MYGUEST": [
+            {
+                "vswitch_name": "MYSWITCH",
+                "nic_vdev": "1000",
+                "nic_fr_rx": 116686,
+                "nic_fr_tx": 14892,
+                "nic_fr_rx_dsc": 0,
+                "nic_fr_tx_dsc": 0,
+                "nic_fr_rx_err": 0,
+                "nic_fr_tx_err": 0,
+                "nic_rx": 6131168,
+                "nic_tx": 1367740
+            }
+        ]
+    }
+}
+
+
+
+
+

7.5.11. Get Guests nic info

+

GET /guests/nics

+

Get guests nic information, including userid, nic number, vswitch, nic id and comments.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid (Optional)

path

string

Guest userid.

nic_id (Optional)

path

string

nic identifier.

vswitch (Optional)

path

string

vswitch name.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

List describing nic information, each nic has one dict +to indicate its info, including userid, interface, +switch, port id and comments.

userid

body

string

the userid of the nic.

interface

body

string

the device number of the nic.

switch

body

string

vswitch name.

port

body

string

nic identifier.

comments

body

string

the comments for the nic.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "output": [{"userid": "id0001",
+                "interface": "1000",
+                "switch": "vsw01",
+                "port": "1111-2222",
+                "comments": null}],
+    "errmsg": ""
+}
+
+
+
+
+

7.5.12. Show Guest definition

+

GET /guests/{userid}

+

Display the user direct by the given userid.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

Dictionary with only one entry describing user directory.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {"user_direct": ["USER1", "INCLUDE PROFILE"]}
+}
+
+
+
+
+

7.5.13. Delete Guest

+

DELETE /guests/{userid}

+

Delete a guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No Response

    +
  • +
+
+
+

7.5.14. Get Guest power state from hypervisor

+

GET /guests/{userid}/power_state_real

+

Get power state of the guest from hypervisor directly,

+

no matter the guest is in zcc database or not.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

string

Power status of guest, can be either on or off.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overllRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": "off"
+}
+
+
+
+
+

7.5.15. Get Guest info

+

GET /guests/{userid}/info

+

Get running information of guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

Status of guest.

max_mem_kb

body

integer

The maximum memory in KBytes that can be allocated for this guest.

num_cpu

body

integer

The count of virtual CPUs for the guest.

cpu_time_us

body

integer

The CPU time used in microseconds.

power_state

body

string

Power status of guest, can be either on or off.

mem_kb

body

integer

Memory size used by the guest, in KBytes.

online_cpu_num

body

integer

The count of online virtual CPUs for the guest.

os_distro

body

string

The os distro information for the guest.

kernel_info

body

string

The kernel information for the guest.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output":
+    {
+        "max_mem_kb": 1,
+        "num_cpu": 1,
+        "cpu_time_us": 0,
+        "power_state": "off",
+        "mem_kb": 0
+    }
+}
+
+
+
+
+

7.5.16. Get Guest user direct

+

GET /guests/{userid}/user_direct

+

Get the user directory info of the given userid from hypervisor.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

Dictionary with only one entry describing user directory.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {"user_direct": ["USER1", "INCLUDE PROFILE"]}
+}
+
+
+
+
+

7.5.17. Get Guest adapters info

+

GET /guests/{userid}/adapters

+

Get adapters information of running guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

A list of adapters info for the guest +It has one or more dictionary that contain some of the below keys, one dictionary represent for one adapter. +each adapter.

lan_owner

path

string

Guest userid

lan_name

path

string

vswitch name.

adapter_address (Optional)

body

string

nic device number, 1- to 4- hexadecimal digits.

adapter_status

body

string

status of adapter, 2 hexadecimal digits. 02 means normal.

mac_address (Optional)

body

string

Mac address, it is only used when changing the guest’s user direct. +Format should be xx:xx:xx:xx:xx:xx, and x is a hexadecimal digit.

mac_ip_address (Optional)

body

string

ip address.

mac_ip_version

body

string

version of IP address, 4 means IPV4, 6 means IPV6.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output":
+    {
+        u'adapters': [{u'lan_owner': u'SYSTEM',
+                       u'adapter_address': u'1000',
+                       u'lan_name': u'VSC11590',
+                       u'adapter_status': u'02',
+                       u'mac_address': u'02:55:36:5D:48:57',
+                       u'mac_ip_version': u'4',
+                       u'mac_ip_address': u'9.152.85.152'}]
+    }
+}
+
+
+
+
+

7.5.18. Create Guest nic

+

POST /guests/{userid}/nic

+

Create a virtual nic on giving guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

nic

body

dict

The information which is used to set nic device number

vdev (Optional)

body

string

nic device number, 1- to 4- hexadecimal digits. null is also allowed.

nic_id (Optional)

body

string

nic identifier

mac_addr (Optional)

body

string

Mac address, it is only used when changing the guest’s user direct. +Format should be xx:xx:xx:xx:xx:xx, and x is a hexadecimal digit.

active (Optional)

body

bool

Whether the change will apply to the active guest.

+
    +
  • Request sample:

  • +
+
{
+  "nic":
+  {
+      "vdev": "1000",
+      "nic_id": "1111-2222-3333",
+      "mac_addr": "12:34:56:AA:BB:CC",
+      "active": True
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.19. Create network interface

+

POST /guests/{userid}/interface

+

Create one or more network interfaces on giving guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

interface

body

dict

The information which is used to describe network interface.

os_version

body

string

Operating system version, the valid alues are: rhel6.x, rhel7.x, rhel8.x, +rhel9.x, sles11.x, sles12.x, sles15.x, ubuntu16.x, ubuntu20.x, ubuntu22.x, rhcos4.x, +all case insensitive. Please contact your cloud administrator if you don’t know +the guest’s OS version.

guest_networks

body

list

Network info list of guest. It has one dictionary that contain some of the below +keys for each interface. All the keys are optional :

+
    +
  • ip_addr: the IP address of the interface, cidr is required if ip address +is set

  • +
  • dns_addr: dns addresses list

  • +
  • gateway_addr: gateway address

  • +
  • cidr: cidr format

  • +
  • nic_vdev: nic device number, 1- to 4- hexadecimal digits

  • +
  • mac_addr: mac address

  • +
  • nic_id: nic identifier

  • +
  • osa_device: OSA device number, 1- to 4- hexadecimal digits

  • +
  • hostname: host name

  • +
+

active (Optional)

body

bool

Whether the change will apply to the active guest.

+
    +
  • Request sample:

  • +
+
{
+  "interface":
+  {
+      "os_version": "rhel7.2",
+      "guest_networks": [
+      {   
+          "ip_addr": "192.168.95.10",
+          "dns_addr": ["9.0.2.1", "9.0.3.1"],
+          "gateway_addr": "192.168.95.1",
+          "cidr": "192.168.95.0/24",
+          "nic_vdev": "1000",
+          "mac_addr": "02:00:00:12:34:56",
+          "nic_id": "111-222-333",
+          "osa_device": "8080"
+      },
+      {
+          "ip_addr": "192.168.95.11",
+          "gateway_addr": "192.168.95.1",
+          "cidr": "192.168.95.0/24",
+          "nic_vdev": "2000",
+          "mac_addr": "02:00:00:12:34:78",
+          "nic_id": "444-555-666"
+      }],
+      "active": True
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.20. Delete network interface

+

DELETE /guests/{userid}/interface

+

Delete one network interface on giving guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

interface

body

dict

The information which is used to describe network interface.

os_version

body

string

Operating system version, the valid alues are: rhel6.x, rhel7.x, rhel8.x, +rhel9.x, sles11.x, sles12.x, sles15.x, ubuntu16.x, ubuntu20.x, ubuntu22.x, rhcos4.x, +all case insensitive. Please contact your cloud administrator if you don’t know +the guest’s OS version.

vdev

body

string

the device number of the nic.

active (Optional)

body

bool

Whether the change will apply to the active guest.

+
    +
  • Request sample:

  • +
+
{
+  "interface":
+  {
+      "os_version": "rhel7.2",
+      "vdev": "1000",
+      "active": True
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.21. Start guest

+

Start a guest.

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take start action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "start"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.22. Stop guest

+

Stop a guest.

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take stop action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "stop"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.23. Softstop guest

+

Stop a guest gracefully, it will firstly shutdown the os on vm, then stop the vm.

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take softstop action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "softstop"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.24. Pause guest

+

Pause a guest.

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take pause action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "pause"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.25. Unpause guest

+

Unpause a guest.

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take unpause action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "unpause"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.26. Reboot guest

+

Reboot a guest, this will use ‘reboot’ command on the +given guest.

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take reboot action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "reboot"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.27. Reset guest

+

Reset a guest, this will first gracefully logoff the guest from +z/VM it is running on, then log on the guest and IPL.

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take reset action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "reset"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.28. Get guest console output

+

POST /guests/{userid}/action

+

Get console output of guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take get_console_output action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "get_console_output"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +
      +
    • output: console_output

    • +
    +
  • +
+
+

Note

+

In order to retrieve the console log from guest vm, you must add user direct +statment “COMMAND SP CONS * START” to the profile that used to deploy guest +vm, otherwise no console log collected for the guest vm.

+
+
+
+

7.5.29. Live migration of guest

+

POST /guests/{userid}/action

+

Live migrate guest in z/VM SSI cluster.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take live_migrate_vm action on guest.

dest_zcc_userid (Optional)

body

string

The userid of zcc on destination node. +Required if lgr_action equals move.

destination

body

string

The system ID of the z/VM system to which +the specified vm will be relocated or tested.

parms (Optional)

body

dict

A dictionary of options for relocation.

lgr_action

body

string

Indicates the action is test or move for the live migration. +test will test the guest is eligible to live migrate or not. +move will live migrate the guest immediately.

+
    +
  • Request sample:

  • +
+
{
+   "action": "live_migrate_vm",
+   "dest_zcc_userid": "destuid",
+   "destination": "destnode",
+   "parms": {
+       "maxtotal": 360,
+       "maxquiesce": 60,
+       "immediate": "YES",
+   },
+   "operation": "move",
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.30. Guest register

+

POST /guests/{userid}/action

+

Register guest to be managed by Feilong.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take register_vm action on guest.

meta

body

string

The metadata of the vm to be registered.

net_set

body

string

Guest network configured or not. +1 means configured, 0 means not configured. Default as 1.

port (Optional)

body

dict

The dict of virtual interface port id and mac id

+
    +
  • Request sample:

  • +
+
{
+   "action": "register_vm",
+   "meta": '{"os_version": "sles12sp3"}',
+   "net_set": "1",
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.31. Guest deregister

+

POST /guests/{userid}/action

+

Deregister guest to be managed by Feilong.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take deregister_vm action on guest.

+
    +
  • Request sample:

  • +
+
{
+   "action": "deregister_vm",
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.32. Live resize CPUs of guest

+

POST /guests/{userid}/action

+

Live resize CPUs of guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take live_resize_cpus action on guest.

cpu_cnt

body

integer

The number of virtual cpus that the guest should +have after resize. The value should be an +positive integer between 1 and 64.

+
    +
  • Request sample:

  • +
+
{
+   "action": "live_resize_cpus",
+   "cpu_cnt": 4
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+

Note

+
    +
  • Currently only increasing CPU count is supported, decreasing is not supported.

  • +
  • The guest to be live resized must be active and managed by Feilong.

  • +
  • If live resize finished successfully, both the active CPU number and the number of +defined CPUs in user directory would be updated to the requested so that the CPU +count would persist even after the guest is restarted.

  • +
  • If requested CPU count is smaller than the current active CPU count, then the API +would return error immediately since lively decrease CPU count is not supported.

  • +
  • If requested CPU count is larger than the defined CPU number in user directory, +this API would increase the CPU number in user directory to requested count. +Otherwise, this API would decrease the CPU number in user directory to the requested +count.

  • +
  • To live resize a guest, the guest must have maximum CPU count defined in user +directory entry with “MACHINE ESA xx” where ‘xx’ is the maximum CPU count. The +resize CPU count can’t exceed the maximum CPU count.

  • +
  • For guests created by Feilong after version 1.2.0, the maximum CPU +count is defined when the guest is created. The maximum CPU count is set by the configuration +“user_default_max_cpu” in [zvm] section and can be overriden by the parameter “max_cpu” when +creating the guest. e.g, the following configuration would define the default maximum CPU count +as 64.

    +
    [zvm]
    +user_default_max_cpu=64
    +
    +
    +
  • +
+
+
+
+

7.5.33. Resize CPUs of guest

+

POST /guests/{userid}/action

+

Resize CPUs of guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take resize_cpus action on guest.

cpu_cnt

body

integer

The number of virtual cpus that the guest should +have after resize. The value should be an +positive integer between 1 and 64.

+
    +
  • Request sample:

  • +
+
{
+   "action": "resize_cpus",
+   "cpu_cnt": 4
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+

Note

+
    +
  • Both increasing and decreasing CPU count are supported.

  • +
  • The target guest can be in either ‘on’ or ‘off’ status, the definition change would +take into effects after logoff and re-logon (reset).

  • +
+
+
+
+

7.5.34. Live resize memory of guest

+

POST /guests/{userid}/action

+

Live resize memory of guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take live_resize_mem action on guest.

size

body

string

The size of memory that the guest should have after resize. +The value should be specified by 1-4 digits suffixed by +either M (Megabytes) or G (Gigabytes). And the number should be +an integer, eg. 512M, 4G.

+
    +
  • Request sample:

  • +
+
{
+   "action": "live_resize_mem",
+   "size": "4096m"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+

Note

+
    +
  • Currently only increasing memory size is supported, decreasing is not supported.

  • +
  • The guest to be live resized must be active and managed by Feilong.

  • +
  • If live resize finished successfully, both the active memory and the initial memory +defined in user directory would be updated to the requested size so that the change +would persist even after the guest is restarted.

  • +
  • If requested memory size is smaller than the current active memory, then the API +would return error immediately since lively decrease memory size is not supported.

  • +
  • If requested memory size is larger than the defined initial memory in user directory, +this API would increase the initial memory defined in user directory to requested size. +Otherwise, this API would decrease the memory in user directory to the requested +size.

  • +
  • The resize memory size can’t exceed the maximum memory defined in user directory.

  • +
  • The maximum memory size is defined when the guest is created. It is set by the configuration +“user_default_max_memory” in [zvm] section and can be overriden by the parameter “max_mem” when +creating the guest. e.g, the following configuration would define the default maximum memory size +as 64G.

    +
    [zvm]
    +user_default_max_memory=64g
    +
    +
    +
  • +
+
+
+
+

7.5.35. Resize memory of guest

+

POST /guests/{userid}/action

+

Resize memory of guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take resize_mem action on guest.

size

body

string

The size of memory that the guest should have after resize. +The value should be specified by 1-4 digits suffixed by +either M (Megabytes) or G (Gigabytes). And the number should be +an integer, eg. 512M, 4G.

+
    +
  • Request sample:

  • +
+
{
+   "action": "resize_mem",
+   "size": "8g"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+

Note

+
    +
  • Both increasing and decreasing memory size are supported.

  • +
  • The target guest can be in either ‘on’ or ‘off’ status, the definition change would +take into effects after logoff and re-logon (reset).

  • +
+
+
+
+

7.5.36. Deploy guest

+

POST /guests/{userid}/action

+

After guest created, deploy image onto the guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take deploy action on guest.

image

body

string

Image name that can be uniquely identify an image.

transportfiles (Optional)

body

string

The files path that used to customize the vm. For RHCOS image, the transportfiles +should be the ignition file and it’s required.

remotehost (Optional)

body

string

The server that the transportfiles located, if remotehost is not +specified, will deploy with the transport file in local server, +otherwise, the format is username@ip, for example, nova@9.x.x.x +or username@hostname eg.``test@test.ibm.com``

vdev (Optional)

body

string

Device number to which the image will be deployed, 1- to 4- hexadecimal +digits. null is also allowed.

hostname (Optional)

body

string

hostname of the guest. Will be ignored if transportfiles +specified. null is also allowed.

skipdiskcopy (Optional)

body

boolean

whether to skip the copy of image to disk. Default value if False. +If the value is True, the image_name specified should be the os version. +If the value is False, the image_name specified should be the name of the image +to be used to copy to the root disk.

+
    +
  • Request sample:

  • +
+
{
+  "action": "deploy",
+  "image": "image1",
+  "transportfiles": "/data/openstack/nova/instances/opnstk1/fp1t001d/cfgdrive.tgz",
+  "remotehost": "nova@192.168.99.1",
+  "vdev": "0100"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.37. Capture guest

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take capture action on guest.

image

body

string

Image name that can be uniquely identify an image.

capture_type (Optional)

body

string

The type of capture:

+
    +
  • rootonly: indicate just root device will be captured, this is the default one

  • +
  • alldisks: indicate all the devices of the userid will be captured

  • +
+

compress_level (Optional)

body

integer

The compression level of the image, default value is 6

+
    +
  • Request sample:

  • +
+
{
+  "action": "capture",
+  "image": "capturedimage",
+  "capture_type": "rootonly",
+  "compress_level": 6
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.38. Grow root volume of guest

+

POST /guests/{userid}/action

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

action

body

string

Take grow_root_volume action on guest.

os_version

body

string

Operating system version, the valid alues are: rhel6.x, rhel7.x, rhel8.x, +rhel9.x, sles11.x, sles12.x, sles15.x, ubuntu16.x, ubuntu20.x, ubuntu22.x, rhcos4.x, +all case insensitive. Please contact your cloud administrator if you don’t know +the guest’s OS version.

+
    +
  • Request sample:

  • +
+
{
+  "action": "grow_root_volume",
+  "os_version": "RHEL7.8"
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
+
+

7.5.39. Get Guest power state

+

GET /guests/{userid}/power_state

+

Get power state of the guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

+
    +
  • Response code:

    +

    HTTP status code 200 on success. +HTTP status code 404 if guest is not in zcc database +or it is in zcc database but its user directory does not exist.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

string

Power status of guest, can be either on or off.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": "off"
+}
+
+
+
+
+

7.5.40. Update Guest nic

+

PUT /guests/{userid}/nic/{vdev}

+

Couple or uncouple nic with vswitch on the guest.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

vdev

path

string

nic device number, 1- to 4- hexadecimal digits.

info

body

dict

The info used to describe the couple/uncouple action.

couple

body

bool

couple or uncouple action.

active (Optional)

body

bool

Whether the change will apply to the active guest.

vswitch (Optional)

body

string

vswitch name.

vlan_id

body

integer

The VLAN ID. This can be any of the value between -1 or 1-4094.

+
    +
  • Request sample:

  • +
+
{
+  "info":
+  {
+      "couple": True,
+      "active": False,
+      "vswitch": "vs_name"
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+

7.5.41. Delete Guest nic

+

DELETE /guests/{userid}/nic/{vdev}

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

vdev

path

string

nic device number, 1- to 4- hexadecimal digits.

active (Optional)

body

bool

Whether the change will apply to the active guest.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+
+

7.6. Host

+

Get guests list, info from host (hypervisor) running on.

+
+

7.6.1. Get Guests List

+

GET /host/guests

+

List names of all the guests on the host.

+
    +
  • Request:

    +

    None

    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

Guests list

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": ["v1", "v2"]
+}
+
+
+

Get info from host (hypervisor) running on.

+
+
+

7.6.2. Get Host Info

+

GET /host

+

Get host information.

+
    +
  • Request:

    +

    No parameters needed.

    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

The dict of host information.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": 
+    {
+         "disk_available": 3057,
+         "ipl_time": "IPL at 06/02/17 11:07:10 EDT",
+         "vcpus_used": 6,
+         "hypervisor_type": "zvm",
+         "vcpus": 6,
+         "zvm_host": "OPNSTK2",
+         "memory_mb": 51200.0,
+         "cpu_info": {
+              "cec_model": "2817",
+              "architecture": "s390x"
+         },
+         "disk_total": 3623,
+         "zcc_userid": "ZCCUID",
+         "hypervisor_hostname": "OPNSTK2",
+         "hypervisor_version": 640,
+         "disk_used": 566,
+         "memory_mb_used": 0.0
+    }
+}
+
+
+
+
+

7.6.3. Get Host disk pool info

+

GET /host/diskpool

+

Get disk pool information(or the free space among all volumes in the disk pool) on the host.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

poolname (Optional)

path

string

The pool name to get pool information from

details (Optional)

path

boolean

get the free space of all volumes on the disk pool or not.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

disk_available

body

int

The total available size of the disks in the pool in Gigabytes(G).

disk_total

body

int

The total size of the pool in Gigabytes (G).

disk_used

body

int

The size of used disks in the pool in Gigabytes(G).

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "output":
+    {
+         "disk_available": 3060,
+         "disk_total": 3623,
+         "disk_used": 563
+    },
+    "errmsg": ""
+}
+
+
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "output":
+    {
+        {
+            'ICICPL':
+             [
+                 {
+                     'volume_name': 'vol1',
+                     'device_type': 'type1',
+                     'start_cylinder': 13456,
+                     'free_size': 2345,
+                     'dasd_group': 'ICICPL',
+                     'region_name': 'vol1'
+                 },
+                 {
+                      'volume_name': 'vol2',
+                      'device_type': 'type1',
+                      'start_cylinder': '22456',
+                      'free_size': 12980,
+                      'dasd_group': 'ICICPL',
+                      'region_name': 'vol2'
+                  }
+              ]
+        }
+    },
+    "errmsg": ""
+}
+
+
+
+
+

7.6.4. Get host disk pool volume names

+

GET /host/diskpool_volumes

+

Get volume list of the diskpool on the host.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

poolname (Optional)

path

string

The pool name to get pool information from

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

diskpool_volumes

body

string

The volume list of the diskpool

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "output":
+    {
+         "diskpool_volumes": "IAS100 IAS101",
+    },
+    "errmsg": ""
+}
+
+
+
+
+

7.6.5. Get host volume info

+

GET /host/volume

+

Get the volume info on the host.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

volumename

path

string

The name of the volume

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

volume_type

body

string

The type of the volume

volume_size

body

int

The disk size of the volume

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "output":
+    {
+         "volume_type": "3390-54",
+         "volume_size": "60102"
+    },
+    "errmsg": ""
+}
+
+
+
+
+

7.6.6. Get Host SSI Cluster Info

+

GET /host/ssi

+

Get the SSI(Single System Image) cluster information of the host.

+
    +
  • Request:

    +

    No parameters needed.

    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

If the host is an SSI cluster member, it returns a list of SSI cluster +information. If current host is not an SSI cluster member, it returns an empty list.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output":
+    [
+         "ssi_name = ZVM2SSI",
+         "ssi_mode = Stable",
+         "ssi_pdr = IAS7CM_on_139E",
+         "cross_system_timeouts = Enabled",
+         "output.ssiInfoCount = 2",
+         "",
+         "member_slot = 1",
+         "member_system_id = OPNSTK2",
+         "member_state = Joined",
+         "member_pdr_heartbeat = 01/12/2022_04:17:54",
+         "member_received_heartbeat = 01/12/2022_04:17:54",
+         "",
+         "member_slot = 2",
+         "member_system_id = OPNSTK3",
+         "member_state = Joined",
+         "member_pdr_heartbeat = 01/12/2022_04:17:35",
+         "member_received_heartbeat = 01/12/2022_04:17:35",
+         ""
+    ]
+}
+
+
+
+
+
+

7.7. Image(s)

+

Lists, creates, shows details for, updates, and deletes images.

+
+

7.7.1. List images

+

GET /images

+

Get the list of image info in image repository.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

imagename (Optional)

path

string

Retrieve the specified image information, if not specified, +when list image, all images information will be returned.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

The image info for specific image or all images, each image has one dict +to indicate its info

imagename

body

string

Image name that can be uniquely identify an image.

imageosdistro

body

string

Operating system version, the valid alues are: rhel6.x, rhel7.x, rhel8.x, +rhel9.x, sles11.x, sles12.x, sles15.x, ubuntu16.x, ubuntu20.x, ubuntu22.x, rhcos4.x, +all case insensitive. Please contact your cloud administrator if you don’t know +the guest’s OS version.

md5sum

body

string

md5sum for the specific image.

disk_size_units

body

string

The image’s root disk size in units CYL or BLK, eg 3338:CYL or 614200:BLK.

image_size_in_bytes

body

string

Physical image size in bytes eg 5120000

type

body

string

How the image is generated, if it captured from root disk the type is netboot.

comments

body

string

the comments for the image

last_access_time

body

float

the time stamp of last access time of this image +the seconds count after 1970 and is generated from python time module.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "output": [{"imagename": "image1",
+                "imageosdistro": "rhel7.2",
+                "md5sum": "52014cd658cea6ed4005fb25885e30e2",
+                "disk_size_units": "0:CYL",
+                "image_size_in_bytes": "55",
+                "type": "netboot",
+                "comments": null}],
+    "errmsg": ""
+}
+
+
+
+
+

7.7.2. Create image

+

POST /images

+

Import an image into image repository

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

image

body

dict

The image info dict.

image_name

body

string

Image name that can be uniquely identify an image.

url

body

string

The location of the image to be imported, support import image from 3 +types location, local file system: eg. file:///opt/images/import.img. +http server: eg. http://192.168.2.1/path/to/import.img +file system on remote host: in this case both url and remote_host parameter +should be specified

image_meta

body

dict

The metadata which describes the image, the valid keys are os_version, md5sum and disk_type. +os_version is a required key, the valid values are: rhel6.x, rhel7.x, rhel8.x, +rhel9.x, sles11.x, sles12.x, sles15.x, ubuntu16.x, ubuntu20.x, ubuntu22.x, rhcos4.x, +all case insensitive. Please contact your cloud administrator +if you don’t know the image’s OS version. disk_type is required if os_version is rhcos4, +the valid disk_type values are: DASD, SCSI.

remote_host (Optional)

body

string

The server from where the image will be import, if remote_host is None, +the image will be import from the url in local server, otherwise, +the format is username@ip, for example, nova@9.x.x.x or +username@hostname, for example, test@test.ibm.com

+
    +
  • Request sample:

  • +
+
{
+  "image": 
+  {
+     "image_name": "image1",
+     "url": "file:///image1",
+     "image_meta": {"os_version": "rhel6.2"},
+     "remote_host": "nova@9.x.x.x"
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+

7.7.3. Export image

+

PUT /images/{name}

+

Export the image to the specified location.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

name

path

string

Image name that can be uniquely identify an image.

location

body

dict

The dictionary to indicate the location info of image to be exported

dest_url

body

string

The location of the exported image, support export to 2 types location, +local file system: eg. file:///opt/images/export.img +file system on remote host: in this case both dest_url and remote_host +parameter should be specified

remote_host (Optional)

body

string

The server that the image will be export to, if remote_host is None, +the image will be stored in the dest_path in local server, otherwise, +the format is username@ip, for example, nova@9.x.x.x or +username@hostname eg.``test@test.ibm.com``.

+
    +
  • Request sample:

  • +
+
{
+  "location": 
+  {
+     "dest_url": "file:///export/to/image1",
+     "remote_host": "test@test.ibm.com"
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

The dict contains image info after export.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {"image_name": "name1",
+               "image_path": "/tmp/images/name1",
+               "os_version": "rhel6",
+               "md5sum": "121212314231"}
+}
+
+
+
+
+

7.7.4. Get root disk size of image

+

GET /images/{name}/root_disk_size

+

Get the root disk size of the image.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

name

path

string

Image name that can be uniquely identify an image.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

string

The image’s root disk size in units CYL or BLK, eg 3338:CYL or 614200:BLK.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "output": "3338:CYL",
+    "errmsg": ""
+}
+
+
+
+
+

7.7.5. Delete image

+

DELETE /images/{name}

+

Delete an image.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

name

path

string

Image name that can be uniquely identify an image.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+
+

7.8. VSwitch

+

Lists, creates, updates, and deletes vswitch.

+
+

7.8.1. Create vswitch

+

POST /vswitches

+

Create a new vswitch.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

name

body

string

vswitch name.

rdev (Optional)

body

string

The real device number, a maximum of three devices. null is also allowed.

controller (Optional)

body

string

The vswitch’s controller. It could be userid or “*” to +specifies any available controller.

connection (Optional)

body

string

Connection type option :

+
    +
  • CONnect: Activate the real device connection.

  • +
  • DISCONnect: Do not active the real device connection.

  • +
  • NOUPLINK: the vswitch will never have connectivity through.

  • +
+

network_type (Optional)

body

string

Specifies the transport mechanism to be used for switch, +as follow:IP, ETHERNET, default is ETHERNET.

router (Optional)

body

string

Connection type option :

+
    +
  • NONROUTER: The OSA-Express device identified in +real_device_address= will not act as a router to the vswitch.

  • +
  • PRIROUTER: The OSA-Express device identified in +real_device_address= will act as a primary router to the vswitch.

  • +
  • Note: If the network_type is ETHERNET, this value must be +unspecified, otherwise, if this value is unspecified, +default is NONROUTER

  • +
+

vid (Optional)

body

string, integer

The VLAN ID. This can be any of the following values: +UNAWARE, AWARE or 1-4094.

port_type (Optional)

body

string

Port type :

+
    +
  • ACCESS: The default porttype attribute for +guests authorized for the virtual switch. +The guest is unaware of VLAN IDs and sends and +receives only untagged traffic

  • +
  • TRUNK: The default porttype attribute for +guests authorized for the virtual switch. +The guest is VLAN aware and sends and receives tagged +traffic for those VLANs to which the guest is authorized. +If the guest is also authorized to the natvid, untagged +traffic sent or received by the guest is associated with +the native VLAN ID (natvid) of the virtual switch.

  • +
+

gvrp (Optional)

body

string

gvrp :

+
    +
  • GVRP: Indicates that the VLAN IDs in use on the virtual +switch should be registered with GVRP-aware switches on the +LAN. This provides dynamic VLAN registration and VLAN +registration removal for networking switches. This +eliminates the need to manually configure the individual +port VLAN assignments.

  • +
  • NOGVRP: Do not register VLAN IDs with GVRP-aware switches on +the LAN. When NOGVRP is specified VLAN port assignments +must be configured manually

  • +
+

queue_mem (Optional)

body

integer

A number between 1 and 8, specifying the QDIO +buffer size in megabytes

native_vid (Optional)

body

integer

The native vlan id, 1-4094 or null.

persist (Optional)

body

boolean

Whether create the vswitch in the permanent +configuration for the system.

+
    +
  • Request sample:

  • +
+
{
+  "vswitch":
+  {
+      "name": "vs_name",
+      "rdev": "FF00",
+      "controller": "*",
+      "connection": "CONnect",
+      "network_type": "ETHERNET",
+      "router": "NONROUTER",
+      "vid": "UNAWARE",
+      "port_type": "ACCESS",
+      "gvrp": "GVRP",
+      "queue_mem": 8,
+      "native_vid": 1,
+      "persist": True
+  }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+

7.8.2. List vswitches

+

GET /vswitches

+

Get the list of vswitch name on the host

+
    +
  • Request:

    +

    No parameter needed.

    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

List of vswitches.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": ["v1", "v2"]
+}
+
+
+
+
+

7.8.3. GET vswitch details

+

GET /vswitches/{name}

+

Get the details of a vswitch

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

name

path

string

vswitch name.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

The vswitch info for specific vswitch

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "output": {
+              "switch_name": "TESTVSW",
+              "lag_group": "(NOGRP)",
+              "port_type": "NONE",
+              "vlan_id": "0000",
+              "queue_memory_limit": "8",
+              "gvrp_request_attribute": "NOGVRP",
+              "MAC_protect": "UNSPECIFIED",
+              "mac_address": "02-00-0C-00-00-09",
+              "gvrp_enabled_attribute": "NOGVRP",
+              "lag_interval": "0",
+              "IP_timeout": "5",
+              "vlan_awareness": "UNAWARE",
+              "isolation_status": "NOISOLATION",
+              "native_vlan_id": "0000",
+              "user_port_based": "USERBASED",
+              "transport_type": "ETHERNET",
+              "link_ag": "LAG",
+              "switch_type": "QDIO",
+              "switch_status": "OSA device ready.",
+              "routing_value": "NA",
+              "VLAN_counters": "E)",
+              "real_devices": {"8070":
+                                     {"dev_status": "Device is active.",
+                                      "controller": "DTCVSW1",
+                                      "port_name": "NONE",
+                                      "dev_err": "No error.",
+                                      "vdev": "0600"}},
+              "authorized_users":
+                     {"UB160120":
+                             {"vlan_ids": [], "prom_mode": "NOPROM",
+                              "port_num": "0000", "osd_sim": "NOOSDSIM",
+                              "vlan_count": 0},
+                      "OPNCLOUD":
+                             {"vlan_ids": [], "prom_mode": "NOPROM",
+                              "port_num": "0000", "osd_sim": "NOOSDSIM",
+                              "vlan_count": 0}},
+              "adapters":
+                     {
+                      "UB160120_1009": {"mac": "02-00-0C-00-01-2D", "type": "QDIO"},
+                      "OPNCLOUD_0700": {"mac": "02-00-0C-00-00-0C", "type": "QDIO"}}
+              },
+    "errmsg": ""
+}
+
+
+
+
+

7.8.4. Grant user to vswitch

+

PUT /vswitches/{name}

+

Grant an user to access vswitch

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

name

path

string

vswitch name.

vswitch

body

dict

The vswitch update info.

grant_userid

body

string

Guest userid.

+
    +
  • Request sample:

  • +
+
{
+   "vswitch":
+   {
+      "grant_userid": "FVTUSER1"
+   }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+

7.8.5. Revoke user from vswitch

+

PUT /vswitches/{name}

+

Revoke the user access from vswitch

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

name

path

string

vswitch name.

vswitch

body

dict

The vswitch update info.

revoke_userid

body

string

Guest userid.

+
    +
  • Request sample:

  • +
+
{
+   "vswitch":
+   {
+      "revoke_userid": "FVTUSER1"
+   }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+

7.8.6. Set user VLANID to vswitch

+

PUT /vswitches/{name}

+

Set vlan id for user when connecting to the vswitch

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

name

path

string

vswitch name.

vswitch

body

dict

The vswitch update info.

user_vlan_id

body

dict

A dict to describe guest userid and vlanid.

userid

body

string

Guest userid.

vlanid

body

integer

The VLAN ID. This can be any of the value between -1 or 1-4094.

+
    +
  • Request sample:

  • +
+
{
+   "vswitch":
+   {
+      "user_vlan_id": {
+          "userid": "FVTUSER1"
+          "vlanid": 100
+      }
+   }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+

7.8.7. Delete vswitch

+

DELETE /vswitches/{name}

+

Delete a vswitch by using given name.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

name

path

string

vswitch name.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+
+

7.9. Volume(s)

+

Handling of volumes and FCP devices.

+
+

7.9.1. Refresh Volume Bootmap Info

+

PUT /volumes/volume_refresh_bootmap

+

Refresh a volume’s bootmap info.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

fcpchannel

body

list

FCP devices list.

wwpn

body

string

World Wide Port Name IDs.

lun

body

string

Logical Unit Number ID

transportfiles (Optional)

body

string

The files path that used to customize the vm. For RHCOS image, the transportfiles +should be the ignition file and it’s required.

guest_networks (Optional)

body

list

Required only if refresh volume bootmap for RHCOS. +Network info list of guest. It has one dictionary that contain some of the below +keys for each interface. All the keys are optional :

+
    +
  • ip_addr: the IP address of the interface, cidr is required if ip address +is set

  • +
  • dns_addr: dns addresses list

  • +
  • gateway_addr: gateway address

  • +
  • cidr: cidr format

  • +
  • nic_vdev: nic device number, 1- to 4- hexadecimal digits

  • +
  • mac_addr: mac address

  • +
  • nic_id: nic identifier

  • +
  • osa_device: OSA device number, 1- to 4- hexadecimal digits

  • +
  • hostname: the hostname of the guest

  • +
+
+
    +
  • Request sample:

  • +
+
{'info':
+        {
+            "fcpchannel": ['5d71'],
+            "wwpn": ['5005076802100c1a', '5005076802200c1b'],
+            "lun": '0000000000000000',
+            "transportfiles": "/path/to/transportfiles",
+            "guest_networks": [
+                {   
+                    "ip_addr": "192.168.95.10",
+                    "dns_addr": ["9.0.2.1", "9.0.3.1"],
+                    "gateway_addr": "192.168.95.1",
+                    "cidr": "192.168.95.0/24",
+                    "nic_vdev": "1000",
+                    "mac_addr": "02:00:00:12:34:56",
+                    "nic_id": "111-222-333",
+                    "osa_device": "8080",
+                    "hostname": "hostname"
+                },
+                {
+                    "ip_addr": "192.168.95.11",
+                    "gateway_addr": "192.168.95.1",
+                    "cidr": "192.168.95.0/24",
+                    "nic_vdev": "2000",
+                    "mac_addr": "02:00:00:12:34:78",
+                    "nic_id": "444-555-666"
+                }
+            ],
+        }
+}
+
+
+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+
{
+    'errmsg': '',
+    'modID': None,
+    'output': ['5d71'], ['5005076802400c1a', '5005076802400c1b'],
+    'overallRC': 0,
+    'rc': 0,
+    'rs': 0
+}
+
+
+
+
+

7.9.2. Get Volume Connector

+

GET /volumes/conn/{userid}

+

Get volume connector for z/VM.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

userid

path

string

Guest userid

reserve

body

boolean

If or not reserve the FCP devices.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {
+        "zvm_fcp": [],
+        "wwpns": []
+        "host": ''
+    }
+}
+
+
+
+
+

7.9.3. Get FCP Usage

+

GET /volumes/fcp/{fcp_id}

+

Get the FCP usage in database for z/VM.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

fcp_id

path

string

ID of FCP device.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

list

FCP usage, contains 3 values [userid, reserved, connections]. +userid is the userid this fcp belongs to. +reserved is 0 or 1, represent the fcp is been used or not. +connections is non-negative value, means the count of volumes on this FCP.

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": ['testid', 1, 3]
+}
+
+
+
+
+

7.9.4. Set FCP Usage

+

PUT /volumes/fcp/{fcp_id}

+

Set the FCP usage in database for z/VM.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

fcp_id

path

string

ID of FCP device.

userid

body

string

Guest userid.

reserved

body

boolean

If or not reserve the FCP devices.

connections

body

integer

The count of volumes on this FCP device.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

    +

    No response.

    +
  • +
+
+
+
+

7.10. Files

+

Imports and exports raw file data.

+

These operations may be restricted to Feilong administrators.

+
+

7.10.1. Import file

+

PUT /files

+

Import binary file data to Feilong. Internal use Only.Please set +the Content-Type of the request header to application/octet-stream. The body +contains the binary data.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

Content-type

header

string

The media type descriptor for the request body. Use ‘application/octet-stream’

+
    +
  • Example call:

    +
    +
    curl http://192.168.99.3:8888/files -i -X PUT -H “X-Auth-Token: $token” -H

    “Content-Type: application/octet-stream” –data-binary @/root/testfile

    +
    +
    +
  • +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response contents:

  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

In

Type

Description

output

body

dict

Dictionary describing the file import status and result

dest_url

body

string

The location of file after imported on Feilong. For example, +‘file:///var/lib/zvmsdk/files/imported/be919b98-8408-11e8-b9fe-020001000053

filesize_in_bytes

body

int

The physical file size in bytes

md5sum

body

string

The md5sum of the file after imported

+
    +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {"filesize_in_bytes": 7614,
+               "md5sum": "8aa3752079b9dc2269cdc44a7185e287",
+               "dest_url": "file:///var/lib/zvmsdk/files/imported/be919b98-8408-11e8-b9fe-020001000053"}
+}
+
+
+
+
+

7.10.2. Export file

+

POST /files

+

Export file from Feilong, internal use only.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

source_file

body

string

The path of the file to be exported, eg. ‘/root/testfile’

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
+

The response body contains the raw binary data that represents the actual file. +The Content-Type header contains the application/octet-stream value.

+
+
+

7.10.3. Get Switch information based on port id

+

GET /switch

+

Get Switch information based on port id.

+
    +
  • Request:

  • +
+ + + + + + + + + + + + + + + +

Name

In

Type

Description

portid

body

string

The ID of the port.

+
    +
  • Response code:

    +

    HTTP status code 200 on success.

    +
  • +
  • Response sample:

  • +
+
{
+    "rs": 0,
+    "overallRC": 0,
+    "modID": null,
+    "rc": 0,
+    "errmsg": "",
+    "output": {['TEST0045', '4000', 'VSTEST', 'da19c4b3-905b-4844-898e-e36813be796e', None]}
+}
+
+
+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/sample.html b/doc/html/sample.html new file mode 100644 index 000000000..140c37aef --- /dev/null +++ b/doc/html/sample.html @@ -0,0 +1,228 @@ + + + + + + + + 6. Basic Usage — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

6. Basic Usage

+

This section introduces the basics of using Feilong to manage z/VM host, and gives some usage examples.

+
+

6.1. Workflow description

+
+

6.1.1. Spawning a virtual machine

+_images/spawn_flow.jpg +
    +
  1. Image import from external image repository into Feilong; for one image, this only needs to be done once

  2. +
  3. Store the information into DB record

  4. +
  5. Call from upper layer to create a guest

  6. +
  7. SMAPI calls DIRMAINT to define a user direct

  8. +
  9. Call from upper layer to deploy a guest

  10. +
  11. Feilong then starts to copy disk contents from image to the disks allocated in step 3

  12. +
  13. Post deploy actions such as network setup, and send customized files from Feilong to the newly deployed VM

  14. +
  15. Start the VM

  16. +
  17. During first power on of the VM, set up the network and utilize the customized files to update network, hostname etc (by default, using cloud-init)

  18. +
+
+
+

6.1.2. Creating a vswitch

+_images/create_vswitch_flow.jpg +
    +
  1. Call from upper layer to trigger the Vswitch create call

  2. +
  3. HTTP service (Feilong REST API) gets the request and handles it to Feilong server

  4. +
  5. SMAPI is then called and handles the VSWITCH create command, this will include persistent definition of Vswitch and define it in z/VM CP

  6. +
  7. CP is called to create vswitch on the fly

  8. +
+
+
+
+

6.2. Usage Examples

+

The following examples show how to spawn a new VM, both in bash and in python.

+

Note: other language bindings exist, for example for golang.

+

In these examples, the Feilong connector runs at the IP address 1.2.3.4.

+
+

6.2.1. From the command line

+
    +
  • Create a parameters file named “create-guest-id001.json”:

    +
    {
    +  "guest":
    +  {
    +    "userid": "myguest",
    +    "vcpus": 2,
    +    "memory": 2048,
    +    "user_profile": "osdflt",
    +    "disk_list": [
    +       {
    +         "size": "5g",
    +         "is_boot_disk": true,
    +         "disk_pool": "ECKD:vmpool"
    +      } ],
    +      "max_cpu": 4,
    +      "max_mem": "4G"
    +  }
    +}
    +
    +
    +
  • +
  • Call “curl” command, referring to this parameters file:

    +
    $ curl -s -X POST \
    +          -H "Content-Type: application/json" \
    +          -d @create-guest-id001.json \
    +          http://1.2.3.4/guests | jq
    +
    +
    +
  • +
+
+
+

6.2.2. From python language

+
+
from zvmconnector import connector
+
+userid = 'myguest'
+vcpus = 2
+memory = 2048
+user_profile = 'osdflt'
+disk_list = [
+  {
+    'size': "5g",
+    'is_boot_disk': True,
+    'disk_pool': 'ECKD:vmpool'
+  } ]
+max_cpu = 4
+max_mem = '4G'
+
+client = connector.ZVMConnector(
+  connection_type = 'rest', ip_addr = '1.2.3.4', port = '80')
+
+guest_create_info = client.send_request(
+  'guest_create', userid, vcpus, memory,
+  disk_list = disk_list, user_profile = user_profile, max_cpu = max_cpu, max_mem = max_mem)
+
+if guest_create_info['overallRC']:
+    raise RuntimeError('Failed to create guest: ' + guest_create_info['errmsg'])
+
+print('Guest created')
+
+
+
+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/search.html b/doc/html/search.html new file mode 100644 index 000000000..73f73fcd3 --- /dev/null +++ b/doc/html/search.html @@ -0,0 +1,95 @@ + + + + + + + Search — Feilong 1.6.7 documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + +
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/html/searchindex.js b/doc/html/searchindex.js new file mode 100644 index 000000000..21649bd88 --- /dev/null +++ b/doc/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"Apache2 + mod_wsgi": [[12, "apache2-mod-wsgi"]], "Apache2 + uwsgi": [[12, "apache2-uwsgi"]], "Attach Volume": [[10, "attach-volume"]], "Basic Usage": [[11, null]], "Bug reporting and questions": [[5, "bug-reporting-and-questions"]], "Capture guest": [[10, "capture-guest"]], "Capture the zLinux to Generate the Image": [[7, "capture-the-zlinux-to-generate-the-image"]], "Change default NIC address": [[4, "change-default-nic-address"]], "Compatibility": [[5, "compatibility"]], "Configuration": [[12, "configuration"]], "Configuration Options": [[2, null]], "Configuration Sample": [[8, "configuration-sample"]], "Configuration of cloud-init in zLinux": [[7, "configuration-of-cloud-init-in-zlinux"]], "Configuration of zvmguestconfigure in zLinux": [[7, "configuration-of-zvmguestconfigure-in-zlinux"]], "Configuration of zvmguestconfigure on RHEL 7.x and SLES 12.x": [[7, "configuration-of-zvmguestconfigure-on-rhel-7-x-and-sles-12-x"]], "Configuration of zvmguestconfigure on RHEL6.x and SLES11.x": [[7, "configuration-of-zvmguestconfigure-on-rhel6-x-and-sles11-x"]], "Configuration of zvmguestconfigure on Ubuntu 16.04 and Ubuntu 20.04": [[7, "configuration-of-zvmguestconfigure-on-ubuntu-16-04-and-ubuntu-20-04"]], "Configure Apache": [[12, "configure-apache"]], "Configure uwsgi": [[12, "configure-uwsgi"]], "Content of this package": [[5, "content-of-this-package"]], "Create Guest": [[10, "create-guest"]], "Create Guest nic": [[10, "create-guest-nic"]], "Create image": [[10, "create-image"]], "Create network interface": [[10, "create-network-interface"]], "Create token": [[10, "create-token"]], "Create vswitch": [[10, "create-vswitch"]], "Creating a vswitch": [[11, "creating-a-vswitch"]], "DEB for Ubuntu": [[8, "deb-for-ubuntu"]], "Delete Guest": [[10, "delete-guest"]], "Delete Guest nic": [[10, "delete-guest-nic"]], "Delete image": [[10, "delete-image"]], "Delete network interface": [[10, "delete-network-interface"]], "Delete vswitch": [[10, "delete-vswitch"]], "Deploy guest": [[10, "deploy-guest"]], "Deprecations": [[5, "deprecations"]], "Detach Volume": [[10, "detach-volume"]], "Error Codes and Messages": [[3, null]], "Export file": [[10, "export-file"]], "Export image": [[10, "export-image"]], "FAQ": [[4, "faq"]], "Files": [[10, "files"]], "Flow of resize": [[9, "flow-of-resize"]], "From python language": [[11, "from-python-language"]], "From the command line": [[11, "from-the-command-line"]], "GET vswitch details": [[10, "get-vswitch-details"]], "General info": [[4, null], [5, null]], "Get FCP Usage": [[10, "get-fcp-usage"]], "Get Feilong version": [[10, "get-feilong-version"]], "Get Guest adapters info": [[10, "get-guest-adapters-info"]], "Get Guest info": [[10, "get-guest-info"]], "Get Guest power state": [[10, "get-guest-power-state"]], "Get Guest power state from hypervisor": [[10, "get-guest-power-state-from-hypervisor"]], "Get Guest user direct": [[10, "get-guest-user-direct"]], "Get Guests List": [[10, "get-guests-list"]], "Get Guests interface stats": [[10, "get-guests-interface-stats"]], "Get Guests nic info": [[10, "get-guests-nic-info"]], "Get Guests stats including cpu and memory": [[10, "get-guests-stats-including-cpu-and-memory"]], "Get Host Info": [[10, "get-host-info"]], "Get Host SSI Cluster Info": [[10, "get-host-ssi-cluster-info"]], "Get Host disk pool info": [[10, "get-host-disk-pool-info"]], "Get Switch information based on port id": [[10, "get-switch-information-based-on-port-id"]], "Get Volume Connector": [[10, "get-volume-connector"]], "Get guest console output": [[10, "get-guest-console-output"]], "Get guest minidisks info": [[10, "get-guest-minidisks-info"]], "Get host disk pool volume names": [[10, "get-host-disk-pool-volume-names"]], "Get host volume info": [[10, "get-host-volume-info"]], "Get root disk size of image": [[10, "get-root-disk-size-of-image"]], "Grant user to vswitch": [[10, "grant-user-to-vswitch"]], "Grow root volume of guest": [[10, "grow-root-volume-of-guest"]], "Guest add disks": [[10, "guest-add-disks"]], "Guest configure disks": [[10, "guest-configure-disks"]], "Guest delete disks": [[10, "guest-delete-disks"]], "Guest deregister": [[10, "guest-deregister"]], "Guest register": [[10, "guest-register"]], "Guest(s)": [[10, "guest-s"]], "Host": [[10, "host"]], "Image Requirements": [[7, "image-requirements"]], "Image and cloud-init Configuration": [[7, null]], "Image(s)": [[10, "image-s"]], "Import file": [[10, "import-file"]], "Import the Images to Feilong": [[7, "import-the-images-to-feilong"]], "Install Linux on z Systems(zLinux) in a Virtual Machine": [[7, "install-linux-on-z-systems-zlinux-in-a-virtual-machine"]], "Installation": [[12, "installation"], [12, "id3"]], "Installation Requirements": [[8, "installation-requirements"]], "Installation and Configuration of IUCV service in zLinux": [[7, "installation-and-configuration-of-iucv-service-in-zlinux"]], "Installation and Configuration of cloud-init": [[7, "installation-and-configuration-of-cloud-init"]], "Installation and Configuration of cloud-init on RHEL 6.x": [[7, "installation-and-configuration-of-cloud-init-on-rhel-6-x"]], "Installation and Configuration of cloud-init on RHEL 7.x and SLES 12.x": [[7, "installation-and-configuration-of-cloud-init-on-rhel-7-x-and-sles-12-x"]], "Installation and Configuration of cloud-init on RHEL8.1 and SLES15": [[7, "installation-and-configuration-of-cloud-init-on-rhel8-1-and-sles15"]], "Installation and Configuration of cloud-init on SLES11.x": [[7, "installation-and-configuration-of-cloud-init-on-sles11-x"]], "Installation and Configuration of cloud-init on Ubuntu 16.04 and Ubuntu 20.04": [[7, "installation-and-configuration-of-cloud-init-on-ubuntu-16-04-and-ubuntu-20-04"]], "Installation using OBS Packages": [[8, "installation-using-obs-packages"]], "Installing from packages": [[12, "installing-from-packages"]], "Integration Examples": [[0, "integration-examples"]], "Internal Architecture": [[0, "internal-architecture"]], "Introduction": [[0, null], [12, "introduction"]], "License": [[5, "license"]], "List Guests": [[10, "list-guests"]], "List images": [[10, "list-images"]], "List vswitches": [[10, "list-vswitches"]], "Live migration of guest": [[10, "live-migration-of-guest"]], "Live resize CPUs of guest": [[10, "live-resize-cpus-of-guest"]], "Live resize memory of guest": [[10, "live-resize-memory-of-guest"]], "Log on through 3270 or PCOM terminal": [[4, "log-on-through-3270-or-pcom-terminal"]], "Make a Deployable Image for Feilong": [[7, "make-a-deployable-image-for-feilong"]], "Manual Installation": [[8, "manual-installation"]], "Pause guest": [[10, "pause-guest"]], "Pre-requirements": [[8, "pre-requirements"]], "Preparation on BYOL": [[8, "preparation-on-byol"]], "Quick Start": [[8, null]], "RESTful APIs": [[10, null]], "RPM for RHEL/Alma/Rocky": [[8, "rpm-for-rhel-alma-rocky"]], "RPM for SLES": [[8, "rpm-for-sles"]], "Reboot guest": [[10, "reboot-guest"]], "Redhat Enterprise Linux": [[12, "redhat-enterprise-linux"]], "Refresh Volume Bootmap Info": [[10, "refresh-volume-bootmap-info"]], "Release 0.3.2": [[1, "release-0-3-2"]], "Release 1.0.0": [[1, "release-1-0-0"]], "Release 1.0.1": [[1, "release-1-0-1"]], "Release 1.1.0": [[1, "release-1-1-0"]], "Release 1.2.0": [[1, "release-1-2-0"]], "Release 1.2.1": [[1, "release-1-2-1"]], "Release 1.3.0": [[1, "release-1-3-0"]], "Release 1.4.0": [[1, "release-1-4-0"]], "Release Notes": [[1, null]], "Report health of SMAPI": [[10, "report-health-of-smapi"]], "Reset guest": [[10, "reset-guest"]], "Resize CPUs of guest": [[10, "resize-cpus-of-guest"]], "Resize Image to a Bigger Size": [[9, null]], "Resize memory of guest": [[10, "resize-memory-of-guest"]], "Response Data Definition": [[10, "response-data-definition"]], "Revoke user from vswitch": [[10, "revoke-user-from-vswitch"]], "SMAPI Health": [[10, "smapi-health"]], "SSH key authentication between consumer and BYOL server": [[8, "ssh-key-authentication-between-consumer-and-byol-server"]], "SUSE Linux Enterprise Server": [[12, "suse-linux-enterprise-server"]], "Securing Connections with Tokens": [[12, "securing-connections-with-tokens"]], "Set FCP Usage": [[10, "set-fcp-usage"]], "Set user VLANID to vswitch": [[10, "set-user-vlanid-to-vswitch"]], "Setup Client Side": [[12, "setup-client-side"]], "Setup Server Side": [[12, "setup-server-side"]], "Setup for z/VM SDK Daemon": [[8, "setup-for-z-vm-sdk-daemon"]], "Setup web server for running RESTful API": [[12, null]], "Show Guest definition": [[10, "show-guest-definition"]], "Softstop guest": [[10, "softstop-guest"]], "Spawning a virtual machine": [[11, "spawning-a-virtual-machine"]], "Start Apache service": [[12, "start-apache-service"]], "Start Feilong in uwsgi": [[12, "start-feilong-in-uwsgi"]], "Start guest": [[10, "start-guest"]], "Start z/VM SDK Daemon": [[8, "start-z-vm-sdk-daemon"]], "Stop guest": [[10, "stop-guest"]], "Token": [[10, "token"]], "Ubuntu": [[12, "ubuntu"]], "Unpause guest": [[10, "unpause-guest"]], "Update Guest nic": [[10, "update-guest-nic"]], "Upgrade z/VM SDK": [[8, "upgrade-z-vm-sdk"]], "Usage Examples": [[11, "usage-examples"]], "VSwitch": [[10, "vswitch"]], "Verification": [[8, "verification"], [12, "verification"], [12, "id4"]], "Version": [[5, "version"], [10, "version"]], "Volume(s)": [[10, "volume-s"]], "Welcome to the Feilong Document": [[6, null]], "What is Feilong": [[0, "what-is-feilong"]], "Workflow description": [[11, "workflow-description"]], "z/VM SDK install": [[8, "z-vm-sdk-install"]], "z/VM zthin install": [[8, "z-vm-zthin-install"]]}, "docnames": ["architecture", "change", "configuration", "errorcodemsg", "faq", "generalinfo", "index", "makeimage", "quickstart", "resize", "restapi", "sample", "setuphttpd"], "envversion": {"sphinx": 64, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx.ext.viewcode": 1}, "filenames": ["architecture.rst", "change.rst", "configuration.rst", "errorcodemsg.rst", "faq.rst", "generalinfo.rst", "index.rst", "makeimage.rst", "quickstart.rst", "resize.rst", "restapi.rst", "sample.rst", "setuphttpd.rst"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [2, 3, 6, 7, 8, 11, 12], "0": [2, 3, 5, 6, 7, 8, 9, 10, 12], "00": [8, 9, 10], "0000": 10, "0000000000000000": 10, "0001": 9, "0003": 9, "000c": [3, 8], "000d": 8, "01": [8, 10], "0100": [2, 7, 9, 10], "0101": 10, "0102": 10, "0123": 10, "02": 10, "020001000053": 10, "04": [8, 12], "06": [10, 12], "0600": 10, "07": 10, "0700": 7, "0822rhel7": [8, 12], "09": 10, "0c": 10, "0x": 10, "0x0100": 9, "0x4020400100000000": 10, "0x50050763050b073d": 10, "1": [0, 2, 3, 5, 6, 8, 9, 10, 11, 12], "10": [2, 3, 7, 9, 10], "100": [2, 3, 10, 12], "1000": [2, 4, 10], "10000": 10, "1003": 2, "100m": [8, 10], "101": 3, "1024": 10, "10240mb": 9, "10dd8ff5ba02": 9, "10g": 9, "11": [3, 7, 8, 10, 12], "110": 3, "1100": 7, "111": 10, "1111": 10, "116": 10, "116686": 10, "11e8": 10, "12": [3, 9, 10], "120": [2, 3, 7], "1200": 2, "121212314231": 10, "1234567890123456789012345678901234567890": 12, "127": [2, 7, 8, 12], "128": 2, "12980": 10, "13": [3, 7], "13456": 10, "1367740": 10, "13min": 12, "14": 3, "14564": 9, "1486mb": 9, "14892": 10, "15": [3, 7, 8, 9, 12], "1509": 7, "152": 10, "16": [3, 8], "1617mb": 9, "168": 10, "1696mb": 9, "17": [3, 10], "18": [3, 7, 8], "180": 2, "1800": 2, "19": 3, "192": 10, "1970": 10, "1fc5": 10, "1g": 10, "1q": 1, "2": [2, 3, 5, 6, 7, 8, 9, 10, 11, 12], "20": [2, 3, 8], "200": [3, 10, 12], "2000": [2, 8, 10], "200000": 10, "201": 3, "2017": [1, 8, 12], "2018": 1, "202": 3, "2022_04": 10, "203": 3, "2030428": 10, "204": 3, "2048": [9, 11], "205": 3, "206": 3, "207": 3, "2097152": 10, "21": [3, 7, 12], "210mb": 9, "214192": 9, "218459": 9, "22": [2, 3, 7, 8, 12], "222": 10, "2222": 10, "22456": 10, "23": 3, "2300": 9, "2345": [7, 10], "236435482": 7, "24": [3, 8, 10, 12], "240": 2, "24814700": 7, "25": [2, 3], "26": 7, "260788896874": 10, "2621520": 9, "26ddd19301d4f9c8a85e812412164bb8": 7, "2817": 10, "29": 12, "29128": 10, "2d": 10, "2g": 3, "2part": 9, "3": [2, 3, 6, 7, 8, 9, 10, 11], "30": 3, "300": [2, 3, 7], "301": 3, "302": 3, "30232": 9, "303": 3, "304": 3, "305": 3, "3057": 10, "3060": 10, "32": [2, 3, 8, 12], "32g": 10, "333": 10, "3333": 10, "3338": 10, "335": 10, "3390": [9, 10], "34": 10, "34499": 9, "35": 10, "35000": 12, "36": 10, "360": 10, "3600": [2, 12], "3623": 10, "39": 7, "393": 12, "396232": 10, "3kb": 9, "4": [2, 3, 6, 7, 8, 10, 11, 12], "40": [3, 7], "400": [2, 3], "4000": 10, "401": 3, "402": 3, "402621": 12, "403": 3, "404": [3, 10], "405": 3, "406": 3, "407": 3, "408": 3, "409": 3, "4094": 10, "4096": [2, 9], "4096b": 9, "4096m": 10, "410": 3, "411": 3, "412": 3, "413": 3, "414": 3, "414000": 9, "415": 3, "416": 3, "417": 3, "418": 3, "419": 3, "420": 3, "421": 3, "422": 3, "423": 3, "424": 3, "4266": 9, "4267": 9, "4268": 9, "444": 10, "47": 8, "48": 10, "4844": 10, "4c08": 9, "4g": [10, 11], "5": [3, 7, 8, 10, 12], "50": [3, 7], "500": 3, "5005076802100c1a": 10, "5005076802200c1b": 10, "5005076802400c1a": 10, "5005076802400c1b": 10, "501": 3, "503": 3, "509530870": 10, "51200": 10, "5120000": 10, "512b": 9, "512m": 10, "52": 12, "52014cd658cea6ed4005fb25885e30e2": 10, "54": 10, "55": 10, "555": 10, "56": 10, "563": 10, "56434": 8, "566": 10, "57": 10, "5779": 8, "58": 12, "5d": 10, "5d71": 10, "5g": [2, 7, 11], "5gb": [7, 9], "5zh2": 12, "6": [1, 2, 3, 5, 8, 10], "60": [10, 12], "60102": 10, "6013": 9, "6018": 10, "601b": 9, "6131168": 10, "614200": 10, "64": [2, 3, 7, 8, 10], "640": 10, "644": 8, "64g": [2, 8, 10], "65535": 12, "65536": 2, "666": [10, 12], "7": [3, 5, 8, 12], "7227": 12, "7229": 12, "7230": 12, "755": 8, "7614": 10, "78": 10, "79": 7, "791368": 10, "7gb": 9, "8": [1, 2, 3, 7, 10, 12], "80": 11, "8070": 10, "8080": [7, 10, 12], "82": 7, "84": 7, "8408": 10, "85": [7, 10], "8888": 10, "892136": 10, "898e": 10, "8aa3752079b9dc2269cdc44a7185e287": 10, "8g": 10, "8m": 2, "9": [3, 7, 8, 10, 12], "900": 2, "905b": 10, "94": 9, "95": 10, "98": 9, "99": [3, 10], "A": [2, 3, 8, 10], "And": [2, 7, 8, 10, 12], "As": 12, "At": 7, "Be": 8, "By": [7, 8, 12], "For": [2, 4, 7, 8, 10, 12], "If": [1, 2, 4, 5, 7, 8, 9, 10, 12], "In": [2, 5, 7, 8, 10, 11, 12], "It": [0, 2, 3, 5, 7, 8, 10], "NOT": 2, "No": [3, 10], "Not": [3, 10], "ON": 9, "On": [3, 7, 12], "The": [2, 3, 5, 7, 8, 9, 10, 11, 12], "Then": [7, 10, 12], "There": 10, "These": [2, 3, 7, 10], "To": [2, 7, 10, 12], "Will": [3, 10], "a2ensit": 12, "a578": 9, "aa": 10, "aazam": 8, "abl": [2, 8, 12], "about": [8, 12], "abov": [2, 7, 12], "abstract": 7, "accept": [2, 7, 12], "access": [1, 2, 5, 7, 8, 10], "access_typ": 10, "accord": [2, 7, 8], "accordingli": [2, 5, 7, 8], "account": 10, "achiev": 8, "across": 12, "act": [7, 10], "action": [1, 2, 7, 10, 11], "activ": [1, 3, 7, 8, 9, 10, 12], "actual": 10, "ad": [7, 10], "adapt": 1, "adapter_address": 10, "adapter_statu": 10, "add": [3, 7, 8, 12], "addit": [2, 3, 7, 8, 10], "addr": 3, "address": [2, 7, 8, 10, 11, 12], "adjust": [2, 7], "adm": 7, "admin": [2, 10, 12], "admin_token": 12, "administr": [2, 4, 10, 12], "admninistr": 12, "affect": 7, "after": [2, 3, 7, 8, 9, 10, 12], "again": [7, 8], "against": 5, "agent": 12, "ago": [8, 12], "algorithm": 2, "align": 2, "all": [1, 2, 3, 7, 8, 9, 10, 12], "alldisk": 10, "alloc": [2, 10, 11], "allow": [2, 3, 4, 7, 10], "almalinux": 8, "almalinux_9": [8, 12], "alreadi": [2, 3, 7, 8, 12], "also": [5, 7, 10, 12], "alter": 8, "alterdev": 10, "although": 3, "alu": 10, "alwai": 5, "among": [7, 10], "an": [0, 2, 3, 7, 8, 9, 10, 12], "analyz": 2, "ani": [2, 3, 4, 5, 7, 8, 10, 12], "anoth": 3, "anp": [8, 12], "answer": 4, "apach": [5, 7], "apache2": 6, "apar": [1, 8], "api": [0, 1, 2, 3, 5, 6, 7, 8, 11], "api_nam": 3, "api_vers": 10, "app": 12, "appear": 7, "append": [7, 8], "appli": [1, 5, 8, 10], "applic": [1, 2, 7, 8, 9, 10, 11, 12], "apt": [7, 8, 12], "ar": [1, 2, 3, 5, 7, 8, 10, 12], "architectur": [6, 10], "area": 7, "arg": 3, "argument": 3, "around": 7, "asc": 8, "ask": [4, 5], "assign": [10, 12], "assigner_id": 10, "associ": 10, "assum": [8, 12], "attach": [1, 2, 3], "attempt": 3, "attent": 7, "attribut": [6, 10], "audio": 7, "audit": 2, "auth": [2, 7, 8, 10, 12], "auth_userid": 7, "authent": [6, 7, 12], "authenticaion": 12, "authic": 12, "authlist": 8, "author": [1, 2, 3, 4, 7, 8, 10], "authorized_kei": [7, 8], "authorized_us": 10, "authorizedsend": 7, "automaictli": 2, "automat": [2, 7, 8, 12], "avail": [3, 7, 8, 10, 12], "available_memori": 10, "avoid": [2, 12], "awar": 10, "b9fe": 10, "backend": [2, 8], "backlog": 12, "backward": 5, "base": [1, 2, 7], "bash": [7, 8, 11], "basic": [1, 6, 8], "bb": 10, "be919b98": 10, "becaus": [3, 7], "becom": [2, 8], "been": [1, 2, 3, 7, 9, 10], "befor": [2, 3, 7, 8, 12], "begin": 7, "belong": 10, "below": [2, 7, 8, 10, 12], "besid": 8, "best": 2, "beta": [1, 10], "between": [2, 5, 6, 7, 10, 12], "bigger": [6, 12], "bill": 10, "bin": [7, 8, 12], "binari": [8, 10], "bind": [2, 11], "bind_addr": [2, 8], "bind_port": [2, 8], "bit": 2, "biz": 7, "blah": 7, "blank": 2, "blk": 10, "blkid": 7, "blksz": 9, "block": [3, 8, 9, 10, 12], "bodi": 10, "bond": 8, "book": [3, 7], "bool": 10, "boolean": 10, "boot": [2, 7, 8, 10], "bootabl": 10, "bootcmd": 7, "bootmap": 3, "both": [3, 7, 8, 10, 11, 12], "bound": 7, "bridg": 7, "bring": [7, 8], "broken": 3, "bu": [3, 9], "buffer": [10, 12], "bug": [6, 10], "build": [7, 8], "buildzthindeb": 8, "buildzthinrpm_rhel": 8, "buildzthinrpm_sl": 8, "buildzvmdsdkrpm_rhel": 8, "buildzvmsdkdeb": 8, "buildzvmsdkrpm_sl": 8, "built": 3, "byobu": 7, "byol": [6, 7], "bypass_smapiout": 2, "byte": [3, 9, 10, 12], "c": [7, 8], "ca": 7, "cach": [1, 2, 8, 12], "cache_interv": 2, "calcul": 3, "call": [2, 3, 5, 7, 8, 10, 11, 12], "caller": 2, "can": [0, 2, 5, 7, 8, 9, 10, 12], "cann": 3, "capac": 2, "captur": [1, 2, 3, 6, 9], "capture_typ": 10, "capturedimag": 10, "case": [2, 7, 10], "cat": [7, 8], "caus": [2, 10], "cc": 10, "ccw": 3, "cd": [7, 8], "cdrom": 7, "cec_model": 10, "cert": 7, "certain": 2, "cfg": 7, "cfgdrive": [7, 10], "cgroup": [8, 12], "chang": [1, 2, 3, 7, 8, 10, 12], "channel": [1, 7, 8], "chapter": 12, "char": 2, "charact": 2, "characterist": 10, "charset": 12, "chccwdev": 8, "chcon": 8, "check": [2, 7, 8], "checkout": 8, "cheetah": 7, "chkconfig": 7, "chmem": 3, "chmod": [8, 12], "choic": 2, "chosen": 12, "chown": 8, "cidr": 10, "cio_ignor": 8, "ckd": 3, "class": [3, 7, 8], "clean": 8, "client": [0, 2, 3, 5, 7, 10, 11], "clone": 8, "close": 12, "cloud": [1, 2, 3, 6, 10, 11], "cloud_config": 7, "cloud_config_modul": 7, "cloud_final_modul": 7, "cloud_init": 7, "cloud_init_modul": 7, "cloudinit": 7, "cloudinitloz": 7, "cluster": 1, "cm": 10, "cmd": 3, "code": [6, 7, 8, 10, 12], "collect": [7, 10], "column": 8, "com": [7, 8, 10], "combin": [2, 10, 12], "come": 0, "comma": 10, "command": [2, 3, 7, 8, 10, 12], "comment": [7, 10], "comment_list": 10, "common": [2, 4, 6], "commonli": 1, "commun": [1, 3, 7, 8, 12], "compat": [2, 6], "compil": 7, "complet": [2, 12], "complic": 2, "compon": 0, "compress": [2, 10], "compress_level": 10, "comput": [8, 10], "con": 10, "concurr": [2, 3, 8], "conf": [4, 7, 8, 10, 12], "config": [1, 7, 8], "configdr": 7, "configur": [1, 3, 4, 5, 6], "conflict": [2, 3, 4], "conn": 10, "connect": [1, 2, 3, 4, 6, 7, 8, 10], "connection_typ": 11, "connector": [1, 2, 3, 11], "consid": 8, "consider": 12, "consist": 8, "consol": [1, 2, 3, 7, 8], "console_log_s": 2, "console_output": 10, "consum": [2, 5, 6, 7, 12], "contact": [10, 12], "contain": [2, 3, 8, 10, 12], "content": [6, 7, 8, 10, 11, 12], "context": [1, 8], "continu": [3, 7, 8, 10], "continuousfail": 10, "control": [2, 10, 12], "convert": 3, "cook": 7, "copi": [2, 3, 7, 8, 10, 11, 12], "core": 12, "corner": 5, "correct": [2, 7, 8], "correctli": 7, "correspond": 2, "could": [3, 10], "count": [1, 3, 10], "coupl": [1, 3, 10], "couple_err": 3, "cover": 10, "cp": [2, 3, 7, 11], "cpu": [1, 2, 3, 5], "cpu_cnt": 10, "cpu_info": 10, "cpu_time_u": 10, "crawler": 7, "creat": [1, 2, 3, 4, 7, 8, 9, 12], "create_err": 3, "creatediskimag": [7, 8], "creation": 2, "creativ": 6, "criteria": 7, "cross_system_timeout": 10, "curl": [7, 10, 11, 12], "current": [1, 2, 3, 4, 7, 8, 10], "custom": [2, 7, 8, 10, 11], "cyl": [7, 9, 10], "cylind": [3, 7, 9, 10], "d": [3, 7, 8, 11, 12], "d80df349": 9, "da19c4b3": 10, "daemon": [2, 6, 7], "damag": 9, "dasd": [2, 9, 10], "dasd_group": 10, "dasda": 9, "dasda1": 9, "dasda2": 9, "dasdfmt": 8, "dat": [2, 10, 12], "data": [1, 2, 3, 6, 7], "data_typ": 3, "databas": [2, 3, 8, 10], "datamov": 8, "datasourc": 7, "datasource_list": 7, "date": [7, 8, 12], "db": [3, 11], "deamon": 2, "debian": 8, "debug": 2, "dec": [1, 12], "decid": 2, "decim": [2, 10], "decreas": [1, 10], "dedic": [1, 3, 10], "dedicate_vdev": 10, "default": [2, 7, 8, 10, 11, 12], "default_admin_userid": [2, 4], "default_compress_level": 2, "default_nic_vdev": [2, 4], "default_us": 7, "defer": 2, "defin": [2, 3, 4, 8, 10, 11], "definit": [1, 2, 3, 4, 6, 8, 11], "delai": 10, "delet": [1, 3], "delimit": [2, 10], "deni": 7, "depend": [7, 8], "deploi": [1, 2, 3, 7, 9, 11], "deploy": [6, 9, 12], "deprec": [6, 10], "deregister_vm": 10, "describ": [5, 7, 8, 9, 10, 12], "descript": [2, 6, 7, 10, 12], "descriptor": 10, "design": [4, 8], "desir": [2, 3, 7], "desired_st": 3, "desired_stat": 3, "dest_path": 10, "dest_url": 10, "dest_zcc_userid": 10, "destin": 10, "destnod": 10, "destuid": 10, "detach": [1, 2, 3], "detail": [2, 3, 4, 7, 8, 12], "determin": 8, "dev": [8, 9, 10], "dev_err": 10, "dev_statu": 10, "develop": 0, "devic": [1, 2, 3, 7, 8, 9, 10], "device_s": 10, "device_typ": 10, "device_unit": 10, "dialout": 7, "dict": 10, "dictionari": 10, "did": 3, "die": 12, "differ": [4, 7, 10, 12], "digit": 10, "dip": 7, "dir": [2, 8], "direct": [2, 3, 11], "directli": [8, 10, 12], "directori": [2, 3, 4, 7, 8, 10, 12], "dirmaint": [8, 11], "disabl": [2, 7, 8, 12], "disable_root": 7, "discard": 10, "disconnect": 10, "discuss": 7, "disk": [1, 2, 3, 5, 7, 8, 9, 11], "disk_avail": 10, "disk_info": 10, "disk_list": [10, 11], "disk_pool": [2, 3, 7, 8, 10, 11], "disk_setup": 7, "disk_siz": 3, "disk_size_unit": [7, 10], "disk_tot": 10, "disk_typ": 10, "disk_us": 10, "diskpo1": 2, "diskpool": 10, "diskpool_volum": 10, "disktyp": 2, "displai": 10, "dist": [10, 12], "distribut": [7, 8, 12], "distro": [7, 8, 10], "divis": 3, "dmssicnf": 2, "dn": 10, "dnf": [8, 12], "dns_addr": 10, "do": [2, 7, 8, 10], "doc": 2, "document": [5, 7, 8, 10, 12], "docview": 8, "doe": [1, 2, 3, 7, 10], "doesn": [2, 4], "dollar": 2, "don": [2, 7, 10, 12], "done": [7, 8, 11, 12], "down": [2, 7], "download": [7, 8, 12], "dpkg": [7, 8], "drive": [1, 3, 7, 9], "driver": [3, 7], "dsmode": 7, "dtcvsw1": 10, "durat": 2, "dure": [2, 3, 7, 8, 9, 10, 11], "dynam": [10, 12], "e": [2, 7, 8, 10], "e277": 9, "e36813be796": 10, "each": [2, 7, 8, 10, 12], "easi": 5, "easier": 1, "easili": 7, "ebcdic": 3, "ec2": 7, "ecdsa": 7, "echo": [7, 8], "eckd": [2, 7, 8, 9, 10, 11], "eckdpool": 8, "eckdpool1": 10, "eckdpoolnam": 10, "edit": [2, 3], "edt": 10, "effect": [2, 7, 8, 10], "effici": 7, "effort": 2, "eg": [8, 10], "egg": 7, "eight": 10, "either": [2, 3, 7, 10, 12], "elaps": 10, "elapsed_cpu_time_u": 10, "element": 10, "elig": 10, "elimin": 10, "emit": 7, "emit_upstart": 7, "empti": [2, 3, 10, 12], "en": 7, "enabl": [1, 2, 3, 7, 8, 10, 12], "encount": [3, 5, 10], "end": [2, 3, 9], "engin": 7, "enhanc": 12, "enlarg": 9, "enough": [8, 12], "ensur": [2, 7, 8], "enter": 3, "enterpris": 8, "entitl": 2, "entri": [2, 3, 8, 10], "environ": [7, 8], "epel": 8, "ephemer": [2, 8, 9], "ephemeral0": 10, "ephemeral1": 10, "equal": [2, 7, 8, 10], "err": 3, "err_info": 3, "errcod": 3, "errmsg": [3, 7, 10, 11, 12], "errno": 3, "error": [2, 6, 7, 8, 10, 12], "error_cod": 3, "esa": 10, "esm": [2, 8], "est": [8, 12], "etc": [0, 2, 4, 7, 8, 10, 11, 12], "ethernet": 10, "even": 10, "evenli": 3, "event": 7, "exampl": [2, 6, 7, 8, 10, 12], "exce": [2, 3, 10], "except": 3, "exception_detail": 3, "excess": 2, "execreload": 12, "execstart": [7, 12], "execstop": 12, "execut": [2, 3, 7, 8, 12], "exhaust": 2, "exist": [2, 3, 7, 8, 10, 11], "exit": [9, 12], "expand": 9, "expect": [3, 7], "experi": 7, "expir": 2, "export": [1, 2, 3, 8], "expos": 12, "express": 10, "ext2": [3, 9, 10], "ext3": [3, 10], "ext4": [3, 9, 10], "extend": 2, "extend_partition_f": 2, "extent": 2, "extern": [5, 11], "extra": 8, "eyjhbgcioijiuzi1niisinr5cci6ikpxvcj9": 12, "eyjlehaioje1mti1ndqyodj9": 12, "f": 7, "fa00": 2, "fa01": 2, "fa02": 2, "fail": [2, 3, 7, 8, 10, 11], "failur": 3, "fals": [2, 7, 10], "faq": 6, "fb00": 2, "fb01": 2, "fb02": 2, "fba": [2, 3, 7, 10], "fbapool1": 10, "fbapoolnam": 10, "fcp": [2, 3, 8], "fcp_id": 10, "fcp_list": 2, "fcpchannel": 10, "fdasd": [8, 9], "fdisk": 8, "featur": [1, 10], "feel": 8, "feilong": [3, 4, 5, 8, 11], "fetch": [2, 8], "few": 3, "ff00": 10, "ffff": 2, "ffffffffffffffff": 10, "field": [7, 12], "file": [2, 3, 4, 6, 7, 8, 9, 11, 12], "file_loc": 3, "file_repositori": 2, "file_system": 3, "filesize_in_byt": 10, "filesystem": [2, 3, 7], "fill": [3, 7, 9], "final": [7, 12], "find": 7, "finish": [2, 8, 10], "firewal": [7, 12], "first": [2, 7, 10, 11, 12], "firstli": 10, "flag": [8, 9], "flavor": 9, "float": 10, "floppi": 7, "flow": [6, 7], "fly": 11, "focus": 8, "folder": [7, 8, 12], "follow": [1, 3, 7, 8, 9, 10, 11, 12], "force_capture_disk": 2, "form": 10, "format": [1, 2, 3, 7, 8, 10], "found": [2, 3, 7, 8], "four": 7, "fox": 12, "fp1t001d": 10, "frame": 10, "free": [8, 10], "free_memori": 10, "free_siz": 10, "frequent": 4, "from": [0, 1, 2, 3, 4, 5, 6, 7, 8], "full": [7, 12], "function": [2, 3, 5, 8], "function_nam": 3, "further": 10, "fvtuser1": 10, "g": [2, 3, 10], "gatewai": 10, "gateway_addr": 10, "gcc": 8, "geco": 7, "gener": [2, 3, 6, 8, 10, 12], "gentoken": 12, "get": [1, 2, 3, 7, 8, 11, 12], "get_console_output": 10, "get_fcp_pair": 2, "get_fcp_pair_with_same_index": 2, "getenforc": 8, "gid": 12, "gigabyt": [2, 10], "git": 8, "github": 8, "give": [10, 11], "given": [2, 8, 10], "glanc": 7, "gmt": 12, "go": [7, 8, 12], "goal": 5, "golang": 11, "got": [3, 7], "govern": 2, "gpg": 8, "gpgkeycheck": 8, "grace": 12, "gracefulli": 10, "grant": [1, 8, 12], "grant_userid": 10, "greater": [3, 7], "grep": [7, 8, 12], "group": [2, 7, 8, 12], "groupadd": 7, "grow_root_volum": 10, "growpart": 7, "grub": 7, "gssapi": 7, "guest": [0, 1, 2, 3, 4, 5, 6, 8, 9, 11], "guest_cpu": 10, "guest_creat": 11, "guest_create_info": 11, "guest_ipl_loadparam": 10, "guest_ipl_param": 10, "guest_network": 10, "guid": 12, "gvrp": 10, "gvrp_enabled_attribut": 10, "gvrp_request_attribut": 10, "gz": 7, "h": [7, 10, 11, 12], "ha": [1, 2, 3, 4, 7, 8, 9, 10], "handl": [2, 7, 10, 11, 12], "happen": 7, "hat": 8, "have": [3, 7, 8, 10, 12], "he": 2, "header": [3, 10, 12], "health": 6, "healthi": 10, "heavi": 8, "heavili": 9, "help": [2, 3, 10, 12], "here": [0, 7, 8], "hex": [2, 3], "hexadecim": 10, "hexdump": [3, 7], "higher": [7, 12], "home": 8, "host": [1, 2, 3, 6, 7, 8, 11, 12], "hostnam": [1, 10, 11], "hot": [1, 3], "how": [2, 7, 8, 9, 10, 11, 12], "html": [7, 12], "http": [1, 2, 3, 7, 8, 10, 11, 12], "httpd": [7, 12], "hub": 8, "hypervisor": 1, "hypervisor_hostnam": 10, "hypervisor_typ": 10, "hypervisor_vers": 10, "i": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], "ias100": 10, "ias101": 10, "ias7cm_on_139": 10, "ibm": [5, 7, 8, 9, 10], "icicpl": 10, "id": [1, 4, 7, 8, 9], "id0001": 10, "id001": [10, 11], "id1": 10, "id2": 10, "id3": 10, "id_rsa": 8, "ident": 2, "identifi": [2, 10], "ignit": [3, 10], "ignor": [7, 8, 10], "im": 3, "imag": [0, 1, 2, 3, 6, 8, 11], "image1": 10, "image_console_get": 3, "image_loc": 7, "image_meta": [7, 10], "image_nam": [7, 10], "image_osvers": 2, "image_path": [7, 10], "image_query_dm": 8, "image_size_in_byt": [7, 10], "imagenam": [2, 7, 10], "imageosdistro": [7, 10], "img": [3, 10], "immedi": 10, "implement": [1, 7, 8], "import": [1, 2, 3, 6, 8, 11], "improv": [1, 7], "inact": 1, "inc": 3, "includ": [0, 1, 2, 7, 8, 11], "incom": 12, "increas": [1, 3, 8, 10], "indent": 7, "independ": 12, "indic": [2, 7, 10, 12], "individu": 10, "info": [2, 3, 6, 7, 8, 9], "inform": [1, 2, 3, 7, 8, 11], "ini": 12, "init": [1, 6, 11], "init0": 7, "init20": 7, "init_mem_s": 3, "initi": [3, 7, 10, 12], "inject": 8, "input": [2, 3], "inputtyp": 3, "insensit": [7, 10], "insert": [2, 7], "insid": 8, "inspect": [1, 2], "insserv": 7, "inst": 3, "instal": [2, 6], "instanc": [3, 7, 10], "instead": [2, 10, 12], "instruct": 12, "int": 10, "intact": 12, "integ": [2, 3, 4, 10], "integr": [1, 6], "intend": [7, 12], "interact": 5, "interfac": [1, 2, 5, 12], "interfacestat": 10, "intern": [3, 6, 10], "interpret": 12, "interv": [2, 3], "introduc": 11, "introduct": 6, "invalid": [2, 3], "inventori": 7, "invok": 1, "ip": [2, 7, 8, 10, 11, 12], "ip_addr": [10, 11], "ip_timeout": 10, "ipl": 10, "ipl_from": 10, "ipl_loadparam": 10, "ipl_param": 10, "ipl_tim": 10, "ipv4": 10, "ipv6": 10, "is_boot_disk": [10, 11], "is_root_volum": 10, "isg1vm66120": 8, "iso": 7, "iso9660": [1, 7], "isolation_statu": 10, "issu": [2, 3, 5, 7, 8, 10], "item": [2, 4, 8, 12], "its": [3, 5, 7, 8, 10], "itself": 8, "iucv": [1, 3, 8], "iucvclnt": 7, "iucvserverdaemoninstal": 7, "ivh": 8, "jm6013": 9, "jm601b": 9, "job": 7, "join": 10, "jone": 2, "journal": 7, "jq": 11, "json": [1, 7, 11, 12], "jun": 7, "just": [8, 10, 12], "kb": 12, "kbyte": 10, "keep": [2, 7], "kei": [2, 6, 7, 10], "kernel": 10, "kernel_info": 10, "keyex": 7, "keygen": [7, 8], "keyword": [2, 3], "keyword_valu": 3, "kilobyt": 2, "kind": 2, "kit": 0, "know": [10, 12], "known": [5, 7], "known_host": 8, "l": [7, 8], "label": [7, 9, 10], "lag": 10, "lag_group": 10, "lag_interv": 10, "lan": [2, 10], "lan_nam": 10, "lan_own": 10, "landscap": 7, "languag": 0, "larg": 2, "larger": [2, 7, 9, 10], "last": [2, 8, 9, 10, 12], "last_access_tim": 10, "lastfail": 10, "lastsuccess": 10, "later": 7, "latest": [7, 8], "launchpad": 7, "layer": [1, 5, 7, 8, 11], "lazi": 12, "lbyonli": 2, "least": [3, 8], "left": [5, 12], "length": [2, 9, 12], "less": 3, "let": 12, "level": [2, 7, 8, 10, 12], "lgr_action": 10, "lib": [2, 7, 8, 10, 12], "libapache2": 12, "librari": [0, 5, 8], "licens": 6, "lifecycl": 5, "like": [2, 8, 10, 12], "limit": 12, "line": 7, "link": [8, 10], "link_ag": 10, "linkdiskandbringonlin": 8, "linux": [2, 3, 8, 9], "linuxon": 5, "list": [0, 1, 2, 3, 7, 8, 9], "listen": [2, 8, 12], "live": [1, 3], "live_migrate_vm": 10, "live_resize_cpu": 10, "live_resize_mem": 10, "ln": 7, "lnknopa": 8, "load": [8, 12], "loaddev": 10, "loadmodul": 12, "loadparam": 10, "loadparm": 10, "local": [3, 7, 10], "local_f": 7, "localhost": 12, "locat": [7, 8, 10], "lock": [3, 12], "lock_passwd": 7, "log": [2, 3, 7, 8, 10, 12], "log_dir": [2, 8], "log_level": [2, 8], "logic": [7, 9, 10], "login": 7, "logoff": [7, 8, 10], "logon": [2, 4, 7, 8, 10], "logonbi": 2, "logto": 12, "lone": 2, "long": [2, 8], "longer": 2, "look": [2, 3], "loop": 7, "loss": 7, "lower": 8, "lpar": 7, "lrwxrwxrwx": 7, "lsdasd": 9, "lt": 8, "lun": [2, 10], "m": [2, 3, 7, 8, 10], "mac": 10, "mac_addr": 10, "mac_address": 10, "mac_ip_address": 10, "mac_ip_vers": 10, "mac_protect": 10, "machin": [1, 2, 3, 4, 5, 8, 10], "macid": 2, "macid1": 2, "macid2": 2, "made": 8, "mai": [2, 3, 7, 10], "main": [8, 12], "mainli": [1, 8], "maintain": [2, 7], "mainthread": 8, "make": [1, 2, 4, 5, 6, 8, 9, 12], "malform": 3, "manag": [0, 1, 2, 5, 7, 8, 10, 11, 12], "mani": 1, "manual": [6, 7, 10, 12], "map": 12, "mark": [5, 8], "master": [8, 12], "match": [7, 12], "matrix": 12, "matter": 10, "max": [2, 3, 9, 10], "max_concurrent_deploy_captur": 2, "max_cpu": [2, 10, 11], "max_cpu_limit": 10, "max_mem": [2, 10, 11], "max_mem_kb": 10, "max_mem_s": 3, "max_vers": [10, 12], "max_wait": [3, 7], "max_worker_count": [2, 8], "maxim": 10, "maximum": [2, 3, 8, 10], "maxquiesc": 10, "maxtot": 10, "maxwait": 3, "mbyte": 10, "mcollect": 7, "md5sum": [3, 7, 10], "mdisk": [2, 3, 10], "mean": [2, 5, 8, 10, 12], "mechan": [1, 2, 10], "media": 10, "meet": 7, "megabyt": [2, 10], "mem_kb": 10, "member": 10, "member_pdr_heartbeat": 10, "member_received_heartbeat": 10, "member_slot": 10, "member_st": 10, "member_system_id": 10, "memori": [1, 2, 3, 5, 8, 11], "memory_mb": 10, "memory_mb_us": 10, "merci": 12, "messag": [6, 7, 10], "meta": 10, "metadata": [7, 10], "metadata_url": 7, "method": 12, "mfcloud": 8, "mic": 7, "microsecond": 10, "might": [2, 7], "migrat": [1, 7], "min": 10, "min_cpu_count": 10, "min_mem_kb": 10, "min_vers": [10, 12], "minidisk": 7, "minim": 10, "minimum": 7, "minion": 7, "minor": 7, "miss": [3, 7], "mkdir": 8, "mkf": 8, "mkisof": 7, "mnt": 10, "mntdir": 10, "mod": 12, "mod_proxy_uwsgi": 12, "mod_wsgi": 6, "mode": [8, 12], "model": 9, "modid": [3, 7, 10, 12], "modifi": [7, 12], "modu": 7, "modul": [7, 10, 12], "mon": 8, "monitor": [1, 2, 3], "more": [2, 3, 4, 5, 7, 10, 12], "most": 8, "mount": [7, 8, 10], "mount_point": 10, "move": 10, "msg": 3, "multi": [7, 12], "multipath": [3, 7, 10], "multipathd": 7, "multipl": 12, "must": [1, 2, 3, 7, 8, 10], "mv": 8, "my_ip": [2, 8], "myguest": [10, 11], "myswitch": 10, "n": 7, "na": 10, "name": [2, 3, 7, 8, 9, 11, 12], "name1": 10, "namelist": 2, "namelistfileidani": 2, "namemapp": 7, "nativ": [9, 10], "native_vid": 10, "native_vlan_id": 10, "natvid": 10, "need": [2, 7, 8, 10, 11, 12], "neg": 10, "net": 7, "net_set": 10, "netboot": [2, 10], "netstat": [8, 12], "network": [0, 1, 2, 3, 4, 7, 8, 11, 12], "network_typ": 10, "networkmanag": 7, "never": 10, "new": [1, 2, 3, 5, 7, 8, 9, 10, 11, 12], "newer": 8, "newli": 11, "next": [7, 8, 10], "nginx": 12, "nic": [1, 2, 3], "nic_fr_rx": 10, "nic_fr_rx_dsc": 10, "nic_fr_rx_err": 10, "nic_fr_tx": 10, "nic_fr_tx_dsc": 10, "nic_fr_tx_err": 10, "nic_id": 10, "nic_rx": 10, "nic_tx": 10, "nic_vdev": 10, "nicdef": 2, "node": [8, 10], "nogrp": 10, "nogvrp": 10, "noisol": 10, "non": [2, 10], "none": [2, 3, 7, 8, 10, 12], "nonrout": 10, "noosdsim": 10, "nopasswd": [7, 8], "noprom": 10, "normal": [2, 8, 10, 12], "note": [2, 5, 6, 7, 8, 9, 10, 11, 12], "noth": 2, "nouplink": 10, "nov": [8, 12], "nova": [7, 8, 10], "nova_hom": 8, "now": [8, 9, 10], "npermiss": 7, "null": [7, 10, 12], "num": 3, "num_block": 3, "num_cpu": 10, "number": [2, 3, 7, 8, 9, 10], "o": [7, 10], "o1": 2, "o2": 2, "o3": 2, "o4": 2, "o5": 2, "o6": 2, "o7": 2, "o8": 2, "o9": 2, "ob": 6, "obj": 3, "obj_desc": 3, "object": [3, 8, 12], "obtain": [3, 8], "occur": [3, 7, 10], "octet": [1, 10], "off": [2, 7, 10], "offlinediskanddetach": 8, "ok": [9, 12], "old": 10, "onc": [2, 11], "one": [1, 2, 3, 10, 11, 12], "oneshot": 7, "onli": [1, 2, 3, 4, 7, 9, 10, 11], "onlin": [3, 8, 10], "online_cpu_num": 10, "onto": [8, 10], "open": [2, 5, 7, 8, 10], "openssl": 7, "openstack": [0, 7, 9, 10], "opensus": [8, 12], "oper": [0, 2, 3, 10, 12], "oper1": 2, "oper2": 2, "oper3": 2, "operand": 3, "operand_posit": 3, "operand_valu": 3, "opncloud": [7, 8, 10], "opncloud_0700": 10, "opnstk1": 10, "opnstk2": 10, "opnstk3": 10, "opt": [7, 8, 10], "option": [3, 6, 7, 8, 10], "option1": 3, "option2": 3, "order": [2, 7, 8, 10], "org": [7, 8, 12], "org_repositories_virtualization_feilong_almalinux_9_": 8, "os_distro": 10, "os_vers": [7, 10], "osa": [1, 3, 10], "osa_devic": [1, 10], "osd_sim": 10, "osdflt": [8, 11], "other": [0, 1, 2, 4, 7, 11, 12], "otherwis": [7, 10], "our": 3, "out": [3, 12], "output": [1, 3, 7, 8, 12], "outsid": 2, "overal": [3, 7, 10], "overallrc": [3, 7, 10, 11, 12], "overllrc": 10, "overriden": 10, "own": [7, 8, 12], "owner": [7, 12], "p": 8, "pack": 7, "packag": [2, 6, 7], "packagehub": 8, "page": 5, "pai": 7, "painfulli": 7, "pair": 2, "param": [2, 10], "paramet": [2, 3, 7, 10, 11], "parm": 10, "part": [2, 7, 8, 9, 10], "partit": [2, 7, 9, 10], "pass": [2, 7, 12], "password": [2, 4, 7, 8, 10, 12], "path": [2, 8, 10, 12], "paus": 1, "pchid": 3, "pdf": 7, "per": 9, "perform": [1, 2, 3, 7, 9, 10], "period": 2, "perman": [7, 10], "permit": 8, "persist": [2, 7, 10, 11], "perspect": [4, 5], "physic": [3, 9, 10], "pid": [8, 12], "pidfil": 12, "pipelin": 7, "place": [2, 12], "plain_text_passwd": 7, "plan": 2, "platform": [1, 5], "pleas": [2, 3, 5, 7, 8, 10, 12], "plug": [1, 3], "plugin": 12, "point": [5, 7, 10], "polici": 8, "poll": 3, "poll_interv": 3, "pool": [1, 2, 3, 8], "poolnam": 10, "port": [2, 3, 7, 8, 11, 12], "port_nam": 10, "port_num": 10, "port_typ": 10, "portid": 10, "portnam": 10, "porttyp": 10, "posit": [3, 10], "possibl": [2, 3, 9], "post": [7, 10, 11, 12], "potenti": 2, "power": [1, 2, 11], "power_st": 10, "power_state_r": 10, "practic": 2, "pre": [6, 7], "prefork": 12, "premad": 12, "prepar": 7, "preset": [8, 12], "prevent": 2, "primari": 10, "print": [9, 11], "prioriti": 2, "prirout": 10, "privileg": 8, "problem": [5, 7], "proce": 9, "procedur": 7, "process": [2, 3, 7, 8, 9, 12], "product": [7, 8], "profil": [2, 8, 10], "program": [2, 8], "programm": 5, "progress": 3, "project": 8, "prom_mod": 10, "proper": 7, "provid": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10], "provison": 1, "proxi": 12, "proxy_uwsgi_modul": 12, "proxypass": 12, "pub": [7, 8], "public": [7, 8, 9], "publickei": 7, "punch": [2, 3, 7, 8], "punch_script_execution_timeout": 2, "puppet": 7, "purg": 3, "put": [2, 10, 12], "py": [7, 8], "py2": 7, "pyjwt": 2, "pypi": 7, "python": [0, 2, 5, 7, 8, 10, 12], "python2": [7, 12], "python3": 7, "q": 9, "qdio": [2, 10], "queri": [1, 2], "question": [4, 6], "queue": 2, "queue_mem": 10, "queue_memory_limit": 10, "quick": 6, "r": [3, 7, 8, 9, 10, 12], "rac": 8, "racf": 8, "rais": 11, "ram": 9, "random": 12, "randomli": 2, "rang": [3, 10, 12], "raw": 10, "rc": [3, 7, 10, 12], "rc5": 7, "rcx": 7, "rdev": 10, "re": [7, 8, 10], "reach": 2, "reachabl": 2, "reachable_timeout": 2, "read": [2, 9], "reader": [3, 7, 8], "readi": [2, 7, 10], "readthedoc": 7, "readwrit": 2, "real": 10, "real_devic": 10, "real_device_address": 10, "reason": [2, 3, 10], "reboot": [1, 7, 8], "receiv": [3, 8, 10], "recevi": 3, "recogn": 3, "recommend": [2, 7, 8, 12], "recommend_max_wait": 3, "recommend_poll_interv": 3, "record": [3, 11], "recreat": 2, "red": 8, "redbook": 7, "redhat": 7, "redhat7": 10, "redirect": 12, "refer": [3, 4, 7, 8, 10, 11, 12], "reflect": 8, "refresh": [3, 8], "refresh_bootmap": 2, "refresh_bootmap_timeout": 2, "region_nam": 10, "regist": 8, "register_vm": 10, "registr": 10, "reject": [2, 3], "rel": 2, "relat": [3, 7], "releas": [5, 6, 7, 8], "reli": 8, "reload": 12, "reloc": [3, 10], "remainafterexit": 7, "remaind": 9, "rememb": [7, 12], "remot": [2, 3, 7, 10], "remote_f": 7, "remote_host": [3, 7, 10], "remotehost": [2, 10], "remotehost_sshd_port": 2, "remov": [2, 7, 10], "renam": 7, "replac": [3, 7, 8], "repli": [3, 12], "repo": 8, "report": 6, "repositori": [2, 7, 8, 10, 11, 12], "repres": [7, 8, 10, 12], "reproduc": 8, "req": 3, "request": [1, 2, 3, 7, 8, 10, 11, 12], "request_data_typ": 3, "request_queue_s": 2, "requir": [1, 2, 3, 6, 10, 12], "rescan": 3, "reserv": [2, 3, 7, 10], "reset": 1, "resid": 7, "resiz": [1, 3, 6], "resize_cpu": 10, "resize_mem": 10, "resizef": 7, "resolv": 7, "resourc": [0, 2, 5], "respons": [3, 6, 12], "rest": [1, 3, 5, 6, 7, 11], "restart": [4, 7, 10, 12], "restclient": 1, "restrict": 10, "result": [7, 8, 9, 10], "retri": 2, "retriev": [2, 7, 10], "return": [2, 3, 8, 10], "reviev": 2, "revok": [1, 3], "revoke_err": 3, "revoke_userid": 10, "rf": 7, "rh": 3, "rhco": [3, 10], "rhcos4": 10, "rhel": 12, "rhel6": 10, "rhel7": [7, 10, 12], "rhel8": 10, "rhel9": 10, "right": 8, "rm": 7, "root": [1, 2, 3, 7, 8, 12], "root_disk_s": 10, "rootonli": [7, 10], "router": 10, "routing_valu": 10, "rpm": 12, "rpmbuild": 8, "rsyslog": 7, "rule": [5, 12], "run": [2, 5, 6, 7, 8, 10, 11], "runcmd": 7, "runlevel": 7, "runtimeerror": 11, "s124": 9, "s390": 9, "s390x": [8, 10], "s50xcatconfinit": 7, "s51cloud": 7, "s52cloud": 7, "s53cloud": 7, "s54cloud": 7, "safe": 5, "safeti": 12, "salt": 7, "same": [2, 3, 7, 8], "sampl": [2, 6, 7, 9, 10, 12], "samples_cpu_delai": 10, "samples_cpu_in_us": 10, "sbin": [8, 12], "schema": 3, "scp": [3, 7, 8], "script": [2, 3, 7], "script_nam": 3, "scsi": 10, "sdk": [0, 2, 3, 5, 6, 7, 12], "sdk_fcp": 8, "sdk_image_repositori": [2, 8], "sdkserver": [2, 7, 8], "sdkwsgi": 12, "sdz": 10, "search": 3, "sec": 3, "second": [2, 3, 7, 10, 12], "section": [4, 5, 7, 8, 9, 10, 11, 12], "sector": 9, "secur": [4, 6, 7, 10], "see": [2, 5, 7, 8, 12], "seed_random": 7, "seen": 5, "sel": 7, "select": 2, "selinux": [7, 8], "semant": 5, "send": [2, 3, 7, 8, 10, 11, 12], "send_request": 11, "sent": [3, 10], "separ": 2, "sequenc": 7, "serial": 9, "server": [1, 2, 3, 6, 7, 9, 10, 11], "servic": [2, 3, 4, 8, 10, 11], "set": [0, 1, 2, 3, 4, 5, 7, 8, 11, 12], "set_hostnam": 7, "setup": [6, 7, 11], "setuptool": [7, 8], "sever": [2, 8], "sg248147": 7, "sg248303": 7, "sg248354": 7, "sg248890": 7, "sh": 7, "share": [2, 7, 10], "shared_mem_kb": 10, "shell": 7, "should": [2, 3, 7, 8, 10, 12], "show": [9, 11, 12], "shut": [2, 7], "shutdown": [2, 10], "sign": 2, "similar": [7, 12], "simpl": [7, 12], "sinc": [1, 7, 8, 10, 12], "singl": [2, 7, 10], "site": [7, 12], "situat": 2, "size": [1, 2, 3, 6, 7, 8, 11, 12], "skip": [8, 10], "skipdiskcopi": 10, "sle": 12, "sle_15_sp5": [8, 12], "sles11": 10, "sles12": [7, 9, 10], "sles12sp3": 10, "sles12sp4": 9, "sles12us": 7, "sles15": [10, 12], "slice": [8, 12], "slow": 7, "small": 9, "smaller": [2, 10], "smapi": [1, 2, 3, 5, 6, 8, 11], "smapi_health": 10, "smapi_socket_long_call_timeout_second": 2, "smapi_socket_timeout_second": 2, "smapiout": 2, "smcli": 8, "smt": 3, "snap201710300123": 8, "snapdat": 8, "snapshot": 2, "so": [2, 3, 7, 8, 10, 12], "socket": [2, 3, 8, 12], "softstop": [1, 2], "softstop_interv": 2, "softstop_retri": 2, "softstop_timeout": 2, "softwar": [0, 7], "solut": 2, "some": [2, 7, 8, 10, 11, 12], "someth": [8, 10], "sometim": [2, 12], "sourc": [3, 7, 8], "source_fil": 10, "sp": 10, "sp3": 7, "sp4": 9, "sp6": [8, 12], "space": [8, 10], "spawn": [7, 8, 9, 12], "specif": [7, 10, 12], "specifi": [1, 2, 3, 7, 10, 12], "specified_funct": 3, "spent": 2, "spool": [3, 8], "spool_class": 3, "spool_id": 3, "sqlite": 8, "sqlite3": 8, "ssh": [4, 6, 7], "ssh_home_t": 8, "sshd": [2, 7], "sshd_config": 7, "ssi": 1, "ssi_mod": 10, "ssi_nam": 10, "ssi_pdr": 10, "ssiinfocount": 10, "ssl": 12, "stabl": 10, "stage": [2, 7, 8], "stamp": 10, "standard": 1, "standardoutput": 7, "standbi": 3, "start": [1, 2, 3, 6, 7, 9, 11], "start_cylind": 10, "startup": 12, "stat": 1, "state": [1, 3], "statement": [2, 8], "static": 1, "statist": 10, "statment": 10, "statu": [2, 3, 7, 8, 9, 10, 12], "status_cod": 3, "step": [7, 8, 11, 12], "step1": 7, "stop": [1, 2, 7, 12], "storag": [3, 5], "store": [2, 7, 10, 11, 12], "stream": [1, 10], "string": [2, 3, 10], "strongli": 12, "su": 8, "subchannel": 9, "subfunct": 3, "subfunction_nam": 3, "subsequ": 7, "success": [10, 12], "successfulli": [7, 8, 10], "sudo": [7, 8], "sudoer": 8, "suffix": [2, 3, 10], "support": [1, 2, 3, 4, 5, 7, 8, 10], "sure": [1, 2, 4, 7, 8], "suse": 8, "suseconnect": 8, "swap": [2, 3, 10], "swap_default_with_mdisk": 2, "swap_force_mdisk": 2, "switch": [1, 5, 7], "switch_nam": 10, "switch_statu": 10, "switch_typ": 10, "sy": 3, "symbol": 10, "syslog": [7, 12], "system": [2, 3, 5, 8, 9, 10, 12], "system_info": 7, "systemctl": [7, 8, 12], "systemd": [7, 8, 12], "sysvinit": 7, "t": [2, 3, 4, 7, 8, 10, 12], "tabl": [2, 8, 9, 10], "tag": [7, 10], "tailor": 7, "take": [2, 7, 10, 12], "talk": [7, 12], "tar": 7, "target": [7, 8, 10, 12], "target_lun": 10, "target_wwpn": 10, "task": 7, "tcp": [8, 12], "tell": 2, "templat": 3, "temporari": 12, "term": 12, "test": [7, 9, 10, 12], "test0045": 10, "testfil": 10, "testid": 10, "testpool": 2, "testvsw": 10, "text": [3, 8, 12], "tgz": [1, 10], "than": [2, 3, 7, 8, 10], "thei": [7, 8], "them": [3, 7], "thi": [2, 3, 4, 6, 7, 8, 9, 10, 11, 12], "thing": 8, "think": [10, 12], "those": 10, "thread": [2, 12], "three": [10, 12], "through": [1, 2, 3, 5, 8, 10, 12], "thu": [2, 5, 8], "thunder": 12, "time": [2, 3, 7, 10, 12], "timeout": [2, 3, 7, 12], "timeoutsec": 7, "timestamp": 3, "timezon": 7, "tliikhsq1a": 12, "tmp": [10, 12], "tmpfile": 7, "token": [1, 2, 3, 6, 7], "token_path": [2, 12], "token_validation_period": 2, "too": 3, "tool": [5, 7, 8, 12], "top": 5, "topic": 7, "total": [2, 10], "total_memori": 10, "totalfail": 10, "totalsuccess": 10, "touch": 7, "track": 9, "tracker": 5, "tradit": 12, "traffic": 10, "transfer": [2, 3], "transit": 8, "transmit": [7, 10], "transport": [3, 10], "transport_typ": 10, "transportfil": [3, 10], "trigger": [8, 11], "true": [2, 7, 9, 10, 11, 12], "trunk": 10, "trust": 8, "try": [2, 7, 12], "tue": 12, "turn": [2, 10], "tvlcqb_quupj37cryzzqror6klz": 12, "two": [2, 8], "type": [1, 2, 3, 7, 8, 9, 10, 11, 12], "type1": 10, "u": [7, 8, 10, 12], "ub160120": 10, "ub160120_1009": 10, "ubuntu16": 10, "ubuntu20": 10, "ubuntu22": 10, "uid": [8, 12], "ultgut0200": 3, "ultgut0201": 3, "ultgut0202": 3, "ultgut0203": 3, "ultgut0204": 3, "ultgut0400": 3, "ultgut0401": 3, "ultgut0402": 3, "ultgut0403": 3, "ultgut0404": 3, "ultgut0405": 3, "ultgut0406": 3, "ultgut0407w": 3, "ultgut0408": 3, "ultgut0409": 3, "ultgut0410": 3, "ultgut0411": 3, "ultgut0412": 3, "ultgut0413": 3, "ultgut0414": 3, "ultgut0415": 3, "ultgut0416": 3, "ultgut0417": 3, "ultgut0418": 3, "ultgut0419": 3, "ultgut0420": 3, "ultgut0421": 3, "ultgut0422w": 3, "ultgut0423w": 3, "ultgut0424": 3, "ultgut0501": 3, "ultmvm0205": 3, "ultmvm0206": 3, "ultmvm0207": 3, "ultrqh0001": 3, "ultrqh0002": 3, "ultrqh0003": 3, "ultrqh0004": 3, "ultrqh0005": 3, "ultrqh0006": 3, "ultrqh0007": 3, "ultrqh0008": 3, "ultrqh0009": 3, "ultrqh0010": 3, "ultrqh0011": 3, "ultrqh0012": 3, "ultrqh0014": 3, "ultrqh0015": 3, "ultrqh0016": 3, "ultrqh0017w": 3, "ultsmp0300": 3, "ultsmp0301": 3, "ultsmp0302": 3, "ultsmp0303": 3, "ultsmp0304": 3, "ultsmp0305": 3, "ultsmp0311": 3, "ultsmp0312": 3, "ultsmp0313": 3, "ultsmp0314": 3, "ultsmp0315": 3, "ultsmp0316": 3, "ultsmp0317": 3, "ultsmp0318": 3, "ultsmp0319": 3, "ultsmp0320": 3, "umount": 8, "unabl": 3, "unavail": 3, "unawar": 10, "uncoupl": [1, 3, 10], "under": [5, 6, 7, 8, 12], "unexpect": 3, "uniqu": 10, "unit": [3, 7, 10, 12], "unknown": 3, "unmount": 9, "unpack_rc": 3, "unpackdiskimag": [3, 8], "unpaus": 1, "unplug": 1, "unrecogn": 3, "unspecifi": 10, "untag": 10, "untar": 7, "until": 2, "up": [2, 3, 7, 11], "updat": [1, 2, 3, 7, 8, 11, 12], "update_etc_host": 7, "update_hostnam": 7, "upgrad": [1, 5, 7], "upload": 1, "upper": [5, 8, 11], "upstart": 7, "url": [3, 7, 10], "us": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 12], "usabl": 8, "usag": [2, 6, 7, 8], "used_cpu_time_u": 10, "used_mem_kb": 10, "usedn": 7, "user": [1, 2, 3, 4, 5, 7, 8, 11, 12], "user1": 10, "user_default_max_cpu": [2, 8, 10], "user_default_max_memori": [2, 8, 10], "user_default_max_reserved_memori": 2, "user_default_password": 2, "user_default_share_unit": 2, "user_direct": 10, "user_port_bas": 10, "user_profil": [2, 8, 10, 11], "user_root_vdev": [2, 7, 10], "user_vlan_id": 10, "useradd": [7, 8], "userbas": 10, "userid": [2, 3, 7, 10, 11], "usermod": 8, "usernam": [2, 10, 12], "userwarn": 7, "usestackfram": 7, "usr": [7, 8, 12], "usual": [7, 10, 12], "utf": [1, 12], "util": [2, 11], "uwsgi": 6, "v": [9, 12], "v1": 10, "v2": 10, "valid": [1, 2, 3, 10], "valid_stat": 3, "valid_subfunct": 3, "valu": [2, 3, 4, 7, 8, 10, 12], "var": [2, 7, 8, 10, 12], "varchar": 8, "variabl": 7, "variou": 5, "vcpu": [2, 9, 10, 11], "vcpus_us": 10, "vdev": [3, 7, 10], "vdev_info": 10, "vdev_list": 10, "vdisk": [2, 3], "vendor": [8, 12], "verif": 6, "verifi": [7, 8, 12], "version": [3, 6, 7, 8, 12], "vhost": 12, "via": [3, 7, 8, 12], "vid": 10, "video": 7, "violat": 5, "virtual": [1, 2, 3, 4, 5, 8, 10, 12], "virtualhost": 12, "vlan": [1, 10], "vlan_awar": 10, "vlan_count": 10, "vlan_id": 10, "vm": [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12], "vm6018": 10, "vm66120": 1, "vmcp": [8, 9], "vmpool": 11, "vmrdr": 8, "vmur": [3, 8], "vnic": [1, 10], "vol": 3, "vol1": [9, 10], "vol2": 10, "volum": [0, 1, 2, 3, 6, 7, 9], "volume_label": 10, "volume_nam": 10, "volume_refresh_bootmap": 10, "volume_s": 10, "volume_typ": 10, "volumelabel": 2, "volumenam": 10, "vs_name": 10, "vsc11590": 10, "vsmwork1": [2, 8], "vstest": 10, "vsw": 3, "vsw01": 10, "vswitch": [1, 3, 6], "vswitch1": 2, "vswitch2": 2, "vswitch_nam": 10, "vtoc": 9, "w": [9, 10], "wa": [3, 8, 9], "wai": [8, 12], "wait": [2, 3], "walk": 12, "want": [2, 4, 7, 8, 12], "wantedbi": [7, 12], "warn": [2, 7, 8, 9], "warnin": 2, "we": [8, 12], "web": 6, "wed": 12, "well": [7, 8, 12], "went": 8, "were": [3, 10], "wget": 8, "what": [2, 6, 12], "when": [1, 2, 3, 7, 8, 10, 12], "where": [2, 7, 8, 9, 10], "whether": [2, 10], "which": [1, 2, 7, 8, 9, 10, 12], "while": [2, 3, 7, 8, 12], "who": 2, "whole": [2, 8, 10], "wick": 7, "wide": 10, "wish": 7, "within": 7, "without": [1, 5, 8, 10], "won": 7, "word": [3, 12], "word1": 3, "word2": 3, "word3": 3, "work": [2, 7, 8, 12], "worker": [2, 3, 12], "workflow": 6, "workload": [2, 8], "workstat": 12, "world": 10, "would": [2, 7, 8, 10], "write": [2, 7, 8, 12], "written": [2, 5, 8], "wsgi": [2, 8, 12], "wsgidaemonprocess": 12, "wsgiprocessgroup": 12, "wsgiscriptalia": 12, "wsgiserv": 12, "wss": 8, "wwpn": 10, "wwpn_npiv": 8, "wwpn_phy": 8, "www": [7, 8], "x": [2, 10, 11, 12], "x3270": 4, "xcat": 7, "xf": [3, 8, 10], "xubuntu_24": [8, 12], "xx": 10, "xxx": [2, 10], "xxxx": 8, "ye": [7, 10], "you": [2, 4, 5, 7, 8, 9, 10, 12], "your": [2, 7, 8, 9, 10, 12], "your_config": 12, "yum": [7, 8, 12], "z": [0, 1, 2, 3, 5, 6, 10, 11, 12], "zcc": 10, "zcc_userid": 10, "zccuid": 10, "zero": 2, "zlinux": 6, "zlinux_ip": 7, "zlinux_userid": 7, "zthin": [7, 12], "zvm": [2, 3, 4, 5, 7, 8, 9, 10], "zvm2ssi": 10, "zvm_fcp": 10, "zvm_host": 10, "zvmcloudconnector": 1, "zvmconnector": 11, "zvmguestconfigureconf4z": 7, "zvmsdk": [2, 3, 4, 7, 8, 10, 12], "zvmsdk_path": 7, "zvmsdk_wsgi": 12, "zvmsdkwsgi": 12, "zxvf": 7, "zypper": [7, 8, 12]}, "titles": ["2. Introduction", "12. Release Notes", "9. Configuration Options", "8. Error Codes and Messages", "11. General info", "1. General info", "Welcome to the Feilong Document", "5. Image and cloud-init Configuration", "3. Quick Start", "10. Resize Image to a Bigger Size", "7. RESTful APIs", "6. Basic Usage", "4. Setup web server for running RESTful API"], "titleterms": {"": 10, "0": 1, "04": 7, "1": [1, 7], "12": 7, "16": 7, "2": 1, "20": 7, "3": 1, "3270": 4, "4": 1, "6": 7, "7": 7, "adapt": 10, "add": 10, "address": 4, "alma": 8, "apach": 12, "apache2": 12, "api": [10, 12], "architectur": 0, "attach": 10, "authent": 8, "base": 10, "basic": 11, "between": 8, "bigger": 9, "bootmap": 10, "bug": 5, "byol": 8, "captur": [7, 10], "chang": 4, "client": 12, "cloud": 7, "cluster": 10, "code": 3, "command": 11, "compat": 5, "configur": [2, 7, 8, 10, 12], "connect": 12, "connector": 10, "consol": 10, "consum": 8, "content": 5, "cpu": 10, "creat": [10, 11], "daemon": 8, "data": 10, "deb": 8, "default": 4, "definit": 10, "delet": 10, "deploi": 10, "deploy": 7, "deprec": 5, "deregist": 10, "descript": 11, "detach": 10, "detail": 10, "direct": 10, "disk": 10, "document": 6, "enterpris": 12, "error": 3, "exampl": [0, 11], "export": 10, "faq": 4, "fcp": 10, "feilong": [0, 6, 7, 10, 12], "file": 10, "flow": 9, "from": [10, 11, 12], "gener": [4, 5, 7], "get": 10, "grant": 10, "grow": 10, "guest": 10, "health": 10, "host": 10, "hypervisor": 10, "i": 0, "id": 10, "imag": [7, 9, 10], "import": [7, 10], "includ": 10, "info": [4, 5, 10], "inform": 10, "init": 7, "instal": [7, 8, 12], "integr": 0, "interfac": 10, "intern": 0, "introduct": [0, 12], "iucv": 7, "kei": 8, "languag": 11, "licens": 5, "line": 11, "linux": [7, 12], "list": 10, "live": 10, "log": 4, "machin": [7, 11], "make": 7, "manual": 8, "memori": 10, "messag": 3, "migrat": 10, "minidisk": 10, "mod_wsgi": 12, "name": 10, "network": 10, "nic": [4, 10], "note": 1, "ob": 8, "option": 2, "output": 10, "packag": [5, 8, 12], "paus": 10, "pcom": 4, "pool": 10, "port": 10, "power": 10, "pre": 8, "prepar": 8, "python": 11, "question": 5, "quick": 8, "reboot": 10, "redhat": 12, "refresh": 10, "regist": 10, "releas": 1, "report": [5, 10], "requir": [7, 8], "reset": 10, "resiz": [9, 10], "respons": 10, "rest": [10, 12], "revok": 10, "rhel": [7, 8], "rhel6": 7, "rhel8": 7, "rocki": 8, "root": 10, "rpm": 8, "run": 12, "sampl": 8, "sdk": 8, "secur": 12, "server": [8, 12], "servic": [7, 12], "set": 10, "setup": [8, 12], "show": 10, "side": 12, "size": [9, 10], "sle": [7, 8], "sles11": 7, "sles15": 7, "smapi": 10, "softstop": 10, "spawn": 11, "ssh": 8, "ssi": 10, "start": [8, 10, 12], "stat": 10, "state": 10, "stop": 10, "suse": 12, "switch": 10, "system": 7, "termin": 4, "thi": 5, "through": 4, "token": [10, 12], "ubuntu": [7, 8, 12], "unpaus": 10, "updat": 10, "upgrad": 8, "us": 8, "usag": [10, 11], "user": 10, "uwsgi": 12, "verif": [8, 12], "version": [5, 10], "virtual": [7, 11], "vlanid": 10, "vm": 8, "volum": 10, "vswitch": [10, 11], "web": 12, "welcom": 6, "what": 0, "workflow": 11, "x": 7, "z": [7, 8], "zlinux": 7, "zthin": 8, "zvmguestconfigur": 7}}) \ No newline at end of file diff --git a/doc/html/setuphttpd.html b/doc/html/setuphttpd.html new file mode 100644 index 000000000..fcf3307ec --- /dev/null +++ b/doc/html/setuphttpd.html @@ -0,0 +1,538 @@ + + + + + + + + 4. Setup web server for running RESTful API — Feilong 1.6.7 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

4. Setup web server for running RESTful API

+
+

4.1. Introduction

+

Each Feilong API is exposed through a RESTful interface, higher level +systems can manage z/VM by consuming these RESTful APIs directly.

+

This chapter describes how to setup a web server for hosting the Feilong RESTful APIs.

+

The recommended deployment for Feilong is to have a web server such as +Apache httpd or nginx handle the HTTP connections and proxy requests to the independent +z/VM SDK server running under a wsgi container such as uwsgi +or directly connected via Apache’s wsgi module.

+

The detailed setup steps for each type of web server is out of this document’s range, +you can refer to the specific guide of your chosen web server. This guide walks you through +the deployment process, either:

+
+
    +
  • with premade packages (which use the mod_wsgi method);

  • +
  • manually, with uwsgi;

  • +
  • or manually, with Apache’s mod_wsgi.

  • +
+
+

This matrix represents the successful setup of different web servers across three Linux distributions. +The last section of this chapter details about using tokens to enhance security.

+ + + + + + + + + + + + + + + + + + + + + + + + + +

Tested

RHEL 9.4

SLES 15 SP6

Ubuntu 24.04

Apache2 + uwsgi

Apache2 + mod_wsgi

nginx + uwsgi

+
+
+

4.2. Installing from packages

+
+

4.2.1. Redhat Enterprise Linux

+

The following instructions are for RHEL 9.4. +The RPM packages can be downloaded from https://download.opensuse.org/repositories/Virtualization:/feilong/AlmaLinux_9/ .

+

Install the downloaded packages zthin and zvmsdk using the yum or dnf command +If not already done, enable the automatic startup of the Apache server, and then start it:

+

..code-block:: text

+
+

# systemctl enable httpd +# systemctl start httpd

+
+

Finally, you can verify if the installation works as intended by making a curl request from your workstation

+

..code-block:: text

+
+

$ curl http://<your server ip address>:8080/

+
+

By default, Feilong will listen on port 8080. +To change that, you need to modify both Apache configuration and firewall rules.

+
+
+

4.2.2. SUSE Linux Enterprise Server

+

The following instructions are for SLES15 SP6. +The RPM packages can be downloaded from https://download.opensuse.org/repositories/Virtualization:/feilong/SLE_15_SP5/

+

Install the downloaded packages using the zypper command +If not already done, enable the automatic startup of the Apache server, and then start it:

+

..code-block:: text

+
+

# systemctl enable apache2 +# systemctl start apache2

+
+

Finally, you can verify if the installation works as intended by making a curl request from your workstation

+

..code-block:: text

+
+

$ curl http://<your server ip address>:8080/

+
+

By default, Feilong will listen on port 8080. +To change that, you need to modify both Apache configuration and firewall rules.

+
+
+

4.2.3. Ubuntu

+

The following instructions are for Ubuntu 24.04. +The RPM packages can be downloaded from https://download.opensuse.org/repositories/Virtualization:/feilong/xUbuntu_24.04/

+

Install the downloaded packages using the apt command +If not already done, enable the automatic startup of the Apache server, and then start it:

+

..code-block:: text

+
+

# systemctl enable apache2 +# systemctl start apache2

+
+

Finally, you can verify if the installation works as intended by making a curl request from your workstation

+

..code-block:: text

+
+

$ curl http://<your server ip address>:8080/

+
+

By default, Feilong will listen on port 8080. +To change that, you need to modify both Apache configuration and firewall rules.

+
+
+
+

4.3. Apache2 + uwsgi

+
+

4.3.1. Installation

+

The following packages need to be installed:

+
    +
  • Apache httpd server

  • +
  • Apache modules: mod_proxy_uwsgi

  • +
  • uwsgi

  • +
  • uwsgi plugin for python: uwsgi-plugin-python

  • +
+
+
+

4.3.2. Configure uwsgi

+

Usually the configuration can be placed at /etc/uwsgi.d/ folder, for example, named as +/etc/uwsgi.d/your_config.ini. Update the file to match your system configuration.

+

The sample below indicated the uwsgi service will be running at port 35000 +so apache server can connect port 35000 and communicate with it

+
[uwsgi]
+chmod-socket = 666
+uwsgi-socket = 127.0.0.1:35000
+lazy-apps = true
+add-header = Connection: close
+buffer-size = 65535
+thunder-lock = true
+plugins = python
+enable-threads = true
+exit-on-reload = true
+die-on-term = true
+master = true
+processes = 2
+threads = 32
+wsgi-file = /usr/bin/zvmsdk-wsgi
+pidfile = /tmp/zvmsdk-wsgi.pid
+socket = /tmp/zvmsdk-wsgi.socket
+uid = zvmsdk
+gid = zvmsdk
+logto = /var/log/zvmsdk/uwsgi.log
+
+
+
+
+

4.3.3. Start Feilong in uwsgi

+
    +
  • Create a uwsgi service

    +

    Use following sample to create a uwsgi service for running the Feilong. +For RHEL7.2, put this file as /usr/lib/systemd/system/zvmsdk-wsgi.service.

    +
    [Unit]
    +Description=Feilong uwsgi
    +After=syslog.target network.target httpd.service
    +
    +[Service]
    +Type=simple
    +ExecStart=/usr/sbin/uwsgi --ini /etc/uwsgi.d/your_config.ini
    +ExecReload=/usr/sbin/uwsgi --reload /etc/uwsgi.d/your_config.ini
    +ExecStop=/usr/sbin/uwsgi --stop /etc/uwsgi.d/your_config.ini
    +
    +[Install]
    +WantedBy=multi-user.target
    +
    +
    +
  • +
  • Enable zvmsdk uwsgi service

    +
    #systemctl enable zvmsdk-wsgi.service
    +
    +
    +
  • +
  • Start zvmsdk uwsgi service

    +
    #systemctl start zvmsdk-wsgi.service
    +
    +
    +
  • +
  • Verify zvmsdk uwsgi service status

    +

    Verify the zvmsdk uwsgi service is started normally and the status is active (running) +in the following command output.

    +
    [root@0822rhel7 ~]# systemctl status zvmsdk-wsgi.service
    +● zvmsdk-wsgi.service - Feilong uwsgi
    +   Loaded: loaded (/usr/lib/systemd/system/zvmsdk-wsgi.service; disabled; vendor preset: disabled)
    +   Active: active (running) since Tue 2017-11-21 21:58:06 EST; 13min ago
    + Main PID: 7227 (uwsgi)
    +   CGroup: /system.slice/zvmsdk-wsgi.service
    +           ├─7227 /usr/sbin/uwsgi --ini /etc/uwsgi.d/zvmsdk-wsgi.ini
    +           ├─7229 /usr/sbin/uwsgi --ini /etc/uwsgi.d/zvmsdk-wsgi.ini
    +           └─7230 /usr/sbin/uwsgi --ini /etc/uwsgi.d/zvmsdk-wsgi.ini
    +
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: your server socket listen backlog is limited to 100 connections
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: your mercy for graceful operations on workers is 60 seconds
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: mapped 402621 bytes (393 KB) for 2 cores
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: *** Operational MODE: preforking ***
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: *** uWSGI is running in multiple interpreter mode ***
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: spawned uWSGI master process (pid: 7227)
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: spawned uWSGI worker 1 (pid: 7229, cores: 1)
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: spawned uWSGI worker 2 (pid: 7230, cores: 1)
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: *** no app loaded. going in full dynamic mode ***
    +Nov 21 21:58:06 0822rhel7 uwsgi[7227]: *** no app loaded. going in full dynamic mode ***
    +
    +
    +

    And the uwsgi process is listenning on port 35000:

    +
    # netstat -anp | grep 35000
    +tcp        0      0 127.0.0.1:35000         0.0.0.0:*               LISTEN      7227/uwsgi
    +
    +# curl -v http://127.0.0.1:35000/
    +* About to connect() to 127.0.0.1 port 35000 (#0)
    +*   Trying 127.0.0.1...
    +* Connected to 127.0.0.1 (127.0.0.1) port 35000 (#0)
    +> GET / HTTP/1.1
    +> User-Agent: curl/7.29.0
    +> Host: 127.0.0.1:35000
    +> Accept: */*
    +>
    +* Empty reply from server
    +* Connection #0 to host 127.0.0.1 left intact
    +curl: (52) Empty reply from server
    +
    +
    +
  • +
+
+
+

4.3.4. Configure Apache

+

Use the following sample as a start for apache to proxy requests to Feilong +wsgi service, copy the content to /etc/httpd/conf.d/zvmsdk.conf and update the file to match +your system and requirements.

+
+

Note

+

Sometimes the REST API call will takes some time to complete while the default timeout +is not enough to complete the handle of the request, for example, Apache Timeout +shows the default timeout value of Apache httpd server is 60, administrator need to +set a bigger value (for example 3600) to avoid time out error.

+
+

Under this sample’s configuration settings, the httpd server will listen on port 8080 +and any incoming request on it will be redirected to zvmsdk wsgi which is listening +at port 35000

+
LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so
+
+Listen 8080
+
+<VirtualHost *:8080>
+   ProxyPass / uwsgi://127.0.0.1:35000/
+</VirtualHost>
+
+
+

SSL is strongly recommended for security considerations. Refer to the specific web server +documentation on how to enable SSL.

+
+
+

4.3.5. Start Apache service

+
#systemctl start httpd.service
+
+
+
+
+

4.3.6. Verification

+

Verify your settings after restart httpd servers (assume you are using above +configurations), if are you able to see similar output below, it means the zvmsdk +http service is running well.

+
# curl http://localhost:8080/
+{"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": {"min_version": "1.0", "version": "1.0", "max_version": "1.0"}, "errmsg": ""}
+
+
+
+
+
+

4.4. Apache2 + mod_wsgi

+
+

4.4.1. Installation

+

The following packages need to be installed:

+
    +
  • apache2

  • +
  • libapache2-mod-wsgi

  • +
+
+
+

4.4.2. Configuration

+

Create a vhost for Feilong in Apache. Copy the following content to +/etc/apache2/sites-available/zvmsdk_wsgi.conf and update the file to match your system and requirements.

+

Then execute command “a2ensite zvmsdk_wsgi” to enable the site.

+
Listen 8080
+<VirtualHost *:8080>
+    WSGIDaemonProcess zvmsdkwsgi user=zvmsdk group=zvmsdk processes=2 threads=5
+        WSGIProcessGroup zvmsdkwsgi
+
+    WSGIScriptAlias / /usr/bin/zvmsdk-wsgi
+    <Directory /usr/lib/python2.7/dist-packages/zvmsdk/sdkwsgi>
+        Require all granted
+    </Directory>
+
+    <Directory /usr/bin>
+    <Files zvmsdk-wsgi>
+        Require all granted
+    </Files>
+    </Directory>
+</VirtualHost>
+
+
+

SSL is strongly recommended for security considerations. Refer to the specific web server +documentation on how to enable SSL.

+
    +
  • Start Apache service

    +
    #systemctl start apache2.service
    +
    +
    +
  • +
+
+
+

4.4.3. Verification

+

Verify your settings after restart httpd servers (assume you are using above +configurations), if are you able to see similar output below, it means the zvmsdk +http service is running well.

+
# curl http://localhost:8080/
+{"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": {"min_version": "1.0", "version": "1.0", "max_version": "1.0"}, "errmsg": ""}
+
+
+
+
+
+

4.5. Securing Connections with Tokens

+

When you sending requests, you can use token authenticaion to enhance security of the connection between client and server. +Feilong use admin-token to authicate the safety of the connection instead of username&password. +In other words, admin-token is what you can think as a combination of traditional username&password.

+

On client side, users should use this admin-token to request for a temporary token first. Then users can use +this temporary token to send requests.

+

On server side, admninistrators are responsible for creating admin-token file. The admin-token will be stored +in this file. Users can get admin-token by contacting administrator.

+
+

4.5.1. Setup Server Side

+
    +
  • Create admin-token file

    +

    Administrators can use zvmsdk-gentoken tool to create admin-token file.

    +

    Fox example, initialize one token file:

    +
    # /usr/bin/zvmsdk-gentoken
    +
    +
    +

    zvmsdk-gentoken use /etc/zvmsdk/token.dat as default path of token file. You can also specify your own token file path:

    +
    # /usr/bin/zvmsdk-gentoken /new/path/of/token/file
    +
    +
    +

    The commands above will initialize one token file and write a random admin-token into it.

    +

    This tool can also help you update the content of token file:

    +
    # /usr/bin/zvmsdk-gentoken -u
    +
    +
    +

    If you don’t assign a file path, zvmsdk-gentoken will update the file of default token path. You can update specified +file by this way:

    +
    # /usr/bin/zvmsdk-gentoken -u /new/path/of/token/file
    +
    +
    +

    NOTE: please remember to change token file’s owner to user zvmsdk after operating it.

    +
  • +
  • Update Configuration file

    +

    After creating admin-token file, configuration should be updated to let the server know the path of token file.

    +

    In configuration file, you can assign token file path by change the value of token_path which is in wsgi section.

    +

    What’s more, you should let server know we have changed the way of authentication by setting value of auth item +in the wsgi section to token, just like auth=token.

    +

    If you want to disable token authentication, just change auth to value none.

    +
  • +
+
+
+

4.5.2. Setup Client Side

+
+

On client side, you need to get the admin-token stored in the admin-token file. Just As what we have talked above, +admin-token file is generated on server side. Users should contact the administrator for admin-token before sending +requests. Then users can put the admin_token into the X-Admin-Token field in headers of request object for +passing the authentication.

+

An example to request for a token:

+
# curl http://localhost:8080/token -X POST -i -H "Content-Type:application/json" -H "X-Admin-Token:1234567890123456789012345678901234567890"
+HTTP/1.0 200 OK
+Date: Wed, 06 Dec 2017 06:11:22 GMT
+Server: WSGIServer/0.1 Python/2.7.5
+Content-Type: text/html; charset=UTF-8
+Content-Length: 0
+X-Auth-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTI1NDQyODJ9.TVlcQb_QuUPJ37cRyzZqroR6kLZ-5zH2-tliIkhsQ1A
+cache-control: no-cache
+
+
+

You can see the temporary token is in the X-Auth-Token field.

+

Then you can send normal RESTful requests using this temporary token to pass the authentication.

+

For example:

+
# curl http://localhost:8080/ -H "Content-Type:application/json" -H 'X-Auth-Token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTI1NDQyODJ9.TVlcQb_QuUPJ37cRyzZqroR6kLZ-5zH2-tliIkhsQ1A'
+{"rs": 0, "overallRC": 0, "modID": null, "rc": 0, "output": {"min_version": "1.0", "version": "1.0", "max_version": "1.0"}, "errmsg": ""}
+
+
+
+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/source/errorcodemsg.rst b/doc/source/errorcodemsg.rst index 9d180b0a7..0c4ebe480 100644 --- a/doc/source/errorcodemsg.rst +++ b/doc/source/errorcodemsg.rst @@ -9,7 +9,7 @@ This is a reference to Feilong API error codes and messages. .. csv-table:: - :header: "overallRC", "modID", "rc", "rs", "errmsg" + :header: "overallRC";"modID";"rc";"rs";"errmsg" :delim: ; - :widths: 20,5,5,5,65 + :widths: 20,10,5,5,65 :file: errcode.csv