Skip to content

Latest commit

 

History

History
428 lines (303 loc) · 8.75 KB

files.md

File metadata and controls

428 lines (303 loc) · 8.75 KB

Adding packages and files

Adding packages to the current (open)SUSE installation

Starting with openSUSE 13.1 and SLE12, the easiest way to include a package in the installation system is modifying the installation-images package in the Open Build Service. That package evaluates the dependencies and automatically adds the required packages. Simply add the needed packages as a BuildRequires dependency to the respective package and that's it.

Modifying the list of files

The method explained above is only useful in some scenarios. It's not suitable to update older systems, already released product or the rescue image. Moreover it does not help if you want to remaster the images locally. Last but not least, it only works for full packages, but it's often useful to include just a subset of the files in a given package.

For every generated image there is a subdirectory in the data directory. Among other several things, those directories contain files with the extension .file_list. In order to fine tune the content of the generated images, just modify the corresponding .file_list file according to the syntax described below.

The output of tree shows the .file_list we're talking about.

#tree data -P "*.file_list"

data
├── base
│   └── base.file_list
├── boot
│   ├── boot.file_list
...
├── cd1
│   ├── cd1.file_list
...
├── initrd
...
│   ├── initrd.file_list
...

Keep in mind that in order to make sure the images still can be generated in the Open Build Service, it's necessary to add the corresponding BuildRequires to the installation-images package.

Format of the file list

Comments

Lines starting with '#' are comments, empty lines are ignored. Example:

 # some comment

Including other files

You can include other files with the following syntax, where FILE is relative to the data/*/ tree.

include FILE

Conditional sections

You can use if/elsif/else/endif with the following syntax.

if EXPRESSION

EXPRESSION is more or less a valid perl expression except that variables don't have a starting '$' and are implicitly environment variables. The only exceptions to this are abuild and arch.

Also, you can use exists(PACKAGE) to test for a specific package or exists(PACKAGE, FILE) to test for a file in a package or exists(PACKAGE, FILE, TYPE) to test for a file of a specific type.

Note that the test for FILE is made in the unpacked rpm stored in the internal cache. So unless it's an absolute path you can walk out of the root tree. This can be used to check for the existence of rpm scripts (they are cached one level up). Looking at the cache in tmp/cache/PRODUCT/RPMNAME might make this clearer.

Examples:

if arch eq 'ppc' && theme eq 'SLES'
# ...
elsif arch eq 'sparc'
# ...
else
# ...
endif 

# only if package foo exists
if exists(foo)
# ...
endif

# only if package foo has a file /usr/bin/bar
if exists(foo, usr/bin/bar)
# ...
endif

# only if package foo has a link /usr/bin/bar
if exists(foo, usr/bin/bar, l)
# ...
endif

# only if package foo has a postin script
if exists(foo, ../postin)
# ...
endif

Environment variables

You can set environment variables:

MyVar1 = package-xxx
MyVar2 = "Value With Spaces"

and use them everywhere by putting the variable name between '<' and '>':

  <MyVar1>:
  MyVar3 = <MyVar2>

Packages

This syntax can be used to include files from a given package.

PACKAGE_NAME: [direct|ignore|nodeps|requires]

It unpacks the selected package into a temporary directory.

You can add tags (comma-separated) after the colon. The following tags are supported:

  • requires: create a file PACKAGE_NAME.requires in the image root
  • nodeps: ignore package dependencies when solving
  • ignore: ignore package ('BuildIgnore')
  • direct: run rpm command to install the package

PACKAGE_NAME may be empty which can be used to tell the parser that subsequent lines do not belong to any package.

PACKAGE_NAME can contain '*'s. In that case the latest package version is used. If PACKAGE_NAME ends in '~' the last but one version is used.

If PACKAGE_NAME starts with a '?', the package is optional. This is a handy shortcut if you'd otherwise use an if with exists().

If you use 'direct', basically rpm -i PACKAGE_NAME is run to install the package. This means that all scripts are run and all files are unpacked. If you don't need all files from the package you can still use 'r' to remove the parts you don't need later.

Examples:

?grub:
glibc:
systemd: ignore

Including packages matching a regexp

To include a group of packages matching a regexp, use add_all:

add_all PACKAGE_REGEXP:

Examples:

add_all skelcd-control-.*:

Note that you cannot associate any actions to such an entry directly. Use templates (see below) if you don't want to install the packages as a whole.

Actions

Several actions can be specified using the following syntax:

<action> <arg1> <arg2> ...

Do the specified action. <action> is one of these:

  • Add the file/directory tree to the image:
  <args>
^ there's a space!
  • Add a file/directory with a different name
m <old_name> <new_name>
  • Same as 'm', but link files
L <old_name> <new_name>
  • Same as 'm', but follows symlinks
a <old_name> <new_name>
  • Add optional files (e.g. some modules in initrd)
M <old_name> <new_name>
  • Add and gunzip files
g <src> <dst>
  • Remove a file/directory tree
r <args>
  • Create directories:
d <args>
  • Create a named pipe:
n <name>
  • Touch a file
t <args>
  • Strip
S <args>
  • Hard link (<args> as for the ln command)
l <args>
  • Symlink
s <args>
  • Apply a patch from the data/*/ tree. The patch must not contain absolute path names!
p <patch>
  • Copy package file (the rpm itself) to directory.
P <dir>
  • chown/chmod files
c <perm> <owner> <group> <args>
  • Make block device
  b <major> <minor> <name>
  • Make char device
C <major> <minor> <name>
  • Add some extra files. That is, add files not from packages but from the data/*/ directory.
  x <src> <dst>
  • Append <src> to <dst>; <src> is from the data/*/ directory.
  A <src> <dst>
  • Execute a program/rpm-script. The program or script is run from within the 'base' environment. $PWD will be at the root of the filesystem which is currently built
  e <program> <arg1> <arg2> ...
  e <script>
  • Execute a program/rpm-script (with chroot). The program/script is run within a chroot env. <script> must be one of the scripts given after the package name.
  E <program> <arg1> <arg2> ...
  E <script>
  • Apply a perl regexp in a sed-like fashion to a file, <regexp> may contain white space but not <file>. If this is a multi line regexp (ends with /s) it is applied to the whole file. Otherwise the regexp is applied to each line.

    Note: <file> must not be an absolute symlink!

  R <regexp> <file>
  • Search for a file <name> below <dir> and copy it to <dst> (<dst> may be omitted)
  f <dir> <name> <dst>
  • search for a file <name> (in the local system!) below <dir> and copy it to <dst> (<dst> may be omitted)
  F <dir> <name> <dst>
  • add files from the local system (This should be used only for testing!)
  X <src> <dst>
  • Allow dangling symlink. Sometimes a symlink is ok because it points to a different image which can't be verified automatically.
  D <from> <to>

Templates of packages

You can specify templates that are applied to groups of packages automatically unless there is already some other valid entry for that package. E.g.

TEMPLATE rubygem-.*:
  /usr/*/ruby/gems/*/gems/*/lib
  /usr/*/ruby/gems/*/specifications

The argument after TEMPLATE is a perl regexp matched agaist package names. If the regexp is empty the TEMPLATE matches every package. This can be used to formulate a default action for packages. E.g.

TEMPLATE:
  /

The package is matched against all templates in the order they appear in the file list and the first match is used.

Note that the template should contain some action (it should not be empty) because otherwise the matching will continue. If you don't need any action use something inconspicuous, e.g. 'd .'.

Resolving dependencies

You can resolve dependencies and add the missing packages with the AUTODEPS placeholder. The solver is run only if there is an AUTODEPS entry somewhere.

AUTODEPS:

If you don't specify any actions in AUTODEPS, templates are applied to each individual package.