Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/orchestrator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,5 +148,5 @@ Automatically set in local mode. Set before running to override:

## Limitations

- Custom template builds support base images from the declared distro families: **Debian/Ubuntu** (apt), the **RHEL family** — Fedora, CentOS Stream, Rocky, Alma — (dnf/microdnf/yum), **TencentOS Server** 3+ and **OpenCloudOS** 8+ (dnf/microdnf/yum; TencentOS Server 2.x repos lack socat, fuse3, nftables and jq, so its builds fail at package install), **Arch** (pacman), and **Alpine** (apk, OpenRC). The distro is resolved from the image's `/etc/os-release` `ID` — never by probing for package managers. Images without an os-release identity (distroless, scratch) or from an undeclared family are rejected fast, with a build-log error naming the reason and the supported families (see `pkg/template/build/phases/base/distro`). Minimal/restricted-repo images may fail provisioning if their repos don't carry the required packages; the failure is surfaced in the build log.
- Custom template builds support base images from the declared distro families: **Debian/Ubuntu** (apt), the **RHEL family** — Fedora, CentOS Stream, Rocky, Alma — (dnf/microdnf/yum), **TencentOS Server** 3+ and **OpenCloudOS** 8+ (dnf/microdnf/yum; TencentOS Server 2.x repos lack socat, fuse3, nftables and jq, so its builds fail at package install), **openEuler** (dnf/microdnf/yum; its repos ship `shadow` rather than `shadow-utils`), **Arch** (pacman), and **Alpine** (apk, OpenRC). The distro is resolved from the image's `/etc/os-release` `ID` — never by probing for package managers. Images without an os-release identity (distroless, scratch) or from an undeclared family are rejected fast, with a build-log error naming the reason and the supported families (see `pkg/template/build/phases/base/distro`). Minimal/restricted-repo images may fail provisioning if their repos don't carry the required packages; the failure is surfaced in the build log.
- Sandboxes always boot the kernel E2B supplies, never one from the base image: `/lib/modules` is empty, no kernel modules can be loaded, and SELinux is disabled on the kernel command line (`selinux=0`), so a base image that ships an SELinux policy boots without it. `kernel-devel` from a distro's repos resolves against a kernel that isn't running. **RHEL** (`rhel`, incl. UBI), **Oracle Linux** (`ol`) and **Amazon Linux** (`amzn`) are therefore not accepted even though they are RPM/dnf images — they are chosen for kABI, signed kernel modules and UEK, which this cannot honour. The community rebuilds above are supported because they are chosen for the userland.
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,35 @@ var Profiles = []Profile{
CABundle: "/etc/ssl/certs/ca-certificates.crt",
CARefresh: `update-ca-trust extract && ln -sf /etc/pki/tls/certs/ca-bundle.crt "$E2B_CA_BUNDLE"`,
},
{
// openEuler is an RPM/dnf, systemd distro and the upstream base for a
// large part of the domestic server ecosystem (e.g. Kylin V10 SP). Its
// /etc/os-release carries ID=openEuler (mixed case, matched verbatim —
// provision.sh does not lowercase it) and no ID_LIKE, so without this
// profile it falls through to the unsupported-distro error. Verified
// against openeuler/openeuler:22.03: the one package-name difference
// from the RHEL family is shadow (shadow-utils does not exist in its
// repos); every other package resolves, and dnf/yum are both present.
Key: "openeuler",
Init: InitSystemd,
IDs: []string{"openEuler"},
Packages: []string{
"systemd", "shadow", "passwd", "openssh-server", "sudo", "chrony",
"socat", "curl", "ca-certificates", "fuse3", "iptables", "git",
"nfs-utils", "less", "nftables", "iputils", "jq", "bash", "tar",
"iproute", "findutils",
},
PkgQueryBody: `rpm -q "$1" >/dev/null 2>&1`,
// dnf → microdnf → yum, as the rest of the RPM family: minimal/container
// openEuler images may ship only microdnf or yum.
PkgInstall: `dnf -y install --allowerasing "$@" || microdnf -y install "$@" || yum -y install "$@"`,
InitBinary: "/usr/lib/systemd/systemd",
TimeSyncUnit: "chronyd",
SSHUnit: "sshd",
AdminGroup: "wheel",
CABundle: "/etc/ssl/certs/ca-certificates.crt",
CARefresh: `update-ca-trust extract && ln -sf /etc/pki/tls/certs/ca-bundle.crt "$E2B_CA_BUNDLE"`,
},
{
Key: "arch",
Init: InitSystemd,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package distro

import (
"slices"
"crypto/sha256"
"encoding/hex"
"strings"
Expand Down Expand Up @@ -339,3 +340,37 @@ func TestRejectedIDsAreNotReachableViaIDLike(t *testing.T) {
t.Error("the rejected-id guard must precede the ID_LIKE fallback")
}
}

// openEuler declares ID=openEuler (mixed case; provision.sh matches it verbatim
// without lowercasing) and no ID_LIKE, so it needs its own profile. Verified
// against openeuler/openeuler:22.03: it is RHEL-shaped except that its repos
// ship shadow, not shadow-utils. These assertions pin both facts so a future
// edit can't silently regress the case-sensitive id or the package name.
func TestOpenEulerProfile(t *testing.T) {
t.Parallel()
oe := profileByKey(t, "openeuler")

if !slices.Contains(oe.IDs, "openEuler") {
t.Errorf("openEuler id must be matched verbatim (mixed case), got IDs=%v", oe.IDs)
}
if slices.Contains(oe.Packages, "shadow-utils") {
t.Error("openEuler repos have no shadow-utils; it must install shadow")
}
if !slices.Contains(oe.Packages, "shadow") {
t.Error("openEuler must install shadow for the shadow-tools capability")
}
// RHEL-family shape: systemd path, dnf→microdnf→yum fallback, wheel admin.
if oe.InitBinary != "/usr/lib/systemd/systemd" {
t.Errorf("openEuler init path wrong: %s", oe.InitBinary)
}
for _, want := range []string{"dnf -y install --allowerasing", "|| microdnf -y install", "|| yum -y install"} {
if !strings.Contains(oe.PkgInstall, want) {
t.Errorf("openEuler install missing %q: %s", want, oe.PkgInstall)
}
}
// The generated selector must carry an openEuler case arm, keyed on the
// exact mixed-case id.
if !strings.Contains(ShellSelector(), "openEuler)") {
t.Error("selector must have an openEuler arm keyed on the verbatim id")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var capabilities = []struct {
"debian": {"systemd", "systemd-sysv"},
"rhel": {"systemd"},
"tencentos": {"systemd"},
"openeuler": {"systemd"},
"arch": {"systemd"},
"alpine": {"openrc"},
}},
Expand All @@ -30,6 +31,7 @@ var capabilities = []struct {
"debian": {},
"rhel": {"bash"},
"tencentos": {"bash"},
"openeuler": {"bash"},
"arch": {"bash"},
"alpine": {"bash"},
}},
Expand All @@ -38,97 +40,111 @@ var capabilities = []struct {
"debian": {},
"rhel": {"shadow-utils", "passwd"},
"tencentos": {"shadow-utils", "passwd"},
"openeuler": {"shadow", "passwd"},
"arch": {"shadow"},
"alpine": {"shadow"},
}},
{"ssh-server", map[string][]string{
"debian": {"openssh-server"},
"rhel": {"openssh-server"},
"tencentos": {"openssh-server"},
"openeuler": {"openssh-server"},
"arch": {"openssh"},
"alpine": {"openssh"},
}},
{"sudo", map[string][]string{
"debian": {"sudo"},
"rhel": {"sudo"},
"tencentos": {"sudo"},
"openeuler": {"sudo"},
"arch": {"sudo"},
"alpine": {"sudo"},
}},
{"time-sync", map[string][]string{
"debian": {"chrony"},
"rhel": {"chrony"},
"tencentos": {"chrony"},
"openeuler": {"chrony"},
"arch": {"chrony"},
"alpine": {"chrony"},
}},
{"ca-certificates", map[string][]string{
"debian": {"ca-certificates"},
"rhel": {"ca-certificates"},
"tencentos": {"ca-certificates"},
"openeuler": {"ca-certificates"},
"arch": {"ca-certificates"},
"alpine": {"ca-certificates"},
}},
{"fuse", map[string][]string{
"debian": {"fuse3"},
"rhel": {"fuse3"},
"tencentos": {"fuse3"},
"openeuler": {"fuse3"},
"arch": {"fuse3"},
"alpine": {"fuse3"},
}},
{"nfs-client", map[string][]string{
"debian": {"nfs-common"},
"rhel": {"nfs-utils"},
"tencentos": {"nfs-utils"},
"openeuler": {"nfs-utils"},
"arch": {"nfs-utils"},
"alpine": {"nfs-utils"},
}},
{"packet-filter", map[string][]string{
"debian": {"iptables", "nftables"},
"rhel": {"iptables", "nftables"},
"tencentos": {"iptables", "nftables"},
"openeuler": {"iptables", "nftables"},
"arch": {"iptables", "nftables"},
"alpine": {"iptables", "nftables"},
}},
{"git", map[string][]string{
"debian": {"git"},
"rhel": {"git"},
"tencentos": {"git"},
"openeuler": {"git"},
"arch": {"git"},
"alpine": {"git"},
}},
{"jq", map[string][]string{
"debian": {"jq"},
"rhel": {"jq"},
"tencentos": {"jq"},
"openeuler": {"jq"},
"arch": {"jq"},
"alpine": {"jq"},
}},
{"socat", map[string][]string{
"debian": {"socat"},
"rhel": {"socat"},
"tencentos": {"socat"},
"openeuler": {"socat"},
"arch": {"socat"},
"alpine": {"socat"},
}},
{"curl", map[string][]string{
"debian": {"curl"},
"rhel": {"curl"},
"tencentos": {"curl"},
"openeuler": {"curl"},
"arch": {"curl"},
"alpine": {"curl"},
}},
{"pager", map[string][]string{
"debian": {"less"},
"rhel": {"less"},
"tencentos": {"less"},
"openeuler": {"less"},
"arch": {"less"},
"alpine": {"less"},
}},
{"ping", map[string][]string{
"debian": {"iputils-ping"},
"rhel": {"iputils"},
"tencentos": {"iputils"},
"openeuler": {"iputils"},
"arch": {"iputils"},
"alpine": {"iputils"},
}},
Expand All @@ -138,6 +154,7 @@ var capabilities = []struct {
"debian": {"iproute2"},
"rhel": {"iproute"},
"tencentos": {"iproute"},
"openeuler": {"iproute"},
"arch": {},
"alpine": {"iproute2"},
}},
Expand All @@ -151,6 +168,7 @@ var capabilities = []struct {
"debian": {},
"rhel": {"findutils"},
"tencentos": {"findutils"},
"openeuler": {"findutils"},
"arch": {},
"alpine": {},
}},
Expand All @@ -160,6 +178,7 @@ var capabilities = []struct {
"debian": {},
"rhel": {"tar"},
"tencentos": {"tar"},
"openeuler": {"tar"},
"arch": {},
"alpine": {},
}},
Expand All @@ -169,6 +188,7 @@ var capabilities = []struct {
"debian": {},
"rhel": {},
"tencentos": {},
"openeuler": {},
"arch": {},
"alpine": {"util-linux-misc"},
}},
Expand Down