6 Source Services

Source Services are tools to validate, generate or modify sources in a trustable way. They are designed as smallest possible tools and can be combined following the powerful idea of the classic UNIX design.

Design goals of source services were:

  • server side generated files must be easy to identify and must not be modifiable by the user. This way others user can trust them to be generated in the documented way without modifications.

  • generated files must never create merge conflicts

  • generated files must be a separate commit to the user change

  • services must be runnable at any time without user commit

  • services must be runnable on server and client side in the same way

  • services must be designed in a safe way. A source checkout and service run must never harm the system of a user.

  • services shall be designed in a way to avoid unnecessary commits. This means there shall be no time-dependent changes. In case the package already contains the same file, the newly generated file must be dropped.

  • local services can be added and used by everybody.

  • server side services must be installed by the admin of the OBS server.

  • service can be defined per package or project wide.

6.1 Using Services for Validation

Source Services may be used to validate sources. This can happen per package, which is useful when the packager wants to validate that downloaded sources are really from the original maintainer. Or validation can happen for an entire project to apply general policies. These services cannot get skipped in any package

Validation can happen by validating files (for example using the verify_file or source_validator service. These services just fail in the error case which leads to the build state "broken". Or validation can happen by redoing a certain action and store the result as new file as download_files is doing. In this case the newly generated file will be used instead of the committed one during build.

6.2 Different Modes of Services

Each service can be used in a special mode defining when it should run and how to use the result. This can be done per package or globally for an entire project.

6.2.1 Default Mode

The default mode of a service is to always run after each commit on the server side and locally before every local build.

6.2.2 trylocal Mode

The trylocal mode is running the service locally when using current osc versions. The result gets committed as standard files and not named with _service: prefix. Additionally the service runs on the server by default, but usually the service should detect that the result is the same and skip the generated files. In case they differ for any reason (because the Web UI or API was used for example), they get generated and added on the server.

6.2.3 localonly Mode

The localonly mode is running the service locally when using current osc versions. The result gets committed as standard files and not named with _service: prefix. The service is never running on the server side. It is also not possible to trigger it manually.

6.2.4 serveronly Mode

The serviceonly mode is running the service on the service only. This can be useful, when the service is not available or can not work on developer workstations.

6.2.5 buildtime Mode

The service is running inside of the build job, for local and server side builds. A side effect is that the service package is becoming a build dependency and must be available. Every user can provide and use a service this way in their projects. The generated sources are not part of the source repository, but part of the generated source packages. Note that services requiring external network access are likely to fail in this mode, because such access is not available if the build workers are running in secure mode (as is always the case at https://build.opensuse.org).

6.2.6 disabled Mode

The disabled mode is neither running the service locally or on the server side. It can be used to temporarily disable the service but keeping the definition as part of the service definition. Or it can be used to define the way how to generate the sources and doing so by manually calling osc service disabledrun The result will get committed as standard files again.

6.3 Storage of Source Service Definitions

The called services are always defined in a _service file. It is either part of the package sources or used project-wide when stored inside the _project package.

The _service file contains a list of services which get called in this order. Each service may define a list of parameters and a mode. The project wide services get called after the per package defined services. The _service file is an XML file like this example:

<services>
  <service name="download_files" mode="trylocal" />
  <service name="verify_file">
    <param name="file">krabber-1.0.tar.gz</param>
    <param name="verifier">sha256</param>
    <param name="checksum">7f535a96a834b31ba2201a90c4d365990785dead92be02d4cf846713be938b78</param>
  </service>
  <service name="update_source" mode="disabled" />
</services>

This example downloads the files via download_files service via the given URLs from the spec file. When using osc this file gets committed as part of the commit. Afterwards the krabber-1.0.tar.gz file will always be compared with the sha256 checksum. And last but not least there is the update_source service mentioned, which is usually not executed. Except when osc service disabledrun is called, which will try to upgrade the package to a newer source version available online.

6.4 Dropping a Source Service Again

Sometimes it is useful to continued to work on generated files manually. In this situation the _service file needs to be dropped, but all generated files need to be committed as standard files. The OBS provides the "mergeservice" command for this. It can also be used via osc by calling osc service merge.

6.5 Defining a Source Service

To define a source service add a service section to the _service file of the project. Within this section, define a script and its arguments that will be called by the source service. The script needs to reside in /usr/lib/obs/service.

<services>
 <service name="MY_SCRIPT">
  <param name="PARAMETER1">PARAMETER1_VALUE</param>
 </service>
</services>

The example above will execute the following command:

/usr/lib/obs/service/ MY_SCRIPT \
--PARAMETER1 PARAMETER1_VALUE --outdir DIR

6.6 Interfaces for Using Source Services

..

Print this page