core -> metropolis

Smalltown is now called Metropolis!

This is the first commit in a series of cleanup commits that prepare us
for an open source release. This one just some Bazel packages around to
follow a stricter directory layout.

All of Metropolis now lives in `//metropolis`.

All of Metropolis Node code now lives in `//metropolis/node`.

All of the main /init now lives in `//m/n/core`.

All of the Kubernetes functionality/glue now lives in `//m/n/kubernetes`.

Next steps:
     - hunt down all references to Smalltown and replace them appropriately
     - narrow down visibility rules
     - document new code organization
     - move `//build/toolchain` to `//monogon/build/toolchain`
     - do another cleanup pass between `//golibs` and
       `//monogon/node/{core,common}`.
     - remove `//delta` and `//anubis`

Fixes T799.

Test Plan: Just a very large refactor. CI should help us out here.

Bug: T799

X-Origin-Diff: phab/D667
GitOrigin-RevId: 6029b8d4edc42325d50042596b639e8b122d0ded
diff --git a/BUILD b/BUILD
index 123670e..f855af7 100644
--- a/BUILD
+++ b/BUILD
@@ -97,13 +97,13 @@
 # Shortcut for launching a single Smalltown instance
 alias(
     name = "launch",
-    actual = "//core/cmd/launch",
+    actual = "//metropolis/test/launch/cli/launch",
 )
 
 # Shortcut for launching a virtual network with two Smalltown instances
 alias(
     name = "launch-multi2",
-    actual = "//core/cmd/launch-multi2",
+    actual = "//metropolis/test/launch/cli/launch-multi2",
 )
 
 alias(
diff --git a/README.md b/README.md
index 7d6c2d3..988d10d 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@
     
 Run a kubectl command:
 
-    bazel run //core/cmd/dbg -- kubectl describe
+    bazel run //metropolis/cli/dbg -- kubectl describe
  
 #### IntelliJ
 
diff --git a/core/cmd/init/BUILD.bazel b/core/cmd/init/BUILD.bazel
deleted file mode 100644
index a6d1ee2..0000000
--- a/core/cmd/init/BUILD.bazel
+++ /dev/null
@@ -1,43 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
-
-go_library(
-    name = "go_default_library",
-    # keep
-    srcs = [
-        "debug_service.go",
-        "main.go",
-        "switchroot.go",
-    ] + select({
-        "//core:debug_build": ["delve_enabled.go"],
-        "//conditions:default": ["delve_disabled.go"],
-    }),
-    importpath = "git.monogon.dev/source/nexantic.git/core/cmd/init",
-    visibility = ["//visibility:private"],
-    deps = [
-        "//core/internal/cluster:go_default_library",
-        "//core/internal/common:go_default_library",
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/consensus/ca:go_default_library",
-        "//core/internal/containerd:go_default_library",
-        "//core/internal/kubernetes:go_default_library",
-        "//core/internal/kubernetes/pki:go_default_library",
-        "//core/internal/localstorage:go_default_library",
-        "//core/internal/localstorage/declarative:go_default_library",
-        "//core/internal/network:go_default_library",
-        "//core/internal/network/dns:go_default_library",
-        "//core/pkg/logtree:go_default_library",
-        "//core/pkg/tpm:go_default_library",
-        "//core/proto/api:go_default_library",
-        "@org_golang_google_grpc//:go_default_library",
-        "@org_golang_google_grpc//codes:go_default_library",
-        "@org_golang_google_grpc//status:go_default_library",
-        "@org_golang_x_sys//unix:go_default_library",
-    ],
-)
-
-go_binary(
-    name = "init",
-    embed = [":go_default_library"],
-    pure = "on",  # keep
-    visibility = ["//visibility:public"],
-)
diff --git a/core/cmd/launch-multi2/BUILD.bazel b/core/cmd/launch-multi2/BUILD.bazel
deleted file mode 100644
index 87f4c88..0000000
--- a/core/cmd/launch-multi2/BUILD.bazel
+++ /dev/null
@@ -1,29 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/cmd/launch-multi2",
-    visibility = ["//visibility:private"],
-    deps = [
-        "//core/internal/common:go_default_library",
-        "//core/internal/launch:go_default_library",
-        "//core/proto/api:go_default_library",
-        "@com_github_grpc_ecosystem_go_grpc_middleware//retry:go_default_library",
-        "@org_golang_google_grpc//:go_default_library",
-    ],
-)
-
-go_binary(
-    name = "launch-multi2",
-    data = [
-        "//core:image",
-        "//core:swtpm_data",
-        "//core/cmd/nanoswitch:initramfs",
-        "//core/tools/ktest:linux-testing",
-        "//third_party/edk2:firmware",
-        "@com_github_bonzini_qboot//:qboot-bin",
-    ],
-    embed = [":go_default_library"],
-    visibility = ["//visibility:public"],
-)
diff --git a/core/internal/cluster/BUILD.bazel b/core/internal/cluster/BUILD.bazel
deleted file mode 100644
index 7c9dfd5..0000000
--- a/core/internal/cluster/BUILD.bazel
+++ /dev/null
@@ -1,25 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "manager.go",
-        "node.go",
-    ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/cluster",
-    visibility = ["//core:__subpackages__"],
-    deps = [
-        "//core/internal/common:go_default_library",
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/consensus:go_default_library",
-        "//core/internal/localstorage:go_default_library",
-        "//core/internal/localstorage/declarative:go_default_library",
-        "//core/internal/network:go_default_library",
-        "//core/proto/api:go_default_library",
-        "//core/proto/internal:go_default_library",
-        "@com_github_cenkalti_backoff_v4//:go_default_library",
-        "@com_github_golang_protobuf//proto:go_default_library",
-        "@io_etcd_go_etcd//clientv3:go_default_library",
-        "@org_golang_x_sys//unix:go_default_library",
-    ],
-)
diff --git a/core/internal/common/BUILD.bazel b/core/internal/common/BUILD.bazel
deleted file mode 100644
index 8bd89d6..0000000
--- a/core/internal/common/BUILD.bazel
+++ /dev/null
@@ -1,8 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["setup.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/common",
-    visibility = ["//:__subpackages__"],
-)
diff --git a/core/internal/common/setup.go b/core/internal/common/setup.go
deleted file mode 100644
index 6510774..0000000
--- a/core/internal/common/setup.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2020 The Monogon Project Authors.
-//
-// SPDX-License-Identifier: Apache-2.0
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package common
-
-import (
-	"crypto/ed25519"
-	"encoding/hex"
-	"errors"
-	"strings"
-)
-
-type (
-	SmalltownState string
-)
-
-const (
-	// These are here to prevent depdendency loops
-	NodeServicePort     = 7835
-	ConsensusPort       = 7834
-	MasterServicePort   = 7833
-	ExternalServicePort = 7836
-	DebugServicePort    = 7837
-	WireGuardPort       = 7838
-	KubernetesAPIPort   = 6443
-	DebuggerPort        = 2345
-)
-
-const (
-	// Node is provisioning a new cluster with itself as a master
-	StateNewClusterMode SmalltownState = "setup"
-	// Node is enrolling itself and waiting to be adopted
-	StateEnrollMode SmalltownState = "join"
-	// Node is fully provisioned.
-	StateJoined SmalltownState = "enrolled"
-)
-
-func NameFromIDKey(pubKey ed25519.PublicKey) string {
-	return "smalltown-" + hex.EncodeToString(pubKey[:16])
-}
-
-func IDKeyPrefixFromName(name string) ([]byte, error) {
-	if !strings.HasPrefix(name, "smalltown-") {
-		return []byte{}, errors.New("invalid name")
-	}
-	return hex.DecodeString(strings.TrimPrefix(name, "smalltown-"))
-}
diff --git a/core/internal/consensus/BUILD.bazel b/core/internal/consensus/BUILD.bazel
deleted file mode 100644
index b8b45a7..0000000
--- a/core/internal/consensus/BUILD.bazel
+++ /dev/null
@@ -1,30 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["consensus.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/consensus",
-    visibility = ["//:__subpackages__"],
-    deps = [
-        "//core/internal/common:go_default_library",
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/consensus/ca:go_default_library",
-        "//core/internal/localstorage:go_default_library",
-        "@io_etcd_go_etcd//clientv3:go_default_library",
-        "@io_etcd_go_etcd//clientv3/namespace:go_default_library",
-        "@io_etcd_go_etcd//embed:go_default_library",
-        "@org_uber_go_atomic//:go_default_library",
-    ],
-)
-
-go_test(
-    name = "go_default_test",
-    srcs = ["consensus_test.go"],
-    embed = [":go_default_library"],
-    deps = [
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/localstorage:go_default_library",
-        "//core/internal/localstorage/declarative:go_default_library",
-        "//golibs/common:go_default_library",
-    ],
-)
diff --git a/core/internal/containerd/BUILD.bazel b/core/internal/containerd/BUILD.bazel
deleted file mode 100644
index 0e2de21..0000000
--- a/core/internal/containerd/BUILD.bazel
+++ /dev/null
@@ -1,20 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/containerd",
-    visibility = ["//core:__subpackages__"],
-    deps = [
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/localstorage:go_default_library",
-        "@com_github_containerd_containerd//:go_default_library",
-        "@com_github_containerd_containerd//namespaces:go_default_library",
-    ],
-)
-
-exports_files([
-    "config.toml",
-    "runsc.toml",
-    "cnispec.gojson",
-])
diff --git a/core/internal/localstorage/BUILD.bazel b/core/internal/localstorage/BUILD.bazel
deleted file mode 100644
index a3a5b0c..0000000
--- a/core/internal/localstorage/BUILD.bazel
+++ /dev/null
@@ -1,26 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "directory_data.go",
-        "directory_pki.go",
-        "directory_root.go",
-        "storage.go",
-    ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/localstorage",
-    visibility = ["//core:__subpackages__"],
-    deps = [
-        "//core/internal/localstorage/crypt:go_default_library",
-        "//core/internal/localstorage/declarative:go_default_library",
-        "//core/pkg/tpm:go_default_library",
-        "@org_golang_x_sys//unix:go_default_library",
-    ],
-)
-
-go_test(
-    name = "go_default_test",
-    srcs = ["storage_test.go"],
-    embed = [":go_default_library"],
-    deps = ["//core/internal/localstorage/declarative:go_default_library"],
-)
diff --git a/core/internal/localstorage/crypt/BUILD.bazel b/core/internal/localstorage/crypt/BUILD.bazel
deleted file mode 100644
index 27968f3..0000000
--- a/core/internal/localstorage/crypt/BUILD.bazel
+++ /dev/null
@@ -1,17 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "blockdev.go",
-        "crypt.go",
-    ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/localstorage/crypt",
-    visibility = ["//core:__subpackages__"],
-    deps = [
-        "//core/pkg/devicemapper:go_default_library",
-        "//core/pkg/sysfs:go_default_library",
-        "@com_github_rekby_gpt//:go_default_library",
-        "@org_golang_x_sys//unix:go_default_library",
-    ],
-)
diff --git a/core/internal/network/BUILD.bazel b/core/internal/network/BUILD.bazel
deleted file mode 100644
index e0530d5..0000000
--- a/core/internal/network/BUILD.bazel
+++ /dev/null
@@ -1,20 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/network",
-    visibility = ["//:__subpackages__"],
-    deps = [
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/network/dns:go_default_library",
-        "//core/pkg/dhcp4c:go_default_library",
-        "//core/pkg/dhcp4c/callback:go_default_library",
-        "//core/pkg/logtree:go_default_library",
-        "@com_github_google_nftables//:go_default_library",
-        "@com_github_google_nftables//expr:go_default_library",
-        "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
-        "@com_github_vishvananda_netlink//:go_default_library",
-        "@org_golang_x_sys//unix:go_default_library",
-    ],
-)
diff --git a/core/internal/network/dns/BUILD.bazel b/core/internal/network/dns/BUILD.bazel
deleted file mode 100644
index 469fbab..0000000
--- a/core/internal/network/dns/BUILD.bazel
+++ /dev/null
@@ -1,15 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "go_default_library",
-    srcs = [
-        "coredns.go",
-        "directives.go",
-    ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/network/dns",
-    visibility = ["//core:__subpackages__"],
-    deps = [
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/pkg/fileargs:go_default_library",
-    ],
-)
diff --git a/core/proto/internal/BUILD.bazel b/core/proto/internal/BUILD.bazel
deleted file mode 100644
index aa16e97..0000000
--- a/core/proto/internal/BUILD.bazel
+++ /dev/null
@@ -1,23 +0,0 @@
-load("@rules_proto//proto:defs.bzl", "proto_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-
-proto_library(
-    name = "internal_proto",
-    srcs = ["internal.proto"],
-    visibility = ["//core:__subpackages__"],
-)
-
-go_proto_library(
-    name = "internal_go_proto",
-    importpath = "git.monogon.dev/source/nexantic.git/core/proto/internal",
-    proto = ":internal_proto",
-    visibility = ["//core:__subpackages__"],
-)
-
-go_library(
-    name = "go_default_library",
-    embed = [":internal_go_proto"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/proto/internal",
-    visibility = ["//core:__subpackages__"],
-)
diff --git a/core/README.md b/metropolis/README.md
similarity index 78%
rename from core/README.md
rename to metropolis/README.md
index fec9d69..28fbb45 100644
--- a/core/README.md
+++ b/metropolis/README.md
@@ -1,4 +1,4 @@
-# Smalltown Operating System
+# Metropolis Operating System
 
 ## Launch VM
 
diff --git a/core/cmd/dbg/BUILD.bazel b/metropolis/cli/dbg/BUILD.bazel
similarity index 77%
rename from core/cmd/dbg/BUILD.bazel
rename to metropolis/cli/dbg/BUILD.bazel
index 563be82..51fa722 100644
--- a/core/cmd/dbg/BUILD.bazel
+++ b/metropolis/cli/dbg/BUILD.bazel
@@ -3,11 +3,11 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/cmd/dbg",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/cli/dbg",
     visibility = ["//visibility:private"],
     deps = [
-        "//core/pkg/logtree:go_default_library",
-        "//core/proto/api:go_default_library",
+        "//metropolis/node/core/logtree:go_default_library",
+        "//metropolis/proto/api:go_default_library",
         "@com_github_spf13_pflag//:go_default_library",
         "@io_k8s_component_base//cli/flag:go_default_library",
         "@io_k8s_kubectl//pkg/cmd/plugin:go_default_library",
diff --git a/core/cmd/dbg/main.go b/metropolis/cli/dbg/main.go
similarity index 97%
rename from core/cmd/dbg/main.go
rename to metropolis/cli/dbg/main.go
index 176973f..1bb6185 100644
--- a/core/cmd/dbg/main.go
+++ b/metropolis/cli/dbg/main.go
@@ -26,8 +26,6 @@
 	"os"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-
 	"github.com/spf13/pflag"
 	"google.golang.org/grpc"
 	cliflag "k8s.io/component-base/cli/flag"
@@ -35,7 +33,8 @@
 	"k8s.io/kubectl/pkg/util/logs"
 	"k8s.io/kubernetes/pkg/kubectl/cmd"
 
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 func main() {
diff --git a/core/BUILD b/metropolis/node/BUILD.bazel
similarity index 75%
rename from core/BUILD
rename to metropolis/node/BUILD.bazel
index edd669a..48c9177 100644
--- a/core/BUILD
+++ b/metropolis/node/BUILD.bazel
@@ -1,4 +1,12 @@
-load("//core/build:def.bzl", "smalltown_initramfs")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("//metropolis/node/build:def.bzl", "smalltown_initramfs")
+
+go_library(
+    name = "go_default_library",
+    srcs = ["ports.go"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node",
+    visibility = ["//visibility:public"],
+)
 
 # debug_build checks if we're building in debug mode and enables various debug features for the image. Currently this
 # is only used for attaching a Delve debugger to init when it's enabled.
@@ -16,7 +24,7 @@
         "/containerd/run",
     ],
     files = {
-        "//core/cmd/init": "/init",
+        "//metropolis/node/core": "/init",
         "//third_party/xfsprogs:mkfs.xfs": "/bin/mkfs.xfs",
 
         # CA Certificate bundle & os-release
@@ -24,7 +32,7 @@
         ":os-release-info": "/etc/os-release",
 
         # Hyperkube
-        "//core/cmd/kube": "/kubernetes/bin/kube",
+        "//metropolis/node/kubernetes/hyperkube": "/kubernetes/bin/kube",
 
         # CoreDNS
         "@com_github_coredns_coredns//:coredns": "/kubernetes/bin/coredns",
@@ -40,13 +48,13 @@
         "@com_github_containerd_containerd//cmd/containerd": "/containerd/bin/containerd",
 
         # Containerd config files
-        "//core/internal/containerd:runsc.toml": "/containerd/conf/runsc.toml",
-        "//core/internal/containerd:config.toml": "/containerd/conf/config.toml",
-        "//core/internal/containerd:cnispec.gojson": "/containerd/conf/cnispec.gojson",
+        "//metropolis/node/kubernetes/containerd:runsc.toml": "/containerd/conf/runsc.toml",
+        "//metropolis/node/kubernetes/containerd:config.toml": "/containerd/conf/config.toml",
+        "//metropolis/node/kubernetes/containerd:cnispec.gojson": "/containerd/conf/cnispec.gojson",
 
         # Containerd preseed bundles
-        "//core/tests/e2e/preseedtest:preseedtest.tar": "/containerd/preseed/k8s.io/preseedtest.tar",
-        "//core/tests/e2e/k8s_cts:k8s_cts_image.tar": "/containerd/preseed/k8s.io/k8s_cts.tar",
+        "//metropolis/test/e2e/preseedtest:preseedtest.tar": "/containerd/preseed/k8s.io/preseedtest.tar",
+        "//metropolis/test/e2e/k8s_cts:k8s_cts_image.tar": "/containerd/preseed/k8s.io/k8s_cts.tar",
 
         # CNI Plugins
         "@com_github_containernetworking_plugins//plugins/main/loopback": "/containerd/bin/cni/loopback",
@@ -72,13 +80,13 @@
         "smalltown.img",
     ],
     cmd = """
-    $(location //core/cmd/mkimage) \
+    $(location //metropolis/node/build/mkimage) \
         -efi $(location //third_party/linux:bzImage) \
         -initramfs $(location :initramfs) \
         -out $@
     """,
     tools = [
-        "//core/cmd/mkimage",
+        "//metropolis/node/build/mkimage",
     ],
     visibility = ["//visibility:public"],
 )
@@ -123,7 +131,7 @@
     visibility = ["//visibility:public"],
 )
 
-load("//core/build/genosrelease:defs.bzl", "os_release")
+load("//metropolis/node/build/genosrelease:defs.bzl", "os_release")
 
 os_release(
     name = "os-release-info",
diff --git a/core/build/BUILD b/metropolis/node/build/BUILD
similarity index 100%
rename from core/build/BUILD
rename to metropolis/node/build/BUILD
diff --git a/core/build/def.bzl b/metropolis/node/build/def.bzl
similarity index 100%
rename from core/build/def.bzl
rename to metropolis/node/build/def.bzl
diff --git a/core/build/genosrelease/BUILD.bazel b/metropolis/node/build/genosrelease/BUILD.bazel
similarity index 79%
rename from core/build/genosrelease/BUILD.bazel
rename to metropolis/node/build/genosrelease/BUILD.bazel
index 4cdc2ee..9403d72 100644
--- a/core/build/genosrelease/BUILD.bazel
+++ b/metropolis/node/build/genosrelease/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/build/genosrelease",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/build/genosrelease",
     visibility = ["//visibility:private"],
     deps = ["@com_github_joho_godotenv//:go_default_library"],
 )
diff --git a/core/build/genosrelease/defs.bzl b/metropolis/node/build/genosrelease/defs.bzl
similarity index 95%
rename from core/build/genosrelease/defs.bzl
rename to metropolis/node/build/genosrelease/defs.bzl
index d6190d9..61ce9e4 100644
--- a/core/build/genosrelease/defs.bzl
+++ b/metropolis/node/build/genosrelease/defs.bzl
@@ -42,7 +42,7 @@
         "os_id": attr.string(mandatory = True),
         "stamp_var": attr.string(mandatory = True),
         "_genosrelease": attr.label(
-            default = Label("//core/build/genosrelease"),
+            default = Label("//metropolis/node/build/genosrelease"),
             cfg = "host",
             executable = True,
             allow_files = True,
diff --git a/core/build/genosrelease/main.go b/metropolis/node/build/genosrelease/main.go
similarity index 100%
rename from core/build/genosrelease/main.go
rename to metropolis/node/build/genosrelease/main.go
diff --git a/core/tools/kconfig-patcher/BUILD.bazel b/metropolis/node/build/kconfig-patcher/BUILD.bazel
similarity index 81%
rename from core/tools/kconfig-patcher/BUILD.bazel
rename to metropolis/node/build/kconfig-patcher/BUILD.bazel
index 7c61d4f..55b2b52 100644
--- a/core/tools/kconfig-patcher/BUILD.bazel
+++ b/metropolis/node/build/kconfig-patcher/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/tools/kconfig-patcher",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/build/kconfig-patcher",
     visibility = ["//visibility:private"],
 )
 
diff --git a/core/tools/kconfig-patcher/kconfig-patcher.bzl b/metropolis/node/build/kconfig-patcher/kconfig-patcher.bzl
similarity index 89%
rename from core/tools/kconfig-patcher/kconfig-patcher.bzl
rename to metropolis/node/build/kconfig-patcher/kconfig-patcher.bzl
index a6af343..337642e 100644
--- a/core/tools/kconfig-patcher/kconfig-patcher.bzl
+++ b/metropolis/node/build/kconfig-patcher/kconfig-patcher.bzl
@@ -23,10 +23,10 @@
         srcs = [src],
         outs = [out],
         tools = [
-            "//core/tools/kconfig-patcher",
+            "//metropolis/node/build/kconfig-patcher",
         ],
         cmd = """
-        $(location //core/tools/kconfig-patcher) \
+        $(location //metropolis/node/build/kconfig-patcher) \
             -in $< -out $@ '%s'
         """ % struct(overrides = override_configs).to_json(),
         **kwargs
diff --git a/core/tools/kconfig-patcher/main.go b/metropolis/node/build/kconfig-patcher/main.go
similarity index 100%
rename from core/tools/kconfig-patcher/main.go
rename to metropolis/node/build/kconfig-patcher/main.go
diff --git a/core/tools/kconfig-patcher/main_test.go b/metropolis/node/build/kconfig-patcher/main_test.go
similarity index 100%
rename from core/tools/kconfig-patcher/main_test.go
rename to metropolis/node/build/kconfig-patcher/main_test.go
diff --git a/core/cmd/mkimage/BUILD.bazel b/metropolis/node/build/mkimage/BUILD.bazel
similarity index 86%
rename from core/cmd/mkimage/BUILD.bazel
rename to metropolis/node/build/mkimage/BUILD.bazel
index 35e162d..b489002 100644
--- a/core/cmd/mkimage/BUILD.bazel
+++ b/metropolis/node/build/mkimage/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/cmd/mkimage",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/build/mkimage",
     visibility = ["//visibility:private"],
     deps = [
         "@com_github_diskfs_go_diskfs//:go_default_library",
diff --git a/core/cmd/mkimage/main.go b/metropolis/node/build/mkimage/main.go
similarity index 100%
rename from core/cmd/mkimage/main.go
rename to metropolis/node/build/mkimage/main.go
diff --git a/core/pkg/devicemapper/BUILD.bazel b/metropolis/node/common/devicemapper/BUILD.bazel
similarity index 79%
rename from core/pkg/devicemapper/BUILD.bazel
rename to metropolis/node/common/devicemapper/BUILD.bazel
index 2395881..12ca0b3 100644
--- a/core/pkg/devicemapper/BUILD.bazel
+++ b/metropolis/node/common/devicemapper/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["devicemapper.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/devicemapper",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/devicemapper",
     visibility = ["//visibility:public"],
     deps = [
         "@com_github_pkg_errors//:go_default_library",
diff --git a/core/pkg/devicemapper/devicemapper.go b/metropolis/node/common/devicemapper/devicemapper.go
similarity index 100%
rename from core/pkg/devicemapper/devicemapper.go
rename to metropolis/node/common/devicemapper/devicemapper.go
diff --git a/core/pkg/fileargs/BUILD.bazel b/metropolis/node/common/fileargs/BUILD.bazel
similarity index 72%
rename from core/pkg/fileargs/BUILD.bazel
rename to metropolis/node/common/fileargs/BUILD.bazel
index 8107579..c4fffc2 100644
--- a/core/pkg/fileargs/BUILD.bazel
+++ b/metropolis/node/common/fileargs/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["fileargs.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/fileargs",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/fileargs",
     visibility = ["//visibility:public"],
     deps = ["@org_golang_x_sys//unix:go_default_library"],
 )
diff --git a/core/pkg/fileargs/fileargs.go b/metropolis/node/common/fileargs/fileargs.go
similarity index 100%
rename from core/pkg/fileargs/fileargs.go
rename to metropolis/node/common/fileargs/fileargs.go
diff --git a/core/pkg/fsquota/BUILD.bazel b/metropolis/node/common/fsquota/BUILD.bazel
similarity index 73%
rename from core/pkg/fsquota/BUILD.bazel
rename to metropolis/node/common/fsquota/BUILD.bazel
index 8feeede..b16d39e 100644
--- a/core/pkg/fsquota/BUILD.bazel
+++ b/metropolis/node/common/fsquota/BUILD.bazel
@@ -1,5 +1,5 @@
 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//core/tools/ktest:ktest.bzl", "ktest")
+load("//metropolis/test/ktest:ktest.bzl", "ktest")
 
 go_library(
     name = "go_default_library",
@@ -7,11 +7,11 @@
         "fsinfo.go",
         "fsquota.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/fsquota",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/fsquota",
     visibility = ["//visibility:public"],
     deps = [
-        "//core/pkg/fsquota/fsxattrs:go_default_library",
-        "//core/pkg/fsquota/quotactl:go_default_library",
+        "//metropolis/node/common/fsquota/fsxattrs:go_default_library",
+        "//metropolis/node/common/fsquota/quotactl:go_default_library",
         "@org_golang_x_sys//unix:go_default_library",
     ],
 )
diff --git a/core/pkg/fsquota/fsinfo.go b/metropolis/node/common/fsquota/fsinfo.go
similarity index 100%
rename from core/pkg/fsquota/fsinfo.go
rename to metropolis/node/common/fsquota/fsinfo.go
diff --git a/core/pkg/fsquota/fsquota.go b/metropolis/node/common/fsquota/fsquota.go
similarity index 96%
rename from core/pkg/fsquota/fsquota.go
rename to metropolis/node/common/fsquota/fsquota.go
index e2d871a..f702d23 100644
--- a/core/pkg/fsquota/fsquota.go
+++ b/metropolis/node/common/fsquota/fsquota.go
@@ -26,9 +26,10 @@
 	"math"
 	"os"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/fsquota/fsxattrs"
-	"git.monogon.dev/source/nexantic.git/core/pkg/fsquota/quotactl"
 	"golang.org/x/sys/unix"
+
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fsquota/fsxattrs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fsquota/quotactl"
 )
 
 // SetQuota sets the quota of bytes and/or inodes in a given path. To not set a limit, set the
diff --git a/core/pkg/fsquota/fsquota_test.go b/metropolis/node/common/fsquota/fsquota_test.go
similarity index 100%
rename from core/pkg/fsquota/fsquota_test.go
rename to metropolis/node/common/fsquota/fsquota_test.go
diff --git a/core/pkg/fsquota/fsxattrs/BUILD.bazel b/metropolis/node/common/fsquota/fsxattrs/BUILD.bazel
similarity index 70%
rename from core/pkg/fsquota/fsxattrs/BUILD.bazel
rename to metropolis/node/common/fsquota/fsxattrs/BUILD.bazel
index 64cbf9a..066200b 100644
--- a/core/pkg/fsquota/fsxattrs/BUILD.bazel
+++ b/metropolis/node/common/fsquota/fsxattrs/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["fsxattrs.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/fsquota/fsxattrs",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/fsquota/fsxattrs",
     visibility = ["//visibility:public"],
     deps = ["@org_golang_x_sys//unix:go_default_library"],
 )
diff --git a/core/pkg/fsquota/fsxattrs/fsxattrs.go b/metropolis/node/common/fsquota/fsxattrs/fsxattrs.go
similarity index 100%
rename from core/pkg/fsquota/fsxattrs/fsxattrs.go
rename to metropolis/node/common/fsquota/fsxattrs/fsxattrs.go
diff --git a/core/pkg/fsquota/quotactl/BUILD.bazel b/metropolis/node/common/fsquota/quotactl/BUILD.bazel
similarity index 70%
rename from core/pkg/fsquota/quotactl/BUILD.bazel
rename to metropolis/node/common/fsquota/quotactl/BUILD.bazel
index de5d085..c1582ad 100644
--- a/core/pkg/fsquota/quotactl/BUILD.bazel
+++ b/metropolis/node/common/fsquota/quotactl/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["quotactl.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/fsquota/quotactl",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/fsquota/quotactl",
     visibility = ["//visibility:public"],
     deps = ["@org_golang_x_sys//unix:go_default_library"],
 )
diff --git a/core/pkg/fsquota/quotactl/quotactl.go b/metropolis/node/common/fsquota/quotactl/quotactl.go
similarity index 100%
rename from core/pkg/fsquota/quotactl/quotactl.go
rename to metropolis/node/common/fsquota/quotactl/quotactl.go
diff --git a/core/pkg/jsonpatch/BUILD.bazel b/metropolis/node/common/jsonpatch/BUILD.bazel
similarity index 76%
rename from core/pkg/jsonpatch/BUILD.bazel
rename to metropolis/node/common/jsonpatch/BUILD.bazel
index c54fcfa..bd77e0a 100644
--- a/core/pkg/jsonpatch/BUILD.bazel
+++ b/metropolis/node/common/jsonpatch/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["jsonpatch.go.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/jsonpatch",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/jsonpatch",
     visibility = ["//visibility:public"],
 )
 
diff --git a/core/pkg/jsonpatch/jsonpatch.go.go b/metropolis/node/common/jsonpatch/jsonpatch.go.go
similarity index 100%
rename from core/pkg/jsonpatch/jsonpatch.go.go
rename to metropolis/node/common/jsonpatch/jsonpatch.go.go
diff --git a/core/pkg/jsonpatch/jsonpatch_test.go b/metropolis/node/common/jsonpatch/jsonpatch_test.go
similarity index 100%
rename from core/pkg/jsonpatch/jsonpatch_test.go
rename to metropolis/node/common/jsonpatch/jsonpatch_test.go
diff --git a/core/pkg/logbuffer/BUILD.bazel b/metropolis/node/common/logbuffer/BUILD.bazel
similarity index 75%
rename from core/pkg/logbuffer/BUILD.bazel
rename to metropolis/node/common/logbuffer/BUILD.bazel
index 958389e..2d4650d 100644
--- a/core/pkg/logbuffer/BUILD.bazel
+++ b/metropolis/node/common/logbuffer/BUILD.bazel
@@ -6,9 +6,9 @@
         "linebuffer.go",
         "logbuffer.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/logbuffer",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/logbuffer",
     visibility = ["//visibility:public"],
-    deps = ["//core/proto/api:go_default_library"],
+    deps = ["//metropolis/proto/api:go_default_library"],
 )
 
 go_test(
diff --git a/core/pkg/logbuffer/linebuffer.go b/metropolis/node/common/logbuffer/linebuffer.go
similarity index 98%
rename from core/pkg/logbuffer/linebuffer.go
rename to metropolis/node/common/logbuffer/linebuffer.go
index fa4dc33..246a91b 100644
--- a/core/pkg/logbuffer/linebuffer.go
+++ b/metropolis/node/common/logbuffer/linebuffer.go
@@ -22,7 +22,7 @@
 	"strings"
 	"sync"
 
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 // Line is a line stored in the log buffer - a string, that has been perhaps truncated (due to exceeded limits).
diff --git a/core/pkg/logbuffer/linebuffer_test.go b/metropolis/node/common/logbuffer/linebuffer_test.go
similarity index 100%
rename from core/pkg/logbuffer/linebuffer_test.go
rename to metropolis/node/common/logbuffer/linebuffer_test.go
diff --git a/core/pkg/logbuffer/logbuffer.go b/metropolis/node/common/logbuffer/logbuffer.go
similarity index 100%
rename from core/pkg/logbuffer/logbuffer.go
rename to metropolis/node/common/logbuffer/logbuffer.go
diff --git a/core/pkg/logbuffer/logbuffer_test.go b/metropolis/node/common/logbuffer/logbuffer_test.go
similarity index 100%
rename from core/pkg/logbuffer/logbuffer_test.go
rename to metropolis/node/common/logbuffer/logbuffer_test.go
diff --git a/core/internal/common/supervisor/BUILD.bazel b/metropolis/node/common/supervisor/BUILD.bazel
similarity index 67%
rename from core/internal/common/supervisor/BUILD.bazel
rename to metropolis/node/common/supervisor/BUILD.bazel
index 9f940f0..ae95892 100644
--- a/core/internal/common/supervisor/BUILD.bazel
+++ b/metropolis/node/common/supervisor/BUILD.bazel
@@ -9,10 +9,13 @@
         "supervisor_support.go",
         "supervisor_testhelpers.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/common/supervisor",
-    visibility = ["//core:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor",
+    visibility = [
+        "//metropolis/node:__subpackages__",
+        "//metropolis/test:__subpackages__",
+    ],
     deps = [
-        "//core/pkg/logtree:go_default_library",
+        "//metropolis/node/core/logtree:go_default_library",
         "@com_github_cenkalti_backoff_v4//:go_default_library",
         "@org_golang_google_grpc//:go_default_library",
     ],
diff --git a/core/internal/common/supervisor/supervisor.go b/metropolis/node/common/supervisor/supervisor.go
similarity index 98%
rename from core/internal/common/supervisor/supervisor.go
rename to metropolis/node/common/supervisor/supervisor.go
index ef8a9cd..df7492c 100644
--- a/core/internal/common/supervisor/supervisor.go
+++ b/metropolis/node/common/supervisor/supervisor.go
@@ -25,7 +25,7 @@
 	"io"
 	"sync"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
 )
 
 // A Runnable is a function that will be run in a goroutine, and supervised throughout its lifetime. It can in turn
diff --git a/core/internal/common/supervisor/supervisor_node.go b/metropolis/node/common/supervisor/supervisor_node.go
similarity index 100%
rename from core/internal/common/supervisor/supervisor_node.go
rename to metropolis/node/common/supervisor/supervisor_node.go
diff --git a/core/internal/common/supervisor/supervisor_processor.go b/metropolis/node/common/supervisor/supervisor_processor.go
similarity index 100%
rename from core/internal/common/supervisor/supervisor_processor.go
rename to metropolis/node/common/supervisor/supervisor_processor.go
diff --git a/core/internal/common/supervisor/supervisor_support.go b/metropolis/node/common/supervisor/supervisor_support.go
similarity index 100%
rename from core/internal/common/supervisor/supervisor_support.go
rename to metropolis/node/common/supervisor/supervisor_support.go
diff --git a/core/internal/common/supervisor/supervisor_test.go b/metropolis/node/common/supervisor/supervisor_test.go
similarity index 100%
rename from core/internal/common/supervisor/supervisor_test.go
rename to metropolis/node/common/supervisor/supervisor_test.go
diff --git a/core/internal/common/supervisor/supervisor_testhelpers.go b/metropolis/node/common/supervisor/supervisor_testhelpers.go
similarity index 100%
rename from core/internal/common/supervisor/supervisor_testhelpers.go
rename to metropolis/node/common/supervisor/supervisor_testhelpers.go
diff --git a/core/pkg/sysfs/BUILD.bazel b/metropolis/node/common/sysfs/BUILD.bazel
similarity index 66%
rename from core/pkg/sysfs/BUILD.bazel
rename to metropolis/node/common/sysfs/BUILD.bazel
index 4272089..a4c7f18 100644
--- a/core/pkg/sysfs/BUILD.bazel
+++ b/metropolis/node/common/sysfs/BUILD.bazel
@@ -3,6 +3,6 @@
 go_library(
     name = "go_default_library",
     srcs = ["uevents.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/sysfs",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/common/sysfs",
     visibility = ["//visibility:public"],
 )
diff --git a/core/pkg/sysfs/uevents.go b/metropolis/node/common/sysfs/uevents.go
similarity index 100%
rename from core/pkg/sysfs/uevents.go
rename to metropolis/node/common/sysfs/uevents.go
diff --git a/metropolis/node/core/BUILD.bazel b/metropolis/node/core/BUILD.bazel
new file mode 100644
index 0000000..2398205
--- /dev/null
+++ b/metropolis/node/core/BUILD.bazel
@@ -0,0 +1,43 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+go_library(
+    name = "go_default_library",
+    # keep
+    srcs = [
+        "debug_service.go",
+        "main.go",
+        "switchroot.go",
+    ] + select({
+        "//metropolis/node:debug_build": ["delve_enabled.go"],
+        "//conditions:default": ["delve_disabled.go"],
+    }),
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core",
+    visibility = ["//visibility:private"],
+    deps = [
+        "//metropolis/node:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/cluster:go_default_library",
+        "//metropolis/node/core/consensus/ca:go_default_library",
+        "//metropolis/node/core/localstorage:go_default_library",
+        "//metropolis/node/core/localstorage/declarative:go_default_library",
+        "//metropolis/node/core/logtree:go_default_library",
+        "//metropolis/node/core/network:go_default_library",
+        "//metropolis/node/core/network/dns:go_default_library",
+        "//metropolis/node/core/tpm:go_default_library",
+        "//metropolis/node/kubernetes:go_default_library",
+        "//metropolis/node/kubernetes/containerd:go_default_library",
+        "//metropolis/node/kubernetes/pki:go_default_library",
+        "//metropolis/proto/api:go_default_library",
+        "@org_golang_google_grpc//:go_default_library",
+        "@org_golang_google_grpc//codes:go_default_library",
+        "@org_golang_google_grpc//status:go_default_library",
+        "@org_golang_x_sys//unix:go_default_library",
+    ],
+)
+
+go_binary(
+    name = "core",
+    embed = [":go_default_library"],
+    pure = "on",  # keep
+    visibility = ["//visibility:public"],
+)
diff --git a/metropolis/node/core/cluster/BUILD.bazel b/metropolis/node/core/cluster/BUILD.bazel
new file mode 100644
index 0000000..70daba2
--- /dev/null
+++ b/metropolis/node/core/cluster/BUILD.bazel
@@ -0,0 +1,25 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "manager.go",
+        "node.go",
+    ],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/cluster",
+    visibility = ["//metropolis/node/core:__subpackages__"],
+    deps = [
+        "//metropolis/node:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/consensus:go_default_library",
+        "//metropolis/node/core/localstorage:go_default_library",
+        "//metropolis/node/core/localstorage/declarative:go_default_library",
+        "//metropolis/node/core/network:go_default_library",
+        "//metropolis/proto/api:go_default_library",
+        "//metropolis/proto/internal:go_default_library",
+        "@com_github_cenkalti_backoff_v4//:go_default_library",
+        "@com_github_golang_protobuf//proto:go_default_library",
+        "@io_etcd_go_etcd//clientv3:go_default_library",
+        "@org_golang_x_sys//unix:go_default_library",
+    ],
+)
diff --git a/core/internal/cluster/manager.go b/metropolis/node/core/cluster/manager.go
similarity index 97%
rename from core/internal/cluster/manager.go
rename to metropolis/node/core/cluster/manager.go
index 2f1355b..6bb87f4 100644
--- a/core/internal/cluster/manager.go
+++ b/metropolis/node/core/cluster/manager.go
@@ -27,18 +27,17 @@
 	"sync"
 	"time"
 
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
-
 	"github.com/cenkalti/backoff/v4"
 	"github.com/golang/protobuf/proto"
 	"go.etcd.io/etcd/clientv3"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/consensus"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
-	"git.monogon.dev/source/nexantic.git/core/internal/network"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/consensus"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 // Manager is a finite state machine that joins this node (ie., Smalltown instance running on a virtual/physical machine)
diff --git a/core/internal/cluster/node.go b/metropolis/node/core/cluster/node.go
similarity index 96%
rename from core/internal/cluster/node.go
rename to metropolis/node/core/cluster/node.go
index 841529d..449c2ff 100644
--- a/core/internal/cluster/node.go
+++ b/metropolis/node/core/cluster/node.go
@@ -28,13 +28,13 @@
 	"go.etcd.io/etcd/clientv3"
 	"golang.org/x/sys/unix"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	ipb "git.monogon.dev/source/nexantic.git/core/proto/internal"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	ipb "git.monogon.dev/source/nexantic.git/metropolis/proto/internal"
 )
 
 // Node is a Smalltown cluster member. A node is a virtual or physical machine running Smalltown. This object represents a
-// node only as part of a Cluster - ie., this object will never be available outside of //core/internal/cluster if the
-// Node is not part of a Cluster.
+// node only as part of a Cluster - ie., this object will never be available outside of //metropolis/node/core/cluster
+// if the Node is not part of a Cluster.
 // Nodes are inherently tied to their long term storage, which is etcd. As such, methods on this object relate heavily
 // to the Node's expected lifecycle on etcd.
 type Node struct {
diff --git a/metropolis/node/core/consensus/BUILD.bazel b/metropolis/node/core/consensus/BUILD.bazel
new file mode 100644
index 0000000..cab2c0a
--- /dev/null
+++ b/metropolis/node/core/consensus/BUILD.bazel
@@ -0,0 +1,30 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+    name = "go_default_library",
+    srcs = ["consensus.go"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/consensus",
+    visibility = ["//:__subpackages__"],
+    deps = [
+        "//metropolis/node:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/consensus/ca:go_default_library",
+        "//metropolis/node/core/localstorage:go_default_library",
+        "@io_etcd_go_etcd//clientv3:go_default_library",
+        "@io_etcd_go_etcd//clientv3/namespace:go_default_library",
+        "@io_etcd_go_etcd//embed:go_default_library",
+        "@org_uber_go_atomic//:go_default_library",
+    ],
+)
+
+go_test(
+    name = "go_default_test",
+    srcs = ["consensus_test.go"],
+    embed = [":go_default_library"],
+    deps = [
+        "//golibs/common:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/localstorage:go_default_library",
+        "//metropolis/node/core/localstorage/declarative:go_default_library",
+    ],
+)
diff --git a/core/internal/consensus/ca/BUILD.bazel b/metropolis/node/core/consensus/ca/BUILD.bazel
similarity index 71%
rename from core/internal/consensus/ca/BUILD.bazel
rename to metropolis/node/core/consensus/ca/BUILD.bazel
index 5f3c006..fecffa0 100644
--- a/core/internal/consensus/ca/BUILD.bazel
+++ b/metropolis/node/core/consensus/ca/BUILD.bazel
@@ -3,7 +3,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["ca.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/consensus/ca",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/consensus/ca",
     visibility = ["//:__subpackages__"],
     deps = ["@io_etcd_go_etcd//clientv3:go_default_library"],
 )
diff --git a/core/internal/consensus/ca/ca.go b/metropolis/node/core/consensus/ca/ca.go
similarity index 100%
rename from core/internal/consensus/ca/ca.go
rename to metropolis/node/core/consensus/ca/ca.go
diff --git a/core/internal/consensus/consensus.go b/metropolis/node/core/consensus/consensus.go
similarity index 97%
rename from core/internal/consensus/consensus.go
rename to metropolis/node/core/consensus/consensus.go
index 1403964..8916164 100644
--- a/core/internal/consensus/consensus.go
+++ b/metropolis/node/core/consensus/consensus.go
@@ -44,10 +44,10 @@
 	"go.etcd.io/etcd/embed"
 	"go.uber.org/atomic"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/consensus/ca"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/consensus/ca"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
 )
 
 const (
diff --git a/core/internal/consensus/consensus_test.go b/metropolis/node/core/consensus/consensus_test.go
similarity index 96%
rename from core/internal/consensus/consensus_test.go
rename to metropolis/node/core/consensus/consensus_test.go
index a308cf4..e08bd29 100644
--- a/core/internal/consensus/consensus_test.go
+++ b/metropolis/node/core/consensus/consensus_test.go
@@ -26,10 +26,10 @@
 	"testing"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
 	"git.monogon.dev/source/nexantic.git/golibs/common"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
 )
 
 type boilerplate struct {
diff --git a/core/cmd/init/debug_service.go b/metropolis/node/core/debug_service.go
similarity index 94%
rename from core/cmd/init/debug_service.go
rename to metropolis/node/core/debug_service.go
index 6cb9620..0155cc6 100644
--- a/core/cmd/init/debug_service.go
+++ b/metropolis/node/core/debug_service.go
@@ -25,12 +25,12 @@
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/cluster"
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/consensus/ca"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes"
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/cluster"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/consensus/ca"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 const (
diff --git a/core/cmd/init/delve_disabled.go b/metropolis/node/core/delve_disabled.go
similarity index 90%
rename from core/cmd/init/delve_disabled.go
rename to metropolis/node/core/delve_disabled.go
index 06bcad0..cb0a59b 100644
--- a/core/cmd/init/delve_disabled.go
+++ b/metropolis/node/core/delve_disabled.go
@@ -16,7 +16,7 @@
 
 package main
 
-import "git.monogon.dev/source/nexantic.git/core/internal/network"
+import "git.monogon.dev/source/nexantic.git/metropolis/node/core/network"
 
 // initializeDebugger does nothing in a non-debug build
 func initializeDebugger(*network.Service) {
diff --git a/core/cmd/init/delve_enabled.go b/metropolis/node/core/delve_enabled.go
similarity index 92%
rename from core/cmd/init/delve_enabled.go
rename to metropolis/node/core/delve_enabled.go
index 1c2af00..b3b859c 100644
--- a/core/cmd/init/delve_enabled.go
+++ b/metropolis/node/core/delve_enabled.go
@@ -21,8 +21,7 @@
 	"fmt"
 	"os/exec"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/network"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network"
 )
 
 // initializeDebugger attaches Delve to ourselves and exposes it on common.DebuggerPort
diff --git a/metropolis/node/core/localstorage/BUILD.bazel b/metropolis/node/core/localstorage/BUILD.bazel
new file mode 100644
index 0000000..099a380
--- /dev/null
+++ b/metropolis/node/core/localstorage/BUILD.bazel
@@ -0,0 +1,26 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "directory_data.go",
+        "directory_pki.go",
+        "directory_root.go",
+        "storage.go",
+    ],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage",
+    visibility = ["//metropolis/node:__subpackages__"],
+    deps = [
+        "//metropolis/node/core/localstorage/crypt:go_default_library",
+        "//metropolis/node/core/localstorage/declarative:go_default_library",
+        "//metropolis/node/core/tpm:go_default_library",
+        "@org_golang_x_sys//unix:go_default_library",
+    ],
+)
+
+go_test(
+    name = "go_default_test",
+    srcs = ["storage_test.go"],
+    embed = [":go_default_library"],
+    deps = ["//metropolis/node/core/localstorage/declarative:go_default_library"],
+)
diff --git a/metropolis/node/core/localstorage/crypt/BUILD.bazel b/metropolis/node/core/localstorage/crypt/BUILD.bazel
new file mode 100644
index 0000000..38e27d6
--- /dev/null
+++ b/metropolis/node/core/localstorage/crypt/BUILD.bazel
@@ -0,0 +1,17 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "blockdev.go",
+        "crypt.go",
+    ],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/crypt",
+    visibility = ["//metropolis/node/core/localstorage:__subpackages__"],
+    deps = [
+        "//metropolis/node/common/devicemapper:go_default_library",
+        "//metropolis/node/common/sysfs:go_default_library",
+        "@com_github_rekby_gpt//:go_default_library",
+        "@org_golang_x_sys//unix:go_default_library",
+    ],
+)
diff --git a/core/internal/localstorage/crypt/blockdev.go b/metropolis/node/core/localstorage/crypt/blockdev.go
similarity index 97%
rename from core/internal/localstorage/crypt/blockdev.go
rename to metropolis/node/core/localstorage/crypt/blockdev.go
index b1886dc..df5f590 100644
--- a/core/internal/localstorage/crypt/blockdev.go
+++ b/metropolis/node/core/localstorage/crypt/blockdev.go
@@ -27,7 +27,7 @@
 	"github.com/rekby/gpt"
 	"golang.org/x/sys/unix"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/sysfs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/sysfs"
 )
 
 var (
diff --git a/core/internal/localstorage/crypt/crypt.go b/metropolis/node/core/localstorage/crypt/crypt.go
similarity index 98%
rename from core/internal/localstorage/crypt/crypt.go
rename to metropolis/node/core/localstorage/crypt/crypt.go
index ba2e8d2..e0a8321 100644
--- a/core/internal/localstorage/crypt/crypt.go
+++ b/metropolis/node/core/localstorage/crypt/crypt.go
@@ -23,9 +23,9 @@
 	"os"
 	"syscall"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/devicemapper"
-
 	"golang.org/x/sys/unix"
+
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/devicemapper"
 )
 
 func readDataSectors(path string) (uint64, error) {
diff --git a/core/internal/localstorage/declarative/BUILD.bazel b/metropolis/node/core/localstorage/declarative/BUILD.bazel
similarity index 62%
rename from core/internal/localstorage/declarative/BUILD.bazel
rename to metropolis/node/core/localstorage/declarative/BUILD.bazel
index c181fd1..5b51aa2 100644
--- a/core/internal/localstorage/declarative/BUILD.bazel
+++ b/metropolis/node/core/localstorage/declarative/BUILD.bazel
@@ -7,7 +7,7 @@
         "placement.go",
         "placement_local.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative",
-    visibility = ["//core:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative",
+    visibility = ["//metropolis/node:__subpackages__"],
     deps = ["@org_golang_x_sys//unix:go_default_library"],
 )
diff --git a/core/internal/localstorage/declarative/declarative.go b/metropolis/node/core/localstorage/declarative/declarative.go
similarity index 100%
rename from core/internal/localstorage/declarative/declarative.go
rename to metropolis/node/core/localstorage/declarative/declarative.go
diff --git a/core/internal/localstorage/declarative/placement.go b/metropolis/node/core/localstorage/declarative/placement.go
similarity index 100%
rename from core/internal/localstorage/declarative/placement.go
rename to metropolis/node/core/localstorage/declarative/placement.go
diff --git a/core/internal/localstorage/declarative/placement_local.go b/metropolis/node/core/localstorage/declarative/placement_local.go
similarity index 100%
rename from core/internal/localstorage/declarative/placement_local.go
rename to metropolis/node/core/localstorage/declarative/placement_local.go
diff --git a/core/internal/localstorage/directory_data.go b/metropolis/node/core/localstorage/directory_data.go
similarity index 94%
rename from core/internal/localstorage/directory_data.go
rename to metropolis/node/core/localstorage/directory_data.go
index 60f030d..e90dc48 100644
--- a/core/internal/localstorage/directory_data.go
+++ b/metropolis/node/core/localstorage/directory_data.go
@@ -21,12 +21,11 @@
 	"os"
 	"os/exec"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
-
 	"golang.org/x/sys/unix"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/crypt"
-	"git.monogon.dev/source/nexantic.git/core/pkg/tpm"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/crypt"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/tpm"
 )
 
 var keySize uint16 = 256 / 8
diff --git a/core/internal/localstorage/directory_pki.go b/metropolis/node/core/localstorage/directory_pki.go
similarity index 97%
rename from core/internal/localstorage/directory_pki.go
rename to metropolis/node/core/localstorage/directory_pki.go
index f6ebb11..6bdebff 100644
--- a/core/internal/localstorage/directory_pki.go
+++ b/metropolis/node/core/localstorage/directory_pki.go
@@ -27,7 +27,7 @@
 	"math/big"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
 )
 
 var (
diff --git a/core/internal/localstorage/directory_root.go b/metropolis/node/core/localstorage/directory_root.go
similarity index 93%
rename from core/internal/localstorage/directory_root.go
rename to metropolis/node/core/localstorage/directory_root.go
index 128cb49..883d1e2 100644
--- a/core/internal/localstorage/directory_root.go
+++ b/metropolis/node/core/localstorage/directory_root.go
@@ -23,8 +23,8 @@
 
 	"golang.org/x/sys/unix"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/crypt"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/crypt"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
 )
 
 func (r *Root) Start(ctx context.Context) error {
diff --git a/core/internal/localstorage/storage.go b/metropolis/node/core/localstorage/storage.go
similarity index 98%
rename from core/internal/localstorage/storage.go
rename to metropolis/node/core/localstorage/storage.go
index 26edae7..8cc291f 100644
--- a/core/internal/localstorage/storage.go
+++ b/metropolis/node/core/localstorage/storage.go
@@ -34,7 +34,7 @@
 import (
 	"sync"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
 )
 
 type Root struct {
diff --git a/core/internal/localstorage/storage_test.go b/metropolis/node/core/localstorage/storage_test.go
similarity index 94%
rename from core/internal/localstorage/storage_test.go
rename to metropolis/node/core/localstorage/storage_test.go
index d676cb5..8029d02 100644
--- a/core/internal/localstorage/storage_test.go
+++ b/metropolis/node/core/localstorage/storage_test.go
@@ -19,7 +19,7 @@
 import (
 	"testing"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
 )
 
 func TestValidateAll(t *testing.T) {
diff --git a/core/pkg/logtree/BUILD.bazel b/metropolis/node/core/logtree/BUILD.bazel
similarity index 74%
rename from core/pkg/logtree/BUILD.bazel
rename to metropolis/node/core/logtree/BUILD.bazel
index 89aab90..120bf9f 100644
--- a/core/pkg/logtree/BUILD.bazel
+++ b/metropolis/node/core/logtree/BUILD.bazel
@@ -14,11 +14,11 @@
         "logtree_entry.go",
         "logtree_publisher.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/logtree",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree",
     visibility = ["//visibility:public"],
     deps = [
-        "//core/pkg/logbuffer:go_default_library",
-        "//core/proto/api:go_default_library",
+        "//metropolis/node/common/logbuffer:go_default_library",
+        "//metropolis/proto/api:go_default_library",
     ],
 )
 
diff --git a/core/pkg/logtree/doc.go b/metropolis/node/core/logtree/doc.go
similarity index 100%
rename from core/pkg/logtree/doc.go
rename to metropolis/node/core/logtree/doc.go
diff --git a/core/pkg/logtree/journal.go b/metropolis/node/core/logtree/journal.go
similarity index 100%
rename from core/pkg/logtree/journal.go
rename to metropolis/node/core/logtree/journal.go
diff --git a/core/pkg/logtree/journal_entry.go b/metropolis/node/core/logtree/journal_entry.go
similarity index 98%
rename from core/pkg/logtree/journal_entry.go
rename to metropolis/node/core/logtree/journal_entry.go
index bc65ef3..61619b3 100644
--- a/core/pkg/logtree/journal_entry.go
+++ b/metropolis/node/core/logtree/journal_entry.go
@@ -16,7 +16,7 @@
 
 package logtree
 
-import "git.monogon.dev/source/nexantic.git/core/pkg/logbuffer"
+import "git.monogon.dev/source/nexantic.git/metropolis/node/common/logbuffer"
 
 // entry is a journal entry, representing a single log event (encompassed in a Payload) at a given DN.
 // See the journal struct for more information about the global/local linked lists.
diff --git a/core/pkg/logtree/journal_subscriber.go b/metropolis/node/core/logtree/journal_subscriber.go
similarity index 100%
rename from core/pkg/logtree/journal_subscriber.go
rename to metropolis/node/core/logtree/journal_subscriber.go
diff --git a/core/pkg/logtree/journal_test.go b/metropolis/node/core/logtree/journal_test.go
similarity index 100%
rename from core/pkg/logtree/journal_test.go
rename to metropolis/node/core/logtree/journal_test.go
diff --git a/core/pkg/logtree/leveled.go b/metropolis/node/core/logtree/leveled.go
similarity index 98%
rename from core/pkg/logtree/leveled.go
rename to metropolis/node/core/logtree/leveled.go
index 125e1df..c24357e 100644
--- a/core/pkg/logtree/leveled.go
+++ b/metropolis/node/core/logtree/leveled.go
@@ -19,7 +19,7 @@
 import (
 	"fmt"
 
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 // LeveledLogger is a generic interface for glog-style logging. There are four hardcoded log severities, in increasing
diff --git a/core/pkg/logtree/leveled_payload.go b/metropolis/node/core/logtree/leveled_payload.go
similarity index 98%
rename from core/pkg/logtree/leveled_payload.go
rename to metropolis/node/core/logtree/leveled_payload.go
index 6338118..fad42e3 100644
--- a/core/pkg/logtree/leveled_payload.go
+++ b/metropolis/node/core/logtree/leveled_payload.go
@@ -22,7 +22,7 @@
 	"strings"
 	"time"
 
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 // LeveledPayload is a log entry for leveled logs (as per leveled.go). It contains the input to these calls (severity and
diff --git a/core/pkg/logtree/logtree.go b/metropolis/node/core/logtree/logtree.go
similarity index 98%
rename from core/pkg/logtree/logtree.go
rename to metropolis/node/core/logtree/logtree.go
index 2d405f8..fab72ba 100644
--- a/core/pkg/logtree/logtree.go
+++ b/metropolis/node/core/logtree/logtree.go
@@ -21,7 +21,7 @@
 	"strings"
 	"sync"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logbuffer"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/logbuffer"
 )
 
 // LogTree is a tree-shaped logging system. For more information, see the package-level documentation.
diff --git a/core/pkg/logtree/logtree_access.go b/metropolis/node/core/logtree/logtree_access.go
similarity index 100%
rename from core/pkg/logtree/logtree_access.go
rename to metropolis/node/core/logtree/logtree_access.go
diff --git a/core/pkg/logtree/logtree_entry.go b/metropolis/node/core/logtree/logtree_entry.go
similarity index 96%
rename from core/pkg/logtree/logtree_entry.go
rename to metropolis/node/core/logtree/logtree_entry.go
index 81d1a42..635e5a8 100644
--- a/core/pkg/logtree/logtree_entry.go
+++ b/metropolis/node/core/logtree/logtree_entry.go
@@ -20,8 +20,8 @@
 	"fmt"
 	"strings"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logbuffer"
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/logbuffer"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 // LogEntry contains a log entry, combining both leveled and raw logging into a single stream of events. A LogEntry
diff --git a/core/pkg/logtree/logtree_publisher.go b/metropolis/node/core/logtree/logtree_publisher.go
similarity index 98%
rename from core/pkg/logtree/logtree_publisher.go
rename to metropolis/node/core/logtree/logtree_publisher.go
index 190ef7e..c4880bc 100644
--- a/core/pkg/logtree/logtree_publisher.go
+++ b/metropolis/node/core/logtree/logtree_publisher.go
@@ -23,7 +23,7 @@
 	"strings"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logbuffer"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/logbuffer"
 )
 
 // LeveledFor returns a LeveledLogger publishing interface for a given DN. An error may be returned if the DN is
diff --git a/core/pkg/logtree/logtree_test.go b/metropolis/node/core/logtree/logtree_test.go
similarity index 100%
rename from core/pkg/logtree/logtree_test.go
rename to metropolis/node/core/logtree/logtree_test.go
diff --git a/core/cmd/init/main.go b/metropolis/node/core/main.go
similarity index 91%
rename from core/cmd/init/main.go
rename to metropolis/node/core/main.go
index 4ba991c..54d09a4 100644
--- a/core/cmd/init/main.go
+++ b/metropolis/node/core/main.go
@@ -32,19 +32,19 @@
 	"golang.org/x/sys/unix"
 	"google.golang.org/grpc"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/cluster"
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/containerd"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/pki"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
-	"git.monogon.dev/source/nexantic.git/core/internal/network"
-	"git.monogon.dev/source/nexantic.git/core/internal/network/dns"
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-	"git.monogon.dev/source/nexantic.git/core/pkg/tpm"
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/cluster"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dns"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/tpm"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/containerd"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/pki"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 var (
diff --git a/metropolis/node/core/network/BUILD.bazel b/metropolis/node/core/network/BUILD.bazel
new file mode 100644
index 0000000..9ba56a9
--- /dev/null
+++ b/metropolis/node/core/network/BUILD.bazel
@@ -0,0 +1,20 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = ["main.go"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/network",
+    visibility = ["//:__subpackages__"],
+    deps = [
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/logtree:go_default_library",
+        "//metropolis/node/core/network/dhcp4c:go_default_library",
+        "//metropolis/node/core/network/dhcp4c/callback:go_default_library",
+        "//metropolis/node/core/network/dns:go_default_library",
+        "@com_github_google_nftables//:go_default_library",
+        "@com_github_google_nftables//expr:go_default_library",
+        "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
+        "@com_github_vishvananda_netlink//:go_default_library",
+        "@org_golang_x_sys//unix:go_default_library",
+    ],
+)
diff --git a/core/pkg/dhcp4c/BUILD.bazel b/metropolis/node/core/network/dhcp4c/BUILD.bazel
similarity index 72%
rename from core/pkg/dhcp4c/BUILD.bazel
rename to metropolis/node/core/network/dhcp4c/BUILD.bazel
index a3fcb2b..19b4c70 100644
--- a/core/pkg/dhcp4c/BUILD.bazel
+++ b/metropolis/node/core/network/dhcp4c/BUILD.bazel
@@ -7,11 +7,11 @@
         "doc.go",
         "lease.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c",
     visibility = ["//visibility:public"],
     deps = [
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/pkg/dhcp4c/transport:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/network/dhcp4c/transport:go_default_library",
         "@com_github_cenkalti_backoff_v4//:go_default_library",
         "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
         "@com_github_insomniacslk_dhcp//iana:go_default_library",
@@ -27,7 +27,7 @@
     embed = [":go_default_library"],
     pure = "on",
     deps = [
-        "//core/pkg/dhcp4c/transport:go_default_library",
+        "//metropolis/node/core/network/dhcp4c/transport:go_default_library",
         "@com_github_cenkalti_backoff_v4//:go_default_library",
         "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
         "@com_github_stretchr_testify//assert:go_default_library",
diff --git a/core/pkg/dhcp4c/callback/BUILD.bazel b/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel
similarity index 75%
rename from core/pkg/dhcp4c/callback/BUILD.bazel
rename to metropolis/node/core/network/dhcp4c/callback/BUILD.bazel
index 802bf11..ed6f330 100644
--- a/core/pkg/dhcp4c/callback/BUILD.bazel
+++ b/metropolis/node/core/network/dhcp4c/callback/BUILD.bazel
@@ -1,13 +1,13 @@
 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("//core/tools/ktest:ktest.bzl", "ktest")
+load("//metropolis/test/ktest:ktest.bzl", "ktest")
 
 go_library(
     name = "go_default_library",
     srcs = ["callback.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/callback",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c/callback",
     visibility = ["//visibility:public"],
     deps = [
-        "//core/pkg/dhcp4c:go_default_library",
+        "//metropolis/node/core/network/dhcp4c:go_default_library",
         "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
         "@com_github_vishvananda_netlink//:go_default_library",
         "@org_golang_x_sys//unix:go_default_library",
@@ -20,7 +20,7 @@
     embed = [":go_default_library"],
     pure = "on",
     deps = [
-        "//core/pkg/dhcp4c:go_default_library",
+        "//metropolis/node/core/network/dhcp4c:go_default_library",
         "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
         "@com_github_stretchr_testify//require:go_default_library",
         "@com_github_vishvananda_netlink//:go_default_library",
diff --git a/core/pkg/dhcp4c/callback/callback.go b/metropolis/node/core/network/dhcp4c/callback/callback.go
similarity index 98%
rename from core/pkg/dhcp4c/callback/callback.go
rename to metropolis/node/core/network/dhcp4c/callback/callback.go
index a1f06bc..10eb6ba 100644
--- a/core/pkg/dhcp4c/callback/callback.go
+++ b/metropolis/node/core/network/dhcp4c/callback/callback.go
@@ -30,7 +30,7 @@
 	"os"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c"
 
 	"github.com/insomniacslk/dhcp/dhcpv4"
 	"github.com/vishvananda/netlink"
diff --git a/core/pkg/dhcp4c/callback/callback_test.go b/metropolis/node/core/network/dhcp4c/callback/callback_test.go
similarity index 98%
rename from core/pkg/dhcp4c/callback/callback_test.go
rename to metropolis/node/core/network/dhcp4c/callback/callback_test.go
index cf99127..d533044 100644
--- a/core/pkg/dhcp4c/callback/callback_test.go
+++ b/metropolis/node/core/network/dhcp4c/callback/callback_test.go
@@ -24,7 +24,7 @@
 	"testing"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c"
 
 	"github.com/insomniacslk/dhcp/dhcpv4"
 	"github.com/stretchr/testify/require"
diff --git a/core/pkg/dhcp4c/dhcpc.go b/metropolis/node/core/network/dhcp4c/dhcpc.go
similarity index 98%
rename from core/pkg/dhcp4c/dhcpc.go
rename to metropolis/node/core/network/dhcp4c/dhcpc.go
index 0811890..4352506 100644
--- a/core/pkg/dhcp4c/dhcpc.go
+++ b/metropolis/node/core/network/dhcp4c/dhcpc.go
@@ -34,8 +34,8 @@
 	"github.com/insomniacslk/dhcp/dhcpv4"
 	"github.com/insomniacslk/dhcp/iana"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/transport"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c/transport"
 )
 
 type state int
diff --git a/core/pkg/dhcp4c/dhcpc_test.go b/metropolis/node/core/network/dhcp4c/dhcpc_test.go
similarity index 99%
rename from core/pkg/dhcp4c/dhcpc_test.go
rename to metropolis/node/core/network/dhcp4c/dhcpc_test.go
index 4c5fb11..6988da2 100644
--- a/core/pkg/dhcp4c/dhcpc_test.go
+++ b/metropolis/node/core/network/dhcp4c/dhcpc_test.go
@@ -27,7 +27,7 @@
 	"github.com/insomniacslk/dhcp/dhcpv4"
 	"github.com/stretchr/testify/assert"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/transport"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c/transport"
 )
 
 type fakeTime struct {
diff --git a/core/pkg/dhcp4c/doc.go b/metropolis/node/core/network/dhcp4c/doc.go
similarity index 100%
rename from core/pkg/dhcp4c/doc.go
rename to metropolis/node/core/network/dhcp4c/doc.go
diff --git a/core/pkg/dhcp4c/lease.go b/metropolis/node/core/network/dhcp4c/lease.go
similarity index 100%
rename from core/pkg/dhcp4c/lease.go
rename to metropolis/node/core/network/dhcp4c/lease.go
diff --git a/core/pkg/dhcp4c/lease_test.go b/metropolis/node/core/network/dhcp4c/lease_test.go
similarity index 100%
rename from core/pkg/dhcp4c/lease_test.go
rename to metropolis/node/core/network/dhcp4c/lease_test.go
diff --git a/core/pkg/dhcp4c/transport/BUILD.bazel b/metropolis/node/core/network/dhcp4c/transport/BUILD.bazel
similarity index 85%
rename from core/pkg/dhcp4c/transport/BUILD.bazel
rename to metropolis/node/core/network/dhcp4c/transport/BUILD.bazel
index 7ee17f6..edd47a1 100644
--- a/core/pkg/dhcp4c/transport/BUILD.bazel
+++ b/metropolis/node/core/network/dhcp4c/transport/BUILD.bazel
@@ -7,7 +7,7 @@
         "transport_broadcast.go",
         "transport_unicast.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/transport",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c/transport",
     visibility = ["//visibility:public"],
     deps = [
         "@com_github_google_gopacket//:go_default_library",
diff --git a/core/pkg/dhcp4c/transport/transport.go b/metropolis/node/core/network/dhcp4c/transport/transport.go
similarity index 100%
rename from core/pkg/dhcp4c/transport/transport.go
rename to metropolis/node/core/network/dhcp4c/transport/transport.go
diff --git a/core/pkg/dhcp4c/transport/transport_broadcast.go b/metropolis/node/core/network/dhcp4c/transport/transport_broadcast.go
similarity index 100%
rename from core/pkg/dhcp4c/transport/transport_broadcast.go
rename to metropolis/node/core/network/dhcp4c/transport/transport_broadcast.go
diff --git a/core/pkg/dhcp4c/transport/transport_unicast.go b/metropolis/node/core/network/dhcp4c/transport/transport_unicast.go
similarity index 100%
rename from core/pkg/dhcp4c/transport/transport_unicast.go
rename to metropolis/node/core/network/dhcp4c/transport/transport_unicast.go
diff --git a/metropolis/node/core/network/dns/BUILD.bazel b/metropolis/node/core/network/dns/BUILD.bazel
new file mode 100644
index 0000000..862d4cf
--- /dev/null
+++ b/metropolis/node/core/network/dns/BUILD.bazel
@@ -0,0 +1,15 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "coredns.go",
+        "directives.go",
+    ],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dns",
+    visibility = ["//metropolis/node:__subpackages__"],
+    deps = [
+        "//metropolis/node/common/fileargs:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+    ],
+)
diff --git a/core/internal/network/dns/coredns.go b/metropolis/node/core/network/dns/coredns.go
similarity index 96%
rename from core/internal/network/dns/coredns.go
rename to metropolis/node/core/network/dns/coredns.go
index a9fdc0f..b6400f7 100644
--- a/core/internal/network/dns/coredns.go
+++ b/metropolis/node/core/network/dns/coredns.go
@@ -26,8 +26,8 @@
 	"sync"
 	"syscall"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/pkg/fileargs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fileargs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
 )
 
 const corefileBase = `
diff --git a/core/internal/network/dns/directives.go b/metropolis/node/core/network/dns/directives.go
similarity index 100%
rename from core/internal/network/dns/directives.go
rename to metropolis/node/core/network/dns/directives.go
diff --git a/core/internal/network/main.go b/metropolis/node/core/network/main.go
similarity index 94%
rename from core/internal/network/main.go
rename to metropolis/node/core/network/main.go
index e0bac79..29e757d 100644
--- a/core/internal/network/main.go
+++ b/metropolis/node/core/network/main.go
@@ -32,11 +32,11 @@
 	"github.com/vishvananda/netlink"
 	"golang.org/x/sys/unix"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/network/dns"
-	"git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c"
-	dhcpcb "git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/callback"
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c"
+	dhcpcb "git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c/callback"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dns"
 )
 
 const (
diff --git a/core/cmd/init/switchroot.go b/metropolis/node/core/switchroot.go
similarity index 98%
rename from core/cmd/init/switchroot.go
rename to metropolis/node/core/switchroot.go
index 8308a25..5865225 100644
--- a/core/cmd/init/switchroot.go
+++ b/metropolis/node/core/switchroot.go
@@ -25,9 +25,9 @@
 	"strings"
 	"syscall"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-
 	"golang.org/x/sys/unix"
+
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
 )
 
 // switchRoot moves the root from initramfs into a tmpfs
diff --git a/core/pkg/tpm/BUILD.bazel b/metropolis/node/core/tpm/BUILD.bazel
similarity index 76%
rename from core/pkg/tpm/BUILD.bazel
rename to metropolis/node/core/tpm/BUILD.bazel
index 648a9db..fd42681 100644
--- a/core/pkg/tpm/BUILD.bazel
+++ b/metropolis/node/core/tpm/BUILD.bazel
@@ -6,11 +6,11 @@
         "credactivation_compat.go",
         "tpm.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/tpm",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/tpm",
     visibility = ["//visibility:public"],
     deps = [
-        "//core/pkg/logtree:go_default_library",
-        "//core/pkg/sysfs:go_default_library",
+        "//metropolis/node/common/sysfs:go_default_library",
+        "//metropolis/node/core/logtree:go_default_library",
         "@com_github_gogo_protobuf//proto:go_default_library",
         "@com_github_google_go_tpm//tpm2:go_default_library",
         "@com_github_google_go_tpm//tpmutil:go_default_library",
diff --git a/core/pkg/tpm/credactivation_compat.go b/metropolis/node/core/tpm/credactivation_compat.go
similarity index 100%
rename from core/pkg/tpm/credactivation_compat.go
rename to metropolis/node/core/tpm/credactivation_compat.go
diff --git a/core/pkg/tpm/eventlog/BUILD.bazel b/metropolis/node/core/tpm/eventlog/BUILD.bazel
similarity index 70%
rename from core/pkg/tpm/eventlog/BUILD.bazel
rename to metropolis/node/core/tpm/eventlog/BUILD.bazel
index fd73133..64fa1ff 100644
--- a/core/pkg/tpm/eventlog/BUILD.bazel
+++ b/metropolis/node/core/tpm/eventlog/BUILD.bazel
@@ -7,10 +7,10 @@
         "eventlog.go",
         "secureboot.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/tpm/eventlog",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/tpm/eventlog",
     visibility = ["//visibility:public"],
     deps = [
-        "//core/pkg/tpm/eventlog/internal:go_default_library",
+        "//metropolis/node/core/tpm/eventlog/internal:go_default_library",
         "@com_github_google_certificate_transparency_go//x509:go_default_library",
         "@com_github_google_go_tpm//tpm2:go_default_library",
     ],
diff --git a/core/pkg/tpm/eventlog/LICENSE-3RD-PARTY.txt b/metropolis/node/core/tpm/eventlog/LICENSE-3RD-PARTY.txt
similarity index 100%
rename from core/pkg/tpm/eventlog/LICENSE-3RD-PARTY.txt
rename to metropolis/node/core/tpm/eventlog/LICENSE-3RD-PARTY.txt
diff --git a/core/pkg/tpm/eventlog/compat.go b/metropolis/node/core/tpm/eventlog/compat.go
similarity index 100%
rename from core/pkg/tpm/eventlog/compat.go
rename to metropolis/node/core/tpm/eventlog/compat.go
diff --git a/core/pkg/tpm/eventlog/eventlog.go b/metropolis/node/core/tpm/eventlog/eventlog.go
similarity index 100%
rename from core/pkg/tpm/eventlog/eventlog.go
rename to metropolis/node/core/tpm/eventlog/eventlog.go
diff --git a/core/pkg/tpm/eventlog/internal/BUILD.bazel b/metropolis/node/core/tpm/eventlog/internal/BUILD.bazel
similarity index 64%
rename from core/pkg/tpm/eventlog/internal/BUILD.bazel
rename to metropolis/node/core/tpm/eventlog/internal/BUILD.bazel
index 80293f4..48e1e81 100644
--- a/core/pkg/tpm/eventlog/internal/BUILD.bazel
+++ b/metropolis/node/core/tpm/eventlog/internal/BUILD.bazel
@@ -3,8 +3,8 @@
 go_library(
     name = "go_default_library",
     srcs = ["events.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/pkg/tpm/eventlog/internal",
-    visibility = ["//core/pkg/tpm/eventlog:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/core/tpm/eventlog/internal",
+    visibility = ["//metropolis/node/core/tpm/eventlog:__subpackages__"],
     deps = [
         "@com_github_google_certificate_transparency_go//asn1:go_default_library",
         "@com_github_google_certificate_transparency_go//x509:go_default_library",
diff --git a/core/pkg/tpm/eventlog/internal/events.go b/metropolis/node/core/tpm/eventlog/internal/events.go
similarity index 100%
rename from core/pkg/tpm/eventlog/internal/events.go
rename to metropolis/node/core/tpm/eventlog/internal/events.go
diff --git a/core/pkg/tpm/eventlog/secureboot.go b/metropolis/node/core/tpm/eventlog/secureboot.go
similarity index 98%
rename from core/pkg/tpm/eventlog/secureboot.go
rename to metropolis/node/core/tpm/eventlog/secureboot.go
index 5540a0e..f117d30 100644
--- a/core/pkg/tpm/eventlog/secureboot.go
+++ b/metropolis/node/core/tpm/eventlog/secureboot.go
@@ -24,7 +24,7 @@
 
 	"github.com/google/certificate-transparency-go/x509"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/tpm/eventlog/internal"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/tpm/eventlog/internal"
 )
 
 // SecurebootState describes the secure boot status of a machine, as determined
diff --git a/core/pkg/tpm/tpm.go b/metropolis/node/core/tpm/tpm.go
similarity index 98%
rename from core/pkg/tpm/tpm.go
rename to metropolis/node/core/tpm/tpm.go
index 6fda219..76f4f92 100644
--- a/core/pkg/tpm/tpm.go
+++ b/metropolis/node/core/tpm/tpm.go
@@ -32,10 +32,6 @@
 	"sync"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-
-	"git.monogon.dev/source/nexantic.git/core/pkg/sysfs"
-
 	"github.com/gogo/protobuf/proto"
 	tpmpb "github.com/google/go-tpm-tools/proto"
 	"github.com/google/go-tpm-tools/tpm2tools"
@@ -43,6 +39,9 @@
 	"github.com/google/go-tpm/tpmutil"
 	"github.com/pkg/errors"
 	"golang.org/x/sys/unix"
+
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/sysfs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
 )
 
 var (
diff --git a/core/internal/kubernetes/BUILD.bazel b/metropolis/node/kubernetes/BUILD.bazel
similarity index 64%
rename from core/internal/kubernetes/BUILD.bazel
rename to metropolis/node/kubernetes/BUILD.bazel
index d68d1e8..f1fa849 100644
--- a/core/internal/kubernetes/BUILD.bazel
+++ b/metropolis/node/kubernetes/BUILD.bazel
@@ -11,22 +11,22 @@
         "scheduler.go",
         "service.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/kubernetes",
-    visibility = ["//core:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes",
+    visibility = ["//metropolis/node:__subpackages__"],
     deps = [
-        "//core/internal/common:go_default_library",
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/kubernetes/clusternet:go_default_library",
-        "//core/internal/kubernetes/nfproxy:go_default_library",
-        "//core/internal/kubernetes/pki:go_default_library",
-        "//core/internal/kubernetes/reconciler:go_default_library",
-        "//core/internal/localstorage:go_default_library",
-        "//core/internal/localstorage/declarative:go_default_library",
-        "//core/internal/network/dns:go_default_library",
-        "//core/pkg/fileargs:go_default_library",
-        "//core/pkg/fsquota:go_default_library",
-        "//core/pkg/logtree:go_default_library",
-        "//core/proto/api:go_default_library",
+        "//metropolis/node:go_default_library",
+        "//metropolis/node/common/fileargs:go_default_library",
+        "//metropolis/node/common/fsquota:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/localstorage:go_default_library",
+        "//metropolis/node/core/localstorage/declarative:go_default_library",
+        "//metropolis/node/core/logtree:go_default_library",
+        "//metropolis/node/core/network/dns:go_default_library",
+        "//metropolis/node/kubernetes/clusternet:go_default_library",
+        "//metropolis/node/kubernetes/nfproxy:go_default_library",
+        "//metropolis/node/kubernetes/pki:go_default_library",
+        "//metropolis/node/kubernetes/reconciler:go_default_library",
+        "//metropolis/proto/api:go_default_library",
         "@com_github_container_storage_interface_spec//lib/go/csi:go_default_library",
         "@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
         "@io_k8s_api//core/v1:go_default_library",
diff --git a/core/internal/kubernetes/apiserver.go b/metropolis/node/kubernetes/apiserver.go
similarity index 93%
rename from core/internal/kubernetes/apiserver.go
rename to metropolis/node/kubernetes/apiserver.go
index 58c3d1e..583e268 100644
--- a/core/internal/kubernetes/apiserver.go
+++ b/metropolis/node/kubernetes/apiserver.go
@@ -24,11 +24,11 @@
 	"net"
 	"os/exec"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/pki"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/pkg/fileargs"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fileargs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/pki"
 )
 
 type apiserverService struct {
diff --git a/core/internal/kubernetes/clusternet/BUILD.bazel b/metropolis/node/kubernetes/clusternet/BUILD.bazel
similarity index 62%
rename from core/internal/kubernetes/clusternet/BUILD.bazel
rename to metropolis/node/kubernetes/clusternet/BUILD.bazel
index d011e2f..9e9cc01 100644
--- a/core/internal/kubernetes/clusternet/BUILD.bazel
+++ b/metropolis/node/kubernetes/clusternet/BUILD.bazel
@@ -6,14 +6,14 @@
         "clusternet.go",
         "netlink_compat.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/kubernetes/clusternet",
-    visibility = ["//core:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/clusternet",
+    visibility = ["//metropolis/node/kubernetes:__subpackages__"],
     deps = [
-        "//core/internal/common:go_default_library",
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/localstorage:go_default_library",
-        "//core/pkg/jsonpatch:go_default_library",
-        "//core/pkg/logtree:go_default_library",
+        "//metropolis/node:go_default_library",
+        "//metropolis/node/common/jsonpatch:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/localstorage:go_default_library",
+        "//metropolis/node/core/logtree:go_default_library",
         "@com_github_vishvananda_netlink//:go_default_library",
         "@com_zx2c4_golang_wireguard_wgctrl//:go_default_library",
         "@com_zx2c4_golang_wireguard_wgctrl//wgtypes:go_default_library",
diff --git a/core/internal/kubernetes/clusternet/clusternet.go b/metropolis/node/kubernetes/clusternet/clusternet.go
similarity index 95%
rename from core/internal/kubernetes/clusternet/clusternet.go
rename to metropolis/node/kubernetes/clusternet/clusternet.go
index 15e3d5b..d8dc7ad 100644
--- a/core/internal/kubernetes/clusternet/clusternet.go
+++ b/metropolis/node/kubernetes/clusternet/clusternet.go
@@ -33,24 +33,21 @@
 	"net"
 	"os"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-
-	"k8s.io/client-go/informers"
-
-	"k8s.io/client-go/kubernetes"
-
 	"github.com/vishvananda/netlink"
 	"golang.zx2c4.com/wireguard/wgctrl"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/client-go/informers"
+	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/cache"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/pkg/jsonpatch"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/jsonpatch"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
 )
 
 const (
diff --git a/core/internal/kubernetes/clusternet/netlink_compat.go b/metropolis/node/kubernetes/clusternet/netlink_compat.go
similarity index 100%
rename from core/internal/kubernetes/clusternet/netlink_compat.go
rename to metropolis/node/kubernetes/clusternet/netlink_compat.go
diff --git a/metropolis/node/kubernetes/containerd/BUILD.bazel b/metropolis/node/kubernetes/containerd/BUILD.bazel
new file mode 100644
index 0000000..9e42595
--- /dev/null
+++ b/metropolis/node/kubernetes/containerd/BUILD.bazel
@@ -0,0 +1,20 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = ["main.go"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/containerd",
+    visibility = ["//metropolis/node/core:__subpackages__"],
+    deps = [
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/localstorage:go_default_library",
+        "@com_github_containerd_containerd//:go_default_library",
+        "@com_github_containerd_containerd//namespaces:go_default_library",
+    ],
+)
+
+exports_files([
+    "config.toml",
+    "runsc.toml",
+    "cnispec.gojson",
+])
diff --git a/core/internal/containerd/cnispec.gojson b/metropolis/node/kubernetes/containerd/cnispec.gojson
similarity index 100%
rename from core/internal/containerd/cnispec.gojson
rename to metropolis/node/kubernetes/containerd/cnispec.gojson
diff --git a/core/internal/containerd/config.toml b/metropolis/node/kubernetes/containerd/config.toml
similarity index 100%
rename from core/internal/containerd/config.toml
rename to metropolis/node/kubernetes/containerd/config.toml
diff --git a/core/internal/containerd/main.go b/metropolis/node/kubernetes/containerd/main.go
similarity index 96%
rename from core/internal/containerd/main.go
rename to metropolis/node/kubernetes/containerd/main.go
index 78fee97..366f902 100644
--- a/core/internal/containerd/main.go
+++ b/metropolis/node/kubernetes/containerd/main.go
@@ -30,8 +30,8 @@
 	ctr "github.com/containerd/containerd"
 	"github.com/containerd/containerd/namespaces"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
 )
 
 const (
diff --git a/core/internal/containerd/runsc.toml b/metropolis/node/kubernetes/containerd/runsc.toml
similarity index 100%
rename from core/internal/containerd/runsc.toml
rename to metropolis/node/kubernetes/containerd/runsc.toml
diff --git a/core/internal/kubernetes/controller-manager.go b/metropolis/node/kubernetes/controller-manager.go
similarity index 93%
rename from core/internal/kubernetes/controller-manager.go
rename to metropolis/node/kubernetes/controller-manager.go
index 690a553..487511f 100644
--- a/core/internal/kubernetes/controller-manager.go
+++ b/metropolis/node/kubernetes/controller-manager.go
@@ -23,9 +23,9 @@
 	"net"
 	"os/exec"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/pki"
-	"git.monogon.dev/source/nexantic.git/core/pkg/fileargs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fileargs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/pki"
 )
 
 type controllerManagerConfig struct {
diff --git a/core/internal/kubernetes/csi.go b/metropolis/node/kubernetes/csi.go
similarity index 96%
rename from core/internal/kubernetes/csi.go
rename to metropolis/node/kubernetes/csi.go
index def1d6d..4b44a1a 100644
--- a/core/internal/kubernetes/csi.go
+++ b/metropolis/node/kubernetes/csi.go
@@ -24,8 +24,6 @@
 	"path/filepath"
 	"regexp"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-
 	"github.com/container-storage-interface/spec/lib/go/csi"
 	"github.com/golang/protobuf/ptypes/wrappers"
 	"golang.org/x/sys/unix"
@@ -34,9 +32,10 @@
 	"google.golang.org/grpc/status"
 	pluginregistration "k8s.io/kubelet/pkg/apis/pluginregistration/v1"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/pkg/fsquota"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fsquota"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
 )
 
 // Derived from K8s spec for acceptable names, but shortened to 130 characters to avoid issues with
diff --git a/core/cmd/kube/BUILD b/metropolis/node/kubernetes/hyperkube/BUILD
similarity index 90%
rename from core/cmd/kube/BUILD
rename to metropolis/node/kubernetes/hyperkube/BUILD
index 34466fc..dced1c7 100644
--- a/core/cmd/kube/BUILD
+++ b/metropolis/node/kubernetes/hyperkube/BUILD
@@ -4,7 +4,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/cmd/kube",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/hyperkube",
     visibility = ["//visibility:private"],
     deps = [
         "@com_github_spf13_cobra//:go_default_library",
@@ -21,7 +21,7 @@
 )
 
 go_binary(
-    name = "kube",
+    name = "hyperkube",
     embed = [":go_default_library"],
     pure = "on",
     visibility = ["//visibility:public"],
diff --git a/core/cmd/kube/main.go b/metropolis/node/kubernetes/hyperkube/main.go
similarity index 100%
rename from core/cmd/kube/main.go
rename to metropolis/node/kubernetes/hyperkube/main.go
diff --git a/core/internal/kubernetes/kubelet.go b/metropolis/node/kubernetes/kubelet.go
similarity index 89%
rename from core/internal/kubernetes/kubelet.go
rename to metropolis/node/kubernetes/kubelet.go
index 7a80f60..e9c6ce5 100644
--- a/core/internal/kubernetes/kubelet.go
+++ b/metropolis/node/kubernetes/kubelet.go
@@ -25,15 +25,15 @@
 	"net"
 	"os/exec"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/pki"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/reconciler"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage/declarative"
-	"git.monogon.dev/source/nexantic.git/core/pkg/fileargs"
-
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	kubeletconfig "k8s.io/kubelet/config/v1beta1"
+
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fileargs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage/declarative"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/pki"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/reconciler"
 )
 
 type kubeletService struct {
@@ -64,7 +64,7 @@
 		return fmt.Errorf("could not create volatile kubelet server cert: %w", err)
 	}
 
-	// TODO(q3k): this should probably become its own function //core/internal/kubernetes/pki.
+	// TODO(q3k): this should probably become its own function //metropolis/node/kubernetes/pki.
 	for _, el := range []struct {
 		target declarative.FilePlacement
 		data   []byte
diff --git a/core/internal/kubernetes/nfproxy/BUILD.bazel b/metropolis/node/kubernetes/nfproxy/BUILD.bazel
similarity index 79%
rename from core/internal/kubernetes/nfproxy/BUILD.bazel
rename to metropolis/node/kubernetes/nfproxy/BUILD.bazel
index 4bc7ab7..29124a6 100644
--- a/core/internal/kubernetes/nfproxy/BUILD.bazel
+++ b/metropolis/node/kubernetes/nfproxy/BUILD.bazel
@@ -3,10 +3,10 @@
 go_library(
     name = "go_default_library",
     srcs = ["nfproxy.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/kubernetes/nfproxy",
-    visibility = ["//core:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/nfproxy",
+    visibility = ["//metropolis/node/kubernetes:__subpackages__"],
     deps = [
-        "//core/internal/common/supervisor:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
         "@com_github_sbezverk_nfproxy//pkg/controller:go_default_library",
         "@com_github_sbezverk_nfproxy//pkg/nftables:go_default_library",
         "@com_github_sbezverk_nfproxy//pkg/proxy:go_default_library",
diff --git a/core/internal/kubernetes/nfproxy/nfproxy.go b/metropolis/node/kubernetes/nfproxy/nfproxy.go
similarity index 97%
rename from core/internal/kubernetes/nfproxy/nfproxy.go
rename to metropolis/node/kubernetes/nfproxy/nfproxy.go
index 25962bf..5fc9a11 100644
--- a/core/internal/kubernetes/nfproxy/nfproxy.go
+++ b/metropolis/node/kubernetes/nfproxy/nfproxy.go
@@ -26,8 +26,6 @@
 	"os"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-
 	"github.com/sbezverk/nfproxy/pkg/controller"
 	"github.com/sbezverk/nfproxy/pkg/nftables"
 	"github.com/sbezverk/nfproxy/pkg/proxy"
@@ -39,6 +37,8 @@
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/kubernetes/scheme"
 	"k8s.io/client-go/tools/record"
+
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
 )
 
 type Service struct {
diff --git a/core/internal/kubernetes/pki/BUILD.bazel b/metropolis/node/kubernetes/pki/BUILD.bazel
similarity index 61%
rename from core/internal/kubernetes/pki/BUILD.bazel
rename to metropolis/node/kubernetes/pki/BUILD.bazel
index ab45382..f82603d 100644
--- a/core/internal/kubernetes/pki/BUILD.bazel
+++ b/metropolis/node/kubernetes/pki/BUILD.bazel
@@ -7,11 +7,11 @@
         "certificate.go",
         "kubernetes.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/kubernetes/pki",
-    visibility = ["//core:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/pki",
+    visibility = ["//metropolis/node:__subpackages__"],
     deps = [
-        "//core/internal/common:go_default_library",
-        "//core/pkg/logtree:go_default_library",
+        "//metropolis/node:go_default_library",
+        "//metropolis/node/core/logtree:go_default_library",
         "@io_etcd_go_etcd//clientv3:go_default_library",
         "@io_k8s_client_go//tools/clientcmd:go_default_library",
         "@io_k8s_client_go//tools/clientcmd/api:go_default_library",
diff --git a/core/internal/kubernetes/pki/ca.go b/metropolis/node/kubernetes/pki/ca.go
similarity index 100%
rename from core/internal/kubernetes/pki/ca.go
rename to metropolis/node/kubernetes/pki/ca.go
diff --git a/core/internal/kubernetes/pki/certificate.go b/metropolis/node/kubernetes/pki/certificate.go
similarity index 100%
rename from core/internal/kubernetes/pki/certificate.go
rename to metropolis/node/kubernetes/pki/certificate.go
diff --git a/core/internal/kubernetes/pki/kubernetes.go b/metropolis/node/kubernetes/pki/kubernetes.go
similarity index 98%
rename from core/internal/kubernetes/pki/kubernetes.go
rename to metropolis/node/kubernetes/pki/kubernetes.go
index 9931f03..c4827a9 100644
--- a/core/internal/kubernetes/pki/kubernetes.go
+++ b/metropolis/node/kubernetes/pki/kubernetes.go
@@ -25,13 +25,12 @@
 	"fmt"
 	"net"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-
 	"go.etcd.io/etcd/clientv3"
 	"k8s.io/client-go/tools/clientcmd"
 	configapi "k8s.io/client-go/tools/clientcmd/api"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
 )
 
 // KubeCertificateName is an enum-like unique name of a static Kubernetes certificate. The value of the name is used
diff --git a/core/internal/kubernetes/provisioner.go b/metropolis/node/kubernetes/provisioner.go
similarity index 96%
rename from core/internal/kubernetes/provisioner.go
rename to metropolis/node/kubernetes/provisioner.go
index 3be25e0..b671125 100644
--- a/core/internal/kubernetes/provisioner.go
+++ b/metropolis/node/kubernetes/provisioner.go
@@ -24,8 +24,6 @@
 	"os"
 	"path/filepath"
 
-	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
-
 	v1 "k8s.io/api/core/v1"
 	storagev1 "k8s.io/api/storage/v1"
 	apierrs "k8s.io/apimachinery/pkg/api/errors"
@@ -41,12 +39,13 @@
 	ref "k8s.io/client-go/tools/reference"
 	"k8s.io/client-go/util/workqueue"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/pkg/fsquota"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fsquota"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/logtree"
 )
 
-// ONCHANGE(//core/internal/kubernetes/reconciler:resources_csi.go): needs to match csiProvisionerServerName declared.
+// ONCHANGE(//metropolis/node/kubernetes/reconciler:resources_csi.go): needs to match csiProvisionerServerName declared.
 const csiProvisionerServerName = "com.nexantic.smalltown.vfs"
 
 // csiProvisionerServer is responsible for the provisioning and deprovisioning of CSI-based container volumes. It runs on all
diff --git a/core/internal/kubernetes/reconciler/BUILD.bazel b/metropolis/node/kubernetes/reconciler/BUILD.bazel
similarity index 84%
rename from core/internal/kubernetes/reconciler/BUILD.bazel
rename to metropolis/node/kubernetes/reconciler/BUILD.bazel
index dcfbc49..d8f2db6 100644
--- a/core/internal/kubernetes/reconciler/BUILD.bazel
+++ b/metropolis/node/kubernetes/reconciler/BUILD.bazel
@@ -10,10 +10,10 @@
         "resources_runtimeclass.go",
         "resources_storageclass.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/kubernetes/reconciler",
-    visibility = ["//core:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/reconciler",
+    visibility = ["//metropolis/node:__subpackages__"],
     deps = [
-        "//core/internal/common/supervisor:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
         "@io_k8s_api//core/v1:go_default_library",
         "@io_k8s_api//node/v1beta1:go_default_library",
         "@io_k8s_api//policy/v1beta1:go_default_library",
diff --git a/core/internal/kubernetes/reconciler/reconciler.go b/metropolis/node/kubernetes/reconciler/reconciler.go
similarity index 98%
rename from core/internal/kubernetes/reconciler/reconciler.go
rename to metropolis/node/kubernetes/reconciler/reconciler.go
index 24a34ef..9c5ba4e 100644
--- a/core/internal/kubernetes/reconciler/reconciler.go
+++ b/metropolis/node/kubernetes/reconciler/reconciler.go
@@ -27,11 +27,10 @@
 	"fmt"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-
 	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
-
 	"k8s.io/client-go/kubernetes"
+
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
 )
 
 // Sad workaround for all the pointer booleans in K8s specs
diff --git a/core/internal/kubernetes/reconciler/reconciler_test.go b/metropolis/node/kubernetes/reconciler/reconciler_test.go
similarity index 100%
rename from core/internal/kubernetes/reconciler/reconciler_test.go
rename to metropolis/node/kubernetes/reconciler/reconciler_test.go
diff --git a/core/internal/kubernetes/reconciler/resources_csi.go b/metropolis/node/kubernetes/reconciler/resources_csi.go
similarity index 90%
rename from core/internal/kubernetes/reconciler/resources_csi.go
rename to metropolis/node/kubernetes/reconciler/resources_csi.go
index 73a92d2..ecbcb4b 100644
--- a/core/internal/kubernetes/reconciler/resources_csi.go
+++ b/metropolis/node/kubernetes/reconciler/resources_csi.go
@@ -24,9 +24,9 @@
 	"k8s.io/client-go/kubernetes"
 )
 
-// TODO(q3k): this is duplicated with //core/internal/kubernetes:provisioner.go; integrate this once provisioner.go
+// TODO(q3k): this is duplicated with //metropolis/node/kubernetes:provisioner.go; integrate this once provisioner.go
 // gets moved into a subpackage.
-// ONCHANGE(//core/internal/kubernetes:provisioner.go): needs to match csiProvisionerName declared.
+// ONCHANGE(//metropolis/node/kubernetes:provisioner.go): needs to match csiProvisionerName declared.
 const csiProvisionerName = "com.nexantic.smalltown.vfs"
 
 type resourceCSIDrivers struct {
diff --git a/core/internal/kubernetes/reconciler/resources_podsecuritypolicy.go b/metropolis/node/kubernetes/reconciler/resources_podsecuritypolicy.go
similarity index 100%
rename from core/internal/kubernetes/reconciler/resources_podsecuritypolicy.go
rename to metropolis/node/kubernetes/reconciler/resources_podsecuritypolicy.go
diff --git a/core/internal/kubernetes/reconciler/resources_rbac.go b/metropolis/node/kubernetes/reconciler/resources_rbac.go
similarity index 100%
rename from core/internal/kubernetes/reconciler/resources_rbac.go
rename to metropolis/node/kubernetes/reconciler/resources_rbac.go
diff --git a/core/internal/kubernetes/reconciler/resources_runtimeclass.go b/metropolis/node/kubernetes/reconciler/resources_runtimeclass.go
similarity index 100%
rename from core/internal/kubernetes/reconciler/resources_runtimeclass.go
rename to metropolis/node/kubernetes/reconciler/resources_runtimeclass.go
diff --git a/core/internal/kubernetes/reconciler/resources_storageclass.go b/metropolis/node/kubernetes/reconciler/resources_storageclass.go
similarity index 100%
rename from core/internal/kubernetes/reconciler/resources_storageclass.go
rename to metropolis/node/kubernetes/reconciler/resources_storageclass.go
diff --git a/core/internal/kubernetes/scheduler.go b/metropolis/node/kubernetes/scheduler.go
similarity index 90%
rename from core/internal/kubernetes/scheduler.go
rename to metropolis/node/kubernetes/scheduler.go
index 26f8bb1..21e6663 100644
--- a/core/internal/kubernetes/scheduler.go
+++ b/metropolis/node/kubernetes/scheduler.go
@@ -22,9 +22,9 @@
 	"fmt"
 	"os/exec"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/pki"
-	"git.monogon.dev/source/nexantic.git/core/pkg/fileargs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/fileargs"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/pki"
 )
 
 type schedulerConfig struct {
diff --git a/core/internal/kubernetes/service.go b/metropolis/node/kubernetes/service.go
similarity index 89%
rename from core/internal/kubernetes/service.go
rename to metropolis/node/kubernetes/service.go
index 0075470..2917bfc 100644
--- a/core/internal/kubernetes/service.go
+++ b/metropolis/node/kubernetes/service.go
@@ -29,14 +29,14 @@
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/clientcmd"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/clusternet"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/nfproxy"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/pki"
-	"git.monogon.dev/source/nexantic.git/core/internal/kubernetes/reconciler"
-	"git.monogon.dev/source/nexantic.git/core/internal/localstorage"
-	"git.monogon.dev/source/nexantic.git/core/internal/network/dns"
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/localstorage"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dns"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/clusternet"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/nfproxy"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/pki"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/kubernetes/reconciler"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 type Config struct {
diff --git a/core/proto/common/common.proto b/metropolis/node/ports.go
similarity index 71%
copy from core/proto/common/common.proto
copy to metropolis/node/ports.go
index 5616103..c63ec38 100644
--- a/core/proto/common/common.proto
+++ b/metropolis/node/ports.go
@@ -14,11 +14,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-syntax = "proto3";
-package smalltown.core.proto.common;
-option go_package = "git.monogon.dev/source/nexantic.git/core/proto/common";
+package node
 
-enum TrustBackend {
-    DUMMY = 0;
-    TPM = 1;
-}
+const (
+	NodeServicePort     = 7835
+	ConsensusPort       = 7834
+	MasterServicePort   = 7833
+	ExternalServicePort = 7836
+	DebugServicePort    = 7837
+	WireGuardPort       = 7838
+	KubernetesAPIPort   = 6443
+	DebuggerPort        = 2345
+)
diff --git a/core/proto/api/BUILD.bazel b/metropolis/proto/api/BUILD.bazel
similarity index 75%
rename from core/proto/api/BUILD.bazel
rename to metropolis/proto/api/BUILD.bazel
index 88569f3..ec40562 100644
--- a/core/proto/api/BUILD.bazel
+++ b/metropolis/proto/api/BUILD.bazel
@@ -14,8 +14,7 @@
 go_proto_library(
     name = "api_go_proto",
     compilers = ["@io_bazel_rules_go//proto:go_grpc"],
-    #compilers = ["@io_bazel_rules_go//proto:go_grpc"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/proto/api",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/proto/api",
     proto = ":api_proto",
     visibility = ["//visibility:public"],
 )
@@ -23,6 +22,6 @@
 go_library(
     name = "go_default_library",
     embed = [":api_go_proto"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/proto/api",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/proto/api",
     visibility = ["//visibility:public"],
 )
diff --git a/core/proto/api/debug.proto b/metropolis/proto/api/debug.proto
similarity index 93%
rename from core/proto/api/debug.proto
rename to metropolis/proto/api/debug.proto
index 7a046ec..2483360 100644
--- a/core/proto/api/debug.proto
+++ b/metropolis/proto/api/debug.proto
@@ -16,13 +16,13 @@
 
 syntax = "proto3";
 package smalltown.core.proto.api;
-option go_package = "git.monogon.dev/source/nexantic.git/core/proto/api";
+option go_package = "git.monogon.dev/source/nexantic.git/metropolis/proto/api";
 
-import "core/proto/api/enrolment.proto";
+import "metropolis/proto/api/enrolment.proto";
 
 // NodeDebugService exposes debug and testing endpoints that allow introspection into a running Smalltown instance.
-// It is not authenticated and will be disabled in production. It is currently consumed by core/cmd/dbg and
-// by tests. For exact documentation of the available parameters please look at core/internal/node/debug.go.
+// It is not authenticated and will be disabled in production. It is currently consumed by metropolis/cli/dbg and
+// by tests.
 service NodeDebugService {
     // GetDebugKubeconfig issues kubeconfigs with arbitrary identities and groups for debugging
     rpc GetDebugKubeconfig(GetDebugKubeconfigRequest) returns (GetDebugKubeconfigResponse);
@@ -30,7 +30,7 @@
     // GetLogs Returns historical and/or streaming logs for a given DN with given filters from the system global
     // LogTree.
     //
-    // For more information about this API, see //core/pkg/logtree. But, in summary:
+    // For more information about this API, see //metropolis/node/core/logtree. But, in summary:
     //   - All logging is performed to a DN (distinguished name), which is a dot-delimited string like foo.bar.baz.
     //   - Log entries can be either raw (coming from unstructured logging from an external service, like a running
     //     process) or leveled (emitted by Smalltown code with a source line, timestamp, and severity).
@@ -57,7 +57,7 @@
     string debug_kubeconfig = 1;
 }
 
-// Severity level corresponding to //core/pkg/logtree.Severity.
+// Severity level corresponding to //metropolis/node/core/logtree.Severity.
 enum LeveledLogSeverity {
     INVALID = 0;
     INFO = 1;
diff --git a/core/proto/api/enrolment.proto b/metropolis/proto/api/enrolment.proto
similarity index 96%
rename from core/proto/api/enrolment.proto
rename to metropolis/proto/api/enrolment.proto
index d4176cc..c07e4ea 100644
--- a/core/proto/api/enrolment.proto
+++ b/metropolis/proto/api/enrolment.proto
@@ -16,7 +16,7 @@
 
 syntax = "proto3";
 package smalltown.core.proto.api;
-option go_package = "git.monogon.dev/source/nexantic.git/core/proto/api";
+option go_package = "git.monogon.dev/source/nexantic.git/metropolis/proto/api";
 
 // EnrolmentConfig is the single boot configuration file contained in the Smalltown ESP. It configures
 // the way the node will start up (what cluster it will join/enroll into/create).
diff --git a/core/proto/common/BUILD.bazel b/metropolis/proto/common/BUILD.bazel
similarity index 76%
rename from core/proto/common/BUILD.bazel
rename to metropolis/proto/common/BUILD.bazel
index 69b93af..882bb61 100644
--- a/core/proto/common/BUILD.bazel
+++ b/metropolis/proto/common/BUILD.bazel
@@ -10,7 +10,7 @@
 
 go_proto_library(
     name = "common_go_proto",
-    importpath = "git.monogon.dev/source/nexantic.git/core/proto/common",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/proto/common",
     proto = ":common_proto",
     visibility = ["//visibility:public"],
 )
@@ -18,6 +18,6 @@
 go_library(
     name = "go_default_library",
     embed = [":common_go_proto"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/proto/common",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/proto/common",
     visibility = ["//visibility:public"],
 )
diff --git a/core/proto/common/common.proto b/metropolis/proto/common/common.proto
similarity index 89%
rename from core/proto/common/common.proto
rename to metropolis/proto/common/common.proto
index 5616103..def91e8 100644
--- a/core/proto/common/common.proto
+++ b/metropolis/proto/common/common.proto
@@ -16,7 +16,7 @@
 
 syntax = "proto3";
 package smalltown.core.proto.common;
-option go_package = "git.monogon.dev/source/nexantic.git/core/proto/common";
+option go_package = "git.monogon.dev/source/nexantic.git/metropolis/proto/common";
 
 enum TrustBackend {
     DUMMY = 0;
diff --git a/metropolis/proto/internal/BUILD.bazel b/metropolis/proto/internal/BUILD.bazel
new file mode 100644
index 0000000..2951a08
--- /dev/null
+++ b/metropolis/proto/internal/BUILD.bazel
@@ -0,0 +1,23 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+proto_library(
+    name = "internal_proto",
+    srcs = ["internal.proto"],
+    visibility = ["//metropolis:__subpackages__"],
+)
+
+go_proto_library(
+    name = "internal_go_proto",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/proto/internal",
+    proto = ":internal_proto",
+    visibility = ["//metropolis:__subpackages__"],
+)
+
+go_library(
+    name = "go_default_library",
+    embed = [":internal_go_proto"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/proto/internal",
+    visibility = ["//metropolis:__subpackages__"],
+)
diff --git a/core/proto/internal/internal.proto b/metropolis/proto/internal/internal.proto
similarity index 94%
rename from core/proto/internal/internal.proto
rename to metropolis/proto/internal/internal.proto
index 6811017..c5aa259 100644
--- a/core/proto/internal/internal.proto
+++ b/metropolis/proto/internal/internal.proto
@@ -15,7 +15,7 @@
 // limitations under the License.
 
 syntax = "proto3";
-option go_package = "git.monogon.dev/source/nexantic.git/core/proto/internal";
+option go_package = "git.monogon.dev/source/nexantic.git/metropolis/proto/internal";
 package smalltown.core.proto.internal;
 
 // Node describes a single node's state in etcd
diff --git a/core/tests/e2e/BUILD.bazel b/metropolis/test/e2e/BUILD.bazel
similarity index 72%
rename from core/tests/e2e/BUILD.bazel
rename to metropolis/test/e2e/BUILD.bazel
index 8e74be4..b9bb6f8 100644
--- a/core/tests/e2e/BUILD.bazel
+++ b/metropolis/test/e2e/BUILD.bazel
@@ -6,10 +6,10 @@
         "kubernetes_helpers.go",
         "utils.go",
     ],
-    importpath = "git.monogon.dev/source/nexantic.git/core/tests/e2e",
-    visibility = ["//core/tests:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/e2e",
+    visibility = ["//metropolis/test:__subpackages__"],
     deps = [
-        "//core/proto/api:go_default_library",
+        "//metropolis/proto/api:go_default_library",
         "@io_k8s_api//apps/v1:go_default_library",
         "@io_k8s_api//core/v1:go_default_library",
         "@io_k8s_apimachinery//pkg/api/resource:go_default_library",
@@ -25,16 +25,16 @@
     size = "large",
     srcs = ["main_test.go"],
     data = [
-        "//core:image",
-        "//core:swtpm_data",
+        "//metropolis/node:image",
+        "//metropolis/node:swtpm_data",
         "//third_party/edk2:firmware",
     ],
     embed = [":go_default_library"],
     rundir = ".",
     deps = [
-        "//core/internal/common:go_default_library",
-        "//core/internal/launch:go_default_library",
-        "//core/proto/api:go_default_library",
+        "//metropolis/node:go_default_library",
+        "//metropolis/proto/api:go_default_library",
+        "//metropolis/test/launch:go_default_library",
         "@io_k8s_api//core/v1:go_default_library",
         "@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
         "@io_k8s_kubernetes//pkg/api/v1/pod:go_default_library",
diff --git a/core/tests/e2e/k8s_cts/BUILD.bazel b/metropolis/test/e2e/k8s_cts/BUILD.bazel
similarity index 74%
rename from core/tests/e2e/k8s_cts/BUILD.bazel
rename to metropolis/test/e2e/k8s_cts/BUILD.bazel
index 648e1c5..0e43c24 100644
--- a/core/tests/e2e/k8s_cts/BUILD.bazel
+++ b/metropolis/test/e2e/k8s_cts/BUILD.bazel
@@ -28,12 +28,12 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/tests/e2e/k8s_cts",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/e2e/k8s_cts",
     visibility = ["//visibility:private"],
     deps = [
-        "//core/internal/common:go_default_library",
-        "//core/internal/launch:go_default_library",
-        "//core/tests/e2e:go_default_library",
+        "//metropolis/node:go_default_library",
+        "//metropolis/test/e2e:go_default_library",
+        "//metropolis/test/launch:go_default_library",
         "@io_k8s_api//core/v1:go_default_library",
         "@io_k8s_api//rbac/v1:go_default_library",
         "@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
@@ -43,10 +43,10 @@
 go_binary(
     name = "k8s_cts",
     data = [
-        "//core:image",
-        "//core:swtpm_data",
-        "//core/cmd/nanoswitch:initramfs",
-        "//core/tools/ktest:linux-testing",
+        "//metropolis/node:image",
+        "//metropolis/node:swtpm_data",
+        "//metropolis/test/nanoswitch:initramfs",
+        "//metropolis/test/ktest:linux-testing",
         "//third_party/edk2:firmware",
         "@com_github_bonzini_qboot//:qboot-bin",
     ],
diff --git a/core/tests/e2e/k8s_cts/main.go b/metropolis/test/e2e/k8s_cts/main.go
similarity index 95%
rename from core/tests/e2e/k8s_cts/main.go
rename to metropolis/test/e2e/k8s_cts/main.go
index 412ae7c..728a890 100644
--- a/core/tests/e2e/k8s_cts/main.go
+++ b/metropolis/test/e2e/k8s_cts/main.go
@@ -28,14 +28,13 @@
 	"syscall"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/tests/e2e"
-
 	corev1 "k8s.io/api/core/v1"
 	rbacv1 "k8s.io/api/rbac/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/launch"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/test/e2e"
+	"git.monogon.dev/source/nexantic.git/metropolis/test/launch"
 )
 
 // makeCTSPodSpec generates a spec for a standalone pod running the Kubernetes CTS. It also sets the test configuration
@@ -63,7 +62,7 @@
 			Containers: []corev1.Container{
 				{
 					Name:  "cts",
-					Image: "bazel/core/tests/e2e/k8s_cts:k8s_cts_image",
+					Image: "bazel/metropolis/test/e2e/k8s_cts:k8s_cts_image",
 					Args: []string{
 						"-cluster-ip-range=10.0.0.0/17",
 						"-dump-systemd-journal=false",
diff --git a/core/tests/e2e/kubernetes_helpers.go b/metropolis/test/e2e/kubernetes_helpers.go
similarity index 98%
rename from core/tests/e2e/kubernetes_helpers.go
rename to metropolis/test/e2e/kubernetes_helpers.go
index 4f9ba81..fffbd1b 100644
--- a/core/tests/e2e/kubernetes_helpers.go
+++ b/metropolis/test/e2e/kubernetes_helpers.go
@@ -30,7 +30,7 @@
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/clientcmd"
 
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 // GetKubeClientSet gets a Kubeconfig from the debug API and creates a K8s ClientSet using it. The identity used has
diff --git a/core/tests/e2e/main_test.go b/metropolis/test/e2e/main_test.go
similarity index 96%
rename from core/tests/e2e/main_test.go
rename to metropolis/test/e2e/main_test.go
index 465ef23..46e862c 100644
--- a/core/tests/e2e/main_test.go
+++ b/metropolis/test/e2e/main_test.go
@@ -35,9 +35,9 @@
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	podv1 "k8s.io/kubernetes/pkg/api/v1/pod"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/launch"
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
+	"git.monogon.dev/source/nexantic.git/metropolis/test/launch"
 )
 
 const (
@@ -212,7 +212,7 @@
 						Containers: []corev1.Container{{
 							Name:            "preseed-test-1",
 							ImagePullPolicy: corev1.PullNever,
-							Image:           "bazel/core/tests/e2e/preseedtest:preseedtest",
+							Image:           "bazel/metropolis/test/e2e/preseedtest:preseedtest",
 						}},
 						RestartPolicy: corev1.RestartPolicyNever,
 					},
diff --git a/core/tests/e2e/preseedtest/BUILD.bazel b/metropolis/test/e2e/preseedtest/BUILD.bazel
similarity index 80%
rename from core/tests/e2e/preseedtest/BUILD.bazel
rename to metropolis/test/e2e/preseedtest/BUILD.bazel
index 9536846..41b32e3 100644
--- a/core/tests/e2e/preseedtest/BUILD.bazel
+++ b/metropolis/test/e2e/preseedtest/BUILD.bazel
@@ -4,7 +4,7 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/tests/e2e/preseedtest",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/e2e/preseedtest",
     visibility = ["//visibility:private"],
 )
 
diff --git a/core/tests/e2e/preseedtest/main.go b/metropolis/test/e2e/preseedtest/main.go
similarity index 100%
rename from core/tests/e2e/preseedtest/main.go
rename to metropolis/test/e2e/preseedtest/main.go
diff --git a/core/tests/e2e/utils.go b/metropolis/test/e2e/utils.go
similarity index 100%
rename from core/tests/e2e/utils.go
rename to metropolis/test/e2e/utils.go
diff --git a/core/tools/ktest/BUILD b/metropolis/test/ktest/BUILD
similarity index 85%
rename from core/tools/ktest/BUILD
rename to metropolis/test/ktest/BUILD
index a7f1119..d94831c 100644
--- a/core/tools/ktest/BUILD
+++ b/metropolis/test/ktest/BUILD
@@ -1,12 +1,12 @@
 load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
-load("//core/tools/kconfig-patcher:kconfig-patcher.bzl", "kconfig_patch")
+load("//metropolis/node/build/kconfig-patcher:kconfig-patcher.bzl", "kconfig_patch")
 
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/tools/ktest",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/ktest",
     visibility = ["//visibility:private"],
-    deps = ["//core/internal/launch:go_default_library"],
+    deps = ["//metropolis/test/launch:go_default_library"],
 )
 
 go_binary(
diff --git a/core/tools/ktestinit/BUILD.bazel b/metropolis/test/ktest/init/BUILD.bazel
similarity index 77%
rename from core/tools/ktestinit/BUILD.bazel
rename to metropolis/test/ktest/init/BUILD.bazel
index 74eb742..4161146 100644
--- a/core/tools/ktestinit/BUILD.bazel
+++ b/metropolis/test/ktest/init/BUILD.bazel
@@ -3,13 +3,13 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/tools/ktestinit",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/ktest/init",
     visibility = ["//visibility:private"],
     deps = ["@org_golang_x_sys//unix:go_default_library"],
 )
 
 go_binary(
-    name = "ktestinit",
+    name = "init",
     embed = [":go_default_library"],
     pure = "on",
     visibility = ["//visibility:public"],
diff --git a/core/tools/ktestinit/main.go b/metropolis/test/ktest/init/main.go
similarity index 100%
rename from core/tools/ktestinit/main.go
rename to metropolis/test/ktest/init/main.go
diff --git a/core/tools/ktest/ktest.bzl b/metropolis/test/ktest/ktest.bzl
similarity index 80%
rename from core/tools/ktest/ktest.bzl
rename to metropolis/test/ktest/ktest.bzl
index aef749b..fdbff20 100644
--- a/core/tools/ktest/ktest.bzl
+++ b/metropolis/test/ktest/ktest.bzl
@@ -22,7 +22,7 @@
     native.genrule(
         name = "test_initramfs",
         srcs = [
-            "//core/tools/ktestinit",
+            "//metropolis/test/ktest/init",
         ] + deps + [tester],
         outs = [
             "initramfs.cpio.lz4",
@@ -33,7 +33,7 @@
 dir /dev 0755 0 0
 nod /dev/console 0600 0 0 c 5 1
 nod /dev/null 0644 0 0 c 1 3
-file /init $(location //core/tools/ktestinit) 0755 0 0
+file /init $(location //metropolis/test/ktest/init) 0755 0 0
 file /tester $(location """ + tester + """) 0755 0 0
 """ + initramfs_extra + """
 EOF
@@ -46,17 +46,17 @@
     native.sh_test(
         name = "ktest",
         args = [
-            "$(location //core/tools/ktest)",
+            "$(location //metropolis/test/ktest)",
             "$(location :test_initramfs)",
-            "$(location //core/tools/ktest:linux-testing)",
+            "$(location //metropolis/test/ktest:linux-testing)",
             cmdline,
         ],
         size = "small",
-        srcs = ["//core/tools/ktest:test-script"],
+        srcs = ["//metropolis/test/ktest:test-script"],
         data = [
-            "//core/tools/ktest",
+            "//metropolis/test/ktest",
             ":test_initramfs",
-            "//core/tools/ktest:linux-testing",
+            "//metropolis/test/ktest:linux-testing",
             "@com_github_bonzini_qboot//:qboot-bin",
         ],
     )
diff --git a/core/tools/ktest/main.go b/metropolis/test/ktest/main.go
similarity index 96%
rename from core/tools/ktest/main.go
rename to metropolis/test/ktest/main.go
index 3541f51..7f750b8 100644
--- a/core/tools/ktest/main.go
+++ b/metropolis/test/ktest/main.go
@@ -26,7 +26,7 @@
 	"os"
 	"time"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/launch"
+	"git.monogon.dev/source/nexantic.git/metropolis/test/launch"
 )
 
 var (
diff --git a/core/tools/ktest/run_ktest.sh b/metropolis/test/ktest/run_ktest.sh
similarity index 100%
rename from core/tools/ktest/run_ktest.sh
rename to metropolis/test/ktest/run_ktest.sh
diff --git a/core/internal/launch/BUILD.bazel b/metropolis/test/launch/BUILD.bazel
similarity index 66%
rename from core/internal/launch/BUILD.bazel
rename to metropolis/test/launch/BUILD.bazel
index 1979ec6..b6245e1 100644
--- a/core/internal/launch/BUILD.bazel
+++ b/metropolis/test/launch/BUILD.bazel
@@ -3,12 +3,12 @@
 go_library(
     name = "go_default_library",
     srcs = ["launch.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/internal/launch",
-    visibility = ["//core:__subpackages__"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/launch",
+    visibility = ["//metropolis:__subpackages__"],
     deps = [
-        "//core/internal/common:go_default_library",
-        "//core/proto/api:go_default_library",
         "//golibs/common:go_default_library",
+        "//metropolis/node:go_default_library",
+        "//metropolis/proto/api:go_default_library",
         "@com_github_golang_protobuf//proto:go_default_library",
         "@com_github_grpc_ecosystem_go_grpc_middleware//retry:go_default_library",
         "@org_golang_google_grpc//:go_default_library",
diff --git a/metropolis/test/launch/cli/launch-multi2/BUILD.bazel b/metropolis/test/launch/cli/launch-multi2/BUILD.bazel
new file mode 100644
index 0000000..9f27860
--- /dev/null
+++ b/metropolis/test/launch/cli/launch-multi2/BUILD.bazel
@@ -0,0 +1,29 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = ["main.go"],
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/launch/cli/launch-multi2",
+    visibility = ["//visibility:private"],
+    deps = [
+        "//metropolis/node:go_default_library",
+        "//metropolis/proto/api:go_default_library",
+        "//metropolis/test/launch:go_default_library",
+        "@com_github_grpc_ecosystem_go_grpc_middleware//retry:go_default_library",
+        "@org_golang_google_grpc//:go_default_library",
+    ],
+)
+
+go_binary(
+    name = "launch-multi2",
+    data = [
+        "//metropolis/node:image",
+        "//metropolis/node:swtpm_data",
+        "//metropolis/test/nanoswitch:initramfs",
+        "//metropolis/test/ktest:linux-testing",
+        "//third_party/edk2:firmware",
+        "@com_github_bonzini_qboot//:qboot-bin",
+    ],
+    embed = [":go_default_library"],
+    visibility = ["//visibility:public"],
+)
diff --git a/core/cmd/launch-multi2/main.go b/metropolis/test/launch/cli/launch-multi2/main.go
similarity index 89%
rename from core/cmd/launch-multi2/main.go
rename to metropolis/test/launch/cli/launch-multi2/main.go
index 763395d..265d6a0 100644
--- a/core/cmd/launch-multi2/main.go
+++ b/metropolis/test/launch/cli/launch-multi2/main.go
@@ -27,9 +27,9 @@
 	grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
 	"google.golang.org/grpc"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/launch"
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
+	"git.monogon.dev/source/nexantic.git/metropolis/test/launch"
 )
 
 func main() {
@@ -92,8 +92,8 @@
 	}()
 	if err := launch.RunMicroVM(ctx, &launch.MicroVMOptions{
 		SerialPort:             os.Stdout,
-		KernelPath:             "core/tools/ktest/linux-testing.elf",
-		InitramfsPath:          "core/cmd/nanoswitch/initramfs.lz4",
+		KernelPath:             "metropolis/test/ktest/linux-testing.elf",
+		InitramfsPath:          "metropolis/test/nanoswitch/initramfs.lz4",
 		ExtraNetworkInterfaces: []*os.File{sw0, sw1},
 		PortMap:                nanoswitchPortMap,
 	}); err != nil {
diff --git a/core/cmd/launch/BUILD.bazel b/metropolis/test/launch/cli/launch/BUILD.bazel
similarity index 61%
rename from core/cmd/launch/BUILD.bazel
rename to metropolis/test/launch/cli/launch/BUILD.bazel
index 59d8ecc..6b1461d 100644
--- a/core/cmd/launch/BUILD.bazel
+++ b/metropolis/test/launch/cli/launch/BUILD.bazel
@@ -3,16 +3,16 @@
 go_library(
     name = "go_default_library",
     srcs = ["main.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/cmd/launch",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/launch/cli/launch",
     visibility = ["//visibility:private"],
-    deps = ["//core/internal/launch:go_default_library"],
+    deps = ["//metropolis/test/launch:go_default_library"],
 )
 
 go_binary(
     name = "launch",
     data = [
-        "//core:image",
-        "//core:swtpm_data",
+        "//metropolis/node:image",
+        "//metropolis/node:swtpm_data",
         "//third_party/edk2:firmware",
     ],
     embed = [":go_default_library"],
diff --git a/core/cmd/launch/main.go b/metropolis/test/launch/cli/launch/main.go
similarity index 94%
rename from core/cmd/launch/main.go
rename to metropolis/test/launch/cli/launch/main.go
index aba3dda..852c8e1 100644
--- a/core/cmd/launch/main.go
+++ b/metropolis/test/launch/cli/launch/main.go
@@ -23,7 +23,7 @@
 	"os/signal"
 	"syscall"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/launch"
+	"git.monogon.dev/source/nexantic.git/metropolis/test/launch"
 )
 
 func main() {
diff --git a/core/internal/launch/launch.go b/metropolis/test/launch/launch.go
similarity index 98%
rename from core/internal/launch/launch.go
rename to metropolis/test/launch/launch.go
index f456852..2d495e0 100644
--- a/core/internal/launch/launch.go
+++ b/metropolis/test/launch/launch.go
@@ -34,15 +34,14 @@
 	"syscall"
 	"time"
 
-	grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
-
 	"github.com/golang/protobuf/proto"
+	grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
 	"golang.org/x/sys/unix"
 	"google.golang.org/grpc"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	apb "git.monogon.dev/source/nexantic.git/core/proto/api"
 	freeport "git.monogon.dev/source/nexantic.git/golibs/common"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	apb "git.monogon.dev/source/nexantic.git/metropolis/proto/api"
 )
 
 type qemuValue map[string][]string
@@ -199,7 +198,7 @@
 
 	// Copy TPM state into a temporary directory since it's being modified by the emulator
 	tpmTargetDir := filepath.Join(tempDir, "tpm")
-	tpmSrcDir := "core/tpm"
+	tpmSrcDir := "metropolis/node/tpm"
 	if err := os.Mkdir(tpmTargetDir, 0644); err != nil {
 		return fmt.Errorf("failed to create TPM state directory: %w", err)
 	}
@@ -243,7 +242,7 @@
 		"-cpu", "host", "-smp", "sockets=1,cpus=1,cores=2,threads=2,maxcpus=4",
 		"-drive", "if=pflash,format=raw,readonly,file=external/edk2/OVMF_CODE.fd",
 		"-drive", "if=pflash,format=raw,snapshot=on,file=external/edk2/OVMF_VARS.fd",
-		"-drive", "if=virtio,format=raw,snapshot=on,cache=unsafe,file=core/smalltown.img",
+		"-drive", "if=virtio,format=raw,snapshot=on,cache=unsafe,file=metropolis/node/smalltown.img",
 		"-netdev", qemuNetConfig.toOption(qemuNetType),
 		"-device", "virtio-net-pci,netdev=net0,mac=" + mac.String(),
 		"-chardev", "socket,id=chrtpm,path=" + tpmSocketPath,
@@ -515,8 +514,8 @@
 
 	go func() {
 		if err := RunMicroVM(ctx, &MicroVMOptions{
-			KernelPath:             "core/tools/ktest/linux-testing.elf",
-			InitramfsPath:          "core/cmd/nanoswitch/initramfs.lz4",
+			KernelPath:             "metropolis/test/ktest/linux-testing.elf",
+			InitramfsPath:          "metropolis/test/nanoswitch/initramfs.lz4",
 			ExtraNetworkInterfaces: switchPorts,
 			PortMap:                portMap,
 		}); err != nil {
diff --git a/core/cmd/nanoswitch/BUILD b/metropolis/test/nanoswitch/BUILD
similarity index 67%
rename from core/cmd/nanoswitch/BUILD
rename to metropolis/test/nanoswitch/BUILD
index 56417c5..fc4f932 100644
--- a/core/cmd/nanoswitch/BUILD
+++ b/metropolis/test/nanoswitch/BUILD
@@ -1,17 +1,17 @@
 load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
-load("//core/build:def.bzl", "smalltown_initramfs")
+load("//metropolis/node/build:def.bzl", "smalltown_initramfs")
 
 go_library(
     name = "go_default_library",
     srcs = ["nanoswitch.go"],
-    importpath = "git.monogon.dev/source/nexantic.git/core/cmd/nanoswitch",
+    importpath = "git.monogon.dev/source/nexantic.git/metropolis/test/nanoswitch",
     visibility = ["//visibility:private"],
     deps = [
-        "//core/internal/common:go_default_library",
-        "//core/internal/common/supervisor:go_default_library",
-        "//core/internal/launch:go_default_library",
-        "//core/pkg/dhcp4c:go_default_library",
-        "//core/pkg/dhcp4c/callback:go_default_library",
+        "//metropolis/node:go_default_library",
+        "//metropolis/node/common/supervisor:go_default_library",
+        "//metropolis/node/core/network/dhcp4c:go_default_library",
+        "//metropolis/node/core/network/dhcp4c/callback:go_default_library",
+        "//metropolis/test/launch:go_default_library",
         "@com_github_google_nftables//:go_default_library",
         "@com_github_google_nftables//expr:go_default_library",
         "@com_github_insomniacslk_dhcp//dhcpv4:go_default_library",
diff --git a/core/cmd/nanoswitch/nanoswitch.go b/metropolis/test/nanoswitch/nanoswitch.go
similarity index 96%
rename from core/cmd/nanoswitch/nanoswitch.go
rename to metropolis/test/nanoswitch/nanoswitch.go
index 2fe2a81..1fe6740 100644
--- a/core/cmd/nanoswitch/nanoswitch.go
+++ b/metropolis/test/nanoswitch/nanoswitch.go
@@ -38,11 +38,11 @@
 	"github.com/vishvananda/netlink"
 	"golang.org/x/sys/unix"
 
-	"git.monogon.dev/source/nexantic.git/core/internal/common"
-	"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
-	"git.monogon.dev/source/nexantic.git/core/internal/launch"
-	"git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c"
-	dhcpcb "git.monogon.dev/source/nexantic.git/core/pkg/dhcp4c/callback"
+	common "git.monogon.dev/source/nexantic.git/metropolis/node"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/common/supervisor"
+	"git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c"
+	dhcpcb "git.monogon.dev/source/nexantic.git/metropolis/node/core/network/dhcp4c/callback"
+	"git.monogon.dev/source/nexantic.git/metropolis/test/launch"
 )
 
 var switchIP = net.IP{10, 1, 0, 1}