diff --git a/docs/composer-cli.rst b/docs/composer-cli.rst index f63bd023..8bbf1cca 100644 --- a/docs/composer-cli.rst +++ b/docs/composer-cli.rst @@ -24,15 +24,15 @@ Edit a Blueprint Start out by listing the available blueprints using ``composer-cli blueprints list``, pick one and save it to the local directory by running ``composer-cli -blueprints save http-server``. If there are no blueprints available you can -copy one of the examples `from the test suite -`_. +blueprints save http-server``. Edit the file (it will be saved with a .toml extension) and change the description, add a package or module to it. Send it back to the server by running ``composer-cli blueprints push http-server.toml``. You can verify that it was saved by viewing the changelog - ``composer-cli blueprints changes http-server``. +See the `Example Blueprint`_ for an example. + Build an image ---------------- @@ -199,3 +199,343 @@ end with a failed state. ``--test=2`` will cause a compose to start and then end with a finished state, without actually composing anything. + + +Blueprint Reference +=================== + +Blueprints +---------- + +Blueprints are simple text files in `TOML `_ format that describe +which packages, and what versions, to install into the image. They can also define a limited set +of customizations to make to the final image. + +A basic blueprint looks like this:: + + name = "base" + description = "A base system with bash" + version = "0.0.1" + + [[packages]] + name = "bash" + version = "4.4.*" + +The ``name`` field is the name of the blueprint. It can contain spaces, but they will be converted to ``-`` +when it is written to disk. It should be short and descriptive. + +``description`` can be a longer description of the blueprint, it is only used for display purposes. + +``version`` is a `semver compatible `_ version number. If +a new blueprint is uploaded with the same ``version`` the server will +automatically bump the PATCH level of the ``version``. If the ``version`` +doesn't match it will be used as is. eg. Uploading a blueprint with ``version`` +set to ``0.1.0`` when the existing blueprint ``version`` is ``0.0.1`` will +result in the new blueprint being stored as ``version 0.1.0``. + +[[packages]] and [[modules]] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These entries describe the package names and matching version glob to be installed into the image. + +The names must match the names exactly, and the versions can be an exact match +or a filesystem-like glob of the version using ``*`` wildcards and ``?`` +character matching. + +.. note:: + Currently there are no differences between ``packages`` and ``modules`` + in ``osbuild-composer``. Both are treated like an rpm package dependency. + +For example, to install ``tmux-2.9a`` and ``openssh-server-8.*``, you would add +this to your blueprint:: + + [[packages]] + name = "tmux" + version = "2.9a" + + [[packages]] + name = "openssh-server" + version = "8.*" + + + +[[groups]] +~~~~~~~~~~ + +The ``groups`` entries describe a group of packages to be installed into the image. Package groups are +defined in the repository metadata. Each group has a descriptive name used primarily for display +in user interfaces and an ID more commonly used in kickstart files. Here, the ID is the expected +way of listing a group. + +Groups have three different ways of categorizing their packages: mandatory, default, and optional. +For purposes of blueprints, mandatory and default packages will be installed. There is no mechanism +for selecting optional packages. + +For example, if you want to install the ``anaconda-tools`` group you would add this to your +blueprint:: + + [[groups]] + name="anaconda-tools" + +``groups`` is a TOML list, so each group needs to be listed separately, like ``packages`` but with +no version number. + + +Customizations +~~~~~~~~~~~~~~ + +The ``[customizations]`` section can be used to configure the hostname of the final image. eg.:: + + [customizations] + hostname = "baseimage" + +This is optional and may be left out to use the defaults. + + +[customizations.kernel] +*********************** + +This allows you to append arguments to the bootloader's kernel commandline. This will not have any +effect on ``tar`` or ``ext4-filesystem`` images since they do not include a bootloader. + +For example:: + + [customizations.kernel] + append = "nosmt=force" + + +[[customizations.sshkey]] +************************* + +Set an existing user's ssh key in the final image:: + + [[customizations.sshkey]] + user = "root" + key = "PUBLIC SSH KEY" + +The key will be added to the user's authorized_keys file. + +.. warning:: + + ``key`` expects the entire content of ``~/.ssh/id_rsa.pub`` + + +[[customizations.user]] +*********************** + +Add a user to the image, and/or set their ssh key. +All fields for this section are optional except for the ``name``, here is a complete example:: + + [[customizations.user]] + name = "admin" + description = "Administrator account" + password = "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31L..." + key = "PUBLIC SSH KEY" + home = "/srv/widget/" + shell = "/usr/bin/bash" + groups = ["widget", "users", "wheel"] + uid = 1200 + gid = 1200 + +If the password starts with ``$6$``, ``$5$``, or ``$2b$`` it will be stored as +an encrypted password. Otherwise it will be treated as a plain text password. + +.. warning:: + + ``key`` expects the entire content of ``~/.ssh/id_rsa.pub`` + + +[[customizations.group]] +************************ + +Add a group to the image. ``name`` is required and ``gid`` is optional:: + + [[customizations.group]] + name = "widget" + gid = 1130 + + +[customizations.timezone] +************************* + +Customizing the timezone and the NTP servers to use for the system:: + + [customizations.timezone] + timezone = "US/Eastern" + ntpservers = ["0.north-america.pool.ntp.org", "1.north-america.pool.ntp.org"] + +The values supported by ``timezone`` can be listed by running ``timedatectl list-timezones``. + +If no timezone is setup the system will default to using `UTC`. The ntp servers are also +optional and will default to using the distribution defaults which are fine for most uses. + +In some image types there are already NTP servers setup, eg. Google cloud image, and they +cannot be overridden because they are required to boot in the selected environment. But the +timezone will be updated to the one selected in the blueprint. + + +[customizations.locale] +*********************** + +Customize the locale settings for the system:: + + [customizations.locale] + languages = ["en_US.UTF-8"] + keyboard = "us" + +The values supported by ``languages`` can be listed by running ``localectl list-locales`` from +the command line. + +The values supported by ``keyboard`` can be listed by running ``localectl list-keymaps`` from +the command line. + +Multiple languages can be added. The first one becomes the +primary, and the others are added as secondary. One or the other of ``languages`` +or ``keyboard`` must be included (or both) in the section. + + +[customizations.firewall] +************************* + +By default the firewall blocks all access except for services that enable their ports explicitly, +like ``sshd``. This command can be used to open other ports or services. Ports are configured using +the port:protocol format:: + + [customizations.firewall] + ports = ["22:tcp", "80:tcp", "imap:tcp", "53:tcp", "53:udp"] + +Numeric ports, or their names from ``/etc/services`` can be used in the ``ports`` enabled/disabled lists. + +The blueprint settings extend any existing settings in the image templates, so if ``sshd`` is +already enabled it will extend the list of ports with the ones listed by the blueprint. + +If the distribution uses ``firewalld`` you can specify services listed by ``firewall-cmd --get-services`` +in a ``customizations.firewall.services`` section:: + + [customizations.firewall.services] + enabled = ["ftp", "ntp", "dhcp"] + disabled = ["telnet"] + +Remember that the ``firewall.services`` are different from the names in ``/etc/services``. + +Both are optional, if they are not used leave them out or set them to an empty list ``[]``. If you +only want the default firewall setup this section can be omitted from the blueprint. + +NOTE: The ``Google`` and ``OpenStack`` templates explicitly disable the firewall for their environment. +This cannot be overridden by the blueprint. + +[customizations.services] +************************* + +This section can be used to control which services are enabled at boot time. +Some image types already have services enabled or disabled in order for the +image to work correctly, and cannot be overridden. eg. ``ami`` requires +``sshd``, ``chronyd``, and ``cloud-init``. Without them the image will not +boot. Blueprint services are added to, not replacing, the list already in the +templates, if any. + +The service names are systemd service units. You may specify any systemd unit +file accepted by ``systemctl enable`` eg. ``cockpit.socket``:: + + [customizations.services] + enabled = ["sshd", "cockpit.socket", "httpd"] + disabled = ["postfix", "telnetd"] + + +[[repos.git]] +~~~~~~~~~~~~~ + +.. note:: + Currently ``osbuild-composer`` does not support ``repos.git`` + +The ``[[repos.git]]`` entries are used to add files from a `git repository `_ +repository to the created image. The repository is cloned, the specified ``ref`` is checked out +and an rpm is created to install the files to a ``destination`` path. The rpm includes a summary +with the details of the repository and reference used to create it. The rpm is also included in the +image build metadata. + +To create an rpm named ``server-config-1.0-1.noarch.rpm`` you would add this to your blueprint:: + + [[repos.git]] + rpmname="server-config" + rpmversion="1.0" + rpmrelease="1" + summary="Setup files for server deployment" + repo="PATH OF GIT REPO TO CLONE" + ref="v1.0" + destination="/opt/server/" + +* rpmname: Name of the rpm to create, also used as the prefix name in the tar archive +* rpmversion: Version of the rpm, eg. "1.0.0" +* rpmrelease: Release of the rpm, eg. "1" +* summary: Summary string for the rpm +* repo: URL of the get repo to clone and create the archive from +* ref: Git reference to check out. eg. origin/branch-name, git tag, or git commit hash +* destination: Path to install the / of the git repo at when installing the rpm + +An rpm will be created with the contents of the git repository referenced, with the files +being installed under ``/opt/server/`` in this case. + +``ref`` can be any valid git reference for use with ``git archive``. eg. to use the head +of a branch set it to ``origin/branch-name``, a tag name, or a commit hash. + +Note that the repository is cloned in full each time a build is started, so pointing to a +repository with a large amount of history may take a while to clone and use a significant +amount of disk space. The clone is temporary and is removed once the rpm is created. + +Example Blueprint +================= + + name = "example-custom-base" + description = "A base system with customizations" + version = "0.0.1" + + [[packages]] + name = "tmux" + version = "*" + + [[packages]] + name = "git" + version = "*" + + [[packages]] + name = "vim-enhanced" + version = "*" + + [customizations] + hostname = "custombase" + + [[customizations.sshkey]] + user = "root" + key = "A SSH KEY FOR ROOT" + + [[customizations.user]] + name = "widget" + description = "Widget process user account" + home = "/srv/widget/" + shell = "/usr/bin/false" + groups = ["dialout", "users"] + + [[customizations.user]] + name = "admin" + description = "Widget admin account" + password = "$6$CHO2$3rN8eviE2t50lmVyBYihTgVRHcaecmeCk31LeOUleVK/R/aeWVHVZDi26zAH.o0ywBKH9Tc0/wm7sW/q39uyd1" + home = "/srv/widget/" + shell = "/usr/bin/bash" + groups = ["widget", "users", "students"] + uid = 1200 + + [[customizations.user]] + name = "plain" + password = "simple plain password" + + [[customizations.user]] + name = "bart" + key = "SSH KEY FOR BART" + groups = ["students"] + + [[customizations.group]] + name = "widget" + + [[customizations.group]] + name = "students" diff --git a/src/composer/cli/utilities.py b/src/composer/cli/utilities.py index b6ab23a4..61258e84 100644 --- a/src/composer/cli/utilities.py +++ b/src/composer/cli/utilities.py @@ -103,7 +103,7 @@ def get_arg(args, name, argtype=None): :type name: string :param argtype: Type to use for checking the argument value :type argtype: type - :returns (args, value) + :returns: (args, value) :rtype: tuple This removes the optional argument and value from the argument list, returns the new list,