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), **Kylin** Linux Advanced Server V10 (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,31 @@ 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"`,
},
{
// Kylin Linux Advanced Server (银河麒麟高级服务器) V10 is an RPM/dnf,
// systemd distro widely used across domestic infrastructure. Its
// /etc/os-release declares ID=kylin and no ID_LIKE, so without this
// profile a Kylin base falls through to the unsupported-distro error.
// Verified against macrosan/kylin:v10-sp3-2403: RHEL-shaped, with the
// same one difference as openEuler — it ships shadow, not shadow-utils.
Key: "kylin",
Init: InitSystemd,
IDs: []string{"kylin"},
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`,
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,33 @@ func TestRejectedIDsAreNotReachableViaIDLike(t *testing.T) {
t.Error("the rejected-id guard must precede the ID_LIKE fallback")
}
}

// Kylin Advanced Server V10 declares ID=kylin and no ID_LIKE, so it needs its
// own profile. Verified against macrosan/kylin:v10-sp3-2403: RHEL-shaped, with
// the same package-name difference as openEuler — its repos ship shadow, not
// shadow-utils. These assertions pin both facts.
func TestKylinProfile(t *testing.T) {
t.Parallel()
k := profileByKey(t, "kylin")

if !slices.Contains(k.IDs, "kylin") {
t.Errorf("kylin id must be matched, got IDs=%v", k.IDs)
}
if slices.Contains(k.Packages, "shadow-utils") {
t.Error("Kylin repos have no shadow-utils; it must install shadow")
}
if !slices.Contains(k.Packages, "shadow") {
t.Error("kylin must install shadow for the shadow-tools capability")
}
if k.InitBinary != "/usr/lib/systemd/systemd" {
t.Errorf("kylin init path wrong: %s", k.InitBinary)
}
for _, want := range []string{"dnf -y install --allowerasing", "|| microdnf -y install", "|| yum -y install"} {
if !strings.Contains(k.PkgInstall, want) {
t.Errorf("kylin install missing %q: %s", want, k.PkgInstall)
}
}
if !strings.Contains(ShellSelector(), "kylin)") {
t.Error("selector must have a kylin arm")
}
}
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"},
"kylin": {"systemd"},
"arch": {"systemd"},
"alpine": {"openrc"},
}},
Expand All @@ -30,6 +31,7 @@ var capabilities = []struct {
"debian": {},
"rhel": {"bash"},
"tencentos": {"bash"},
"kylin": {"bash"},
"arch": {"bash"},
"alpine": {"bash"},
}},
Expand All @@ -38,97 +40,111 @@ var capabilities = []struct {
"debian": {},
"rhel": {"shadow-utils", "passwd"},
"tencentos": {"shadow-utils", "passwd"},
"kylin": {"shadow", "passwd"},
"arch": {"shadow"},
"alpine": {"shadow"},
}},
{"ssh-server", map[string][]string{
"debian": {"openssh-server"},
"rhel": {"openssh-server"},
"tencentos": {"openssh-server"},
"kylin": {"openssh-server"},
"arch": {"openssh"},
"alpine": {"openssh"},
}},
{"sudo", map[string][]string{
"debian": {"sudo"},
"rhel": {"sudo"},
"tencentos": {"sudo"},
"kylin": {"sudo"},
"arch": {"sudo"},
"alpine": {"sudo"},
}},
{"time-sync", map[string][]string{
"debian": {"chrony"},
"rhel": {"chrony"},
"tencentos": {"chrony"},
"kylin": {"chrony"},
"arch": {"chrony"},
"alpine": {"chrony"},
}},
{"ca-certificates", map[string][]string{
"debian": {"ca-certificates"},
"rhel": {"ca-certificates"},
"tencentos": {"ca-certificates"},
"kylin": {"ca-certificates"},
"arch": {"ca-certificates"},
"alpine": {"ca-certificates"},
}},
{"fuse", map[string][]string{
"debian": {"fuse3"},
"rhel": {"fuse3"},
"tencentos": {"fuse3"},
"kylin": {"fuse3"},
"arch": {"fuse3"},
"alpine": {"fuse3"},
}},
{"nfs-client", map[string][]string{
"debian": {"nfs-common"},
"rhel": {"nfs-utils"},
"tencentos": {"nfs-utils"},
"kylin": {"nfs-utils"},
"arch": {"nfs-utils"},
"alpine": {"nfs-utils"},
}},
{"packet-filter", map[string][]string{
"debian": {"iptables", "nftables"},
"rhel": {"iptables", "nftables"},
"tencentos": {"iptables", "nftables"},
"kylin": {"iptables", "nftables"},
"arch": {"iptables", "nftables"},
"alpine": {"iptables", "nftables"},
}},
{"git", map[string][]string{
"debian": {"git"},
"rhel": {"git"},
"tencentos": {"git"},
"kylin": {"git"},
"arch": {"git"},
"alpine": {"git"},
}},
{"jq", map[string][]string{
"debian": {"jq"},
"rhel": {"jq"},
"tencentos": {"jq"},
"kylin": {"jq"},
"arch": {"jq"},
"alpine": {"jq"},
}},
{"socat", map[string][]string{
"debian": {"socat"},
"rhel": {"socat"},
"tencentos": {"socat"},
"kylin": {"socat"},
"arch": {"socat"},
"alpine": {"socat"},
}},
{"curl", map[string][]string{
"debian": {"curl"},
"rhel": {"curl"},
"tencentos": {"curl"},
"kylin": {"curl"},
"arch": {"curl"},
"alpine": {"curl"},
}},
{"pager", map[string][]string{
"debian": {"less"},
"rhel": {"less"},
"tencentos": {"less"},
"kylin": {"less"},
"arch": {"less"},
"alpine": {"less"},
}},
{"ping", map[string][]string{
"debian": {"iputils-ping"},
"rhel": {"iputils"},
"tencentos": {"iputils"},
"kylin": {"iputils"},
"arch": {"iputils"},
"alpine": {"iputils"},
}},
Expand All @@ -138,6 +154,7 @@ var capabilities = []struct {
"debian": {"iproute2"},
"rhel": {"iproute"},
"tencentos": {"iproute"},
"kylin": {"iproute"},
"arch": {},
"alpine": {"iproute2"},
}},
Expand All @@ -151,6 +168,7 @@ var capabilities = []struct {
"debian": {},
"rhel": {"findutils"},
"tencentos": {"findutils"},
"kylin": {"findutils"},
"arch": {},
"alpine": {},
}},
Expand All @@ -160,6 +178,7 @@ var capabilities = []struct {
"debian": {},
"rhel": {"tar"},
"tencentos": {"tar"},
"kylin": {"tar"},
"arch": {},
"alpine": {},
}},
Expand All @@ -169,6 +188,7 @@ var capabilities = []struct {
"debian": {},
"rhel": {},
"tencentos": {},
"kylin": {},
"arch": {},
"alpine": {"util-linux-misc"},
}},
Expand Down