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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
third_party/** linguist-vendored
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ jobs:
with:
version: v2.12.2

- name: Check the vendored lbd source matches go.mod
run: ./hack/sync-lbd-src.sh --check

- name: Check go.mod tidiness
run: |
# Run go mod tidy and check if there are any changes
Expand Down
21 changes: 21 additions & 0 deletions api/core/core_v1alpha/extra.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package core_v1alpha

import (
"strings"

entity "miren.dev/runtime/pkg/entity"
)

Expand All @@ -9,3 +11,22 @@ func MD(ea entity.AttrGetter) Metadata {
md.Decode(ea)
return md
}

// SystemArtifactPrefix marks an image miren pushes to the cluster registry for
// its own use rather than on behalf of an app.
//
// An artifact's entity name is the tag it was pushed under (see the registry's
// putManifest), so the prefix rides in the tag and needs no schema field. It
// exists because artifact GC archives everything no AppVersion references, and
// a system image belongs to no app: without a way to tell it apart from a
// genuinely orphaned artifact, it would be collected within the hour and its
// blobs deleted underneath the nodes still pulling it.
const SystemArtifactPrefix = "miren-system-"

// IsSystemArtifact reports whether an artifact is one miren pushed for itself,
// and so must survive garbage collection even though no AppVersion points at
// it.
func IsSystemArtifact(id entity.Id) bool {
name := strings.TrimPrefix(string(id), "artifact/")
return strings.HasPrefix(name, SystemArtifactPrefix)
}
6 changes: 6 additions & 0 deletions api/nodeadmin/nodeadmin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Package nodeadmin carries the RPC the coordinator uses to ask one node to
// change something about itself.
package nodeadmin

//go:generate mkdir -p nodeadmin_v1alpha
//go:generate go run ../../pkg/rpc/cmd/rpcgen -pkg nodeadmin_v1alpha -input rpc.yml -output nodeadmin_v1alpha/rpc.gen.go
220 changes: 220 additions & 0 deletions api/nodeadmin/nodeadmin_v1alpha/rpc.gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package nodeadmin_v1alpha

import (
"context"
"encoding/json"

"github.com/fxamacker/cbor/v2"
rpc "miren.dev/runtime/pkg/rpc"
)

type nodeAdminInstallDiskAcceleratorArgsData struct {
Image *string `cbor:"0,keyasint,omitempty" json:"image,omitempty"`
Force *bool `cbor:"1,keyasint,omitempty" json:"force,omitempty"`
}

type NodeAdminInstallDiskAcceleratorArgs struct {
call rpc.Call
data nodeAdminInstallDiskAcceleratorArgsData
}

func (v *NodeAdminInstallDiskAcceleratorArgs) HasImage() bool {
return v.data.Image != nil
}

func (v *NodeAdminInstallDiskAcceleratorArgs) Image() string {
if v.data.Image == nil {
return ""
}
return *v.data.Image
}

func (v *NodeAdminInstallDiskAcceleratorArgs) HasForce() bool {
return v.data.Force != nil
}

func (v *NodeAdminInstallDiskAcceleratorArgs) Force() bool {
if v.data.Force == nil {
return false
}
return *v.data.Force
}

func (v *NodeAdminInstallDiskAcceleratorArgs) MarshalCBOR() ([]byte, error) {
return cbor.Marshal(v.data)
}

func (v *NodeAdminInstallDiskAcceleratorArgs) UnmarshalCBOR(data []byte) error {
return cbor.Unmarshal(data, &v.data)
}

func (v *NodeAdminInstallDiskAcceleratorArgs) MarshalJSON() ([]byte, error) {
return json.Marshal(v.data)
}

func (v *NodeAdminInstallDiskAcceleratorArgs) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, &v.data)
}

type nodeAdminInstallDiskAcceleratorResultsData struct {
KernelRelease *string `cbor:"0,keyasint,omitempty" json:"kernel_release,omitempty"`
LbdVersion *string `cbor:"1,keyasint,omitempty" json:"lbd_version,omitempty"`
Error *string `cbor:"2,keyasint,omitempty" json:"error,omitempty"`
}

type NodeAdminInstallDiskAcceleratorResults struct {
call rpc.Call
data nodeAdminInstallDiskAcceleratorResultsData
}

func (v *NodeAdminInstallDiskAcceleratorResults) SetKernelRelease(kernel_release string) {
v.data.KernelRelease = &kernel_release
}

func (v *NodeAdminInstallDiskAcceleratorResults) SetLbdVersion(lbd_version string) {
v.data.LbdVersion = &lbd_version
}

func (v *NodeAdminInstallDiskAcceleratorResults) SetError(error string) {
v.data.Error = &error
}

func (v *NodeAdminInstallDiskAcceleratorResults) MarshalCBOR() ([]byte, error) {
return cbor.Marshal(v.data)
}

func (v *NodeAdminInstallDiskAcceleratorResults) UnmarshalCBOR(data []byte) error {
return cbor.Unmarshal(data, &v.data)
}

func (v *NodeAdminInstallDiskAcceleratorResults) MarshalJSON() ([]byte, error) {
return json.Marshal(v.data)
}

func (v *NodeAdminInstallDiskAcceleratorResults) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, &v.data)
}

type NodeAdminInstallDiskAccelerator struct {
rpc.Call
args NodeAdminInstallDiskAcceleratorArgs
results NodeAdminInstallDiskAcceleratorResults
}

func (t *NodeAdminInstallDiskAccelerator) Args() *NodeAdminInstallDiskAcceleratorArgs {
args := &t.args
if args.call != nil {
return args
}
args.call = t.Call
t.Call.Args(args)
return args
}

func (t *NodeAdminInstallDiskAccelerator) Results() *NodeAdminInstallDiskAcceleratorResults {
results := &t.results
if results.call != nil {
return results
}
results.call = t.Call
t.Call.Results(results)
return results
}

type NodeAdmin interface {
InstallDiskAccelerator(ctx context.Context, state *NodeAdminInstallDiskAccelerator) error
}

type reexportNodeAdmin struct {
client rpc.Client
}

func (reexportNodeAdmin) InstallDiskAccelerator(ctx context.Context, state *NodeAdminInstallDiskAccelerator) error {
panic("not implemented")
}

func (t reexportNodeAdmin) CapabilityClient() rpc.Client {
return t.client
}

func AdaptNodeAdmin(t NodeAdmin) *rpc.Interface {
methods := []rpc.Method{
{
Name: "install_disk_accelerator",
InterfaceName: "NodeAdmin",
Index: 0,
Public: false,
Params: []string{"image", "force"},
Handler: func(ctx context.Context, call rpc.Call) error {
return t.InstallDiskAccelerator(ctx, &NodeAdminInstallDiskAccelerator{Call: call})
},
},
}

return rpc.NewInterface(methods, t)
}

type NodeAdminClient struct {
rpc.Client
}

func NewNodeAdminClient(client rpc.Client) *NodeAdminClient {
return &NodeAdminClient{Client: client}
}

func (c NodeAdminClient) Export() NodeAdmin {
return reexportNodeAdmin{client: c.Client}
}

type NodeAdminClientInstallDiskAcceleratorResults struct {
client rpc.Client
data nodeAdminInstallDiskAcceleratorResultsData
}

func (v *NodeAdminClientInstallDiskAcceleratorResults) HasKernelRelease() bool {
return v.data.KernelRelease != nil
}

func (v *NodeAdminClientInstallDiskAcceleratorResults) KernelRelease() string {
if v.data.KernelRelease == nil {
return ""
}
return *v.data.KernelRelease
}

func (v *NodeAdminClientInstallDiskAcceleratorResults) HasLbdVersion() bool {
return v.data.LbdVersion != nil
}

func (v *NodeAdminClientInstallDiskAcceleratorResults) LbdVersion() string {
if v.data.LbdVersion == nil {
return ""
}
return *v.data.LbdVersion
}

func (v *NodeAdminClientInstallDiskAcceleratorResults) HasError() bool {
return v.data.Error != nil
}

func (v *NodeAdminClientInstallDiskAcceleratorResults) Error() string {
if v.data.Error == nil {
return ""
}
return *v.data.Error
}

func (v NodeAdminClient) InstallDiskAccelerator(ctx context.Context, image string, force bool) (*NodeAdminClientInstallDiskAcceleratorResults, error) {
args := NodeAdminInstallDiskAcceleratorArgs{}
args.data.Image = &image
args.data.Force = &force

var ret nodeAdminInstallDiskAcceleratorResultsData

err := v.Call(ctx, "install_disk_accelerator", &args, &ret)
if err != nil {
return nil, err
}

return &NodeAdminClientInstallDiskAcceleratorResults{client: v.Client, data: ret}, nil
}
38 changes: 38 additions & 0 deletions api/nodeadmin/rpc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
apiVersion: miren.dev/rpc/v1
kind: IDL

# Work the coordinator asks one specific node to do to itself.
#
# This is separate from the exec service because it is not about a sandbox: it
# acts on the host, and the coordinator picks the node rather than deriving it
# from a workload's placement.

interfaces:
- name: NodeAdmin
methods:
- name: install_disk_accelerator
doc: |
Build and load the lbd kernel module on this node, so its disks can
use accelerator mode instead of loop devices.

The module has to be compiled against the kernel actually running
here, which is why this happens on the node rather than centrally.
The toolchain image is built once by the coordinator and pulled from
the cluster registry.
parameters:
- name: image
type: string
doc: Toolchain image reference to build with
- name: force
type: bool
doc: Rebuild even when the installed module is already current
results:
- name: kernel_release
type: string
doc: Kernel the module was built for
- name: lbd_version
type: string
doc: lbd version that was installed
- name: error
type: string
doc: Error message if the install failed
30 changes: 30 additions & 0 deletions api/runner/rpc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,36 @@ interfaces:
type: string
doc: Error message if issuance failed

- name: InstallDiskAccelerator
index: 13
doc: |
Build and load the lbd kernel module on a runner, so its disks can
use accelerator mode instead of loop devices.

The coordinator makes sure the toolchain image is in the cluster
registry, then asks the node to do the install. It runs on the node
because the module is compiled against the kernel running there.
parameters:
- name: query
type: string
doc: Runner to install on (name, ID, or short ID)
- name: force
type: bool
doc: Rebuild even when the installed module is already current
results:
- name: name
type: string
doc: Name of the runner installed on
- name: kernel_release
type: string
doc: Kernel the module was built for
- name: lbd_version
type: string
doc: lbd version that was installed
- name: error
type: string
doc: Error message if the install failed

types:
- type: InviteInfo
doc: Information about a runner invite
Expand Down
Loading
Loading