Files
2026-06-25 19:32:06 +02:00

313 lines
25 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en-us" dir="ltr" itemscope itemtype="http://schema.org/Article" data-r-output-format="html">
<head>
<meta charset="utf-8">
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta name="generator" content="Hugo 0.161.1">
<meta name="generator" content="Relearn 8.2.0+220806ce3ced8264fbdd693f77f28216a8a1b6ae">
<meta name="description" content="Process supervision Tip You can find the corresponding code in func gokrazy.supervise.
gokrazys init process (pid 1) supervises all the binaries the user specified via gokr-packer flags.
More specifically, gokrazy:
Starts your binary using Gos os/exec.Command API. The stdout and stderr file descriptors are hooked up to a ring buffer and can be viewed via gokrazys web interface. Extra command-line flags or environment variables can be specified using per-package configuration. When your binarys process exits, gokrazy restarts it! If the process exits with status code 0 (or 125), gokrazy will stop supervision. Exiting immediately with status code 0 when the GOKRAZY_FIRST_START=1 environment variable is set means “dont start the program on boot” Environment variables gokrazy sets the HOME environment variable to HOME=/perm/home/&lt;cmd&gt;, where &lt;cmd&gt; is the name of your binary. For example, tailscale.com/cmd/tailscaled is started with HOME=/perm/home/tailscaled.">
<meta name="author" content="">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Process interface / requirements :: gokrazy">
<meta name="twitter:description" content="Process supervision Tip You can find the corresponding code in func gokrazy.supervise.
gokrazys init process (pid 1) supervises all the binaries the user specified via gokr-packer flags.
More specifically, gokrazy:
Starts your binary using Gos os/exec.Command API. The stdout and stderr file descriptors are hooked up to a ring buffer and can be viewed via gokrazys web interface. Extra command-line flags or environment variables can be specified using per-package configuration. When your binarys process exits, gokrazy restarts it! If the process exits with status code 0 (or 125), gokrazy will stop supervision. Exiting immediately with status code 0 when the GOKRAZY_FIRST_START=1 environment variable is set means “dont start the program on boot” Environment variables gokrazy sets the HOME environment variable to HOME=/perm/home/&lt;cmd&gt;, where &lt;cmd&gt; is the name of your binary. For example, tailscale.com/cmd/tailscaled is started with HOME=/perm/home/tailscaled.">
<meta property="og:url" content="https://gokrazy.org/development/process-interface/index.html">
<meta property="og:site_name" content="gokrazy">
<meta property="og:title" content="Process interface / requirements :: gokrazy">
<meta property="og:description" content="Process supervision Tip You can find the corresponding code in func gokrazy.supervise.
gokrazys init process (pid 1) supervises all the binaries the user specified via gokr-packer flags.
More specifically, gokrazy:
Starts your binary using Gos os/exec.Command API. The stdout and stderr file descriptors are hooked up to a ring buffer and can be viewed via gokrazys web interface. Extra command-line flags or environment variables can be specified using per-package configuration. When your binarys process exits, gokrazy restarts it! If the process exits with status code 0 (or 125), gokrazy will stop supervision. Exiting immediately with status code 0 when the GOKRAZY_FIRST_START=1 environment variable is set means “dont start the program on boot” Environment variables gokrazy sets the HOME environment variable to HOME=/perm/home/&lt;cmd&gt;, where &lt;cmd&gt; is the name of your binary. For example, tailscale.com/cmd/tailscaled is started with HOME=/perm/home/tailscaled.">
<meta property="og:locale" content="en_us">
<meta property="og:type" content="article">
<meta property="article:section" content="Package development">
<meta itemprop="name" content="Process interface / requirements :: gokrazy">
<meta itemprop="description" content="Process supervision Tip You can find the corresponding code in func gokrazy.supervise.
gokrazys init process (pid 1) supervises all the binaries the user specified via gokr-packer flags.
More specifically, gokrazy:
Starts your binary using Gos os/exec.Command API. The stdout and stderr file descriptors are hooked up to a ring buffer and can be viewed via gokrazys web interface. Extra command-line flags or environment variables can be specified using per-package configuration. When your binarys process exits, gokrazy restarts it! If the process exits with status code 0 (or 125), gokrazy will stop supervision. Exiting immediately with status code 0 when the GOKRAZY_FIRST_START=1 environment variable is set means “dont start the program on boot” Environment variables gokrazy sets the HOME environment variable to HOME=/perm/home/&lt;cmd&gt;, where &lt;cmd&gt; is the name of your binary. For example, tailscale.com/cmd/tailscaled is started with HOME=/perm/home/tailscaled.">
<meta itemprop="wordCount" content="290">
<title>Process interface / requirements :: gokrazy</title>
<link href="/images/favicon.png?1782408721" rel="icon" type="image/png">
<link href="/css/auto-complete/auto-complete.min.css?1782408721" rel="stylesheet">
<script src="/js/auto-complete/auto-complete.min.js?1782408721" defer></script>
<script src="/js/search-lunr.min.js?1782408721" defer></script>
<script src="/js/search.min.js?1782408721" defer></script>
<script>
window.relearn = window.relearn || {};
window.relearn.index_js_url="/searchindex.en.js?1782408721";
</script>
<script src="/js/lunr/lunr.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.stemmer.support.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.multi.min.js?1782408721" defer></script>
<script src="/js/lunr/lunr.en.min.js?1782408721" defer></script>
<script>
window.relearn = window.relearn || {};
window.relearn.contentLangs=['en'];
</script>
<link href="/fonts/fontawesome/css/fontawesome-all.min.css?1782408721" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/fonts/fontawesome/css/fontawesome-all.min.css?1782408721" rel="stylesheet"></noscript>
<link href="/css/perfect-scrollbar/perfect-scrollbar.min.css?1782408721" rel="stylesheet">
<link href="/css/theme.min.css?1782408721" rel="stylesheet">
<link href="/css/format-html.min.css?1782408721" rel="stylesheet" id="R-format-style">
<script>
window.relearn = window.relearn || {};
// configuration
window.relearn.min = `.min`;
window.relearn.path='\/development\/process-interface\/index.html';
window.relearn.relBasePath='..\/..';
window.relearn.relBaseUri='..\/..';
window.relearn.absBaseUri='https:\/\/gokrazy.org';
window.relearn.disableInlineCopyToClipboard=true;
window.relearn.enableBlockCodeWrap=true;
// legal
window.relearn.getItem = (s,n) => {return s.getItem(n)};
window.relearn.setItem = (s,n,v) => {return s.setItem(n,v)};
window.relearn.removeItem = (s,n) => {return s.removeItem(n)};
// translations
window.T_Copy_to_clipboard = `Copy text to clipboard`;
window.T_Copied_to_clipboard = `Text copied to clipboard!`;
window.T_Link_copied_to_clipboard = `Link copied to clipboard!`;
window.T_Reset_view = `Reset view`;
window.T_View_reset = `View reset!`;
window.T_No_results_found = `No results found for "{0}"`;
window.T_N_results_found = `{1} results found for "{0}"`;
window.T_Browser_unsupported_feature = `This browser doesn't support this feature`;
// variant stuff
window.relearn.themevariants = [ 'auto' ];
window.relearn.customvariantname = "my-custom-variant";
window.relearn.changeVariant = function(variant) {
var oldVariant = document.documentElement.dataset.rThemeVariant;
window.relearn.setItem(window.localStorage, window.relearn.absBaseUri + "/variant", variant);
document.documentElement.dataset.rThemeVariant = variant;
if (oldVariant != variant) {
document.dispatchEvent( new CustomEvent('themeVariantLoaded', { detail: { variant, oldVariant } }) );
window.relearn.markVariant();
}
}
window.relearn.markVariant = function() {
var variant = window.relearn.getItem(window.localStorage, window.relearn.absBaseUri + "/variant");
document.querySelectorAll(".R-variantswitcher select").forEach((select) => {select.value = variant;});
}
window.relearn.initVariant = function() {
var variant = window.relearn.getItem(window.localStorage, window.relearn.absBaseUri + "/variant") ?? "";
if( variant == window.relearn.customvariantname ){
}else if( !variant || !window.relearn.themevariants.includes(variant) ){
variant = window.relearn.themevariants[0];
window.relearn.setItem(window.localStorage, window.relearn.absBaseUri + "/variant", variant);
}
document.documentElement.dataset.rThemeVariant = variant;
}
window.relearn.initVariant();
window.relearn.markVariant();
</script>
</head>
<body class="mobile-support html" data-url="/development/process-interface/index.html">
<div id="R-body" class="default-animation">
<div id="R-body-overlay"></div>
<nav id="R-topbar">
<div class="topbar-wrapper">
<div class="topbar-sidebar-divider"></div>
<div class="topbar-area topbar-area-start" data-area="start">
<div class="topbar-button topbar-button-sidebar" data-content-empty="disable" data-width-s="show" data-width-m="hide" data-width-l="hide">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleNav()" type="button" title="Menu (CTRL&#43;ALT&#43;n)"><i class="fa-fw fas fa-bars"></i></button></span>
</div>
<div class="topbar-button topbar-button-toc" data-content-empty="hide" data-width-s="show" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleTopbarFlyout(this)" type="button" title="Table of Contents (CTRL&#43;ALT&#43;t)"><i class="fa-fw fas fa-list-alt"></i></button></span>
<div class="topbar-content">
<div class="topbar-content-wrapper">
<nav class="TableOfContents">
<ul>
<li><a href="#process-supervision">Process supervision</a></li>
<li><a href="#environment-variables">Environment variables</a></li>
<li><a href="#privilege-dropping--security">Privilege dropping / security</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<ol class="topbar-breadcrumbs breadcrumbs highlightable" itemscope itemtype="http://schema.org/BreadcrumbList"><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><a itemprop="item" href="/index.html"><span itemprop="name">gokrazy Go appliances</span></a><meta itemprop="position" content="1">&nbsp;>&nbsp;</li><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><a itemprop="item" href="/development/index.html"><span itemprop="name">Package development</span></a><meta itemprop="position" content="2">&nbsp;>&nbsp;</li><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><span itemprop="name">Process interface / requirements</span><meta itemprop="position" content="3"></li>
</ol>
<div class="topbar-area topbar-area-end" data-area="end">
<div class="topbar-button topbar-button-edit" data-content-empty="disable" data-width-s="area-more" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><a href="https://github.com/gokrazy/gokrazy/tree/master/website/content/development/process-interface.md" rel="external" title="Edit (CTRL+ALT+w)"><i class="fa-fw fas fa-pen"></i></a></span>
</div>
<div class="topbar-button topbar-button-more" data-content-empty="hide" data-width-s="show" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleTopbarFlyout(this)" type="button" title="More"><i class="fa-fw fas fa-ellipsis-v"></i></button></span>
<div class="topbar-content">
<div class="topbar-content-wrapper">
<div class="topbar-area topbar-area-more" data-area="more">
</div>
</div>
</div>
</div>
</div>
</div>
</nav>
<div id="R-main-overlay"></div>
<main id="R-body-inner" class="highlightable development" tabindex="-1">
<div class="flex-block-wrapper">
<article class="default">
<header class="headline">
</header>
<h1 id="process-interface--requirements">Process interface / requirements</h1>
<h2 id="process-supervision">Process supervision<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<details open class="box cstyle notices tip">
<summary class="box-label" tabindex="-1">
<i class="fa-fw fas fa-lightbulb"></i>
Tip
</summary>
<div class="box-content">
<p>You can find the corresponding code in
<a href="https://sourcegraph.com/search?q=context:global+repo:%5Egithub%5C.com/gokrazy/gokrazy%24+type:symbol+%5Esupervise%24&patternType=regexp&case=yes" rel="external">func gokrazy.supervise</a>.</p>
</div>
</details>
<p>gokrazys init process (pid 1) supervises all the binaries the user specified via <code>gokr-packer</code> flags.</p>
<p>More specifically, gokrazy:</p>
<ol>
<li>Starts your binary using Gos <code>os/exec.Command</code> API.
<ul>
<li>The <code>stdout</code> and <code>stderr</code> file descriptors are hooked up to a ring buffer and can be viewed via gokrazys web interface.</li>
<li>Extra command-line flags or environment variables can be specified using
<a href="/userguide/package-config/index.html">per-package configuration</a>.</li>
</ul>
</li>
<li>When your binarys process exits, gokrazy restarts it!
<ul>
<li>If the process exits with status code <code>0</code> (or <code>125</code>), gokrazy will stop
supervision. Exiting immediately with status code <code>0</code> when the
<code>GOKRAZY_FIRST_START=1</code> environment variable is set means “dont start the
program on boot”</li>
</ul>
</li>
</ol>
<h2 id="environment-variables">Environment variables<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>gokrazy sets the <code>HOME</code> environment variable to <code>HOME=/perm/home/&lt;cmd&gt;</code>, where
<code>&lt;cmd&gt;</code> is the name of your binary. For example, <code>tailscale.com/cmd/tailscaled</code>
is started with <code>HOME=/perm/home/tailscaled</code>.</p>
<p>When your binary is first started, gokrazy sets the <code>GOKRAZY_FIRST_START=1</code>
environment variable.</p>
<p>The <code>PATH</code> environment variable is set to <code>/user:/gokrazy</code> so that all binaries
on the system can be discovered.</p>
<h2 id="privilege-dropping--security">Privilege dropping / security<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>An easy way to implement privilege dropping in Go is to re-execute the process
with <a href="https://pkg.go.dev/syscall#SysProcAttr" rel="external">syscall.SysProcAttr</a> fields
set. For example, this is how you would drop privileges to user <code>nobody</code>
(uid/gid 65534):</p>
<div class="highlight actionbar-wrapper wrap-code" dir="auto"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#75715e">// mustDropPrivileges re-executes the program in a child process,</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// dropping root privileges to user nobody.</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">mustDropPrivileges</span>() {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Getenv</span>(<span style="color:#e6db74">&#34;NTP_PRIVILEGES_DROPPED&#34;</span>) <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;1&#34;</span> {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">cmd</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">exec</span>.<span style="color:#a6e22e">Command</span>(<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Args</span>[<span style="color:#ae81ff">0</span>])
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">cmd</span>.<span style="color:#a6e22e">Env</span> = append(<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Environ</span>(), <span style="color:#e6db74">&#34;NTP_PRIVILEGES_DROPPED=1&#34;</span>)
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">cmd</span>.<span style="color:#a6e22e">Stdout</span> = <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stdout</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">cmd</span>.<span style="color:#a6e22e">Stderr</span> = <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stderr</span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">cmd</span>.<span style="color:#a6e22e">SysProcAttr</span> = <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">syscall</span>.<span style="color:#a6e22e">SysProcAttr</span>{
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Credential</span>: <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">syscall</span>.<span style="color:#a6e22e">Credential</span>{
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Uid</span>: <span style="color:#ae81ff">65534</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">Gid</span>: <span style="color:#ae81ff">65534</span>,
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">cmd</span>.<span style="color:#a6e22e">Run</span>())
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>
<p>Examples:</p>
<ul>
<li><a href="https://sourcegraph.com/github.com/gokrazy/gokrazy/-/blob/cmd/ntp/privdrop.go" rel="external"><code>github.com/gokrazy/gokrazy/cmd/ntp</code></a>
is a rather involved example which retains the CAP_SYS_TIME capability in the
child process</li>
<li><a href="https://sourcegraph.com/github.com/gokrazy/rsync/-/blob/internal/maincmd/namespacing_linux.go" rel="external"><code>github.com/gokrazy/rsync</code></a> uses Linux
mount namespaces and constructs a file system with read-only bind mounts of
the configured rsync modules</li>
</ul>
<footer class="footline">
</footer>
</article>
</div>
</main>
</div>
<aside id="R-sidebar" class="default-animation">
<div id="R-header-topbar" class="default-animation"></div>
<div id="R-header-wrapper" class="default-animation">
<div id="R-header" class="default-animation">
<img src="/logo.svg" width="100%" alt="gokrazy logo" title="gokrazy logo">
</div>
<search><form action="/search/index.html" method="get">
<div class="searchbox default-animation">
<button class="search-detail" type="submit" title="Search (CTRL+ALT+f)"><i class="fas fa-search"></i></button>
<label class="a11y-only" for="R-search-by">Search</label>
<input data-search-input id="R-search-by" name="search-by" class="search-by" type="search" placeholder="Search...">
<button class="search-clear" type="button" data-search-clear="" title="Clear search"><i class="fas fa-times" title="Clear search"></i></button>
</div>
</form></search>
</div>
<div id="R-homelinks" class="default-animation homelinks">
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-homelinks">
<ul class="space collapsible-menu">
<li class="" data-nav-url="/index.html"><a class="padding" href="/index.html"><i class="fa-fw fas fa-home"></i> Home</a></li>
</ul>
</div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-headercontrols">
<ul class="">
</ul>
</div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
</div>
<div id="R-content-wrapper" class="highlightable">
<div class="R-sidebarmenu R-shortcutmenu-main">
<ul class="enlarge morespace collapsible-menu">
<li class="" data-nav-url="/quickstart/index.html"><a class="padding" href="/quickstart/index.html"><b>1. </b>Quickstart</a></li>
<li class="" data-nav-url="/platforms/index.html"><a class="padding" href="/platforms/index.html"><b>2. </b>Supported platforms</a></li>
<li class="" data-nav-url="/userguide/index.html"><a class="padding" href="/userguide/index.html"><b>3. </b>Configuration</a><ul id="R-subsections-74b4df3a3d9365853f09e9f1dfe7bbba" class="collapsible-menu"></ul></li>
<li class="" data-nav-url="/packages/index.html"><a class="padding" href="/packages/index.html"><b>4. </b>Available packages</a><ul id="R-subsections-bdf1e8ce92aa8ff6883c617f10480430" class="collapsible-menu"></ul></li>
<li class="parent " data-nav-url="/development/index.html"><a class="padding" href="/development/index.html"><b>5. </b>Package development</a><ul id="R-subsections-54b0ce3c97b111c8cd4d107325fd580c" class="collapsible-menu">
<li class="active " data-nav-url="/development/process-interface/index.html"><a class="padding" href="/development/process-interface/index.html">Process interface / requirements</a></li>
<li class="" data-nav-url="/development/gpio/index.html"><a class="padding" href="/development/gpio/index.html">Controlling a GPIO input/output pin</a></li>
<li class="" data-nav-url="/development/modules/index.html"><a class="padding" href="/development/modules/index.html">Working with Go modules</a></li>
<li class="" data-nav-url="/development/buildtags/index.html"><a class="padding" href="/development/buildtags/index.html">The gokrazy Go build tag</a></li>
<li class="" data-nav-url="/development/non-go/index.html"><a class="padding" href="/development/non-go/index.html">Non-Go Prototyping</a></li></ul></li>
</ul>
</div>
<div class="R-sidebarmenu R-shortcutmenu-shortcuts">
<div class="nav-title padding">More</div>
<ul class="space collapsible-menu">
<li class="" data-nav-url="https://github.com/gokrazy/gokrazy"><a class="padding" href="https://github.com/gokrazy/gokrazy" rel="external"><i class='fab fa-github'></i> GitHub repo</a></li>
</ul>
</div>
<div id="R-footer-margin"></div>
<div class="R-menu-divider default-animation">
<hr class="padding">
</div>
<div class="R-sidebarmenu R-shortcutmenu-footercontrols">
<ul class="">
</ul>
</div>
<div id="R-footer"><p>Built with <a href="https://github.com/McShelby/hugo-theme-relearn" title="love"><i class="fas fa-heart"></i></a> by <a href="https://gohugo.io/">Hugo</a></p></div>
</div>
</aside>
<script src="/js/perfect-scrollbar/perfect-scrollbar.min.js?1782408721" defer></script>
<script src="/js/theme.min.js?1782408721" defer></script>
<div id="toast-container" role="status" aria-live="polite" aria-atomic="false"></div>
</body>
</html>