genode/repos/gems/run/sculpt.run
Norman Feske 8ecc258d3f sculpt: introduce runtime priorities
This patch adds 4 priority levels to the runtime subsystem. The highest
priority is used for components that are critical for the operation of
Sculpt, in particular the Leitzentrale GUI. All regularly deployed
components are assigned the lowest priority by default.

With priorities available in the runtime subsystem, this patch flattens
the priority levels at the top-level init to only two levels and
overlays the priority bands of the drivers, leitzentrale, and runtime
subsystems into one priority band. This has three benenfits:

- This change prevents the starvation of the Leitzentrale GUI from a
  spinning high-priority driver (issue #3997).

- The change will also ease the hosting of latency-critical components
  in the runtime subsystem that are prioritized higher than regular
  components, the storage stack, and the network stack.

- The Leitzentrale GUI remains always perfectly responsive regardless
  of the workloads deployed from packages. In the previous version,
  the runtime graph was sometimes stuttering on high system load.

Issue #4045
2021-03-12 12:01:39 +01:00

682 lines
24 KiB
Plaintext

if {![have_board pc] && ![have_board imx8q_evk]} {
puts "Platform is unsupported.";
exit 0;
}
if {[have_spec nova]} {
proc kernel_output { } { return "novga serial logmem" }
}
create_boot_directory
import_from_depot [depot_user]/src/[base_src] \
[depot_user]/pkg/sculpt-[board]
proc config_system_content {} { return {\
<!-- supported states: "poweroff" or "reset" when acpica started -->
<!-- Note: power down your persistent Genode applications & VMs beforehand on your own ! -->
<system state=""/>} }
proc nic_drv {} {
if {[have_board pc]} { return ipxe_nic_drv }
if {[have_board imx8q_evk]} { return fec_nic_drv }
puts "\n Run script is not supported on this platform. \n";
exit 0;
}
install_config {
<config prio_levels="2">
<parent-provides>
<service name="ROM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="TRACE"/>
<service name="VM"/>
</parent-provides>
<affinity-space width="2" height="1"/>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="100"/>
<resource name="RAM" preserve="2M"/>
<start name="timer" priority="0">
<resource name="RAM" quantum="1M"/>
<resource name="CPU" quantum="10"/>
<provides><service name="Timer"/></provides>
</start>
<start name="report_rom" priority="0">
<binary name="report_rom"/>
<resource name="RAM" quantum="2M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="no">
<policy label="leitzentrale_config -> leitzentrale"
report="global_keys_handler -> leitzentrale"/>
<policy label="pointer -> hover" report="nitpicker -> hover"/>
<policy label="pointer -> xray"
report="global_keys_handler -> leitzentrale"/>
<policy label="pointer -> shape" report="shape"/>
<policy label="clipboard -> focus" report="nitpicker -> focus"/>
<policy label="drivers -> capslock" report="global_keys_handler -> capslock"/>
<policy label="runtime -> capslock" report="global_keys_handler -> capslock"/>
<policy label="drivers -> numlock" report="global_keys_handler -> numlock"/>
<policy label="runtime -> clicked" report="nitpicker -> clicked"/>
<policy label="nit_focus -> leitzentrale"
report="global_keys_handler -> leitzentrale"/>
<policy label="nit_focus -> slides"
report="global_keys_handler -> slides"/>
<policy label="nit_focus -> hover" report="nitpicker -> hover"/>
<policy label="slides_gui_fb_config -> slides"
report="global_keys_handler -> slides"/>
</config>
</start>
<start name="report_logger" priority="0">
<binary name="report_rom"/>
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="yes"/>
</start>
<start name="config_fs" caps="200" priority="0">
<binary name="vfs"/>
<resource name="RAM" quantum="12M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs>
<ram/>
<import>
<dir name="managed">
<rom name="fonts" label="fonts.config"/>
<rom name="fb_drv" label="fb_drv.config"/>
<rom name="wifi" label="wifi.config"/>
<rom name="installation"/>
<rom name="runtime" label="empty_runtime.config"/>
<rom name="event_filter" label="event_filter.config"/>
<inline name="depot_query"><query/></inline>
</dir>
<rom name="event_filter" label="event_filter.config"/>
<rom name="fb_drv" label="fb_drv.config"/>
<rom name="nitpicker" label="nitpicker.config"/>
<rom name="numlock_remap" label="numlock_remap.config"/>
<rom name="leitzentrale" label="leitzentrale.config"/>
<rom name="drivers" label="drivers.config"/>
<rom name="deploy" label="manual_deploy.config"/>
<rom name="usb" label="usb.config"/>
<rom name="clipboard" label="clipboard.config"/>
<rom name="en_us.chargen"/>
<rom name="de_ch.chargen"/>
<rom name="de_de.chargen"/>
<rom name="fr_ch.chargen"/>
<rom name="fr_fr.chargen"/>
<rom name="special.chargen"/>
<rom name="vimrc"/>
<tar name="launcher.tar"/>
<inline name="system">} [config_system_content] {
</inline>
</import>
</vfs>
<policy label="config_fs_rom -> " root="/" />
<policy label="rw" root="/" writeable="yes" />
</config>
</start>
<start name="config_fs_rom">
<binary name="fs_rom"/>
<resource name="RAM" quantum="10M"/>
<provides> <service name="ROM"/> </provides>
<route>
<service name="File_system"> <child name="config_fs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="report_fs_rom">
<binary name="fs_rom"/>
<resource name="RAM" quantum="3M"/>
<provides> <service name="ROM"/> </provides>
<route>
<service name="File_system"> <child name="report_fs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="report_fs">
<binary name="vfs"/>
<resource name="RAM" quantum="16M"/>
<provides> <service name="File_system"/> </provides>
<config>
<vfs>
<ram/>
<import>
<inline name="log">### start ###</inline>
<dir name="runtime">
<inline name="state"><empty/></inline>
<dir name="wifi_drv">
<inline name="accesspoints"><empty/></inline>
<inline name="state"> <empty/></inline>
</dir>
<dir name="nic_router"> <inline name="state"> <empty/></inline> </dir>
<dir name="update"> <inline name="state"> <empty/></inline> </dir>
<dir name="depot_query"><inline name="blueprint"><empty/></inline> </dir>
</dir>
</import>
</vfs>
<policy label="fs_report -> " root="/" writeable="yes"/>
<policy label="log_terminal -> " root="/" writeable="yes"/>
<policy label="report_fs_rom -> " root="/"/>
<policy label="ro" root="/"/>
</config>
</start>
<start name="log_terminal">
<binary name="file_terminal"/>
<resource name="RAM" quantum="2M"/>
<provides> <service name="Terminal"/> </provides>
<config>
<default-policy filename="log" />
<vfs> <dir name="dev"> <log/> </dir> <fs/> </vfs>
<libc stdout="/dev/log"/>
</config>
<route>
<service name="File_system"> <child name="report_fs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="log">
<binary name="terminal_log"/>
<resource name="RAM" quantum="1M"/>
<provides> <service name="LOG"/> </provides>
<config/>
<route>
<service name="Terminal"> <child name="log_terminal"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="log_core">
<resource name="RAM" quantum="1M"/>
<config period_ms="2000"/>
<route>
<service name="ROM" label="log"> <parent label="core_log"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="LOG" label="log"> <child name="log" label="core"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="log_kernel">
<binary name="log_core"/>
<resource name="RAM" quantum="1M"/>
<config period_ms="2000"/>
<route>
<service name="ROM" label="log"> <parent label="kernel_log"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="LOG" label="log"> <child name="log" label="kernel"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="fs_report">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> </provides>
<config> <vfs> <fs/> </vfs> </config>
<route>
<service name="File_system"> <child name="report_fs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="drivers" caps="3150" priority="-1" managing_system="yes">
<resource name="RAM" quantum="128M"/>
<resource name="CPU" quantum="40"/>
<binary name="init"/>
<route>
<service name="LOG"> <child name="log"/> </service>
<service name="ROM" label="config">
<child name="config_fs_rom" label="drivers"/> </service>
<service name="ROM" label_last="capslock"> <child name="report_rom"/> </service>
<service name="ROM" label_last="event_filter.config">
<child name="config_fs_rom" label="managed/event_filter"/> </service>
<service name="ROM" label_prefix="event_filter" label_suffix=".chargen">
<child name="config_fs_rom"/> </service>
<service name="ROM" label_last="fb_drv.config">
<child name="config_fs_rom" label="managed/fb_drv"/> </service>
<service name="ROM" label_last="numlock_remap.config">
<child name="config_fs_rom" label="numlock_remap"/> </service>
<service name="ROM" label_last="usb_policy">
<child name="config_fs_rom" label="usb"/> </service>
<service name="ROM" label_last="numlock"> <child name="report_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<service name="Report"> <child name="fs_report"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides>
<service name="Block"/>
<service name="Usb"/>
<service name="Platform"/>
<service name="Rtc"/>
</provides>
</start>
<start name="nitpicker" caps="1000" priority="0">
<resource name="RAM" quantum="6M"/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<route>
<service name="ROM" label="config">
<child name="config_fs_rom" label="nitpicker"/> </service>
<service name="ROM" label="focus">
<child name="nit_focus"/> </service>
<service name="Report" label="keystate">
<child name="report_logger"/> </service>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<!-- override user focus when leitzentrale is active -->
<start name="nit_focus" priority="-1">
<binary name="rom_filter"/>
<resource name="RAM" quantum="1M"/>
<provides> <service name="ROM"/> </provides>
<config>
<input name="lockscreen_enabled" rom="hover" node="hover">
<attribute name="label" /> </input>
<input name="leitzentrale_enabled" rom="leitzentrale" node="leitzentrale">
<attribute name="enabled" /> </input>
<input name="slides_enabled" rom="slides" node="slides">
<attribute name="enabled" /> </input>
<output node="focus">
<if>
<has_value input="lockscreen_enabled" value="lock_screen" />
<then>
<attribute name="label" value="lock_screen"/>
</then>
<else>
<if>
<has_value input="leitzentrale_enabled" value="yes" />
<then>
<attribute name="label" value="leitzentrale -> manager -> fader -> "/>
</then>
<else>
<if>
<has_value input="slides_enabled" value="yes" />
<then>
<attribute name="label" value="slides"/>
</then>
<else>
<attribute name="label" value="runtime -> focus"/>
</else>
</if>
</else>
</if>
</else>
</if>
</output>
</config>
<route>
<service name="ROM" label="hover"> <child name="report_rom"/> </service>
<service name="ROM" label="leitzentrale"> <child name="report_rom"/> </service>
<service name="ROM" label="slides"> <child name="report_rom"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="pointer" priority="-1">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Report"/> </provides>
<config shapes="yes"/>
<route>
<service name="Gui"> <child name="nitpicker"/> </service>
<service name="ROM" label="hover"> <child name="report_rom"/> </service>
<service name="ROM" label="xray"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="global_keys_handler" priority="-1">
<resource name="RAM" quantum="1M"/>
<config>
<bool name="leitzentrale" initial="yes"/>
<bool name="capslock" initial="no"/>
<bool name="numlock" initial="no"/>
<bool name="slides" initial="no"/>
<press name="KEY_PRESENTATION" bool="slides" change="toggle"/>
<press name="KEY_DASHBOARD" bool="leitzentrale" change="toggle"/>
<press name="KEY_CAPSLOCK" bool="capslock" change="toggle"/>
<press name="KEY_NUMLOCK" bool="numlock" change="toggle"/>
<report name="leitzentrale"> <bool name="leitzentrale"/> </report>
<report name="capslock"> <bool name="capslock"/> </report>
<report name="numlock"> <bool name="numlock"/> </report>
<report name="slides"> <bool name="slides"/> </report>
</config>
<route>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Gui"> <child name="nitpicker"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="leitzentrale_config" priority="-1">
<binary name="rom_filter"/>
<resource name="RAM" quantum="1M"/>
<provides><service name="ROM"/></provides>
<route>
<service name="ROM" label="leitzentrale"> <child name="report_rom"/> </service>
<service name="ROM" label="config">
<child name="config_fs_rom" label="leitzentrale"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="clipboard" priority="-1">
<resource name="RAM" quantum="2M"/>
<provides>
<service name="ROM"/> <service name="Report"/>
</provides>
<route>
<service name="ROM" label="config">
<child name="config_fs_rom" label="clipboard"/> </service>
<service name="ROM" label="focus"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="leitzentrale" caps="2350" priority="-1">
<binary name="init"/>
<resource name="RAM" quantum="130M"/>
<affinity xpos="1" width="1"/> <!-- decouple leitzentrale from boot CPU -->
<provides>
<service name="Gui"/>
<service name="File_system"/> <!-- fonts -->
<service name="ROM"/> <!-- view dialog ROMs -->
<service name="Report"/> <!-- view hover reports -->
</provides>
<route>
<service name="LOG"> <child name="log"/> </service>
<service name="ROM" label="config">
<child name="leitzentrale_config"/> </service>
<service name="ROM" label_prefix="report -> ">
<child name="report_fs_rom"/> </service>
<service name="ROM" label_prefix="manager -> report -> ">
<child name="report_fs_rom"/> </service>
<service name="ROM" label_prefix="manager -> config -> ">
<child name="config_fs_rom"/> </service>
<service name="ROM" label_prefix="config -> ">
<child name="config_fs_rom"/> </service>
<service name="ROM" label="manager -> nitpicker_hover">
<child name="report_rom"/> </service>
<service name="Report"> <child name="fs_report"/> </service>
<service name="Gui"> <child name="nitpicker"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="File_system" label="config">
<child name="config_fs" label="rw"/> </service>
<service name="File_system" label="report">
<child name="report_fs" label="ro"/> </service>
<service name="File_system" label="report">
<child name="report_fs" label="ro"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="runtime" caps="50000" priority="-1">
<binary name="init"/>
<resource name="RAM" quantum="32G"/>
<resource name="CPU" quantum="40"/>
<route>
<service name="ROM" label="config">
<child name="config_fs_rom" label="managed/runtime"/> </service>
<service name="ROM" label_prefix="config -> ">
<child name="config_fs_rom"/> </service>
<service name="ROM" label="capslock">
<child name="report_rom"/> </service>
<service name="ROM" label="clicked">
<child name="report_rom"/> </service>
<service name="File_system" label="config">
<child name="config_fs" label="rw"/> </service>
<service name="File_system" label="report">
<child name="report_fs" label="ro"/> </service>
<service name="Block"> <child name="drivers"/> </service>
<service name="Usb"> <child name="drivers"/> </service>
<service name="Platform" label_prefix="acpica">
<child name="drivers" label="acpica"/> </service>
<service name="Platform"> <child name="drivers"/> </service>
<service name="Rtc"> <child name="drivers"/> </service>
<service name="Gui" label_prefix="leitzentrale">
<child name="leitzentrale"/> </service>
<service name="Gui" label="backdrop">
<child name="nitpicker" label="backdrop"/> </service>
<service name="Gui" label="lock_screen">
<child name="nitpicker" label="lock_screen"/> </service>
<service name="Gui"> <child name="nitpicker"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Report" label_suffix="-> shape"> <child name="pointer"/> </service>
<service name="Report" label="inspect -> clipboard">
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
<service name="Report" label="editor -> clipboard">
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
<service name="ROM" label="inspect -> clipboard">
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
<service name="ROM" label="editor -> clipboard">
<child name="clipboard" label="leitzentrale -> manager -> fader -> -> clipboard"/> </service>
<service name="Report" label_suffix="-> clipboard"> <child name="clipboard"/> </service>
<service name="ROM" label_suffix="-> clipboard"> <child name="clipboard"/> </service>
<service name="Report" label_prefix="leitzentrale ->">
<child name="leitzentrale"/> </service>
<service name="ROM" label_prefix="leitzentrale ->">
<child name="leitzentrale"/> </service>
<service name="File_system" label="leitzentrale -> fonts">
<child name="leitzentrale" label="fonts"/> </service>
<service name="Report"> <child name="fs_report"/> </service>
<service name="LOG" label="unlogged"> <parent/> </service>
<service name="LOG"> <child name="log"/> </service>
<service name="ROM" label="nic_drv"> <parent label="} [nic_drv] {"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
</config>}
foreach file [glob "[genode_dir]/repos/gems/run/sculpt/*.config"] {
file copy -force $file [run_dir]/genode/ }
#
# Override files normally obtained from depot archive with the most current
# version found in the Genode source tree. This way, we don't need to
# rebuild the corresponding depot archives each time we tweak one of the
# files. This is just a hack to accelerate the work flow.
#
file copy -force [genode_dir]/repos/gems/recipes/pkg/sculpt/README [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/run/sculpt/vimrc [run_dir]/genode/
foreach file { en_us.chargen de_ch.chargen de_de.chargen fr_ch.chargen fr_fr.chargen special.chargen } {
file copy -force [genode_dir]/repos/os/src/server/event_filter/$file \
[run_dir]/genode/$file }
file copy -force [genode_dir]/repos/gems/recipes/raw/depot_download/depot_download.config \
[run_dir]/genode/depot_download.config
file copy -force [genode_dir]/VERSION [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/src/app/backdrop/genode_logo.png [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/run/sculpt/drop_shadow.png [run_dir]/genode/
if {[have_board pc]} {
file copy -force [genode_dir]/repos/gems/recipes/raw/drivers_managed-pc/event_filter.config \
[run_dir]/genode/event_filter.config
file copy -force [genode_dir]/repos/gems/run/sculpt/machine.vbox [run_dir]/genode/
file copy -force [genode_dir]/repos/gems/recipes/raw/drivers_managed-pc/drivers.config \
[run_dir]/genode/drivers.config
exec gzip -dc [genode_dir]/repos/gems/run/sculpt/machine.vdi.gz > [run_dir]/genode/machine.vdi
}
#
# Define 'VERSION' ROM module
#
# Note: the string must be exactly 5 bytes long.
#
proc sculpt_version { } {
return "21.03" }
# write file with newline (for producing nice output when using 'cat /VERSION')
set fd [open [run_dir]/genode/VERSION w]
puts $fd "[sculpt_version]"
close $fd
#
# Depot packages to be included in the default installation
#
proc current_pkg { pkg } { return $pkg/[_current_depot_archive_version pkg $pkg] }
set pkgs_to_install { }
set fd [open [run_dir]/genode/installation w]
puts $fd "<installation arch=\"[depot_spec]\">"
foreach pkg $pkgs_to_install {
puts $fd " <archive path=\"[depot_user]/pkg/[current_pkg $pkg]\" source=\"false\"/>" }
puts $fd "</installation>"
close $fd
#
# Configuration of deploy runtime
#
# This configuration is not provided as a file at run/sculpt/ because some
# parts need to be filled in at run-script execution time, in particular the
# current versions of the packages to deploy.
#
append manual_deploy_config {
<config arch="} [depot_spec] {">
<common_routes>
<service name="ROM" label_last="ld.lib.so"> <parent/> </service>
<service name="ROM" label_last="vfs.lib.so"> <parent/> </service>
<service name="ROM" label_last="init"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service>
</common_routes>
</config>}
set fd [open [run_dir]/genode/manual_deploy.config w]
puts $fd $manual_deploy_config
close $fd
#
# Install launcher snippets
#
# The launcher snippets are wrapped into a tar archive to be loaded as boot
# module. This procedure involves the following steps:
#
# The launcher snippets are copied from run/sculpt/launcher/ to
# [run_dir]/genode/launcher. Each launcher is inspected regarding its 'pkg'
# attribute. If its 'pkg' attribute contains a single identifier (rather than
# a valid pkg path), the attribute value is replaced by a valid pkg path
# referring to the current version of the pkg and the [depot_user]. The
# filtered launchers are archived into 'launcher.tar' and removed from the
# [run_dir].
#
set launchers [glob -tails -directory [genode_dir]/repos/gems/run/sculpt/launcher/ *]
foreach file $launchers {
# skip backup files
if {[regexp {~$} $file dummy]} { continue }
set fd [open [genode_dir]/repos/gems/run/sculpt/launcher/$file r]
set content [read $fd]
close $fd
# filter 'pkg' attribute
set pattern {(\<launcher[^\>]+?pkg=")([^/]+)(")}
if {[regexp $pattern $content dummy head pkg tail]} {
set pkg_path [depot_user]/pkg/[current_pkg $pkg]
regsub $pattern $content "$head$pkg_path$tail" content
}
# write filtered launcher snippet
file mkdir [run_dir]/genode/launcher
set fd [open [run_dir]/genode/launcher/$file w]
puts $fd $content
close $fd
}
# wrap launcher snippets into tar archive and remove individual snippets
exec tar cf [run_dir]/genode/launcher.tar -C [run_dir]/genode launcher
exec rm -r [run_dir]/genode/launcher
#
# Generate depot index from gems/run/sculpt/index
#
set fd [open [genode_dir]/repos/gems/run/sculpt/index r]
set pkg_index [read $fd]
close $fd
# filter 'pkg' attribute
set pattern {(\<pkg[^\>]+?path=")([^/]+)(")}
while {[regexp $pattern $pkg_index dummy head pkg tail]} {
set pkg_path [depot_user]/pkg/[current_pkg $pkg]
regsub $pattern $pkg_index "$head$pkg_path$tail" pkg_index
}
# write filtered pkg index into the depot
file mkdir [depot_dir]/[depot_user]/index
set fd [open [depot_dir]/[depot_user]/index/[sculpt_version] w]
puts $fd $pkg_index
close $fd
#
# Assemble 'depot_users.tar' with the keys and download locations of the
# depot user found at genode/depot/.
#
# Add current depot index of [depot_user] as generated above.
#
set depot_users_files [exec sh -c "cd [genode_dir]; \
find depot -maxdepth 3 -name pubkey \
-or -name download"]
exec sh -c "tar cf [run_dir]/genode/depot_users.tar -C [genode_dir] \
[join $depot_users_files]"
#
# Create boot image
#
append boot_modules { }
build_boot_image $boot_modules