Skip to content

sailfishos/oneshot

Repository files navigation

Oneshot
-------

Packages can have scripts installed into file system and they can request such
a script to be run at next boot by creating a link to /etc/oneshot.d/<uid>/

Links created to /etc/oneshot.d/0/ get run at the beginning of the next boot
as root. This happens before user session is started.

Links created to /etc/oneshot.d/<UID>/ get executed during next boot at the
very beginning of the user session and will be executed as the user specifed by
the UID.

Links created to /etc/oneshot.d/newuser/ will be added to user's oneshot
directory after user creation.

Links should be only created through the add-oneshot utility described in the
next section.

oneshot
-------

Executes the scripts found under /etc/oneshot.d/$UID/

Usage: oneshot [--mic]

The --mic option can be used for example when building images from
kickstart files with mic. Setting this option will export MIC_RUN,
which can be checked in the oneshot scriptlets.

add-oneshot
-----------

Adds a oneshot job to be run later or now.

Usage: add-oneshot [--now] [--late] [--user|--all-users|--uid <uid>] [--privileged] [--] <name of the job> [<more job names>]
or:    add-oneshot --new-users [--all-users] [--late] [--privileged] [--] <name of the job> [<more job names>]

If --now is given, job is run immediately instead of postponing it later
If instant run fails or if --now is not given, the link is created for later run
If --user is given, job is run as current user, otherwise as root
If --all-users is given then the job is ran for all users
If --new-users is given then the job is ran for each newly created user
If --uid <uid> is given then that user is used to run the job
If --late is given then job is run after first boot is over (after init-done)
If --privileged is given, job is run in privileged group (unless run as root)
Without --late or --now job is run at the very beginning of the boot or user session
Job names must follow options and you may use -- to specify files beginning with --
Job name is given as name of the executable located in /usr/lib/oneshot.d
ie. no path mentioned

It's almost always wrong to use --user in packaging and it's rarely the right
thing to use --uid <uid>. You should use --all-users possibly with --new-users
instead.

populate-oneshot-dir
--------------------

Populates oneshot directory for new user. This needs to be run when a new user
is created.

groupadd-user
-------------

Packages can create new groups and request that the current user should be
added to that group. They can do this by calling 
/usr/bin/groupadd-user <groupname>, it will add the default user (looked up
from login.defs and passwd) to that group if possible.

During bootstrap this user might not exist yet, in that case the request is
saved, and will be executed through oneshot at the end of image creation, or
at the first device boot.


RPM packaging macros
--------------------

Oneshot scripts should be installed into %{_oneshotdir}

Packages using oneshot macros must BuildRequire oneshot as macros are
located in the oneshot RPM package.

Packages using oneshot functionality must Require oneshot, and use the
%{_oneshot_requires_post} macro to add the necessary Requires(post) dependencies.

Packages using the groupadd functionality must Require oneshot, and use the
%{_oneshot_groupadd_requires_pre} and %{_oneshot_groupadd_requires_post} macros
to add the necessary Requires(pre) and Requires(post) dependencies.

Two convenience-macros are provided as well:

%_system_groupadd groupname adds a system group named groupname
%{_default_uid} contains the lowest UID reserved for users on the system

Example for adding a group for the default user in .spec file:
--------------------------------------------------------------

%{_oneshot_groupadd_requires_pre}
%{_oneshot_groupadd_requires_post}
BuildRequires: oneshot
Requires: oneshot

%pre
%_system_groupadd groupname

%post
/usr/bin/groupadd-user groupname


Example for running a oneshot script in .spec file as user:
-----------------------------------------------------------

%{_oneshot_requires_post}
BuildRequires: oneshot
Requires: oneshot

%post
%{_bindir}/add-oneshot --user sample-script

(A file %{_oneshotdir}/sample-script needs to exist for this to work)