Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Yuji Ito <llamerada.jp@gmail.com>
  • Loading branch information
llamerada-jp committed Feb 7, 2023
1 parent 7b3f684 commit 2db41df
Show file tree
Hide file tree
Showing 4 changed files with 868 additions and 0 deletions.
101 changes: 101 additions & 0 deletions agent/cri/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package cri

import (
"encoding/json"
"strings"

"github.com/llamerada-jp/oinari/agent/crosslink"
)

const (
crosslinkPath = "cri"
)

type criImpl struct {
cl crosslink.Crosslink
}

func NewCRI(cl crosslink.Crosslink) CRI {
return &criImpl{
cl: cl,
}
}

func criCallHelper[REQ any, RES any](ci *criImpl, path string, request *REQ) (*RES, error) {
type ResErr struct {
res *RES
err error
}

reqJson, err := json.Marshal(request)
if err != nil {
return nil, err
}

ch := make(chan *ResErr)

ci.cl.Call(string(reqJson), map[string]string{
crosslink.TAG_PATH: strings.Join([]string{crosslinkPath, path}, "/"),
}, func(result string, err error) {
if err != nil {
ch <- &ResErr{nil, err}
return
}

var res RES
err = json.Unmarshal([]byte(result), &res)
if err != nil {
ch <- &ResErr{nil, err}
return
}

ch <- &ResErr{&res, nil}
})

resErr := <-ch
return resErr.res, resErr.err
}

func (ci *criImpl) RunPodSandbox(request *RunPodSandboxRequest) (*RunPodSandboxResponse, error) {
return criCallHelper[RunPodSandboxRequest, RunPodSandboxResponse](ci, "runPodSandbox", request)
}

func (ci *criImpl) StopPodSandbox(request *StopPodSandboxRequest) (*StopPodSandboxResponse, error) {
return criCallHelper[StopPodSandboxRequest, StopPodSandboxResponse](ci, "stopPodSandbox", request)
}

func (ci *criImpl) RemovePodSandbox(request *RemovePodSandboxRequest) (*RemovePodSandboxResponse, error) {
return criCallHelper[RemovePodSandboxRequest, RemovePodSandboxResponse](ci, "removePodSandbox", request)
}

func (ci *criImpl) PodSandboxStatus(request *PodSandboxStatusRequest) (*PodSandboxStatusResponse, error) {
return criCallHelper[PodSandboxStatusRequest, PodSandboxStatusResponse](ci, "podSandboxStatus", request)
}

func (ci *criImpl) CreateContainer(request *CreateContainerRequest) (*CreateContainerResponse, error) {
return criCallHelper[CreateContainerRequest, CreateContainerResponse](ci, "createContainer", request)
}

func (ci *criImpl) StartContainer(request *StartContainerRequest) (*StartContainerResponse, error) {
return criCallHelper[StartContainerRequest, StartContainerResponse](ci, "startContainer", request)
}

func (ci *criImpl) StopContainer(request *StopContainerRequest) (*StopContainerResponse, error) {
return criCallHelper[StopContainerRequest, StopContainerResponse](ci, "stopContainer", request)
}

func (ci *criImpl) RemoveContainer(request *RemoveContainerRequest) (*RemoveContainerResponse, error) {
return criCallHelper[RemoveContainerRequest, RemoveContainerResponse](ci, "removeContainer", request)
}

func (ci *criImpl) ListImages(request *ListImagesRequest) (*ListImagesResponse, error) {
return criCallHelper[ListImagesRequest, ListImagesResponse](ci, "listImages", request)
}

func (ci *criImpl) PullImage(request *PullImageRequest) (*PullImageResponse, error) {
return criCallHelper[PullImageRequest, PullImageResponse](ci, "pullImage", request)
}

func (ci *criImpl) RemoveImage(request *RemoveImageRequest) (*RemoveImageResponse, error) {
return criCallHelper[RemoveImageRequest, RemoveImageResponse](ci, "removeImage", request)
}
190 changes: 190 additions & 0 deletions agent/cri/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package cri

/**
* This interface is partial mimic of Kubernetes cri-api. And there are some differences
* caused by Oinari using WASM on the web browsers. Oinari implements the interface
* using crosslink internally without gRPC because it is difficult to implement it
* using gRPC between Go(WASM) and TypeScript via web worker.
* ref: https://github.com/kubernetes/cri-api
*/
type CRI interface {
// apis for sandbox
RunPodSandbox(*RunPodSandboxRequest) (*RunPodSandboxResponse, error)
StopPodSandbox(*StopPodSandboxRequest) (*StopPodSandboxResponse, error)
RemovePodSandbox(*RemovePodSandboxRequest) (*RemovePodSandboxResponse, error)
PodSandboxStatus(*PodSandboxStatusRequest) (*PodSandboxStatusResponse, error)

// apis for container
CreateContainer(*CreateContainerRequest) (*CreateContainerResponse, error)
StartContainer(*StartContainerRequest) (*StartContainerResponse, error)
StopContainer(*StopContainerRequest) (*StopContainerResponse, error)
RemoveContainer(*RemoveContainerRequest) (*RemoveContainerResponse, error)

// apis for image
ListImages(*ListImagesRequest) (*ListImagesResponse, error)
PullImage(*PullImageRequest) (*PullImageResponse, error)
RemoveImage(*RemoveImageRequest) (*RemoveImageResponse, error)
}

type RunPodSandboxRequest struct {
Config PodSandboxConfig `json:"config"`
}

type PodSandboxConfig struct {
Metadata PodSandboxMetadata `json:"metadata"`
}

type PodSandboxMetadata struct {
Name string `json:"name"`
// UID is equal to Pod UID in the Pod ObjectMeta. This value must be global unique in the Oinari system.
UID string `json:"uid"`
Namespace string `json:"namespace"`
}

type RunPodSandboxResponse struct {
// PodSandboxID is not equal to UID of PodSandboxMetadata. This value used in node local and unique in only the node.
PodSandboxID string `json:"pod_sandbox_id"`
}

type StopPodSandboxRequest struct {
PodSandboxID string `json:"pod_sandbox_id"`
}

type StopPodSandboxResponse struct {
// empty
}

type RemovePodSandboxRequest struct {
PodSandboxID string `json:"pod_sandbox_id"`
}

type RemovePodSandboxResponse struct {
// empty
}

type PodSandboxStatusRequest struct {
PodSandboxID string `json:"pod_sandbox_id"`
}

type PodSandboxStatusResponse struct {
Status PodSandboxStatus `json:"status"`
ContainersStatuses []ContainerStatus `json:"containers_statuses "`
Timestamp string `json:"timestamp"`
}

type PodSandboxStatus struct {
ID string `json:"id"`
Metadata PodSandboxMetadata `json:"metadata"`
State PodSandboxState `json:"state"`
CreatedAt string `json:"created_at"`
}

type PodSandboxState int

const (
SandboxReady PodSandboxState = iota
SandboxNotReady
)

type CreateContainerRequest struct {
PodSandboxID string `json:"pod_sandbox_id"`
Config ContainerConfig `json:"config"`
SandboxConfig PodSandboxConfig `json:"sandbox_config"`
}

type ContainerConfig struct {
Metadata ContainerMetadata `json:"metadata"`
Image ImageSpec `json:"image"`
}

type ContainerMetadata struct {
Name string `json:"name"`
}

type CreateContainerResponse struct {
ContainerID string `json:"container_id"`
}

type StartContainerRequest struct {
ContainerID string `json:"container_id"`
}

type StartContainerResponse struct {
// empty
}

type StopContainerRequest struct {
ContainerID string `json:"container_id"`
}

type StopContainerResponse struct {
// empty
}

type RemoveContainerRequest struct {
ContainerID string `json:"container_id"`
}

type RemoveContainerResponse struct {
// empty
}

type ContainerStatus struct {
ID string `json:"id"`
Metadata ContainerMetadata `json:"metadata"`
State ContainerState `json:"state"`
CreatedAt string `json:"created_at"`
StartedAt string `json:"started_at"`
FinishedAt string `json:"finished_at"`
ExitCode int32 `json:"exit_code"`
Image ImageSpec `json:"image"`
ImageRef string `json:"image_ref"`
}

type ContainerState int

const (
ContainerCreated ContainerState = iota
ContainerRunning
ContainerExited
ContainerUnknown
)

type ListImagesRequest struct {
Filter ImageFilter `json:"filter"`
}

type ImageFilter struct {
Image ImageSpec `json:"image"`
}

type ImageSpec struct {
Image string `json:"image"`
}

type ListImagesResponse struct {
Images []Image `json:"images"`
}

type Image struct {
ID string `json:"id"`
Spec ImageSpec `json:"spec"`
// this field meaning the runtime environment of wasm, like 'go:1.19'
Runtime string `json:"runtime"`
}

type PullImageRequest struct {
Image ImageSpec `json:"image"`
}

type PullImageResponse struct {
ImageRef string `json:"image_ref"`
}

type RemoveImageRequest struct {
Image ImageSpec `json:"image"`
}

type RemoveImageResponse struct {
// nothing
}
2 changes: 2 additions & 0 deletions cmd/agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

"github.com/llamerada-jp/colonio/go/colonio"
"github.com/llamerada-jp/oinari/agent/core"
"github.com/llamerada-jp/oinari/agent/cri"
"github.com/llamerada-jp/oinari/agent/crosslink"
"github.com/llamerada-jp/oinari/agent/global"
"github.com/llamerada-jp/oinari/agent/local"
Expand Down Expand Up @@ -131,6 +132,7 @@ func main() {

gcd := global.NewCommandDriver(col)
lcd := local.NewCommandDriver(cl)
cri := cri.NewCRI(cl)
seh := newSystemEventHandler(col)

sys := core.NewSystem(col, seh, gcd, lcd)
Expand Down
Loading

0 comments on commit 2db41df

Please sign in to comment.