openSUSE:Packaging guidelines
Dit artikel is nog maar gedeeltelijk vertaald. Als u mee wilt helpen met vertalen lees dan Wiki vertalen naar het Nederlands. |
- It is the reviewer's responsibility to point out specific problems with a package and a packager's responsibility to deal with those issues. The reviewer and packager work together to determine the severity of the issues — whether they block a package or can be worked on after the package is in the repository.
- The packaging guidelines are a collection of common issues and the severity that should be placed on them. While these guidelines should not be ignored, they should also not be blindly followed. If you think that your package should be exempt from part of the guidelines, please bring the issue to the openSUSE-packaging mailing list.
- Please also note that, in the Build Service, a lot of the rules will be enforced, or warned about, after a successful build, by a tool called rpmlint. The packager should always check its output to be notified of common packaging errors and to get hints where the packaging could be improved. See Packaging checks for explanations about most of the rpmlint warnings. That page also contains instructions how false positives can be suppressed.
Inhoud
- 1 General guidelines
- 2 Legal
- 3 Package features
- 4 GConf scriptlets
- 5 SuSEfirewall2 Service Definitions
- 6 Licences
- 7 Package types
- 7.1 32bit (baselib) Packages
- 7.2 Branding
- 7.3 Debuginfo
- 7.4 Eclipse Plugins
- 7.5 Emacs
- 7.6 Fonts
- 7.7 Games
- 7.8 GNOME
- 7.9 Haskell
- 7.10 Java
- 7.11 JPackage
- 7.12 Lisp
- 7.13 Mono
- 7.14 Mozilla
- 7.15 OCaml
- 7.16 OpenOffice.org extensions
- 7.17 PAM (Pluggable Authentication Modules)
- 7.18 Perl
- 7.19 PHP
- 7.20 Python
- 7.21 R
- 7.22 Ruby
- 7.23 Libraries
- 7.24 Tcl
- 7.25 Web Applications
General guidelines
There are some general rules that must be followed.
No inclusion of pre-built binaries or libraries
All binaries or libraries included with openSUSE packages must have been built from source code included in the source package. This is a requirement for the following reasons:
- Security: Pre-packaged binaries and libraries not built from source could include anything, malicious or dangerous content, or just being plain broken. Also, these are functionally impossible to patch and bugfix.
- Compiler flags: Pre-packaged binaries and libraries not built from source probably do not have the standard openSUSE compiler flags for security and optimization.
If you are in doubt as to whether something is considered a binary or library, here is some helpful criteria:
- Is it executable? If so, it is probably a binary.
- Does it contain a .so, .so.#, .so.#.# or .so.#.#.# extension? If so, it is probably a library.
- If in doubt, ask on the openSUSE-packaging mailing list.
Packages which require non-open source components to build are also not permitted (e.g. proprietary compiler required).
Exceptions
- Some software (usually related to compilers or cross-compiler environments) cannot be built without the use of a previous toolchain or development environment (open source). If you have a package which meets this criteria, contact the openSUSE Packaging Committee for approval.
- An exception is made for binary firmware, as long as it meets the documented requirements: BinaryFirmware
Bundling of multiple projects
Packages in openSUSE should make every effort to avoid having multiple, separate, upstream projects bundled together in a single package.
Specfile guidelines
The rules that apply to content of specfiles are in a seperate document called the Specfile guidelines.
Architecture support
All openSUSE packages must successfully compile and build into binary RPM files on at least one of the supported architectures, which are i586 and x86_64. The packagers should make every effort to make the package build for both supported architectures. Content — code which does not need to be compiled or built — and architecture independent code (noarch) are notable exceptions.
Relocatable packages
The use of RPM's facility for generating relocatable packages is strongly discouraged. It is difficult to make it work properly, impossible to use from the installer or from zypper and yast, and not generally necessary if other packaging guidelines are followed. However, in the unlikely event that you have a good reason to make a package relocatable, you MUST state this intent and reasoning in the request for package review.
Legal
Banned software
Applications (or other software) listed on the Build Service application blacklist are banned from being packaged.
Licensing
The licensing has to be OSI compliant. The list of Open Source Licenses (Licenses by Name) enumerates these licenses approved by the Open Source Initiative (OSI).
Code vs Content
It is important to make distinction between computer executable code and content. While code is permitted (assuming, of course, that it has an open source compatible license, is not legally questionable, etc.), only some kinds of content are permissible. The rule is:
If the content enhances the user experience, then the content is OK to be packaged in openSUSE. This means, for example, that things like: fonts, themes, clipart, and wallpaper are OK.
Content still has to be reviewed for inclusion. It must have an open source compatible license and must not be legally questionable. In addition, there are several additional restrictions for content:
- Content must not be pornographic, or contain nudity, whether animated, simulated, or photographed. There are better places on the Internet to get porn.
- Content should not be offensive, discriminatory, or derogatory. If you are not sure if a piece of content is one of these things, it probably is.
Some examples of content which is permissable:
- Clipart for use in office suites
- Wallpaper (non-offensive, discriminatory, with permission to freely redistribute)
- Fonts (under an open source license, with no ownership/legal concerns)
- Game levels are not considered content, since games without levels would be non-functional.
- Sound or graphics included with the source tarball that the program or theme uses (or the documentation uses) are acceptable.
- Game music or audio content is permissible, as long as the content is freely distributable without restriction.
- Example files included with the source tarball are not considered content.
Some examples of content which are not permissible:
- Comic book art files
- Religious texts
- mp3 files (patent encumbered)
If you are unsure if something is considered approved content, ask on the openSUSE-packaging mailing list.
Package features
Init scripts
Currently, only SystemV-style initscripts are supported in openSUSE. There are detailed guidelines for SysV-style initscripts at [1].
Desktop files
If a package contains a GUI application, then it needs to also include a properly installed .desktop file. For the purposes of these guidelines, a GUI application is defined as any application which draws an X window and runs from within that window. Installed .desktop files MUST follow the desktop-entry-spec, paying particular attention to validating correct usage of the Name, GenericName, Categories and StartupNotify entries.
Icon tag in Desktop Files
The icon tag has to be the basename of the icon file(s), because it allows for icon theming:
-
Icon=comical
It assumes .png by default, then tries .svg and finally .xpm.
.desktop file creation
If the package does not already include and install its own .desktop file, you need to make your own, and include it as a source (e.g. Source3: %name.desktop
). The contents of a sample .desktop file (comical.desktop) are:
[Desktop Entry] Name=Comical GenericName=Comic Archive Reader Comment=Open .cbr & .cbz files Exec=comical Icon=comical Terminal=false Type=Application Categories=Graphics;
%suse_update_desktop_file usage
It is not simply enough to just include the .desktop file in the package. One MUST run %suse_update_desktop_file
in the %install
section, and have BuildRequires: update-desktop-files
enlisted, to help ensure .desktop file safety and spec-compliance. %suse_update_desktop_file
MUST be used if the package does not install the file or there are changes desired to the .desktop file (such as adding/removing categories, etc). Some examples of usage:
- check desktop file
%suse_update_desktop_file %{name}
- install desktop file and change categories
%suse_update_desktop_file -r %{name} System Utility Core GTK FileManager
Users and Groups
Note that for the moment, we primarily address the case where the mapping from user/group names to uids/gids is decided dynamically by target systems at package install time. Some options for system administrators for making this mapping static even though the package scriptlets use a dynamic scheme are also discussed below, and more are being investigated, including possibilities to make the mapping static at package build time.
To create users and groups in packages, use:
Requires(pre): pwdutils [...] %pre getent group GROUPNAME >/dev/null || groupadd -r GROUPNAME getent passwd USERNAME >/dev/null || useradd -r -g GROUPNAME -d HOMEDIR -s /sbin/nologin -c "user for PACKAGENAME" USERNAME exit 0 [...]
HOMEDIR
should usually be a directory created and owned by the package, with appropriate restrictive permissions. A good choice for the location of the directory is the package's data directory or directory under /var
like /var/cache/NAME
or /var/lib/NAME
, in case it has one.
User accounts created by packages are rarely used for interactive logons, and should thus generally use /bin/false or /sbin/nologin as the user's shell.
The exit 0
at the end will result in the %pre
scriptlet returning success even if the user/group creation fails for some reason. This is suboptimal, but has less potential for system-wide breakage than allowing it to fail. If the user/group is not available at the time the package's payload is unpacked, rpm will fall back to getting those files owned by root.
getent
is run before groupadd
/useradd
, to check whether the user/group that is about to be created already exists, and if so, skip the creation. This is done so to provide a possibility for local system administrators to create the user/group beforehand, in case they wish to get a predefined static UID/GID mapping for those users.
groupadd
/useradd
in %pre is always run — both on initial installs and upgrades. This is made possible by doing the getent
checks above, and should fix things up if the user/group has disappeared after the package to be upgraded was initially installed (just like file permissions get reset on upgrades etc).
Users or groups created by packages are never removed. There is no sane way to check if files owned by those users/groups are left behind — and even if there were, what would we do to them? Leaving those behind with ownerships pointing to then-nonexistent users/groups may result in security issues when a semantically unrelated user/group is created later and reuses the UID/GID. Also, in some setups, deleting the user/group might not be possible or/nor desirable, for example, when using a shared remote user/group database. Cleanup of unused users/groups is left to the system administrators to take care of, if they so desire.
In some cases it is desirable to create only a group without a user account. Usually, this is because there are some system resources to which we want to control access by using that group, and a separate user account would add no value. Examples of common such cases include (but are not limited to) games whose executables are setgid for the purpose of sharing high score files or the like, and/or software that needs exceptional permissions to some hardware devices and it would not be appropriate to grant those to all system users nor even only those logged in on the console. In these cases, apply only the groupadd
parts of the above recipe.
Note that the practice of not creating users/groups if they already exist has a drawback of possibly unrelated but coincidentally same named existing system users and/or groups unnecessarily and undesirably getting access to things in a package that uses the same user/group names. This version of the users/groups guideline does not address that issue in any way, but it is possible that future revisions will if a good enough way to do that is found.
Patches
See Packaging Patches guidelines.
GConf scriptlets
SuSEfirewall2 Service Definitions
Licences
Package types
Some applications have specific guidelines written for them, located on their own pages in the Packaging/ hierarchy.
32bit (baselib) Packages
openSUSE:Build_Service_baselibs.conf
Branding
Debuginfo
Packages should produce useful -debuginfo packages, or explicitly disable them when it is not possible to generate a useful one, but where rpmbuild would do it anyway. Whenever a -debuginfo package is explicitly disabled, an explanation why this was done so is required in the specfile. Debuginfo packages are discussed in more detail in a separate document, [2].
Eclipse Plugins
Emacs
Fonts
Fonts in general-purpose formats such as Type1, OpenType TT (TTF) or OpenType CFF (OTF) are subject to specific packaging guidelines, and should never be packaged in a private application directory instead of the system-wide font repositories. For more information, see: Package layout for fonts.
Games
GNOME
Haskell
Java
JPackage
Lisp
Mono
Mozilla
OCaml
OpenOffice.org extensions
PAM (Pluggable Authentication Modules)
Perl
PHP
Python
R
Ruby
Libraries
openSUSE:Shared library packaging policy
Static Libraries
Packages including libraries should exclude static libraries as far as possible (e.g. by configuring with the --disable-static switch). Static libraries should only be included in exceptional circumstances. Applications linking against libraries should, as far as possible, link against shared libraries, not static versions.
Libtool archives, foo.la files, should not be included. Packages using libtool will install these by default even if you configure with --disable-static, so they may need to be removed before packaging. Due to bugs in older versions of libtool or bugs in programs that use it, there are times when it is not always possible to remove *.la files without modifying the program. In most cases, it is fairly easy to work with upstream to fix these issues. Note that if you are updating a library in a stable openSUSE release and the package already contains *.la files, removing the *.la files should be treated as an API/ABI change, in other words, removing them changes the interface that the library gives to the rest of the world and should not be undertaken lightly.
Exception
We want to be able to track which packages are using static libraries so we can find which packages need to be rebuilt if a security flaw in a static library is fixed, for instance. If you really need to package static libraries, you have to follow this guideline.
Static libraries must be placed in a *-devel-static subpackage, which Requires
the *-devel subpackage. Separating the static libraries from the other development files in *-devel allow us to track this usage by checking which packages BuildRequire
the *-devel-static package. The intent is that, whenever possible, packages will move away from using these static libraries, to the shared libraries. When a package only provides static libraries, skip the Requires
on the *-devel subpackage. Packages which explicitly need to link against the static version must then BuildRequire: foo-devel-static
, so that the usage can be tracked.
If (and only if) a package has shared libraries which require static libraries to be functional, the static libraries can be included in the *-devel subpackage. The devel subpackage must have a virtual Provide for the *-devel-static package, and packages dependent on it must BuildRequire
the *-devel-static package.
Duplication of system libraries
For several reasons, a package should not include or build against a local copy of a library that exists on a system. The package should be patched to use the system libraries. This prevents old bugs and security holes from living on after the core system libraries have been fixed.
Tcl
Web Applications
Web applications packaged in openSUSE should put their content into /srv/www/%name</ttt> and NOT into <tt>/var/www. This is done because:
- /var is supposed to contain variable data files and logs. /srv/www is much more appropriate for this.
- Users may already have content in /var/www, and we do not want any openSUSE package to step on top of that.
- /var/www is no longer specified by the Filesystem Hierarchy Standard.