7 Using Source Services #
7.1 About 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.
Source services allow:
Server-side generated files are easy to identify and are not modifiable by the user. This way, other users can trust them to be generated in the documented way without modifications.
Generated files never create merge conflicts.
Generated files are a separate commit to the user change.
Source services are runnable at any time without user commit.
Source services are runnable on server and client side in the same way.
Source services are safe. A source checkout and service run never harms the system of a user.
Source services avoid unnecessary commits. This means there are no time-dependent changes. In case the package already contains the same file, the newly generated file is dropped.
Source services running local or inside the build environment can get created, added and used by everybody.
Source services running in default or server side mode must be installed by the administrator of the OBS server.
The use of a source service can be defined per package or project wide.
For using source services you need (refer to Example 7.1, “Structure of a _service
File”):
An XML file named
_service
.A root element
services
.A
service
element which uses the specific service with optional parameters.
_service
File #<services> 1
<service name="MY_SCRIPT"2 mode="MODE"3>
<param name="PARAMETER1">PARAMETER1_VALUE</param>4
</service>
</services>
The example above will execute the script:
/usr/lib/obs/service/MY_SCRIPT
--PARAMETER1 PARAMETER1_VALUE --outdir DIR
7.2 Modes of Source Services #
Each source service can be used in a mode defining when it should run and how to use the result. This can be done per package or globally for an entire project.
Mode | Runs remotely | Runs locally | Added File Handling |
---|---|---|---|
Default | After each commit | Before local build | Generated files are prefixed with _service: |
trylocal | Yes | Yes | Changes are merged into commit |
localonly | No | Yes | Changes are merged into commit |
serveronly | Yes | No | Generated files are prefixed with _service:
This can be useful, when the service is not available or can not
work on developer workstations.
|
buildtime | During each build before calling the build tool (for example, rpm-build)[a]The service package must be available for building. | ||
manual | No | Only via explicit CLI call | Exists since OBS 2.11 |
disabled | No | Only via explicit CLI call | |
[a] A side effect is that the service package is becoming a build dependency and must be available. |
- 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.
trylocal
ModeThis mode is running the service locally. The result is committed as standard files and not named with a
_service:
prefix. Additionally, the service runs on the server by default. Usually the service should detect that the result is the same and skip the generated files. In case they differ, they are generated and added on the server.localonly
ModeThis mode is running the service locally. 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.serveronly
ModeThe serveronly mode is running the service on the server only. This can be useful, when the service is not available or can not work on developer workstations.
buildtime
ModeThe service is running inside of the build job, both 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).
manual
Mode,disabled
ModeThe manual mode is neither running the service locally nor on the server side by default. 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 rundisabled
. The result will get committed as standard files again. NOTE: it did only exist as "disabled" before OBS 2.11, but "manual" is the better matching alias name for its usage. The osc client may do have different behaviour in future between manual and disabled.
7.3 Defining Source Services for Validation #
Source services can be used to validate sources. This can be defined at different levels:
Per Package. Useful when the packager wants to validate whether the downloaded sources are really from the original maintainer.
Per Project. Useful for applying project-wide policies which cannot be skipped for any package.
You can validate sources using either of two methods:
By comparing checksums and metadata of the files in your repository with checksums and metadata as recorded by the maintainer.
Alternatively, you can download the sources from a trusted location again and verify that they did not change.
7.4 Creating Source Service Definitions #
Source services are defined in the _service
file
and are either part of the package sources or used project-wide.
Project-wide services are stored under the _project
package
in file _service
.
The _service
file contains a list of services
which get called in the listed order. Each service can define a list of
parameters and a mode.
The project wide services get called after the per package defined
services.
The _service
file is in XML format and looks like this:
<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>
</services>
With the example above, the services above are executed in the following order:
Downloads the file via the
download_files
service using the URL from the Spec file. When using osc, the downloaded file gets committed as part of the commit.Compares the downloaded file (
krabber-1.0.tar.gz
) against the SHA256 checksum.
7.5 Removing a Source Service #
Sometimes it is useful to continue working 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
.
7.6 Trigger a service run via a webhook #
You may want to update sources in Open Build Service whenever they change in a SCM system. You can create a token which allows to trigger a specific package update and use it via a webhook. It is recommended to create a token for a specific package and not a wildcard token. Read Chapter 36, Authorization to learn how to create a token.
7.6.1 Creating a webhook on GitLab #
Go to your repository settings page in your gitlab instance. Select Integrations there. All what you need to fill is the URL
https://YOUR_INSTANCE/trigger/runservice
and the Secret Token. Hit the
button and you are good. You may specify project and package via CGI parameters in case you created a wildcard token:https://YOUR_INSTANCE/trigger/runservice?project=PROJECT&package=PACKAGE
7.6.2 Creating a webhook on GitHub #
Go to your repository settings page of your repository on github.com. Select Webhooks settings and create a hook via
button. Define the payload URL ashttps://YOUR_INSTANCE/trigger/webhook?id=$TOKEN_ID
and fill the secret box with your token string. Please note that github requires that you must also define the token id as part of the webhook string. All other settings can stay untouched and just hit the
button.