Compare commits

...

258 Commits

Author SHA1 Message Date
Brian C. Lane 474097587e Automatic commit of package [lorax] release [28.27-1].
Created by command:

/bin/tito tag
2019-02-28 10:58:30 -08:00
Brian C. Lane f6b68cbd3d Add some extra cancel_func protection to QEMUInstall
In livemedia-creator's usage of this it can never pass in None, but if
someone were to import the library and use it, it would crash with
NoneType. So add the extra checks to make sure cancel_func isn't None,
just in case.

(cherry picked from commit 9041174142)
2019-02-28 09:45:29 -08:00
Yuval Turgeman cf13e9fd32 installer: make sure cancel_func has a value (#612)
When using LMC to virt-install a system to an image, cancel_func is not
provided in run_creator, causing a TypeError (NoneType object is not
callable).

Signed-off-by: Yuval Turgeman <yturgema@redhat.com>
(cherry picked from commit 1c731b5618)
2019-02-28 09:45:26 -08:00
Brian C. Lane b3c4e530fe Automatic commit of package [lorax] release [28.26-1].
Created by command:

/bin/tito tag
2019-01-30 12:10:35 -08:00
Brian C. Lane 6f90f18e31 Remove duplicate repositories from the sources list
In some cases when the host has, for whatever reason, multiple copies of
the same repo listed the build may fail with an error about running out
of space.

So this commit removes duplicate entries after the host's repos have been
loaded. It also adjusts some of the test repos to use different
temporary repo names for the tests.

(cherry picked from commit 98482e444d)
2019-01-30 08:43:51 -08:00
Brian C. Lane 98d56fba67 lorax: Move default tmp dir to /var/tmp/lorax
If systemd's tmpfiles.d timer is executed while lorax is running it will
remove any files and directories older than 30 days. This is what has
been causing the occasional error where /proc/ would seem to vanish
during the install.

Upstream has proposed this solution, https://github.com/systemd/systemd/pull/11482
but until that is released we need a work-around to protect the lorax
files.

This commit does several things:

* Move the default tmpdir from /var/tmp/ to /var/tmp/lorax/
* Add a lorax.conf tmpfiles.d file that prevents systemd-tmpfiles from
  removing anything under /var/tmp/lorax/
* Add an exit handler to lorax so that temporary directories are removed on
  exit or on a python traceback.
* Use flock to lock access to the tempdir while lorax is running.
* Remove any unlocked tempdirs named /var/tmp/lorax/lorax.* at startup

Note that the exit handler will not remove the tempdir if lorax is
killed with a signal -- those are being caught by dnf and prevent the
exit handler from running.

systemd-tmpfiles cannot clean up the tempdirs at boot time because they
contain files labeled as shadow_t, so we have to remove those when lorax
runs. It uses the flock to prevent removing any directories created by
parallel instances of lorax and only removes ones that are unlocked.
Worst case they will be around until the first run of lorax after a
reboot.

If you want to keep the working directory around for debugging purposes
use --workdir /var/tmp/lorax/my-workdir and it won't be removed by
lorax.

(cherry picked from commit e4fe1aab32)
2019-01-29 13:58:47 -08:00
Brian C. Lane 7e694c9c96 Automatic commit of package [lorax] release [28.25-1].
Created by command:

/bin/tito tag
2019-01-18 09:38:09 -08:00
Adam Williamson 2953328fd0 Don't exclude /dev from the `setfiles` in `novirt_install`
After a novirt disk image install, we run `setfiles` in the
install root to ensure some SELinux contexts are correct. /dev
is currently excluded from this run. However, as reported and
discussed in https://bugzilla.redhat.com/show_bug.cgi?id=1663040
it seems that with a recent systemd change, startup of many
services will fail if /dev itself is incorrectly labelled, and
in current Rawhide live images, it *is* incorrectly labelled.
Including `/dev` in this setfiles command appears to resolve the
problem in my testing.

Resolves: rhbz#1663040

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit 2d3f266373)
2019-01-18 09:34:51 -08:00
Brian C. Lane 304091471c dracut-fips is no longer a subpackage, it is included in dracut. 2019-01-18 09:06:05 -08:00
Brian C. Lane e11e428a6e Automatic commit of package [lorax] release [28.24-1].
Created by command:

/bin/tito tag
2019-01-08 14:40:07 -08:00
Brian C. Lane 9431a85b85 Remove unneeded else from for/else loop. It confuses pylint
(cherry picked from commit 2950f2641b)
2019-01-08 14:13:22 -08:00
Brian C. Lane e2a0c38e75 Turn off pylint warning about docstring with backslash
(cherry picked from commit 4fe21135e3)
2019-01-08 14:13:16 -08:00
Brian C. Lane f51a940718 Turn off smartquotes in Sphinx documentation
It mangles the double dashes in the docstrings, and should close #155

(cherry picked from commit e85bcf4359)
2019-01-08 14:13:07 -08:00
Anthony F McInerney cb03752810 fixes #543 qemu -nodefconfig deprecated
(cherry picked from commit f66bff5aa7)
2019-01-08 14:13:01 -08:00
Anthony F McInerney 4312408ade fix spinx build warnings
(cherry picked from commit 6bb64f94ff)
2019-01-08 14:12:56 -08:00
David Shea bc574e2e2f Allow customizations to be specified as a toml list
Support both

  [customizations]
  hostname = "whatever"

and

  [[customizations]]
  hostname = "whatever"

in the blueprint data. The [[ syntax matches the other customization
directives (user, group, sshkey), and as such it's easy to accidentally
use it for the hostname without even realizing it's specifying something
different.

Add some tests for converting customizations to kickstarts.

(cherry picked from commit 35ab6a1336)
2019-01-08 14:12:50 -08:00
Brian C. Lane a466f26c95 Revert "lorax-composer: Cancel running Anaconda process"
Drop running pkill. This causes problems if more than one is running on
a system (eg. in parallel using mock). It can kill off other processes
unrelated to this instance of anaconda.

This reverts commit e3e892ea43.
2019-01-08 14:12:14 -08:00
Brian C. Lane 8b59860217 Make sure cancel_func is not None
(cherry picked from commit ca2c3d9e77)
2019-01-07 14:11:59 -08:00
Brian C. Lane 970b787e68 Automatic commit of package [lorax] release [28.23-1].
Created by command:

/bin/tito tag
2018-12-17 16:55:19 -08:00
Brian C. Lane 2a86ed148e lorax: Save information about rootfs filesystem size and usage
Run df on the filesystem image after it has been created.
Output will be in program.log, eg:

Running... df /var/tmp/lorax.imgutils.wm04pg_v
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/loop0       1998672 1619508    362780  82% /var/tmp/lorax.imgutils.wm04pg_v
Return code: 0
2018-12-17 16:25:01 -08:00
Brian C. Lane 2aee00aea5 Turn on signed tags when using tito.
This requires a patched version of tito at the moment, and doesn't hurt
to have it set -- it will just continue not signing the tags.
2018-12-17 16:23:38 -08:00
Brian C. Lane e3e892ea43 lorax-composer: Cancel running Anaconda process
It ends up that this isn't as easy as you'd think. Anaconda sets up some
signal handlers to handle cleanly exiting, but they are not being run
when sent a TERM after package installation has started. I think DNF
resets them causing it to get ignored.

When the cancel is sent it can take several minutes for it to have an
effect. In my testing it usually takes around 2 minutes for anaconda to
notice and exit.

This sends a TERM to the process and then waits for it to exit. When it
returns it then removed any device-mapper devices that were setup for
image installations, removes any hanging loop devices.

It then kills off any process with pyanaconda. in the cmdline, and
anaconda-bus.conf (because anaconda starts a bunch of helpers and if it
doesn't shut down cleanly they remain running).

Resolves: rhbz#1656691
2018-12-17 16:22:37 -08:00
Brian C. Lane 41658811dc Add cancel_func to virt and novirt_install functions
In addition to monitoring the logs for errors, call a function (or
functions) that tell it to cancel the anaconda process and cleanup.

Also check for a cancel after creating the squashfs image for live-iso
since that's a long running process.

This required adding a new argument to a number of existing functions,
passing it down to QEMUInstall and novirt_install where the function is
called.

Resolves: rhbz#1656691
2018-12-17 16:22:37 -08:00
Brian C. Lane 9f0c50ee83 lorax-composer: Check for STATUS before deleting
When there is no run or new symlink do one last check to make sure no
STATUS file was written. If it is missing, go ahead and remove the
results directory.

Related: rhbz#1656691
2018-12-17 16:22:37 -08:00
Brian C. Lane 63d6024230 Check for existing CANCEL request, and exit on FINISHED
If another CANCEL request has already been made just exit from
uuid_cancel. If the build is FINISHED before it times out just exit,
don't remove the finished results.

Related: rhbz#1656691
2018-12-17 16:22:37 -08:00
Vendula Poncova 3211284638 Fix vhd images
Images don't work without these fixes:

* Enable Network Manager.
* Disable cloud-init.
* Add Hyper-V modules into initramfs.

Fixes specific for RHEL:

* Create ifcfg-eth0 required by waagent.
* Install python3 and net-tools required by waagent.

Recommended changes:

* Use recommended kernel boot args.
* Disable kdump.
2018-12-11 08:30:28 -08:00
Brian C. Lane 286f4c1dce Automatic commit of package [lorax] release [28.22-1].
Created by command:

/bin/tito tag
2018-12-06 16:17:37 -08:00
Brian C. Lane ed611933cb lorax-composer: Handle packages with multiple builds
When the repository has multiple arches, eg. i686 and x86_64, it should
add a new entry to the project's builds list, not create a new project
in the list.

This handles that by adding a modified insort_left function and
examining the packages returned from dnf to make sure they aren't
already listed in the results. It also handles adding them in sorted
order so that no further sorting needs to be done on the results.

Resolves: rhbz#1656642
(cherry picked from commit d18934775c)
2018-12-06 16:07:22 -08:00
Brian C. Lane dfb2b962b3 lorax-composer: Check the queue and results at startup
If the system ran out of space, or was rebooted unexpectedly, the state
of the queue symlinks, or the results STATUS files may be inconsistent.
This checks them and:
 * Removes broken symlinks from queue/new and queue/run
 * Removes symlinks from run and sets the build to FAILED
 * Sets builds w/o a STATUS to FAILED
 * Sets builds with STATUS of RUNNING to FAILED
 * Creates missing queue/new symlinks to results with STATUS of WAITING

So, any builds that were running during the reboot will be FAILED, and
any that were waiting to be started will be started upon rebooting.

Resolves: rhbz#1647985
(cherry picked from commit 4dd9004d13)
2018-12-06 15:26:59 -08:00
Brian C. Lane d262f6eaab Automatic commit of package [lorax] release [28.21-1].
Created by command:

/bin/tito tag
2018-11-29 14:58:43 -08:00
Brian C. Lane c1977b8427 Adjust tmux version in the tests to 2.8 2018-11-29 12:18:41 -08:00
Brian C. Lane 6667521b0a New lorax documentation - 28.21 2018-11-29 11:36:02 -08:00
Brian C. Lane 91257da87e lorax-composer: Install selinux-policy-targeted in images
This is required to ensure that SELinux is configured properly while
building. It fixes the problem with building tar, and should be
installed in the other image types for consistency.

Resolves: rhbz#1645189
(cherry picked from commit 99d867db65)
2018-11-29 11:34:40 -08:00
Brian C. Lane 8105443bc6 Remove setfiles from mkrootfsimage
SELinux applies the correct labels, setfiles is no longer needed.
This allows lorax to run with SELinux in Enforcing mode.

(cherry picked from commit 4a4a415f88)
2018-11-29 11:34:35 -08:00
Brian C. Lane e52d40216c Remove SELinux Permissive checks
Anaconda, Lorax, lorax-composer, and livemedia-creator can all now run
with SELinux in Enforcing mode. It does not need to be disabled and if
there are denials they should be reported as a bug.

Log the current state of SELinux when starting, update the
documentation.

(cherry picked from commit 080705e8e6)
2018-11-29 11:34:29 -08:00
Brian C. Lane a5c5cb457e Add --no-system-repos to lorax-composer
Running lorax-composer --no-system-repos will prevent it from copying
the dnf repositories from /etc/yum.repos.d/ into the lorax-composer repo
directory. It will *only* use repositories setup using the sources api
or written to /var/lib/lorax/composer/repos.d/

If lorax-composer has previously been run without this switch the system
repos will need to be removed from the composer/repos.d/ directory. It
would also be a good idea to remove the cached metadata in
/var/tmp/composer/

Resolves: rhbz#1650363
(cherry picked from commit 43ff505804)
2018-11-29 11:33:16 -08:00
Brian C. Lane 8129e5a9f8 Automatic commit of package [lorax] release [28.20-1].
Created by command:

/usr/bin/tito tag
2018-10-29 15:48:24 -07:00
Brian C. Lane bb1349cade New lorax documentation - 28.20 2018-10-29 15:25:10 -07:00
Brian C. Lane f5732d21bf Build manpages for composer-cli and lorax-composer
Add manpage creation to make docs target to keep them updated.

(cherry picked from commit 7500a17f27)
(cherry picked from commit d9b282150e)
2018-10-29 15:22:38 -07:00
Brian C. Lane 4e46d776d5 Add tests for ltmpl.py
This covers things like installing globbed package names from multiple
repos, pinned package versions, and ltmpl functions

Related: rhbz#1548586
2018-10-29 13:53:59 -07:00
Brian C. Lane 71be466bde Move get_dnf_base_object into a module
This allows it to be imported by tests.
2018-10-25 11:20:42 -07:00
Brian C. Lane 6e57bfe11d lorax: Fix dnf problems with selecting highest NEVRA from multiple repos
When using package name globs and multiple repos dnf doesn't choose the
highest NEVRA as you would expect, work around this by applying max() to
the duplicate package names in installpkg.

Resolves: rhbz#1548586
2018-10-25 11:15:03 -07:00
Brian C. Lane 32156bd349 Automatic commit of package [lorax] release [28.19-1].
Created by command:

/usr/bin/tito tag
2018-10-12 15:51:00 -07:00
Brian C. Lane 9c758c7c4b Fix directory creation for blueprints
Depending on how lorax-composer is run setting up an empty blueprints
directory can fail. So this moves checking/creation until after the
other directories are created and uses make_owned_dir to make sure
ownership is correct.
2018-10-10 14:25:51 -07:00
Brian C. Lane 1a7b6c74b4 Update the tests for new make_dnf_dir arguments.
Use the uid and gid that the test is running as instead of hard-coding
0.
2018-10-10 14:25:51 -07:00
Brian C. Lane d170622357 Change make_dnf_dirs to be run as root
It needs to be root in order to set the ownership and permissions on the
directories that are under /var/lib/lorax/composer/

Refactor the directory creation into a utility function, and use a umask
of 0o006 to ensure that the parent directories created do not have o+rw
set on them (makedirs behavior is different between Python 3.6 and 3.7
so umask of 0 doesn't work consistently).
2018-10-10 14:25:51 -07:00
Brian C. Lane 0a96c1eedb Disable false context-manager pylint error 2018-10-09 15:47:38 -07:00
Brian C. Lane 0037f10205 Add an openstack image type
This is a qcow2 image with cloud-init in the template.
2018-10-09 15:17:45 -07:00
David Shea 8908ae8a7a Add cloud-init to vhd images.
cloud-init can be used in Azure now
2018-10-09 15:17:34 -07:00
David Shea e401f36496 Replace /etc/machine-id with an empty file
Since these images can be used to create multiple machines, they should
not have a unique machine-id attached to them. Replace /etc/machine-id
with an empty file so that it will be regenerated at boot time.
2018-10-09 15:17:24 -07:00
Brian C. Lane 9d73975c9f Update cli tests to use composer-cli name 2018-10-09 15:17:13 -07:00
Brian C. Lane a0fc9eb7ad Work around dnf problem with multiple repos
If a package is in multiple repos dnf may return more than 1 of them
when using best...glob so we pick the highest NEVRA one and install
that.

Related: rhbz#1636239
2018-10-09 15:17:00 -07:00
Lars Karlitski 577618a1fc Add and enable cloud-init for ami images
Images don't work at all on AWS without cloud-init.

Fixes #492
2018-10-09 15:16:49 -07:00
David Shea 955631b872 Make no-virt generated images sparser
At the end of disk image installs, use fstrim on the generated filesystem to
discard any blocks that were allocated during the install and are now unused.
This will allow tools such as qemu-img to create images that do not include
deleted data.

For raw disk images that do not go through qemu-img, use fallocate --dig-holes
to create sparse holes in place of the unused blocks.
2018-10-09 15:16:38 -07:00
Brian C. Lane fb1dfc9488 Report an error if the blueprint doesn't exist
composer-cli uses TOML for 'blueprints save' which was returning an
empty 200 response if the blueprint didn't exist. Change this to return
a standard 400 error response if the blueprint doesn't exist.

composer-cli is already setup to handle receiving json when an error is
returned so just the toml API response for `blueprints/save` needed to
be changed.
2018-10-09 15:16:20 -07:00
Lars Karlitski bb40856f3e cli: Clarify error message for unprivileged access
`os.path.exists("/run/weldr/api.socket")` returns False for users which have no
access. This leads to composer printing that the file does not exist, which is
misleading.

Since it's no possible to distinguish the two cases, fix this problem by
combining them and showing a single error message.
2018-10-09 15:15:57 -07:00
Brian C. Lane c2b0e8a8bb Write a rootpw line if no root customizations in the blueprint
Anaconda requires the root password to be set or locked, so if there
isn't anything setting it we write out 'rootpw --lock'

Also adds tests for this.

Resolves: rhbz#1626122
2018-10-09 15:15:42 -07:00
Brian C. Lane 558fdecde5 Add beakerlib to Dockerfile.test
Also kill the lorax-composer process and remove /run/weldr/api.socket
so that when this is run with podman you don't get an error about
attempting to tar up the socket.
2018-10-09 15:15:23 -07:00
Brian C. Lane 0a71478ac4 Adjust the new templates for locked root
also remote the auth line so that it uses the defaults.

Related: rhbz#1628645
Related: rhbz#1628646
Related: rhbz#1628647
Related: rhbz#1628648
2018-10-09 15:14:53 -07:00
Brian C. Lane 13e6a68154 Always update repo metadata when building an image
When the kickstart is handed off to Anaconda for building it will
download its own copy of the metadata and re-run the depsolve. So if the
dnf cache isn't current there will be a mismatch and the build will
fail to find some of the versions in final-kickstart.ks

This adds a new context to DNFLock, .lock_check, that will force a check
of the metadata. It also implements its own timeout and forces a
refresh of the metadata when that expires because the dnf expiration
doesn't always work as expected.

Resolves: rhbz#1631561
2018-10-09 15:13:48 -07:00
Brian C. Lane f5679f61b1 Add a test for repo metadata expiration
This tests to make sure that the metadata timer is working (by setting
it to 10s and adding a new package to the repo), and that
DNFLock.lock_check immediately picks up a new package.

This depends on rpmfluff which is available from Fedora or EPEL repos.

Related: rhbz#1631561
2018-10-09 15:12:21 -07:00
Brian C. Lane 8479319621 Add tests for setting root password and ssh key with blueprints
Related: rhbz#1626120
2018-10-09 15:12:09 -07:00
Brian C. Lane a1f11f943d Use rootpw for setting the root password instead of user
Ends up you cannot use the kickstart user command on root, since it
already exists, so we have to translate that into a rootpw command.

So [[customizations.user]] with name = "root" only support key, which
will set the ssh key, and password which will use rootpw to set the
password. plain text or encrypted are supported.

Related: rhbz#1626122
2018-10-09 15:12:01 -07:00
Brian C. Lane 0cb4d04479 Lock the root account, except on live-iso
If we leave the root account w/o a password people will use it that way,
leading to insecure images. Also if we use a default password. So lock
the root account in the templates.

Users will need to do one of these things:
 1. Use [[customizations.user]] in their blueprint to configure root or
    another user.
 2. Use [[customizations.sshkey]] to set a key for root
 2. Install a package that configures a user at install time
 3. Install a package that sets up a user at boot time (eg. cloud-init)

This also drops the auth line from the kickstart templates, allowing it
to use the default password algoritm instead of md5.

Resolves: rhbz#1626122
2018-10-09 15:11:51 -07:00
David Shea 3ea07ed44a Add new compose types to compose sanity test 2018-10-09 15:11:36 -07:00
Lars Karlitski 9ae690e3b6 Also run `make check` on travis 2018-10-09 15:10:45 -07:00
Lars Karlitski d8cb1a19f8 Fix pylint errors and warnings
Remove `except` block which immediately raises the same exception again (it's
not a subclass of another caught exception, so this is safe).

Remove a false positive, because it is not emitted from the code base.

Disable subprocess-popen-preexec-fn in startProgram, which is not used
internally.
2018-10-09 15:04:43 -07:00
Alexander Todorov ca1bf01b03 New cli test covering basic compose commands
- need to specify --sharedir so lorax-composer can find its
  kickstart files

- each test script writes results into a separate directory to
  avoid a passing test overwriting the results from a failing one.
  To avoid reporting failures in case of previously failing tests
  (e.g. during development) remove the temporary directories holding
  tets results before execution!
2018-10-09 15:03:24 -07:00
Alexander Todorov ee62425388 Execute bash tests for composer-cli
these are built on top of beakerlib and we use its internal
protocol to figure out the result without relying on the full
test runner that is tipically used inside of a RHEL environment!

Includes a disabled test snippet for Issue #460
2018-10-09 15:02:57 -07:00
Stef Walter e95c09dd7e Start a HACKING.md file and document how to run the tests 2018-10-09 15:02:38 -07:00
Stef Walter 5cb1748908 Ignore files created by tests 2018-10-09 15:01:26 -07:00
Stef Walter 5891879ae4 Makefile: Fix the 'make install' target
This fixes the 'make install' target to work on a typical RHEL or
Fedora system. We now by default install to a prefix of /usr instead
of /usr/local

The prefix is overridable like so:

     $ make install PREFIX=/opt/
2018-10-09 15:01:14 -07:00
Brian C. Lane 48f7ad780d lorax: Only run depmod on the installed kernels
In the near-future there may be /lib/modules/ directories for older
kernels with weak dependencies listed. These may not match the installed
kernel(s) so we cannot depend on them to drive generate_module_data.

Instead use the existing findkernels() function to get the list of
installed kernels and iterate those, running depmod on them.

Resolves: rhbz#1622213
2018-10-09 14:51:05 -07:00
David Shea 2304a73676 Add virt guest agents to the qcow2 compose
(cherry picked from commit d5a1993640)
2018-10-02 12:56:56 -04:00
David Shea de6e1d027e Add a vmdk compose type.
This is similar to the AMI type, but also adds open-vm-tools and does not do
anything special to the partitioning

(cherry picked from commit 1056bfc25b)
2018-10-02 12:56:52 -04:00
David Shea 68c1a7aa96 Add a vhd compose type for Azure images
This does pretty much the same things as the AMI compose type, but also
replaces NetworkManager with the Azure linux agent.

(cherry picked from commit e0c236ff36)
2018-10-02 12:56:47 -04:00
David Shea f79fd46f1f Add an ami compose type for AWS images
This differs from lmc's --make-ami in that creates a full disk image instead of
an fsimage. Create a raw disk image with a / and /boot partitions, and enable
sshd, chronyd, and cockpit by default.

(cherry picked from commit 18188bf6cf)
2018-10-02 12:56:33 -04:00
David Shea 09b34889bc Remove --fstype from the generated part line
Instead of specifying the fstype, just let anaconda use the default.

(cherry picked from commit 847fff4e11)
2018-10-02 12:56:03 -04:00
Brian C. Lane 7823d46747 New lorax documentation - 28.18 2018-09-06 10:41:38 -07:00
Brian C. Lane 6eb357e71e Fix /compose/cancel API documentation
It said /blueprints/cancel which is incorrect.
2018-08-29 10:08:15 -07:00
Brian C. Lane a951bf083d Automatic commit of package [lorax] release [28.18-1].
Created by command:

/usr/bin/tito tag
2018-08-27 15:47:16 -07:00
Brian C. Lane a286e9b3dc Fix composer-cli blueprints changes to get correct total
blueprints/changes is different, each blueprint has it's own total,
limited by the call's limit. So it needs to find the max total of all
the requested blueprints.

(cherry picked from commit 57674c9a1a)
2018-08-27 12:02:39 -07:00
Brian C. Lane 630df546e6 Fix blueprints/list and blueprints/changes to return the correct total
(cherry picked from commit ec908fcd2a)
2018-08-27 12:02:39 -07:00
Brian C. Lane 8838ee12bc Add tests for limit=0 routes
Passing ?limit=0 to the blueprints/list, blueprints/changes,
projects/list, modules/list should always return the total possible
results, not 0.

Also move the composer-cli test_diff to the end so that it will work
consistently. Do this by naming it test_z_diff.

(cherry picked from commit 972b5c4142)
2018-08-27 12:02:39 -07:00
Brian C. Lane 187cd935df Add a function to get_url_json_unlimited to retrieve the total
The blueprints/changes API is a bit different from the others, the total
that it includes is for each blueprint, not one total for all of them,
since there will be a different number of commits for each.

The function is passed the dict, and it can be used to select the total
to use for retrieving all of the results. If it isn't included it will
use data["total"] which works fine in most cases.

(cherry picked from commit 0a76d635ca)
2018-08-27 12:02:39 -07:00
Brian C. Lane 7773be2bda Fix tests related to blueprint name changes 2018-08-23 13:46:39 -07:00
Brian C. Lane b198c6e498 Add 'example' to the example blueprint names 2018-08-23 13:45:32 -07:00
Brian C. Lane 9249d21d6f Use urllib.parse instead of urlparse
python3 moved this to a new module.

(cherry picked from commit 86d556e87c)
2018-08-21 16:50:53 -07:00
David Shea e3ef3d9a29 In composer-cli, request all results
Add a limit argument to all potentially paginated results, equal to
whatever the composer backend is the total number of results. This still
has the potential to provide truncated data if the number of results
increases between the two HTTP requests.

Resolves: #404
(cherry picked from commit ee98d87cea)
2018-08-21 16:50:53 -07:00
David Shea eedf1a9243 Add tests for /compose/status filter arguments
(cherry picked from commit c52ba4236a)
2018-08-21 16:50:53 -07:00
David Shea bba0a85aaf Allow '*' as a uuid in /compose/status/<uuid>
This will display all UUIDs that match the filter arguments

(cherry picked from commit deff4d325f)
2018-08-21 16:50:53 -07:00
David Shea 5272be3127 Add filter arguments to /compose/status
This adds the following optional arguments to the /compose/status route:

  - type, matches the compose_type field
  - status, matches the queue_status field
  - blueprint, matches the blueprint field

(cherry picked from commit 40f23f093d)
2018-08-21 16:50:53 -07:00
Brian C. Lane 8694c7a7dc composer-cli should not log to a file by default
The user can pass --log /path/to/logfile.log if they want logging
enabled.

(cherry picked from commit 844ff9998b)
2018-08-21 11:59:12 -07:00
Brian C. Lane 93b207e752 Add documentation for using a DVD as the package source 2018-08-21 11:28:59 -07:00
Lars Karlitski d55ff41870 Set TCP listen backlog for API socket to SOMAXCONN
A value of 1 is too low for heavy users of the API, such as the weldr-web
interface.

This is also systemd's default for sockets it opens. Using lorax-composer with
socket activation already results in a backlog of SOMAXCONN connections.

(cherry picked from commit be5d50e6f3)
2018-08-20 14:54:57 -07:00
Brian C. Lane cef073d832 New lorax documentation - 28.17 2018-08-13 16:49:52 -07:00
Brian C. Lane c2f96b3d3b Add a note about using lorax-composer.service
Update the docs to make it clear that .socket will be slow to respond to
the first request, and to use .service to speed it up.

(cherry picked from commit 83e5f3f885)
2018-08-13 16:47:12 -07:00
Brian C. Lane 64efb8b415 Ignore dnf.logging when building docs
(cherry picked from commit 07de4c371a)
2018-08-13 16:47:10 -07:00
Chris Lumens 312faf6275 Fix a little bug in running "modules list".
(cherry picked from commit 5dddef6f49)
2018-08-10 12:00:54 -04:00
Brian C. Lane 3a89828faf Automatic commit of package [lorax] release [28.17-1].
Created by command:

/usr/bin/tito tag
2018-08-09 16:38:21 -07:00
Brian C. Lane 77dc017c78 Fix bash_completion.d typo 2018-08-09 16:25:26 -07:00
Brian C. Lane 02dc3404a8 Move disklabel and UEFI support to compose.py
Currently we are making MBR disk images for qcow2 and partitioned disk,
so the UEFI packages aren't required at this point.

Move the clearpart command into compose.py so that in the futute it can
use clearpart --disklabel to create a GPT image, and add the required
packages to the package set.
2018-08-09 15:26:09 -07:00
Chris Lumens a08c16158d Fix more tests.
These were broken due to me rebasing before sending a PR off.  They
should work now.

(cherry picked from commit 4cb15e0a0f)
2018-08-09 16:33:30 -04:00
Chris Lumens a567157aa2 Change INVALID_NAME to INVALID_CHARS.
It's getting used in a whole lot more places now, so make it a bit more
generic sounding.

(cherry picked from commit bf0318eab6)
2018-08-09 16:33:26 -04:00
Chris Lumens 9c188b84a6 Update composer-cli for the new error return types.
(cherry picked from commit bc96f75992)
2018-08-09 16:33:19 -04:00
Chris Lumens 05e1a34687 Add default error IDs everywhere else.
The idea here is to make sure all return points have the same type for
the error cases.  There's not really all that many, so they just go in
one patch.  Some of these could potentially turn into more specialized
errors later.

(cherry picked from commit fd901c5e3f)
2018-08-09 16:33:06 -04:00
Chris Lumens 7c19be3792 Add error IDs to things that can go wrong when running a compose.
Note the exception string checking around compose_type.  I didn't really
want to introduce a new exception type just for this, but also didn't
want to duplicate strings.  I'd be open to other suggestions for how to
do this.

(cherry picked from commit b3bb438254)
2018-08-09 16:32:45 -04:00
Chris Lumens 23fe52dd70 Add error IDs for common source-related errors.
(cherry picked from commit e43adfc7af)
2018-08-09 16:32:40 -04:00
Chris Lumens cb97c59079 Add error IDs for unknown modules and unknown projects.
(cherry picked from commit 2adcfc9563)
2018-08-09 16:32:36 -04:00
Chris Lumens 3a2716dec4 Add error IDs for when an unknown commit is requested.
(cherry picked from commit 07528a431e)
2018-08-09 16:32:27 -04:00
Chris Lumens 2a8a9bc506 Add error IDs for when an unknown blueprint is requested.
This adds some fairly redundant code to the beginning of all the
blueprint routes to attempt reading a commit from git for the
blueprint's recipe.  If it succeeds, the blueprint exists and the route
can continue.  Otherwise, return an error.  Hopefully this doesn't slow
things down too much.

(cherry picked from commit a925cc7ddb)
2018-08-09 16:32:22 -04:00
Chris Lumens 44b8b79af7 Add error IDs for when an unknown build UUID is requested.
Note that this also changes the return type of uuid_info to return None
when an unknown ID is given.  The other uuid_* functions are fine
because they are checked ahead of time.

(cherry picked from commit 6497b4fb65)
2018-08-09 16:32:05 -04:00
Chris Lumens 3e0ece3634 Add error IDs for bad state conditions.
(cherry picked from commit d76e24053a)
2018-08-09 16:31:34 -04:00
Chris Lumens 91c6c730f3 Change the error return type for bad limit= and offset=.
Each element in the errors value is now a dict, with a msg field and an
id field.  The id field contains a value out of errors.py that can be
used by the front end to key on.  The msg field is the same as what's
been there.

The idea is to keep the number of IDs somewhat limited so there's not a
huge number of things for the front end to know.

(cherry picked from commit 9677b012da)
2018-08-09 16:31:29 -04:00
Chris Lumens 31293f8460 Don't sort error messages.
This should make it easier to return more complex error structures.  It
also doesn't appear to matter - tests still pass without changes.

(cherry picked from commit 4c3f93e329)
2018-08-09 16:31:19 -04:00
Brian C. Lane b4fa931eca Fix bash completion of compose info 2018-08-07 16:48:12 -07:00
Brian C. Lane 4307eebb49 Add + to the allowed API string character set 2018-08-07 16:48:12 -07:00
Brian C. Lane 716fb3277f Add job_* timestamp support to compose status 2018-08-07 15:21:22 -07:00
Will Woods c44347ca77 Add etc/bash_completion.d/composer-cli
Here's a bash_completion file for composer-cli! It completes known
commands, subcommands, and flags, plus arguments to flags that take
arguments, and if you've got write access to the socket it'll also
autocomplete:

* source names for commands that need source names
* blueprint names for commands that take blueprint names
* compose uuids for commands that take compose uuids
  * intelligently only suggests appropriate uuids - e.g. only
    suggests uuids of running composes for "compose cancel"

NOTE: bash completion scripts are horrible and this is no exception.
Please forgive me.
2018-08-07 10:18:10 -07:00
Will Woods 3f8b9d7737 composer-cli: clean up "list" commands
This patch does two things:

1) Add "compose list", which lists compose UUIDs and other basic info,
2) Fix up "blueprints list", "modules list", "sources list", and
   "compose types" so their output is just a plain list of identifiers
2018-08-07 10:18:10 -07:00
Brian C. Lane a034b205aa Drop .decode from UTF8_TEST_STRING 2018-08-07 10:07:39 -07:00
Brian C. Lane 2b0f9c4bd7 Add input string checks to the branch and format arguments
Make sure no UTF8 characters are allowed and return an error if they
are.

Also includes tests to make sure the correct error is returned.

(cherry picked from commit 86d79cd8a6)
2018-08-07 09:45:02 -07:00
Brian C. Lane f5cdb94c9c Add a test for invalid characters in the API route
Currently the code is not UTF8 safe, so we need to return a clear error
when invalid characters are passed in.

This also adds tests for the routes to confirm that an error is
correctly returned.

(cherry picked from commit 74f5def3d4)
2018-08-07 09:45:02 -07:00
Brian C. Lane 7999ae3ee7 Fix logging argument 2018-08-07 09:26:32 -07:00
Brian C. Lane a6c3a82695 Update get_system_repo for dnf
With dnf we iterate the repos and return their names, not the filenames
like we do with yum. Also make the list test more flexible.
2018-08-07 09:20:16 -07:00
Brian C. Lane e9b16c7a47 Update ConfigParser usage for Py3
SafeConfigParser is now just ConfigParser
2018-08-07 08:41:43 -07:00
Brian C. Lane 4bb7f14e2a Update StringIO use for Py3
It is imported from io now.
2018-08-07 08:41:11 -07:00
Brian C. Lane 619a9a2939 Add a test for the pylorax.api.timestamp functions 2018-08-07 08:40:21 -07:00
Brian C. Lane 0a6e58d03d Fix write_timestamp for py3
toml.dumps() returns a string for write() so .encode is not needed.
2018-08-07 08:39:05 -07:00
Chris Lumens b614a81f5b Return a JSON error instead of a 404 on certain malformed URLs.
This handles the case where a route is requested, but without a required
parameter.  So, /blueprints/info is requested instead of
/blueprints/info/http-server.  It accomplishes this via a decorator, so
a lot of these route-related functions now have quite a few decorators
attached to them.

Typo'd URLs (/blueprints/nfo for instance) will still return a 404.  I
think this is a reasonable thing to do.

(cherry picked from commit 5daf2d416a)
2018-08-06 17:00:56 -07:00
Chris Lumens 05091d221a Return an error if /modules/info doesn't return anything.
Unfortunately, this isn't very useful if /modules/info is provided with
multiple modules.  yum doesn't traceback when doPackageLists is given
something that doesn't exist.  It just returns an empty list.  If
/modules/info is given just one module and yum gives us an empty list,
it's easy to say what happened.  If /modules/info is given several
modules and just one does not exist, we will not be able to detect that.

Fixing this would require doing more yum operations, which is likely to
slow things down and isn't the direction I want to be going.

(cherry picked from commit 8e948e4a4d)
2018-08-06 17:00:56 -07:00
Chris Lumens 5979d570c7 Update documentation (#409).
(cherry picked from commit 6193a7c9d8)
2018-08-06 17:00:56 -07:00
Chris Lumens 099ff0bdc2 Use constants instead of strings (#409).
(cherry picked from commit fdf4d63f3b)
2018-08-06 17:00:56 -07:00
Chris Lumens 12bc717266 Write timestamps when important events happen during the compose (#409).
Right now, this is when the compose is queued up, when it is started by
anaconda, and when it is finished (whether that's success or not).

(cherry picked from commit 3ba9d53b8b)
2018-08-06 17:00:56 -07:00
Chris Lumens 9e1b7f2d4e Return multiple timestamps in API results (#409).
If one of the timestamps isn't present (for instance, the finished
timestamp for a job that is still running), null is returned.

(cherry picked from commit 17c40ef271)
2018-08-06 17:00:56 -07:00
Chris Lumens 5b3b13cd08 Add a new timestamp.py file to the API directory (#409).
This is responsible for writing out a new times.toml file, containing
important timestamps in the life of a compose.  This seems a little more
reliable than attempting to infer things from the filesystem, especially
in light of the fact that we can't ever really know when a file was
created.

(cherry picked from commit b59d59b124)
2018-08-06 17:00:56 -07:00
Brian C. Lane 5ebcd2cf11 Use the first enabled system repo for the test
(cherry picked from commit 3fd5e50c80)
2018-08-06 17:00:56 -07:00
Brian C. Lane 51c17ae361 Show more details when the system repo delete test fails
Works fine for me locally, but not in Travis for some reason so let's
get more info.

(cherry picked from commit 26df083bd4)
2018-08-06 17:00:56 -07:00
Brian C. Lane 7869c59847 Add composer-cli function tests
These depend on there being a freshly installed lorax-composer API
server running, if there is no /run/weldr/api.socket they will be
skipped.

(cherry picked from commit 7700ae3135)
2018-08-06 17:00:56 -07:00
Brian C. Lane 03e6015f20 Add a test library
This adds empty __init__.py to tests so that a lib.py library of helper
functions can be imported from the tests.

Add captured_output to use with composer-cli tests to capture stdout/err
output from the functions.

(cherry picked from commit eeae331ba0)
2018-08-06 17:00:56 -07:00
Brian C. Lane c52d45e168 composer-cli: Add support for Group to blueprints diff
(cherry picked from commit 2edd7a995b)
2018-08-06 17:00:56 -07:00
Brian C. Lane 1fff409465 Update status.py to use new handle_api_result
Use the new function to properly handle error responses for all the
commands.

(cherry picked from commit 642f117d54)
2018-08-06 17:00:56 -07:00
Brian C. Lane 2ec00fb5ce Update sources.py to use new handle_api_result
Use the new function to properly handle error responses for all the
commands.

(cherry picked from commit 3205e47a13)
2018-08-06 17:00:56 -07:00
Brian C. Lane 14542df02c Update projects.py to use new handle_api_result
Use the new function to properly handle error responses for all the
commands.

(cherry picked from commit 77767cd93a)
2018-08-06 17:00:56 -07:00
Brian C. Lane 6614f65198 Update modules.py to use new handle_api_result
Use the new function to properly handle error responses for all the
commands.

(cherry picked from commit b55b86d0b3)
2018-08-06 17:00:56 -07:00
Brian C. Lane 35e2471e41 Update compose.py to use new handle_api_result
Use the new function to properly handle error responses for all the
commands.

(cherry picked from commit 760aeb61a7)
2018-08-06 17:00:56 -07:00
Brian C. Lane 7e5590d459 Update blueprints.py to use new handle_api_result
Use the new function to properly handle error responses for all the
commands.

(cherry picked from commit c1c5536ec8)
2018-08-06 17:00:56 -07:00
Brian C. Lane 74d76789e1 Modify handle_api_result so it can be used in more places
Some results have errors and no status, others have status and errors.
Update the function to return the final rc to exit with, and a bool
indicating whether or not to continue processing the other fields.

Add a bunch of tests for the new function to make sure I have the logic
correct.

(cherry picked from commit 35fa067219)
2018-08-06 17:00:56 -07:00
Chris Lumens d598b51294 Fix help output on the compose subcommand.
(cherry picked from commit a3572c9fdd)
2018-07-26 14:25:55 -04:00
Chris Lumens 4aa6768e03 Add timestamps to "compose-cli compose status" output.
(cherry picked from commit 7bcb61849d)
2018-07-26 14:25:52 -04:00
Chris Lumens 20fb27ec41 And then add real output to the status command.
(cherry picked from commit eb0939d967)
2018-07-26 14:25:48 -04:00
Chris Lumens 23892f19eb Add the beginnings of a new status subcommand.
(cherry picked from commit 9eafc60fa0)
2018-07-26 14:25:38 -04:00
Chris Lumens 73810e162d Document that you shouldn't run lorax-composer twice.
(cherry picked from commit 052828047c)
2018-07-26 14:25:34 -04:00
Chris Lumens 00af7c6da1 Add PIDFile to the .service file.
This will cause systemd to delete the lock file when the service
terminates.  This does not do anything if lorax-composer is started on
the command line, however.

(cherry picked from commit e37eae55b8)
2018-07-26 14:25:23 -04:00
Brian C. Lane 4eae24de40 composer-cli: Fix non-zero epoch in projets info
The json value is an int, so convert it to a str.

(cherry picked from commit 18521cec1a)
2018-07-25 11:39:34 -07:00
Brian C. Lane 0060729c3d Automatic commit of package [lorax] release [28.16-1].
Created by command:

/usr/bin/tito tag
2018-07-20 16:09:36 -07:00
Brian C. Lane 3a39b22f71 New lorax documentation - 28.16 2018-07-20 16:09:21 -07:00
Brian C. Lane b0b97adf75 Update rsync version in http-server.toml 2018-07-18 16:50:51 -07:00
Brian C. Lane 49380b4b49 Log and exit on metadata update errors at startup
A bad system repo can cause lorax-composer to fail to start. Instead of
a traceback log the error and exit.

(note that the exit still results in an OSError traceback due to part of
it running as root, this needs to be addressed in another commit).

(cherry picked from commit b1dd22afa6)
2018-07-18 16:44:44 -07:00
Brian C. Lane de0e5d2b59 Check /projects responses for null values.
Some values can be null/None so check for that instead of crashing.

(cherry picked from commit f916e41d00)
(cherry picked from commit 83680d92b0)
2018-07-18 16:44:44 -07:00
Brian C. Lane 5993802bc6 Clarify error message from /source/new
(cherry picked from commit b20aa4609c)
(cherry picked from commit 816f1658db)
2018-07-18 16:44:44 -07:00
Chris Lumens 1de67f4f63 Support loading groups from the kickstart template files.
(cherry picked from commit c8d2045f89)
(cherry picked from commit fbda20b8b7)
2018-07-18 16:35:48 -07:00
Chris Lumens dbeb653942 Add group-based tests.
(cherry picked from commit ab0655d5a9)
(cherry picked from commit e151c8399d)
2018-07-18 16:35:48 -07:00
Chris Lumens 0259f3564d Include groups in depsolving.
This adds a new argument to projects_depsolve and
projects_depsolve_with_size that contains the group list, unfortunately.
I would have prefered adding a function that just returns a list of all
the contents of a group and then add that to what was being passed into
projects_depsolve.  However, there does not appear to be any good way to
do that in yum aside from a lot of grubbing around in the comps object,
which I am unwilling to do.

(cherry picked from commit 5fe4b47072)
(cherry picked from commit 8c4804eb15)
2018-07-18 16:35:48 -07:00
Chris Lumens f1f8980c49 Add support for groups to blueprints.
Nothing is currently being done with this information, but it will be
soon.

(cherry picked from commit 0f69d2084c)
(cherry picked from commit 76d376fe18)
2018-07-18 16:35:48 -07:00
Chris Lumens f5115291bd Add help output to each subcommand.
This is the same as the output at the top level, just trimmed down to
only the options for a single subcommand.  It's trigged by providing
"help" or "--help" as a subcommand option.

(cherry picked from commit 954f330ace)
(cherry picked from commit bb8fdcb854)
2018-07-18 16:35:48 -07:00
Chris Lumens 0179a976ba Split the help output into its own module.
This means I can reuse it for help output for individual subcommands.

(cherry picked from commit 70e4211ad1)
(cherry picked from commit eba5658a71)
2018-07-18 16:35:48 -07:00
Chris Lumens 18620700fd If the help subcommand is given, print the help output.
This isn't a real subcommand like the others.  The option processing
just intercepts it and prints the output.  Given that we're subcommand
based, it makes sense to support this in addition to --help.

(cherry picked from commit 3743d6d208)
(cherry picked from commit 3c6478e179)
2018-07-18 16:35:48 -07:00
Brian C. Lane d92f2f5b04 Check the compose templates at startup
Depsolve the packages included in the templates and report any errors
using the /api/status 'msgs' field. This should help narrow down
problems with package sources not being setup correctly.
2018-07-13 09:51:36 -07:00
Brian C. Lane 6acbb0be0e Fix a couple typos in lorax-composer docs.
The description of blueprint versions was wrong, now it is
correct.

(cherry picked from commit 9e41052992)
2018-06-29 14:16:59 -07:00
Brian C. Lane 914c33ef97 Include example blueprints in the rpm
This also sets ownership of /var/lib/lorax/composer/ to root:weldr to
allow missing directories to be created at runtime.

(cherry picked from commit f38f5cc168)
2018-06-27 16:13:39 -07:00
Brian C. Lane b7ed511554 Make sure /run/weldr has correct ownership and permissions
Normally tmpfiles.d will handle this at boot time, but if you install
lorax-composer without rebooting it was ending up with root:root
ownership instead of root:weldr

(cherry picked from commit 7adc5162fb)
2018-06-27 16:13:39 -07:00
Brian C. Lane 841e65a397 Allow more than 1 bash build in tests
It is perfectly valid to have more than one build of a package, eg. one
in the release repo and one in the updates repo.

(cherry picked from commit 86c4ef5f45)
2018-06-21 16:19:06 -07:00
Brian C. Lane a5ddd5e3bf Add redhat.exec to s390 .treeinfo
Resolves: rhbz#1593657
(cherry picked from commit 6d9187d559)
2018-06-21 11:22:55 -07:00
Brian C. Lane 590341f735 Retry losetup if loop_attach fails
It appears that sometimes the loop device doesn't get setup properly,
this may be a race with other users of loop devices on the system, or
some other mechanism that isn't understood.

To try and prevent total failure when this happens this patch retries
the loop setup 3 times before giving up. Previously it would wait for
the loop device to appear (checking 5 times), that operation is now
executed 3 times with a new losetup attempt each time.

Resolves: rhbz#1589084
(cherry picked from commit c746e8b0c3)
2018-06-11 14:00:42 -07:00
Brian C. Lane de73924cd3 Add reqpart to example kickstart files
This will make sure that platform specific partitions are created when
making partitioned disk images.

(cherry picked from commit 98de565979)
2018-06-11 13:55:42 -07:00
Brian C. Lane ec8ecba9d1 Increase default ram used with lmc and virt to 2048
1024 is a bit small in some situations, double it.

Resolves: rhbz#1538747
(cherry picked from commit 594e762d63)
2018-06-11 13:47:59 -07:00
Brian C. Lane 96e132f733 Automatic commit of package [lorax] release [28.15-1].
Created by command:

/usr/bin/tito tag
2018-06-11 11:04:32 -07:00
Martin Kolman 68e850d57a Make LogRequestHandler configurable
Make it possible to manipulate the simple and regexp
tests the LogRequestHandler class uses to check error
messages for potential error states.

This is accomplished by moving the simple and regexp test
strings to class members, where they can be easily
manipulated by users of the pylorax module.

It's also now possible to set the log request handler class
for a LogMonitor.

This functionality can then be used for example like this:

customized_log_request_handler = monitor.LogRequestHandler
customized_log_request_handler.simple_tests.remove("Call Trace:")
log_monitor = monitor.LogMonitor(install_log,
                                 timeout=opts.timeout,
                                 log_request_handler_class = customized_log_request_handler)

This way installation will continue even if there was a call
trace in the logs. In a similar way additional tests and regexps can be
also added.

(cherry picked from commit d5d3dd3be3)
2018-06-11 11:04:00 -07:00
Brian C. Lane 760d70f158 Automatic commit of package [lorax] release [28.14-1].
Created by command:

/usr/bin/tito tag
2018-06-07 09:18:26 -07:00
Brian C. Lane e1088fe6e9 New lorax documentation - 28.14 2018-06-07 09:18:10 -07:00
Brian C. Lane a1905c3b4b Add --dracut-arg support to lorax
Use it to override the default dracut arguments (displayed as part of
the --help output). If you want to extend the default arguments they
all need to be passed in on the cmdline as well. eg.

--dracut-arg='--xz' --dracut-arg='--install /.buildstamp' ...

Resolves: rhbz#1452220
(cherry picked from commit d8ce013a2b)
2018-06-07 09:01:42 -07:00
Brian C. Lane b9fe90000e gevent has deprecated .wsgi, should use .pywsgi instead
https://github.com/gevent/gevent/blob/master/doc/api/gevent.wsgi.rst
(cherry picked from commit c9ca451568)
2018-06-05 16:58:25 -07:00
Brian C. Lane fd2b5de02c Automatic commit of package [lorax] release [28.13-1].
Created by command:

/usr/bin/tito tag
2018-06-04 16:51:00 -07:00
Brian C. Lane d272304603 New lorax documentation - 28.13 2018-06-04 16:50:39 -07:00
Brian C. Lane d824d63b97 Override Sphinx documentation version with LORAX_VERSION
Normally you want to document the NEXT release, not the last. This
allows you to build the documentation using:

LORAX_VERSION="29.6" make docs

(cherry picked from commit d47d38e0c8)
2018-06-04 16:48:11 -07:00
Brian C. Lane 0314cbd0e8 Add support for sources to composer-cli
This adds the sources command which can be used to list, add, change,
and delete sources using the TOML formatted source file.

(cherry picked from commit 6f6ce410c0)
2018-06-04 15:48:41 -07:00
Brian C. Lane 693dc9a6f6 Fix DNF related issues with source selection
DNF Repo.dump() function cannot be used as a .repo file for dnf due to
it writing baseurl and gpgkey as a list instead of a string. Add a new
function to write this in the correct format, and limited to the fields
we use.

Add a test for the new function.

Fix /projects/source/info to return an error 400 if a nonexistant TOML
source is requested. If JSON is used the error is part of the standard
response.

Update test_server.py to check for the correct error code.

(cherry picked from commit afa89ea657)
2018-06-04 15:47:38 -07:00
Brian C. Lane 1ab33b6416 Fix handling bad source repos and add a test
When adding a source failed it wasn't being removed from the dnf object.
This fixes that, and returns an error when setting up the source fails.
Also adds a test for it.
This also includes detecting rawhide vs. non-rawhide releases and
adjusting the tests accordingly (some of the source names change).

(cherry picked from commit dd8e4d9e99)
2018-06-04 15:47:32 -07:00
Brian C. Lane 45f4d3e633 Speed up test_dnfbase.py
Calling get_base_object is no longer needed, this speeds things up by
not unnecessarily downloading metadata.

(cherry picked from commit 666d7f1e03)
2018-06-04 15:47:26 -07:00
Brian C. Lane d9d73a128b Make sure new sources show up in the source/list output
Also remove an unneeded makedirs from test_server.py

(cherry picked from commit 1034cfd9a7)
2018-06-04 15:47:20 -07:00
Brian C. Lane a283ec9582 Fix make_dnf_dirs
It was chopping off an extra directory level due to realpath removing
the trailing / from the paths when they are setup.

(cherry picked from commit 23f4b2a3ec)
2018-06-04 15:47:15 -07:00
Brian C. Lane f88fbc3fca Update test_server for rawhide
The system repo is 'rawhide' and the 'fedora' and 'updates' repos are
disabled.

(cherry picked from commit 22070dcf42)
2018-06-04 15:47:08 -07:00
Brian C. Lane 8ac04a1521 Add support for user defined package sources API
This lives under /api/v0/projects/source/*

See the documentation for details

(cherry picked from commit 6d677b2207)
2018-06-04 15:47:00 -07:00
Brian C. Lane 5548f5f1c7 Automatic commit of package [lorax] release [28.12-1].
Created by command:

/usr/bin/tito tag
2018-05-24 09:13:16 -07:00
Colin Walters e5ef195a3b templates: Stop using gconfset
We had only been indirectly pulling in GConf, and anyways
nothing was listening to these keys.

<kalev> I still think it's a fallout from 27a90d973f?branch=master

Really in general, if we wanted to make changes like this
it'd probably be a lot simpler to do them on boot or so.

https://bugzilla.redhat.com/show_bug.cgi?id=1581838
(cherry picked from commit bb3d8edd06)
2018-05-24 09:13:05 -07:00
Brian C. Lane 1af6040143 Add support for version globs to blueprints
This uses dnf's version__glob filter to implement it. It amounts to '*'
wildcards and '?' for single character matching.

(cherry picked from commit 095829171a)
2018-05-21 15:41:45 -07:00
Brian C. Lane 13234166f5 Update atlas blueprint
(cherry picked from commit d406fbdf83)
2018-05-21 15:41:45 -07:00
Brian C. Lane 9c7446f44c Automatic commit of package [lorax] release [28.11-1].
Created by command:

/usr/bin/tito tag
2018-05-17 13:13:17 -07:00
Brian C. Lane 140a736518 Update the generated html docs 2018-05-17 10:34:35 -07:00
Brian C. Lane dcb5c5b59a Update the README with relevant URLs
Time to point to the blog and to the online documentation.
2018-05-17 10:34:35 -07:00
Brian C. Lane 1fef566bb2 Fix documentation for enabling lorax-composer.socket
It needs to be enabled AND started for it to work.
2018-05-17 10:34:35 -07:00
Brian C. Lane 55b89d1aeb Add support for systemd socket activation
Instead of enabling lorax-composer.service enable lorax-composer.socket
and it will start lorax-composer on first access to
/run/weldr/api.socket
2018-05-17 10:34:35 -07:00
Brian C. Lane 680393de3d Add documentation for lorax-composer and composer-cli 2018-05-17 10:34:35 -07:00
Brian C. Lane e7f9028fca Move lorax-composer and composer-cli argument parsing into modules
This allows sphinx-argparse to document them automatically.
2018-05-17 10:34:35 -07:00
Brian C. Lane 8bd028e9d0 Update composer templates for use with Fedora 2018-05-17 10:34:35 -07:00
Brian C. Lane cd1d414e0e Add new cmdline args to compose_args settings 2018-05-17 10:34:35 -07:00
Brian C. Lane d68429071c lorax-composer also requires tar 2018-05-17 10:34:35 -07:00
Brian C. Lane e91aed9b10 Remove temporary files after run_compose
A crash can also leave temporary lmc-* files, remove them as well.
2018-05-17 10:34:35 -07:00
Brian C. Lane 611f5e62f3 Add --proxy to lorax-composer cmdline
Overrides the [dnf] proxy setting in the config file.
2018-05-17 10:34:35 -07:00
Brian C. Lane d9c4a6c951 Pass the --tmp value into run_creator and cleanup after a crash
Crashing can sometimes leave directories in /var/tmp/lmc-* so clean
those up after run_creator is finished.
2018-05-17 10:34:35 -07:00
Brian C. Lane 559b66b7e3 Add --tmp to lorax-composer and set default tempdir
It was using /tmp/ which can fill up quickly when building images.
Default to /var/tmp unless the user passes --tmp /tmp/
2018-05-17 10:34:35 -07:00
Brian C. Lane bb652368dc Set lorax_templates to the correct directory
Templates are under the share dir, so use find_templates() to find them.
2018-05-17 10:34:35 -07:00
Brian C. Lane d6283f9540 Adjust the disk size estimates to match Anaconda
First is Anaconda uses 6k blocks per file for its estimate, and it
fudges by 10% so adjust for those with an extra 10% of headroom just in
case.

Second is an Anaconda bug that won't allow it to do a kickstart install
to a disk smaller than 3000 MB. There is a PR to fix it upstream, but
for now the minimum size has to be 3000e9
2018-05-17 10:34:35 -07:00
Brian C. Lane 5443c1cfea Skip creating groups with the same name as a user
Otherwise the user creation fails when anaconda sees there is already a
group with that name. Log a warning and continue on.
2018-05-17 10:34:35 -07:00
Brian C. Lane cb7e4e55ba Add user and group creation to blueprint
[[customizations.user]] and [[customizations.group]]
2018-05-17 10:34:34 -07:00
Brian C. Lane 8839182f43 Add blueprint customization support for hostname and ssh key
This adds support for the optional blueprint section [customizations].

Use it like this:

[customizations]
hostname = yourhostnamehere

[[customizations.sshkey]]
user = root
key = root user key
2018-05-17 10:34:34 -07:00
Brian C. Lane df63cfddc5 Update setup.py for lorax-composer and composer-cli 2018-05-17 10:34:34 -07:00
Brian C. Lane fb58277028 Add composer-cli and tests 2018-05-17 10:34:34 -07:00
Brian C. Lane b67c821706 Fix the compose arguments for the Fedora version of Anaconda
This adds make_oci, and moves qcow2 to the more generic image_type
(which just uses qemu-img disk names).
2018-05-17 10:34:34 -07:00
Brian C. Lane b6e0ba2e45 Add selinux check to lorax-composer
anaconda needs to have SELinux set to disabled or permissive in order to
run correctly. Check at startup and exit with an error.
2018-05-17 10:34:34 -07:00
Brian C. Lane 01645a1faf Update test_server for blueprint and Yum to DNF changes. 2018-05-17 10:34:34 -07:00
Brian C. Lane e6145faf86 Convert Yum usage to DNF
The DNF api is similar, but not the same, as Yum. Make the needed
changes, and rename yum references to dnf to avoid confustion later.
2018-05-17 10:34:34 -07:00
Brian C. Lane c4a09c42cc workspace read and write needs UTF-8 conversion
reading needs to decode the bytes to str and writing needs to encode the
str to bytes.
2018-05-17 10:34:34 -07:00
Brian C. Lane 99cdd573a3 Return an empty list if depsolve results are empty 2018-05-17 10:34:34 -07:00
Brian C. Lane 6aa52b0b53 The git blob needs to be bytes
In py3 str is unicode so it needs to be encoded as UTF-8 when writing to
the blob.
2018-05-17 10:34:34 -07:00
Brian C. Lane 25e12f1971 Remove bin and sbin from nose
They are not packages and cannot be imported.
2018-05-17 10:34:34 -07:00
Brian C. Lane 8970b6758b Update the test blueprints
Change versions to match Fedora versions. Add version numbers to the
blueprints except for glusterfs.toml, not having a version is used as
part of the tests.
2018-05-17 10:34:34 -07:00
Brian C. Lane bb214b21ab Ignore more pylint errors 2018-05-17 10:34:34 -07:00
Brian C. Lane 0f59710b36 Use default commit sort order instead of TIME
Different versions of libgit2 act differently. Using TIME results in
some commits (like a revert) being listed correctly, but the rest being
listed in reverse order. Leaving it at the default works for
libgit2-0.26.3
2018-05-17 10:34:34 -07:00
Brian C. Lane cb0158ca22 Add lorax-composer and the composer kickstart templates 2018-05-17 10:34:34 -07:00
Brian C. Lane 9085840401 Update pylorax.api.projects for DNF usage
And adjust tests to match.
2018-05-17 10:34:34 -07:00
Brian C. Lane e1be281fbb Update dnfbase (formerly yumbase) for DNF support
And adjust tests to match.
2018-05-17 10:34:34 -07:00
Brian C. Lane 7fa009c66e Move core of livemedia-creator into pylorax.creator
This moves everything except the cmdline checking into run_creator in
pylorax.creator

It also rearranges some functions to prevent import loops, and adds a
utility function to imgutils (mkfsimage_from_disk for copying a
partition into a filesystem image).
2018-05-17 10:34:34 -07:00
Brian C. Lane 96a82b07d9 Update dnfbase tests 2018-05-17 10:34:34 -07:00
Brian C. Lane 25394eefb7 Convert lorax-composer yum base object to DNF
This no longer uses the enabled configuration setting to select repos to
use. It uses everything in the repo_dir, and if system repos have not
been disabled it copies them into the repo_dir at startup, overwriting
the previous copy.
2018-05-17 10:34:34 -07:00
Brian C. Lane 9bf93d7154 Use 2to3 to convert the python2 lorax-composer code to python3 2018-05-17 10:34:34 -07:00
Brian C. Lane b4096ccb62 Add the tests from lorax-composer branch
These currently fail for several reasons and will be adjusted as the
code it ported to this branch.
2018-05-17 10:34:34 -07:00
Brian C. Lane b3d6dab83b Update .dockerignore
Don't send .git to docker daemon
2018-05-17 10:34:34 -07:00
Brian C. Lane 263f1154a0 Update lorax.spec for lorax-composer
Add new subpackages for lorax-composer and composer-cli, and new requirements.
Trim changelog
Fix a couple of un-versioned Provides
2018-05-17 10:34:34 -07:00
Brian C. Lane fc56671638 livemedia-creator: Move core functions into pylorax modules
This reduces the amount of code in livemedia-creator to the cmdline
parsing and calling of the installer functions. Moving them into other
modules will allow them to be used by other projects, like the
lorax-composer API server.
2018-05-17 10:34:34 -07:00
Brian C. Lane 39673941a8 Check selinux state before creating output directory
This closes issue #163

(cherry picked from commit dc348fac25)
2018-05-17 10:34:34 -07:00
Dan Horák 1f48a5137d really kill kernel-bootwrapper on ppc
(cherry picked from commit 4a905bdfb0)
2018-05-17 10:33:55 -07:00
Brian C. Lane 8db9618768 Use Fedora 28 for Dockerfile.test 2018-05-16 11:07:56 -07:00
Alexander Todorov 5ab23e6567 Enable testing in Travis and collecting of coverage history
(cherry picked from commit 88139bcc03)
2018-05-16 10:52:39 -07:00
Brian C. Lane 751780664a Remove -boot-info-table from s390 boot.iso creation (#1478448)
It corrupts the kernel+initrd and isn't needed when booting on s390.

Related: rhbz#1478448
(cherry picked from commit 081da8859a)
2018-05-16 10:50:54 -07:00
Dan Horák 1c06fccfe8 change installed packages on ppc
- drop kernel-bootwrapper as it was used with 32-bit ppc
- replace ppc64-utils meta-package (to be retired) with the real requirements

(cherry picked from commit 1d32a0cb36)
2018-05-16 10:40:06 -07:00
Dan Horák 8ba16e8f15 drop support for 32-bit ppc
(cherry picked from commit d95cb93df0)
2018-05-16 10:39:58 -07:00
Dan Horák d569830f50 remove redundant mkdir
(cherry picked from commit 2fd3174684)
2018-05-16 10:39:51 -07:00
Brian C. Lane 63d144e5d9 Automatic commit of package [lorax] release [28.10-1].
Created by command:

/usr/bin/tito tag
2018-04-09 13:49:53 -07:00
Martin Kolman 16009e092e Fix anaconda metapackage name
"anaconda-install-deps" was the original placeholder name
of the metapackage and it looks like I forgot to change it
to "anaconda-install-env-deps", which is the final name
we have decided sounds better.

Oops! (it's even correct in the commit message...)

(cherry picked from commit db9e2a1e41)
Signed-off-by: Brian C. Lane <bcl@redhat.com>
2018-04-09 09:11:17 -07:00
Martin Kolman bd81fa5d60 Include the anaconda-install-env-deps metapackage
Use the anaconda-install-env-deps metapackage to pull in the
Anaconda dependencies needed in the installation environment.

The anaconda-install-env-deps metapackage lists all install time
dependencies and makes it possible for packages such as
Initial Setup to depend on Anaconda without pulling all
the (mainly storage related) install time dependencies
to the installed system.

The same is applicable for dirinstall which also does
not require the install time dependencies as it is just
installing to a local folder.

Also drop the tmux and gdb dependencies from the template as
both have been added to the metapackage to make install time
dependency tracking more consistent.

(cherry picked from commit 106f330bb2)
Signed-off-by: Brian C. Lane <bcl@redhat.com>
2018-04-09 09:11:17 -07:00
Brian C. Lane c417f8475d Update the URL in lorax.spec to point to new Lorax location
Moved to https://github.com/weldr/lorax

(cherry picked from commit 1cf2d8fe6f)
2018-03-19 13:45:22 -07:00
Brian C. Lane 0654552987 New lorax documentation - 28.9 2018-03-15 13:53:58 -07:00
Brian C. Lane fa28f2ba2e Automatic commit of package [lorax] release [28.9-1].
Created by command:

/usr/bin/tito tag
2018-03-15 13:52:45 -07:00
Brian C. Lane 3b1933b400 Update default releasever to Fedora 28 2018-03-15 13:52:20 -07:00
Brian C. Lane a85ef02dca Update Copyright year to 2018 in Sphinx docs
(cherry picked from commit 6a161ade95eec18dabd5eb22ac8e3139017bcb10)
2018-03-15 13:50:28 -07:00
Brian C. Lane fe83f251df make docs now also builds html
(cherry picked from commit 2ed8b7f86e)
2018-03-15 13:50:12 -07:00
279 changed files with 46690 additions and 5396 deletions

3
.coveragerc Normal file
View File

@ -0,0 +1,3 @@
[paths]
source = .
/lorax/

2
.dockerignore Normal file
View File

@ -0,0 +1,2 @@
.git/
.coverage

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ tests/pylint/.pylint.d/
__pycache__/
.coverage
pylint-log
.pytest_cache/

23
.travis.yml Normal file
View File

@ -0,0 +1,23 @@
sudo: required
language: python
services:
- docker
script:
- make test-in-docker
after_success:
- |
sudo docker create --name results-cont welder/lorax /bin/echo
sudo docker cp results-cont:/lorax/.coverage .coverage.docker
sudo docker rm results-cont
pip install coverage coveralls
coverage combine
coveralls
notifications:
email:
on_failure: change
on_success: never

35
Dockerfile.test Normal file
View File

@ -0,0 +1,35 @@
FROM fedora:28
RUN dnf -y install \
anaconda-tui \
libgit2-glib \
libselinux-python3 \
make \
pykickstart \
python3-coverage \
python3-coveralls \
python3-flask \
python3-gevent \
python3-mako \
python3-nose \
python3-pocketlint \
python3-pylint \
python3-pytoml \
python3-semantic_version \
python3-sphinx \
python3-rpmfluff \
beakerlib \
sudo \
tito \
which
RUN useradd weldr
RUN mkdir /lorax
COPY . /lorax
# remove byte-compiled files to avoid issues between Python 2/3
# this can happen when you switch between rhel7 and master branches
RUN find /lorax -name "*.pyc" -exec rm -f {} \;
WORKDIR /lorax
RUN make check test

31
HACKING.md Normal file
View File

@ -0,0 +1,31 @@
# Hacking on Lorax
Here's where to get the code:
$ git clone https://github.com/weldr/lorax
$ cd lorax/
How to build it:
$ make
## How to run the tests
To run the tests you need the following dependencies installed:
$ yum install python3-nose python3-pytest-mock python3-pocketlint \
python3-mock
Run the basic linting tests like this:
$ make check
To run the broader unit and integration tests we use:
$ make test
Some of the tests will be skipped unless a lorax-composer process is running
and listening on an accessible socket. Either run lorax-composer from the
checkout, or the installed version.

View File

@ -1,5 +1,7 @@
PYTHON ?= /usr/bin/python3
DESTDIR ?= /
PREFIX ?= /usr
mandir ?= $(PREFIX)/share/man
PKGNAME = lorax
VERSION = $(shell awk '/Version:/ { print $$2 }' $(PKGNAME).spec)
@ -9,17 +11,24 @@ TAG = lorax-$(VERSION)-$(RELEASE)
default: all
src/composer/version.py: lorax.spec
echo "num = '$(VERSION)-$(RELEASE)'" > src/composer/version.py
src/pylorax/version.py: lorax.spec
echo "num = '$(VERSION)-$(RELEASE)'" > src/pylorax/version.py
all: src/pylorax/version.py
all: src/pylorax/version.py src/composer/version.py
$(PYTHON) setup.py build
install: all
$(PYTHON) setup.py install --root=$(DESTDIR)
$(PYTHON) setup.py install --root=$(DESTDIR) --prefix=$(PREFIX)
mkdir -p $(DESTDIR)/$(mandir)/man1
install -m 644 docs/man/lorax.1 $(DESTDIR)/$(mandir)/man1
install -m 644 docs/man/livemedia-creator.1 $(DESTDIR)/$(mandir)/man1
install -m 644 docs/man/lorax-composer.1 $(DESTDIR)/$(mandir)/man1
install -m 644 docs/man/composer-cli.1 $(DESTDIR)/$(mandir)/man1
mkdir -p $(DESTDIR)/etc/bash_completion.d
install -m 644 etc/bash_completion.d/composer-cli $(DESTDIR)/etc/bash_completion.d
check:
@echo "*** Running pylint ***"
@ -28,21 +37,25 @@ check:
test:
@echo "*** Running tests ***"
PYTHONPATH=$(PYTHONPATH):./src/ $(PYTHON) -m nose -v --with-coverage --cover-erase --cover-branches \
--cover-package=pylorax --cover-package=bin --cover-package=sbin --cover-inclusive \
./tests/pylorax/
--cover-package=pylorax --cover-inclusive \
./tests/pylorax/ ./tests/composer/
coverage3 report -m
[ -f "/usr/bin/coveralls" ] && [ -n "$(COVERALLS_REPO_TOKEN)" ] && coveralls || echo
./tests/test_cli.sh
clean:
-rm -rf build src/pylorax/version.py
-rm -rf build src/composer/version.py
tag:
git tag -f $(TAG)
docs:
$(MAKE) -C docs apidoc
$(MAKE) -C docs apidoc html man
archive:
@git archive --format=tar --prefix=$(PKGNAME)-$(VERSION)/ $(TAG) > $(PKGNAME)-$(VERSION).tar
@ -61,4 +74,9 @@ local:
@rm -rf /var/tmp/$(PKGNAME)-$(VERSION)
@echo "The archive is in $(PKGNAME)-$(VERSION).tar.gz"
test-in-docker:
sudo docker build -t welder/lorax:latest -f Dockerfile.test .
ci: check test
.PHONY: docs

51
README
View File

@ -1,51 +0,0 @@
I am the Lorax. I speak for the trees [and images].
Tree building tools such as pungi and revisor rely on 'buildinstall' in
anaconda/scripts/ to produce the boot images and other such control files
in the final tree. The existing buildinstall scripts written in a mix of
bash and Python are unmaintainable. Lorax is an attempt to replace them
with something more flexible.
EXISTING WORKFLOW:
pungi and other tools call scripts/buildinstall, which in turn call other
scripts to do the image building and data generation. Here's how it
currently looks:
-> buildinstall
* process command line options
* write temporary yum.conf to point to correct repo
* find anaconda release RPM
* unpack RPM, pull in those versions of upd-instroot, mk-images,
maketreeinfo.py, makestamp.py, and buildinstall
-> call upd-instroot
-> call maketreeinfo.py
-> call mk-images (which figures out which mk-images.ARCH to call)
-> call makestamp.py
* clean up
PROBLEMS:
The existing workflow presents some problems with maintaining the scripts.
First, almost all knowledge of what goes in to the stage 1 and stage 2
images lives in upd-instroot. The mk-images* scripts copy things from the
root created by upd-instroot in order to build the stage 1 image, though
it's not completely clear from reading the scripts.
NEW IDEAS:
Create a new central driver with all information living in Python modules.
Configuration files will provide the knowledge previously contained in the
upd-instroot and mk-images* scripts.
--
David Cantrell <dcantrell@redhat.com>

7
README.md Normal file
View File

@ -0,0 +1,7 @@
Lorax is a set of tools used to create bootable images.
* lorax - creates the Anaconda boot.iso used to install Fedora
* livemedia-creator - uses Anaconda to create bootable images
* lorax-composer - API server implementing the Weldr BDCS protocol using livemedia-creator
See the [Weldr blog](https://weldr.io) for more info about BDCS and the [Lorax documentation](https://weldr.io/lorax) for more information about Lorax and associated tools.

62
docs/composer-cli.rst Normal file
View File

@ -0,0 +1,62 @@
composer-cli
============
:Authors:
Brian C. Lane <bcl@redhat.com>
``composer-cli`` is used to interact with the ``lorax-composer`` API server, managing blueprints, exploring available packages, and building new images.
It requires `lorax-composer <lorax-composer.html>`_ to be installed on the
local system, and the user running it needs to be a member of the ``weldr``
group. They do not need to be root, but all of the `security precautions
<lorax-composer.html#security>`_ apply.
composer-cli cmdline arguments
------------------------------
.. argparse::
:ref: composer.cli.cmdline.composer_cli_parser
:prog: composer-cli
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
<https://github.com/weldr/lorax/tree/master/tests/pylorax/blueprints/>`_.
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``.
Build an image
----------------
Build a ``qcow2`` disk image from this blueprint by running ``composer-cli
compose start http-server qcow2``. It will print a UUID that you can use to
keep track of the build. You can also cancel the build if needed.
The available types of images is displayed by ``composer-cli compose types``.
Currently this consists of: ami, ext4-filesystem, live-iso, partitioned-disk,
qcow2, tar, vhd, vmdk
Monitor the build status
------------------------
Monitor it using ``composer-cli compose status``, which will show the status of
all the builds on the system. You can view the end of the anaconda build logs
once it is in the ``RUNNING`` state using ``composer-cli compose log UUID``
where UUID is the UUID returned by the start command.
Once the build is in the ``FINISHED`` state you can download the image.
Download the image
------------------
Downloading the final image is done with ``composer-cli compose image UUID`` and it will
save the qcow2 image as ``UUID-disk.qcow2`` which you can then use to boot a VM like this::
qemu-kvm --name test-image -m 1024 -hda ./UUID-disk.qcow2

View File

@ -51,13 +51,17 @@ master_doc = 'index'
# General information about the project.
project = u'Lorax'
copyright = u'2015, Red Hat, Inc.' # pylint: disable=redefined-builtin
copyright = u'2018, Red Hat, Inc.' # pylint: disable=redefined-builtin
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
def read_version():
""" Read version from ../lorax.spec"""
"""Read version from $LORAX_VERSION or ../lorax.spec"""
# This allows the .spec version to be overridded. eg. when documenting an upcoming release
if "LORAX_VERSION" in os.environ:
return os.environ["LORAX_VERSION"]
import re
version_re = re.compile(r"Version:\s+(.*)")
with open("../lorax.spec", "rt") as f:
@ -155,6 +159,9 @@ html_static_path = ['_static']
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# Turn off smartquotes, it mangles dashes in the docstrings
smartquotes = False
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
@ -214,7 +221,7 @@ latex_elements = {
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'Lorax.tex', u'Lorax Documentation',
u'Anaconda Team', 'manual'),
u'Weldr Team', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@ -243,8 +250,10 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('lorax', 'lorax', u'Lorax Documentation', [u'Anaconda Team'], 1),
('livemedia-creator', 'livemedia-creator', u'Live Media Creator Documentation', [u'Anaconda Team'], 1)
('lorax', 'lorax', u'Lorax Documentation', [u'Weldr Team'], 1),
('livemedia-creator', 'livemedia-creator', u'Live Media Creator Documentation', [u'Weldr Team'], 1),
('lorax-composer', 'lorax-composer', u'Lorax Composer Documentation', [u'Weldr Team'], 1),
('composer-cli', 'composer-cli', u'Composer Cmdline Utility Documentation', [u'Weldr Team'], 1),
]
# If true, show URL addresses after external links.
@ -258,7 +267,7 @@ man_pages = [
# dir menu entry, description, category)
texinfo_documents = [
('index', 'Lorax', u'Lorax Documentation',
u'Anaconda Team', 'Lorax', 'One line description of project.',
u'Weldr Team', 'Lorax', 'One line description of project.',
'Miscellaneous'),
]
@ -279,9 +288,9 @@ texinfo_documents = [
# Bibliographic Dublin Core info.
epub_title = u'Lorax'
epub_author = u'Anaconda Team'
epub_publisher = u'Anaconda Team'
epub_copyright = u'2015, Red Hat, Inc.'
epub_author = u'Weldr Team'
epub_publisher = u'Weldr Team'
epub_copyright = u'2018, Red Hat, Inc.'
# The basename for the epub file. It defaults to the project name.
#epub_basename = u'src'
@ -388,6 +397,6 @@ class Mock(object):
def __getitem__(cls, key):
return cls.__getattr__(key)
MOCK_MODULES = ["selinux", "dnf", "rpmUtils", "rpmUtils.arch"]
MOCK_MODULES = ["selinux", "dnf", "dnf.logging", "dnf.transaction", "rpmUtils", "rpmUtils.arch"]
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = Mock()

View File

@ -30,6 +30,7 @@ bootloader --location=none
clearpart --all --initlabel
rootpw rootme
# Disk partitioning information
reqpart
part / --size=6656
%post

View File

@ -29,6 +29,7 @@ bootloader --location=mbr
# Partition clearing information
clearpart --all --initlabel
# Disk partitioning information
reqpart
part / --fstype="ext4" --size=4000
part swap --size=1000

View File

@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: f1415c4a8da85a626a1e43de08e00a62
config: 7b4b3984ba08dffb8c3213c34827d061
tags: 645f666f9bcd5a90fca523b33c5a78b7

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Overview: module code &mdash; Lorax 28.2 documentation</title>
<title>Overview: module code &mdash; Lorax 28.21 documentation</title>
@ -24,25 +24,17 @@
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../genindex.html"/>
<link rel="search" title="Search" href="../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../index.html"/>
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<script src="../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -64,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -93,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../modules.html">pylorax</a></li>
</ul>
@ -106,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">Lorax</a>
@ -114,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -144,8 +139,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -158,14 +151,28 @@
<h1>All modules for which code is available</h1>
<ul><li><a href="pylorax.html">pylorax</a></li>
<ul><li><a href="pylorax/base.html">pylorax.base</a></li>
<ul><li><a href="pylorax/api/cmdline.html">pylorax.api.cmdline</a></li>
<li><a href="pylorax/api/compose.html">pylorax.api.compose</a></li>
<li><a href="pylorax/api/config.html">pylorax.api.config</a></li>
<li><a href="pylorax/api/crossdomain.html">pylorax.api.crossdomain</a></li>
<li><a href="pylorax/api/dnfbase.html">pylorax.api.dnfbase</a></li>
<li><a href="pylorax/api/projects.html">pylorax.api.projects</a></li>
<li><a href="pylorax/api/queue.html">pylorax.api.queue</a></li>
<li><a href="pylorax/api/recipes.html">pylorax.api.recipes</a></li>
<li><a href="pylorax/api/server.html">pylorax.api.server</a></li>
<li><a href="pylorax/api/v0.html">pylorax.api.v0</a></li>
<li><a href="pylorax/api/workspace.html">pylorax.api.workspace</a></li>
<li><a href="pylorax/base.html">pylorax.base</a></li>
<li><a href="pylorax/buildstamp.html">pylorax.buildstamp</a></li>
<li><a href="pylorax/cmdline.html">pylorax.cmdline</a></li>
<li><a href="pylorax/creator.html">pylorax.creator</a></li>
<li><a href="pylorax/decorators.html">pylorax.decorators</a></li>
<li><a href="pylorax/discinfo.html">pylorax.discinfo</a></li>
<li><a href="pylorax/dnfbase.html">pylorax.dnfbase</a></li>
<li><a href="pylorax/dnfhelper.html">pylorax.dnfhelper</a></li>
<li><a href="pylorax/executils.html">pylorax.executils</a></li>
<li><a href="pylorax/imgutils.html">pylorax.imgutils</a></li>
<li><a href="pylorax/installer.html">pylorax.installer</a></li>
<li><a href="pylorax/ltmpl.html">pylorax.ltmpl</a></li>
<li><a href="pylorax/monitor.html">pylorax.monitor</a></li>
<li><a href="pylorax/mount.html">pylorax.mount</a></li>
@ -175,9 +182,7 @@
</ul></ul>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -186,11 +191,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -205,35 +210,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax &mdash; Lorax 28.2 documentation</title>
<title>pylorax &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../genindex.html"/>
<link rel="search" title="Search" href="../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../index.html"/>
<link rel="up" title="Module code" href="index.html"/>
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<script src="../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -147,8 +141,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -220,6 +212,8 @@
<span class="k">else</span><span class="p">:</span>
<span class="n">vernum</span> <span class="o">=</span> <span class="n">pylorax</span><span class="o">.</span><span class="n">version</span><span class="o">.</span><span class="n">num</span>
<span class="n">DRACUT_DEFAULT</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;--xz&quot;</span><span class="p">,</span> <span class="s2">&quot;--install&quot;</span><span class="p">,</span> <span class="s2">&quot;/.buildstamp&quot;</span><span class="p">,</span> <span class="s2">&quot;--no-early-microcode&quot;</span><span class="p">,</span> <span class="s2">&quot;--add&quot;</span><span class="p">,</span> <span class="s2">&quot;fips&quot;</span><span class="p">]</span>
<span class="c1"># List of drivers to remove on ppc64 arch to keep initrd &lt; 32MiB</span>
<span class="n">REMOVE_PPC64_DRIVERS</span> <span class="o">=</span> <span class="s2">&quot;floppy scsi_debug nouveau radeon cirrus mgag200&quot;</span>
<span class="n">REMOVE_PPC64_MODULES</span> <span class="o">=</span> <span class="s2">&quot;drm plymouth&quot;</span>
@ -342,7 +336,8 @@
<span class="n">add_template_vars</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">add_arch_templates</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">add_arch_template_vars</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">verify</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="n">verify</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">user_dracut_args</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">_configured</span>
@ -370,6 +365,8 @@
<span class="bp">self</span><span class="o">.</span><span class="n">init_file_logging</span><span class="p">(</span><span class="n">logdir</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;version is </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">vernum</span><span class="p">)</span>
<span class="n">log_selinux_state</span><span class="p">()</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;using work directory </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">workdir</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;using log directory </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">logdir</span><span class="p">)</span>
@ -385,22 +382,6 @@
<span class="n">logger</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s2">&quot;no root privileges&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># is selinux disabled?</span>
<span class="c1"># With selinux in enforcing mode the rpcbind package required for</span>
<span class="c1"># dracut nfs module, which is in turn required by anaconda module,</span>
<span class="c1"># will not get installed, because it&#39;s preinstall scriptlet fails,</span>
<span class="c1"># resulting in an incomplete initial ramdisk image.</span>
<span class="c1"># The reason is that the scriptlet runs tools from the shadow-utils</span>
<span class="c1"># package in chroot, particularly groupadd and useradd to add the</span>
<span class="c1"># required rpc group and rpc user. This operation fails, because</span>
<span class="c1"># the selinux context on files in the chroot, that the shadow-utils</span>
<span class="c1"># tools need to access (/etc/group, /etc/passwd, /etc/shadow etc.),</span>
<span class="c1"># is wrong and selinux therefore disallows access to these files.</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;checking the selinux mode&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">selinux</span><span class="o">.</span><span class="n">is_selinux_enabled</span><span class="p">()</span> <span class="ow">and</span> <span class="n">selinux</span><span class="o">.</span><span class="n">security_getenforce</span><span class="p">():</span>
<span class="n">logger</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s2">&quot;selinux must be disabled or in Permissive mode&quot;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># do we have a proper dnf base object?</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;checking dnf base object&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">dnf</span><span class="o">.</span><span class="n">Base</span><span class="p">):</span>
@ -443,7 +424,8 @@
<span class="c1"># write .buildstamp</span>
<span class="n">buildstamp</span> <span class="o">=</span> <span class="n">BuildStamp</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">bugurl</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">isfinal</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">buildarch</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">bugurl</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">isfinal</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">arch</span><span class="o">.</span><span class="n">buildarch</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">product</span><span class="o">.</span><span class="n">variant</span><span class="p">)</span>
<span class="n">buildstamp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inroot</span><span class="p">,</span> <span class="s2">&quot;.buildstamp&quot;</span><span class="p">))</span>
@ -503,7 +485,13 @@
<span class="n">workdir</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">workdir</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;rebuilding initramfs images&quot;</span><span class="p">)</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;--xz&quot;</span><span class="p">,</span> <span class="s2">&quot;--install&quot;</span><span class="p">,</span> <span class="s2">&quot;/.buildstamp&quot;</span><span class="p">,</span> <span class="s2">&quot;--no-early-microcode&quot;</span><span class="p">,</span> <span class="s2">&quot;--add&quot;</span><span class="p">,</span> <span class="s2">&quot;fips&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">user_dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="n">DRACUT_DEFAULT</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">user_dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">anaconda_args</span> <span class="o">=</span> <span class="n">dracut_args</span> <span class="o">+</span> <span class="p">[</span><span class="s2">&quot;--add&quot;</span><span class="p">,</span> <span class="s2">&quot;anaconda pollcdrom qemu qemu-net&quot;</span><span class="p">]</span>
<span class="c1"># ppc64 cannot boot an initrd &gt; 32MiB so remove some drivers</span>
@ -514,6 +502,8 @@
<span class="c1"># upgrade.img</span>
<span class="n">anaconda_args</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="s2">&quot;--omit&quot;</span><span class="p">,</span> <span class="n">REMOVE_PPC64_MODULES</span><span class="p">])</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;dracut args = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">dracut_args</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;anaconda args = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">anaconda_args</span><span class="p">)</span>
<span class="n">treebuilder</span><span class="o">.</span><span class="n">rebuild_initrds</span><span class="p">(</span><span class="n">add_args</span><span class="o">=</span><span class="n">anaconda_args</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;populating output tree and building boot images&quot;</span><span class="p">)</span>
@ -603,12 +593,20 @@
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">return</span> <span class="n">templatedir</span></div>
<div class="viewcode-block" id="log_selinux_state"><a class="viewcode-back" href="../pylorax.html#pylorax.log_selinux_state">[docs]</a><span class="k">def</span> <span class="nf">log_selinux_state</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;Log the current state of selinux&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">selinux</span><span class="o">.</span><span class="n">is_selinux_enabled</span><span class="p">():</span>
<span class="k">if</span> <span class="n">selinux</span><span class="o">.</span><span class="n">security_getenforce</span><span class="p">():</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;selinux is enabled and in Enforcing mode&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;selinux is enabled and in Permissive mode&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;selinux is Disabled&quot;</span><span class="p">)</span></div>
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -617,11 +615,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -636,35 +634,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -0,0 +1,277 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.cmdline &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.cmdline</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.cmdline</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># cmdline.py</span>
<span class="c1">#</span>
<span class="c1"># Copyright (C) 2018 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">argparse</span>
<span class="kn">from</span> <span class="nn">pylorax</span> <span class="k">import</span> <span class="n">vernum</span>
<span class="n">version</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{0}</span><span class="s2">-</span><span class="si">{1}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">vernum</span><span class="p">)</span>
<div class="viewcode-block" id="lorax_composer_parser"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.cmdline.lorax_composer_parser">[docs]</a><span class="k">def</span> <span class="nf">lorax_composer_parser</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot; Return the ArgumentParser for lorax-composer&quot;&quot;&quot;</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Lorax Composer API Server&quot;</span><span class="p">,</span>
<span class="n">fromfile_prefix_chars</span><span class="o">=</span><span class="s2">&quot;@&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--socket&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;/run/weldr/api.socket&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;SOCKET&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Path to the socket file to listen on&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--user&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;weldr&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;USER&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;User to use for reduced permissions&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--group&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;weldr&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;GROUP&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Group to set ownership of the socket to&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--log&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;logfile&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;/var/log/lorax-composer/composer.log&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;LOG&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Path to logfile (/var/log/lorax-composer/composer.log)&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--mockfiles&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;/var/tmp/bdcs-mockfiles/&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;MOCKFILES&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Path to JSON files used for /api/mock/ paths (/var/tmp/bdcs-mockfiles/)&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--sharedir&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;SHAREDIR&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Directory containing all the templates. Overrides config file sharedir&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-V&quot;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_true&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;showver&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;show program&#39;s version number and exit&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-c&quot;</span><span class="p">,</span> <span class="s2">&quot;--config&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;/etc/lorax/composer.conf&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;CONFIG&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Path to lorax-composer configuration file.&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--releasever&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;STRING&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Release version to use for $releasever in dnf repository urls&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--tmp&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;/var/tmp&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Top level temporary directory&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--proxy&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;PROXY&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Set proxy for DNF, overrides configuration file setting.&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--no-system-repos&quot;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_true&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Do not copy over system repos from /etc/yum.repos.d/ at startup&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;BLUEPRINTS&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;BLUEPRINTS&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Path to the blueprints&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">parser</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -0,0 +1,897 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.compose &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.compose</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.compose</h1><div class="highlight"><pre>
<span></span><span class="c1"># Copyright (C) 2018 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&quot;&quot;&quot; Setup for composing an image</span>
<span class="sd">Adding New Output Types</span>
<span class="sd">-----------------------</span>
<span class="sd">The new output type must add a kickstart template to ./share/composer/ where the</span>
<span class="sd">name of the kickstart (without the trailing .ks) matches the entry in compose_args.</span>
<span class="sd">The kickstart should not have any url or repo entries, these will be added at build</span>
<span class="sd">time. The %packages section should be the last thing, and while it can contain mandatory</span>
<span class="sd">packages required by the output type, it should not have the trailing %end because the</span>
<span class="sd">package NEVRAs will be appended to it at build time.</span>
<span class="sd">compose_args should have a name matching the kickstart, and it should set the novirt_install</span>
<span class="sd">parameters needed to generate the desired output. Other types should be set to False.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;lorax-composer&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="k">import</span> <span class="n">glob</span>
<span class="kn">from</span> <span class="nn">math</span> <span class="k">import</span> <span class="n">ceil</span>
<span class="kn">import</span> <span class="nn">pytoml</span> <span class="k">as</span> <span class="nn">toml</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">from</span> <span class="nn">uuid</span> <span class="k">import</span> <span class="n">uuid4</span>
<span class="kn">from</span> <span class="nn">pyanaconda.simpleconfig</span> <span class="k">import</span> <span class="n">SimpleConfigFile</span>
<span class="c1"># Use pykickstart to calculate disk image size</span>
<span class="kn">from</span> <span class="nn">pykickstart.parser</span> <span class="k">import</span> <span class="n">KickstartParser</span>
<span class="kn">from</span> <span class="nn">pykickstart.version</span> <span class="k">import</span> <span class="n">makeVersion</span>
<span class="kn">from</span> <span class="nn">pylorax.api.projects</span> <span class="k">import</span> <span class="n">projects_depsolve</span><span class="p">,</span> <span class="n">projects_depsolve_with_size</span><span class="p">,</span> <span class="n">dep_nevra</span>
<span class="kn">from</span> <span class="nn">pylorax.api.projects</span> <span class="k">import</span> <span class="n">ProjectsError</span>
<span class="kn">from</span> <span class="nn">pylorax.api.recipes</span> <span class="k">import</span> <span class="n">read_recipe_and_id</span>
<span class="kn">from</span> <span class="nn">pylorax.api.timestamp</span> <span class="k">import</span> <span class="n">TS_CREATED</span><span class="p">,</span> <span class="n">write_timestamp</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="k">import</span> <span class="n">default_image_name</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="k">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="test_templates"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.test_templates">[docs]</a><span class="k">def</span> <span class="nf">test_templates</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">share_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Try depsolving each of the the templates and report any errors</span>
<span class="sd"> :param dbo: dnf base object</span>
<span class="sd"> :type dbo: dnf.Base</span>
<span class="sd"> :returns: List of template types and errors</span>
<span class="sd"> :rtype: List of errors</span>
<span class="sd"> Return a list of templates and errors encountered or an empty list</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">template_errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">compose_type</span> <span class="ow">in</span> <span class="n">compose_types</span><span class="p">(</span><span class="n">share_dir</span><span class="p">):</span>
<span class="c1"># Read the kickstart template for this type</span>
<span class="n">ks_template_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">share_dir</span><span class="p">,</span> <span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="n">compose_type</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;.ks&quot;</span>
<span class="n">ks_template</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">ks_template_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="c1"># How much space will the packages in the default template take?</span>
<span class="n">ks_version</span> <span class="o">=</span> <span class="n">makeVersion</span><span class="p">()</span>
<span class="n">ks</span> <span class="o">=</span> <span class="n">KickstartParser</span><span class="p">(</span><span class="n">ks_version</span><span class="p">,</span> <span class="n">errorsAreFatal</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">missingIncludeIsFatal</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">ks</span><span class="o">.</span><span class="n">readKickstartFromString</span><span class="p">(</span><span class="n">ks_template</span><span class="o">+</span><span class="s2">&quot;</span><span class="se">\n</span><span class="si">%e</span><span class="s2">nd</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">pkgs</span> <span class="o">=</span> <span class="p">[(</span><span class="n">name</span><span class="p">,</span> <span class="s2">&quot;*&quot;</span><span class="p">)</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">packages</span><span class="o">.</span><span class="n">packageList</span><span class="p">]</span>
<span class="n">grps</span> <span class="o">=</span> <span class="p">[</span><span class="n">grp</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">grp</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">packages</span><span class="o">.</span><span class="n">groupList</span><span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">_</span> <span class="o">=</span> <span class="n">projects_depsolve</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">pkgs</span><span class="p">,</span> <span class="n">grps</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ProjectsError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">template_errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;Error depsolving </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">compose_type</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">template_errors</span></div>
<div class="viewcode-block" id="repo_to_ks"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.repo_to_ks">[docs]</a><span class="k">def</span> <span class="nf">repo_to_ks</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">url</span><span class="o">=</span><span class="s2">&quot;url&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Return a kickstart line with the correct args.</span>
<span class="sd"> :param r: DNF repository information</span>
<span class="sd"> :type r: dnf.Repo</span>
<span class="sd"> :param url: &quot;url&quot; or &quot;baseurl&quot; to use for the baseurl parameter</span>
<span class="sd"> :type url: str</span>
<span class="sd"> :returns: kickstart command arguments for url/repo command</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> Set url to &quot;baseurl&quot; if it is a repo, leave it as &quot;url&quot; for the installation url.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># url uses --url not --baseurl</span>
<span class="k">if</span> <span class="n">r</span><span class="o">.</span><span class="n">baseurl</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s1">&#39;--</span><span class="si">%s</span><span class="s1">=&quot;</span><span class="si">%s</span><span class="s1">&quot; &#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">r</span><span class="o">.</span><span class="n">baseurl</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">elif</span> <span class="n">r</span><span class="o">.</span><span class="n">metalink</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s1">&#39;--metalink=&quot;</span><span class="si">%s</span><span class="s1">&quot; &#39;</span> <span class="o">%</span> <span class="n">r</span><span class="o">.</span><span class="n">metalink</span>
<span class="k">elif</span> <span class="n">r</span><span class="o">.</span><span class="n">mirrorlist</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s1">&#39;--mirrorlist=&quot;</span><span class="si">%s</span><span class="s1">&quot; &#39;</span> <span class="o">%</span> <span class="n">r</span><span class="o">.</span><span class="n">mirrorlist</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Repo has no baseurl, metalink, or mirrorlist&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">r</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s1">&#39;--proxy=&quot;</span><span class="si">%s</span><span class="s1">&quot; &#39;</span> <span class="o">%</span> <span class="n">r</span><span class="o">.</span><span class="n">proxy</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">r</span><span class="o">.</span><span class="n">sslverify</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">+=</span> <span class="s1">&#39;--noverifyssl&#39;</span>
<span class="k">return</span> <span class="n">cmd</span></div>
<div class="viewcode-block" id="write_ks_root"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.write_ks_root">[docs]</a><span class="k">def</span> <span class="nf">write_ks_root</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">user</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Write kickstart root password and sshkey entry</span>
<span class="sd"> :param f: kickstart file object</span>
<span class="sd"> :type f: open file object</span>
<span class="sd"> :param user: A blueprint user dictionary</span>
<span class="sd"> :type user: dict</span>
<span class="sd"> :returns: True if it wrote a rootpw command to the kickstart</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> If the entry contains a ssh key, use sshkey to write it</span>
<span class="sd"> If it contains password, use rootpw to set it</span>
<span class="sd"> root cannot be used with the user command. So only key and password are supported</span>
<span class="sd"> for root.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">wrote_rootpw</span> <span class="o">=</span> <span class="kc">False</span>
<span class="c1"># ssh key uses the sshkey kickstart command</span>
<span class="k">if</span> <span class="s2">&quot;key&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;sshkey --user </span><span class="si">%s</span><span class="s1"> &quot;</span><span class="si">%s</span><span class="s1">&quot;</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">]))</span>
<span class="k">if</span> <span class="s2">&quot;password&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">user</span><span class="p">[</span><span class="s2">&quot;password&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">prefix</span><span class="p">)</span> <span class="k">for</span> <span class="n">prefix</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;$2b$&quot;</span><span class="p">,</span> <span class="s2">&quot;$6$&quot;</span><span class="p">,</span> <span class="s2">&quot;$5$&quot;</span><span class="p">]):</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Detected pre-crypted password&quot;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;rootpw --iscrypted &quot;</span><span class="si">%s</span><span class="s1">&quot;</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;password&quot;</span><span class="p">])</span>
<span class="n">wrote_rootpw</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Detected plaintext password&quot;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;rootpw --plaintext &quot;</span><span class="si">%s</span><span class="s1">&quot;</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;password&quot;</span><span class="p">])</span>
<span class="n">wrote_rootpw</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">return</span> <span class="n">wrote_rootpw</span></div>
<div class="viewcode-block" id="write_ks_user"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.write_ks_user">[docs]</a><span class="k">def</span> <span class="nf">write_ks_user</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">user</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Write kickstart user and sshkey entry</span>
<span class="sd"> :param f: kickstart file object</span>
<span class="sd"> :type f: open file object</span>
<span class="sd"> :param user: A blueprint user dictionary</span>
<span class="sd"> :type user: dict</span>
<span class="sd"> If the entry contains a ssh key, use sshkey to write it</span>
<span class="sd"> All of the user fields are optional, except name, write out a kickstart user entry</span>
<span class="sd"> with whatever options are relevant.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># ssh key uses the sshkey kickstart command</span>
<span class="k">if</span> <span class="s2">&quot;key&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;sshkey --user </span><span class="si">%s</span><span class="s1"> &quot;</span><span class="si">%s</span><span class="s1">&quot;</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">]))</span>
<span class="c1"># Write out the user kickstart command, much of it is optional</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;user --name </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="s2">&quot;home&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --homedir </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;home&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="s2">&quot;password&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">user</span><span class="p">[</span><span class="s2">&quot;password&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">prefix</span><span class="p">)</span> <span class="k">for</span> <span class="n">prefix</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;$2b$&quot;</span><span class="p">,</span> <span class="s2">&quot;$6$&quot;</span><span class="p">,</span> <span class="s2">&quot;$5$&quot;</span><span class="p">]):</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Detected pre-crypted password&quot;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --iscrypted&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Detected plaintext password&quot;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --plaintext&quot;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --password </span><span class="se">\&quot;</span><span class="si">%s</span><span class="se">\&quot;</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;password&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="s2">&quot;shell&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --shell </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;shell&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="s2">&quot;uid&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --uid </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">int</span><span class="p">(</span><span class="n">user</span><span class="p">[</span><span class="s2">&quot;uid&quot;</span><span class="p">]))</span>
<span class="k">if</span> <span class="s2">&quot;gid&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --gid </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">int</span><span class="p">(</span><span class="n">user</span><span class="p">[</span><span class="s2">&quot;gid&quot;</span><span class="p">]))</span>
<span class="k">if</span> <span class="s2">&quot;description&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --gecos </span><span class="se">\&quot;</span><span class="si">%s</span><span class="se">\&quot;</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;description&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="s2">&quot;groups&quot;</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --groups </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">user</span><span class="p">[</span><span class="s2">&quot;groups&quot;</span><span class="p">]))</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="write_ks_group"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.write_ks_group">[docs]</a><span class="k">def</span> <span class="nf">write_ks_group</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">group</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Write kickstart group entry</span>
<span class="sd"> :param f: kickstart file object</span>
<span class="sd"> :type f: open file object</span>
<span class="sd"> :param group: A blueprint group dictionary</span>
<span class="sd"> :type user: dict</span>
<span class="sd"> gid is optional</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;name&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">group</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;group entry requires a name&quot;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;group --name </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">group</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="s2">&quot;gid&quot;</span> <span class="ow">in</span> <span class="n">group</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot; --gid </span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">int</span><span class="p">(</span><span class="n">group</span><span class="p">[</span><span class="s2">&quot;gid&quot;</span><span class="p">]))</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="add_customizations"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.add_customizations">[docs]</a><span class="k">def</span> <span class="nf">add_customizations</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">recipe</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Add customizations to the kickstart file</span>
<span class="sd"> :param f: kickstart file object</span>
<span class="sd"> :type f: open file object</span>
<span class="sd"> :param recipe:</span>
<span class="sd"> :type recipe: Recipe object</span>
<span class="sd"> :returns: None</span>
<span class="sd"> :raises: RuntimeError if there was a problem writing to the kickstart</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;customizations&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">recipe</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;rootpw --lock</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">customizations</span> <span class="o">=</span> <span class="n">recipe</span><span class="p">[</span><span class="s2">&quot;customizations&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="s2">&quot;hostname&quot;</span> <span class="ow">in</span> <span class="n">customizations</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;network --hostname=</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">customizations</span><span class="p">[</span><span class="s2">&quot;hostname&quot;</span><span class="p">])</span>
<span class="c1"># TODO - remove this, should use user section to define this</span>
<span class="k">if</span> <span class="s2">&quot;sshkey&quot;</span> <span class="ow">in</span> <span class="n">customizations</span><span class="p">:</span>
<span class="c1"># This is a list of entries</span>
<span class="k">for</span> <span class="n">sshkey</span> <span class="ow">in</span> <span class="n">customizations</span><span class="p">[</span><span class="s2">&quot;sshkey&quot;</span><span class="p">]:</span>
<span class="k">if</span> <span class="s2">&quot;user&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sshkey</span> <span class="ow">or</span> <span class="s2">&quot;key&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sshkey</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> is incorrect, skipping&quot;</span><span class="p">,</span> <span class="n">sshkey</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;sshkey --user </span><span class="si">%s</span><span class="s1"> &quot;</span><span class="si">%s</span><span class="s1">&quot;</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">sshkey</span><span class="p">[</span><span class="s2">&quot;user&quot;</span><span class="p">],</span> <span class="n">sshkey</span><span class="p">[</span><span class="s2">&quot;key&quot;</span><span class="p">]))</span>
<span class="c1"># Creating a user also creates a group. Make a list of the names for later</span>
<span class="n">user_groups</span> <span class="o">=</span> <span class="p">[]</span>
<span class="c1"># kickstart requires a rootpw line</span>
<span class="n">wrote_rootpw</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="s2">&quot;user&quot;</span> <span class="ow">in</span> <span class="n">customizations</span><span class="p">:</span>
<span class="c1"># only name is required, everything else is optional</span>
<span class="k">for</span> <span class="n">user</span> <span class="ow">in</span> <span class="n">customizations</span><span class="p">[</span><span class="s2">&quot;user&quot;</span><span class="p">]:</span>
<span class="k">if</span> <span class="s2">&quot;name&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;user entry requires a name&quot;</span><span class="p">)</span>
<span class="c1"># root is special, cannot use normal user command for it</span>
<span class="k">if</span> <span class="n">user</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;root&quot;</span><span class="p">:</span>
<span class="n">wrote_rootpw</span> <span class="o">=</span> <span class="n">write_ks_root</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">user</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">write_ks_user</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">user</span><span class="p">)</span>
<span class="n">user_groups</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">user</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="s2">&quot;group&quot;</span> <span class="ow">in</span> <span class="n">customizations</span><span class="p">:</span>
<span class="k">for</span> <span class="n">group</span> <span class="ow">in</span> <span class="n">customizations</span><span class="p">[</span><span class="s2">&quot;group&quot;</span><span class="p">]:</span>
<span class="k">if</span> <span class="n">group</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">user_groups</span><span class="p">:</span>
<span class="n">write_ks_group</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">group</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;Skipping group </span><span class="si">%s</span><span class="s2">, already created by user&quot;</span><span class="p">,</span> <span class="n">group</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">])</span>
<span class="c1"># Lock the root account if no root user password has been specified</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">wrote_rootpw</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;rootpw --lock</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span></div>
<div class="viewcode-block" id="start_build"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.start_build">[docs]</a><span class="k">def</span> <span class="nf">start_build</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">dnflock</span><span class="p">,</span> <span class="n">gitlock</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">,</span> <span class="n">compose_type</span><span class="p">,</span> <span class="n">test_mode</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Start the build</span>
<span class="sd"> :param cfg: Configuration object</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param dnflock: Lock and YumBase for depsolving</span>
<span class="sd"> :type dnflock: YumLock</span>
<span class="sd"> :param recipe: The recipe to build</span>
<span class="sd"> :type recipe: str</span>
<span class="sd"> :param compose_type: The type of output to create from the recipe</span>
<span class="sd"> :type compose_type: str</span>
<span class="sd"> :returns: Unique ID for the build that can be used to track its status</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">share_dir</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;share_dir&quot;</span><span class="p">)</span>
<span class="n">lib_dir</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">)</span>
<span class="c1"># Make sure compose_type is valid</span>
<span class="k">if</span> <span class="n">compose_type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">compose_types</span><span class="p">(</span><span class="n">share_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Invalid compose type (</span><span class="si">%s</span><span class="s2">), must be one of </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">compose_type</span><span class="p">,</span> <span class="n">compose_types</span><span class="p">(</span><span class="n">share_dir</span><span class="p">)))</span>
<span class="k">with</span> <span class="n">gitlock</span><span class="o">.</span><span class="n">lock</span><span class="p">:</span>
<span class="p">(</span><span class="n">commit_id</span><span class="p">,</span> <span class="n">recipe</span><span class="p">)</span> <span class="o">=</span> <span class="n">read_recipe_and_id</span><span class="p">(</span><span class="n">gitlock</span><span class="o">.</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">)</span>
<span class="c1"># Combine modules and packages and depsolve the list</span>
<span class="c1"># TODO include the version/glob in the depsolving</span>
<span class="n">module_nver</span> <span class="o">=</span> <span class="n">recipe</span><span class="o">.</span><span class="n">module_nver</span>
<span class="n">package_nver</span> <span class="o">=</span> <span class="n">recipe</span><span class="o">.</span><span class="n">package_nver</span>
<span class="n">projects</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">module_nver</span><span class="o">+</span><span class="n">package_nver</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="n">deps</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># This can possibly update repodata and reset the YumBase object.</span>
<span class="k">with</span> <span class="n">dnflock</span><span class="o">.</span><span class="n">lock_check</span><span class="p">:</span>
<span class="p">(</span><span class="n">installed_size</span><span class="p">,</span> <span class="n">deps</span><span class="p">)</span> <span class="o">=</span> <span class="n">projects_depsolve_with_size</span><span class="p">(</span><span class="n">dnflock</span><span class="o">.</span><span class="n">dbo</span><span class="p">,</span> <span class="n">projects</span><span class="p">,</span> <span class="n">recipe</span><span class="o">.</span><span class="n">group_names</span><span class="p">,</span> <span class="n">with_core</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ProjectsError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;start_build depsolve: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Problem depsolving </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">recipe</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="c1"># Read the kickstart template for this type</span>
<span class="n">ks_template_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">share_dir</span><span class="p">,</span> <span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="n">compose_type</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;.ks&quot;</span>
<span class="n">ks_template</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">ks_template_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="c1"># How much space will the packages in the default template take?</span>
<span class="n">ks_version</span> <span class="o">=</span> <span class="n">makeVersion</span><span class="p">()</span>
<span class="n">ks</span> <span class="o">=</span> <span class="n">KickstartParser</span><span class="p">(</span><span class="n">ks_version</span><span class="p">,</span> <span class="n">errorsAreFatal</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">missingIncludeIsFatal</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">ks</span><span class="o">.</span><span class="n">readKickstartFromString</span><span class="p">(</span><span class="n">ks_template</span><span class="o">+</span><span class="s2">&quot;</span><span class="se">\n</span><span class="si">%e</span><span class="s2">nd</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">pkgs</span> <span class="o">=</span> <span class="p">[(</span><span class="n">name</span><span class="p">,</span> <span class="s2">&quot;*&quot;</span><span class="p">)</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">packages</span><span class="o">.</span><span class="n">packageList</span><span class="p">]</span>
<span class="n">grps</span> <span class="o">=</span> <span class="p">[</span><span class="n">grp</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">grp</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">packages</span><span class="o">.</span><span class="n">groupList</span><span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">with</span> <span class="n">dnflock</span><span class="o">.</span><span class="n">lock</span><span class="p">:</span>
<span class="p">(</span><span class="n">template_size</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">projects_depsolve_with_size</span><span class="p">(</span><span class="n">dnflock</span><span class="o">.</span><span class="n">dbo</span><span class="p">,</span> <span class="n">pkgs</span><span class="p">,</span> <span class="n">grps</span><span class="p">,</span> <span class="n">with_core</span><span class="o">=</span><span class="ow">not</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">packages</span><span class="o">.</span><span class="n">nocore</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ProjectsError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;start_build depsolve: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Problem depsolving </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">recipe</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;installed_size = </span><span class="si">%d</span><span class="s2">, template_size=</span><span class="si">%d</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">installed_size</span><span class="p">,</span> <span class="n">template_size</span><span class="p">)</span>
<span class="c1"># Minimum LMC disk size is 1GiB, and anaconda bumps the estimated size up by 10% (which doesn&#39;t always work).</span>
<span class="c1"># XXX BUT Anaconda has a bug, it won&#39;t execute a kickstart on a disk smaller than 3000 MB</span>
<span class="c1"># XXX There is an upstream patch pending, but until then, use that as the minimum</span>
<span class="n">installed_size</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mf">3e9</span><span class="p">,</span> <span class="nb">int</span><span class="p">((</span><span class="n">installed_size</span><span class="o">+</span><span class="n">template_size</span><span class="p">)))</span> <span class="o">*</span> <span class="mf">1.2</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;/ partition size = </span><span class="si">%d</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">installed_size</span><span class="p">)</span>
<span class="c1"># Create the results directory</span>
<span class="n">build_id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid4</span><span class="p">())</span>
<span class="n">results_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">lib_dir</span><span class="p">,</span> <span class="s2">&quot;results&quot;</span><span class="p">,</span> <span class="n">build_id</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">results_dir</span><span class="p">)</span>
<span class="c1"># Write the recipe commit hash</span>
<span class="n">commit_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;COMMIT&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">commit_path</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">commit_id</span><span class="p">)</span>
<span class="c1"># Write the original recipe</span>
<span class="n">recipe_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;blueprint.toml&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">recipe_path</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">recipe</span><span class="o">.</span><span class="n">toml</span><span class="p">())</span>
<span class="c1"># Write the frozen recipe</span>
<span class="n">frozen_recipe</span> <span class="o">=</span> <span class="n">recipe</span><span class="o">.</span><span class="n">freeze</span><span class="p">(</span><span class="n">deps</span><span class="p">)</span>
<span class="n">recipe_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;frozen.toml&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">recipe_path</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">frozen_recipe</span><span class="o">.</span><span class="n">toml</span><span class="p">())</span>
<span class="c1"># Write out the dependencies to the results dir</span>
<span class="n">deps_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;deps.toml&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">deps_path</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">toml</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s2">&quot;packages&quot;</span><span class="p">:</span><span class="n">deps</span><span class="p">}))</span>
<span class="c1"># Save a copy of the original kickstart</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">ks_template_path</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="k">with</span> <span class="n">dnflock</span><span class="o">.</span><span class="n">lock</span><span class="p">:</span>
<span class="n">repos</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">dnflock</span><span class="o">.</span><span class="n">dbo</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">iter_enabled</span><span class="p">())</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">repos</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;No enabled repos, canceling build.&quot;</span><span class="p">)</span>
<span class="c1"># Create the final kickstart with repos and package list</span>
<span class="n">ks_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;final-kickstart.ks&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">ks_path</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">ks_url</span> <span class="o">=</span> <span class="n">repo_to_ks</span><span class="p">(</span><span class="n">repos</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s2">&quot;url&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;url = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">ks_url</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;url </span><span class="si">%s</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">ks_url</span><span class="p">)</span>
<span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">repos</span><span class="p">[</span><span class="mi">1</span><span class="p">:]):</span>
<span class="n">ks_repo</span> <span class="o">=</span> <span class="n">repo_to_ks</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="s2">&quot;baseurl&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;repo composer-</span><span class="si">%s</span><span class="s2"> = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">idx</span><span class="p">,</span> <span class="n">ks_repo</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;repo --name=&quot;composer-</span><span class="si">%s</span><span class="s1">&quot; </span><span class="si">%s</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">idx</span><span class="p">,</span> <span class="n">ks_repo</span><span class="p">))</span>
<span class="c1"># Setup the disk for booting</span>
<span class="c1"># TODO Add GPT and UEFI boot support</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;clearpart --all --initlabel</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="c1"># Write the root partition and it&#39;s size in MB (rounded up)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;part / --size=</span><span class="si">%d</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">ceil</span><span class="p">(</span><span class="n">installed_size</span> <span class="o">/</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">ks_template</span><span class="p">)</span>
<span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">deps</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">dep_nevra</span><span class="p">(</span><span class="n">d</span><span class="p">)</span><span class="o">+</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%e</span><span class="s2">nd</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">add_customizations</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">recipe</span><span class="p">)</span>
<span class="c1"># Setup the config to pass to novirt_install</span>
<span class="n">log_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;logs/&quot;</span><span class="p">)</span>
<span class="n">cfg_args</span> <span class="o">=</span> <span class="n">compose_args</span><span class="p">(</span><span class="n">compose_type</span><span class="p">)</span>
<span class="c1"># Get the title, project, and release version from the host</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="s2">&quot;/etc/os-release&quot;</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;/etc/os-release is missing, cannot determine product or release version&quot;</span><span class="p">)</span>
<span class="n">os_release</span> <span class="o">=</span> <span class="n">SimpleConfigFile</span><span class="p">(</span><span class="s2">&quot;/etc/os-release&quot;</span><span class="p">)</span>
<span class="n">os_release</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;os_release = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">os_release</span><span class="p">)</span>
<span class="n">cfg_args</span><span class="p">[</span><span class="s2">&quot;title&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">os_release</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;PRETTY_NAME&quot;</span><span class="p">)</span>
<span class="n">cfg_args</span><span class="p">[</span><span class="s2">&quot;project&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">os_release</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;NAME&quot;</span><span class="p">)</span>
<span class="n">cfg_args</span><span class="p">[</span><span class="s2">&quot;releasever&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">os_release</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;VERSION_ID&quot;</span><span class="p">)</span>
<span class="n">cfg_args</span><span class="p">[</span><span class="s2">&quot;volid&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">cfg_args</span><span class="o">.</span><span class="n">update</span><span class="p">({</span>
<span class="s2">&quot;compression&quot;</span><span class="p">:</span> <span class="s2">&quot;xz&quot;</span><span class="p">,</span>
<span class="s2">&quot;compress_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;ks&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">ks_path</span><span class="p">],</span>
<span class="s2">&quot;logfile&quot;</span><span class="p">:</span> <span class="n">log_dir</span><span class="p">,</span>
<span class="s2">&quot;timeout&quot;</span><span class="p">:</span> <span class="mi">60</span><span class="p">,</span> <span class="c1"># 60 minute timeout</span>
<span class="p">})</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;config.toml&quot;</span><span class="p">),</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">toml</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">cfg_args</span><span class="p">))</span>
<span class="c1"># Set the initial status</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;WAITING&quot;</span><span class="p">)</span>
<span class="c1"># Set the test mode, if requested</span>
<span class="k">if</span> <span class="n">test_mode</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;TEST&quot;</span><span class="p">),</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">test_mode</span><span class="p">)</span>
<span class="n">write_timestamp</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">TS_CREATED</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Adding </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">) to compose queue&quot;</span><span class="p">,</span> <span class="n">build_id</span><span class="p">,</span> <span class="n">recipe</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span> <span class="n">compose_type</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">symlink</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">lib_dir</span><span class="p">,</span> <span class="s2">&quot;queue/new/&quot;</span><span class="p">,</span> <span class="n">build_id</span><span class="p">))</span>
<span class="k">return</span> <span class="n">build_id</span></div>
<span class="c1"># Supported output types</span>
<div class="viewcode-block" id="compose_types"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.compose_types">[docs]</a><span class="k">def</span> <span class="nf">compose_types</span><span class="p">(</span><span class="n">share_dir</span><span class="p">):</span>
<span class="sa">r</span><span class="sd">&quot;&quot;&quot; Returns a list of the supported output types</span>
<span class="sd"> The output types come from the kickstart names in /usr/share/lorax/composer/\*ks</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">([</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">ks</span><span class="p">)[:</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="k">for</span> <span class="n">ks</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">share_dir</span><span class="p">,</span> <span class="s2">&quot;composer/*.ks&quot;</span><span class="p">))])</span></div>
<div class="viewcode-block" id="compose_args"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.compose_args">[docs]</a><span class="k">def</span> <span class="nf">compose_args</span><span class="p">(</span><span class="n">compose_type</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Returns the settings to pass to novirt_install for the compose type</span>
<span class="sd"> :param compose_type: The type of compose to create, from `compose_types()`</span>
<span class="sd"> :type compose_type: str</span>
<span class="sd"> This will return a dict of options that match the ArgumentParser options for livemedia-creator.</span>
<span class="sd"> These are the ones the define the type of output, it&#39;s filename, etc.</span>
<span class="sd"> Other options will be filled in by `make_compose()`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">_MAP</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;tar&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> <span class="c1"># False instead of None because of TOML</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="n">default_image_name</span><span class="p">(</span><span class="s2">&quot;xz&quot;</span><span class="p">,</span> <span class="s2">&quot;root.tar&quot;</span><span class="p">),</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">},</span>
<span class="s2">&quot;live-iso&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> <span class="c1"># False instead of None because of TOML</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="s2">&quot;live.iso&quot;</span><span class="p">,</span>
<span class="s2">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s2">&quot;Anaconda&quot;</span><span class="p">,</span> <span class="c1"># Live booting may expect this to be &#39;Anaconda&#39;</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;iso_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;iso_name&quot;</span><span class="p">:</span> <span class="s2">&quot;live.iso&quot;</span><span class="p">,</span>
<span class="p">},</span>
<span class="s2">&quot;partitioned-disk&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> <span class="c1"># False instead of None because of TOML</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="s2">&quot;disk.img&quot;</span><span class="p">,</span>
<span class="s2">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">},</span>
<span class="s2">&quot;qcow2&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="s2">&quot;qcow2&quot;</span><span class="p">,</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="s2">&quot;disk.qcow2&quot;</span><span class="p">,</span>
<span class="s2">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">},</span>
<span class="s2">&quot;ext4-filesystem&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> <span class="c1"># False instead of None because of TOML</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="s2">&quot;filesystem.img&quot;</span><span class="p">,</span>
<span class="s2">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">},</span>
<span class="s2">&quot;ami&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="s2">&quot;disk.ami&quot;</span><span class="p">,</span>
<span class="s2">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">},</span>
<span class="s2">&quot;vhd&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="s2">&quot;vpc&quot;</span><span class="p">,</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&quot;-o&quot;</span><span class="p">,</span> <span class="s2">&quot;subformat=fixed,force_size&quot;</span><span class="p">],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="s2">&quot;disk.vhd&quot;</span><span class="p">,</span>
<span class="s2">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">},</span>
<span class="s2">&quot;vmdk&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="s2">&quot;vmdk&quot;</span><span class="p">,</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="s2">&quot;disk.vmdk&quot;</span><span class="p">,</span>
<span class="s2">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">},</span>
<span class="s2">&quot;openstack&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;make_iso&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_disk&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;make_fsimage&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_appliance&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ami&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_tar&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_pxe_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_ostree_live&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_oci&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;make_vagrant&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;ostree&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_keep_size&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;live_rootfs_size&quot;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="s2">&quot;image_type&quot;</span><span class="p">:</span> <span class="s2">&quot;qcow2&quot;</span><span class="p">,</span>
<span class="s2">&quot;qemu_args&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="s2">&quot;image_name&quot;</span><span class="p">:</span> <span class="s2">&quot;disk.qcow2&quot;</span><span class="p">,</span>
<span class="s2">&quot;fs_label&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;image_only&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;app_name&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_template&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;app_file&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">},</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">_MAP</span><span class="p">[</span><span class="n">compose_type</span><span class="p">]</span></div>
<div class="viewcode-block" id="move_compose_results"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.compose.move_compose_results">[docs]</a><span class="k">def</span> <span class="nf">move_compose_results</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Move the final image to the results_dir and cleanup the unneeded compose files</span>
<span class="sd"> :param cfg: Build configuration</span>
<span class="sd"> :type cfg: DataHolder</span>
<span class="sd"> :param results_dir: Directory to put the results into</span>
<span class="sd"> :type results_dir: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;make_tar&quot;</span><span class="p">]:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;result_dir&quot;</span><span class="p">],</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;image_name&quot;</span><span class="p">]),</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;make_iso&quot;</span><span class="p">]:</span>
<span class="c1"># Output from live iso is always a boot.iso under images/, move and rename it</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;result_dir&quot;</span><span class="p">],</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;iso_name&quot;</span><span class="p">]),</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;image_name&quot;</span><span class="p">]))</span>
<span class="k">elif</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;make_disk&quot;</span><span class="p">]</span> <span class="ow">or</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;make_fsimage&quot;</span><span class="p">]:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;result_dir&quot;</span><span class="p">],</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;image_name&quot;</span><span class="p">]),</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;image_name&quot;</span><span class="p">]))</span>
<span class="c1"># Cleanup the compose directory, but only if it looks like a compose directory</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;result_dir&quot;</span><span class="p">])</span> <span class="o">==</span> <span class="s2">&quot;compose&quot;</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">cfg</span><span class="p">[</span><span class="s2">&quot;result_dir&quot;</span><span class="p">])</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Incorrect compose directory, not cleaning up&quot;</span><span class="p">)</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -0,0 +1,355 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.config &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.config</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.config</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="kn">import</span> <span class="nn">configparser</span>
<span class="kn">import</span> <span class="nn">grp</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">pwd</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="k">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="ComposerConfig"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.ComposerConfig">[docs]</a><span class="k">class</span> <span class="nc">ComposerConfig</span><span class="p">(</span><span class="n">configparser</span><span class="o">.</span><span class="n">SafeConfigParser</span><span class="p">):</span>
<div class="viewcode-block" id="ComposerConfig.get_default"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.ComposerConfig.get_default">[docs]</a> <span class="k">def</span> <span class="nf">get_default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">section</span><span class="p">,</span> <span class="n">option</span><span class="p">,</span> <span class="n">default</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">section</span><span class="p">,</span> <span class="n">option</span><span class="p">)</span>
<span class="k">except</span> <span class="n">configparser</span><span class="o">.</span><span class="n">Error</span><span class="p">:</span>
<span class="k">return</span> <span class="n">default</span></div></div>
<div class="viewcode-block" id="configure"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.configure">[docs]</a><span class="k">def</span> <span class="nf">configure</span><span class="p">(</span><span class="n">conf_file</span><span class="o">=</span><span class="s2">&quot;/etc/lorax/composer.conf&quot;</span><span class="p">,</span> <span class="n">root_dir</span><span class="o">=</span><span class="s2">&quot;/&quot;</span><span class="p">,</span> <span class="n">test_config</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;lorax-composer configuration</span>
<span class="sd"> :param conf_file: Path to the config file overriding the default settings</span>
<span class="sd"> :type conf_file: str</span>
<span class="sd"> :param root_dir: Directory to prepend to paths, defaults to /</span>
<span class="sd"> :type root_dir: str</span>
<span class="sd"> :param test_config: Set to True to skip reading conf_file</span>
<span class="sd"> :type test_config: bool</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">conf</span> <span class="o">=</span> <span class="n">ComposerConfig</span><span class="p">()</span>
<span class="c1"># set defaults</span>
<span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;share_dir&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s2">&quot;/usr/share/lorax/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s2">&quot;/var/lib/lorax/composer/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;repo_dir&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s2">&quot;/var/lib/lorax/composer/repos.d/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;dnf_conf&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s2">&quot;/var/tmp/composer/dnf.conf&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;dnf_root&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s2">&quot;/var/tmp/composer/dnf/root/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;cache_dir&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s2">&quot;/var/tmp/composer/cache/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;tmp&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s2">&quot;/var/tmp/&quot;</span><span class="p">)))</span>
<span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s2">&quot;users&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;users&quot;</span><span class="p">,</span> <span class="s2">&quot;root&quot;</span><span class="p">,</span> <span class="s2">&quot;1&quot;</span><span class="p">)</span>
<span class="c1"># Enable all available repo files by default</span>
<span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s2">&quot;repos&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;repos&quot;</span><span class="p">,</span> <span class="s2">&quot;use_system_repos&quot;</span><span class="p">,</span> <span class="s2">&quot;1&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;repos&quot;</span><span class="p">,</span> <span class="s2">&quot;enabled&quot;</span><span class="p">,</span> <span class="s2">&quot;*&quot;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">add_section</span><span class="p">(</span><span class="s2">&quot;dnf&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">test_config</span><span class="p">:</span>
<span class="c1"># read the config file</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">conf_file</span><span class="p">):</span>
<span class="n">conf</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">conf_file</span><span class="p">)</span>
<span class="k">return</span> <span class="n">conf</span></div>
<div class="viewcode-block" id="make_owned_dir"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.make_owned_dir">[docs]</a><span class="k">def</span> <span class="nf">make_owned_dir</span><span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Make a directory and its parents, setting owner and group</span>
<span class="sd"> :param p_dir: path to directory to create</span>
<span class="sd"> :type p_dir: string</span>
<span class="sd"> :param uid: uid of owner</span>
<span class="sd"> :type uid: int</span>
<span class="sd"> :param gid: gid of owner</span>
<span class="sd"> :type gid: int</span>
<span class="sd"> :returns: list of errors</span>
<span class="sd"> :rtype: list of str</span>
<span class="sd"> Check to make sure it does not have o+rw permissions and that it is owned by uid:gid</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">p_dir</span><span class="p">):</span>
<span class="c1"># Make sure no o+rw permissions are set</span>
<span class="n">orig_umask</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">umask</span><span class="p">(</span><span class="mo">0o006</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="mo">0o771</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">chown</span><span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">umask</span><span class="p">(</span><span class="n">orig_umask</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">p_stat</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">p_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">p_stat</span><span class="o">.</span><span class="n">st_mode</span> <span class="o">&amp;</span> <span class="mo">0o006</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;Incorrect permissions on </span><span class="si">%s</span><span class="s2">, no o+rw permissions are allowed.&quot;</span> <span class="o">%</span> <span class="n">p_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">p_stat</span><span class="o">.</span><span class="n">st_gid</span> <span class="o">!=</span> <span class="n">gid</span> <span class="ow">or</span> <span class="n">p_stat</span><span class="o">.</span><span class="n">st_uid</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">gr_name</span> <span class="o">=</span> <span class="n">grp</span><span class="o">.</span><span class="n">getgrgid</span><span class="p">(</span><span class="n">gid</span><span class="p">)</span><span class="o">.</span><span class="n">gr_name</span>
<span class="n">u_name</span> <span class="o">=</span> <span class="n">pwd</span><span class="o">.</span><span class="n">getpwuid</span><span class="p">(</span><span class="n">uid</span><span class="p">)</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> should be owned by </span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="n">u_name</span><span class="p">,</span> <span class="n">gr_name</span><span class="p">))</span>
<span class="k">return</span> <span class="n">errors</span></div>
<div class="viewcode-block" id="make_dnf_dirs"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.make_dnf_dirs">[docs]</a><span class="k">def</span> <span class="nf">make_dnf_dirs</span><span class="p">(</span><span class="n">conf</span><span class="p">,</span> <span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Make any missing dnf directories owned by user:group</span>
<span class="sd"> :param conf: The configuration to use</span>
<span class="sd"> :type conf: ComposerConfig</span>
<span class="sd"> :param uid: uid of owner</span>
<span class="sd"> :type uid: int</span>
<span class="sd"> :param gid: gid of owner</span>
<span class="sd"> :type gid: int</span>
<span class="sd"> :returns: list of errors</span>
<span class="sd"> :rtype: list of str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;dnf_conf&quot;</span><span class="p">,</span> <span class="s2">&quot;repo_dir&quot;</span><span class="p">,</span> <span class="s2">&quot;cache_dir&quot;</span><span class="p">,</span> <span class="s2">&quot;dnf_root&quot;</span><span class="p">]:</span>
<span class="n">p_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="n">p</span><span class="p">))</span>
<span class="k">if</span> <span class="n">p</span> <span class="o">==</span> <span class="s2">&quot;dnf_conf&quot;</span><span class="p">:</span>
<span class="n">p_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">p_dir</span><span class="p">)</span>
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">make_owned_dir</span><span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="p">))</span></div>
<div class="viewcode-block" id="make_queue_dirs"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.config.make_queue_dirs">[docs]</a><span class="k">def</span> <span class="nf">make_queue_dirs</span><span class="p">(</span><span class="n">conf</span><span class="p">,</span> <span class="n">gid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Make any missing queue directories</span>
<span class="sd"> :param conf: The configuration to use</span>
<span class="sd"> :type conf: ComposerConfig</span>
<span class="sd"> :param gid: Group ID that has access to the queue directories</span>
<span class="sd"> :type gid: int</span>
<span class="sd"> :returns: list of errors</span>
<span class="sd"> :rtype: list of str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">lib_dir</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;queue/run&quot;</span><span class="p">,</span> <span class="s2">&quot;queue/new&quot;</span><span class="p">,</span> <span class="s2">&quot;results&quot;</span><span class="p">]:</span>
<span class="n">p_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">lib_dir</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">make_owned_dir</span><span class="p">(</span><span class="n">p_dir</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">gid</span><span class="p">))</span>
<span class="k">return</span> <span class="n">errors</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -0,0 +1,281 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.crossdomain &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.crossdomain</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.crossdomain</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="c1"># crossdomain decorator from - http://flask.pocoo.org/snippets/56/</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="k">import</span> <span class="n">timedelta</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="k">import</span> <span class="n">make_response</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">current_app</span>
<span class="kn">from</span> <span class="nn">functools</span> <span class="k">import</span> <span class="n">update_wrapper</span>
<div class="viewcode-block" id="crossdomain"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.crossdomain.crossdomain">[docs]</a><span class="k">def</span> <span class="nf">crossdomain</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">max_age</span><span class="o">=</span><span class="mi">21600</span><span class="p">,</span> <span class="n">attach_to_all</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">automatic_options</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="k">if</span> <span class="n">methods</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">methods</span> <span class="o">=</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">methods</span><span class="p">))</span>
<span class="k">if</span> <span class="n">headers</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">headers</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">headers</span> <span class="o">=</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">origin</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<span class="n">origin</span> <span class="o">=</span> <span class="p">[</span><span class="n">origin</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">max_age</span><span class="p">,</span> <span class="n">timedelta</span><span class="p">):</span>
<span class="n">max_age</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">max_age</span><span class="o">.</span><span class="n">total_seconds</span><span class="p">())</span>
<span class="k">def</span> <span class="nf">get_methods</span><span class="p">():</span>
<span class="k">if</span> <span class="n">methods</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">methods</span>
<span class="n">options_resp</span> <span class="o">=</span> <span class="n">current_app</span><span class="o">.</span><span class="n">make_default_options_response</span><span class="p">()</span>
<span class="k">return</span> <span class="n">options_resp</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">&#39;allow&#39;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">wrapped_function</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="n">automatic_options</span> <span class="ow">and</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">&#39;OPTIONS&#39;</span><span class="p">:</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">current_app</span><span class="o">.</span><span class="n">make_default_options_response</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">make_response</span><span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">attach_to_all</span> <span class="ow">and</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">!=</span> <span class="s1">&#39;OPTIONS&#39;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">resp</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">headers</span>
<span class="n">h</span><span class="o">.</span><span class="n">extend</span><span class="p">([(</span><span class="s2">&quot;Access-Control-Allow-Origin&quot;</span><span class="p">,</span> <span class="n">orig</span><span class="p">)</span> <span class="k">for</span> <span class="n">orig</span> <span class="ow">in</span> <span class="n">origin</span><span class="p">])</span>
<span class="n">h</span><span class="p">[</span><span class="s1">&#39;Access-Control-Allow-Methods&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">get_methods</span><span class="p">()</span>
<span class="n">h</span><span class="p">[</span><span class="s1">&#39;Access-Control-Max-Age&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">max_age</span><span class="p">)</span>
<span class="k">if</span> <span class="n">headers</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">h</span><span class="p">[</span><span class="s1">&#39;Access-Control-Allow-Headers&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">headers</span>
<span class="k">return</span> <span class="n">resp</span>
<span class="n">f</span><span class="o">.</span><span class="n">provide_automatic_options</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">f</span><span class="o">.</span><span class="n">required_methods</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;OPTIONS&#39;</span><span class="p">]</span>
<span class="k">return</span> <span class="n">update_wrapper</span><span class="p">(</span><span class="n">wrapped_function</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
<span class="k">return</span> <span class="n">decorator</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -0,0 +1,351 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.dnfbase &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.dnfbase</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.dnfbase</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Copyright (C) 2017-2018 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="c1"># pylint: disable=bad-preconf-access</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;lorax-composer&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">dnf</span>
<span class="kn">import</span> <span class="nn">dnf.logging</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="k">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">from</span> <span class="nn">threading</span> <span class="k">import</span> <span class="n">Lock</span>
<span class="kn">import</span> <span class="nn">time</span>
<div class="viewcode-block" id="DNFLock"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.dnfbase.DNFLock">[docs]</a><span class="k">class</span> <span class="nc">DNFLock</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Hold the dnf.Base object and a Lock to control access to it.</span>
<span class="sd"> self.dbo is a property that returns the dnf.Base object, but it *may* change</span>
<span class="sd"> from one call to the next if the upstream repositories have changed.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conf</span><span class="p">,</span> <span class="n">expire_secs</span><span class="o">=</span><span class="mi">6</span><span class="o">*</span><span class="mi">60</span><span class="o">*</span><span class="mi">60</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_conf</span> <span class="o">=</span> <span class="n">conf</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_lock</span> <span class="o">=</span> <span class="n">Lock</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">dbo</span> <span class="o">=</span> <span class="n">get_base_object</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_conf</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_expire_secs</span> <span class="o">=</span> <span class="n">expire_secs</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_expire_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_expire_secs</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">lock</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Check for repo updates (using expiration time) and return the lock</span>
<span class="sd"> If the repository has been updated, tear down the old dnf.Base and</span>
<span class="sd"> create a new one. This is the only way to force dnf to use the new</span>
<span class="sd"> metadata.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">_expire_time</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">lock_check</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">lock_check</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Force a check for repo updates and return the lock</span>
<span class="sd"> Use this method sparingly, it removes the repodata and downloads a new copy every time.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_expire_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_expire_secs</span>
<span class="bp">self</span><span class="o">.</span><span class="n">dbo</span><span class="o">.</span><span class="n">update_cache</span><span class="p">()</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span></div>
<div class="viewcode-block" id="get_base_object"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.dnfbase.get_base_object">[docs]</a><span class="k">def</span> <span class="nf">get_base_object</span><span class="p">(</span><span class="n">conf</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Get the DNF object with settings from the config file</span>
<span class="sd"> :param conf: configuration object</span>
<span class="sd"> :type conf: ComposerParser</span>
<span class="sd"> :returns: A DNF Base object</span>
<span class="sd"> :rtype: dnf.Base</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">cachedir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;cache_dir&quot;</span><span class="p">))</span>
<span class="n">dnfconf</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;dnf_conf&quot;</span><span class="p">))</span>
<span class="n">dnfroot</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;dnf_root&quot;</span><span class="p">))</span>
<span class="n">repodir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;repo_dir&quot;</span><span class="p">))</span>
<span class="c1"># Setup the config for the DNF Base object</span>
<span class="n">dbo</span> <span class="o">=</span> <span class="n">dnf</span><span class="o">.</span><span class="n">Base</span><span class="p">()</span>
<span class="n">dbc</span> <span class="o">=</span> <span class="n">dbo</span><span class="o">.</span><span class="n">conf</span>
<span class="c1"># TODO - Handle this</span>
<span class="c1"># dbc.logdir = logdir</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">installroot</span> <span class="o">=</span> <span class="n">dnfroot</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">dnfroot</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">dnfroot</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">repodir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">repodir</span><span class="p">)</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">cachedir</span> <span class="o">=</span> <span class="n">cachedir</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">reposdir</span> <span class="o">=</span> <span class="p">[</span><span class="n">repodir</span><span class="p">]</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">install_weak_deps</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">prepend_installroot</span><span class="p">(</span><span class="s1">&#39;persistdir&#39;</span><span class="p">)</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">tsflags</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;nodocs&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">conf</span><span class="o">.</span><span class="n">get_default</span><span class="p">(</span><span class="s2">&quot;dnf&quot;</span><span class="p">,</span> <span class="s2">&quot;proxy&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">proxy</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;dnf&quot;</span><span class="p">,</span> <span class="s2">&quot;proxy&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">conf</span><span class="o">.</span><span class="n">has_option</span><span class="p">(</span><span class="s2">&quot;dnf&quot;</span><span class="p">,</span> <span class="s2">&quot;sslverify&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">conf</span><span class="o">.</span><span class="n">getboolean</span><span class="p">(</span><span class="s2">&quot;dnf&quot;</span><span class="p">,</span> <span class="s2">&quot;sslverify&quot;</span><span class="p">):</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">sslverify</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">_releasever</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">get_default</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;releasever&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_releasever</span><span class="p">:</span>
<span class="c1"># Use the releasever of the host system</span>
<span class="n">_releasever</span> <span class="o">=</span> <span class="n">dnf</span><span class="o">.</span><span class="n">rpm</span><span class="o">.</span><span class="n">detect_releasever</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;releasever = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">_releasever</span><span class="p">)</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">releasever</span> <span class="o">=</span> <span class="n">_releasever</span>
<span class="c1"># Make sure metadata is always current</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">metadata_expire</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">dbc</span><span class="o">.</span><span class="n">metadata_expire_filter</span> <span class="o">=</span> <span class="s2">&quot;never&quot;</span>
<span class="c1"># write the dnf configuration file</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">dnfconf</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">dbc</span><span class="o">.</span><span class="n">dump</span><span class="p">())</span>
<span class="c1"># dnf needs the repos all in one directory, composer uses repodir for this</span>
<span class="c1"># if system repos are supposed to be used, copy them into repodir, overwriting any previous copies</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">conf</span><span class="o">.</span><span class="n">has_option</span><span class="p">(</span><span class="s2">&quot;repos&quot;</span><span class="p">,</span> <span class="s2">&quot;use_system_repos&quot;</span><span class="p">)</span> <span class="ow">or</span> <span class="n">conf</span><span class="o">.</span><span class="n">getboolean</span><span class="p">(</span><span class="s2">&quot;repos&quot;</span><span class="p">,</span> <span class="s2">&quot;use_system_repos&quot;</span><span class="p">):</span>
<span class="k">for</span> <span class="n">repo_file</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="s2">&quot;/etc/yum.repos.d/*.repo&quot;</span><span class="p">):</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">repo_file</span><span class="p">,</span> <span class="n">repodir</span><span class="p">)</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">read_all_repos</span><span class="p">()</span>
<span class="c1"># Update the metadata from the enabled repos to speed up later operations</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Updating repository metadata&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">fill_sack</span><span class="p">(</span><span class="n">load_system_repo</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">read_comps</span><span class="p">()</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">update_cache</span><span class="p">()</span>
<span class="k">except</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">Error</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Failed to update metadata: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Fetching metadata failed: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">return</span> <span class="n">dbo</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -0,0 +1,768 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.projects &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.projects</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.projects</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;lorax-composer&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">configparser</span> <span class="k">import</span> <span class="n">ConfigParser</span>
<span class="kn">import</span> <span class="nn">dnf</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="k">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="n">TIME_FORMAT</span> <span class="o">=</span> <span class="s2">&quot;%Y-%m-</span><span class="si">%d</span><span class="s2">T%H:%M:%S&quot;</span>
<div class="viewcode-block" id="ProjectsError"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.ProjectsError">[docs]</a><span class="k">class</span> <span class="nc">ProjectsError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="api_time"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.api_time">[docs]</a><span class="k">def</span> <span class="nf">api_time</span><span class="p">(</span><span class="n">t</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Convert time since epoch to a string</span>
<span class="sd"> :param t: Seconds since epoch</span>
<span class="sd"> :type t: int</span>
<span class="sd"> :returns: Time string</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">TIME_FORMAT</span><span class="p">,</span> <span class="n">time</span><span class="o">.</span><span class="n">localtime</span><span class="p">(</span><span class="n">t</span><span class="p">))</span></div>
<div class="viewcode-block" id="api_changelog"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.api_changelog">[docs]</a><span class="k">def</span> <span class="nf">api_changelog</span><span class="p">(</span><span class="n">changelog</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Convert the changelog to a string</span>
<span class="sd"> :param changelog: A list of time, author, string tuples.</span>
<span class="sd"> :type changelog: tuple</span>
<span class="sd"> :returns: The most recent changelog text or &quot;&quot;</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> This returns only the most recent changelog entry.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">entry</span> <span class="o">=</span> <span class="n">changelog</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="n">entry</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="n">entry</span></div>
<div class="viewcode-block" id="pkg_to_project"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.pkg_to_project">[docs]</a><span class="k">def</span> <span class="nf">pkg_to_project</span><span class="p">(</span><span class="n">pkg</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Extract the details from a hawkey.Package object</span>
<span class="sd"> :param pkgs: hawkey.Package object with package details</span>
<span class="sd"> :type pkgs: hawkey.Package</span>
<span class="sd"> :returns: A dict with the name, summary, description, and url.</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> upstream_vcs is hard-coded to UPSTREAM_VCS</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="s2">&quot;summary&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">summary</span><span class="p">,</span>
<span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">description</span><span class="p">,</span>
<span class="s2">&quot;homepage&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">url</span><span class="p">,</span>
<span class="s2">&quot;upstream_vcs&quot;</span><span class="p">:</span> <span class="s2">&quot;UPSTREAM_VCS&quot;</span><span class="p">}</span></div>
<div class="viewcode-block" id="pkg_to_project_info"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.pkg_to_project_info">[docs]</a><span class="k">def</span> <span class="nf">pkg_to_project_info</span><span class="p">(</span><span class="n">pkg</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Extract the details from a hawkey.Package object</span>
<span class="sd"> :param pkg: hawkey.Package object with package details</span>
<span class="sd"> :type pkg: hawkey.Package</span>
<span class="sd"> :returns: A dict with the project details, as well as epoch, release, arch, build_time, changelog, ...</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> metadata entries are hard-coded to {}</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">build</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;epoch&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">epoch</span><span class="p">,</span>
<span class="s2">&quot;release&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">release</span><span class="p">,</span>
<span class="s2">&quot;arch&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span>
<span class="s2">&quot;build_time&quot;</span><span class="p">:</span> <span class="n">api_time</span><span class="p">(</span><span class="n">pkg</span><span class="o">.</span><span class="n">buildtime</span><span class="p">),</span>
<span class="s2">&quot;changelog&quot;</span><span class="p">:</span> <span class="s2">&quot;CHANGELOG_NEEDED&quot;</span><span class="p">,</span> <span class="c1"># XXX Not in hawkey.Package</span>
<span class="s2">&quot;build_config_ref&quot;</span><span class="p">:</span> <span class="s2">&quot;BUILD_CONFIG_REF&quot;</span><span class="p">,</span>
<span class="s2">&quot;build_env_ref&quot;</span><span class="p">:</span> <span class="s2">&quot;BUILD_ENV_REF&quot;</span><span class="p">,</span>
<span class="s2">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{},</span>
<span class="s2">&quot;source&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;license&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">license</span><span class="p">,</span>
<span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="s2">&quot;source_ref&quot;</span><span class="p">:</span> <span class="s2">&quot;SOURCE_REF&quot;</span><span class="p">,</span>
<span class="s2">&quot;metadata&quot;</span><span class="p">:</span> <span class="p">{}}}</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="s2">&quot;summary&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">summary</span><span class="p">,</span>
<span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">description</span><span class="p">,</span>
<span class="s2">&quot;homepage&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">url</span><span class="p">,</span>
<span class="s2">&quot;upstream_vcs&quot;</span><span class="p">:</span> <span class="s2">&quot;UPSTREAM_VCS&quot;</span><span class="p">,</span>
<span class="s2">&quot;builds&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">build</span><span class="p">]}</span></div>
<div class="viewcode-block" id="pkg_to_dep"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.pkg_to_dep">[docs]</a><span class="k">def</span> <span class="nf">pkg_to_dep</span><span class="p">(</span><span class="n">pkg</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Extract the info from a hawkey.Package object</span>
<span class="sd"> :param pkg: A hawkey.Package object</span>
<span class="sd"> :type pkg: hawkey.Package</span>
<span class="sd"> :returns: A dict with name, epoch, version, release, arch</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="s2">&quot;epoch&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">epoch</span><span class="p">,</span>
<span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">version</span><span class="p">,</span>
<span class="s2">&quot;release&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">release</span><span class="p">,</span>
<span class="s2">&quot;arch&quot;</span><span class="p">:</span> <span class="n">pkg</span><span class="o">.</span><span class="n">arch</span><span class="p">}</span></div>
<div class="viewcode-block" id="proj_to_module"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.proj_to_module">[docs]</a><span class="k">def</span> <span class="nf">proj_to_module</span><span class="p">(</span><span class="n">proj</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Extract the name from a project_info dict</span>
<span class="sd"> :param pkg: dict with package details</span>
<span class="sd"> :type pkg: dict</span>
<span class="sd"> :returns: A dict with name, and group_type</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> group_type is hard-coded to &quot;rpm&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">proj</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span>
<span class="s2">&quot;group_type&quot;</span><span class="p">:</span> <span class="s2">&quot;rpm&quot;</span><span class="p">}</span></div>
<div class="viewcode-block" id="dep_evra"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.dep_evra">[docs]</a><span class="k">def</span> <span class="nf">dep_evra</span><span class="p">(</span><span class="n">dep</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the epoch:version-release.arch for the dep</span>
<span class="sd"> :param dep: dependency dict</span>
<span class="sd"> :type dep: dict</span>
<span class="sd"> :returns: epoch:version-release.arch</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">dep</span><span class="p">[</span><span class="s2">&quot;epoch&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="n">dep</span><span class="p">[</span><span class="s2">&quot;version&quot;</span><span class="p">]</span><span class="o">+</span><span class="s2">&quot;-&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s2">&quot;release&quot;</span><span class="p">]</span><span class="o">+</span><span class="s2">&quot;.&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s2">&quot;arch&quot;</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">dep</span><span class="p">[</span><span class="s2">&quot;epoch&quot;</span><span class="p">])</span><span class="o">+</span><span class="s2">&quot;:&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s2">&quot;version&quot;</span><span class="p">]</span><span class="o">+</span><span class="s2">&quot;-&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s2">&quot;release&quot;</span><span class="p">]</span><span class="o">+</span><span class="s2">&quot;.&quot;</span><span class="o">+</span><span class="n">dep</span><span class="p">[</span><span class="s2">&quot;arch&quot;</span><span class="p">]</span></div>
<div class="viewcode-block" id="dep_nevra"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.dep_nevra">[docs]</a><span class="k">def</span> <span class="nf">dep_nevra</span><span class="p">(</span><span class="n">dep</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the name-epoch:version-release.arch&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">dep</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">]</span><span class="o">+</span><span class="s2">&quot;-&quot;</span><span class="o">+</span><span class="n">dep_evra</span><span class="p">(</span><span class="n">dep</span><span class="p">)</span></div>
<div class="viewcode-block" id="projects_list"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.projects_list">[docs]</a><span class="k">def</span> <span class="nf">projects_list</span><span class="p">(</span><span class="n">dbo</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a list of projects</span>
<span class="sd"> :param dbo: dnf base object</span>
<span class="sd"> :type dbo: dnf.Base</span>
<span class="sd"> :returns: List of project info dicts with name, summary, description, homepage, upstream_vcs</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">projects_info</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span></div>
<div class="viewcode-block" id="projects_info"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.projects_info">[docs]</a><span class="k">def</span> <span class="nf">projects_info</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">project_names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return details about specific projects</span>
<span class="sd"> :param dbo: dnf base object</span>
<span class="sd"> :type dbo: dnf.Base</span>
<span class="sd"> :param project_names: List of names of projects to get info about</span>
<span class="sd"> :type project_names: str</span>
<span class="sd"> :returns: List of project info dicts with pkg_to_project as well as epoch, version, release, etc.</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> If project_names is None it will return the full list of available packages</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">project_names</span><span class="p">:</span>
<span class="n">pkgs</span> <span class="o">=</span> <span class="n">dbo</span><span class="o">.</span><span class="n">sack</span><span class="o">.</span><span class="n">query</span><span class="p">()</span><span class="o">.</span><span class="n">available</span><span class="p">()</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name__glob</span><span class="o">=</span><span class="n">project_names</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">pkgs</span> <span class="o">=</span> <span class="n">dbo</span><span class="o">.</span><span class="n">sack</span><span class="o">.</span><span class="n">query</span><span class="p">()</span><span class="o">.</span><span class="n">available</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">pkg_to_project_info</span><span class="p">,</span> <span class="n">pkgs</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span></div>
<span class="k">def</span> <span class="nf">_depsolve</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">projects</span><span class="p">,</span> <span class="n">groups</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Add projects to a new transaction</span>
<span class="sd"> :param dbo: dnf base object</span>
<span class="sd"> :type dbo: dnf.Base</span>
<span class="sd"> :param projects: The projects and version globs to find the dependencies for</span>
<span class="sd"> :type projects: List of tuples</span>
<span class="sd"> :param groups: The groups to include in dependency solving</span>
<span class="sd"> :type groups: List of str</span>
<span class="sd"> :returns: None</span>
<span class="sd"> :rtype: None</span>
<span class="sd"> :raises: ProjectsError if there was a problem installing something</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># This resets the transaction and updates the cache.</span>
<span class="c1"># It is important that the cache always be synchronized because Anaconda will grab its own copy</span>
<span class="c1"># and if that is different the NEVRAs will not match and the build will fail.</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">reset</span><span class="p">(</span><span class="n">goal</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">install_errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">groups</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">group_install</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;mandatory&quot;</span><span class="p">,</span> <span class="s2">&quot;default&quot;</span><span class="p">])</span>
<span class="k">except</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">MarkingError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">install_errors</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="s2">&quot;Group </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">version</span> <span class="ow">in</span> <span class="n">projects</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">version</span><span class="p">:</span>
<span class="n">version</span> <span class="o">=</span> <span class="s2">&quot;*&quot;</span>
<span class="c1"># Find the best package matching the name + version glob</span>
<span class="c1"># dnf can return multiple packages if it is in more than 1 repository, so use max() to select one of them</span>
<span class="n">pkg</span> <span class="o">=</span> <span class="nb">max</span><span class="p">([</span><span class="n">pkg</span> <span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">dnf</span><span class="o">.</span><span class="n">subject</span><span class="o">.</span><span class="n">Subject</span><span class="p">(</span><span class="n">name</span><span class="p">)</span><span class="o">.</span><span class="n">get_best_query</span><span class="p">(</span><span class="n">dbo</span><span class="o">.</span><span class="n">sack</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">version__glob</span><span class="o">=</span><span class="n">version</span><span class="p">,</span> <span class="n">latest</span><span class="o">=</span><span class="kc">True</span><span class="p">)]</span> <span class="ow">or</span> <span class="p">[</span><span class="kc">None</span><span class="p">])</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">pkg</span><span class="p">:</span>
<span class="n">install_errors</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">version</span><span class="p">),</span> <span class="s2">&quot;No match&quot;</span><span class="p">))</span>
<span class="k">continue</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">package_install</span><span class="p">(</span><span class="n">pkg</span><span class="p">)</span>
<span class="k">except</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">MarkingError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">install_errors</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">version</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">if</span> <span class="n">install_errors</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s2">&quot;The following package(s) had problems: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> (</span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="k">for</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">err</span> <span class="ow">in</span> <span class="n">install_errors</span><span class="p">]))</span>
<div class="viewcode-block" id="projects_depsolve"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.projects_depsolve">[docs]</a><span class="k">def</span> <span class="nf">projects_depsolve</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">projects</span><span class="p">,</span> <span class="n">groups</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the dependencies for a list of projects</span>
<span class="sd"> :param dbo: dnf base object</span>
<span class="sd"> :type dbo: dnf.Base</span>
<span class="sd"> :param projects: The projects to find the dependencies for</span>
<span class="sd"> :type projects: List of Strings</span>
<span class="sd"> :param groups: The groups to include in dependency solving</span>
<span class="sd"> :type groups: List of str</span>
<span class="sd"> :returns: NEVRA&#39;s of the project and its dependencies</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> :raises: ProjectsError if there was a problem installing something</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">_depsolve</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">projects</span><span class="p">,</span> <span class="n">groups</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">resolve</span><span class="p">()</span>
<span class="k">except</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">DepsolveError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s2">&quot;There was a problem depsolving </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">projects</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">dbo</span><span class="o">.</span><span class="n">transaction</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">pkg_to_dep</span><span class="p">,</span> <span class="n">dbo</span><span class="o">.</span><span class="n">transaction</span><span class="o">.</span><span class="n">install_set</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span></div>
<div class="viewcode-block" id="estimate_size"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.estimate_size">[docs]</a><span class="k">def</span> <span class="nf">estimate_size</span><span class="p">(</span><span class="n">packages</span><span class="p">,</span> <span class="n">block_size</span><span class="o">=</span><span class="mi">6144</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Estimate the installed size of a package list</span>
<span class="sd"> :param packages: The packages to be installed</span>
<span class="sd"> :type packages: list of hawkey.Package objects</span>
<span class="sd"> :param block_size: The block size to use for rounding up file sizes.</span>
<span class="sd"> :type block_size: int</span>
<span class="sd"> :returns: The estimated size of installed packages</span>
<span class="sd"> :rtype: int</span>
<span class="sd"> Estimating actual requirements is difficult without the actual file sizes, which</span>
<span class="sd"> dnf doesn&#39;t provide access to. So use the file count and block size to estimate</span>
<span class="sd"> a minimum size for each package.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">installed_size</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">packages</span><span class="p">:</span>
<span class="n">installed_size</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">files</span><span class="p">)</span> <span class="o">*</span> <span class="n">block_size</span>
<span class="n">installed_size</span> <span class="o">+=</span> <span class="n">p</span><span class="o">.</span><span class="n">installsize</span>
<span class="k">return</span> <span class="n">installed_size</span></div>
<div class="viewcode-block" id="projects_depsolve_with_size"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.projects_depsolve_with_size">[docs]</a><span class="k">def</span> <span class="nf">projects_depsolve_with_size</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">projects</span><span class="p">,</span> <span class="n">groups</span><span class="p">,</span> <span class="n">with_core</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the dependencies and installed size for a list of projects</span>
<span class="sd"> :param dbo: dnf base object</span>
<span class="sd"> :type dbo: dnf.Base</span>
<span class="sd"> :param project_names: The projects to find the dependencies for</span>
<span class="sd"> :type project_names: List of Strings</span>
<span class="sd"> :param groups: The groups to include in dependency solving</span>
<span class="sd"> :type groups: List of str</span>
<span class="sd"> :returns: installed size and a list of NEVRA&#39;s of the project and its dependencies</span>
<span class="sd"> :rtype: tuple of (int, list of dicts)</span>
<span class="sd"> :raises: ProjectsError if there was a problem installing something</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">_depsolve</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">projects</span><span class="p">,</span> <span class="n">groups</span><span class="p">)</span>
<span class="k">if</span> <span class="n">with_core</span><span class="p">:</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">group_install</span><span class="p">(</span><span class="s2">&quot;core&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;mandatory&#39;</span><span class="p">,</span> <span class="s1">&#39;default&#39;</span><span class="p">,</span> <span class="s1">&#39;optional&#39;</span><span class="p">])</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">dbo</span><span class="o">.</span><span class="n">resolve</span><span class="p">()</span>
<span class="k">except</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">DepsolveError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s2">&quot;There was a problem depsolving </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">projects</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">dbo</span><span class="o">.</span><span class="n">transaction</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">[])</span>
<span class="n">installed_size</span> <span class="o">=</span> <span class="n">estimate_size</span><span class="p">(</span><span class="n">dbo</span><span class="o">.</span><span class="n">transaction</span><span class="o">.</span><span class="n">install_set</span><span class="p">)</span>
<span class="n">deps</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">pkg_to_dep</span><span class="p">,</span> <span class="n">dbo</span><span class="o">.</span><span class="n">transaction</span><span class="o">.</span><span class="n">install_set</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
<span class="k">return</span> <span class="p">(</span><span class="n">installed_size</span><span class="p">,</span> <span class="n">deps</span><span class="p">)</span></div>
<div class="viewcode-block" id="modules_list"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.modules_list">[docs]</a><span class="k">def</span> <span class="nf">modules_list</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">module_names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a list of modules</span>
<span class="sd"> :param dbo: dnf base object</span>
<span class="sd"> :type dbo: dnf.Base</span>
<span class="sd"> :param offset: Number of modules to skip</span>
<span class="sd"> :type limit: int</span>
<span class="sd"> :param limit: Maximum number of modules to return</span>
<span class="sd"> :type limit: int</span>
<span class="sd"> :returns: List of module information and total count</span>
<span class="sd"> :rtype: tuple of a list of dicts and an Int</span>
<span class="sd"> Modules don&#39;t exist in RHEL7 so this only returns projects</span>
<span class="sd"> and sets the type to &quot;rpm&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># TODO - Figure out what to do with this for Fedora &#39;modules&#39;</span>
<span class="n">projs</span> <span class="o">=</span> <span class="n">projects_info</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">module_names</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">proj_to_module</span><span class="p">,</span> <span class="n">projs</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span></div>
<div class="viewcode-block" id="modules_info"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.modules_info">[docs]</a><span class="k">def</span> <span class="nf">modules_info</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">module_names</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return details about a module, including dependencies</span>
<span class="sd"> :param dbo: dnf base object</span>
<span class="sd"> :type dbo: dnf.Base</span>
<span class="sd"> :param module_names: Names of the modules to get info about</span>
<span class="sd"> :type module_names: str</span>
<span class="sd"> :returns: List of dicts with module details and dependencies.</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">modules</span> <span class="o">=</span> <span class="n">projects_info</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="n">module_names</span><span class="p">)</span>
<span class="c1"># Add the dependency info to each one</span>
<span class="k">for</span> <span class="n">module</span> <span class="ow">in</span> <span class="n">modules</span><span class="p">:</span>
<span class="n">module</span><span class="p">[</span><span class="s2">&quot;dependencies&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">projects_depsolve</span><span class="p">(</span><span class="n">dbo</span><span class="p">,</span> <span class="p">[(</span><span class="n">module</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span> <span class="s2">&quot;*.*&quot;</span><span class="p">)],</span> <span class="p">[])</span>
<span class="k">return</span> <span class="n">modules</span></div>
<div class="viewcode-block" id="dnf_repo_to_file_repo"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.dnf_repo_to_file_repo">[docs]</a><span class="k">def</span> <span class="nf">dnf_repo_to_file_repo</span><span class="p">(</span><span class="n">repo</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a string representation of a DNF Repo object suitable for writing to a .repo file</span>
<span class="sd"> :param repo: DNF Repository</span>
<span class="sd"> :type repo: dnf.RepoDict</span>
<span class="sd"> :returns: A string</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> The DNF Repo.dump() function does not produce a string that can be used as a dnf .repo file,</span>
<span class="sd"> it ouputs baseurl and gpgkey as python lists which DNF cannot read. So do this manually with</span>
<span class="sd"> only the attributes we care about.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">repo_str</span> <span class="o">=</span> <span class="s2">&quot;[</span><span class="si">%s</span><span class="s2">]</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">repo</span><span class="o">.</span><span class="n">id</span>
<span class="k">if</span> <span class="n">repo</span><span class="o">.</span><span class="n">metalink</span><span class="p">:</span>
<span class="n">repo_str</span> <span class="o">+=</span> <span class="s2">&quot;metalink = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">repo</span><span class="o">.</span><span class="n">metalink</span>
<span class="k">elif</span> <span class="n">repo</span><span class="o">.</span><span class="n">mirrorlist</span><span class="p">:</span>
<span class="n">repo_str</span> <span class="o">+=</span> <span class="s2">&quot;mirrorlist = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">repo</span><span class="o">.</span><span class="n">mirrorlist</span>
<span class="k">elif</span> <span class="n">repo</span><span class="o">.</span><span class="n">baseurl</span><span class="p">:</span>
<span class="n">repo_str</span> <span class="o">+=</span> <span class="s2">&quot;baseurl = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">repo</span><span class="o">.</span><span class="n">baseurl</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Repo has no baseurl, metalink, or mirrorlist&quot;</span><span class="p">)</span>
<span class="c1"># proxy is optional</span>
<span class="k">if</span> <span class="n">repo</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">repo_str</span> <span class="o">+=</span> <span class="s2">&quot;proxy = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">repo</span><span class="o">.</span><span class="n">proxy</span>
<span class="n">repo_str</span> <span class="o">+=</span> <span class="s2">&quot;sslverify = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">repo</span><span class="o">.</span><span class="n">sslverify</span>
<span class="n">repo_str</span> <span class="o">+=</span> <span class="s2">&quot;gpgcheck = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">repo</span><span class="o">.</span><span class="n">gpgcheck</span>
<span class="k">if</span> <span class="n">repo</span><span class="o">.</span><span class="n">gpgkey</span><span class="p">:</span>
<span class="n">repo_str</span> <span class="o">+=</span> <span class="s2">&quot;gpgkey = </span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">repo</span><span class="o">.</span><span class="n">gpgkey</span><span class="p">)</span>
<span class="k">return</span> <span class="n">repo_str</span></div>
<div class="viewcode-block" id="repo_to_source"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.repo_to_source">[docs]</a><span class="k">def</span> <span class="nf">repo_to_source</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">system_source</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a Weldr Source dict created from the DNF Repository</span>
<span class="sd"> :param repo: DNF Repository</span>
<span class="sd"> :type repo: dnf.RepoDict</span>
<span class="sd"> :param system_source: True if this source is an immutable system source</span>
<span class="sd"> :type system_source: bool</span>
<span class="sd"> :returns: A dict with Weldr Source fields filled in</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> Example::</span>
<span class="sd"> {</span>
<span class="sd"> &quot;check_gpg&quot;: true,</span>
<span class="sd"> &quot;check_ssl&quot;: true,</span>
<span class="sd"> &quot;gpgkey_url&quot;: [</span>
<span class="sd"> &quot;file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-28-x86_64&quot;</span>
<span class="sd"> ],</span>
<span class="sd"> &quot;name&quot;: &quot;fedora&quot;,</span>
<span class="sd"> &quot;proxy&quot;: &quot;http://proxy.brianlane.com:8123&quot;,</span>
<span class="sd"> &quot;system&quot;: true</span>
<span class="sd"> &quot;type&quot;: &quot;yum-metalink&quot;,</span>
<span class="sd"> &quot;url&quot;: &quot;https://mirrors.fedoraproject.org/metalink?repo=fedora-28&amp;arch=x86_64&quot;</span>
<span class="sd"> }</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">source</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="n">repo</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="s2">&quot;system&quot;</span><span class="p">:</span> <span class="n">system_source</span><span class="p">}</span>
<span class="k">if</span> <span class="n">repo</span><span class="o">.</span><span class="n">baseurl</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">baseurl</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;type&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;yum-baseurl&quot;</span>
<span class="k">elif</span> <span class="n">repo</span><span class="o">.</span><span class="n">metalink</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">metalink</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;type&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;yum-metalink&quot;</span>
<span class="k">elif</span> <span class="n">repo</span><span class="o">.</span><span class="n">mirrorlist</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">mirrorlist</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;type&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;yum-mirrorlist&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Repo has no baseurl, metalink, or mirrorlist&quot;</span><span class="p">)</span>
<span class="c1"># proxy is optional</span>
<span class="k">if</span> <span class="n">repo</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;proxy&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">proxy</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">repo</span><span class="o">.</span><span class="n">sslverify</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;check_ssl&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;check_ssl&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">repo</span><span class="o">.</span><span class="n">gpgcheck</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;check_gpg&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;check_gpg&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">repo</span><span class="o">.</span><span class="n">gpgkey</span><span class="p">:</span>
<span class="n">source</span><span class="p">[</span><span class="s2">&quot;gpgkey_urls&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">gpgkey</span>
<span class="k">return</span> <span class="n">source</span></div>
<div class="viewcode-block" id="source_to_repo"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.source_to_repo">[docs]</a><span class="k">def</span> <span class="nf">source_to_repo</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">dnf_conf</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a dnf Repo object created from a source dict</span>
<span class="sd"> :param source: A Weldr source dict</span>
<span class="sd"> :type source: dict</span>
<span class="sd"> :returns: A dnf Repo object</span>
<span class="sd"> :rtype: dnf.Repo</span>
<span class="sd"> Example::</span>
<span class="sd"> {</span>
<span class="sd"> &quot;check_gpg&quot;: True,</span>
<span class="sd"> &quot;check_ssl&quot;: True,</span>
<span class="sd"> &quot;gpgkey_urls&quot;: [</span>
<span class="sd"> &quot;file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-28-x86_64&quot;</span>
<span class="sd"> ],</span>
<span class="sd"> &quot;name&quot;: &quot;fedora&quot;,</span>
<span class="sd"> &quot;proxy&quot;: &quot;http://proxy.brianlane.com:8123&quot;,</span>
<span class="sd"> &quot;system&quot;: True</span>
<span class="sd"> &quot;type&quot;: &quot;yum-metalink&quot;,</span>
<span class="sd"> &quot;url&quot;: &quot;https://mirrors.fedoraproject.org/metalink?repo=fedora-28&amp;arch=x86_64&quot;</span>
<span class="sd"> }</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">repo</span> <span class="o">=</span> <span class="n">dnf</span><span class="o">.</span><span class="n">repo</span><span class="o">.</span><span class="n">Repo</span><span class="p">(</span><span class="n">source</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span> <span class="n">dnf_conf</span><span class="p">)</span>
<span class="c1"># This will allow errors to be raised so we can catch them</span>
<span class="c1"># without this they are logged, but the repo is silently disabled</span>
<span class="n">repo</span><span class="o">.</span><span class="n">skip_if_unavailable</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;type&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;yum-baseurl&quot;</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">baseurl</span> <span class="o">=</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;type&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;yum-metalink&quot;</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">metalink</span> <span class="o">=</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;type&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;yum-mirrorlist&quot;</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">mirrorlist</span> <span class="o">=</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="s2">&quot;proxy&quot;</span> <span class="ow">in</span> <span class="n">source</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">proxy</span> <span class="o">=</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;proxy&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;check_ssl&quot;</span><span class="p">]:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">sslverify</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">sslverify</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">source</span><span class="p">[</span><span class="s2">&quot;check_gpg&quot;</span><span class="p">]:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">gpgcheck</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">gpgcheck</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="s2">&quot;gpgkey_urls&quot;</span> <span class="ow">in</span> <span class="n">source</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">gpgkey</span> <span class="o">=</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">source</span><span class="p">[</span><span class="s2">&quot;gpgkey_urls&quot;</span><span class="p">])</span>
<span class="n">repo</span><span class="o">.</span><span class="n">enable</span><span class="p">()</span>
<span class="k">return</span> <span class="n">repo</span></div>
<div class="viewcode-block" id="get_source_ids"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.get_source_ids">[docs]</a><span class="k">def</span> <span class="nf">get_source_ids</span><span class="p">(</span><span class="n">source_path</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a list of the source ids in a file</span>
<span class="sd"> :param source_path: Full path and filename of the source (yum repo) file</span>
<span class="sd"> :type source_path: str</span>
<span class="sd"> :returns: A list of source id strings</span>
<span class="sd"> :rtype: list of str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">source_path</span><span class="p">):</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="n">cfg</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="p">()</span>
<span class="n">cfg</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">source_path</span><span class="p">)</span>
<span class="k">return</span> <span class="n">cfg</span><span class="o">.</span><span class="n">sections</span><span class="p">()</span></div>
<div class="viewcode-block" id="get_repo_sources"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.get_repo_sources">[docs]</a><span class="k">def</span> <span class="nf">get_repo_sources</span><span class="p">(</span><span class="n">source_glob</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a list of sources from a directory of yum repositories</span>
<span class="sd"> :param source_glob: A glob to use to match the source files, including full path</span>
<span class="sd"> :type source_glob: str</span>
<span class="sd"> :returns: A list of the source ids in all of the matching files</span>
<span class="sd"> :rtype: list of str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">sources</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">source_glob</span><span class="p">):</span>
<span class="n">sources</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">get_source_ids</span><span class="p">(</span><span class="n">f</span><span class="p">))</span>
<span class="k">return</span> <span class="n">sources</span></div>
<div class="viewcode-block" id="delete_repo_source"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.projects.delete_repo_source">[docs]</a><span class="k">def</span> <span class="nf">delete_repo_source</span><span class="p">(</span><span class="n">source_glob</span><span class="p">,</span> <span class="n">source_name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Delete a source from a repo file</span>
<span class="sd"> :param source_glob: A glob of the repo sources to search</span>
<span class="sd"> :type source_glob: str</span>
<span class="sd"> :returns: None</span>
<span class="sd"> :raises: ProjectsError if there was a problem</span>
<span class="sd"> A repo file may have multiple sources in it, delete only the selected source.</span>
<span class="sd"> If it is the last one in the file, delete the file.</span>
<span class="sd"> WARNING: This will delete ANY source, the caller needs to ensure that a system</span>
<span class="sd"> source_name isn&#39;t passed to it.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">found</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">source_glob</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">cfg</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="p">()</span>
<span class="n">cfg</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">if</span> <span class="n">source_name</span> <span class="ow">in</span> <span class="n">cfg</span><span class="o">.</span><span class="n">sections</span><span class="p">():</span>
<span class="n">found</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">cfg</span><span class="o">.</span><span class="n">remove_section</span><span class="p">(</span><span class="n">source_name</span><span class="p">)</span>
<span class="c1"># If there are other sections, rewrite the file without the deleted one</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">sections</span><span class="p">())</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">cfg_file</span><span class="p">:</span>
<span class="n">cfg</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">cfg_file</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># No sections left, just delete the file</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s2">&quot;Problem deleting repo source </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">source_name</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ProjectsError</span><span class="p">(</span><span class="s2">&quot;source </span><span class="si">%s</span><span class="s2"> not found&quot;</span> <span class="o">%</span> <span class="n">source_name</span><span class="p">)</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -0,0 +1,847 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.queue &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.queue</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.queue</h1><div class="highlight"><pre>
<span></span><span class="c1"># Copyright (C) 2018 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="sd">&quot;&quot;&quot; Functions to monitor compose queue and run anaconda&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">grp</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="k">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="nn">multiprocessing</span> <span class="k">as</span> <span class="nn">mp</span>
<span class="kn">import</span> <span class="nn">pytoml</span> <span class="k">as</span> <span class="nn">toml</span>
<span class="kn">import</span> <span class="nn">pwd</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="k">import</span> <span class="n">Popen</span><span class="p">,</span> <span class="n">PIPE</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">pylorax</span> <span class="k">import</span> <span class="n">find_templates</span>
<span class="kn">from</span> <span class="nn">pylorax.api.compose</span> <span class="k">import</span> <span class="n">move_compose_results</span>
<span class="kn">from</span> <span class="nn">pylorax.api.recipes</span> <span class="k">import</span> <span class="n">recipe_from_file</span>
<span class="kn">from</span> <span class="nn">pylorax.api.timestamp</span> <span class="k">import</span> <span class="n">TS_CREATED</span><span class="p">,</span> <span class="n">TS_STARTED</span><span class="p">,</span> <span class="n">TS_FINISHED</span><span class="p">,</span> <span class="n">write_timestamp</span><span class="p">,</span> <span class="n">timestamp_dict</span>
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="k">import</span> <span class="n">DataHolder</span>
<span class="kn">from</span> <span class="nn">pylorax.creator</span> <span class="k">import</span> <span class="n">run_creator</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="k">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="start_queue_monitor"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.start_queue_monitor">[docs]</a><span class="k">def</span> <span class="nf">start_queue_monitor</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Start the queue monitor as a mp process</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uid: User ID that owns the queue</span>
<span class="sd"> :type uid: int</span>
<span class="sd"> :param gid: Group ID that owns the queue</span>
<span class="sd"> :type gid: int</span>
<span class="sd"> :returns: None</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lib_dir</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">)</span>
<span class="n">share_dir</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;share_dir&quot;</span><span class="p">)</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;tmp&quot;</span><span class="p">)</span>
<span class="n">monitor_cfg</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">composer_dir</span><span class="o">=</span><span class="n">lib_dir</span><span class="p">,</span> <span class="n">share_dir</span><span class="o">=</span><span class="n">share_dir</span><span class="p">,</span> <span class="n">uid</span><span class="o">=</span><span class="n">uid</span><span class="p">,</span> <span class="n">gid</span><span class="o">=</span><span class="n">gid</span><span class="p">,</span> <span class="n">tmp</span><span class="o">=</span><span class="n">tmp</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">mp</span><span class="o">.</span><span class="n">Process</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">monitor</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">monitor_cfg</span><span class="p">,))</span>
<span class="n">p</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">p</span><span class="o">.</span><span class="n">start</span><span class="p">()</span></div>
<div class="viewcode-block" id="monitor"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.monitor">[docs]</a><span class="k">def</span> <span class="nf">monitor</span><span class="p">(</span><span class="n">cfg</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Monitor the queue for new compose requests</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: DataHolder</span>
<span class="sd"> :returns: Does not return</span>
<span class="sd"> The queue has 2 subdirectories, new and run. When a compose is ready to be run</span>
<span class="sd"> a symlink to the uniquely named results directory should be placed in ./queue/new/</span>
<span class="sd"> When the it is ready to be run (it is checked every 30 seconds or after a previous</span>
<span class="sd"> compose is finished) the symlink will be moved into ./queue/run/ and a STATUS file</span>
<span class="sd"> will be created in the results directory.</span>
<span class="sd"> STATUS can contain one of: RUNNING, FINISHED, FAILED</span>
<span class="sd"> If the system is restarted while a compose is running it will move any old symlinks</span>
<span class="sd"> from ./queue/run/ to ./queue/new/ and rerun them.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">queue_sort</span><span class="p">(</span><span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Sort the queue entries by their mtime, not their names&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s2">&quot;queue/new&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">))</span><span class="o">.</span><span class="n">st_mtime</span>
<span class="c1"># Move any symlinks in the run queue back to the new queue</span>
<span class="k">for</span> <span class="n">link</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s2">&quot;queue/run&quot;</span><span class="p">)):</span>
<span class="n">src</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s2">&quot;queue/run&quot;</span><span class="p">,</span> <span class="n">link</span><span class="p">)</span>
<span class="n">dst</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s2">&quot;queue/new&quot;</span><span class="p">,</span> <span class="n">link</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Moved unfinished compose </span><span class="si">%s</span><span class="s2"> back to new state&quot;</span><span class="p">,</span> <span class="n">src</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">uuids</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s2">&quot;queue/new&quot;</span><span class="p">)),</span> <span class="n">key</span><span class="o">=</span><span class="n">queue_sort</span><span class="p">)</span>
<span class="c1"># Pick the oldest and move it into ./run/</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">uuids</span><span class="p">:</span>
<span class="c1"># No composes left to process, sleep for a bit</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">src</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s2">&quot;queue/new&quot;</span><span class="p">,</span> <span class="n">uuids</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">dst</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">composer_dir</span><span class="p">,</span> <span class="s2">&quot;queue/run&quot;</span><span class="p">,</span> <span class="n">uuids</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dst</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
<span class="c1"># The symlink may vanish if uuid_cancel() has been called</span>
<span class="k">continue</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Starting new compose: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">dst</span><span class="p">)</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="s2">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;RUNNING</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">make_compose</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">dst</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Finished building </span><span class="si">%s</span><span class="s2">, results are in </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">dst</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">dst</span><span class="p">))</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="s2">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;FINISHED</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">write_timestamp</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="n">TS_FINISHED</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="kn">import</span> <span class="nn">traceback</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;traceback: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">())</span>
<span class="c1"># TODO - Write the error message to an ERROR-LOG file to include with the status</span>
<span class="c1"># log.error(&quot;Error running compose: %s&quot;, e)</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="s2">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;FAILED</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">write_timestamp</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="n">TS_FINISHED</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">dst</span><span class="p">)</span></div>
<div class="viewcode-block" id="make_compose"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.make_compose">[docs]</a><span class="k">def</span> <span class="nf">make_compose</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Run anaconda with the final-kickstart.ks from results_dir</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: DataHolder</span>
<span class="sd"> :param results_dir: The directory containing the metadata and results for the build</span>
<span class="sd"> :type results_dir: str</span>
<span class="sd"> :returns: Nothing</span>
<span class="sd"> :raises: May raise various exceptions</span>
<span class="sd"> This takes the final-kickstart.ks, and the settings in config.toml and runs Anaconda</span>
<span class="sd"> in no-virt mode (directly on the host operating system). Exceptions should be caught</span>
<span class="sd"> at the higer level.</span>
<span class="sd"> If there is a failure, the build artifacts will be cleaned up, and any logs will be</span>
<span class="sd"> moved into logs/anaconda/ and their ownership will be set to the user from the cfg</span>
<span class="sd"> object.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Check on the ks&#39;s presence</span>
<span class="n">ks_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;final-kickstart.ks&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">ks_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Missing kickstart file at </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">ks_path</span><span class="p">)</span>
<span class="c1"># The anaconda logs are copied into ./anaconda/ in this directory</span>
<span class="n">log_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;logs/&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">log_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">log_dir</span><span class="p">)</span>
<span class="c1"># Load the compose configuration</span>
<span class="n">cfg_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;config.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Missing config.toml for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="n">cfg_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="c1"># The keys in cfg_dict correspond to the arguments setup in livemedia-creator</span>
<span class="c1"># keys that define what to build should be setup in compose_args, and keys with</span>
<span class="c1"># defaults should be setup here.</span>
<span class="c1"># Make sure that image_name contains no path components</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;image_name&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;image_name&quot;</span><span class="p">])</span>
<span class="c1"># Only support novirt installation, set some other defaults</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;no_virt&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;disk_image&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;fs_image&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;keep_image&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;domacboot&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;anaconda_args&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;proxy&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;armplatform&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;squashfs_args&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;lorax_templates&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">find_templates</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">share_dir</span><span class="p">)</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;tmp&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">tmp</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;dracut_args&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Use default args for dracut</span>
<span class="c1"># TODO How to support other arches?</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;arch&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># Compose things in a temporary directory inside the results directory</span>
<span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;result_dir&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;compose&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;result_dir&quot;</span><span class="p">])</span>
<span class="n">install_cfg</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="o">**</span><span class="n">cfg_dict</span><span class="p">)</span>
<span class="c1"># Some kludges for the 99-copy-logs %post, failure in it will crash the build</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;/tmp/NOSAVE_INPUT_KS&quot;</span><span class="p">,</span> <span class="s2">&quot;/tmp/NOSAVE_LOGS&quot;</span><span class="p">]:</span>
<span class="nb">open</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span>
<span class="c1"># Placing a CANCEL file in the results directory will make execWithRedirect send anaconda a SIGTERM</span>
<span class="k">def</span> <span class="nf">cancel_build</span><span class="p">():</span>
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;CANCEL&quot;</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;cfg = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">install_cfg</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">test_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;TEST&quot;</span><span class="p">)</span>
<span class="n">write_timestamp</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">TS_STARTED</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">test_path</span><span class="p">):</span>
<span class="c1"># Pretend to run the compose</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">test_mode</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">test_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">test_mode</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">test_mode</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;TESTING FAILED compose&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">install_cfg</span><span class="o">.</span><span class="n">image_name</span><span class="p">),</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;TEST IMAGE&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">run_creator</span><span class="p">(</span><span class="n">install_cfg</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="n">cancel_build</span><span class="p">)</span>
<span class="c1"># Extract the results of the compose into results_dir and cleanup the compose directory</span>
<span class="n">move_compose_results</span><span class="p">(</span><span class="n">install_cfg</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="c1"># Make sure any remaining temporary directories are removed (eg. if there was an exception)</span>
<span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">tmp</span><span class="p">,</span> <span class="s2">&quot;lmc-*&quot;</span><span class="p">)):</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">d</span><span class="p">):</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">d</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
<span class="c1"># Make sure that everything under the results directory is owned by the user</span>
<span class="n">user</span> <span class="o">=</span> <span class="n">pwd</span><span class="o">.</span><span class="n">getpwuid</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">uid</span><span class="p">)</span><span class="o">.</span><span class="n">pw_name</span>
<span class="n">group</span> <span class="o">=</span> <span class="n">grp</span><span class="o">.</span><span class="n">getgrgid</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">gid</span><span class="p">)</span><span class="o">.</span><span class="n">gr_name</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Install finished, chowning results to </span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">group</span><span class="p">)</span>
<span class="n">subprocess</span><span class="o">.</span><span class="n">call</span><span class="p">([</span><span class="s2">&quot;chown&quot;</span><span class="p">,</span> <span class="s2">&quot;-R&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">group</span><span class="p">),</span> <span class="n">results_dir</span><span class="p">])</span></div>
<div class="viewcode-block" id="get_compose_type"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.get_compose_type">[docs]</a><span class="k">def</span> <span class="nf">get_compose_type</span><span class="p">(</span><span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the type of composition.</span>
<span class="sd"> :param results_dir: The directory containing the metadata and results for the build</span>
<span class="sd"> :type results_dir: str</span>
<span class="sd"> :returns: The type of compose (eg. &#39;tar&#39;)</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> :raises: RuntimeError if no kickstart template can be found.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Should only be 2 kickstarts, the final-kickstart.ks and the template</span>
<span class="n">t</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">ks</span><span class="p">)[:</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="k">for</span> <span class="n">ks</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;*.ks&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="s2">&quot;final-kickstart&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ks</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Cannot find ks template for build </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">results_dir</span><span class="p">))</span>
<span class="k">return</span> <span class="n">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></div>
<div class="viewcode-block" id="compose_detail"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.compose_detail">[docs]</a><span class="k">def</span> <span class="nf">compose_detail</span><span class="p">(</span><span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return details about the build.</span>
<span class="sd"> :param results_dir: The directory containing the metadata and results for the build</span>
<span class="sd"> :type results_dir: str</span>
<span class="sd"> :returns: A dictionary with details about the compose</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> :raises: IOError if it cannot read the directory, STATUS, or blueprint file.</span>
<span class="sd"> The following details are included in the dict:</span>
<span class="sd"> * id - The uuid of the comoposition</span>
<span class="sd"> * queue_status - The final status of the composition (FINISHED or FAILED)</span>
<span class="sd"> * compose_type - The type of output generated (tar, iso, etc.)</span>
<span class="sd"> * blueprint - Blueprint name</span>
<span class="sd"> * version - Blueprint version</span>
<span class="sd"> * image_size - Size of the image, if finished. 0 otherwise.</span>
<span class="sd"> Various timestamps are also included in the dict. These are all Unix UTC timestamps.</span>
<span class="sd"> It is possible for these timestamps to not always exist, in which case they will be</span>
<span class="sd"> None in Python (or null in JSON). The following timestamps are included:</span>
<span class="sd"> * job_created - When the user submitted the compose</span>
<span class="sd"> * job_started - Anaconda started running</span>
<span class="sd"> * job_finished - Job entered FINISHED or FAILED state</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">build_id</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">results_dir</span><span class="p">))</span>
<span class="n">status</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;STATUS&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">blueprint</span> <span class="o">=</span> <span class="n">recipe_from_file</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="s2">&quot;blueprint.toml&quot;</span><span class="p">))</span>
<span class="n">compose_type</span> <span class="o">=</span> <span class="n">get_compose_type</span><span class="p">(</span><span class="n">results_dir</span><span class="p">)</span>
<span class="n">image_path</span> <span class="o">=</span> <span class="n">get_image_name</span><span class="p">(</span><span class="n">results_dir</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="n">status</span> <span class="o">==</span> <span class="s2">&quot;FINISHED&quot;</span> <span class="ow">and</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">image_path</span><span class="p">):</span>
<span class="n">image_size</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span><span class="o">.</span><span class="n">st_size</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">image_size</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">times</span> <span class="o">=</span> <span class="n">timestamp_dict</span><span class="p">(</span><span class="n">results_dir</span><span class="p">)</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="n">build_id</span><span class="p">,</span>
<span class="s2">&quot;queue_status&quot;</span><span class="p">:</span> <span class="n">status</span><span class="p">,</span>
<span class="s2">&quot;job_created&quot;</span><span class="p">:</span> <span class="n">times</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">TS_CREATED</span><span class="p">),</span>
<span class="s2">&quot;job_started&quot;</span><span class="p">:</span> <span class="n">times</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">TS_STARTED</span><span class="p">),</span>
<span class="s2">&quot;job_finished&quot;</span><span class="p">:</span> <span class="n">times</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">TS_FINISHED</span><span class="p">),</span>
<span class="s2">&quot;compose_type&quot;</span><span class="p">:</span> <span class="n">compose_type</span><span class="p">,</span>
<span class="s2">&quot;blueprint&quot;</span><span class="p">:</span> <span class="n">blueprint</span><span class="p">[</span><span class="s2">&quot;name&quot;</span><span class="p">],</span>
<span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="n">blueprint</span><span class="p">[</span><span class="s2">&quot;version&quot;</span><span class="p">],</span>
<span class="s2">&quot;image_size&quot;</span><span class="p">:</span> <span class="n">image_size</span>
<span class="p">}</span></div>
<div class="viewcode-block" id="queue_status"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.queue_status">[docs]</a><span class="k">def</span> <span class="nf">queue_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return details about what is in the queue.</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :returns: A list of the new composes, and a list of the running composes</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> This returns a dict with 2 lists. &quot;new&quot; is the list of uuids that are waiting to be built,</span>
<span class="sd"> and &quot;run&quot; has the uuids that are being built (currently limited to 1 at a time).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">queue_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;queue&quot;</span><span class="p">)</span>
<span class="n">new_queue</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">queue_dir</span><span class="p">,</span> <span class="s2">&quot;new/*&quot;</span><span class="p">))]</span>
<span class="n">run_queue</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">queue_dir</span><span class="p">,</span> <span class="s2">&quot;run/*&quot;</span><span class="p">))]</span>
<span class="n">new_details</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">new_queue</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">compose_detail</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">new_details</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
<span class="n">run_details</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">run_queue</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">compose_detail</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">run_details</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
<span class="k">return</span> <span class="p">{</span>
<span class="s2">&quot;new&quot;</span><span class="p">:</span> <span class="n">new_details</span><span class="p">,</span>
<span class="s2">&quot;run&quot;</span><span class="p">:</span> <span class="n">run_details</span>
<span class="p">}</span></div>
<div class="viewcode-block" id="uuid_status"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_status">[docs]</a><span class="k">def</span> <span class="nf">uuid_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the details of a specific UUID compose</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: Details about the build</span>
<span class="sd"> :rtype: dict or None</span>
<span class="sd"> Returns the same dict as `compose_details()`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">compose_detail</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span></div>
<div class="viewcode-block" id="build_status"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.build_status">[docs]</a><span class="k">def</span> <span class="nf">build_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">status_filter</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the details of finished or failed builds</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param status_filter: What builds to return. None == all, &quot;FINISHED&quot;, or &quot;FAILED&quot;</span>
<span class="sd"> :type status_filter: str</span>
<span class="sd"> :returns: A list of the build details (from compose_details)</span>
<span class="sd"> :rtype: list of dicts</span>
<span class="sd"> This returns a list of build details for each of the matching builds on the</span>
<span class="sd"> system. It does not return the status of builds that have not been finished.</span>
<span class="sd"> Use queue_status() for those.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">status_filter</span><span class="p">:</span>
<span class="n">status_filter</span> <span class="o">=</span> <span class="p">[</span><span class="n">status_filter</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">status_filter</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;FINISHED&quot;</span><span class="p">,</span> <span class="s2">&quot;FAILED&quot;</span><span class="p">]</span>
<span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;results&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">build</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">result_dir</span> <span class="o">+</span> <span class="s2">&quot;/*&quot;</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Checking status of build </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">build</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">status</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">build</span><span class="p">,</span> <span class="s2">&quot;STATUS&quot;</span><span class="p">),</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="n">status</span> <span class="ow">in</span> <span class="n">status_filter</span><span class="p">:</span>
<span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">compose_detail</span><span class="p">(</span><span class="n">build</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">return</span> <span class="n">results</span></div>
<div class="viewcode-block" id="uuid_cancel"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_cancel">[docs]</a><span class="k">def</span> <span class="nf">uuid_cancel</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Cancel a build and delete its results</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: True if it was canceled and deleted</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> Only call this if the build status is WAITING or RUNNING</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># This status can change (and probably will) while it is in the middle of doing this:</span>
<span class="c1"># It can move from WAITING -&gt; RUNNING or it can move from RUNNING -&gt; FINISHED|FAILED</span>
<span class="c1"># If it is in WAITING remove the symlink and then check to make sure it didn&#39;t show up</span>
<span class="c1"># in RUNNING</span>
<span class="n">queue_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;queue&quot;</span><span class="p">)</span>
<span class="n">uuid_new</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">queue_dir</span><span class="p">,</span> <span class="s2">&quot;new&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_new</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">uuid_new</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
<span class="c1"># The symlink may vanish if the queue monitor started the build</span>
<span class="k">pass</span>
<span class="n">uuid_run</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">queue_dir</span><span class="p">,</span> <span class="s2">&quot;run&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_run</span><span class="p">):</span>
<span class="c1"># Successfully removed it before the build started</span>
<span class="k">return</span> <span class="n">uuid_delete</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c1"># Tell the build to stop running</span>
<span class="n">cancel_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="s2">&quot;CANCEL&quot;</span><span class="p">)</span>
<span class="nb">open</span><span class="p">(</span><span class="n">cancel_path</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="c1"># Wait for status to move to FAILED</span>
<span class="n">started</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">status</span> <span class="o">=</span> <span class="n">uuid_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="n">status</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">status</span><span class="p">[</span><span class="s2">&quot;queue_status&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;FAILED&quot;</span><span class="p">:</span>
<span class="k">break</span>
<span class="c1"># Is this taking too long? Exit anyway and try to cleanup.</span>
<span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">&gt;</span> <span class="n">started</span> <span class="o">+</span> <span class="p">(</span><span class="mi">10</span> <span class="o">*</span> <span class="mi">60</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Failed to cancel the build of </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">break</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="c1"># Remove the partial results</span>
<span class="n">uuid_delete</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span></div>
<div class="viewcode-block" id="uuid_delete"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_delete">[docs]</a><span class="k">def</span> <span class="nf">uuid_delete</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Delete all of the results from a compose</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: True if it was deleted</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> :raises: This will raise an error if the delete failed</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">uuid_dir</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Directory length is too short: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">uuid_dir</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="uuid_info"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_info">[docs]</a><span class="k">def</span> <span class="nf">uuid_info</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return information about the composition</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: dictionary of information about the composition or None</span>
<span class="sd"> :rtype: dict</span>
<span class="sd"> :raises: RuntimeError if there was a problem</span>
<span class="sd"> This will return a dict with the following fields populated:</span>
<span class="sd"> * id - The uuid of the comoposition</span>
<span class="sd"> * config - containing the configuration settings used to run Anaconda</span>
<span class="sd"> * blueprint - The depsolved blueprint used to generate the kickstart</span>
<span class="sd"> * commit - The (local) git commit hash for the blueprint used</span>
<span class="sd"> * deps - The NEVRA of all of the dependencies used in the composition</span>
<span class="sd"> * compose_type - The type of output generated (tar, iso, etc.)</span>
<span class="sd"> * queue_status - The final status of the composition (FINISHED or FAILED)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="c1"># Load the compose configuration</span>
<span class="n">cfg_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;config.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Missing config.toml for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">cfg_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">frozen_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;frozen.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">frozen_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Missing frozen.toml for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">frozen_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">frozen_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">deps_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;deps.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">deps_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Missing deps.toml for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">deps_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">deps_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">details</span> <span class="o">=</span> <span class="n">compose_detail</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">)</span>
<span class="n">commit_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;COMMIT&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">commit_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Missing commit hash for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">commit_id</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">commit_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="n">uuid</span><span class="p">,</span>
<span class="s2">&quot;config&quot;</span><span class="p">:</span> <span class="n">cfg_dict</span><span class="p">,</span>
<span class="s2">&quot;blueprint&quot;</span><span class="p">:</span> <span class="n">frozen_dict</span><span class="p">,</span>
<span class="s2">&quot;commit&quot;</span><span class="p">:</span> <span class="n">commit_id</span><span class="p">,</span>
<span class="s2">&quot;deps&quot;</span><span class="p">:</span> <span class="n">deps_dict</span><span class="p">,</span>
<span class="s2">&quot;compose_type&quot;</span><span class="p">:</span> <span class="n">details</span><span class="p">[</span><span class="s2">&quot;compose_type&quot;</span><span class="p">],</span>
<span class="s2">&quot;queue_status&quot;</span><span class="p">:</span> <span class="n">details</span><span class="p">[</span><span class="s2">&quot;queue_status&quot;</span><span class="p">],</span>
<span class="s2">&quot;image_size&quot;</span><span class="p">:</span> <span class="n">details</span><span class="p">[</span><span class="s2">&quot;image_size&quot;</span><span class="p">]</span>
<span class="p">}</span></div>
<div class="viewcode-block" id="uuid_tar"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_tar">[docs]</a><span class="k">def</span> <span class="nf">uuid_tar</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">metadata</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">image</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">logs</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return a tar of the build data</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :param metadata: Set to true to include all the metadata needed to reproduce the build</span>
<span class="sd"> :type metadata: bool</span>
<span class="sd"> :param image: Set to true to include the output image</span>
<span class="sd"> :type image: bool</span>
<span class="sd"> :param logs: Set to true to include the logs from the build</span>
<span class="sd"> :type logs: bool</span>
<span class="sd"> :returns: A stream of bytes from tar</span>
<span class="sd"> :rtype: A generator</span>
<span class="sd"> :raises: RuntimeError if there was a problem (eg. missing config file)</span>
<span class="sd"> This yields an uncompressed tar&#39;s data to the caller. It includes</span>
<span class="sd"> the selected data to the caller by returning the Popen stdout from the tar process.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> is not a valid build_id&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c1"># Load the compose configuration</span>
<span class="n">cfg_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;config.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Missing config.toml for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">cfg_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">image_name</span> <span class="o">=</span> <span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;image_name&quot;</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">include_file</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;/logs&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="n">logs</span>
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="n">image_name</span><span class="p">):</span>
<span class="k">return</span> <span class="n">image</span>
<span class="k">return</span> <span class="n">metadata</span>
<span class="n">filenames</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;*&quot;</span><span class="p">))</span> <span class="k">if</span> <span class="n">include_file</span><span class="p">(</span><span class="n">f</span><span class="p">)]</span>
<span class="n">tar</span> <span class="o">=</span> <span class="n">Popen</span><span class="p">([</span><span class="s2">&quot;tar&quot;</span><span class="p">,</span> <span class="s2">&quot;-C&quot;</span><span class="p">,</span> <span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;-cf-&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">filenames</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">PIPE</span><span class="p">)</span>
<span class="k">return</span> <span class="n">tar</span><span class="o">.</span><span class="n">stdout</span></div>
<div class="viewcode-block" id="uuid_image"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_image">[docs]</a><span class="k">def</span> <span class="nf">uuid_image</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the filename and full path of the build&#39;s image file</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: The image filename and full path</span>
<span class="sd"> :rtype: tuple of strings</span>
<span class="sd"> :raises: RuntimeError if there was a problem (eg. invalid uuid, missing config file)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">return</span> <span class="n">get_image_name</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">)</span></div>
<div class="viewcode-block" id="get_image_name"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.get_image_name">[docs]</a><span class="k">def</span> <span class="nf">get_image_name</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return the filename and full path of the build&#39;s image file</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :returns: The image filename and full path</span>
<span class="sd"> :rtype: tuple of strings</span>
<span class="sd"> :raises: RuntimeError if there was a problem (eg. invalid uuid, missing config file)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> is not a valid build_id&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c1"># Load the compose configuration</span>
<span class="n">cfg_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;config.toml&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Missing config.toml for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="n">cfg_dict</span> <span class="o">=</span> <span class="n">toml</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">cfg_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">image_name</span> <span class="o">=</span> <span class="n">cfg_dict</span><span class="p">[</span><span class="s2">&quot;image_name&quot;</span><span class="p">]</span>
<span class="k">return</span> <span class="p">(</span><span class="n">image_name</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="n">image_name</span><span class="p">))</span></div>
<div class="viewcode-block" id="uuid_log"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.queue.uuid_log">[docs]</a><span class="k">def</span> <span class="nf">uuid_log</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">1024</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Return `size` kbytes from the end of the anaconda.log</span>
<span class="sd"> :param cfg: Configuration settings</span>
<span class="sd"> :type cfg: ComposerConfig</span>
<span class="sd"> :param uuid: The UUID of the build</span>
<span class="sd"> :type uuid: str</span>
<span class="sd"> :param size: Number of kbytes to read. Default is 1024</span>
<span class="sd"> :type size: int</span>
<span class="sd"> :returns: Up to `size` kbytes from the end of the log</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> :raises: RuntimeError if there was a problem (eg. no log file available)</span>
<span class="sd"> This function tries to return lines from the end of the log, it will</span>
<span class="sd"> attempt to start on a line boundry, and may return less than `size` kbytes.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">uuid_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;composer&quot;</span><span class="p">,</span> <span class="s2">&quot;lib_dir&quot;</span><span class="p">),</span> <span class="s2">&quot;results&quot;</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> is not a valid build_id&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="c1"># While a build is running the logs will be in /tmp/anaconda.log and when it</span>
<span class="c1"># has finished they will be in the results directory</span>
<span class="n">status</span> <span class="o">=</span> <span class="n">uuid_status</span><span class="p">(</span><span class="n">cfg</span><span class="p">,</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="n">status</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Status is missing for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">uuid</span><span class="p">)</span>
<span class="k">if</span> <span class="n">status</span><span class="p">[</span><span class="s2">&quot;queue_status&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;RUNNING&quot;</span><span class="p">:</span>
<span class="n">log_path</span> <span class="o">=</span> <span class="s2">&quot;/tmp/anaconda.log&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">uuid_dir</span><span class="p">,</span> <span class="s2">&quot;logs&quot;</span><span class="p">,</span> <span class="s2">&quot;anaconda&quot;</span><span class="p">,</span> <span class="s2">&quot;anaconda.log&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">log_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;No anaconda.log available.&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">log_path</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
<span class="k">if</span> <span class="n">end</span> <span class="o">&lt;</span> <span class="mi">1024</span> <span class="o">*</span> <span class="n">size</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="n">end</span> <span class="o">-</span> <span class="p">(</span><span class="mi">1024</span> <span class="o">*</span> <span class="n">size</span><span class="p">))</span>
<span class="c1"># Find the start of the next line and return the rest</span>
<span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
<span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,299 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.server &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.server</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.server</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;lorax-composer&quot;</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">namedtuple</span>
<span class="kn">from</span> <span class="nn">flask</span> <span class="k">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">jsonify</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">send_from_directory</span>
<span class="kn">from</span> <span class="nn">glob</span> <span class="k">import</span> <span class="n">glob</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">pylorax</span> <span class="k">import</span> <span class="n">vernum</span>
<span class="kn">from</span> <span class="nn">pylorax.api.crossdomain</span> <span class="k">import</span> <span class="n">crossdomain</span>
<span class="kn">from</span> <span class="nn">pylorax.api.v0</span> <span class="k">import</span> <span class="n">v0_api</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="k">import</span> <span class="n">joinpaths</span>
<span class="n">GitLock</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s2">&quot;GitLock&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;repo&quot;</span><span class="p">,</span> <span class="s2">&quot;lock&quot;</span><span class="p">,</span> <span class="s2">&quot;dir&quot;</span><span class="p">])</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;server&quot;</span><span class="p">,</span> <span class="s2">&quot;GitLock&quot;</span><span class="p">]</span>
<span class="nd">@server</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">server_root</span><span class="p">():</span>
<span class="n">redirect</span><span class="p">(</span><span class="s2">&quot;/api/docs/&quot;</span><span class="p">)</span>
<span class="nd">@server</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/api/docs/&quot;</span><span class="p">)</span>
<span class="nd">@server</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/api/docs/&lt;path:path&gt;&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">api_docs</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="c1"># Find the html docs</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># This assumes it is running from the source tree</span>
<span class="n">docs_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="vm">__file__</span><span class="p">),</span> <span class="s2">&quot;../../../docs/html&quot;</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="n">docs_path</span> <span class="o">=</span> <span class="n">glob</span><span class="p">(</span><span class="s2">&quot;/usr/share/doc/lorax-*/html/&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">path</span><span class="p">:</span>
<span class="n">path</span><span class="o">=</span><span class="s2">&quot;index.html&quot;</span>
<span class="k">return</span> <span class="n">send_from_directory</span><span class="p">(</span><span class="n">docs_path</span><span class="p">,</span> <span class="n">path</span><span class="p">)</span>
<span class="nd">@server</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/api/status&quot;</span><span class="p">)</span>
<span class="nd">@crossdomain</span><span class="p">(</span><span class="n">origin</span><span class="o">=</span><span class="s2">&quot;*&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">v0_status</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> `/api/v0/status`</span>
<span class="sd"> ^^^^^^^^^^^^^^^^</span>
<span class="sd"> Return the status of the API Server::</span>
<span class="sd"> { &quot;api&quot;: &quot;0&quot;,</span>
<span class="sd"> &quot;build&quot;: &quot;devel&quot;,</span>
<span class="sd"> &quot;db_supported&quot;: true,</span>
<span class="sd"> &quot;db_version&quot;: &quot;0&quot;,</span>
<span class="sd"> &quot;schema_version&quot;: &quot;0&quot;,</span>
<span class="sd"> &quot;backend&quot;: &quot;lorax-composer&quot;,</span>
<span class="sd"> &quot;msgs&quot;: []}</span>
<span class="sd"> The &#39;msgs&#39; field can be a list of strings describing startup problems or status that</span>
<span class="sd"> should be displayed to the user. eg. if the compose templates are not depsolving properly</span>
<span class="sd"> the errors will be in &#39;msgs&#39;.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">jsonify</span><span class="p">(</span><span class="n">backend</span><span class="o">=</span><span class="s2">&quot;lorax-composer&quot;</span><span class="p">,</span>
<span class="n">build</span><span class="o">=</span><span class="n">vernum</span><span class="p">,</span>
<span class="n">api</span><span class="o">=</span><span class="s2">&quot;0&quot;</span><span class="p">,</span>
<span class="n">db_version</span><span class="o">=</span><span class="s2">&quot;0&quot;</span><span class="p">,</span>
<span class="n">schema_version</span><span class="o">=</span><span class="s2">&quot;0&quot;</span><span class="p">,</span>
<span class="n">db_supported</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">msgs</span><span class="o">=</span><span class="n">server</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s2">&quot;TEMPLATE_ERRORS&quot;</span><span class="p">])</span>
<span class="n">v0_api</span><span class="p">(</span><span class="n">server</span><span class="p">)</span>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.api.workspace &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<script src="../../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../../index.html">Docs</a> &raquo;</li>
<li><a href="../../index.html">Module code</a> &raquo;</li>
<li><a href="../../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.api.workspace</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.api.workspace</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Copyright (C) 2017 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">pylorax.api.recipes</span> <span class="k">import</span> <span class="n">recipe_filename</span><span class="p">,</span> <span class="n">recipe_from_toml</span><span class="p">,</span> <span class="n">RecipeFileError</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="k">import</span> <span class="n">joinpaths</span>
<div class="viewcode-block" id="workspace_dir"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.workspace.workspace_dir">[docs]</a><span class="k">def</span> <span class="nf">workspace_dir</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Create the workspace&#39;s path from a Repository and branch</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :returns: The path to the branch&#39;s workspace directory</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">repo_path</span> <span class="o">=</span> <span class="n">repo</span><span class="o">.</span><span class="n">get_location</span><span class="p">()</span><span class="o">.</span><span class="n">get_path</span><span class="p">()</span>
<span class="k">return</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">repo_path</span><span class="p">,</span> <span class="s2">&quot;workspace&quot;</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span></div>
<div class="viewcode-block" id="workspace_read"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.workspace.workspace_read">[docs]</a><span class="k">def</span> <span class="nf">workspace_read</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Read a Recipe from the branch&#39;s workspace</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: The name of the recipe</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :returns: The workspace copy of the recipe, or None if it doesn&#39;t exist</span>
<span class="sd"> :rtype: Recipe or None</span>
<span class="sd"> :raises: RecipeFileError</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ws_dir</span> <span class="o">=</span> <span class="n">workspace_dir</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span>
<span class="n">recipe</span> <span class="o">=</span> <span class="n">recipe_from_toml</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;UTF-8&quot;</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">RecipeFileError</span>
<span class="k">return</span> <span class="n">recipe</span></div>
<div class="viewcode-block" id="workspace_write"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.workspace.workspace_write">[docs]</a><span class="k">def</span> <span class="nf">workspace_write</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Write a recipe to the workspace</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe: The recipe to write to the workspace</span>
<span class="sd"> :type recipe: Recipe</span>
<span class="sd"> :returns: None</span>
<span class="sd"> :raises: IO related errors</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ws_dir</span> <span class="o">=</span> <span class="n">workspace_dir</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">,</span> <span class="n">recipe</span><span class="o">.</span><span class="n">filename</span><span class="p">)</span>
<span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">recipe</span><span class="o">.</span><span class="n">toml</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;UTF-8&quot;</span><span class="p">))</span></div>
<div class="viewcode-block" id="workspace_delete"><a class="viewcode-back" href="../../../pylorax.api.html#pylorax.api.workspace.workspace_delete">[docs]</a><span class="k">def</span> <span class="nf">workspace_delete</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">,</span> <span class="n">recipe_name</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Delete the recipe from the workspace</span>
<span class="sd"> :param repo: Open repository</span>
<span class="sd"> :type repo: Git.Repository</span>
<span class="sd"> :param branch: Branch name</span>
<span class="sd"> :type branch: str</span>
<span class="sd"> :param recipe_name: The name of the recipe</span>
<span class="sd"> :type recipe_name: str</span>
<span class="sd"> :returns: None</span>
<span class="sd"> :raises: IO related errors</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ws_dir</span> <span class="o">=</span> <span class="n">workspace_dir</span><span class="p">(</span><span class="n">repo</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">ws_dir</span><span class="p">,</span> <span class="n">recipe_filename</span><span class="p">(</span><span class="n">recipe_name</span><span class="p">))</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.base &mdash; Lorax 28.2 documentation</title>
<title>pylorax.base &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -232,9 +224,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -243,11 +233,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -262,35 +252,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.buildstamp &mdash; Lorax 28.2 documentation</title>
<title>pylorax.buildstamp &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -191,11 +183,12 @@
<div class="viewcode-block" id="BuildStamp"><a class="viewcode-back" href="../../pylorax.html#pylorax.buildstamp.BuildStamp">[docs]</a><span class="k">class</span> <span class="nc">BuildStamp</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">product</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">bugurl</span><span class="p">,</span> <span class="n">isfinal</span><span class="p">,</span> <span class="n">buildarch</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">product</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">bugurl</span><span class="p">,</span> <span class="n">isfinal</span><span class="p">,</span> <span class="n">buildarch</span><span class="p">,</span> <span class="n">variant</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">product</span> <span class="o">=</span> <span class="n">product</span>
<span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">=</span> <span class="n">version</span>
<span class="bp">self</span><span class="o">.</span><span class="n">bugurl</span> <span class="o">=</span> <span class="n">bugurl</span>
<span class="bp">self</span><span class="o">.</span><span class="n">isfinal</span> <span class="o">=</span> <span class="n">isfinal</span>
<span class="bp">self</span><span class="o">.</span><span class="n">variant</span> <span class="o">=</span> <span class="n">variant</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">now</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%Y%m</span><span class="si">%d</span><span class="s2">%H%M&quot;</span><span class="p">)</span>
@ -218,14 +211,14 @@
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;BugURL=</span><span class="si">{0.bugurl}</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;IsFinal=</span><span class="si">{0.isfinal}</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;UUID=</span><span class="si">{0.uuid}</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">variant</span><span class="p">:</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;Variant=</span><span class="si">{0.variant}</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;[Compose]</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">fobj</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;Lorax=</span><span class="si">{0}</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">vernum</span><span class="p">))</span></div></div>
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -234,11 +227,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -253,35 +246,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.cmdline &mdash; Lorax 28.2 documentation</title>
<title>pylorax.cmdline &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -190,7 +182,7 @@
<span class="n">version</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{0}</span><span class="s2">-</span><span class="si">{1}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">vernum</span><span class="p">)</span>
<div class="viewcode-block" id="lorax_parser"><a class="viewcode-back" href="../../pylorax.html#pylorax.cmdline.lorax_parser">[docs]</a><span class="k">def</span> <span class="nf">lorax_parser</span><span class="p">():</span>
<div class="viewcode-block" id="lorax_parser"><a class="viewcode-back" href="../../pylorax.html#pylorax.cmdline.lorax_parser">[docs]</a><span class="k">def</span> <span class="nf">lorax_parser</span><span class="p">(</span><span class="n">dracut_default</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Return the ArgumentParser for lorax&quot;&quot;&quot;</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;Create the Anaconda boot.iso&quot;</span><span class="p">)</span>
@ -210,7 +202,7 @@
<span class="n">optional</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-m&quot;</span><span class="p">,</span> <span class="s2">&quot;--mirrorlist&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;mirrorlist repository (may be listed multiple times)&quot;</span><span class="p">,</span>
<span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;REPOSITORY&quot;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&quot;append&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="p">[])</span>
<span class="n">optional</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-t&quot;</span><span class="p">,</span> <span class="s2">&quot;--variant&quot;</span><span class="p">,</span>
<span class="n">optional</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-t&quot;</span><span class="p">,</span> <span class="s2">&quot;--variant&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;variant name&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;VARIANT&quot;</span><span class="p">)</span>
<span class="n">optional</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-b&quot;</span><span class="p">,</span> <span class="s2">&quot;--bugurl&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;bug reporting URL for the product&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;URL&quot;</span><span class="p">,</span>
@ -272,6 +264,14 @@
<span class="n">optional</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--noverifyssl&quot;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_true&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Do not verify SSL certificates&quot;</span><span class="p">)</span>
<span class="c1"># dracut arguments</span>
<span class="n">dracut_group</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">add_argument_group</span><span class="p">(</span><span class="s2">&quot;dracut arguments&quot;</span><span class="p">)</span>
<span class="n">dracut_group</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--dracut-arg&quot;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&quot;append&quot;</span><span class="p">,</span> <span class="n">dest</span><span class="o">=</span><span class="s2">&quot;dracut_args&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Argument to pass to dracut when &quot;</span>
<span class="s2">&quot;rebuilding the initramfs. Pass this &quot;</span>
<span class="s2">&quot;once for each argument. NOTE: this &quot;</span>
<span class="s2">&quot;overrides the default. (default: </span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="n">dracut_default</span><span class="p">)</span>
<span class="c1"># add the show version option</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;-V&quot;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;show program&#39;s version number and exit&quot;</span><span class="p">,</span>
<span class="n">action</span><span class="o">=</span><span class="s2">&quot;version&quot;</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="n">version</span><span class="p">)</span>
@ -389,7 +389,7 @@
<span class="c1"># Group of arguments to pass to qemu</span>
<span class="n">virt_group</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">add_argument_group</span><span class="p">(</span><span class="s2">&quot;qemu arguments&quot;</span><span class="p">)</span>
<span class="n">virt_group</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--ram&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;MEMORY&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">int</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="mi">1024</span><span class="p">,</span>
<span class="n">virt_group</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--ram&quot;</span><span class="p">,</span> <span class="n">metavar</span><span class="o">=</span><span class="s2">&quot;MEMORY&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">int</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="mi">2048</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Memory to allocate for installer in megabytes.&quot;</span><span class="p">)</span>
<span class="n">virt_group</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--vcpus&quot;</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">int</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Passed to qemu -smp command&quot;</span><span class="p">)</span>
@ -407,6 +407,8 @@
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Use OVMF firmware to boot the VM in UEFI mode&quot;</span><span class="p">)</span>
<span class="n">virt_group</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--no-kvm&quot;</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s2">&quot;store_true&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Skip using kvm with qemu even if it is available.&quot;</span><span class="p">)</span>
<span class="n">virt_group</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--with-rng&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;/dev/random&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;RNG device for QEMU (none for no RNG)&quot;</span><span class="p">)</span>
<span class="c1"># dracut arguments</span>
<span class="n">dracut_group</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">add_argument_group</span><span class="p">(</span><span class="s2">&quot;dracut arguments&quot;</span><span class="p">)</span>
@ -441,7 +443,7 @@
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;Substituted for @TITLE@ in bootloader config files&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--project&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;Linux&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;substituted for @PROJECT@ in bootloader config files&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--releasever&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;25&quot;</span><span class="p">,</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--releasever&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">&quot;28&quot;</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s2">&quot;substituted for @VERSION@ in bootloader config files&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--volid&quot;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s2">&quot;volume id&quot;</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s2">&quot;--squashfs_args&quot;</span><span class="p">,</span>
@ -457,9 +459,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -468,11 +468,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -487,35 +487,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -0,0 +1,931 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.creator &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../index.html">Docs</a> &raquo;</li>
<li><a href="../index.html">Module code</a> &raquo;</li>
<li><a href="../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.creator</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.creator</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Copyright (C) 2011-2018 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">glob</span>
<span class="c1"># Use Mako templates for appliance builder descriptions</span>
<span class="kn">from</span> <span class="nn">mako.template</span> <span class="k">import</span> <span class="n">Template</span>
<span class="kn">from</span> <span class="nn">mako.exceptions</span> <span class="k">import</span> <span class="n">text_error_template</span>
<span class="c1"># Use pykickstart to calculate disk image size</span>
<span class="kn">from</span> <span class="nn">pykickstart.parser</span> <span class="k">import</span> <span class="n">KickstartParser</span>
<span class="kn">from</span> <span class="nn">pykickstart.constants</span> <span class="k">import</span> <span class="n">KS_SHUTDOWN</span>
<span class="kn">from</span> <span class="nn">pykickstart.version</span> <span class="k">import</span> <span class="n">makeVersion</span>
<span class="c1"># Use the Lorax treebuilder branch for iso creation</span>
<span class="kn">from</span> <span class="nn">pylorax</span> <span class="k">import</span> <span class="n">ArchData</span>
<span class="kn">from</span> <span class="nn">pylorax.base</span> <span class="k">import</span> <span class="n">DataHolder</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="k">import</span> <span class="n">execWithRedirect</span><span class="p">,</span> <span class="n">runcmd</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="k">import</span> <span class="n">PartitionMount</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="k">import</span> <span class="n">mount</span><span class="p">,</span> <span class="n">umount</span><span class="p">,</span> <span class="n">Mount</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="k">import</span> <span class="n">mksquashfs</span><span class="p">,</span> <span class="n">mkrootfsimg</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="k">import</span> <span class="n">copytree</span>
<span class="kn">from</span> <span class="nn">pylorax.installer</span> <span class="k">import</span> <span class="n">novirt_install</span><span class="p">,</span> <span class="n">virt_install</span><span class="p">,</span> <span class="n">InstallError</span>
<span class="kn">from</span> <span class="nn">pylorax.treebuilder</span> <span class="k">import</span> <span class="n">TreeBuilder</span><span class="p">,</span> <span class="n">RuntimeBuilder</span>
<span class="kn">from</span> <span class="nn">pylorax.treebuilder</span> <span class="k">import</span> <span class="n">findkernels</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="k">import</span> <span class="n">joinpaths</span><span class="p">,</span> <span class="n">remove</span>
<span class="c1"># Default parameters for rebuilding initramfs, override with --dracut-args</span>
<span class="n">DRACUT_DEFAULT</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;--xz&quot;</span><span class="p">,</span> <span class="s2">&quot;--add&quot;</span><span class="p">,</span> <span class="s2">&quot;livenet dmsquash-live convertfs pollcdrom qemu qemu-net&quot;</span><span class="p">,</span>
<span class="s2">&quot;--omit&quot;</span><span class="p">,</span> <span class="s2">&quot;plymouth&quot;</span><span class="p">,</span> <span class="s2">&quot;--no-hostonly&quot;</span><span class="p">,</span> <span class="s2">&quot;--debug&quot;</span><span class="p">,</span> <span class="s2">&quot;--no-early-microcode&quot;</span><span class="p">]</span>
<span class="n">RUNTIME</span> <span class="o">=</span> <span class="s2">&quot;images/install.img&quot;</span>
<div class="viewcode-block" id="FakeDNF"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.FakeDNF">[docs]</a><span class="k">class</span> <span class="nc">FakeDNF</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A minimal DNF object suitable for passing to RuntimeBuilder</span>
<span class="sd"> lmc uses RuntimeBuilder to run the arch specific iso creation</span>
<span class="sd"> templates, so the the installroot config value is the important part of</span>
<span class="sd"> this. Everything else should be a nop.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conf</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">conf</span> <span class="o">=</span> <span class="n">conf</span>
<div class="viewcode-block" id="FakeDNF.reset"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.FakeDNF.reset">[docs]</a> <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">pass</span></div></div>
<div class="viewcode-block" id="is_image_mounted"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.is_image_mounted">[docs]</a><span class="k">def</span> <span class="nf">is_image_mounted</span><span class="p">(</span><span class="n">disk_img</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check to see if the disk_img is mounted</span>
<span class="sd"> :returns: True if disk_img is in /proc/mounts</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&quot;/proc/mounts&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mounts</span><span class="p">:</span>
<span class="k">for</span> <span class="n">mnt</span> <span class="ow">in</span> <span class="n">mounts</span><span class="p">:</span>
<span class="n">fields</span> <span class="o">=</span> <span class="n">mnt</span><span class="o">.</span><span class="n">split</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">fields</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">fields</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">disk_img</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="find_ostree_root"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.find_ostree_root">[docs]</a><span class="k">def</span> <span class="nf">find_ostree_root</span><span class="p">(</span><span class="n">phys_root</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Find root of ostree deployment</span>
<span class="sd"> :param str phys_root: Path to physical root</span>
<span class="sd"> :returns: Relative path of ostree deployment root</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> :raise Exception: More than one deployment roots were found</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">ostree_root</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">ostree_sysroots</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">phys_root</span><span class="p">,</span> <span class="s2">&quot;ostree/boot.?/*/*/0&quot;</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;ostree_sysroots = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">ostree_sysroots</span><span class="p">)</span>
<span class="k">if</span> <span class="n">ostree_sysroots</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">ostree_sysroots</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;Too many deployment roots found: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">ostree_sysroots</span><span class="p">)</span>
<span class="n">ostree_root</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">ostree_sysroots</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">phys_root</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ostree_root</span></div>
<div class="viewcode-block" id="get_arch"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.get_arch">[docs]</a><span class="k">def</span> <span class="nf">get_arch</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the kernel arch</span>
<span class="sd"> :returns: Arch of first kernel found at mount_dir/boot/ or i386</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="n">findkernels</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;i386&quot;</span>
<span class="k">return</span> <span class="n">kernels</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">arch</span></div>
<div class="viewcode-block" id="squashfs_args"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.squashfs_args">[docs]</a><span class="k">def</span> <span class="nf">squashfs_args</span><span class="p">(</span><span class="n">opts</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Returns the compression type and args to use when making squashfs</span>
<span class="sd"> :param opts: ArgumentParser object with compression and compressopts</span>
<span class="sd"> :returns: tuple of compression type and args</span>
<span class="sd"> :rtype: tuple</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">compression</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span> <span class="ow">or</span> <span class="s2">&quot;xz&quot;</span>
<span class="n">arch</span> <span class="o">=</span> <span class="n">ArchData</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">arch</span> <span class="ow">or</span> <span class="n">os</span><span class="o">.</span><span class="n">uname</span><span class="p">()</span><span class="o">.</span><span class="n">machine</span><span class="p">)</span>
<span class="k">if</span> <span class="n">compression</span> <span class="o">==</span> <span class="s2">&quot;xz&quot;</span> <span class="ow">and</span> <span class="n">arch</span><span class="o">.</span><span class="n">bcj</span><span class="p">:</span>
<span class="n">compressargs</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;-Xbcj&quot;</span><span class="p">,</span> <span class="n">arch</span><span class="o">.</span><span class="n">bcj</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">compressargs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">return</span> <span class="p">(</span><span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="make_appliance"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_appliance">[docs]</a><span class="k">def</span> <span class="nf">make_appliance</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">template</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">networks</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">ram</span><span class="o">=</span><span class="mi">1024</span><span class="p">,</span>
<span class="n">vcpus</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s2">&quot;Linux&quot;</span><span class="p">,</span> <span class="n">project</span><span class="o">=</span><span class="s2">&quot;Linux&quot;</span><span class="p">,</span>
<span class="n">releasever</span><span class="o">=</span><span class="s2">&quot;29&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Generate an appliance description file</span>
<span class="sd"> :param str disk_img: Full path of the disk image</span>
<span class="sd"> :param str name: Name of the appliance, passed to the template</span>
<span class="sd"> :param str template: Full path of Mako template</span>
<span class="sd"> :param str outfile: Full path of file to write, using template</span>
<span class="sd"> :param list networks: List of networks(str) from the kickstart</span>
<span class="sd"> :param int ram: Ram, in MiB, passed to template. Default is 1024</span>
<span class="sd"> :param int vcpus: CPUs, passed to template. Default is 1</span>
<span class="sd"> :param str arch: CPU architecture. Default is &#39;x86_64&#39;</span>
<span class="sd"> :param str title: Title, passed to template. Default is &#39;Linux&#39;</span>
<span class="sd"> :param str project: Project, passed to template. Default is &#39;Linux&#39;</span>
<span class="sd"> :param str releasever: Release version, passed to template. Default is 29</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">disk_img</span> <span class="ow">and</span> <span class="n">template</span> <span class="ow">and</span> <span class="n">outfile</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Creating appliance definition using </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">template</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">arch</span><span class="p">:</span>
<span class="n">arch</span> <span class="o">=</span> <span class="s2">&quot;x86_64&quot;</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Calculating SHA256 checksum of </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="n">sha256</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">()</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">disk_img</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1024</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">sha256</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;SHA256 of </span><span class="si">%s</span><span class="s2"> is </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">sha256</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
<span class="n">disk_info</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">disk_img</span><span class="p">),</span> <span class="nb">format</span><span class="o">=</span><span class="s2">&quot;raw&quot;</span><span class="p">,</span>
<span class="n">checksum_type</span><span class="o">=</span><span class="s2">&quot;sha256&quot;</span><span class="p">,</span> <span class="n">checksum</span><span class="o">=</span><span class="n">sha256</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="n">template</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">disks</span><span class="o">=</span><span class="p">[</span><span class="n">disk_info</span><span class="p">],</span> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
<span class="n">arch</span><span class="o">=</span><span class="n">arch</span><span class="p">,</span> <span class="n">memory</span><span class="o">=</span><span class="n">ram</span><span class="p">,</span> <span class="n">vcpus</span><span class="o">=</span><span class="n">vcpus</span><span class="p">,</span> <span class="n">networks</span><span class="o">=</span><span class="n">networks</span><span class="p">,</span>
<span class="n">title</span><span class="o">=</span><span class="n">title</span><span class="p">,</span> <span class="n">project</span><span class="o">=</span><span class="n">project</span><span class="p">,</span> <span class="n">releasever</span><span class="o">=</span><span class="n">releasever</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">text_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span>
<span class="k">raise</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">result</span><span class="p">)</span></div>
<div class="viewcode-block" id="make_runtime"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_runtime">[docs]</a><span class="k">def</span> <span class="nf">make_runtime</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Make the squashfs image from a directory</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str mount_dir: Directory tree to compress</span>
<span class="sd"> :param str work_dir: Output compressed image to work_dir+images/install.img</span>
<span class="sd"> :param int size: Size of disk image, in GiB</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">kernel_arch</span> <span class="o">=</span> <span class="n">get_arch</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">)</span>
<span class="c1"># Fake dnf object</span>
<span class="n">fake_dbo</span> <span class="o">=</span> <span class="n">FakeDNF</span><span class="p">(</span><span class="n">conf</span><span class="o">=</span><span class="n">DataHolder</span><span class="p">(</span><span class="n">installroot</span><span class="o">=</span><span class="n">mount_dir</span><span class="p">))</span>
<span class="c1"># Fake arch with only basearch set</span>
<span class="n">arch</span> <span class="o">=</span> <span class="n">ArchData</span><span class="p">(</span><span class="n">kernel_arch</span><span class="p">)</span>
<span class="c1"># TODO: Need to get release info from someplace...</span>
<span class="n">product</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">project</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">releasever</span><span class="p">,</span> <span class="n">release</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">variant</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">bugurl</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">isfinal</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="c1"># This is a mounted image partition, cannot hardlink to it, so just use it</span>
<span class="c1"># symlink mount_dir/images to work_dir/images so we don&#39;t run out of space</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s2">&quot;images&quot;</span><span class="p">))</span>
<span class="n">rb</span> <span class="o">=</span> <span class="n">RuntimeBuilder</span><span class="p">(</span><span class="n">product</span><span class="p">,</span> <span class="n">arch</span><span class="p">,</span> <span class="n">fake_dbo</span><span class="p">)</span>
<span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span> <span class="o">=</span> <span class="n">squashfs_args</span><span class="p">(</span><span class="n">opts</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Creating runtime&quot;</span><span class="p">)</span>
<span class="n">rb</span><span class="o">.</span><span class="n">create_runtime</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="n">RUNTIME</span><span class="p">),</span> <span class="n">size</span><span class="o">=</span><span class="n">size</span><span class="p">,</span>
<span class="n">compression</span><span class="o">=</span><span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span><span class="o">=</span><span class="n">compressargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="rebuild_initrds_for_live"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.rebuild_initrds_for_live">[docs]</a><span class="k">def</span> <span class="nf">rebuild_initrds_for_live</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">sys_root_dir</span><span class="p">,</span> <span class="n">results_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Rebuild intrds for pxe live image (root=live:http://)</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str sys_root_dir: Path to root of the system</span>
<span class="sd"> :param str results_dir: Path of directory for storing results</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="n">DRACUT_DEFAULT</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;dracut args = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">dracut_args</span><span class="p">)</span>
<span class="n">dracut</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;dracut&quot;</span><span class="p">,</span> <span class="s2">&quot;--nomdadmconf&quot;</span><span class="p">,</span> <span class="s2">&quot;--nolvmconf&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">dracut_args</span>
<span class="n">kdir</span> <span class="o">=</span> <span class="s2">&quot;boot&quot;</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">kernels_dir</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;boot/ostree/*&quot;</span><span class="p">))</span>
<span class="k">if</span> <span class="n">kernels_dir</span><span class="p">:</span>
<span class="n">kdir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">kernels_dir</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">sys_root_dir</span><span class="p">)</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="p">[</span><span class="n">kernel</span> <span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">findkernels</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="n">kdir</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;No initrds found, cannot rebuild_initrds&quot;</span><span class="p">)</span>
<span class="c1"># Hush some dracut warnings. TODO: bind-mount proc in place?</span>
<span class="nb">open</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span><span class="s2">&quot;/proc/modules&quot;</span><span class="p">),</span><span class="s2">&quot;w&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="c1"># Dracut assumes to have some dirs in disk image</span>
<span class="c1"># /var/tmp for temp files</span>
<span class="n">vartmp_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;var/tmp&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">vartmp_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">vartmp_dir</span><span class="p">)</span>
<span class="c1"># /root (maybe not fatal)</span>
<span class="n">root_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;var/roothome&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">root_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">root_dir</span><span class="p">)</span>
<span class="c1"># /tmp (maybe not fatal)</span>
<span class="n">tmp_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;sysroot/tmp&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">tmp_dir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">tmp_dir</span><span class="p">)</span>
<span class="c1"># Write the new initramfs directly to the results directory</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;results&quot;</span><span class="p">))</span>
<span class="n">mount</span><span class="p">(</span><span class="n">results_dir</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s2">&quot;bind&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;results&quot;</span><span class="p">))</span>
<span class="c1"># Dracut runs out of space inside the minimal rootfs image</span>
<span class="n">mount</span><span class="p">(</span><span class="s2">&quot;/var/tmp&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s2">&quot;bind&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;var/tmp&quot;</span><span class="p">))</span>
<span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">kernel</span><span class="p">,</span> <span class="s2">&quot;initrd&quot;</span><span class="p">):</span>
<span class="n">outfile</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">kernel</span><span class="o">.</span><span class="n">initrd</span><span class="o">.</span><span class="n">path</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Construct an initrd from the kernel name</span>
<span class="n">outfile</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">kernel</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;vmlinuz-&quot;</span><span class="p">,</span> <span class="s2">&quot;initrd-&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;.img&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;rebuilding </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">outfile</span><span class="p">)</span>
<span class="n">kver</span> <span class="o">=</span> <span class="n">kernel</span><span class="o">.</span><span class="n">version</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="n">dracut</span> <span class="o">+</span> <span class="p">[</span><span class="s2">&quot;/results/&quot;</span><span class="o">+</span><span class="n">outfile</span><span class="p">,</span> <span class="n">kver</span><span class="p">]</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">sys_root_dir</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="n">kernel</span><span class="o">.</span><span class="n">path</span><span class="p">),</span> <span class="n">results_dir</span><span class="p">)</span>
<span class="n">umount</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;var/tmp&quot;</span><span class="p">),</span> <span class="n">delete</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">umount</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span> <span class="s2">&quot;results&quot;</span><span class="p">),</span> <span class="n">delete</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">sys_root_dir</span><span class="p">,</span><span class="s2">&quot;/proc/modules&quot;</span><span class="p">))</span></div>
<div class="viewcode-block" id="create_pxe_config"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.create_pxe_config">[docs]</a><span class="k">def</span> <span class="nf">create_pxe_config</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="n">images_dir</span><span class="p">,</span> <span class="n">live_image_name</span><span class="p">,</span> <span class="n">add_args</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create template for pxe to live configuration</span>
<span class="sd"> :param str images_dir: Path of directory with images to be used</span>
<span class="sd"> :param str live_image_name: Name of live rootfs image file</span>
<span class="sd"> :param list add_args: Arguments to be added to initrd= pxe config</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">add_args</span> <span class="o">=</span> <span class="n">add_args</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="n">kernels</span> <span class="o">=</span> <span class="p">[</span><span class="n">kernel</span> <span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">findkernels</span><span class="p">(</span><span class="n">images_dir</span><span class="p">,</span> <span class="n">kdir</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">kernel</span><span class="p">,</span> <span class="s2">&quot;initrd&quot;</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kernels</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">kernel</span> <span class="o">=</span> <span class="n">kernels</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">add_args_str</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">add_args</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="n">template</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">kernel</span><span class="o">=</span><span class="n">kernel</span><span class="o">.</span><span class="n">path</span><span class="p">,</span>
<span class="n">initrd</span><span class="o">=</span><span class="n">kernel</span><span class="o">.</span><span class="n">initrd</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="n">liveimg</span><span class="o">=</span><span class="n">live_image_name</span><span class="p">,</span>
<span class="n">addargs</span><span class="o">=</span><span class="n">add_args_str</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">text_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">())</span>
<span class="k">raise</span>
<span class="k">with</span> <span class="nb">open</span> <span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">images_dir</span><span class="p">,</span> <span class="s2">&quot;PXE_CONFIG&quot;</span><span class="p">),</span> <span class="s2">&quot;w&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">result</span><span class="p">)</span></div>
<div class="viewcode-block" id="make_livecd"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_livecd">[docs]</a><span class="k">def</span> <span class="nf">make_livecd</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Take the content from the disk image and make a livecd out of it</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str mount_dir: Directory tree to compress</span>
<span class="sd"> :param str work_dir: Output compressed image to work_dir+images/install.img</span>
<span class="sd"> This uses wwood&#39;s squashfs live initramfs method:</span>
<span class="sd"> * put the real / into LiveOS/rootfs.img</span>
<span class="sd"> * make a squashfs of the LiveOS/rootfs.img tree</span>
<span class="sd"> * This is loaded by dracut when the cmdline is passed to the kernel:</span>
<span class="sd"> root=live:CDLABEL=&lt;volid&gt; rd.live.image</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">kernel_arch</span> <span class="o">=</span> <span class="n">get_arch</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">)</span>
<span class="n">arch</span> <span class="o">=</span> <span class="n">ArchData</span><span class="p">(</span><span class="n">kernel_arch</span><span class="p">)</span>
<span class="c1"># TODO: Need to get release info from someplace...</span>
<span class="n">product</span> <span class="o">=</span> <span class="n">DataHolder</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">project</span><span class="p">,</span> <span class="n">version</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">releasever</span><span class="p">,</span> <span class="n">release</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">variant</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">bugurl</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">isfinal</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="c1"># Link /images to work_dir/images to make the templates happy</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">islink</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="s2">&quot;images&quot;</span><span class="p">)):</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="s2">&quot;images&quot;</span><span class="p">))</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;/bin/ln&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;-s&quot;</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s2">&quot;images&quot;</span><span class="p">),</span>
<span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="s2">&quot;images&quot;</span><span class="p">)])</span>
<span class="c1"># The templates expect the config files to be in /tmp/config_files</span>
<span class="c1"># I think these should be release specific, not from lorax, but for now</span>
<span class="n">configdir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">lorax_templates</span><span class="p">,</span><span class="s2">&quot;live/config_files/&quot;</span><span class="p">)</span>
<span class="n">configdir_path</span> <span class="o">=</span> <span class="s2">&quot;tmp/config_files&quot;</span>
<span class="n">fullpath</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">configdir_path</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">fullpath</span><span class="p">):</span>
<span class="n">remove</span><span class="p">(</span><span class="n">fullpath</span><span class="p">)</span>
<span class="n">copytree</span><span class="p">(</span><span class="n">configdir</span><span class="p">,</span> <span class="n">fullpath</span><span class="p">)</span>
<span class="n">isolabel</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">volid</span> <span class="ow">or</span> <span class="s2">&quot;</span><span class="si">{0.name}</span><span class="s2">-</span><span class="si">{0.version}</span><span class="s2">-</span><span class="si">{1.basearch}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">product</span><span class="p">,</span> <span class="n">arch</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">isolabel</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">32</span><span class="p">:</span>
<span class="n">isolabel</span> <span class="o">=</span> <span class="n">isolabel</span><span class="p">[:</span><span class="mi">32</span><span class="p">]</span>
<span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;Truncating isolabel to 32 chars: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">isolabel</span><span class="p">)</span>
<span class="n">tb</span> <span class="o">=</span> <span class="n">TreeBuilder</span><span class="p">(</span><span class="n">product</span><span class="o">=</span><span class="n">product</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="n">arch</span><span class="p">,</span> <span class="n">domacboot</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">domacboot</span><span class="p">,</span>
<span class="n">inroot</span><span class="o">=</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">outroot</span><span class="o">=</span><span class="n">work_dir</span><span class="p">,</span>
<span class="n">runtime</span><span class="o">=</span><span class="n">RUNTIME</span><span class="p">,</span> <span class="n">isolabel</span><span class="o">=</span><span class="n">isolabel</span><span class="p">,</span>
<span class="n">templatedir</span><span class="o">=</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">lorax_templates</span><span class="p">,</span><span class="s2">&quot;live/&quot;</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Rebuilding initrds&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="n">DRACUT_DEFAULT</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">dracut_args</span><span class="p">:</span>
<span class="n">dracut_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;dracut args = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">dracut_args</span><span class="p">)</span>
<span class="n">tb</span><span class="o">.</span><span class="n">rebuild_initrds</span><span class="p">(</span><span class="n">add_args</span><span class="o">=</span><span class="n">dracut_args</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Building boot.iso&quot;</span><span class="p">)</span>
<span class="n">tb</span><span class="o">.</span><span class="n">build</span><span class="p">()</span>
<span class="k">return</span> <span class="n">work_dir</span></div>
<div class="viewcode-block" id="mount_boot_part_over_root"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.mount_boot_part_over_root">[docs]</a><span class="k">def</span> <span class="nf">mount_boot_part_over_root</span><span class="p">(</span><span class="n">img_mount</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Mount boot partition to /boot of root fs mounted in img_mount</span>
<span class="sd"> Used for OSTree so it finds deployment configurations on live rootfs</span>
<span class="sd"> param img_mount: object with mounted disk image root partition</span>
<span class="sd"> type img_mount: imgutils.PartitionMount</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">root_dir</span> <span class="o">=</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span>
<span class="n">is_boot_part</span> <span class="o">=</span> <span class="k">lambda</span> <span class="nb">dir</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="nb">dir</span><span class="o">+</span><span class="s2">&quot;/loader.0&quot;</span><span class="p">)</span>
<span class="n">tmp_mount_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-tmpdir-&quot;</span><span class="p">)</span>
<span class="n">sysroot_boot_dir</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">for</span> <span class="n">dev</span><span class="p">,</span> <span class="n">_size</span> <span class="ow">in</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">loop_devices</span><span class="p">:</span>
<span class="k">if</span> <span class="n">dev</span> <span class="ow">is</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dev</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">mount</span><span class="p">(</span><span class="s2">&quot;/dev/mapper/&quot;</span><span class="o">+</span><span class="n">dev</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">tmp_mount_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">is_boot_part</span><span class="p">(</span><span class="n">tmp_mount_dir</span><span class="p">):</span>
<span class="n">umount</span><span class="p">(</span><span class="n">tmp_mount_dir</span><span class="p">)</span>
<span class="n">sysroot_boot_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">root_dir</span><span class="p">,</span> <span class="s2">&quot;boot&quot;</span><span class="p">)</span>
<span class="n">mount</span><span class="p">(</span><span class="s2">&quot;/dev/mapper/&quot;</span><span class="o">+</span><span class="n">dev</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">sysroot_boot_dir</span><span class="p">)</span>
<span class="k">break</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span><span class="n">tmp_mount_dir</span><span class="p">)</span>
<span class="k">except</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Looking for boot partition error: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="n">remove</span><span class="p">(</span><span class="n">tmp_mount_dir</span><span class="p">)</span>
<span class="k">return</span> <span class="n">sysroot_boot_dir</span></div>
<div class="viewcode-block" id="make_squashfs"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_squashfs">[docs]</a><span class="k">def</span> <span class="nf">make_squashfs</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create a squashfs image of an unpartitioned filesystem disk image</span>
<span class="sd"> :param str disk_img: Path to the unpartitioned filesystem disk image</span>
<span class="sd"> :param str work_dir: Output compressed image to work_dir+images/install.img</span>
<span class="sd"> :param str compression: Compression type to use</span>
<span class="sd"> :returns: True if squashfs creation was successful. False if there was an error.</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> Take disk_img and put it into LiveOS/rootfs.img and squashfs this</span>
<span class="sd"> tree into work_dir+images/install.img</span>
<span class="sd"> fsck.ext4 is run on the disk image to make sure there are no errors and to zero</span>
<span class="sd"> out any deleted blocks to make it compress better. If this fails for any reason</span>
<span class="sd"> it will return False and log the error.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Make sure free blocks are actually zeroed so it will compress</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;/usr/sbin/fsck.ext4&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;-y&quot;</span><span class="p">,</span> <span class="s2">&quot;-f&quot;</span><span class="p">,</span> <span class="s2">&quot;-E&quot;</span><span class="p">,</span> <span class="s2">&quot;discard&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">])</span>
<span class="k">if</span> <span class="n">rc</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Problem zeroing free blocks of </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="n">liveos_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s2">&quot;runtime/LiveOS&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="n">RUNTIME</span><span class="p">)))</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;/bin/ln&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">,</span> <span class="s2">&quot;rootfs.img&quot;</span><span class="p">)])</span>
<span class="k">if</span> <span class="n">rc</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">,</span> <span class="s2">&quot;rootfs.img&quot;</span><span class="p">))</span>
<span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span> <span class="o">=</span> <span class="n">squashfs_args</span><span class="p">(</span><span class="n">opts</span><span class="p">)</span>
<span class="n">mksquashfs</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s2">&quot;runtime&quot;</span><span class="p">),</span>
<span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="n">RUNTIME</span><span class="p">),</span> <span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span><span class="p">)</span>
<span class="n">remove</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s2">&quot;runtime&quot;</span><span class="p">))</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="calculate_disk_size"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.calculate_disk_size">[docs]</a><span class="k">def</span> <span class="nf">calculate_disk_size</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">ks</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Calculate the disk size from the kickstart</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str ks: Path to the kickstart to use for the installation</span>
<span class="sd"> :returns: Disk size in MiB</span>
<span class="sd"> :rtype: int</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Disk size for a filesystem image should only be the size of /</span>
<span class="c1"># to prevent surprises when using the same kickstart for different installations.</span>
<span class="n">unique_partitions</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">((</span><span class="n">p</span><span class="o">.</span><span class="n">mountpoint</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">partition</span><span class="o">.</span><span class="n">partitions</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span> <span class="ow">and</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">make_iso</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span><span class="p">):</span>
<span class="n">disk_size</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">+</span> <span class="nb">sum</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">size</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">unique_partitions</span><span class="o">.</span><span class="n">values</span><span class="p">()</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">mountpoint</span> <span class="o">==</span> <span class="s2">&quot;/&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">disk_size</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">+</span> <span class="nb">sum</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">size</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">unique_partitions</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Using disk size of </span><span class="si">%s</span><span class="s2">MiB&quot;</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">)</span>
<span class="k">return</span> <span class="n">disk_size</span></div>
<div class="viewcode-block" id="make_image"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_image">[docs]</a><span class="k">def</span> <span class="nf">make_image</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">ks</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Install to a disk image</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str ks: Path to the kickstart to use for the installation</span>
<span class="sd"> :returns: Path of the image created</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> Use qemu+boot.iso or anaconda to install to a disk image.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_name</span><span class="p">:</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_name</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-disk-&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s2">&quot;.img&quot;</span><span class="p">,</span> <span class="nb">dir</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">result_dir</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;disk_img = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="n">disk_size</span> <span class="o">=</span> <span class="n">calculate_disk_size</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">ks</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span><span class="p">:</span>
<span class="n">novirt_install</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">install_log</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">logfile</span><span class="p">))</span><span class="o">+</span><span class="s2">&quot;/virt-install.log&quot;</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;install_log = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">install_log</span><span class="p">)</span>
<span class="n">virt_install</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">install_log</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">)</span>
<span class="k">except</span> <span class="n">InstallError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Install failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">keep_image</span> <span class="ow">and</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">disk_img</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Removing bad disk image&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">disk_img</span><span class="p">)</span>
<span class="k">raise</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Disk Image install successful&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">disk_img</span></div>
<div class="viewcode-block" id="make_live_images"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.make_live_images">[docs]</a><span class="k">def</span> <span class="nf">make_live_images</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create live images from direcory or rootfs image</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str work_dir: Directory for storing results</span>
<span class="sd"> :param str disk_img: Path to disk image (fsimage or partitioned)</span>
<span class="sd"> :returns: Path of directory with created images or None</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> fsck.ext4 is run on the rootfs_image to make sure there are no errors and to zero</span>
<span class="sd"> out any deleted blocks to make it compress better. If this fails for any reason</span>
<span class="sd"> it will return None and log the error.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">sys_root</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">squashfs_root_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="s2">&quot;squashfs_root&quot;</span><span class="p">)</span>
<span class="n">liveos_dir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">squashfs_root_dir</span><span class="p">,</span> <span class="s2">&quot;LiveOS&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">)</span>
<span class="n">rootfs_img</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">liveos_dir</span><span class="p">,</span> <span class="s2">&quot;rootfs.img&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span><span class="p">:</span>
<span class="c1"># Find the ostree root in the fsimage</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="k">with</span> <span class="n">Mount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s2">&quot;loop&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mnt_dir</span><span class="p">:</span>
<span class="n">sys_root</span> <span class="o">=</span> <span class="n">find_ostree_root</span><span class="p">(</span><span class="n">mnt_dir</span><span class="p">)</span>
<span class="c1"># Try to hardlink the image, if that fails, copy it</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;/bin/ln&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">rootfs_img</span><span class="p">])</span>
<span class="k">if</span> <span class="n">rc</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">rootfs_img</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">is_root_part</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">is_root_part</span> <span class="o">=</span> <span class="k">lambda</span> <span class="nb">dir</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="nb">dir</span><span class="o">+</span><span class="s2">&quot;/ostree/deploy&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">mount_ok</span><span class="o">=</span><span class="n">is_root_part</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="n">img_mount</span> <span class="ow">and</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">mounted_sysroot_boot_dir</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">sys_root</span> <span class="o">=</span> <span class="n">find_ostree_root</span><span class="p">(</span><span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">)</span>
<span class="n">mounted_sysroot_boot_dir</span> <span class="o">=</span> <span class="n">mount_boot_part_over_root</span><span class="p">(</span><span class="n">img_mount</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">live_rootfs_keep_size</span><span class="p">:</span>
<span class="n">size</span> <span class="o">=</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_size</span> <span class="o">/</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">3</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">size</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">live_rootfs_size</span> <span class="ow">or</span> <span class="kc">None</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Creating live rootfs image&quot;</span><span class="p">)</span>
<span class="n">mkrootfsimg</span><span class="p">(</span><span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">rootfs_img</span><span class="p">,</span> <span class="s2">&quot;LiveOS&quot;</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">size</span><span class="p">,</span> <span class="n">sysroot</span><span class="o">=</span><span class="n">sys_root</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">if</span> <span class="n">mounted_sysroot_boot_dir</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span><span class="n">mounted_sysroot_boot_dir</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;sys_root = </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">sys_root</span><span class="p">)</span>
<span class="c1"># Make sure free blocks are actually zeroed so it will compress</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;/usr/sbin/fsck.ext4&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;-y&quot;</span><span class="p">,</span> <span class="s2">&quot;-f&quot;</span><span class="p">,</span> <span class="s2">&quot;-E&quot;</span><span class="p">,</span> <span class="s2">&quot;discard&quot;</span><span class="p">,</span> <span class="n">rootfs_img</span><span class="p">])</span>
<span class="k">if</span> <span class="n">rc</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Problem zeroing free blocks of </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Packing live rootfs image&quot;</span><span class="p">)</span>
<span class="n">add_pxe_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">live_image_name</span> <span class="o">=</span> <span class="s2">&quot;live-rootfs.squashfs.img&quot;</span>
<span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span> <span class="o">=</span> <span class="n">squashfs_args</span><span class="p">(</span><span class="n">opts</span><span class="p">)</span>
<span class="n">mksquashfs</span><span class="p">(</span><span class="n">squashfs_root_dir</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">work_dir</span><span class="p">,</span> <span class="n">live_image_name</span><span class="p">),</span> <span class="n">compression</span><span class="p">,</span> <span class="n">compressargs</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Rebuilding initramfs for live&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="n">Mount</span><span class="p">(</span><span class="n">rootfs_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s2">&quot;loop&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mnt_dir</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">mount</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">mnt_dir</span><span class="p">,</span> <span class="s2">&quot;boot&quot;</span><span class="p">),</span> <span class="n">opts</span><span class="o">=</span><span class="s2">&quot;bind&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">mnt_dir</span><span class="p">,</span> <span class="n">sys_root</span><span class="p">,</span> <span class="s2">&quot;boot&quot;</span><span class="p">))</span>
<span class="n">rebuild_initrds_for_live</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">mnt_dir</span><span class="p">,</span> <span class="n">sys_root</span><span class="p">),</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">mnt_dir</span><span class="p">,</span> <span class="n">sys_root</span><span class="p">,</span> <span class="s2">&quot;boot&quot;</span><span class="p">),</span> <span class="n">delete</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">remove</span><span class="p">(</span><span class="n">squashfs_root_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ostree</span><span class="p">:</span>
<span class="n">add_pxe_args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;ostree=/</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">sys_root</span><span class="p">)</span>
<span class="n">template</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">lorax_templates</span><span class="p">,</span> <span class="s2">&quot;pxe-live/pxe-config.tmpl&quot;</span><span class="p">)</span>
<span class="n">create_pxe_config</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">live_image_name</span><span class="p">,</span> <span class="n">add_pxe_args</span><span class="p">)</span>
<span class="k">return</span> <span class="n">work_dir</span></div>
<div class="viewcode-block" id="run_creator"><a class="viewcode-back" href="../../pylorax.html#pylorax.creator.run_creator">[docs]</a><span class="k">def</span> <span class="nf">run_creator</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">callback_func</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Run the image creator process</span>
<span class="sd"> :param opts: Commandline options to control the process</span>
<span class="sd"> :type opts: Either a DataHolder or ArgumentParser</span>
<span class="sd"> :returns: The result directory and the disk image path.</span>
<span class="sd"> :rtype: Tuple of str</span>
<span class="sd"> This function takes the opts arguments and creates the selected output image.</span>
<span class="sd"> See the cmdline --help for livemedia-creator for the possible options</span>
<span class="sd"> (Yes, this is not ideal, but we can fix that later)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># Parse the kickstart</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">:</span>
<span class="n">ks_version</span> <span class="o">=</span> <span class="n">makeVersion</span><span class="p">()</span>
<span class="n">ks</span> <span class="o">=</span> <span class="n">KickstartParser</span><span class="p">(</span><span class="n">ks_version</span><span class="p">,</span> <span class="n">errorsAreFatal</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">missingIncludeIsFatal</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">ks</span><span class="o">.</span><span class="n">readKickstart</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="c1"># live iso usually needs dracut-live so warn the user if it is missing</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span> <span class="ow">and</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_iso</span><span class="p">:</span>
<span class="k">if</span> <span class="s2">&quot;dracut-live&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">packages</span><span class="o">.</span><span class="n">packageList</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;dracut-live package is missing from the kickstart.&quot;</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;dracut-live package is missing from the kickstart.&quot;</span><span class="p">)</span>
<span class="c1"># Make the disk or filesystem image</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Image creation requires a kickstart file&quot;</span><span class="p">)</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span> <span class="ow">and</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">method</span><span class="o">.</span><span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;url&quot;</span><span class="p">,</span> <span class="s2">&quot;nfs&quot;</span><span class="p">)</span> \
<span class="ow">and</span> <span class="ow">not</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">ostreesetup</span><span class="o">.</span><span class="n">seen</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;Only url, nfs and ostreesetup install methods are currently supported.&quot;</span>
<span class="s2">&quot;Please fix your kickstart file.&quot;</span> <span class="p">)</span>
<span class="k">if</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">method</span><span class="o">.</span><span class="n">method</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;url&quot;</span><span class="p">,</span> <span class="s2">&quot;nfs&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">seen</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;The kickstart must activate networking if &quot;</span>
<span class="s2">&quot;the url or nfs install method is used.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">displaymode</span><span class="o">.</span><span class="n">displayMode</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;The kickstart must not set a display mode (text, cmdline, &quot;</span>
<span class="s2">&quot;graphical), this will interfere with livemedia-creator.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span> <span class="ow">or</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">make_pxe_live</span> <span class="ow">and</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span><span class="p">):</span>
<span class="c1"># Make sure the kickstart isn&#39;t using autopart and only has a / mountpoint</span>
<span class="n">part_ok</span> <span class="o">=</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">(</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">partition</span><span class="o">.</span><span class="n">partitions</span>
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">mountpoint</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;/&quot;</span><span class="p">,</span> <span class="s2">&quot;swap&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">part_ok</span> <span class="ow">or</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">autopart</span><span class="o">.</span><span class="n">seen</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;Filesystem images must use a single / part, not autopart or &quot;</span>
<span class="s2">&quot;multiple partitions. swap is allowed but not used.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span> <span class="ow">and</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">reboot</span><span class="o">.</span><span class="n">action</span> <span class="o">!=</span> <span class="n">KS_SHUTDOWN</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;The kickstart must include shutdown when using virt installation.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">errors</span><span class="p">:</span>
<span class="nb">list</span><span class="p">(</span><span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span> <span class="ow">in</span> <span class="n">errors</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">errors</span><span class="p">))</span>
<span class="c1"># Make the image. Output of this is either a partitioned disk image or a fsimage</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">make_image</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">ks</span><span class="p">)</span>
<span class="k">except</span> <span class="n">InstallError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;ERROR: Image creation failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Image creation failed: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">e</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_only</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_iso</span><span class="p">:</span>
<span class="n">work_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-work-&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;working dir is </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_virt</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span><span class="p">:</span>
<span class="c1"># Create iso from a filesystem image</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span> <span class="ow">or</span> <span class="n">disk_img</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">make_squashfs</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;squashfs.img creation failed&quot;</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;squashfs.img creation failed&quot;</span><span class="p">)</span>
<span class="k">with</span> <span class="n">Mount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s2">&quot;loop&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">mount_dir</span><span class="p">:</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">make_livecd</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Create iso from a partitioned disk image</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">or</span> <span class="n">disk_img</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="n">img_mount</span> <span class="ow">and</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="n">make_runtime</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">calculate_disk_size</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">ks</span><span class="p">)</span><span class="o">/</span><span class="mf">1024.0</span><span class="p">)</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">make_livecd</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="c1"># --iso-only removes the extra build artifacts, keeping only the boot.iso</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">iso_only</span> <span class="ow">and</span> <span class="n">result_dir</span><span class="p">:</span>
<span class="n">boot_iso</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">result_dir</span><span class="p">,</span> <span class="s2">&quot;images/boot.iso&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">boot_iso</span><span class="p">):</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> is missing, skipping --iso-only.&quot;</span><span class="p">,</span> <span class="n">boot_iso</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">iso_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-result-&quot;</span><span class="p">)</span>
<span class="n">dest_file</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">iso_dir</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">iso_name</span> <span class="ow">or</span> <span class="s2">&quot;boot.iso&quot;</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">boot_iso</span><span class="p">,</span> <span class="n">dest_file</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">result_dir</span><span class="p">)</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">iso_dir</span>
<span class="c1"># cleanup the mess</span>
<span class="c1"># cleanup work_dir?</span>
<span class="k">if</span> <span class="n">disk_img</span> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">keep_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">disk_img</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Disk image erased&quot;</span><span class="p">)</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_appliance</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">:</span>
<span class="n">networks</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">networks</span> <span class="o">=</span> <span class="n">ks</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">network</span>
<span class="n">make_appliance</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">or</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">app_name</span><span class="p">,</span>
<span class="n">opts</span><span class="o">.</span><span class="n">app_template</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">app_file</span><span class="p">,</span> <span class="n">networks</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">ram</span><span class="p">,</span>
<span class="n">opts</span><span class="o">.</span><span class="n">vcpus</span> <span class="ow">or</span> <span class="mi">1</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">project</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">releasever</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_pxe_live</span><span class="p">:</span>
<span class="n">work_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-work-&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;working dir is </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">)</span>
<span class="n">disk_img</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">fs_image</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">disk_image</span> <span class="ow">or</span> <span class="n">disk_img</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;disk image is </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="n">make_live_images</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">work_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span>
<span class="k">if</span> <span class="n">result_dir</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Creating PXE live image failed.&quot;</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Creating PXE live image failed.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">result_dir</span> <span class="o">!=</span> <span class="n">opts</span><span class="o">.</span><span class="n">tmp</span> <span class="ow">and</span> <span class="n">result_dir</span><span class="p">:</span>
<span class="n">copytree</span><span class="p">(</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">preserve</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">result_dir</span><span class="p">)</span>
<span class="n">result_dir</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">return</span> <span class="p">(</span><span class="n">result_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">)</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.decorators &mdash; Lorax 28.2 documentation</title>
<title>pylorax.decorators &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -195,9 +187,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -206,11 +196,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -225,35 +215,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.discinfo &mdash; Lorax 28.2 documentation</title>
<title>pylorax.discinfo &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -204,9 +196,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -215,11 +205,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -234,35 +224,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -0,0 +1,380 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.dnfbase &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../index.html">Docs</a> &raquo;</li>
<li><a href="../index.html">Module code</a> &raquo;</li>
<li><a href="../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.dnfbase</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.dnfbase</h1><div class="highlight"><pre>
<span></span><span class="c1"># Copyright (C) 2018 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">dnf</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<div class="viewcode-block" id="get_dnf_base_object"><a class="viewcode-back" href="../../pylorax.html#pylorax.dnfbase.get_dnf_base_object">[docs]</a><span class="k">def</span> <span class="nf">get_dnf_base_object</span><span class="p">(</span><span class="n">installroot</span><span class="p">,</span> <span class="n">sources</span><span class="p">,</span> <span class="n">mirrorlists</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">repos</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">enablerepos</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">disablerepos</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">tempdir</span><span class="o">=</span><span class="s2">&quot;/var/tmp&quot;</span><span class="p">,</span> <span class="n">proxy</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">releasever</span><span class="o">=</span><span class="s2">&quot;28&quot;</span><span class="p">,</span>
<span class="n">cachedir</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">logdir</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">sslverify</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Create a dnf Base object and setup the repositories and installroot</span>
<span class="sd"> :param string installroot: Full path to the installroot</span>
<span class="sd"> :param list sources: List of source repo urls to use for the installation</span>
<span class="sd"> :param list enablerepos: List of repo names to enable</span>
<span class="sd"> :param list disablerepos: List of repo names to disable</span>
<span class="sd"> :param list mirrorlist: List of mirrors to use</span>
<span class="sd"> :param string tempdir: Path of temporary directory</span>
<span class="sd"> :param string proxy: http proxy to use when fetching packages</span>
<span class="sd"> :param string releasever: Release version to pass to dnf</span>
<span class="sd"> :param string cachedir: Directory to use for caching packages</span>
<span class="sd"> :param bool noverifyssl: Set to True to ignore the CA of ssl certs. eg. use self-signed ssl for https repos.</span>
<span class="sd"> If tempdir is not set /var/tmp is used.</span>
<span class="sd"> If cachedir is None a dnf.cache directory is created inside tmpdir</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">sanitize_repo</span><span class="p">(</span><span class="n">repo</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Convert bare paths to file:/// URIs, and silently reject protocols unhandled by yum&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">repo</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">&quot;file://</span><span class="si">{0}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">repo</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">any</span><span class="p">(</span><span class="n">repo</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;http://&#39;</span><span class="p">,</span> <span class="s1">&#39;https://&#39;</span><span class="p">,</span> <span class="s1">&#39;ftp://&#39;</span><span class="p">,</span> <span class="s1">&#39;file://&#39;</span><span class="p">)):</span>
<span class="k">return</span> <span class="n">repo</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="n">mirrorlists</span> <span class="o">=</span> <span class="n">mirrorlists</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="c1"># sanitize the repositories</span>
<span class="n">sources</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">sanitize_repo</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">sources</span><span class="p">)</span>
<span class="n">mirrorlists</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">sanitize_repo</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">mirrorlists</span><span class="p">)</span>
<span class="c1"># remove invalid repositories</span>
<span class="n">sources</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">r</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">sources</span> <span class="k">if</span> <span class="n">r</span><span class="p">)</span>
<span class="n">mirrorlists</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">r</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">mirrorlists</span> <span class="k">if</span> <span class="n">r</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">cachedir</span><span class="p">:</span>
<span class="n">cachedir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tempdir</span><span class="p">,</span> <span class="s2">&quot;dnf.cache&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">cachedir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">cachedir</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">logdir</span><span class="p">:</span>
<span class="n">logdir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tempdir</span><span class="p">,</span> <span class="s2">&quot;dnf.logs&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">logdir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">logdir</span><span class="p">)</span>
<span class="n">dnfbase</span> <span class="o">=</span> <span class="n">dnf</span><span class="o">.</span><span class="n">Base</span><span class="p">()</span>
<span class="n">conf</span> <span class="o">=</span> <span class="n">dnfbase</span><span class="o">.</span><span class="n">conf</span>
<span class="n">conf</span><span class="o">.</span><span class="n">logdir</span> <span class="o">=</span> <span class="n">logdir</span>
<span class="n">conf</span><span class="o">.</span><span class="n">cachedir</span> <span class="o">=</span> <span class="n">cachedir</span>
<span class="n">conf</span><span class="o">.</span><span class="n">install_weak_deps</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">conf</span><span class="o">.</span><span class="n">releasever</span> <span class="o">=</span> <span class="n">releasever</span>
<span class="n">conf</span><span class="o">.</span><span class="n">installroot</span> <span class="o">=</span> <span class="n">installroot</span>
<span class="n">conf</span><span class="o">.</span><span class="n">prepend_installroot</span><span class="p">(</span><span class="s1">&#39;persistdir&#39;</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">tsflags</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;nodocs&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">proxy</span><span class="p">:</span>
<span class="n">conf</span><span class="o">.</span><span class="n">proxy</span> <span class="o">=</span> <span class="n">proxy</span>
<span class="k">if</span> <span class="n">sslverify</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>
<span class="n">conf</span><span class="o">.</span><span class="n">sslverify</span> <span class="o">=</span> <span class="kc">False</span>
<span class="c1"># Add .repo files</span>
<span class="k">if</span> <span class="n">repos</span><span class="p">:</span>
<span class="n">reposdir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tempdir</span><span class="p">,</span> <span class="s2">&quot;dnf.repos&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">reposdir</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">reposdir</span><span class="p">)</span>
<span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">repos</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">reposdir</span><span class="p">)</span>
<span class="n">conf</span><span class="o">.</span><span class="n">reposdir</span> <span class="o">=</span> <span class="p">[</span><span class="n">reposdir</span><span class="p">]</span>
<span class="n">dnfbase</span><span class="o">.</span><span class="n">read_all_repos</span><span class="p">()</span>
<span class="c1"># add the sources</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">sources</span><span class="p">):</span>
<span class="k">if</span> <span class="s2">&quot;SRPM&quot;</span> <span class="ow">in</span> <span class="n">r</span> <span class="ow">or</span> <span class="s2">&quot;srpm&quot;</span> <span class="ow">in</span> <span class="n">r</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Skipping source repo: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">repo_name</span> <span class="o">=</span> <span class="s2">&quot;lorax-repo-</span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">i</span>
<span class="n">repo</span> <span class="o">=</span> <span class="n">dnf</span><span class="o">.</span><span class="n">repo</span><span class="o">.</span><span class="n">Repo</span><span class="p">(</span><span class="n">repo_name</span><span class="p">,</span> <span class="n">conf</span><span class="p">)</span>
<span class="n">repo</span><span class="o">.</span><span class="n">baseurl</span> <span class="o">=</span> <span class="p">[</span><span class="n">r</span><span class="p">]</span>
<span class="k">if</span> <span class="n">proxy</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">proxy</span> <span class="o">=</span> <span class="n">proxy</span>
<span class="n">repo</span><span class="o">.</span><span class="n">enable</span><span class="p">()</span>
<span class="n">dnfbase</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">repo</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Added &#39;</span><span class="si">%s</span><span class="s2">&#39;: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">repo_name</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Fetching metadata...&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
<span class="k">except</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">RepoError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Error fetching metadata for </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">repo_name</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="c1"># add the mirrorlists</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">r</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">mirrorlists</span><span class="p">):</span>
<span class="k">if</span> <span class="s2">&quot;SRPM&quot;</span> <span class="ow">in</span> <span class="n">r</span> <span class="ow">or</span> <span class="s2">&quot;srpm&quot;</span> <span class="ow">in</span> <span class="n">r</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Skipping source repo: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="k">continue</span>
<span class="n">repo_name</span> <span class="o">=</span> <span class="s2">&quot;lorax-mirrorlist-</span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">i</span>
<span class="n">repo</span> <span class="o">=</span> <span class="n">dnf</span><span class="o">.</span><span class="n">repo</span><span class="o">.</span><span class="n">Repo</span><span class="p">(</span><span class="n">repo_name</span><span class="p">,</span> <span class="n">conf</span><span class="p">)</span>
<span class="n">repo</span><span class="o">.</span><span class="n">mirrorlist</span> <span class="o">=</span> <span class="n">r</span>
<span class="k">if</span> <span class="n">proxy</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">proxy</span> <span class="o">=</span> <span class="n">proxy</span>
<span class="n">repo</span><span class="o">.</span><span class="n">enable</span><span class="p">()</span>
<span class="n">dnfbase</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">repo</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Added &#39;</span><span class="si">%s</span><span class="s2">&#39;: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">repo_name</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Fetching metadata...&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">repo</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
<span class="k">except</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">RepoError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Error fetching metadata for </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">repo_name</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="c1"># Enable repos listed on the cmdline</span>
<span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">enablerepos</span><span class="p">:</span>
<span class="n">repolist</span> <span class="o">=</span> <span class="n">dnfbase</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">get_matching</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">repolist</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> is an unknown repo, not enabling it&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">repolist</span><span class="o">.</span><span class="n">enable</span><span class="p">()</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Enabled repo </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="c1"># Disable repos listed on the cmdline</span>
<span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">disablerepos</span><span class="p">:</span>
<span class="n">repolist</span> <span class="o">=</span> <span class="n">dnfbase</span><span class="o">.</span><span class="n">repos</span><span class="o">.</span><span class="n">get_matching</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">repolist</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> is an unknown repo, not disabling it&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">repolist</span><span class="o">.</span><span class="n">disable</span><span class="p">()</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Disabled repo </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">)</span>
<span class="n">dnfbase</span><span class="o">.</span><span class="n">fill_sack</span><span class="p">(</span><span class="n">load_system_repo</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">dnfbase</span><span class="o">.</span><span class="n">read_comps</span><span class="p">()</span>
<span class="k">return</span> <span class="n">dnfbase</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.dnfhelper &mdash; Lorax 28.2 documentation</title>
<title>pylorax.dnfhelper &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -274,9 +266,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -285,11 +275,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -304,35 +294,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.executils &mdash; Lorax 28.2 documentation</title>
<title>pylorax.executils &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -191,6 +183,7 @@
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="n">program_log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;program&quot;</span><span class="p">)</span>
<span class="c1"># pylint: disable=not-context-manager</span>
<span class="kn">from</span> <span class="nn">threading</span> <span class="k">import</span> <span class="n">Lock</span>
<span class="n">program_log_lock</span> <span class="o">=</span> <span class="n">Lock</span><span class="p">()</span>
@ -279,6 +272,7 @@
<span class="k">if</span> <span class="n">env_add</span><span class="p">:</span>
<span class="n">env</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">env_add</span><span class="p">)</span>
<span class="c1"># pylint: disable=subprocess-popen-preexec-fn</span>
<span class="k">return</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="n">argv</span><span class="p">,</span>
<span class="n">stdin</span><span class="o">=</span><span class="n">stdin</span><span class="p">,</span>
<span class="n">stdout</span><span class="o">=</span><span class="n">stdout</span><span class="p">,</span>
@ -512,9 +506,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -523,11 +515,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -542,35 +534,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.imgutils &mdash; Lorax 28.2 documentation</title>
<title>pylorax.imgutils &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -275,20 +267,7 @@
<span class="k">else</span><span class="p">:</span>
<span class="n">fssize</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Let mkext4img figure out the needed size</span>
<span class="n">mkext4img</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">label</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">fssize</span><span class="p">)</span>
<span class="c1"># Reset selinux context on new rootfs</span>
<span class="k">with</span> <span class="n">LoopDev</span><span class="p">(</span><span class="n">outfile</span><span class="p">)</span> <span class="k">as</span> <span class="n">loopdev</span><span class="p">:</span>
<span class="k">with</span> <span class="n">Mount</span><span class="p">(</span><span class="n">loopdev</span><span class="p">)</span> <span class="k">as</span> <span class="n">mnt</span><span class="p">:</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="p">[</span> <span class="s2">&quot;setfiles&quot;</span><span class="p">,</span> <span class="s2">&quot;-e&quot;</span><span class="p">,</span> <span class="s2">&quot;/proc&quot;</span><span class="p">,</span> <span class="s2">&quot;-e&quot;</span><span class="p">,</span> <span class="s2">&quot;/sys&quot;</span><span class="p">,</span> <span class="s2">&quot;-e&quot;</span><span class="p">,</span> <span class="s2">&quot;/dev&quot;</span><span class="p">,</span>
<span class="s2">&quot;-e&quot;</span><span class="p">,</span> <span class="s2">&quot;/install&quot;</span><span class="p">,</span> <span class="s2">&quot;-e&quot;</span><span class="p">,</span> <span class="s2">&quot;/ostree&quot;</span><span class="p">,</span>
<span class="s2">&quot;/etc/selinux/targeted/contexts/files/file_contexts&quot;</span><span class="p">,</span> <span class="s2">&quot;/&quot;</span><span class="p">]</span>
<span class="n">root</span> <span class="o">=</span> <span class="n">join</span><span class="p">(</span><span class="n">mnt</span><span class="p">,</span> <span class="n">sysroot</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">root</span><span class="p">)</span>
<span class="k">except</span> <span class="n">CalledProcessError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;setfiles exited with a non-zero return code (</span><span class="si">%d</span><span class="s2">) which may &quot;</span>
<span class="s2">&quot;be caused by running without SELinux in Permissive mode.&quot;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">returncode</span><span class="p">)</span>
<span class="k">raise</span></div>
<span class="n">mkext4img</span><span class="p">(</span><span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">label</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">fssize</span><span class="p">)</span></div>
<span class="c1">######## Utility functions ###############################################</span>
@ -343,13 +322,31 @@
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Unable to setup </span><span class="si">%s</span><span class="s2"> on </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">loop_dev</span><span class="p">,</span> <span class="n">outfile</span><span class="p">))</span></div>
<div class="viewcode-block" id="loop_attach"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.loop_attach">[docs]</a><span class="k">def</span> <span class="nf">loop_attach</span><span class="p">(</span><span class="n">outfile</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Attach a loop device to the given file. Return the loop device name.</span>
<span class="sd"> Raises CalledProcessError if losetup fails.&#39;&#39;&#39;</span>
<span class="n">dev</span> <span class="o">=</span> <span class="n">runcmd_output</span><span class="p">([</span><span class="s2">&quot;losetup&quot;</span><span class="p">,</span> <span class="s2">&quot;--find&quot;</span><span class="p">,</span> <span class="s2">&quot;--show&quot;</span><span class="p">,</span> <span class="n">outfile</span><span class="p">])</span>
<span class="sd">&quot;&quot;&quot;Attach a loop device to the given file. Return the loop device name.</span>
<span class="c1"># Sometimes the loop device isn&#39;t ready yet, make extra sure before returning</span>
<span class="n">loop_waitfor</span><span class="p">(</span><span class="n">dev</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span> <span class="n">outfile</span><span class="p">)</span>
<span class="k">return</span> <span class="n">dev</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span></div>
<span class="sd"> On rare occasions it appears that the device never shows up, some experiments</span>
<span class="sd"> seem to indicate that it may be a race with another process using /dev/loop* devices.</span>
<span class="sd"> So we now try 3 times before actually failing.</span>
<span class="sd"> Raises CalledProcessError if losetup fails.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">retries</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">retries</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">dev</span> <span class="o">=</span> <span class="n">runcmd_output</span><span class="p">([</span><span class="s2">&quot;losetup&quot;</span><span class="p">,</span> <span class="s2">&quot;--find&quot;</span><span class="p">,</span> <span class="s2">&quot;--show&quot;</span><span class="p">,</span> <span class="n">outfile</span><span class="p">])</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="c1"># Sometimes the loop device isn&#39;t ready yet, make extra sure before returning</span>
<span class="n">loop_waitfor</span><span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="n">outfile</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
<span class="c1"># Try to setup the loop device 3 times</span>
<span class="k">if</span> <span class="n">retries</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;loop_attach failed, retries exhausted.&quot;</span><span class="p">)</span>
<span class="k">raise</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Try </span><span class="si">%d</span><span class="s2"> failed, </span><span class="si">%s</span><span class="s2"> did not appear.&quot;</span><span class="p">,</span> <span class="n">retries</span><span class="p">,</span> <span class="n">dev</span><span class="p">)</span>
<span class="k">break</span>
<span class="k">return</span> <span class="n">dev</span></div>
<div class="viewcode-block" id="loop_detach"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.loop_detach">[docs]</a><span class="k">def</span> <span class="nf">loop_detach</span><span class="p">(</span><span class="n">loopdev</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Detach the given loop device. Return False on failure.&#39;&#39;&#39;</span>
@ -647,12 +644,44 @@
<span class="n">graft</span> <span class="o">=</span> <span class="n">graft</span> <span class="ow">or</span> <span class="p">{}</span>
<span class="n">mkfsimage</span><span class="p">(</span><span class="s2">&quot;hfsplus&quot;</span><span class="p">,</span> <span class="n">rootdir</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">mountargs</span><span class="o">=</span><span class="n">mountargs</span><span class="p">,</span>
<span class="n">mkfsargs</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;-v&quot;</span><span class="p">,</span> <span class="n">label</span><span class="p">],</span> <span class="n">graft</span><span class="o">=</span><span class="n">graft</span><span class="p">)</span></div>
<div class="viewcode-block" id="mkfsimage_from_disk"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.mkfsimage_from_disk">[docs]</a><span class="k">def</span> <span class="nf">mkfsimage_from_disk</span><span class="p">(</span><span class="n">diskimage</span><span class="p">,</span> <span class="n">fsimage</span><span class="p">,</span> <span class="n">img_size</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Anaconda&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Copy the / partition of a partitioned disk image to an un-partitioned</span>
<span class="sd"> disk image.</span>
<span class="sd"> :param str diskimage: The full path to partitioned disk image with a /</span>
<span class="sd"> :param str fsimage: The full path of the output fs image file</span>
<span class="sd"> :param int img_size: Optional size of the fsimage in MiB or None to make</span>
<span class="sd"> it as small as possible</span>
<span class="sd"> :param str label: The label to apply to the image. Defaults to &quot;Anaconda&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">diskimage</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">img_mount</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Creating fsimage </span><span class="si">%s</span><span class="s2"> (</span><span class="si">%s</span><span class="s2">)&quot;</span><span class="p">,</span> <span class="n">fsimage</span><span class="p">,</span> <span class="n">img_size</span> <span class="ow">or</span> <span class="s2">&quot;minimized&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">img_size</span><span class="p">:</span>
<span class="c1"># convert to Bytes</span>
<span class="n">img_size</span> <span class="o">*=</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">2</span>
<span class="n">mkext4img</span><span class="p">(</span><span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">fsimage</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">img_size</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">label</span><span class="p">)</span></div>
<div class="viewcode-block" id="default_image_name"><a class="viewcode-back" href="../../pylorax.html#pylorax.imgutils.default_image_name">[docs]</a><span class="k">def</span> <span class="nf">default_image_name</span><span class="p">(</span><span class="n">compression</span><span class="p">,</span> <span class="n">basename</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Return a default image name with the correct suffix for the compression type.</span>
<span class="sd"> :param str compression: Compression type</span>
<span class="sd"> :param str basename: Base filename</span>
<span class="sd"> :returns: basename with compression suffix</span>
<span class="sd"> If the compression is unknown it defaults to xz</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">SUFFIXES</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;xz&quot;</span><span class="p">:</span> <span class="s2">&quot;.xz&quot;</span><span class="p">,</span> <span class="s2">&quot;gzip&quot;</span><span class="p">:</span> <span class="s2">&quot;.gz&quot;</span><span class="p">,</span> <span class="s2">&quot;bzip2&quot;</span><span class="p">:</span> <span class="s2">&quot;.bz2&quot;</span><span class="p">,</span> <span class="s2">&quot;lzma&quot;</span><span class="p">:</span> <span class="s2">&quot;.lzma&quot;</span><span class="p">}</span>
<span class="k">return</span> <span class="n">basename</span> <span class="o">+</span> <span class="n">SUFFIXES</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">compression</span><span class="p">,</span> <span class="s2">&quot;.xz&quot;</span><span class="p">)</span></div>
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -661,11 +690,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -680,35 +709,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -0,0 +1,830 @@
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.installer &mdash; Lorax 28.21 documentation</title>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search">
<a href="../../index.html" class="icon icon-home"> Lorax
</a>
<div class="version">
28.21
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../intro.html">Introduction to Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../index.html">Docs</a> &raquo;</li>
<li><a href="../index.html">Module code</a> &raquo;</li>
<li><a href="../pylorax.html">pylorax</a> &raquo;</li>
<li>pylorax.installer</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<h1>Source code for pylorax.installer</h1><div class="highlight"><pre>
<span></span><span class="c1">#</span>
<span class="c1"># Copyright (C) 2011-2018 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
<span class="c1"># the Free Software Foundation; either version 2 of the License, or</span>
<span class="c1"># (at your option) any later version.</span>
<span class="c1">#</span>
<span class="c1"># This program is distributed in the hope that it will be useful,</span>
<span class="c1"># but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="c1"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span class="c1"># GNU General Public License for more details.</span>
<span class="c1">#</span>
<span class="c1"># You should have received a copy of the GNU General Public License</span>
<span class="c1"># along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<span class="c1">#</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;pylorax&quot;</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">glob</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">math</span> <span class="k">import</span> <span class="n">ceil</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">import</span> <span class="nn">socket</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="c1"># Use the Lorax treebuilder branch for iso creation</span>
<span class="kn">from</span> <span class="nn">pylorax.executils</span> <span class="k">import</span> <span class="n">execWithRedirect</span><span class="p">,</span> <span class="n">execReadlines</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="k">import</span> <span class="n">PartitionMount</span><span class="p">,</span> <span class="n">mksparse</span><span class="p">,</span> <span class="n">mkext4img</span><span class="p">,</span> <span class="n">loop_detach</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="k">import</span> <span class="n">get_loop_name</span><span class="p">,</span> <span class="n">dm_detach</span><span class="p">,</span> <span class="n">mount</span><span class="p">,</span> <span class="n">umount</span>
<span class="kn">from</span> <span class="nn">pylorax.imgutils</span> <span class="k">import</span> <span class="n">mkqemu_img</span><span class="p">,</span> <span class="n">mktar</span><span class="p">,</span> <span class="n">mkcpio</span><span class="p">,</span> <span class="n">mkfsimage_from_disk</span>
<span class="kn">from</span> <span class="nn">pylorax.monitor</span> <span class="k">import</span> <span class="n">LogMonitor</span>
<span class="kn">from</span> <span class="nn">pylorax.mount</span> <span class="k">import</span> <span class="n">IsoMountpoint</span>
<span class="kn">from</span> <span class="nn">pylorax.sysutils</span> <span class="k">import</span> <span class="n">joinpaths</span>
<span class="kn">from</span> <span class="nn">pylorax.treebuilder</span> <span class="k">import</span> <span class="n">udev_escape</span>
<span class="n">ROOT_PATH</span> <span class="o">=</span> <span class="s2">&quot;/mnt/sysimage/&quot;</span>
<div class="viewcode-block" id="InstallError"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.InstallError">[docs]</a><span class="k">class</span> <span class="nc">InstallError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="create_vagrant_metadata"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.create_vagrant_metadata">[docs]</a><span class="k">def</span> <span class="nf">create_vagrant_metadata</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Create a default Vagrant metadata.json file</span>
<span class="sd"> :param str path: Path to metadata.json file</span>
<span class="sd"> :param int size: Disk size in MiB</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">metadata</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;provider&quot;</span><span class="p">:</span><span class="s2">&quot;libvirt&quot;</span><span class="p">,</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span><span class="s2">&quot;qcow2&quot;</span><span class="p">,</span> <span class="s2">&quot;virtual_size&quot;</span><span class="p">:</span> <span class="n">ceil</span><span class="p">(</span><span class="n">size</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">)</span> <span class="p">}</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s2">&quot;wt&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">json</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span></div>
<div class="viewcode-block" id="update_vagrant_metadata"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.update_vagrant_metadata">[docs]</a><span class="k">def</span> <span class="nf">update_vagrant_metadata</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">size</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Update the Vagrant metadata.json file</span>
<span class="sd"> :param str path: Path to metadata.json file</span>
<span class="sd"> :param int size: Disk size in MiB</span>
<span class="sd"> This function makes sure that the provider, format and virtual size of the</span>
<span class="sd"> metadata file are set correctly. All other values are left untouched.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s2">&quot;rt&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">metadata</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Problem reading metadata file </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">metadata</span><span class="p">[</span><span class="s2">&quot;provider&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;libvirt&quot;</span>
<span class="n">metadata</span><span class="p">[</span><span class="s2">&quot;format&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;qcow2&quot;</span>
<span class="n">metadata</span><span class="p">[</span><span class="s2">&quot;virtual_size&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ceil</span><span class="p">(</span><span class="n">size</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s2">&quot;wt&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">json</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">metadata</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span></div>
<div class="viewcode-block" id="find_free_port"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.find_free_port">[docs]</a><span class="k">def</span> <span class="nf">find_free_port</span><span class="p">(</span><span class="n">start</span><span class="o">=</span><span class="mi">5900</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="mi">5999</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="s2">&quot;127.0.0.1&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Return first free port in range.</span>
<span class="sd"> :param int start: Starting port number</span>
<span class="sd"> :param int end: Ending port number</span>
<span class="sd"> :param str host: Host IP to search</span>
<span class="sd"> :returns: First free port or -1 if none found</span>
<span class="sd"> :rtype: int</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
<span class="k">for</span> <span class="n">port</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">s</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">))</span>
<span class="n">s</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">return</span> <span class="n">port</span>
<span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span></div>
<div class="viewcode-block" id="append_initrd"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.append_initrd">[docs]</a><span class="k">def</span> <span class="nf">append_initrd</span><span class="p">(</span><span class="n">initrd</span><span class="p">,</span> <span class="n">files</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot; Append files to an initrd.</span>
<span class="sd"> :param str initrd: Path to initrd</span>
<span class="sd"> :param list files: list of file paths to add</span>
<span class="sd"> :returns: Path to a new initrd</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> The files are added to the initrd by creating a cpio image</span>
<span class="sd"> of the files (stored at /) and writing the cpio to the end of a</span>
<span class="sd"> copy of the initrd.</span>
<span class="sd"> The initrd is not changed, a copy is made before appending the</span>
<span class="sd"> cpio archive.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">qemu_initrd</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-initrd-&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s2">&quot;.img&quot;</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">initrd</span><span class="p">,</span> <span class="n">qemu_initrd</span><span class="p">)</span>
<span class="n">ks_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-ksdir-&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">ks</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">ks</span><span class="p">,</span> <span class="n">ks_dir</span><span class="p">)</span>
<span class="n">ks_initrd</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-ks-&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s2">&quot;.img&quot;</span><span class="p">)</span>
<span class="n">mkcpio</span><span class="p">(</span><span class="n">ks_dir</span><span class="p">,</span> <span class="n">ks_initrd</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">ks_dir</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">qemu_initrd</span><span class="p">,</span> <span class="s2">&quot;ab&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">initrd_fp</span><span class="p">:</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">ks_initrd</span><span class="p">,</span> <span class="s2">&quot;rb&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">ks_fp</span><span class="p">:</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">ks_fp</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1024</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">initrd_fp</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">ks_initrd</span><span class="p">)</span>
<span class="k">return</span> <span class="n">qemu_initrd</span></div>
<div class="viewcode-block" id="QEMUInstall"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.QEMUInstall">[docs]</a><span class="k">class</span> <span class="nc">QEMUInstall</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Run qemu using an iso and a kickstart</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Mapping of arch to qemu command</span>
<span class="n">QEMU_CMDS</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;x86_64&quot;</span><span class="p">:</span> <span class="s2">&quot;qemu-system-x86_64&quot;</span><span class="p">,</span>
<span class="s2">&quot;i386&quot;</span><span class="p">:</span> <span class="s2">&quot;qemu-system-i386&quot;</span><span class="p">,</span>
<span class="s2">&quot;arm&quot;</span><span class="p">:</span> <span class="s2">&quot;qemu-system-arm&quot;</span><span class="p">,</span>
<span class="s2">&quot;aarch64&quot;</span><span class="p">:</span> <span class="s2">&quot;qemu-system-aarch64&quot;</span><span class="p">,</span>
<span class="s2">&quot;ppc&quot;</span><span class="p">:</span> <span class="s2">&quot;qemu-system-ppc&quot;</span><span class="p">,</span>
<span class="s2">&quot;ppc64&quot;</span><span class="p">:</span> <span class="s2">&quot;qemu-system-ppc64&quot;</span>
<span class="p">}</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">opts</span><span class="p">,</span> <span class="n">iso</span><span class="p">,</span> <span class="n">ks_paths</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">img_size</span><span class="o">=</span><span class="mi">2048</span><span class="p">,</span>
<span class="n">kernel_args</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">memory</span><span class="o">=</span><span class="mi">1024</span><span class="p">,</span> <span class="n">vcpus</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">vnc</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">log_check</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">virtio_host</span><span class="o">=</span><span class="s2">&quot;127.0.0.1&quot;</span><span class="p">,</span> <span class="n">virtio_port</span><span class="o">=</span><span class="mi">6080</span><span class="p">,</span>
<span class="n">image_type</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">boot_uefi</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">ovmf_path</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Start the installation</span>
<span class="sd"> :param iso: Information about the iso to use for the installation</span>
<span class="sd"> :type iso: IsoMountpoint</span>
<span class="sd"> :param list ks_paths: Paths to kickstart files. All are injected, the</span>
<span class="sd"> first one is the one executed.</span>
<span class="sd"> :param str disk_img: Path to a disk image, created it it doesn&#39;t exist</span>
<span class="sd"> :param int img_size: The image size, in MiB, to create if it doesn&#39;t exist</span>
<span class="sd"> :param str kernel_args: Extra kernel arguments to pass on the kernel cmdline</span>
<span class="sd"> :param int memory: Amount of RAM to assign to the virt, in MiB</span>
<span class="sd"> :param int vcpus: Number of virtual cpus</span>
<span class="sd"> :param str vnc: Arguments to pass to qemu -display</span>
<span class="sd"> :param str arch: Optional architecture to use in the virt</span>
<span class="sd"> :param log_check: Method that returns True if the installation fails</span>
<span class="sd"> :type log_check: method</span>
<span class="sd"> :param str virtio_host: Hostname to connect virtio log to</span>
<span class="sd"> :param int virtio_port: Port to connect virtio log to</span>
<span class="sd"> :param str image_type: Type of qemu-img disk to create, or None.</span>
<span class="sd"> :param bool boot_uefi: Use OVMF to boot the VM in UEFI mode</span>
<span class="sd"> :param str ovmf_path: Path to the OVMF firmware</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Lookup qemu-system- for arch if passed, or try to guess using host arch</span>
<span class="n">qemu_cmd</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">QEMU_CMDS</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">arch</span> <span class="ow">or</span> <span class="n">os</span><span class="o">.</span><span class="n">uname</span><span class="p">()</span><span class="o">.</span><span class="n">machine</span><span class="p">,</span> <span class="s2">&quot;qemu-system-&quot;</span><span class="o">+</span><span class="n">os</span><span class="o">.</span><span class="n">uname</span><span class="p">()</span><span class="o">.</span><span class="n">machine</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="s2">&quot;/usr/bin/&quot;</span><span class="o">+</span><span class="n">qemu_cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> does not exist, cannot run qemu&quot;</span> <span class="o">%</span> <span class="n">qemu_cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-nodefconfig&quot;</span><span class="p">]</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-m&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">memory</span><span class="p">)]</span>
<span class="k">if</span> <span class="n">vcpus</span><span class="p">:</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-smp&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">vcpus</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">no_kvm</span> <span class="ow">and</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="s2">&quot;/dev/kvm&quot;</span><span class="p">):</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;--machine&quot;</span><span class="p">,</span> <span class="s2">&quot;accel=kvm&quot;</span><span class="p">]</span>
<span class="c1"># Copy the initrd from the iso, create a cpio archive of the kickstart files</span>
<span class="c1"># and append it to the temporary initrd.</span>
<span class="n">qemu_initrd</span> <span class="o">=</span> <span class="n">append_initrd</span><span class="p">(</span><span class="n">iso</span><span class="o">.</span><span class="n">initrd</span><span class="p">,</span> <span class="n">ks_paths</span><span class="p">)</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-kernel&quot;</span><span class="p">,</span> <span class="n">iso</span><span class="o">.</span><span class="n">kernel</span><span class="p">]</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-initrd&quot;</span><span class="p">,</span> <span class="n">qemu_initrd</span><span class="p">]</span>
<span class="c1"># Add the disk and cdrom</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">disk_img</span><span class="p">):</span>
<span class="n">mksparse</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">img_size</span> <span class="o">*</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="n">drive_args</span> <span class="o">=</span> <span class="s2">&quot;file=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">disk_img</span>
<span class="n">drive_args</span> <span class="o">+=</span> <span class="s2">&quot;,cache=unsafe,discard=unmap&quot;</span>
<span class="k">if</span> <span class="n">image_type</span><span class="p">:</span>
<span class="n">drive_args</span> <span class="o">+=</span> <span class="s2">&quot;,format=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">image_type</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">drive_args</span> <span class="o">+=</span> <span class="s2">&quot;,format=raw&quot;</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-drive&quot;</span><span class="p">,</span> <span class="n">drive_args</span><span class="p">]</span>
<span class="n">drive_args</span> <span class="o">=</span> <span class="s2">&quot;file=</span><span class="si">%s</span><span class="s2">,media=cdrom,readonly=on&quot;</span> <span class="o">%</span> <span class="n">iso</span><span class="o">.</span><span class="n">iso_path</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-drive&quot;</span><span class="p">,</span> <span class="n">drive_args</span><span class="p">]</span>
<span class="c1"># Setup the cmdline args</span>
<span class="c1"># ======================</span>
<span class="n">cmdline_args</span> <span class="o">=</span> <span class="s2">&quot;ks=file:/</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">ks_paths</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">cmdline_args</span> <span class="o">+=</span> <span class="s2">&quot; inst.stage2=hd:LABEL=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">udev_escape</span><span class="p">(</span><span class="n">iso</span><span class="o">.</span><span class="n">label</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">cmdline_args</span> <span class="o">+=</span> <span class="s2">&quot; inst.proxy=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">opts</span><span class="o">.</span><span class="n">proxy</span>
<span class="k">if</span> <span class="n">kernel_args</span><span class="p">:</span>
<span class="n">cmdline_args</span> <span class="o">+=</span> <span class="s2">&quot; &quot;</span><span class="o">+</span><span class="n">kernel_args</span>
<span class="n">cmdline_args</span> <span class="o">+=</span> <span class="s2">&quot; inst.text inst.cmdline&quot;</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-append&quot;</span><span class="p">,</span> <span class="n">cmdline_args</span><span class="p">]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">vnc</span><span class="p">:</span>
<span class="n">vnc_port</span> <span class="o">=</span> <span class="n">find_free_port</span><span class="p">()</span>
<span class="k">if</span> <span class="n">vnc_port</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;No free VNC ports&quot;</span><span class="p">)</span>
<span class="n">display_args</span> <span class="o">=</span> <span class="s2">&quot;vnc=127.0.0.1:</span><span class="si">%d</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">vnc_port</span> <span class="o">-</span> <span class="mi">5900</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">display_args</span> <span class="o">=</span> <span class="n">opts</span><span class="o">.</span><span class="n">vnc</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;qemu </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">display_args</span><span class="p">)</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-nographic&quot;</span><span class="p">,</span> <span class="s2">&quot;-display&quot;</span><span class="p">,</span> <span class="n">display_args</span> <span class="p">]</span>
<span class="c1"># Setup the virtio log port</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-device&quot;</span><span class="p">,</span> <span class="s2">&quot;virtio-serial-pci,id=virtio-serial0&quot;</span><span class="p">]</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-device&quot;</span><span class="p">,</span> <span class="s2">&quot;virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0&quot;</span>
<span class="s2">&quot;,id=channel0,name=org.fedoraproject.anaconda.log.0&quot;</span><span class="p">]</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-chardev&quot;</span><span class="p">,</span> <span class="s2">&quot;socket,id=charchannel0,host=</span><span class="si">%s</span><span class="s2">,port=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">virtio_host</span><span class="p">,</span> <span class="n">virtio_port</span><span class="p">)]</span>
<span class="c1"># PAss through rng from host</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">with_rng</span> <span class="o">!=</span> <span class="s2">&quot;none&quot;</span><span class="p">:</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-object&quot;</span><span class="p">,</span> <span class="s2">&quot;rng-random,id=virtio-rng0,filename=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">opts</span><span class="o">.</span><span class="n">with_rng</span><span class="p">]</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-device&quot;</span><span class="p">,</span> <span class="s2">&quot;virtio-rng-pci,rng=virtio-rng0,id=rng0,bus=pci.0,addr=0x9&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">boot_uefi</span> <span class="ow">and</span> <span class="n">ovmf_path</span><span class="p">:</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-drive&quot;</span><span class="p">,</span> <span class="s2">&quot;file=</span><span class="si">%s</span><span class="s2">/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on&quot;</span> <span class="o">%</span> <span class="n">ovmf_path</span><span class="p">]</span>
<span class="c1"># Make a copy of the OVMF_VARS.fd for this run</span>
<span class="n">ovmf_vars</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-OVMF_VARS-&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s2">&quot;.fd&quot;</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">joinpaths</span><span class="p">(</span><span class="n">ovmf_path</span><span class="p">,</span> <span class="s2">&quot;/OVMF_VARS.fd&quot;</span><span class="p">),</span> <span class="n">ovmf_vars</span><span class="p">)</span>
<span class="n">qemu_cmd</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-drive&quot;</span><span class="p">,</span> <span class="s2">&quot;file=</span><span class="si">%s</span><span class="s2">,if=pflash,format=raw,unit=1&quot;</span> <span class="o">%</span> <span class="n">ovmf_vars</span><span class="p">]</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Running qemu&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">qemu_cmd</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="n">qemu_cmd</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">qemu_cmd</span><span class="p">[</span><span class="mi">1</span><span class="p">:],</span> <span class="n">reset_lang</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">raise_err</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">callback</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="ow">not</span> <span class="n">log_check</span><span class="p">())</span>
<span class="k">except</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Running qemu failed:&quot;</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;cmd: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">cmd</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;output: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">output</span> <span class="ow">or</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;QEMUInstall failed&quot;</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">OSError</span><span class="p">,</span> <span class="ne">KeyboardInterrupt</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Running qemu failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;QEMUInstall failed&quot;</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">qemu_initrd</span><span class="p">)</span>
<span class="k">if</span> <span class="n">boot_uefi</span> <span class="ow">and</span> <span class="n">ovmf_path</span><span class="p">:</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">ovmf_vars</span><span class="p">)</span>
<span class="k">if</span> <span class="n">log_check</span><span class="p">():</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Installation error detected. See logfile for details.&quot;</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;QEMUInstall failed&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Installation finished without errors.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="novirt_log_check"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.novirt_log_check">[docs]</a><span class="k">def</span> <span class="nf">novirt_log_check</span><span class="p">(</span><span class="n">log_check</span><span class="p">,</span> <span class="n">proc</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check to see if there has been an error in the logs</span>
<span class="sd"> :param log_check: method to call to check for an error in the logs</span>
<span class="sd"> :param proc: Popen object for the anaconda process</span>
<span class="sd"> :returns: True if the process has been terminated</span>
<span class="sd"> The log_check method should return a True if an error has been detected.</span>
<span class="sd"> When an error is detected the process is terminated and this returns True</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">log_check</span><span class="p">():</span>
<span class="n">proc</span><span class="o">.</span><span class="n">terminate</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="anaconda_cleanup"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.anaconda_cleanup">[docs]</a><span class="k">def</span> <span class="nf">anaconda_cleanup</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Cleanup any leftover mounts from anaconda</span>
<span class="sd"> :param str dirinstall_path: Path where anaconda mounts things</span>
<span class="sd"> :returns: True if cleanups were successful. False if any of them failed.</span>
<span class="sd"> If anaconda crashes it may leave things mounted under this path. It will</span>
<span class="sd"> typically be set to /mnt/sysimage/</span>
<span class="sd"> Attempts to cleanup may also fail. Catch these and continue trying the</span>
<span class="sd"> other mountpoints.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">rc</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">dirinstall_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">)</span>
<span class="c1"># unmount filesystems</span>
<span class="k">for</span> <span class="n">mounted</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">&quot;/proc/mounts&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">readlines</span><span class="p">()):</span>
<span class="p">(</span><span class="n">_device</span><span class="p">,</span> <span class="n">mountpoint</span><span class="p">,</span> <span class="n">_rest</span><span class="p">)</span> <span class="o">=</span> <span class="n">mounted</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="k">if</span> <span class="n">mountpoint</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">)</span> <span class="ow">and</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">ismount</span><span class="p">(</span><span class="n">mountpoint</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">umount</span><span class="p">(</span><span class="n">mountpoint</span><span class="p">)</span>
<span class="k">except</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Cleanup of </span><span class="si">%s</span><span class="s2"> failed. See program.log for details&quot;</span><span class="p">,</span> <span class="n">mountpoint</span><span class="p">)</span>
<span class="n">rc</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">return</span> <span class="n">rc</span></div>
<div class="viewcode-block" id="novirt_install"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.novirt_install">[docs]</a><span class="k">def</span> <span class="nf">novirt_install</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Use Anaconda to install to a disk image</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str disk_img: The full path to the disk image to be created</span>
<span class="sd"> :param int disk_size: The size of the disk_img in MiB</span>
<span class="sd"> This method runs anaconda to create the image and then based on the opts</span>
<span class="sd"> passed creates a qemu disk image or tarfile.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">dirinstall_path</span> <span class="o">=</span> <span class="n">ROOT_PATH</span>
<span class="c1"># Clean up /tmp/ from previous runs to prevent stale info from being used</span>
<span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;/tmp/yum.repos.d/&quot;</span><span class="p">,</span> <span class="s2">&quot;/tmp/yum.cache/&quot;</span><span class="p">]:</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;--kickstart&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s2">&quot;--cmdline&quot;</span><span class="p">,</span> <span class="s2">&quot;--loglevel&quot;</span><span class="p">,</span> <span class="s2">&quot;debug&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">anaconda_args</span><span class="p">:</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">anaconda_args</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;--proxy&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">proxy</span><span class="p">]</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">armplatform</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;--armplatform&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">armplatform</span><span class="p">]</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_iso</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_pxe_live</span><span class="p">:</span>
<span class="c1"># Make a blank fs image</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;--dirinstall&quot;</span><span class="p">]</span>
<span class="n">mkext4img</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">fs_label</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="n">disk_size</span> <span class="o">*</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">)</span>
<span class="n">mount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">=</span><span class="s2">&quot;loop&quot;</span><span class="p">,</span> <span class="n">mnt</span><span class="o">=</span><span class="n">dirinstall_path</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_tar</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_oci</span><span class="p">:</span>
<span class="c1"># Install under dirinstall_path, make sure it starts clean</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">):</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_oci</span><span class="p">:</span>
<span class="c1"># OCI installs under /rootfs/</span>
<span class="n">dirinstall_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">,</span> <span class="s2">&quot;rootfs&quot;</span><span class="p">)</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;--dirinstall&quot;</span><span class="p">,</span> <span class="n">dirinstall_path</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;--dirinstall&quot;</span><span class="p">]</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;--image&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">]</span>
<span class="c1"># Create the sparse image</span>
<span class="n">mksparse</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span> <span class="o">*</span> <span class="mi">1024</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
<span class="n">log_monitor</span> <span class="o">=</span> <span class="n">LogMonitor</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
<span class="n">args</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;--remotelog&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">log_monitor</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">port</span><span class="p">)]</span>
<span class="c1"># Make sure anaconda has the right product and release</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Running anaconda.&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">execReadlines</span><span class="p">(</span><span class="s2">&quot;anaconda&quot;</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">reset_lang</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">env_add</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;ANACONDA_PRODUCTNAME&quot;</span><span class="p">:</span> <span class="n">opts</span><span class="o">.</span><span class="n">project</span><span class="p">,</span>
<span class="s2">&quot;ANACONDA_PRODUCTVERSION&quot;</span><span class="p">:</span> <span class="n">opts</span><span class="o">.</span><span class="n">releasever</span><span class="p">},</span>
<span class="n">callback</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="ow">not</span> <span class="n">novirt_log_check</span><span class="p">(</span><span class="n">log_monitor</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_check</span><span class="p">,</span> <span class="n">p</span><span class="p">)):</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="c1"># Make sure the new filesystem is correctly labeled</span>
<span class="n">setfiles_args</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;-e&quot;</span><span class="p">,</span> <span class="s2">&quot;/proc&quot;</span><span class="p">,</span> <span class="s2">&quot;-e&quot;</span><span class="p">,</span> <span class="s2">&quot;/sys&quot;</span><span class="p">,</span> <span class="s2">&quot;-e&quot;</span><span class="p">,</span> <span class="s2">&quot;/dev&quot;</span><span class="p">,</span>
<span class="s2">&quot;/etc/selinux/targeted/contexts/files/file_contexts&quot;</span><span class="p">,</span> <span class="s2">&quot;/&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="s2">&quot;--dirinstall&quot;</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
<span class="c1"># setfiles may not be available, warn instead of fail</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;setfiles&quot;</span><span class="p">,</span> <span class="n">setfiles_args</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">dirinstall_path</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span><span class="p">,</span> <span class="ne">OSError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;Running setfiles on install tree failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">disk_img</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="n">img_mount</span> <span class="ow">and</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;setfiles&quot;</span><span class="p">,</span> <span class="n">setfiles_args</span><span class="p">,</span> <span class="n">root</span><span class="o">=</span><span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span><span class="p">,</span> <span class="ne">OSError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;Running setfiles on install tree failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="c1"># For image installs, run fstrim to discard unused blocks. This way</span>
<span class="c1"># unused blocks do not need to be allocated for sparse image types</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;fstrim&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">])</span>
<span class="k">except</span> <span class="p">(</span><span class="n">subprocess</span><span class="o">.</span><span class="n">CalledProcessError</span><span class="p">,</span> <span class="ne">OSError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;Running anaconda failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;novirt_install failed&quot;</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">log_monitor</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
<span class="c1"># Move the anaconda logs over to a log directory</span>
<span class="n">log_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">logfile</span><span class="p">))</span>
<span class="n">log_anaconda</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">log_dir</span><span class="p">,</span> <span class="s2">&quot;anaconda&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">log_anaconda</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">log_anaconda</span><span class="p">)</span>
<span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s2">&quot;/tmp/*log&quot;</span><span class="p">)</span><span class="o">+</span><span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s2">&quot;/tmp/anaconda-tb-*&quot;</span><span class="p">):</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">l</span><span class="p">,</span> <span class="n">log_anaconda</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">l</span><span class="p">)</span>
<span class="c1"># Make sure any leftover anaconda mounts have been cleaned up</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">anaconda_cleanup</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;novirt_install cleanup of anaconda mounts failed.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_iso</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_pxe_live</span><span class="p">:</span>
<span class="n">dm_name</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">disk_img</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">dm_path</span> <span class="o">=</span> <span class="s2">&quot;/dev/mapper/&quot;</span><span class="o">+</span><span class="n">dm_name</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">dm_path</span><span class="p">):</span>
<span class="n">dm_detach</span><span class="p">(</span><span class="n">dm_path</span><span class="p">)</span>
<span class="n">loop_detach</span><span class="p">(</span><span class="n">get_loop_name</span><span class="p">(</span><span class="n">disk_img</span><span class="p">))</span>
<span class="c1"># qemu disk image is used by bare qcow2 images and by Vagrant</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_type</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Converting </span><span class="si">%s</span><span class="s2"> to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_type</span><span class="p">)</span>
<span class="n">qemu_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">qemu_args</span><span class="p">:</span>
<span class="n">qemu_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1"># convert the image to the selected format</span>
<span class="k">if</span> <span class="s2">&quot;-O&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">qemu_args</span><span class="p">:</span>
<span class="n">qemu_args</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="s2">&quot;-O&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_type</span><span class="p">])</span>
<span class="n">qemu_img</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-disk-&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s2">&quot;.img&quot;</span><span class="p">)</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;qemu-img&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;convert&quot;</span><span class="p">]</span> <span class="o">+</span> <span class="n">qemu_args</span> <span class="o">+</span> <span class="p">[</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">qemu_img</span><span class="p">],</span> <span class="n">raise_err</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_vagrant</span><span class="p">:</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;mv&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;-f&quot;</span><span class="p">,</span> <span class="n">qemu_img</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">],</span> <span class="n">raise_err</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Take the new qcow2 image and package it up for Vagrant</span>
<span class="n">compress_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">vagrant_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-tmpdir-&quot;</span><span class="p">)</span>
<span class="n">metadata_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">,</span> <span class="s2">&quot;metadata.json&quot;</span><span class="p">)</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;mv&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;-f&quot;</span><span class="p">,</span> <span class="n">qemu_img</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">,</span> <span class="s2">&quot;box.img&quot;</span><span class="p">)],</span> <span class="n">raise_err</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">vagrant_metadata</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">vagrant_metadata</span><span class="p">,</span> <span class="n">metadata_path</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">create_vagrant_metadata</span><span class="p">(</span><span class="n">metadata_path</span><span class="p">)</span>
<span class="n">update_vagrant_metadata</span><span class="p">(</span><span class="n">metadata_path</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">vagrantfile</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">vagrantfile</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">,</span> <span class="s2">&quot;vagrantfile&quot;</span><span class="p">))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Creating Vagrant image&quot;</span><span class="p">)</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">mktar</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span> <span class="n">compress_args</span><span class="p">,</span> <span class="n">selinux</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;novirt_install mktar failed: rc=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">rc</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_tar</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">mktar</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span> <span class="n">compress_args</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">dirinstall_path</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;novirt_install mktar failed: rc=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">rc</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_oci</span><span class="p">:</span>
<span class="c1"># An OCI image places the filesystem under /rootfs/ and adds the json files at the top</span>
<span class="c1"># And then creates a tar of the whole thing.</span>
<span class="n">compress_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">oci_config</span><span class="p">,</span> <span class="n">ROOT_PATH</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">oci_runtime</span><span class="p">,</span> <span class="n">ROOT_PATH</span><span class="p">)</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">mktar</span><span class="p">(</span><span class="n">ROOT_PATH</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span> <span class="n">compress_args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;novirt_install mktar failed: rc=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">rc</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># For raw disk images, use fallocate to deallocate unused space</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;fallocate&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;--dig-holes&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">],</span> <span class="n">raise_err</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
<div class="viewcode-block" id="virt_install"><a class="viewcode-back" href="../../pylorax.html#pylorax.installer.virt_install">[docs]</a><span class="k">def</span> <span class="nf">virt_install</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">install_log</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Use qemu to install to a disk image</span>
<span class="sd"> :param opts: options passed to livemedia-creator</span>
<span class="sd"> :type opts: argparse options</span>
<span class="sd"> :param str install_log: The path to write the log from qemu</span>
<span class="sd"> :param str disk_img: The full path to the disk image to be created</span>
<span class="sd"> :param int disk_size: The size of the disk_img in MiB</span>
<span class="sd"> This uses qemu with a boot.iso and a kickstart to create a disk</span>
<span class="sd"> image and then optionally, based on the opts passed, creates tarfile.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">iso_mount</span> <span class="o">=</span> <span class="n">IsoMountpoint</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">iso</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">location</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">iso_mount</span><span class="o">.</span><span class="n">stage2</span><span class="p">:</span>
<span class="n">iso_mount</span><span class="o">.</span><span class="n">umount</span><span class="p">()</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;ISO is missing stage2, cannot continue&quot;</span><span class="p">)</span>
<span class="n">log_monitor</span> <span class="o">=</span> <span class="n">LogMonitor</span><span class="p">(</span><span class="n">install_log</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">timeout</span><span class="p">)</span>
<span class="n">kernel_args</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">kernel_args</span><span class="p">:</span>
<span class="n">kernel_args</span> <span class="o">+=</span> <span class="n">opts</span><span class="o">.</span><span class="n">kernel_args</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">proxy</span><span class="p">:</span>
<span class="n">kernel_args</span> <span class="o">+=</span> <span class="s2">&quot; proxy=&quot;</span><span class="o">+</span><span class="n">opts</span><span class="o">.</span><span class="n">proxy</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_type</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span><span class="p">:</span>
<span class="n">qemu_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">qemu_args</span><span class="p">:</span>
<span class="n">qemu_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;-f&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">qemu_args</span><span class="p">:</span>
<span class="n">qemu_args</span> <span class="o">+=</span> <span class="p">[</span><span class="s2">&quot;-f&quot;</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">image_type</span><span class="p">]</span>
<span class="n">mkqemu_img</span><span class="p">(</span><span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="o">*</span><span class="mi">1024</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span> <span class="n">qemu_args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_tar</span> <span class="ow">or</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_oci</span><span class="p">:</span>
<span class="n">diskimg_path</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mktemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-disk-&quot;</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="s2">&quot;.img&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">diskimg_path</span> <span class="o">=</span> <span class="n">disk_img</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">QEMUInstall</span><span class="p">(</span><span class="n">opts</span><span class="p">,</span> <span class="n">iso_mount</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">ks</span><span class="p">,</span> <span class="n">diskimg_path</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">,</span>
<span class="n">kernel_args</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">ram</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">vcpus</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">vnc</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">arch</span><span class="p">,</span>
<span class="n">log_check</span> <span class="o">=</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_check</span><span class="p">,</span>
<span class="n">virtio_host</span> <span class="o">=</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">host</span><span class="p">,</span>
<span class="n">virtio_port</span> <span class="o">=</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">port</span><span class="p">,</span>
<span class="n">image_type</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">image_type</span><span class="p">,</span> <span class="n">boot_uefi</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">virt_uefi</span><span class="p">,</span>
<span class="n">ovmf_path</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">ovmf_path</span><span class="p">)</span>
<span class="n">log_monitor</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
<span class="k">except</span> <span class="n">InstallError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;VirtualInstall failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
<span class="k">raise</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;unmounting the iso&quot;</span><span class="p">)</span>
<span class="n">iso_mount</span><span class="o">.</span><span class="n">umount</span><span class="p">()</span>
<span class="k">if</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_check</span><span class="p">():</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">error_line</span> <span class="ow">and</span> <span class="n">opts</span><span class="o">.</span><span class="n">timeout</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;virt_install failed due to timeout&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;virt_install failed on line: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">log_monitor</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">error_line</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_fsimage</span><span class="p">:</span>
<span class="n">mkfsimage_from_disk</span><span class="p">(</span><span class="n">diskimg_path</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">opts</span><span class="o">.</span><span class="n">fs_label</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">diskimg_path</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_tar</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">diskimg_path</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="n">img_mount</span> <span class="ow">and</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">:</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">mktar</span><span class="p">(</span><span class="n">img_mount</span><span class="o">.</span><span class="n">mount_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span> <span class="n">compress_args</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">rc</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">diskimg_path</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;virt_install failed&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_oci</span><span class="p">:</span>
<span class="c1"># An OCI image places the filesystem under /rootfs/ and adds the json files at the top</span>
<span class="c1"># And then creates a tar of the whole thing.</span>
<span class="n">compress_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">with</span> <span class="n">PartitionMount</span><span class="p">(</span><span class="n">diskimg_path</span><span class="p">,</span> <span class="n">submount</span><span class="o">=</span><span class="s2">&quot;rootfs&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">img_mount</span><span class="p">:</span>
<span class="k">if</span> <span class="n">img_mount</span> <span class="ow">and</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">temp_dir</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">oci_config</span><span class="p">,</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">temp_dir</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">oci_runtime</span><span class="p">,</span> <span class="n">img_mount</span><span class="o">.</span><span class="n">temp_dir</span><span class="p">)</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">mktar</span><span class="p">(</span><span class="n">img_mount</span><span class="o">.</span><span class="n">temp_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span> <span class="n">compress_args</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">rc</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">diskimg_path</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;virt_install failed&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">opts</span><span class="o">.</span><span class="n">make_vagrant</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">opts</span><span class="o">.</span><span class="n">compress_args</span><span class="p">:</span>
<span class="n">compress_args</span> <span class="o">+=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">vagrant_dir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;lmc-tmpdir-&quot;</span><span class="p">)</span>
<span class="n">metadata_path</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">,</span> <span class="s2">&quot;metadata.json&quot;</span><span class="p">)</span>
<span class="n">execWithRedirect</span><span class="p">(</span><span class="s2">&quot;mv&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;-f&quot;</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">,</span> <span class="s2">&quot;box.img&quot;</span><span class="p">)],</span> <span class="n">raise_err</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">vagrant_metadata</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">vagrant_metadata</span><span class="p">,</span> <span class="n">metadata_path</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">create_vagrant_metadata</span><span class="p">(</span><span class="n">metadata_path</span><span class="p">)</span>
<span class="n">update_vagrant_metadata</span><span class="p">(</span><span class="n">metadata_path</span><span class="p">,</span> <span class="n">disk_size</span><span class="p">)</span>
<span class="k">if</span> <span class="n">opts</span><span class="o">.</span><span class="n">vagrantfile</span><span class="p">:</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy2</span><span class="p">(</span><span class="n">opts</span><span class="o">.</span><span class="n">vagrantfile</span><span class="p">,</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">,</span> <span class="s2">&quot;vagrantfile&quot;</span><span class="p">))</span>
<span class="n">rc</span> <span class="o">=</span> <span class="n">mktar</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">,</span> <span class="n">disk_img</span><span class="p">,</span> <span class="n">opts</span><span class="o">.</span><span class="n">compression</span><span class="p">,</span> <span class="n">compress_args</span><span class="p">,</span> <span class="n">selinux</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rc</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">InstallError</span><span class="p">(</span><span class="s2">&quot;virt_install failed&quot;</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">vagrant_dir</span><span class="p">)</span></div>
</pre></div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.ltmpl &mdash; Lorax 28.2 documentation</title>
<title>pylorax.ltmpl &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -165,7 +157,7 @@
<span></span><span class="c1">#</span>
<span class="c1"># ltmpl.py</span>
<span class="c1">#</span>
<span class="c1"># Copyright (C) 2009-2015 Red Hat, Inc.</span>
<span class="c1"># Copyright (C) 2009-2018 Red Hat, Inc.</span>
<span class="c1">#</span>
<span class="c1"># This program is free software; you can redistribute it and/or modify</span>
<span class="c1"># it under the terms of the GNU General Public License as published by</span>
@ -293,7 +285,7 @@
<span class="sd"> * Parsing and execution are *separate* passes - so you can&#39;t use the result</span>
<span class="sd"> of a command in an %if statement (or any other control statements)!</span>
<span class="sd"> * Commands that run external programs (systemctl, gconfset) currently use</span>
<span class="sd"> * Commands that run external programs (e.g. systemctl) currently use</span>
<span class="sd"> the *host*&#39;s copy of that program, which may cause problems if there&#39;s a</span>
<span class="sd"> big enough difference between the host and the image you&#39;re modifying.</span>
@ -373,7 +365,6 @@
<span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">debug_pkgs</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">pkg</span><span class="p">)</span>
<div class="viewcode-block" id="LoraxTemplateRunner.run"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">templatefile</span><span class="p">,</span> <span class="o">**</span><span class="n">variables</span><span class="p">):</span>
<span class="k">for</span> <span class="n">k</span><span class="p">,</span><span class="n">v</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="o">.</span><span class="n">items</span><span class="p">())</span> <span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">builtins</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="n">variables</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">k</span><span class="p">,</span><span class="n">v</span><span class="p">)</span>
@ -412,10 +403,10 @@
<span class="c1"># skip the bit about &quot;ltmpl.py, in _run()&quot; - we know that</span>
<span class="n">exclines</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># log the &quot;ErrorType: this is what happened&quot; line</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="n">exclines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot; </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">exclines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="c1"># and log the entire traceback to the debug log</span>
<span class="k">for</span> <span class="n">_line</span> <span class="ow">in</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">exclines</span><span class="p">)</span><span class="o">.</span><span class="n">splitlines</span><span class="p">():</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="n">_line</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot; </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">_line</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fatalerrors</span><span class="p">:</span>
<span class="k">raise</span>
@ -623,22 +614,6 @@
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">rglob</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="n">fileglob</span><span class="p">),</span> <span class="n">fatal</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">chmod</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">mode</span><span class="p">,</span><span class="mi">8</span><span class="p">))</span></div>
<span class="c1"># TODO: do we need a new command for gsettings?</span>
<div class="viewcode-block" id="LoraxTemplateRunner.gconfset"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.gconfset">[docs]</a> <span class="k">def</span> <span class="nf">gconfset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">keytype</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">outfile</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> gconfset PATH KEYTYPE VALUE [OUTFILE]</span>
<span class="sd"> Set the given gconf PATH, with type KEYTYPE, to the given value.</span>
<span class="sd"> OUTFILE defaults to /etc/gconf/gconf.xml.defaults if not given.</span>
<span class="sd"> Example:</span>
<span class="sd"> gconfset /apps/metacity/general/num_workspaces int 1</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">outfile</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">outfile</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_out</span><span class="p">(</span><span class="s2">&quot;etc/gconf/gconf.xml.defaults&quot;</span><span class="p">)</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;gconftool-2&quot;</span><span class="p">,</span> <span class="s2">&quot;--direct&quot;</span><span class="p">,</span>
<span class="s2">&quot;--config-source=xml:readwrite:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">outfile</span><span class="p">,</span>
<span class="s2">&quot;--set&quot;</span><span class="p">,</span> <span class="s2">&quot;--type&quot;</span><span class="p">,</span> <span class="n">keytype</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">value</span><span class="p">]</span>
<span class="n">runcmd</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span></div>
<div class="viewcode-block" id="LoraxTemplateRunner.log"><a class="viewcode-back" href="../../pylorax.html#pylorax.ltmpl.LoraxTemplateRunner.log">[docs]</a> <span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> log MESSAGE</span>
@ -714,7 +689,7 @@
<span class="n">pkgs</span> <span class="o">=</span> <span class="n">pkgs</span><span class="p">[:</span><span class="n">idx</span><span class="p">]</span> <span class="o">+</span> <span class="n">pkgs</span><span class="p">[</span><span class="n">idx</span><span class="o">+</span><span class="mi">2</span><span class="p">:]</span>
<span class="n">errors</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pkgs</span><span class="p">:</span>
<span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">pkgs</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># Start by using Subject to generate a package query, which will</span>
<span class="c1"># give us a query object similar to what dbo.install would select,</span>
@ -727,30 +702,38 @@
<span class="c1"># dnf queries don&#39;t have a concept of negative globs which is why</span>
<span class="c1"># the filtering is done the hard way.</span>
<span class="n">pkgnames</span> <span class="o">=</span> <span class="p">[</span><span class="n">pkg</span> <span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">dnf</span><span class="o">.</span><span class="n">subject</span><span class="o">.</span><span class="n">Subject</span><span class="p">(</span><span class="n">p</span><span class="p">)</span><span class="o">.</span><span class="n">get_best_query</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dbo</span><span class="o">.</span><span class="n">sack</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">latest</span><span class="o">=</span><span class="kc">True</span><span class="p">)]</span>
<span class="n">pkgnames</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">dnf</span><span class="o">.</span><span class="n">subject</span><span class="o">.</span><span class="n">Subject</span><span class="p">(</span><span class="n">pkg</span><span class="p">)</span><span class="o">.</span><span class="n">get_best_query</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dbo</span><span class="o">.</span><span class="n">sack</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">latest</span><span class="o">=</span><span class="kc">True</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">pkgnames</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">PackageNotFoundError</span><span class="p">(</span><span class="s2">&quot;no package matched&quot;</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
<span class="c1"># Sort the results so that we have consistent results</span>
<span class="n">pkgnames</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">([</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">-</span><span class="si">{}</span><span class="s2">-</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">pkg</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">pkg</span><span class="o">.</span><span class="n">version</span><span class="p">,</span> <span class="n">pkg</span><span class="o">.</span><span class="n">release</span><span class="p">)</span> <span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">pkgnames</span><span class="p">])</span>
<span class="k">raise</span> <span class="n">dnf</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">PackageNotFoundError</span><span class="p">(</span><span class="s2">&quot;no package matched&quot;</span><span class="p">,</span> <span class="n">pkg</span><span class="p">)</span>
<span class="c1"># Apply excludes to the name only</span>
<span class="k">for</span> <span class="n">exclude</span> <span class="ow">in</span> <span class="n">excludes</span><span class="p">:</span>
<span class="n">pkgnames</span> <span class="o">=</span> <span class="p">[</span><span class="n">pkg</span> <span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">pkgnames</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">fnmatch</span><span class="o">.</span><span class="n">fnmatch</span><span class="p">(</span><span class="n">pkg</span><span class="p">,</span> <span class="n">exclude</span><span class="p">)]</span>
<span class="n">pkgnames</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pkgnames</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">fnmatch</span><span class="o">.</span><span class="n">fnmatch</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">exclude</span><span class="p">)]</span>
<span class="c1"># dnf doesn&#39;t handle globs and multiple repos correctly, we need to find the highest nvr for each unique</span>
<span class="c1"># package name and install those. Except that we also support version pinning but in that case it</span>
<span class="c1"># won&#39;t be a glob so this should work.</span>
<span class="n">d</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pkgnames</span><span class="p">:</span>
<span class="n">d</span><span class="p">[</span><span class="n">p</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">p</span><span class="p">))</span>
<span class="c1"># Convert to a sorted NVR list for installation</span>
<span class="n">pkgnvrs</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">([</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">-</span><span class="si">{}</span><span class="s2">-</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">version</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">release</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">d</span><span class="o">.</span><span class="n">values</span><span class="p">()])</span>
<span class="c1"># If the request is a glob, expand it in the log</span>
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">g</span> <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;*&#39;</span><span class="p">,</span><span class="s1">&#39;?&#39;</span><span class="p">,</span><span class="s1">&#39;.&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">p</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;installpkg: </span><span class="si">%s</span><span class="s2"> expands to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">pkgnames</span><span class="p">))</span>
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">g</span> <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;*&#39;</span><span class="p">,</span><span class="s1">&#39;?&#39;</span><span class="p">,</span><span class="s1">&#39;.&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">pkg</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;installpkg: </span><span class="si">%s</span><span class="s2"> expands to </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">pkg</span><span class="p">,</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">pkgnvrs</span><span class="p">))</span>
<span class="k">for</span> <span class="n">pkgname</span> <span class="ow">in</span> <span class="n">pkgnames</span><span class="p">:</span>
<span class="k">for</span> <span class="n">pkgnvr</span> <span class="ow">in</span> <span class="n">pkgnvrs</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">dbo</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="n">pkgname</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">dbo</span><span class="o">.</span><span class="n">install</span><span class="p">(</span><span class="n">pkgnvr</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="c1"># pylint: disable=broad-except</span>
<span class="k">if</span> <span class="n">required</span><span class="p">:</span>
<span class="k">raise</span>
<span class="c1"># Not required, log it and continue processing pkgs</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;installpkg </span><span class="si">%s</span><span class="s2"> failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">pkgname</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;installpkg </span><span class="si">%s</span><span class="s2"> failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">pkgnvr</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="c1"># pylint: disable=broad-except</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;installpkg </span><span class="si">%s</span><span class="s2"> failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;installpkg </span><span class="si">%s</span><span class="s2"> failed: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">pkg</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="n">errors</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">errors</span> <span class="ow">and</span> <span class="n">required</span><span class="p">:</span>
@ -951,9 +934,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -962,11 +943,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -981,35 +962,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.monitor &mdash; Lorax 28.2 documentation</title>
<title>pylorax.monitor &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -198,6 +190,26 @@
<span class="sd"> for patterns that would indicate that the installation failed.</span>
<span class="sd"> self.server.log_error is set True when this happens.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">simple_tests</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;Traceback (&quot;</span><span class="p">,</span>
<span class="s2">&quot;traceback script(s) have been run&quot;</span><span class="p">,</span>
<span class="s2">&quot;Out of memory:&quot;</span><span class="p">,</span>
<span class="s2">&quot;Call Trace:&quot;</span><span class="p">,</span>
<span class="s2">&quot;insufficient disk space:&quot;</span><span class="p">,</span>
<span class="s2">&quot;Not enough disk space to download the packages&quot;</span><span class="p">,</span>
<span class="s2">&quot;error populating transaction after&quot;</span><span class="p">,</span>
<span class="s2">&quot;crashed on signal&quot;</span><span class="p">,</span>
<span class="s2">&quot;packaging: Missed: NoSuchPackage&quot;</span><span class="p">,</span>
<span class="s2">&quot;packaging: Installation failed&quot;</span><span class="p">,</span>
<span class="s2">&quot;The following error occurred while installing. This is a fatal error&quot;</span>
<span class="p">]</span>
<span class="n">re_tests</span> <span class="o">=</span> <span class="p">[</span>
<span class="sa">r</span><span class="s2">&quot;packaging: base repo .* not valid&quot;</span><span class="p">,</span>
<span class="sa">r</span><span class="s2">&quot;packaging: .* requires .*&quot;</span>
<span class="p">]</span>
<div class="viewcode-block" id="LogRequestHandler.setup"><a class="viewcode-back" href="../../pylorax.html#pylorax.monitor.LogRequestHandler.setup">[docs]</a> <span class="k">def</span> <span class="nf">setup</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Start writing to self.server.log_path&quot;&quot;&quot;</span>
@ -263,25 +275,13 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="s2">&quot;IGNORED&quot;</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">simple_tests</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;Traceback (&quot;</span><span class="p">,</span>
<span class="s2">&quot;Out of memory:&quot;</span><span class="p">,</span>
<span class="s2">&quot;Call Trace:&quot;</span><span class="p">,</span>
<span class="s2">&quot;insufficient disk space:&quot;</span><span class="p">,</span>
<span class="s2">&quot;Not enough disk space to download the packages&quot;</span><span class="p">,</span>
<span class="s2">&quot;error populating transaction after&quot;</span><span class="p">,</span>
<span class="s2">&quot;traceback script(s) have been run&quot;</span><span class="p">,</span>
<span class="s2">&quot;crashed on signal&quot;</span><span class="p">,</span>
<span class="s2">&quot;packaging: Missed: NoSuchPackage&quot;</span><span class="p">,</span>
<span class="s2">&quot;packaging: Installation failed&quot;</span><span class="p">,</span>
<span class="s2">&quot;The following error occurred while installing. This is a fatal error&quot;</span><span class="p">]</span>
<span class="n">re_tests</span> <span class="o">=</span> <span class="p">[</span><span class="sa">r</span><span class="s2">&quot;packaging: base repo .* not valid&quot;</span><span class="p">,</span>
<span class="sa">r</span><span class="s2">&quot;packaging: .* requires .*&quot;</span><span class="p">]</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">simple_tests</span><span class="p">:</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">simple_tests</span><span class="p">:</span>
<span class="k">if</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_error</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">error_line</span> <span class="o">=</span> <span class="n">line</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">re_tests</span><span class="p">:</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">re_tests</span><span class="p">:</span>
<span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">log_error</span> <span class="o">=</span> <span class="kc">True</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">error_line</span> <span class="o">=</span> <span class="n">line</span>
@ -332,7 +332,7 @@
<span class="sd"> This needs to be running before the virt-install runs, it expects</span>
<span class="sd"> there to be a listener on the port used for the virtio log port.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log_path</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="s2">&quot;localhost&quot;</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">log_path</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="s2">&quot;localhost&quot;</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">log_request_handler_class</span><span class="o">=</span><span class="n">LogRequestHandler</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Start a thread to monitor the logs.</span>
@ -346,7 +346,7 @@
<span class="sd"> If log_path isn&#39;t set then it only monitors the logs, instead of</span>
<span class="sd"> also writing them to disk.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span> <span class="o">=</span> <span class="n">LogServer</span><span class="p">(</span><span class="n">log_path</span><span class="p">,</span> <span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">),</span> <span class="n">LogRequestHandler</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server</span> <span class="o">=</span> <span class="n">LogServer</span><span class="p">(</span><span class="n">log_path</span><span class="p">,</span> <span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">),</span> <span class="n">log_request_handler_class</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="n">timeout</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">server_address</span>
<span class="bp">self</span><span class="o">.</span><span class="n">log_path</span> <span class="o">=</span> <span class="n">log_path</span>
<span class="bp">self</span><span class="o">.</span><span class="n">server_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">handle_request</span><span class="p">)</span>
@ -360,9 +360,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -371,11 +369,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -390,35 +388,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.mount &mdash; Lorax 28.2 documentation</title>
<title>pylorax.mount &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -267,9 +259,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -278,11 +268,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -297,35 +287,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.sysutils &mdash; Lorax 28.2 documentation</title>
<title>pylorax.sysutils &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -273,9 +265,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -284,11 +274,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -303,35 +293,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.treebuilder &mdash; Lorax 28.2 documentation</title>
<title>pylorax.treebuilder &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -257,7 +249,8 @@
<span class="n">release</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">q</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">dbo</span><span class="o">.</span><span class="n">sack</span><span class="o">.</span><span class="n">query</span><span class="p">()</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">q</span><span class="o">.</span><span class="n">available</span><span class="p">()</span>
<span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">a</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">provides</span><span class="o">=</span><span class="s1">&#39;/etc/system-release&#39;</span><span class="p">):</span>
<span class="k">for</span> <span class="n">pkg</span> <span class="ow">in</span> <span class="n">a</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">provides</span><span class="o">=</span><span class="s1">&#39;system-release&#39;</span><span class="p">):</span>
<span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;Found release package </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">pkg</span><span class="p">)</span>
<span class="k">if</span> <span class="n">pkg</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;generic&#39;</span><span class="p">):</span>
<span class="k">continue</span>
<span class="k">else</span><span class="p">:</span>
@ -372,11 +365,11 @@
<div class="viewcode-block" id="RuntimeBuilder.generate_module_data"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.generate_module_data">[docs]</a> <span class="k">def</span> <span class="nf">generate_module_data</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">root</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">vars</span><span class="o">.</span><span class="n">root</span>
<span class="n">moddir</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="s2">&quot;lib/modules/&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">kver</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">moddir</span><span class="p">):</span>
<span class="n">ksyms</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="s2">&quot;boot/System.map-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">kver</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;doing depmod and module-info for </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">kver</span><span class="p">)</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s2">&quot;depmod&quot;</span><span class="p">,</span> <span class="s2">&quot;-a&quot;</span><span class="p">,</span> <span class="s2">&quot;-F&quot;</span><span class="p">,</span> <span class="n">ksyms</span><span class="p">,</span> <span class="s2">&quot;-b&quot;</span><span class="p">,</span> <span class="n">root</span><span class="p">,</span> <span class="n">kver</span><span class="p">])</span>
<span class="n">generate_module_info</span><span class="p">(</span><span class="n">moddir</span><span class="o">+</span><span class="n">kver</span><span class="p">,</span> <span class="n">outfile</span><span class="o">=</span><span class="n">moddir</span><span class="o">+</span><span class="s2">&quot;module-info&quot;</span><span class="p">)</span></div>
<span class="k">for</span> <span class="n">kernel</span> <span class="ow">in</span> <span class="n">findkernels</span><span class="p">(</span><span class="n">root</span><span class="o">=</span><span class="n">root</span><span class="p">):</span>
<span class="n">ksyms</span> <span class="o">=</span> <span class="n">joinpaths</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="s2">&quot;boot/System.map-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">kernel</span><span class="o">.</span><span class="n">version</span><span class="p">)</span>
<span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;doing depmod and module-info for </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">kernel</span><span class="o">.</span><span class="n">version</span><span class="p">)</span>
<span class="n">runcmd</span><span class="p">([</span><span class="s2">&quot;depmod&quot;</span><span class="p">,</span> <span class="s2">&quot;-a&quot;</span><span class="p">,</span> <span class="s2">&quot;-F&quot;</span><span class="p">,</span> <span class="n">ksyms</span><span class="p">,</span> <span class="s2">&quot;-b&quot;</span><span class="p">,</span> <span class="n">root</span><span class="p">,</span> <span class="n">kernel</span><span class="o">.</span><span class="n">version</span><span class="p">])</span>
<span class="n">generate_module_info</span><span class="p">(</span><span class="n">moddir</span><span class="o">+</span><span class="n">kernel</span><span class="o">.</span><span class="n">version</span><span class="p">,</span> <span class="n">outfile</span><span class="o">=</span><span class="n">moddir</span><span class="o">+</span><span class="s2">&quot;module-info&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="RuntimeBuilder.create_runtime"><a class="viewcode-back" href="../../pylorax.html#pylorax.treebuilder.RuntimeBuilder.create_runtime">[docs]</a> <span class="k">def</span> <span class="nf">create_runtime</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">outfile</span><span class="o">=</span><span class="s2">&quot;/var/tmp/squashfs.img&quot;</span><span class="p">,</span> <span class="n">compression</span><span class="o">=</span><span class="s2">&quot;xz&quot;</span><span class="p">,</span> <span class="n">compressargs</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">2</span><span class="p">):</span>
<span class="c1"># make live rootfs image - must be named &quot;LiveOS/rootfs.img&quot; for dracut</span>
@ -564,9 +557,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -575,11 +566,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -594,35 +585,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pylorax.treeinfo &mdash; Lorax 28.2 documentation</title>
<title>pylorax.treeinfo &mdash; Lorax 28.21 documentation</title>
@ -24,26 +24,17 @@
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Lorax 28.2 documentation" href="../../index.html"/>
<link rel="up" title="pylorax" href="../pylorax.html"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<script src="../../_static/js/modernizr.min.js"></script>
</head>
<body class="wy-body-for-nav" role="document">
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
@ -65,7 +56,7 @@
<div class="version">
28.2
28.21
</div>
@ -94,6 +85,8 @@
<li class="toctree-l1"><a class="reference internal" href="../../intro.html#before-lorax">Before Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax.html">Lorax</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livemedia-creator.html">livemedia-creator</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lorax-composer.html">lorax-composer</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../composer-cli.html">composer-cli</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../product-images.html">Product and Updates Images</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../modules.html">pylorax</a></li>
</ul>
@ -107,7 +100,7 @@
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">Lorax</a>
@ -115,9 +108,10 @@
</nav>
<div class="wy-nav-content">
<div class="rst-content">
@ -149,8 +143,6 @@
<li class="wy-breadcrumbs-aside">
</li>
</ul>
@ -222,9 +214,7 @@
</pre></div>
</div>
<div class="articleComments">
</div>
</div>
<footer>
@ -233,11 +223,11 @@
<div role="contentinfo">
<p>
&copy; Copyright 2015, Red Hat, Inc..
&copy; Copyright 2018, Red Hat, Inc.
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
@ -252,35 +242,33 @@
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.2',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'28.21',
LANGUAGE:'None',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript" src="../../_static/js/theme.js"></script>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.StickyNav.enable();
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</script>
</body>
</html>

View File

@ -0,0 +1,62 @@
composer-cli
============
:Authors:
Brian C. Lane <bcl@redhat.com>
``composer-cli`` is used to interact with the ``lorax-composer`` API server, managing blueprints, exploring available packages, and building new images.
It requires `lorax-composer <lorax-composer.html>`_ to be installed on the
local system, and the user running it needs to be a member of the ``weldr``
group. They do not need to be root, but all of the `security precautions
<lorax-composer.html#security>`_ apply.
composer-cli cmdline arguments
------------------------------
.. argparse::
:ref: composer.cli.cmdline.composer_cli_parser
:prog: composer-cli
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
<https://github.com/weldr/lorax/tree/master/tests/pylorax/blueprints/>`_.
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``.
Build an image
----------------
Build a ``qcow2`` disk image from this blueprint by running ``composer-cli
compose start http-server qcow2``. It will print a UUID that you can use to
keep track of the build. You can also cancel the build if needed.
The available types of images is displayed by ``composer-cli compose types``.
Currently this consists of: ami, ext4-filesystem, live-iso, partitioned-disk,
qcow2, tar, vhd, vmdk
Monitor the build status
------------------------
Monitor it using ``composer-cli compose status``, which will show the status of
all the builds on the system. You can view the end of the anaconda build logs
once it is in the ``RUNNING`` state using ``composer-cli compose log UUID``
where UUID is the UUID returned by the start command.
Once the build is in the ``FINISHED`` state you can download the image.
Download the image
------------------
Downloading the final image is done with ``composer-cli compose image UUID`` and it will
save the qcow2 image as ``UUID-disk.qcow2`` which you can then use to boot a VM like this::
qemu-kvm --name test-image -m 1024 -hda ./UUID-disk.qcow2

View File

@ -14,9 +14,16 @@ Contents:
intro
lorax
livemedia-creator
lorax-composer
composer-cli
product-images
modules
Documentation for other Lorax Branches
======================================
* `Fedora 28 <f28-branch/>`_
* `RHEL7 lorax-composer <lorax-composer/>`_
Indices and tables
==================

View File

@ -192,10 +192,7 @@ install. There are a couple of things to keep in mind when doing this:
running under you may encounter strange bugs if you try to build newer or
older releases.
2. Make sure selinux is set to permissive or disabled. It won't install
correctly with selinux set to enforcing yet.
3. It may totally trash your host. So far I haven't had this happen, but the
2. It may totally trash your host. So far I haven't had this happen, but the
possibility exists that a bug in Anaconda could result in it operating on
real devices. I recommend running it in a virt or on a system that you can
afford to lose all data from.
@ -213,6 +210,10 @@ Example cmdline:
or UEFI). You can create BIOS partitioned disk images on UEFI by using
virt.
.. note::
As of version 30.7 SELinux can be set to Enforcing. The current state is
logged for debugging purposes and if there are SELinux denials they should
be reported as a bug.
AMI Images
----------
@ -393,14 +394,14 @@ group.
``url points to the correct repo``
7. Init the mock
``mock -r fedora-rawhide-x86_64 --init``
``mock -r fedora-rawhide-x86_64 --old-chroot --init``
8. Copy the kickstart inside the mock
``mock -r fedora-rawhide-x86_64 --copyin ./fedora-minimal.ks /root/``
``mock -r fedora-rawhide-x86_64 --old-chroot --copyin ./fedora-minimal.ks /root/``
9. Make a minimal iso::
mock -r fedora-rawhide-x86_64 --chroot -- livemedia-creator --no-virt \
mock -r fedora-rawhide-x86_64 --old-chroot --chroot -- livemedia-creator --no-virt \
--resultdir=/results/try-1 --logfile=/results/logs/try-1/try-1.log \
--make-iso --ks /root/fedora-minimal.ks
@ -447,17 +448,17 @@ group.
``url points to the correct repo``
7. Init the mock
``mock -r fedora-rawhide-x86_64 --init``
``mock -r fedora-rawhide-x86_64 --old-chroot --init``
8. Copy the kickstart inside the mock
``mock -r fedora-rawhide-x86_64 --copyin ./fedora-minimal.ks /root/``
``mock -r fedora-rawhide-x86_64 --old-chroot --copyin ./fedora-minimal.ks /root/``
9. Copy the Anaconda boot.iso inside the mock
``mock -r fedora-rawhide-x86_64 --copyin ./boot.iso /root/``
``mock -r fedora-rawhide-x86_64 --old-chroot --copyin ./boot.iso /root/``
10. Make a minimal iso::
mock -r fedora-rawhide-x86_64 --chroot -- livemedia-creator \
mock -r fedora-rawhide-x86_64 --old-chroot --chroot -- livemedia-creator \
--resultdir=/results/try-1 --logfile=/results/logs/try-1/try-1.log \
--make-iso --ks /root/fedora-minimal.ks --iso /root/boot.iso

View File

@ -0,0 +1,356 @@
lorax-composer
==============
:Authors:
Brian C. Lane <bcl@redhat.com>
``lorax-composer`` is an API server that allows you to build disk images using
`Blueprints`_ to describe the package versions to be installed into the image.
It is compatible with the Weldr project's bdcs-api REST protocol. More
information on Weldr can be found `on the Weldr blog <http://www.weldr.io>`_.
Behind the scenes it uses `livemedia-creator <livemedia-creator.html>`_ and
`Anaconda <https://anaconda-installer.readthedocs.io/en/latest/>`_ to handle the
installation and configuration of the images.
Important Things To Note
------------------------
* As of version 30.7 SELinux can be set to Enforcing. The current state is
logged for debugging purposes and if there are SELinux denials they should
be reported as a bug.
* All image types lock the root account, except for live-iso. You will need to either
use one of the `Customizations`_ methods for setting a ssh key/password, install a
package that creates a user, or use something like `cloud-init` to setup access at
boot time.
Installation
------------
The best way to install ``lorax-composer`` is to use ``sudo dnf install
lorax-composer composer-cli``, this will setup the weldr user and install the
systemd socket activation service. You will then need to enable it with ``sudo
systemctl enable lorax-composer.socket && sudo systemctl start
lorax-composer.socket``. This will leave the server off until the first request
is made. Systemd will then launch the server and it will remain running until
the system is rebooted. This will cause some delay in responding to the first
request from the UI or `composer-cli`.
.. note::
If you want lorax-composer to respond immediately to the first request you can
start and enable `lorax-composer.service` instead of `lorax-composer.socket`
Quickstart
----------
1. Create a ``weldr`` user and group by running ``useradd weldr``
2. Remove any pre-existing socket directory with ``rm -rf /run/weldr/``
A new directory with correct permissions will be created the first time the server runs.
3. Enable the socket activation with ``systemctl enable lorax-composer.socket
&& sudo systemctl start lorax-composer.socket``.
NOTE: You can also run it directly with ``lorax-composer /path/to/blueprints``. However,
``lorax-composer`` does not react well to being started both on the command line and via
socket activation at the same time. It is therefore recommended that you run it directly
on the command line only for testing or development purposes. For real use or development
of other projects that simply use the API, you should stick to socket activation only.
The ``/path/to/blueprints/`` directory is where the blueprints' git repo will
be created, and all the blueprints created with the ``/api/v0/blueprints/new``
route will be stored. If there are blueprint ``.toml`` files in the top level
of the directory they will be imported into the blueprint git storage when
``lorax-composer`` starts.
Logs
----
Logs are stored under ``/var/log/lorax-composer/`` and include all console
messages as well as extra debugging info and API requests.
Security
--------
Some security related issues that you should be aware of before running ``lorax-composer``:
* One of the API server threads needs to retain root privileges in order to run Anaconda.
* Only allow authorized users access to the ``weldr`` group and socket.
Since Anaconda kickstarts are used there is the possibility that a user could
inject commands into a blueprint that would result in the kickstart executing
arbitrary code on the host. Only authorized users should be allowed to build
images using ``lorax-composer``.
lorax-composer cmdline arguments
--------------------------------
.. argparse::
:ref: pylorax.api.cmdline.lorax_composer_parser
:prog: lorax-composer
How it Works
------------
The server runs as root, and as ``weldr``. Communication with it is via a unix
domain socket (``/run/weldr/api.socket`` by default). The directory and socket
are owned by ``root:weldr`` so that any user in the ``weldr`` group can use the API
to control ``lorax-composer``.
At startup the server will check for the correct permissions and
ownership of a pre-existing directory, or it will create a new one if it
doesn't exist. The socket path and group owner's name can be changed from the
cmdline by passing it the ``--socket`` and ``--group`` arguments.
It will then drop root privileges for the API thread and run as the ``weldr``
user. The queue and compose thread still runs as root because it needs to be
able to mount/umount files and run Anaconda.
Composing Images
----------------
The `welder-web <https://github.com/weldr/welder-web/>`_ GUI project can be used to construct
blueprints and create composes using a web browser.
Or use the command line with `composer-cli <composer-cli.html>`_.
Blueprints
----------
Blueprints are simple text files in `TOML <https://github.com/toml-lang/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.
Example blueprints can be found in the ``lorax-composer`` `test suite
<https://github.com/weldr/lorax/tree/master/tests/pylorax/blueprints/>`_, with a simple one
looking 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 <https://semver.org/>`_ 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: As of lorax-composer-29.2-1 the versions are not used for depsolving,
that is planned for a future release. And currently there are no differences
between ``packages`` and ``modules`` in ``lorax-composer``.
[[groups]]
~~~~~~~~~~
These 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.
Customizations
~~~~~~~~~~~~~~
The ``[[customizations]]`` section can be used to configure the hostname of the final image. eg.::
[[customizations]]
hostname = "baseimage"
[[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.
[[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.
[[customizations.group]]
************************
Add a group to the image. ``name`` is required and ``gid`` is optional::
[[customizations.group]]
name = "widget"
gid = 1130
Adding Output Types
-------------------
``livemedia-creator`` supports a large number of output types, and only some of
these are currently available via ``lorax-composer``. To add a new output type to
lorax-composer a kickstart file needs to be added to ``./share/composer/``. The
name of the kickstart is what will be used by the ``/compose/types`` route, and the
``compose_type`` field of the POST to start a compose. It also needs to have
code added to the :py:func:`pylorax.api.compose.compose_args` function. The
``_MAP`` entry in this function defines what lorax-composer will pass to
:py:func:`pylorax.installer.novirt_install` when it runs the compose. When the
compose is finished the output files need to be copied out of the build
directory (``/var/lib/lorax/composer/results/<UUID>/compose/``),
:py:func:`pylorax.api.compose.move_compose_results` handles this for each type.
You should move them instead of copying to save space.
If the new output type does not have support in livemedia-creator it should be
added there first. This will make the output available to the widest number of
users.
Example: Add partitioned disk support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Partitioned disk support is something that livemedia-creator already supports
via the ``--make-disk`` cmdline argument. To add this to lorax-composer it
needs 3 things:
* A ``partitioned-disk.ks`` file in ``./share/composer/``
* A new entry in the _MAP in :py:func:`pylorax.api.compose.compose_args`
* Add a bit of code to :py:func:`pylorax.api.compose.move_compose_results` to move the disk image from
the compose directory to the results directory.
The ``partitioned-disk.ks`` is pretty similar to the example minimal kickstart
in ``./docs/fedora-minimal.ks``. You should remove the ``url`` and ``repo``
commands, they will be added by the compose process. Make sure the bootloader
packages are included in the ``%packages`` section at the end of the kickstart,
and you will want to leave off the ``%end`` so that the compose can append the
list of packages from the blueprint.
The new ``_MAP`` entry should be a copy of one of the existing entries, but with ``make_disk`` set
to ``True``. Make sure that none of the other ``make_*`` options are ``True``. The ``image_name`` is
what the name of the final image will be.
``move_compose_results()`` can be as simple as moving the output file into
the results directory, or it could do some post-processing on it. The end of
the function should always clean up the ``./compose/`` directory, removing any
unneeded extra files. This is especially true for the ``live-iso`` since it produces
the contents of the iso as well as the boot.iso itself.
Package Sources
---------------
By default lorax-composer uses the host's configured repositories. It copies
the ``*.repo`` files from ``/etc/yum.repos.d/`` into
``/var/lib/lorax/composer/repos.d/`` at startup, these are immutable system
repositories and cannot be deleted or changed. If you want to add additional
repos you can put them into ``/var/lib/lorax/composer/repos.d/`` or use the
``/api/v0/projects/source/*`` API routes to create them.
The new source can be added by doing a POST to the ``/api/v0/projects/source/new``
route using JSON (with `Content-Type` header set to `application/json`) or TOML
(with it set to `text/x-toml`). The format of the source looks like this (in
TOML)::
name = "custom-source-1"
url = "https://url/path/to/repository/"
type = "yum-baseurl"
proxy = "https://proxy-url/"
check_ssl = true
check_gpg = true
gpgkey_urls = ["https://url/path/to/gpg-key"]
The ``proxy`` and ``gpgkey_urls`` entries are optional. All of the others are required. The supported
types for the urls are:
* ``yum-baseurl`` is a URL to a yum repository.
* ``yum-mirrorlist`` is a URL for a mirrorlist.
* ``yum-metalink`` is a URL for a metalink.
If ``check_ssl`` is true the https certificates must be valid. If they are self-signed you can either set
this to false, or add your Certificate Authority to the host system.
If ``check_gpg`` is true the GPG key must either be installed on the host system, or ``gpgkey_urls``
should point to it.
You can edit an existing source (other than system sources), by doing a POST to the ``new`` route
with the new version of the source. It will overwrite the previous one.
A list of existing sources is available from ``/api/v0/projects/source/list``, and detailed info
on a source can be retrieved with the ``/api/v0/projects/source/info/<source-name>`` route. By default
it returns JSON but it can also return TOML if ``?format=toml`` is added to the request.
Non-system sources can be deleted by doing a ``DELETE`` request to the
``/api/v0/projects/source/delete/<source-name>`` route.
The documentation for the source API routes can be `found here <pylorax.api.html#api-v0-projects-source-list>`_
The configured sources are used for all blueprint depsolve operations, and for composing images.
When adding additional sources you must make sure that the packages in the source do not
conflict with any other package sources, otherwise depsolving will fail.
DVD ISO Package Source
~~~~~~~~~~~~~~~~~~~~~~
In some situations the system may want to *only* use a DVD iso as the package
source, not the repos from the network. ``lorax-composer`` and ``anaconda``
understand ``file://`` URLs so you can mount an iso on the host, and replace the
system repo files with a configuration file pointing to the DVD.
* Stop the ``lorax-composer.service`` if it is running
* Move the repo files in ``/etc/yum.repos.d/`` someplace safe
* Create a new ``iso.repo`` file in ``/etc/yum.repos.d/``::
[iso]
name=iso
baseurl=file:///mnt/iso/
enabled=1
gpgcheck=1
gpgkey=file:///mnt/iso/RPM-GPG-KEY-redhat-release
* Remove all the cached repo files from ``/var/lib/lorax/composer/repos/``
* Restart the ``lorax-composer.service``
* Check the output of ``composer-cli status show`` for any output specific depsolve errors.
For example, the DVD usually does not include ``grub2-efi-*-cdboot-*`` so the live-iso image
type will not be available.
If you want to *add* the DVD source to the existing sources you can do that by
mounting the iso and creating a source file to point to it as described in the
`Package Sources`_ documentation. In that case there is no need to remove the other
sources from ``/etc/yum.repos.d/`` or clear the cached repos.

View File

@ -92,7 +92,6 @@ installation. A number of template commands are used here:
* :func:`append <pylorax.ltmpl.LoraxTemplateRunner.append>` to add text to a file.
* :func:`chmod <pylorax.ltmpl.LoraxTemplateRunner.chmod>` changes the file's mode.
* :func:`gconfset <pylorax.ltmpl.LoraxTemplateRunner.gconfset>` runs gconfset.
* :func:`install <pylorax.ltmpl.LoraxTemplateRunner.install>` to install a file into the installroot.
* :func:`mkdir <pylorax.ltmpl.LoraxTemplateRunner.mkdir>` makes a new directory.
* :func:`move <pylorax.ltmpl.LoraxTemplateRunner.move>` to move a file into the installroot

View File

@ -0,0 +1,102 @@
pylorax.api package
===================
Submodules
----------
pylorax.api.cmdline module
--------------------------
.. automodule:: pylorax.api.cmdline
:members:
:undoc-members:
:show-inheritance:
pylorax.api.compose module
--------------------------
.. automodule:: pylorax.api.compose
:members:
:undoc-members:
:show-inheritance:
pylorax.api.config module
-------------------------
.. automodule:: pylorax.api.config
:members:
:undoc-members:
:show-inheritance:
pylorax.api.crossdomain module
------------------------------
.. automodule:: pylorax.api.crossdomain
:members:
:undoc-members:
:show-inheritance:
pylorax.api.dnfbase module
--------------------------
.. automodule:: pylorax.api.dnfbase
:members:
:undoc-members:
:show-inheritance:
pylorax.api.projects module
---------------------------
.. automodule:: pylorax.api.projects
:members:
:undoc-members:
:show-inheritance:
pylorax.api.queue module
------------------------
.. automodule:: pylorax.api.queue
:members:
:undoc-members:
:show-inheritance:
pylorax.api.recipes module
--------------------------
.. automodule:: pylorax.api.recipes
:members:
:undoc-members:
:show-inheritance:
pylorax.api.server module
-------------------------
.. automodule:: pylorax.api.server
:members:
:undoc-members:
:show-inheritance:
pylorax.api.v0 module
---------------------
.. automodule:: pylorax.api.v0
:members:
:undoc-members:
:show-inheritance:
pylorax.api.workspace module
----------------------------
.. automodule:: pylorax.api.workspace
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: pylorax.api
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,123 +1,154 @@
pylorax package
===============
Subpackages
-----------
.. toctree::
pylorax.api
Submodules
----------
pylorax\.base module
--------------------
pylorax.base module
-------------------
.. automodule:: pylorax.base
:members:
:undoc-members:
:show-inheritance:
pylorax\.buildstamp module
--------------------------
pylorax.buildstamp module
-------------------------
.. automodule:: pylorax.buildstamp
:members:
:undoc-members:
:show-inheritance:
pylorax\.cmdline module
-----------------------
pylorax.cmdline module
----------------------
.. automodule:: pylorax.cmdline
:members:
:undoc-members:
:show-inheritance:
pylorax\.decorators module
--------------------------
pylorax.creator module
----------------------
.. automodule:: pylorax.creator
:members:
:undoc-members:
:show-inheritance:
pylorax.decorators module
-------------------------
.. automodule:: pylorax.decorators
:members:
:undoc-members:
:show-inheritance:
pylorax\.discinfo module
------------------------
pylorax.discinfo module
-----------------------
.. automodule:: pylorax.discinfo
:members:
:undoc-members:
:show-inheritance:
pylorax\.dnfhelper module
-------------------------
pylorax.dnfbase module
----------------------
.. automodule:: pylorax.dnfbase
:members:
:undoc-members:
:show-inheritance:
pylorax.dnfhelper module
------------------------
.. automodule:: pylorax.dnfhelper
:members:
:undoc-members:
:show-inheritance:
pylorax\.executils module
-------------------------
pylorax.executils module
------------------------
.. automodule:: pylorax.executils
:members:
:undoc-members:
:show-inheritance:
pylorax\.imgutils module
------------------------
pylorax.imgutils module
-----------------------
.. automodule:: pylorax.imgutils
:members:
:undoc-members:
:show-inheritance:
pylorax\.ltmpl module
---------------------
pylorax.installer module
------------------------
.. automodule:: pylorax.installer
:members:
:undoc-members:
:show-inheritance:
pylorax.ltmpl module
--------------------
.. automodule:: pylorax.ltmpl
:members:
:undoc-members:
:show-inheritance:
pylorax\.monitor module
-----------------------
pylorax.monitor module
----------------------
.. automodule:: pylorax.monitor
:members:
:undoc-members:
:show-inheritance:
pylorax\.mount module
---------------------
pylorax.mount module
--------------------
.. automodule:: pylorax.mount
:members:
:undoc-members:
:show-inheritance:
pylorax\.output module
----------------------
pylorax.output module
---------------------
.. automodule:: pylorax.output
:members:
:undoc-members:
:show-inheritance:
pylorax\.sysutils module
------------------------
pylorax.sysutils module
-----------------------
.. automodule:: pylorax.sysutils
:members:
:undoc-members:
:show-inheritance:
pylorax\.treebuilder module
---------------------------
pylorax.treebuilder module
--------------------------
.. automodule:: pylorax.treebuilder
:members:
:undoc-members:
:show-inheritance:
pylorax\.treeinfo module
------------------------
pylorax.treeinfo module
-----------------------
.. automodule:: pylorax.treeinfo
:members:

View File

@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@ -82,9 +82,21 @@ div.sphinxsidebar input {
}
div.sphinxsidebar #searchbox input[type="text"] {
width: 170px;
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%;
@ -199,6 +211,11 @@ table.modindextable td {
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: 450px;
max-width: 800px;
}
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
@ -332,6 +349,11 @@ table.docutils {
border-collapse: collapse;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
@ -398,6 +420,13 @@ table.field-list td, table.field-list th {
margin: 0;
}
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
@ -438,10 +467,14 @@ dd {
margin-left: 30px;
}
dt:target, .highlighted {
dt:target, span.highlighted {
background-color: #fbe54e;
}
rect.highlighted {
fill: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;

View File

@ -1,2 +1 @@
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
/*# sourceMappingURL=badge_only.css.map */
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../fonts/fontawesome-webfont.eot");src:url("../fonts/fontawesome-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff") format("woff"),url("../fonts/fontawesome-webfont.ttf") format("truetype"),url("../fonts/fontawesome-webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@ -45,7 +45,7 @@ jQuery.urlencode = encodeURIComponent;
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s == 'undefined')
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
@ -66,29 +66,55 @@ jQuery.getQueryParameters = function(s) {
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node) {
if (node.nodeType == 3) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
var span = document.createElement("span");
span.className = className;
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var bbox = span.getBBox();
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
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);
var parentOfText = node.parentNode.parentNode;
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this);
highlight(this, addItems);
});
}
}
return this.each(function() {
highlight(this);
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
@ -131,21 +157,21 @@ var Documentation = {
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
PLURAL_EXPR : function(n) { return 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 : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated == 'undefined')
if (typeof translated === 'undefined')
return string;
return (typeof translated == 'string') ? translated : translated[0];
return (typeof translated === 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated == 'undefined')
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
@ -180,7 +206,7 @@ var Documentation = {
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash)
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
@ -216,7 +242,7 @@ var Documentation = {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) == 'minus.png')
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
@ -248,7 +274,7 @@ var Documentation = {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this == '..')
if (this === '..')
parts.pop();
});
var url = parts.join('/');

View File

@ -0,0 +1,9 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '28.21',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

10253
docs/html/_static/jquery-3.2.1.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,169 +1,3 @@
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"sphinx-rtd-theme":[function(require,module,exports){
var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');
// Sphinx theme nav state
function ThemeNav () {
var nav = {
navBar: null,
win: null,
winScroll: false,
winResize: false,
linkScroll: false,
winPosition: 0,
winHeight: null,
docHeight: null,
isRunning: false
};
nav.enable = function () {
var self = this;
if (!self.isRunning) {
self.isRunning = true;
jQuery(function ($) {
self.init($);
self.reset();
self.win.on('hashchange', self.reset);
// Set scroll monitor
self.win.on('scroll', function () {
if (!self.linkScroll) {
self.winScroll = true;
}
});
setInterval(function () { if (self.winScroll) self.onScroll(); }, 25);
// Set resize monitor
self.win.on('resize', function () {
self.winResize = true;
});
setInterval(function () { if (self.winResize) self.onResize(); }, 25);
self.onResize();
});
};
};
nav.init = function ($) {
var doc = $(document),
self = this;
this.navBar = $('div.wy-side-scroll:first');
this.win = $(window);
// Set up javascript UX bits
$(document)
// Shift nav in mobile when clicking the menu.
.on('click', "[data-toggle='wy-nav-top']", function() {
$("[data-toggle='wy-nav-shift']").toggleClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
})
// Nav menu link click operations
.on('click', ".wy-menu-vertical .current ul li a", function() {
var target = $(this);
// Close menu when you click a link.
$("[data-toggle='wy-nav-shift']").removeClass("shift");
$("[data-toggle='rst-versions']").toggleClass("shift");
// Handle dynamic display of l3 and l4 nav lists
self.toggleCurrent(target);
self.hashChange();
})
.on('click', "[data-toggle='rst-current-version']", function() {
$("[data-toggle='rst-versions']").toggleClass("shift-up");
})
// Make tables responsive
$("table.docutils:not(.field-list)")
.wrap("<div class='wy-table-responsive'></div>");
// Add expand links to all parents of nested ul
$('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
var link = $(this);
expand = $('<span class="toctree-expand"></span>');
expand.on('click', function (ev) {
self.toggleCurrent(link);
ev.stopPropagation();
return false;
});
link.prepend(expand);
});
};
nav.reset = function () {
// Get anchor from URL and open up nested nav
var anchor = encodeURI(window.location.hash);
if (anchor) {
try {
var link = $('.wy-menu-vertical')
.find('[href="' + anchor + '"]');
// If we didn't find a link, it may be because we clicked on
// something that is not in the sidebar (eg: when using
// sphinxcontrib.httpdomain it generates headerlinks but those
// aren't picked up and placed in the toctree). So let's find
// the closest header in the document and try with that one.
if (link.length === 0) {
var doc_link = $('.document a[href="' + anchor + '"]');
var closest_section = doc_link.closest('div.section');
// Try again with the closest section entry.
link = $('.wy-menu-vertical')
.find('[href="#' + closest_section.attr("id") + '"]');
}
$('.wy-menu-vertical li.toctree-l1 li.current')
.removeClass('current');
link.closest('li.toctree-l2').addClass('current');
link.closest('li.toctree-l3').addClass('current');
link.closest('li.toctree-l4').addClass('current');
}
catch (err) {
console.log("Error expanding nav for anchor", err);
}
}
};
nav.onScroll = function () {
this.winScroll = false;
var newWinPosition = this.win.scrollTop(),
winBottom = newWinPosition + this.winHeight,
navPosition = this.navBar.scrollTop(),
newNavPosition = navPosition + (newWinPosition - this.winPosition);
if (newWinPosition < 0 || winBottom > this.docHeight) {
return;
}
this.navBar.scrollTop(newNavPosition);
this.winPosition = newWinPosition;
};
nav.onResize = function () {
this.winResize = false;
this.winHeight = this.win.height();
this.docHeight = $(document).height();
};
nav.hashChange = function () {
this.linkScroll = true;
this.win.one('hashchange', function () {
this.linkScroll = false;
});
};
nav.toggleCurrent = function (elem) {
var parent_li = elem.closest('li');
parent_li.siblings('li.current').removeClass('current');
parent_li.siblings().find('li.current').removeClass('current');
parent_li.find('> ul li.current').removeClass('current');
parent_li.toggleClass('current');
}
return nav;
};
module.exports.ThemeNav = ThemeNav();
if (typeof(window) != 'undefined') {
window.SphinxRtdTheme = { StickyNav: module.exports.ThemeNav };
}
},{"jquery":"jquery"}]},{},["sphinx-rtd-theme"]);
/* sphinx_rtd_theme version 0.4.2 | MIT license */
/* Built 20181005 13:10 */
require=function r(s,a,l){function c(e,n){if(!a[e]){if(!s[e]){var i="function"==typeof require&&require;if(!n&&i)return i(e,!0);if(u)return u(e,!0);var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}var o=a[e]={exports:{}};s[e][0].call(o.exports,function(n){return c(s[e][1][n]||n)},o,o.exports,r,s,a,l)}return a[e].exports}for(var u="function"==typeof require&&require,n=0;n<l.length;n++)c(l[n]);return c}({"sphinx-rtd-theme":[function(n,e,i){var jQuery="undefined"!=typeof window?window.jQuery:n("jquery");e.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(e){var i=this;void 0===e&&(e=!0),i.isRunning||(i.isRunning=!0,jQuery(function(n){i.init(n),i.reset(),i.win.on("hashchange",i.reset),e&&i.win.on("scroll",function(){i.linkScroll||i.winScroll||(i.winScroll=!0,requestAnimationFrame(function(){i.onScroll()}))}),i.win.on("resize",function(){i.winResize||(i.winResize=!0,requestAnimationFrame(function(){i.onResize()}))}),i.onResize()}))},enableSticky:function(){this.enable(!0)},init:function(i){i(document);var t=this;this.navBar=i("div.wy-side-scroll:first"),this.win=i(window),i(document).on("click","[data-toggle='wy-nav-top']",function(){i("[data-toggle='wy-nav-shift']").toggleClass("shift"),i("[data-toggle='rst-versions']").toggleClass("shift")}).on("click",".wy-menu-vertical .current ul li a",function(){var n=i(this);i("[data-toggle='wy-nav-shift']").removeClass("shift"),i("[data-toggle='rst-versions']").toggleClass("shift"),t.toggleCurrent(n),t.hashChange()}).on("click","[data-toggle='rst-current-version']",function(){i("[data-toggle='rst-versions']").toggleClass("shift-up")}),i("table.docutils:not(.field-list,.footnote,.citation)").wrap("<div class='wy-table-responsive'></div>"),i("table.docutils.footnote").wrap("<div class='wy-table-responsive footnote'></div>"),i("table.docutils.citation").wrap("<div class='wy-table-responsive citation'></div>"),i(".wy-menu-vertical ul").not(".simple").siblings("a").each(function(){var e=i(this);expand=i('<span class="toctree-expand"></span>'),expand.on("click",function(n){return t.toggleCurrent(e),n.stopPropagation(),!1}),e.prepend(expand)})},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),i=e.find('[href="'+n+'"]');if(0===i.length){var t=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(i=e.find('[href="#'+t.attr("id")+'"]')).length&&(i=e.find('[href="#"]'))}0<i.length&&($(".wy-menu-vertical .current").removeClass("current"),i.addClass("current"),i.closest("li.toctree-l1").addClass("current"),i.closest("li.toctree-l1").parent().addClass("current"),i.closest("li.toctree-l1").addClass("current"),i.closest("li.toctree-l2").addClass("current"),i.closest("li.toctree-l3").addClass("current"),i.closest("li.toctree-l4").addClass("current"))}catch(o){console.log("Error expanding nav for anchor",o)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,i=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(i),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",function(){this.linkScroll=!1})},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:e.exports.ThemeNav,StickyNav:e.exports.ThemeNav}),function(){for(var r=0,n=["ms","moz","webkit","o"],e=0;e<n.length&&!window.requestAnimationFrame;++e)window.requestAnimationFrame=window[n[e]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[n[e]+"CancelAnimationFrame"]||window[n[e]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(n,e){var i=(new Date).getTime(),t=Math.max(0,16-(i-r)),o=window.setTimeout(function(){n(i+t)},t);return r=i+t,o}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(n){clearTimeout(n)})}()},{jquery:"jquery"}]},{},["sphinx-rtd-theme"]);

View File

@ -4,7 +4,7 @@
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@ -540,6 +540,9 @@ var Search = {
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
if (suffix === undefined) {
suffix = '.txt';
}
$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
dataType: "text",
complete: function(jqxhr, textstatus) {

Some files were not shown because too many files have changed in this diff Show More