mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
daemon: isPermissibleC8dRuntimeName: use local utility to reduce c8d deps
The `shim.BinaryName()` function used from containerd is part of the "github.com/containerd/containerd/runtime/v2/shim" packaqge, which comes with a large number of dependencies. This patch implements a local variant of the check so that we can remove the dependency. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -17,7 +17,6 @@ import (
|
||||
|
||||
"github.com/containerd/containerd/plugin"
|
||||
v2runcoptions "github.com/containerd/containerd/runtime/v2/runc/options"
|
||||
"github.com/containerd/containerd/runtime/v2/shim"
|
||||
"github.com/containerd/log"
|
||||
"github.com/docker/docker/daemon/config"
|
||||
"github.com/docker/docker/errdefs"
|
||||
@@ -265,6 +264,17 @@ func isPermissibleC8dRuntimeName(name string) bool {
|
||||
// "containerd-shim---".
|
||||
//
|
||||
// https://github.com/containerd/containerd/blob/11ded166c15f92450958078cd13c6d87131ec563/runtime/v2/manager.go#L297-L317
|
||||
// https://github.com/containerd/containerd/blob/11ded166c15f92450958078cd13c6d87131ec563/runtime/v2/shim/util.go#L83-L93
|
||||
return !filepath.IsAbs(name) && !strings.ContainsRune(name, '/') && shim.BinaryName(name) != ""
|
||||
if filepath.IsAbs(name) || strings.ContainsRune(name, '/') {
|
||||
return false
|
||||
}
|
||||
|
||||
// runtime name should format like $prefix.name.version
|
||||
// see: https://github.com/containerd/containerd/blob/11ded166c15f92450958078cd13c6d87131ec563/runtime/v2/shim/util.go#L83-L93
|
||||
//
|
||||
// FIXME(thaJeztah): add a utility to the containerd module for this; some parts (like [shim.BinaryName]) are in the shim package, which comes with a large number of dependencies.
|
||||
if prefix, _, ok := strings.Cut(name, "."); !ok || prefix == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
17
vendor/github.com/containerd/containerd/api/runtime/task/v2/doc.go
generated
vendored
17
vendor/github.com/containerd/containerd/api/runtime/task/v2/doc.go
generated
vendored
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 task
|
||||
2338
vendor/github.com/containerd/containerd/api/runtime/task/v2/shim.pb.go
generated
vendored
2338
vendor/github.com/containerd/containerd/api/runtime/task/v2/shim.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
201
vendor/github.com/containerd/containerd/api/runtime/task/v2/shim.proto
generated
vendored
201
vendor/github.com/containerd/containerd/api/runtime/task/v2/shim.proto
generated
vendored
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package containerd.task.v2;
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "github.com/containerd/containerd/api/types/mount.proto";
|
||||
import "github.com/containerd/containerd/api/types/task/task.proto";
|
||||
|
||||
option go_package = "github.com/containerd/containerd/api/runtime/task/v2;task";
|
||||
|
||||
// Shim service is launched for each container and is responsible for owning the IO
|
||||
// for the container and its additional processes. The shim is also the parent of
|
||||
// each container and allows reattaching to the IO and receiving the exit status
|
||||
// for the container processes.
|
||||
service Task {
|
||||
rpc State(StateRequest) returns (StateResponse);
|
||||
rpc Create(CreateTaskRequest) returns (CreateTaskResponse);
|
||||
rpc Start(StartRequest) returns (StartResponse);
|
||||
rpc Delete(DeleteRequest) returns (DeleteResponse);
|
||||
rpc Pids(PidsRequest) returns (PidsResponse);
|
||||
rpc Pause(PauseRequest) returns (google.protobuf.Empty);
|
||||
rpc Resume(ResumeRequest) returns (google.protobuf.Empty);
|
||||
rpc Checkpoint(CheckpointTaskRequest) returns (google.protobuf.Empty);
|
||||
rpc Kill(KillRequest) returns (google.protobuf.Empty);
|
||||
rpc Exec(ExecProcessRequest) returns (google.protobuf.Empty);
|
||||
rpc ResizePty(ResizePtyRequest) returns (google.protobuf.Empty);
|
||||
rpc CloseIO(CloseIORequest) returns (google.protobuf.Empty);
|
||||
rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty);
|
||||
rpc Wait(WaitRequest) returns (WaitResponse);
|
||||
rpc Stats(StatsRequest) returns (StatsResponse);
|
||||
rpc Connect(ConnectRequest) returns (ConnectResponse);
|
||||
rpc Shutdown(ShutdownRequest) returns (google.protobuf.Empty);
|
||||
}
|
||||
|
||||
message CreateTaskRequest {
|
||||
string id = 1;
|
||||
string bundle = 2;
|
||||
repeated containerd.types.Mount rootfs = 3;
|
||||
bool terminal = 4;
|
||||
string stdin = 5;
|
||||
string stdout = 6;
|
||||
string stderr = 7;
|
||||
string checkpoint = 8;
|
||||
string parent_checkpoint = 9;
|
||||
google.protobuf.Any options = 10;
|
||||
}
|
||||
|
||||
message CreateTaskResponse {
|
||||
uint32 pid = 1;
|
||||
}
|
||||
|
||||
message DeleteRequest {
|
||||
string id = 1;
|
||||
string exec_id = 2;
|
||||
}
|
||||
|
||||
message DeleteResponse {
|
||||
uint32 pid = 1;
|
||||
uint32 exit_status = 2;
|
||||
google.protobuf.Timestamp exited_at = 3;
|
||||
}
|
||||
|
||||
message ExecProcessRequest {
|
||||
string id = 1;
|
||||
string exec_id = 2;
|
||||
bool terminal = 3;
|
||||
string stdin = 4;
|
||||
string stdout = 5;
|
||||
string stderr = 6;
|
||||
google.protobuf.Any spec = 7;
|
||||
}
|
||||
|
||||
message ExecProcessResponse {
|
||||
}
|
||||
|
||||
message ResizePtyRequest {
|
||||
string id = 1;
|
||||
string exec_id = 2;
|
||||
uint32 width = 3;
|
||||
uint32 height = 4;
|
||||
}
|
||||
|
||||
message StateRequest {
|
||||
string id = 1;
|
||||
string exec_id = 2;
|
||||
}
|
||||
|
||||
message StateResponse {
|
||||
string id = 1;
|
||||
string bundle = 2;
|
||||
uint32 pid = 3;
|
||||
containerd.v1.types.Status status = 4;
|
||||
string stdin = 5;
|
||||
string stdout = 6;
|
||||
string stderr = 7;
|
||||
bool terminal = 8;
|
||||
uint32 exit_status = 9;
|
||||
google.protobuf.Timestamp exited_at = 10;
|
||||
string exec_id = 11;
|
||||
}
|
||||
|
||||
message KillRequest {
|
||||
string id = 1;
|
||||
string exec_id = 2;
|
||||
uint32 signal = 3;
|
||||
bool all = 4;
|
||||
}
|
||||
|
||||
message CloseIORequest {
|
||||
string id = 1;
|
||||
string exec_id = 2;
|
||||
bool stdin = 3;
|
||||
}
|
||||
|
||||
message PidsRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message PidsResponse {
|
||||
repeated containerd.v1.types.ProcessInfo processes = 1;
|
||||
}
|
||||
|
||||
message CheckpointTaskRequest {
|
||||
string id = 1;
|
||||
string path = 2;
|
||||
google.protobuf.Any options = 3;
|
||||
}
|
||||
|
||||
message UpdateTaskRequest {
|
||||
string id = 1;
|
||||
google.protobuf.Any resources = 2;
|
||||
map<string, string> annotations = 3;
|
||||
}
|
||||
|
||||
message StartRequest {
|
||||
string id = 1;
|
||||
string exec_id = 2;
|
||||
}
|
||||
|
||||
message StartResponse {
|
||||
uint32 pid = 1;
|
||||
}
|
||||
|
||||
message WaitRequest {
|
||||
string id = 1;
|
||||
string exec_id = 2;
|
||||
}
|
||||
|
||||
message WaitResponse {
|
||||
uint32 exit_status = 1;
|
||||
google.protobuf.Timestamp exited_at = 2;
|
||||
}
|
||||
|
||||
message StatsRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message StatsResponse {
|
||||
google.protobuf.Any stats = 1;
|
||||
}
|
||||
|
||||
message ConnectRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message ConnectResponse {
|
||||
uint32 shim_pid = 1;
|
||||
uint32 task_pid = 2;
|
||||
string version = 3;
|
||||
}
|
||||
|
||||
message ShutdownRequest {
|
||||
string id = 1;
|
||||
bool now = 2;
|
||||
}
|
||||
|
||||
message PauseRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message ResumeRequest {
|
||||
string id = 1;
|
||||
}
|
||||
301
vendor/github.com/containerd/containerd/api/runtime/task/v2/shim_ttrpc.pb.go
generated
vendored
301
vendor/github.com/containerd/containerd/api/runtime/task/v2/shim_ttrpc.pb.go
generated
vendored
@@ -1,301 +0,0 @@
|
||||
// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT.
|
||||
// source: github.com/containerd/containerd/api/runtime/task/v2/shim.proto
|
||||
package task
|
||||
|
||||
import (
|
||||
context "context"
|
||||
ttrpc "github.com/containerd/ttrpc"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
type TaskService interface {
|
||||
State(context.Context, *StateRequest) (*StateResponse, error)
|
||||
Create(context.Context, *CreateTaskRequest) (*CreateTaskResponse, error)
|
||||
Start(context.Context, *StartRequest) (*StartResponse, error)
|
||||
Delete(context.Context, *DeleteRequest) (*DeleteResponse, error)
|
||||
Pids(context.Context, *PidsRequest) (*PidsResponse, error)
|
||||
Pause(context.Context, *PauseRequest) (*emptypb.Empty, error)
|
||||
Resume(context.Context, *ResumeRequest) (*emptypb.Empty, error)
|
||||
Checkpoint(context.Context, *CheckpointTaskRequest) (*emptypb.Empty, error)
|
||||
Kill(context.Context, *KillRequest) (*emptypb.Empty, error)
|
||||
Exec(context.Context, *ExecProcessRequest) (*emptypb.Empty, error)
|
||||
ResizePty(context.Context, *ResizePtyRequest) (*emptypb.Empty, error)
|
||||
CloseIO(context.Context, *CloseIORequest) (*emptypb.Empty, error)
|
||||
Update(context.Context, *UpdateTaskRequest) (*emptypb.Empty, error)
|
||||
Wait(context.Context, *WaitRequest) (*WaitResponse, error)
|
||||
Stats(context.Context, *StatsRequest) (*StatsResponse, error)
|
||||
Connect(context.Context, *ConnectRequest) (*ConnectResponse, error)
|
||||
Shutdown(context.Context, *ShutdownRequest) (*emptypb.Empty, error)
|
||||
}
|
||||
|
||||
func RegisterTaskService(srv *ttrpc.Server, svc TaskService) {
|
||||
srv.RegisterService("containerd.task.v2.Task", &ttrpc.ServiceDesc{
|
||||
Methods: map[string]ttrpc.Method{
|
||||
"State": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req StateRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.State(ctx, &req)
|
||||
},
|
||||
"Create": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req CreateTaskRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Create(ctx, &req)
|
||||
},
|
||||
"Start": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req StartRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Start(ctx, &req)
|
||||
},
|
||||
"Delete": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req DeleteRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Delete(ctx, &req)
|
||||
},
|
||||
"Pids": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req PidsRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Pids(ctx, &req)
|
||||
},
|
||||
"Pause": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req PauseRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Pause(ctx, &req)
|
||||
},
|
||||
"Resume": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req ResumeRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Resume(ctx, &req)
|
||||
},
|
||||
"Checkpoint": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req CheckpointTaskRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Checkpoint(ctx, &req)
|
||||
},
|
||||
"Kill": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req KillRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Kill(ctx, &req)
|
||||
},
|
||||
"Exec": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req ExecProcessRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Exec(ctx, &req)
|
||||
},
|
||||
"ResizePty": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req ResizePtyRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.ResizePty(ctx, &req)
|
||||
},
|
||||
"CloseIO": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req CloseIORequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.CloseIO(ctx, &req)
|
||||
},
|
||||
"Update": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req UpdateTaskRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Update(ctx, &req)
|
||||
},
|
||||
"Wait": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req WaitRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Wait(ctx, &req)
|
||||
},
|
||||
"Stats": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req StatsRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Stats(ctx, &req)
|
||||
},
|
||||
"Connect": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req ConnectRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Connect(ctx, &req)
|
||||
},
|
||||
"Shutdown": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req ShutdownRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Shutdown(ctx, &req)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type taskClient struct {
|
||||
client *ttrpc.Client
|
||||
}
|
||||
|
||||
func NewTaskClient(client *ttrpc.Client) TaskService {
|
||||
return &taskClient{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *taskClient) State(ctx context.Context, req *StateRequest) (*StateResponse, error) {
|
||||
var resp StateResponse
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "State", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Create(ctx context.Context, req *CreateTaskRequest) (*CreateTaskResponse, error) {
|
||||
var resp CreateTaskResponse
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Create", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Start(ctx context.Context, req *StartRequest) (*StartResponse, error) {
|
||||
var resp StartResponse
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Start", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Delete(ctx context.Context, req *DeleteRequest) (*DeleteResponse, error) {
|
||||
var resp DeleteResponse
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Delete", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Pids(ctx context.Context, req *PidsRequest) (*PidsResponse, error) {
|
||||
var resp PidsResponse
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Pids", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Pause(ctx context.Context, req *PauseRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Pause", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Resume(ctx context.Context, req *ResumeRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Resume", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Checkpoint(ctx context.Context, req *CheckpointTaskRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Checkpoint", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Kill(ctx context.Context, req *KillRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Kill", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Exec(ctx context.Context, req *ExecProcessRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Exec", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) ResizePty(ctx context.Context, req *ResizePtyRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "ResizePty", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) CloseIO(ctx context.Context, req *CloseIORequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "CloseIO", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Update(ctx context.Context, req *UpdateTaskRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Update", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Wait(ctx context.Context, req *WaitRequest) (*WaitResponse, error) {
|
||||
var resp WaitResponse
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Wait", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Stats(ctx context.Context, req *StatsRequest) (*StatsResponse, error) {
|
||||
var resp StatsResponse
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Stats", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Connect(ctx context.Context, req *ConnectRequest) (*ConnectResponse, error) {
|
||||
var resp ConnectResponse
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Connect", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (c *taskClient) Shutdown(ctx context.Context, req *ShutdownRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.task.v2.Task", "Shutdown", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
18
vendor/github.com/containerd/containerd/api/services/ttrpc/events/v1/doc.go
generated
vendored
18
vendor/github.com/containerd/containerd/api/services/ttrpc/events/v1/doc.go
generated
vendored
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 events defines the ttrpc event service.
|
||||
package events
|
||||
292
vendor/github.com/containerd/containerd/api/services/ttrpc/events/v1/events.pb.go
generated
vendored
292
vendor/github.com/containerd/containerd/api/services/ttrpc/events/v1/events.pb.go
generated
vendored
@@ -1,292 +0,0 @@
|
||||
//
|
||||
//Copyright The containerd Authors.
|
||||
//
|
||||
//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.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.20.1
|
||||
// source: github.com/containerd/containerd/api/services/ttrpc/events/v1/events.proto
|
||||
|
||||
package events
|
||||
|
||||
import (
|
||||
_ "github.com/containerd/containerd/api/types"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ForwardRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Envelope *Envelope `protobuf:"bytes,1,opt,name=envelope,proto3" json:"envelope,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ForwardRequest) Reset() {
|
||||
*x = ForwardRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ForwardRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ForwardRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ForwardRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ForwardRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ForwardRequest) Descriptor() ([]byte, []int) {
|
||||
return file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ForwardRequest) GetEnvelope() *Envelope {
|
||||
if x != nil {
|
||||
return x.Envelope
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Envelope struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"`
|
||||
Topic string `protobuf:"bytes,3,opt,name=topic,proto3" json:"topic,omitempty"`
|
||||
Event *anypb.Any `protobuf:"bytes,4,opt,name=event,proto3" json:"event,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Envelope) Reset() {
|
||||
*x = Envelope{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Envelope) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Envelope) ProtoMessage() {}
|
||||
|
||||
func (x *Envelope) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Envelope.ProtoReflect.Descriptor instead.
|
||||
func (*Envelope) Descriptor() ([]byte, []int) {
|
||||
return file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Envelope) GetTimestamp() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.Timestamp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Envelope) GetNamespace() string {
|
||||
if x != nil {
|
||||
return x.Namespace
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Envelope) GetTopic() string {
|
||||
if x != nil {
|
||||
return x.Topic
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Envelope) GetEvent() *anypb.Any {
|
||||
if x != nil {
|
||||
return x.Event
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDesc = []byte{
|
||||
0x0a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
|
||||
0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f,
|
||||
0x74, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x23, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x74, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76,
|
||||
0x31, 0x1a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f,
|
||||
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
|
||||
0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x66, 0x69,
|
||||
0x65, 0x6c, 0x64, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61,
|
||||
0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5b, 0x0a, 0x0e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72,
|
||||
0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x49, 0x0a, 0x08, 0x65, 0x6e, 0x76, 0x65,
|
||||
0x6c, 0x6f, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
|
||||
0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x74, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x52, 0x08, 0x65, 0x6e, 0x76, 0x65, 0x6c,
|
||||
0x6f, 0x70, 0x65, 0x22, 0xaa, 0x01, 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65,
|
||||
0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||
0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69,
|
||||
0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x2a,
|
||||
0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x41, 0x6e, 0x79, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x04, 0x80, 0xb9, 0x1f, 0x01,
|
||||
0x32, 0x60, 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x56, 0x0a, 0x07, 0x46, 0x6f,
|
||||
0x72, 0x77, 0x61, 0x72, 0x64, 0x12, 0x33, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
|
||||
0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e,
|
||||
0x74, 0x73, 0x2e, 0x74, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x77,
|
||||
0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
|
||||
0x74, 0x79, 0x42, 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74,
|
||||
0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x73, 0x2f, 0x74, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73,
|
||||
0x2f, 0x76, 0x31, 0x3b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescOnce sync.Once
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescData = file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescGZIP() []byte {
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescOnce.Do(func() {
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescData)
|
||||
})
|
||||
return file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_goTypes = []interface{}{
|
||||
(*ForwardRequest)(nil), // 0: containerd.services.events.ttrpc.v1.ForwardRequest
|
||||
(*Envelope)(nil), // 1: containerd.services.events.ttrpc.v1.Envelope
|
||||
(*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp
|
||||
(*anypb.Any)(nil), // 3: google.protobuf.Any
|
||||
(*emptypb.Empty)(nil), // 4: google.protobuf.Empty
|
||||
}
|
||||
var file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_depIdxs = []int32{
|
||||
1, // 0: containerd.services.events.ttrpc.v1.ForwardRequest.envelope:type_name -> containerd.services.events.ttrpc.v1.Envelope
|
||||
2, // 1: containerd.services.events.ttrpc.v1.Envelope.timestamp:type_name -> google.protobuf.Timestamp
|
||||
3, // 2: containerd.services.events.ttrpc.v1.Envelope.event:type_name -> google.protobuf.Any
|
||||
0, // 3: containerd.services.events.ttrpc.v1.Events.Forward:input_type -> containerd.services.events.ttrpc.v1.ForwardRequest
|
||||
4, // 4: containerd.services.events.ttrpc.v1.Events.Forward:output_type -> google.protobuf.Empty
|
||||
4, // [4:5] is the sub-list for method output_type
|
||||
3, // [3:4] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_init() }
|
||||
func file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_init() {
|
||||
if File_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ForwardRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Envelope); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_goTypes,
|
||||
DependencyIndexes: file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_depIdxs,
|
||||
MessageInfos: file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_msgTypes,
|
||||
}.Build()
|
||||
File_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto = out.File
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_rawDesc = nil
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_goTypes = nil
|
||||
file_github_com_containerd_containerd_api_services_ttrpc_events_v1_events_proto_depIdxs = nil
|
||||
}
|
||||
47
vendor/github.com/containerd/containerd/api/services/ttrpc/events/v1/events.proto
generated
vendored
47
vendor/github.com/containerd/containerd/api/services/ttrpc/events/v1/events.proto
generated
vendored
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package containerd.services.events.ttrpc.v1;
|
||||
|
||||
import "github.com/containerd/containerd/api/types/fieldpath.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
option go_package = "github.com/containerd/containerd/api/services/ttrpc/events/v1;events";
|
||||
|
||||
service Events {
|
||||
// Forward sends an event that has already been packaged into an envelope
|
||||
// with a timestamp and namespace.
|
||||
//
|
||||
// This is useful if earlier timestamping is required or when forwarding on
|
||||
// behalf of another component, namespace or publisher.
|
||||
rpc Forward(ForwardRequest) returns (google.protobuf.Empty);
|
||||
}
|
||||
|
||||
message ForwardRequest {
|
||||
Envelope envelope = 1;
|
||||
}
|
||||
|
||||
message Envelope {
|
||||
option (containerd.types.fieldpath) = true;
|
||||
google.protobuf.Timestamp timestamp = 1;
|
||||
string namespace = 2;
|
||||
string topic = 3;
|
||||
google.protobuf.Any event = 4;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// Code generated by protoc-gen-go-fieldpath. DO NOT EDIT.
|
||||
// source: github.com/containerd/containerd/api/services/ttrpc/events/v1/events.proto
|
||||
package events
|
||||
|
||||
import (
|
||||
v2 "github.com/containerd/typeurl/v2"
|
||||
)
|
||||
|
||||
// Field returns the value for the given fieldpath as a string, if defined.
|
||||
// If the value is not defined, the second value will be false.
|
||||
func (m *ForwardRequest) Field(fieldpath []string) (string, bool) {
|
||||
if len(fieldpath) == 0 {
|
||||
return "", false
|
||||
}
|
||||
switch fieldpath[0] {
|
||||
case "envelope":
|
||||
// NOTE(stevvooe): This is probably not correct in many cases.
|
||||
// We assume that the target message also implements the Field
|
||||
// method, which isn't likely true in a lot of cases.
|
||||
//
|
||||
// If you have a broken build and have found this comment,
|
||||
// you may be closer to a solution.
|
||||
if m.Envelope == nil {
|
||||
return "", false
|
||||
}
|
||||
return m.Envelope.Field(fieldpath[1:])
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Field returns the value for the given fieldpath as a string, if defined.
|
||||
// If the value is not defined, the second value will be false.
|
||||
func (m *Envelope) Field(fieldpath []string) (string, bool) {
|
||||
if len(fieldpath) == 0 {
|
||||
return "", false
|
||||
}
|
||||
switch fieldpath[0] {
|
||||
// unhandled: timestamp
|
||||
case "namespace":
|
||||
return string(m.Namespace), len(m.Namespace) > 0
|
||||
case "topic":
|
||||
return string(m.Topic), len(m.Topic) > 0
|
||||
case "event":
|
||||
decoded, err := v2.UnmarshalAny(m.Event)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
adaptor, ok := decoded.(interface{ Field([]string) (string, bool) })
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
return adaptor.Field(fieldpath[1:])
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
45
vendor/github.com/containerd/containerd/api/services/ttrpc/events/v1/events_ttrpc.pb.go
generated
vendored
45
vendor/github.com/containerd/containerd/api/services/ttrpc/events/v1/events_ttrpc.pb.go
generated
vendored
@@ -1,45 +0,0 @@
|
||||
// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT.
|
||||
// source: github.com/containerd/containerd/api/services/ttrpc/events/v1/events.proto
|
||||
package events
|
||||
|
||||
import (
|
||||
context "context"
|
||||
ttrpc "github.com/containerd/ttrpc"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
type EventsService interface {
|
||||
Forward(context.Context, *ForwardRequest) (*emptypb.Empty, error)
|
||||
}
|
||||
|
||||
func RegisterEventsService(srv *ttrpc.Server, svc EventsService) {
|
||||
srv.RegisterService("containerd.services.events.ttrpc.v1.Events", &ttrpc.ServiceDesc{
|
||||
Methods: map[string]ttrpc.Method{
|
||||
"Forward": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
|
||||
var req ForwardRequest
|
||||
if err := unmarshal(&req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return svc.Forward(ctx, &req)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type eventsClient struct {
|
||||
client *ttrpc.Client
|
||||
}
|
||||
|
||||
func NewEventsClient(client *ttrpc.Client) EventsService {
|
||||
return &eventsClient{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *eventsClient) Forward(ctx context.Context, req *ForwardRequest) (*emptypb.Empty, error) {
|
||||
var resp emptypb.Empty
|
||||
if err := c.client.Call(ctx, "containerd.services.events.ttrpc.v1.Events", "Forward", req, &resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
148
vendor/github.com/containerd/containerd/pkg/atomicfile/file.go
generated
vendored
148
vendor/github.com/containerd/containerd/pkg/atomicfile/file.go
generated
vendored
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 atomicfile provides a mechanism (on Unix-like platforms) to present a consistent view of a file to separate
|
||||
processes even while the file is being written. This is accomplished by writing a temporary file, syncing to disk, and
|
||||
renaming over the destination file name.
|
||||
|
||||
Partial/inconsistent reads can occur due to:
|
||||
1. A process attempting to read the file while it is being written to (both in the case of a new file with a
|
||||
short/incomplete write or in the case of an existing, updated file where new bytes may be written at the beginning
|
||||
but old bytes may still be present after).
|
||||
2. Concurrent goroutines leading to multiple active writers of the same file.
|
||||
|
||||
The above mechanism explicitly protects against (1) as all writes are to a file with a temporary name.
|
||||
|
||||
There is no explicit protection against multiple, concurrent goroutines attempting to write the same file. However,
|
||||
atomically writing the file should mean only one writer will "win" and a consistent file will be visible.
|
||||
|
||||
Note: atomicfile is partially implemented for Windows. The Windows codepath performs the same operations, however
|
||||
Windows does not guarantee that a rename operation is atomic; a crash in the middle may leave the destination file
|
||||
truncated rather than with the expected content.
|
||||
*/
|
||||
package atomicfile
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// File is an io.ReadWriteCloser that can also be Canceled if a change needs to be abandoned.
|
||||
type File interface {
|
||||
io.ReadWriteCloser
|
||||
// Cancel abandons a change to a file. This can be called if a write fails or another error occurs.
|
||||
Cancel() error
|
||||
}
|
||||
|
||||
// ErrClosed is returned if Read or Write are called on a closed File.
|
||||
var ErrClosed = errors.New("file is closed")
|
||||
|
||||
// New returns a new atomic file. On Unix-like platforms, the writer (an io.ReadWriteCloser) is backed by a temporary
|
||||
// file placed into the same directory as the destination file (using filepath.Dir to split the directory from the
|
||||
// name). On a call to Close the temporary file is synced to disk and renamed to its final name, hiding any previous
|
||||
// file by the same name.
|
||||
//
|
||||
// Note: Take care to call Close and handle any errors that are returned. Errors returned from Close may indicate that
|
||||
// the file was not written with its final name.
|
||||
func New(name string, mode os.FileMode) (File, error) {
|
||||
return newFile(name, mode)
|
||||
}
|
||||
|
||||
type atomicFile struct {
|
||||
name string
|
||||
f *os.File
|
||||
closed bool
|
||||
closedMu sync.RWMutex
|
||||
}
|
||||
|
||||
func newFile(name string, mode os.FileMode) (File, error) {
|
||||
dir := filepath.Dir(name)
|
||||
f, err := os.CreateTemp(dir, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create temp file: %w", err)
|
||||
}
|
||||
if err := f.Chmod(mode); err != nil {
|
||||
return nil, fmt.Errorf("failed to change temp file permissions: %w", err)
|
||||
}
|
||||
return &atomicFile{name: name, f: f}, nil
|
||||
}
|
||||
|
||||
func (a *atomicFile) Close() (err error) {
|
||||
a.closedMu.Lock()
|
||||
defer a.closedMu.Unlock()
|
||||
|
||||
if a.closed {
|
||||
return nil
|
||||
}
|
||||
a.closed = true
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = os.Remove(a.f.Name()) // ignore errors
|
||||
}
|
||||
}()
|
||||
// The order of operations here is:
|
||||
// 1. sync
|
||||
// 2. close
|
||||
// 3. rename
|
||||
// While the ordering of 2 and 3 is not important on Unix-like operating systems, Windows cannot rename an open
|
||||
// file. By closing first, we allow the rename operation to succeed.
|
||||
if err = a.f.Sync(); err != nil {
|
||||
return fmt.Errorf("failed to sync temp file %q: %w", a.f.Name(), err)
|
||||
}
|
||||
if err = a.f.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close temp file %q: %w", a.f.Name(), err)
|
||||
}
|
||||
if err = os.Rename(a.f.Name(), a.name); err != nil {
|
||||
return fmt.Errorf("failed to rename %q to %q: %w", a.f.Name(), a.name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *atomicFile) Cancel() error {
|
||||
a.closedMu.Lock()
|
||||
defer a.closedMu.Unlock()
|
||||
|
||||
if a.closed {
|
||||
return nil
|
||||
}
|
||||
a.closed = true
|
||||
_ = a.f.Close() // ignore error
|
||||
return os.Remove(a.f.Name())
|
||||
}
|
||||
|
||||
func (a *atomicFile) Read(p []byte) (n int, err error) {
|
||||
a.closedMu.RLock()
|
||||
defer a.closedMu.RUnlock()
|
||||
if a.closed {
|
||||
return 0, ErrClosed
|
||||
}
|
||||
return a.f.Read(p)
|
||||
}
|
||||
|
||||
func (a *atomicFile) Write(p []byte) (n int, err error) {
|
||||
a.closedMu.RLock()
|
||||
defer a.closedMu.RUnlock()
|
||||
if a.closed {
|
||||
return 0, ErrClosed
|
||||
}
|
||||
return a.f.Write(p)
|
||||
}
|
||||
115
vendor/github.com/containerd/containerd/pkg/shutdown/shutdown.go
generated
vendored
115
vendor/github.com/containerd/containerd/pkg/shutdown/shutdown.go
generated
vendored
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shutdown
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// ErrShutdown is the error condition when a context has been fully shutdown
|
||||
var ErrShutdown = errors.New("shutdown")
|
||||
|
||||
// Service is used to facilitate shutdown by through callback
|
||||
// registration and shutdown initiation
|
||||
type Service interface {
|
||||
// Shutdown initiates shutdown
|
||||
Shutdown()
|
||||
// RegisterCallback registers functions to be called on shutdown and before
|
||||
// the shutdown channel is closed. A callback error will propagate to the
|
||||
// context error
|
||||
RegisterCallback(func(context.Context) error)
|
||||
// Done returns a channel that's closed when all shutdown callbacks are invoked.
|
||||
Done() <-chan struct{}
|
||||
// Err returns nil if Done is not yet closed.
|
||||
// If Done is closed, Err returns first failed callback error or ErrShutdown.
|
||||
Err() error
|
||||
}
|
||||
|
||||
// WithShutdown returns a context which is similar to a cancel context, but
|
||||
// with callbacks which can propagate to the context error. Unlike a cancel
|
||||
// context, the shutdown context cannot be canceled from the parent context.
|
||||
// However, future child contexes will be canceled upon shutdown.
|
||||
func WithShutdown(ctx context.Context) (context.Context, Service) {
|
||||
ss := &shutdownService{
|
||||
Context: ctx,
|
||||
doneC: make(chan struct{}),
|
||||
timeout: 30 * time.Second,
|
||||
}
|
||||
return ss, ss
|
||||
}
|
||||
|
||||
type shutdownService struct {
|
||||
context.Context
|
||||
|
||||
mu sync.Mutex
|
||||
isShutdown bool
|
||||
callbacks []func(context.Context) error
|
||||
doneC chan struct{}
|
||||
err error
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func (s *shutdownService) Shutdown() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if s.isShutdown {
|
||||
return
|
||||
}
|
||||
s.isShutdown = true
|
||||
|
||||
go func(callbacks []func(context.Context) error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
|
||||
defer cancel()
|
||||
grp, ctx := errgroup.WithContext(ctx)
|
||||
for i := range callbacks {
|
||||
fn := callbacks[i]
|
||||
grp.Go(func() error { return fn(ctx) })
|
||||
}
|
||||
err := grp.Wait()
|
||||
if err == nil {
|
||||
err = ErrShutdown
|
||||
}
|
||||
s.mu.Lock()
|
||||
s.err = err
|
||||
close(s.doneC)
|
||||
s.mu.Unlock()
|
||||
}(s.callbacks)
|
||||
}
|
||||
|
||||
func (s *shutdownService) Done() <-chan struct{} {
|
||||
return s.doneC
|
||||
}
|
||||
|
||||
func (s *shutdownService) Err() error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.err
|
||||
}
|
||||
|
||||
func (s *shutdownService) RegisterCallback(fn func(context.Context) error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if s.callbacks == nil {
|
||||
s.callbacks = []func(context.Context) error{}
|
||||
}
|
||||
s.callbacks = append(s.callbacks, fn)
|
||||
}
|
||||
123
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go
generated
vendored
123
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go
generated
vendored
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 ttrpcutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
v1 "github.com/containerd/containerd/api/services/ttrpc/events/v1"
|
||||
"github.com/containerd/containerd/pkg/dialer"
|
||||
"github.com/containerd/ttrpc"
|
||||
)
|
||||
|
||||
const ttrpcDialTimeout = 5 * time.Second
|
||||
|
||||
type ttrpcConnector func() (*ttrpc.Client, error)
|
||||
|
||||
// Client is the client to interact with TTRPC part of containerd server (plugins, events)
|
||||
type Client struct {
|
||||
mu sync.Mutex
|
||||
connector ttrpcConnector
|
||||
client *ttrpc.Client
|
||||
closed bool
|
||||
}
|
||||
|
||||
// NewClient returns a new containerd TTRPC client that is connected to the containerd instance provided by address
|
||||
func NewClient(address string, opts ...ttrpc.ClientOpts) (*Client, error) {
|
||||
connector := func() (*ttrpc.Client, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), ttrpcDialTimeout)
|
||||
defer cancel()
|
||||
conn, err := dialer.ContextDialer(ctx, address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect: %w", err)
|
||||
}
|
||||
|
||||
client := ttrpc.NewClient(conn, opts...)
|
||||
return client, nil
|
||||
}
|
||||
|
||||
return &Client{
|
||||
connector: connector,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Reconnect re-establishes the TTRPC connection to the containerd daemon
|
||||
func (c *Client) Reconnect() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if c.connector == nil {
|
||||
return errors.New("unable to reconnect to containerd, no connector available")
|
||||
}
|
||||
|
||||
if c.closed {
|
||||
return errors.New("client is closed")
|
||||
}
|
||||
|
||||
if c.client != nil {
|
||||
if err := c.client.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
client, err := c.connector()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.client = client
|
||||
return nil
|
||||
}
|
||||
|
||||
// EventsService creates an EventsService client
|
||||
func (c *Client) EventsService() (v1.EventsService, error) {
|
||||
client, err := c.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v1.NewEventsClient(client), nil
|
||||
}
|
||||
|
||||
// Client returns the underlying TTRPC client object
|
||||
func (c *Client) Client() (*ttrpc.Client, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.client == nil {
|
||||
client, err := c.connector()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.client = client
|
||||
}
|
||||
return c.client, nil
|
||||
}
|
||||
|
||||
// Close closes the clients TTRPC connection to containerd
|
||||
func (c *Client) Close() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.closed = true
|
||||
if c.client != nil {
|
||||
return c.client.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
169
vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go
generated
vendored
169
vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go
generated
vendored
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
v1 "github.com/containerd/containerd/api/services/ttrpc/events/v1"
|
||||
"github.com/containerd/containerd/events"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/pkg/ttrpcutil"
|
||||
"github.com/containerd/containerd/protobuf"
|
||||
"github.com/containerd/ttrpc"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
queueSize = 2048
|
||||
maxRequeue = 5
|
||||
)
|
||||
|
||||
type item struct {
|
||||
ev *v1.Envelope
|
||||
ctx context.Context
|
||||
count int
|
||||
}
|
||||
|
||||
// NewPublisher creates a new remote events publisher
|
||||
func NewPublisher(address string) (*RemoteEventsPublisher, error) {
|
||||
client, err := ttrpcutil.NewClient(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
l := &RemoteEventsPublisher{
|
||||
client: client,
|
||||
closed: make(chan struct{}),
|
||||
requeue: make(chan *item, queueSize),
|
||||
}
|
||||
|
||||
go l.processQueue()
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// RemoteEventsPublisher forwards events to a ttrpc server
|
||||
type RemoteEventsPublisher struct {
|
||||
client *ttrpcutil.Client
|
||||
closed chan struct{}
|
||||
closer sync.Once
|
||||
requeue chan *item
|
||||
}
|
||||
|
||||
// Done returns a channel which closes when done
|
||||
func (l *RemoteEventsPublisher) Done() <-chan struct{} {
|
||||
return l.closed
|
||||
}
|
||||
|
||||
// Close closes the remote connection and closes the done channel
|
||||
func (l *RemoteEventsPublisher) Close() (err error) {
|
||||
err = l.client.Close()
|
||||
l.closer.Do(func() {
|
||||
close(l.closed)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *RemoteEventsPublisher) processQueue() {
|
||||
for i := range l.requeue {
|
||||
if i.count > maxRequeue {
|
||||
logrus.Errorf("evicting %s from queue because of retry count", i.ev.Topic)
|
||||
// drop the event
|
||||
continue
|
||||
}
|
||||
|
||||
if err := l.forwardRequest(i.ctx, &v1.ForwardRequest{Envelope: i.ev}); err != nil {
|
||||
logrus.WithError(err).Error("forward event")
|
||||
l.queue(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *RemoteEventsPublisher) queue(i *item) {
|
||||
go func() {
|
||||
i.count++
|
||||
// re-queue after a short delay
|
||||
time.Sleep(time.Duration(1*i.count) * time.Second)
|
||||
l.requeue <- i
|
||||
}()
|
||||
}
|
||||
|
||||
// Publish publishes the event by forwarding it to the configured ttrpc server
|
||||
func (l *RemoteEventsPublisher) Publish(ctx context.Context, topic string, event events.Event) error {
|
||||
ns, err := namespaces.NamespaceRequired(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
any, err := protobuf.MarshalAnyToProto(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i := &item{
|
||||
ev: &v1.Envelope{
|
||||
Timestamp: protobuf.ToTimestamp(time.Now()),
|
||||
Namespace: ns,
|
||||
Topic: topic,
|
||||
Event: any,
|
||||
},
|
||||
ctx: ctx,
|
||||
}
|
||||
|
||||
if err := l.forwardRequest(i.ctx, &v1.ForwardRequest{Envelope: i.ev}); err != nil {
|
||||
l.queue(i)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.ForwardRequest) error {
|
||||
service, err := l.client.EventsService()
|
||||
if err == nil {
|
||||
fCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
_, err = service.Forward(fCtx, req)
|
||||
cancel()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if err != ttrpc.ErrClosed {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reconnect and retry request
|
||||
if err = l.client.Reconnect(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
service, err = l.client.EventsService()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// try again with a fresh context, otherwise we may get a context timeout unexpectedly.
|
||||
fCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
_, err = service.Forward(fCtx, req)
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
538
vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
generated
vendored
538
vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
generated
vendored
@@ -1,538 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
|
||||
shimapi "github.com/containerd/containerd/api/runtime/task/v2"
|
||||
"github.com/containerd/containerd/events"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/pkg/shutdown"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
"github.com/containerd/containerd/protobuf"
|
||||
"github.com/containerd/containerd/protobuf/proto"
|
||||
"github.com/containerd/containerd/version"
|
||||
"github.com/containerd/log"
|
||||
"github.com/containerd/ttrpc"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Publisher for events
|
||||
type Publisher interface {
|
||||
events.Publisher
|
||||
io.Closer
|
||||
}
|
||||
|
||||
// StartOpts describes shim start configuration received from containerd
|
||||
type StartOpts struct {
|
||||
ID string // TODO(2.0): Remove ID, passed directly to start for call symmetry
|
||||
ContainerdBinary string // TODO(2.0): Remove ContainerdBinary, use the TTRPC_ADDRESS env to forward events
|
||||
Address string
|
||||
TTRPCAddress string
|
||||
Debug bool
|
||||
}
|
||||
|
||||
// BootstrapParams is a JSON payload returned in stdout from shim.Start call.
|
||||
type BootstrapParams struct {
|
||||
// Version is the version of shim parameters (expected 2 for shim v2)
|
||||
Version int `json:"version"`
|
||||
// Address is a address containerd should use to connect to shim.
|
||||
Address string `json:"address"`
|
||||
// Protocol is either TTRPC or GRPC.
|
||||
Protocol string `json:"protocol"`
|
||||
}
|
||||
|
||||
type StopStatus struct {
|
||||
Pid int
|
||||
ExitStatus int
|
||||
ExitedAt time.Time
|
||||
}
|
||||
|
||||
// Init func for the creation of a shim server
|
||||
// TODO(2.0): Remove init function
|
||||
type Init func(context.Context, string, Publisher, func()) (Shim, error)
|
||||
|
||||
// Shim server interface
|
||||
// TODO(2.0): Remove unified shim interface
|
||||
type Shim interface {
|
||||
shimapi.TaskService
|
||||
Cleanup(ctx context.Context) (*shimapi.DeleteResponse, error)
|
||||
StartShim(ctx context.Context, opts StartOpts) (string, error)
|
||||
}
|
||||
|
||||
// Manager is the interface which manages the shim process
|
||||
type Manager interface {
|
||||
Name() string
|
||||
Start(ctx context.Context, id string, opts StartOpts) (string, error)
|
||||
Stop(ctx context.Context, id string) (StopStatus, error)
|
||||
}
|
||||
|
||||
// OptsKey is the context key for the Opts value.
|
||||
type OptsKey struct{}
|
||||
|
||||
// Opts are context options associated with the shim invocation.
|
||||
type Opts struct {
|
||||
BundlePath string
|
||||
Debug bool
|
||||
}
|
||||
|
||||
// BinaryOpts allows the configuration of a shims binary setup
|
||||
type BinaryOpts func(*Config)
|
||||
|
||||
// Config of shim binary options provided by shim implementations
|
||||
type Config struct {
|
||||
// NoSubreaper disables setting the shim as a child subreaper
|
||||
NoSubreaper bool
|
||||
// NoReaper disables the shim binary from reaping any child process implicitly
|
||||
NoReaper bool
|
||||
// NoSetupLogger disables automatic configuration of logrus to use the shim FIFO
|
||||
NoSetupLogger bool
|
||||
}
|
||||
|
||||
type ttrpcService interface {
|
||||
RegisterTTRPC(*ttrpc.Server) error
|
||||
}
|
||||
|
||||
type ttrpcServerOptioner interface {
|
||||
ttrpcService
|
||||
|
||||
UnaryInterceptor() ttrpc.UnaryServerInterceptor
|
||||
}
|
||||
|
||||
type taskService struct {
|
||||
shimapi.TaskService
|
||||
}
|
||||
|
||||
func (t taskService) RegisterTTRPC(server *ttrpc.Server) error {
|
||||
shimapi.RegisterTaskService(server, t.TaskService)
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
debugFlag bool
|
||||
versionFlag bool
|
||||
id string
|
||||
namespaceFlag string
|
||||
socketFlag string
|
||||
bundlePath string
|
||||
addressFlag string
|
||||
containerdBinaryFlag string
|
||||
action string
|
||||
)
|
||||
|
||||
const (
|
||||
ttrpcAddressEnv = "TTRPC_ADDRESS"
|
||||
grpcAddressEnv = "GRPC_ADDRESS"
|
||||
namespaceEnv = "NAMESPACE"
|
||||
maxVersionEnv = "MAX_SHIM_VERSION"
|
||||
)
|
||||
|
||||
func parseFlags() {
|
||||
flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs")
|
||||
flag.BoolVar(&versionFlag, "v", false, "show the shim version and exit")
|
||||
flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim")
|
||||
flag.StringVar(&id, "id", "", "id of the task")
|
||||
flag.StringVar(&socketFlag, "socket", "", "socket path to serve")
|
||||
flag.StringVar(&bundlePath, "bundle", "", "path to the bundle if not workdir")
|
||||
|
||||
flag.StringVar(&addressFlag, "address", "", "grpc address back to main containerd")
|
||||
flag.StringVar(&containerdBinaryFlag, "publish-binary", "",
|
||||
fmt.Sprintf("path to publish binary (used for publishing events), but %s will ignore this flag, please use the %s env", os.Args[0], ttrpcAddressEnv),
|
||||
)
|
||||
|
||||
flag.Parse()
|
||||
action = flag.Arg(0)
|
||||
}
|
||||
|
||||
func setRuntime() {
|
||||
debug.SetGCPercent(40)
|
||||
go func() {
|
||||
for range time.Tick(30 * time.Second) {
|
||||
debug.FreeOSMemory()
|
||||
}
|
||||
}()
|
||||
if os.Getenv("GOMAXPROCS") == "" {
|
||||
// If GOMAXPROCS hasn't been set, we default to a value of 2 to reduce
|
||||
// the number of Go stacks present in the shim.
|
||||
runtime.GOMAXPROCS(2)
|
||||
}
|
||||
}
|
||||
|
||||
func setLogger(ctx context.Context, id string) (context.Context, error) {
|
||||
l := log.G(ctx)
|
||||
l.Logger.SetFormatter(&logrus.TextFormatter{
|
||||
TimestampFormat: log.RFC3339NanoFixed,
|
||||
FullTimestamp: true,
|
||||
})
|
||||
if debugFlag {
|
||||
l.Logger.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
f, err := openLog(ctx, id)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
l.Logger.SetOutput(f)
|
||||
return log.WithLogger(ctx, l), nil
|
||||
}
|
||||
|
||||
// Run initializes and runs a shim server
|
||||
// TODO(2.0): Remove function
|
||||
func Run(name string, initFunc Init, opts ...BinaryOpts) {
|
||||
var config Config
|
||||
for _, o := range opts {
|
||||
o(&config)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithField("runtime", name))
|
||||
|
||||
if err := run(ctx, nil, initFunc, name, config); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s: %s", name, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(2.0): Remove this type
|
||||
type shimToManager struct {
|
||||
shim Shim
|
||||
name string
|
||||
}
|
||||
|
||||
func (stm shimToManager) Name() string {
|
||||
return stm.name
|
||||
}
|
||||
|
||||
func (stm shimToManager) Start(ctx context.Context, id string, opts StartOpts) (string, error) {
|
||||
opts.ID = id
|
||||
return stm.shim.StartShim(ctx, opts)
|
||||
}
|
||||
|
||||
func (stm shimToManager) Stop(ctx context.Context, id string) (StopStatus, error) {
|
||||
// shim must already have id
|
||||
dr, err := stm.shim.Cleanup(ctx)
|
||||
if err != nil {
|
||||
return StopStatus{}, err
|
||||
}
|
||||
return StopStatus{
|
||||
Pid: int(dr.Pid),
|
||||
ExitStatus: int(dr.ExitStatus),
|
||||
ExitedAt: protobuf.FromTimestamp(dr.ExitedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RunManager initializes and runs a shim server.
|
||||
// TODO(2.0): Rename to Run
|
||||
func RunManager(ctx context.Context, manager Manager, opts ...BinaryOpts) {
|
||||
var config Config
|
||||
for _, o := range opts {
|
||||
o(&config)
|
||||
}
|
||||
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithField("runtime", manager.Name()))
|
||||
|
||||
if err := run(ctx, manager, nil, "", config); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s: %s", manager.Name(), err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run(ctx context.Context, manager Manager, initFunc Init, name string, config Config) error {
|
||||
parseFlags()
|
||||
if versionFlag {
|
||||
fmt.Printf("%s:\n", filepath.Base(os.Args[0]))
|
||||
fmt.Println(" Version: ", version.Version)
|
||||
fmt.Println(" Revision:", version.Revision)
|
||||
fmt.Println(" Go version:", version.GoVersion)
|
||||
fmt.Println("")
|
||||
return nil
|
||||
}
|
||||
|
||||
if namespaceFlag == "" {
|
||||
return fmt.Errorf("shim namespace cannot be empty")
|
||||
}
|
||||
|
||||
setRuntime()
|
||||
|
||||
signals, err := setupSignals(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !config.NoSubreaper {
|
||||
if err := subreaper(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ttrpcAddress := os.Getenv(ttrpcAddressEnv)
|
||||
publisher, err := NewPublisher(ttrpcAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer publisher.Close()
|
||||
|
||||
ctx = namespaces.WithNamespace(ctx, namespaceFlag)
|
||||
ctx = context.WithValue(ctx, OptsKey{}, Opts{BundlePath: bundlePath, Debug: debugFlag})
|
||||
ctx, sd := shutdown.WithShutdown(ctx)
|
||||
defer sd.Shutdown()
|
||||
|
||||
if manager == nil {
|
||||
service, err := initFunc(ctx, id, publisher, sd.Shutdown)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plugin.Register(&plugin.Registration{
|
||||
Type: plugin.TTRPCPlugin,
|
||||
ID: "task",
|
||||
Requires: []plugin.Type{
|
||||
plugin.EventPlugin,
|
||||
},
|
||||
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
|
||||
return taskService{service}, nil
|
||||
},
|
||||
})
|
||||
manager = shimToManager{
|
||||
shim: service,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// Handle explicit actions
|
||||
switch action {
|
||||
case "delete":
|
||||
if debugFlag {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
logger := log.G(ctx).WithFields(log.Fields{
|
||||
"pid": os.Getpid(),
|
||||
"namespace": namespaceFlag,
|
||||
})
|
||||
go reap(ctx, logger, signals)
|
||||
ss, err := manager.Stop(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := proto.Marshal(&shimapi.DeleteResponse{
|
||||
Pid: uint32(ss.Pid),
|
||||
ExitStatus: uint32(ss.ExitStatus),
|
||||
ExitedAt: protobuf.ToTimestamp(ss.ExitedAt),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stdout.Write(data); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
case "start":
|
||||
opts := StartOpts{
|
||||
Address: addressFlag,
|
||||
TTRPCAddress: ttrpcAddress,
|
||||
Debug: debugFlag,
|
||||
}
|
||||
|
||||
address, err := manager.Start(ctx, id, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stdout.WriteString(address); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if !config.NoSetupLogger {
|
||||
ctx, err = setLogger(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
plugin.Register(&plugin.Registration{
|
||||
Type: plugin.InternalPlugin,
|
||||
ID: "shutdown",
|
||||
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
|
||||
return sd, nil
|
||||
},
|
||||
})
|
||||
|
||||
// Register event plugin
|
||||
plugin.Register(&plugin.Registration{
|
||||
Type: plugin.EventPlugin,
|
||||
ID: "publisher",
|
||||
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
|
||||
return publisher, nil
|
||||
},
|
||||
})
|
||||
|
||||
var (
|
||||
initialized = plugin.NewPluginSet()
|
||||
ttrpcServices = []ttrpcService{}
|
||||
|
||||
ttrpcUnaryInterceptors = []ttrpc.UnaryServerInterceptor{}
|
||||
)
|
||||
plugins := plugin.Graph(func(*plugin.Registration) bool { return false })
|
||||
for _, p := range plugins {
|
||||
id := p.URI()
|
||||
log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id)
|
||||
|
||||
initContext := plugin.NewContext(
|
||||
ctx,
|
||||
p,
|
||||
initialized,
|
||||
// NOTE: Root is empty since the shim does not support persistent storage,
|
||||
// shim plugins should make use state directory for writing files to disk.
|
||||
// The state directory will be destroyed when the shim if cleaned up or
|
||||
// on reboot
|
||||
"",
|
||||
bundlePath,
|
||||
)
|
||||
initContext.Address = addressFlag
|
||||
initContext.TTRPCAddress = ttrpcAddress
|
||||
|
||||
// load the plugin specific configuration if it is provided
|
||||
// TODO: Read configuration passed into shim, or from state directory?
|
||||
// if p.Config != nil {
|
||||
// pc, err := config.Decode(p)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// initContext.Config = pc
|
||||
// }
|
||||
|
||||
result := p.Init(initContext)
|
||||
if err := initialized.Add(result); err != nil {
|
||||
return fmt.Errorf("could not add plugin result to plugin set: %w", err)
|
||||
}
|
||||
|
||||
instance, err := result.Instance()
|
||||
if err != nil {
|
||||
if plugin.IsSkipPlugin(err) {
|
||||
log.G(ctx).WithError(err).WithField("type", p.Type).Infof("skip loading plugin %q...", id)
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("failed to load plugin %s: %w", id, err)
|
||||
}
|
||||
|
||||
if src, ok := instance.(ttrpcService); ok {
|
||||
logrus.WithField("id", id).Debug("registering ttrpc service")
|
||||
ttrpcServices = append(ttrpcServices, src)
|
||||
|
||||
}
|
||||
|
||||
if src, ok := instance.(ttrpcServerOptioner); ok {
|
||||
ttrpcUnaryInterceptors = append(ttrpcUnaryInterceptors, src.UnaryInterceptor())
|
||||
}
|
||||
}
|
||||
|
||||
if len(ttrpcServices) == 0 {
|
||||
return fmt.Errorf("required that ttrpc service")
|
||||
}
|
||||
|
||||
unaryInterceptor := chainUnaryServerInterceptors(ttrpcUnaryInterceptors...)
|
||||
server, err := newServer(ttrpc.WithUnaryServerInterceptor(unaryInterceptor))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed creating server: %w", err)
|
||||
}
|
||||
|
||||
for _, srv := range ttrpcServices {
|
||||
if err := srv.RegisterTTRPC(server); err != nil {
|
||||
return fmt.Errorf("failed to register service: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := serve(ctx, server, signals, sd.Shutdown); err != nil {
|
||||
if err != shutdown.ErrShutdown {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: If the shim server is down(like oom killer), the address
|
||||
// socket might be leaking.
|
||||
if address, err := ReadAddress("address"); err == nil {
|
||||
_ = RemoveSocket(address)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-publisher.Done():
|
||||
return nil
|
||||
case <-time.After(5 * time.Second):
|
||||
return errors.New("publisher not closed")
|
||||
}
|
||||
}
|
||||
|
||||
// serve serves the ttrpc API over a unix socket in the current working directory
|
||||
// and blocks until the context is canceled
|
||||
func serve(ctx context.Context, server *ttrpc.Server, signals chan os.Signal, shutdown func()) error {
|
||||
dump := make(chan os.Signal, 32)
|
||||
setupDumpStacks(dump)
|
||||
|
||||
path, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l, err := serveListener(socketFlag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
defer l.Close()
|
||||
if err := server.Serve(ctx, l); err != nil && !errors.Is(err, net.ErrClosed) {
|
||||
log.G(ctx).WithError(err).Fatal("containerd-shim: ttrpc server failure")
|
||||
}
|
||||
}()
|
||||
logger := log.G(ctx).WithFields(log.Fields{
|
||||
"pid": os.Getpid(),
|
||||
"path": path,
|
||||
"namespace": namespaceFlag,
|
||||
})
|
||||
go func() {
|
||||
for range dump {
|
||||
dumpStacks(logger)
|
||||
}
|
||||
}()
|
||||
|
||||
go handleExitSignals(ctx, logger, shutdown)
|
||||
return reap(ctx, logger, signals)
|
||||
}
|
||||
|
||||
func dumpStacks(logger *logrus.Entry) {
|
||||
var (
|
||||
buf []byte
|
||||
stackSize int
|
||||
)
|
||||
bufferLen := 16384
|
||||
for stackSize == len(buf) {
|
||||
buf = make([]byte, bufferLen)
|
||||
stackSize = runtime.Stack(buf, true)
|
||||
bufferLen *= 2
|
||||
}
|
||||
buf = buf[:stackSize]
|
||||
logger.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
||||
}
|
||||
27
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_darwin.go
generated
vendored
27
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_darwin.go
generated
vendored
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import "github.com/containerd/ttrpc"
|
||||
|
||||
func newServer(opts ...ttrpc.ServerOpt) (*ttrpc.Server, error) {
|
||||
return ttrpc.NewServer(opts...)
|
||||
}
|
||||
|
||||
func subreaper() error {
|
||||
return nil
|
||||
}
|
||||
27
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_freebsd.go
generated
vendored
27
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_freebsd.go
generated
vendored
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import "github.com/containerd/ttrpc"
|
||||
|
||||
func newServer(opts ...ttrpc.ServerOpt) (*ttrpc.Server, error) {
|
||||
return ttrpc.NewServer(opts...)
|
||||
}
|
||||
|
||||
func subreaper() error {
|
||||
return nil
|
||||
}
|
||||
31
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_linux.go
generated
vendored
31
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_linux.go
generated
vendored
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import (
|
||||
"github.com/containerd/containerd/sys/reaper"
|
||||
"github.com/containerd/ttrpc"
|
||||
)
|
||||
|
||||
func newServer(opts ...ttrpc.ServerOpt) (*ttrpc.Server, error) {
|
||||
opts = append(opts, ttrpc.WithServerHandshaker(ttrpc.UnixSocketRequireSameUser()))
|
||||
return ttrpc.NewServer(opts...)
|
||||
}
|
||||
|
||||
func subreaper() error {
|
||||
return reaper.SetSubreaper(1)
|
||||
}
|
||||
112
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_unix.go
generated
vendored
112
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_unix.go
generated
vendored
@@ -1,112 +0,0 @@
|
||||
//go:build !windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/containerd/sys/reaper"
|
||||
"github.com/containerd/fifo"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// setupSignals creates a new signal handler for all signals and sets the shim as a
|
||||
// sub-reaper so that the container processes are reparented
|
||||
func setupSignals(config Config) (chan os.Signal, error) {
|
||||
signals := make(chan os.Signal, 32)
|
||||
smp := []os.Signal{unix.SIGTERM, unix.SIGINT, unix.SIGPIPE}
|
||||
if !config.NoReaper {
|
||||
smp = append(smp, unix.SIGCHLD)
|
||||
}
|
||||
signal.Notify(signals, smp...)
|
||||
return signals, nil
|
||||
}
|
||||
|
||||
func setupDumpStacks(dump chan<- os.Signal) {
|
||||
signal.Notify(dump, syscall.SIGUSR1)
|
||||
}
|
||||
|
||||
func serveListener(path string) (net.Listener, error) {
|
||||
var (
|
||||
l net.Listener
|
||||
err error
|
||||
)
|
||||
if path == "" {
|
||||
l, err = net.FileListener(os.NewFile(3, "socket"))
|
||||
path = "[inherited from parent]"
|
||||
} else {
|
||||
if len(path) > socketPathLimit {
|
||||
return nil, fmt.Errorf("%q: unix socket path too long (> %d)", path, socketPathLimit)
|
||||
}
|
||||
l, err = net.Listen("unix", path)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logrus.WithField("socket", path).Debug("serving api on socket")
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func reap(ctx context.Context, logger *logrus.Entry, signals chan os.Signal) error {
|
||||
logger.Debug("starting signal loop")
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case s := <-signals:
|
||||
// Exit signals are handled separately from this loop
|
||||
// They get registered with this channel so that we can ignore such signals for short-running actions (e.g. `delete`)
|
||||
switch s {
|
||||
case unix.SIGCHLD:
|
||||
if err := reaper.Reap(); err != nil {
|
||||
logger.WithError(err).Error("reap exit status")
|
||||
}
|
||||
case unix.SIGPIPE:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleExitSignals(ctx context.Context, logger *logrus.Entry, cancel context.CancelFunc) {
|
||||
ch := make(chan os.Signal, 32)
|
||||
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
for {
|
||||
select {
|
||||
case s := <-ch:
|
||||
logger.WithField("signal", s).Debugf("Caught exit signal")
|
||||
cancel()
|
||||
return
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func openLog(ctx context.Context, _ string) (io.Writer, error) {
|
||||
return fifo.OpenFifoDup2(ctx, "log", unix.O_WRONLY, 0700, int(os.Stderr.Fd()))
|
||||
}
|
||||
58
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_windows.go
generated
vendored
58
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_windows.go
generated
vendored
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/containerd/errdefs"
|
||||
"github.com/containerd/ttrpc"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func setupSignals(config Config) (chan os.Signal, error) {
|
||||
return nil, errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func newServer(opts ...ttrpc.ServerOpt) (*ttrpc.Server, error) {
|
||||
return nil, errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func subreaper() error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func setupDumpStacks(dump chan<- os.Signal) {
|
||||
}
|
||||
|
||||
func serveListener(path string) (net.Listener, error) {
|
||||
return nil, errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func reap(ctx context.Context, logger *logrus.Entry, signals chan os.Signal) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func handleExitSignals(ctx context.Context, logger *logrus.Entry, cancel context.CancelFunc) {
|
||||
}
|
||||
|
||||
func openLog(ctx context.Context, _ string) (io.Writer, error) {
|
||||
return nil, errdefs.ErrNotImplemented
|
||||
}
|
||||
236
vendor/github.com/containerd/containerd/runtime/v2/shim/util.go
generated
vendored
236
vendor/github.com/containerd/containerd/runtime/v2/shim/util.go
generated
vendored
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/ttrpc"
|
||||
"github.com/containerd/typeurl/v2"
|
||||
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/pkg/atomicfile"
|
||||
"github.com/containerd/containerd/protobuf/proto"
|
||||
"github.com/containerd/containerd/protobuf/types"
|
||||
"github.com/containerd/errdefs"
|
||||
)
|
||||
|
||||
type CommandConfig struct {
|
||||
Runtime string
|
||||
Address string
|
||||
TTRPCAddress string
|
||||
Path string
|
||||
SchedCore bool
|
||||
Args []string
|
||||
Opts *types.Any
|
||||
}
|
||||
|
||||
// Command returns the shim command with the provided args and configuration
|
||||
func Command(ctx context.Context, config *CommandConfig) (*exec.Cmd, error) {
|
||||
ns, err := namespaces.NamespaceRequired(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
self, err := os.Executable()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args := []string{
|
||||
"-namespace", ns,
|
||||
"-address", config.Address,
|
||||
"-publish-binary", self,
|
||||
}
|
||||
args = append(args, config.Args...)
|
||||
cmd := exec.CommandContext(ctx, config.Runtime, args...)
|
||||
cmd.Dir = config.Path
|
||||
cmd.Env = append(
|
||||
os.Environ(),
|
||||
"GOMAXPROCS=2",
|
||||
fmt.Sprintf("%s=2", maxVersionEnv),
|
||||
fmt.Sprintf("%s=%s", ttrpcAddressEnv, config.TTRPCAddress),
|
||||
fmt.Sprintf("%s=%s", grpcAddressEnv, config.Address),
|
||||
fmt.Sprintf("%s=%s", namespaceEnv, ns),
|
||||
)
|
||||
if config.SchedCore {
|
||||
cmd.Env = append(cmd.Env, "SCHED_CORE=1")
|
||||
}
|
||||
cmd.SysProcAttr = getSysProcAttr()
|
||||
if config.Opts != nil {
|
||||
d, err := proto.Marshal(config.Opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.Stdin = bytes.NewReader(d)
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// BinaryName returns the shim binary name from the runtime name,
|
||||
// empty string returns means runtime name is invalid
|
||||
func BinaryName(runtime string) string {
|
||||
// runtime name should format like $prefix.name.version
|
||||
parts := strings.Split(runtime, ".")
|
||||
if len(parts) < 2 || parts[0] == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf(shimBinaryFormat, parts[len(parts)-2], parts[len(parts)-1])
|
||||
}
|
||||
|
||||
// BinaryPath returns the full path for the shim binary from the runtime name,
|
||||
// empty string returns means runtime name is invalid
|
||||
func BinaryPath(runtime string) string {
|
||||
dir := filepath.Dir(runtime)
|
||||
binary := BinaryName(runtime)
|
||||
|
||||
path, err := filepath.Abs(filepath.Join(dir, binary))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
// Connect to the provided address
|
||||
func Connect(address string, d func(string, time.Duration) (net.Conn, error)) (net.Conn, error) {
|
||||
return d(address, 100*time.Second)
|
||||
}
|
||||
|
||||
// WritePidFile writes a pid file atomically
|
||||
func WritePidFile(path string, pid int) error {
|
||||
path, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := atomicfile.New(path, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintf(f, "%d", pid)
|
||||
if err != nil {
|
||||
f.Cancel()
|
||||
return err
|
||||
}
|
||||
return f.Close()
|
||||
}
|
||||
|
||||
// WriteAddress writes a address file atomically
|
||||
func WriteAddress(path, address string) error {
|
||||
path, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := atomicfile.New(path, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write([]byte(address))
|
||||
if err != nil {
|
||||
f.Cancel()
|
||||
return err
|
||||
}
|
||||
return f.Close()
|
||||
}
|
||||
|
||||
// ErrNoAddress is returned when the address file has no content
|
||||
var ErrNoAddress = errors.New("no shim address")
|
||||
|
||||
// ReadAddress returns the shim's socket address from the path
|
||||
func ReadAddress(path string) (string, error) {
|
||||
path, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return "", ErrNoAddress
|
||||
}
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
// ReadRuntimeOptions reads config bytes from io.Reader and unmarshals it into the provided type.
|
||||
// The type must be registered with typeurl.
|
||||
//
|
||||
// The function will return ErrNotFound, if the config is not provided.
|
||||
// And ErrInvalidArgument, if unable to cast the config to the provided type T.
|
||||
func ReadRuntimeOptions[T any](reader io.Reader) (T, error) {
|
||||
var config T
|
||||
|
||||
data, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return config, fmt.Errorf("failed to read config bytes from stdin: %w", err)
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
return config, errdefs.ErrNotFound
|
||||
}
|
||||
|
||||
var any types.Any
|
||||
if err := proto.Unmarshal(data, &any); err != nil {
|
||||
return config, err
|
||||
}
|
||||
|
||||
v, err := typeurl.UnmarshalAny(&any)
|
||||
if err != nil {
|
||||
return config, err
|
||||
}
|
||||
|
||||
config, ok := v.(T)
|
||||
if !ok {
|
||||
return config, fmt.Errorf("invalid type %T: %w", v, errdefs.ErrInvalidArgument)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// chainUnaryServerInterceptors creates a single ttrpc server interceptor from
|
||||
// a chain of many interceptors executed from first to last.
|
||||
func chainUnaryServerInterceptors(interceptors ...ttrpc.UnaryServerInterceptor) ttrpc.UnaryServerInterceptor {
|
||||
n := len(interceptors)
|
||||
|
||||
// force to use default interceptor in ttrpc
|
||||
if n == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return func(ctx context.Context, unmarshal ttrpc.Unmarshaler, info *ttrpc.UnaryServerInfo, method ttrpc.Method) (interface{}, error) {
|
||||
currentMethod := method
|
||||
|
||||
for i := n - 1; i > 0; i-- {
|
||||
interceptor := interceptors[i]
|
||||
innerMethod := currentMethod
|
||||
|
||||
currentMethod = func(currentCtx context.Context, currentUnmarshal func(interface{}) error) (interface{}, error) {
|
||||
return interceptor(currentCtx, currentUnmarshal, info, innerMethod)
|
||||
}
|
||||
}
|
||||
return interceptors[0](ctx, unmarshal, info, currentMethod)
|
||||
}
|
||||
}
|
||||
179
vendor/github.com/containerd/containerd/runtime/v2/shim/util_unix.go
generated
vendored
179
vendor/github.com/containerd/containerd/runtime/v2/shim/util_unix.go
generated
vendored
@@ -1,179 +0,0 @@
|
||||
//go:build !windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/defaults"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/sys"
|
||||
)
|
||||
|
||||
const (
|
||||
shimBinaryFormat = "containerd-shim-%s-%s"
|
||||
socketPathLimit = 106
|
||||
)
|
||||
|
||||
func getSysProcAttr() *syscall.SysProcAttr {
|
||||
return &syscall.SysProcAttr{
|
||||
Setpgid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// AdjustOOMScore sets the OOM score for the process to the parents OOM score +1
|
||||
// to ensure that they parent has a lower* score than the shim
|
||||
// if not already at the maximum OOM Score
|
||||
func AdjustOOMScore(pid int) error {
|
||||
parent := os.Getppid()
|
||||
score, err := sys.GetOOMScoreAdj(parent)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get parent OOM score: %w", err)
|
||||
}
|
||||
shimScore := score + 1
|
||||
if err := sys.AdjustOOMScore(pid, shimScore); err != nil {
|
||||
return fmt.Errorf("set shim OOM score: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const socketRoot = defaults.DefaultStateDir
|
||||
|
||||
// SocketAddress returns a socket address
|
||||
func SocketAddress(ctx context.Context, socketPath, id string) (string, error) {
|
||||
ns, err := namespaces.NamespaceRequired(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
d := sha256.Sum256([]byte(filepath.Join(socketPath, ns, id)))
|
||||
return fmt.Sprintf("unix://%s/%x", filepath.Join(socketRoot, "s"), d), nil
|
||||
}
|
||||
|
||||
// AnonDialer returns a dialer for a socket
|
||||
func AnonDialer(address string, timeout time.Duration) (net.Conn, error) {
|
||||
return net.DialTimeout("unix", socket(address).path(), timeout)
|
||||
}
|
||||
|
||||
// AnonReconnectDialer returns a dialer for an existing socket on reconnection
|
||||
func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error) {
|
||||
return AnonDialer(address, timeout)
|
||||
}
|
||||
|
||||
// NewSocket returns a new socket
|
||||
func NewSocket(address string) (*net.UnixListener, error) {
|
||||
var (
|
||||
sock = socket(address)
|
||||
path = sock.path()
|
||||
isAbstract = sock.isAbstract()
|
||||
perm = os.FileMode(0600)
|
||||
)
|
||||
|
||||
// Darwin needs +x to access socket, otherwise it'll fail with "bind: permission denied" when running as non-root.
|
||||
if runtime.GOOS == "darwin" {
|
||||
perm = 0700
|
||||
}
|
||||
|
||||
if !isAbstract {
|
||||
if err := os.MkdirAll(filepath.Dir(path), perm); err != nil {
|
||||
return nil, fmt.Errorf("mkdir failed for %s: %w", path, err)
|
||||
}
|
||||
}
|
||||
l, err := net.Listen("unix", path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !isAbstract {
|
||||
if err := os.Chmod(path, perm); err != nil {
|
||||
os.Remove(sock.path())
|
||||
l.Close()
|
||||
return nil, fmt.Errorf("chmod failed for %s: %w", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
return l.(*net.UnixListener), nil
|
||||
}
|
||||
|
||||
const abstractSocketPrefix = "\x00"
|
||||
|
||||
type socket string
|
||||
|
||||
func (s socket) isAbstract() bool {
|
||||
return !strings.HasPrefix(string(s), "unix://")
|
||||
}
|
||||
|
||||
func (s socket) path() string {
|
||||
path := strings.TrimPrefix(string(s), "unix://")
|
||||
// if there was no trim performed, we assume an abstract socket
|
||||
if len(path) == len(s) {
|
||||
path = abstractSocketPrefix + path
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// RemoveSocket removes the socket at the specified address if
|
||||
// it exists on the filesystem
|
||||
func RemoveSocket(address string) error {
|
||||
sock := socket(address)
|
||||
if !sock.isAbstract() {
|
||||
return os.Remove(sock.path())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SocketEaddrinuse returns true if the provided error is caused by the
|
||||
// EADDRINUSE error number
|
||||
func SocketEaddrinuse(err error) bool {
|
||||
netErr, ok := err.(*net.OpError)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if netErr.Op != "listen" {
|
||||
return false
|
||||
}
|
||||
syscallErr, ok := netErr.Err.(*os.SyscallError)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
errno, ok := syscallErr.Err.(syscall.Errno)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return errno == syscall.EADDRINUSE
|
||||
}
|
||||
|
||||
// CanConnect returns true if the socket provided at the address
|
||||
// is accepting new connections
|
||||
func CanConnect(address string) bool {
|
||||
conn, err := AnonDialer(address, 100*time.Millisecond)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
conn.Close()
|
||||
return true
|
||||
}
|
||||
87
vendor/github.com/containerd/containerd/runtime/v2/shim/util_windows.go
generated
vendored
87
vendor/github.com/containerd/containerd/runtime/v2/shim/util_windows.go
generated
vendored
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 shim
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
winio "github.com/Microsoft/go-winio"
|
||||
)
|
||||
|
||||
const shimBinaryFormat = "containerd-shim-%s-%s.exe"
|
||||
|
||||
func getSysProcAttr() *syscall.SysProcAttr {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AnonReconnectDialer returns a dialer for an existing npipe on containerd reconnection
|
||||
func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
c, err := winio.DialPipeContext(ctx, address)
|
||||
if os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("npipe not found on reconnect: %w", os.ErrNotExist)
|
||||
} else if err == context.DeadlineExceeded {
|
||||
return nil, fmt.Errorf("timed out waiting for npipe %s: %w", address, err)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// AnonDialer returns a dialer for a npipe
|
||||
func AnonDialer(address string, timeout time.Duration) (net.Conn, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
// If there is nobody serving the pipe we limit the timeout for this case to
|
||||
// 5 seconds because any shim that would serve this endpoint should serve it
|
||||
// within 5 seconds.
|
||||
serveTimer := time.NewTimer(5 * time.Second)
|
||||
defer serveTimer.Stop()
|
||||
for {
|
||||
c, err := winio.DialPipeContext(ctx, address)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
select {
|
||||
case <-serveTimer.C:
|
||||
return nil, fmt.Errorf("pipe not found before timeout: %w", os.ErrNotExist)
|
||||
default:
|
||||
// Wait 10ms for the shim to serve and try again.
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
} else if err == context.DeadlineExceeded {
|
||||
return nil, fmt.Errorf("timed out waiting for npipe %s: %w", address, err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveSocket removes the socket at the specified address if
|
||||
// it exists on the filesystem
|
||||
func RemoveSocket(address string) error {
|
||||
return nil
|
||||
}
|
||||
282
vendor/github.com/containerd/containerd/sys/reaper/reaper_unix.go
generated
vendored
282
vendor/github.com/containerd/containerd/sys/reaper/reaper_unix.go
generated
vendored
@@ -1,282 +0,0 @@
|
||||
//go:build !windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 reaper
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
runc "github.com/containerd/go-runc"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// ErrNoSuchProcess is returned when the process no longer exists
|
||||
var ErrNoSuchProcess = errors.New("no such process")
|
||||
|
||||
const bufferSize = 32
|
||||
|
||||
type subscriber struct {
|
||||
sync.Mutex
|
||||
c chan runc.Exit
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (s *subscriber) close() {
|
||||
s.Lock()
|
||||
if s.closed {
|
||||
s.Unlock()
|
||||
return
|
||||
}
|
||||
close(s.c)
|
||||
s.closed = true
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *subscriber) do(fn func()) {
|
||||
s.Lock()
|
||||
fn()
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
// Reap should be called when the process receives an SIGCHLD. Reap will reap
|
||||
// all exited processes and close their wait channels
|
||||
func Reap() error {
|
||||
now := time.Now()
|
||||
exits, err := reap(false)
|
||||
for _, e := range exits {
|
||||
done := Default.notify(runc.Exit{
|
||||
Timestamp: now,
|
||||
Pid: e.Pid,
|
||||
Status: e.Status,
|
||||
})
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(1 * time.Second):
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Default is the default monitor initialized for the package
|
||||
var Default = &Monitor{
|
||||
subscribers: make(map[chan runc.Exit]*subscriber),
|
||||
}
|
||||
|
||||
// Monitor monitors the underlying system for process status changes
|
||||
type Monitor struct {
|
||||
sync.Mutex
|
||||
|
||||
subscribers map[chan runc.Exit]*subscriber
|
||||
}
|
||||
|
||||
// Start starts the command and registers the process with the reaper
|
||||
func (m *Monitor) Start(c *exec.Cmd) (chan runc.Exit, error) {
|
||||
ec := m.Subscribe()
|
||||
if err := c.Start(); err != nil {
|
||||
m.Unsubscribe(ec)
|
||||
return nil, err
|
||||
}
|
||||
return ec, nil
|
||||
}
|
||||
|
||||
// Wait blocks until a process is signal as dead.
|
||||
// User should rely on the value of the exit status to determine if the
|
||||
// command was successful or not.
|
||||
func (m *Monitor) Wait(c *exec.Cmd, ec chan runc.Exit) (int, error) {
|
||||
for e := range ec {
|
||||
if e.Pid == c.Process.Pid {
|
||||
// make sure we flush all IO
|
||||
c.Wait()
|
||||
m.Unsubscribe(ec)
|
||||
return e.Status, nil
|
||||
}
|
||||
}
|
||||
// return no such process if the ec channel is closed and no more exit
|
||||
// events will be sent
|
||||
return -1, ErrNoSuchProcess
|
||||
}
|
||||
|
||||
// WaitTimeout is used to skip the blocked command and kill the left process.
|
||||
func (m *Monitor) WaitTimeout(c *exec.Cmd, ec chan runc.Exit, timeout time.Duration) (int, error) {
|
||||
type exitStatusWrapper struct {
|
||||
status int
|
||||
err error
|
||||
}
|
||||
|
||||
// capacity can make sure that the following goroutine will not be
|
||||
// blocked if there is no receiver when timeout.
|
||||
waitCh := make(chan *exitStatusWrapper, 1)
|
||||
go func() {
|
||||
defer close(waitCh)
|
||||
|
||||
status, err := m.Wait(c, ec)
|
||||
waitCh <- &exitStatusWrapper{
|
||||
status: status,
|
||||
err: err,
|
||||
}
|
||||
}()
|
||||
|
||||
timer := time.NewTimer(timeout)
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-timer.C:
|
||||
syscall.Kill(c.Process.Pid, syscall.SIGKILL)
|
||||
return 0, fmt.Errorf("timeout %v for cmd(pid=%d): %s, %s", timeout, c.Process.Pid, c.Path, c.Args)
|
||||
case res := <-waitCh:
|
||||
return res.status, res.err
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to process exit changes
|
||||
func (m *Monitor) Subscribe() chan runc.Exit {
|
||||
c := make(chan runc.Exit, bufferSize)
|
||||
m.Lock()
|
||||
m.subscribers[c] = &subscriber{
|
||||
c: c,
|
||||
}
|
||||
m.Unlock()
|
||||
return c
|
||||
}
|
||||
|
||||
// Unsubscribe to process exit changes
|
||||
func (m *Monitor) Unsubscribe(c chan runc.Exit) {
|
||||
m.Lock()
|
||||
s, ok := m.subscribers[c]
|
||||
if !ok {
|
||||
m.Unlock()
|
||||
return
|
||||
}
|
||||
s.close()
|
||||
delete(m.subscribers, c)
|
||||
m.Unlock()
|
||||
}
|
||||
|
||||
func (m *Monitor) getSubscribers() map[chan runc.Exit]*subscriber {
|
||||
out := make(map[chan runc.Exit]*subscriber)
|
||||
m.Lock()
|
||||
for k, v := range m.subscribers {
|
||||
out[k] = v
|
||||
}
|
||||
m.Unlock()
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *Monitor) notify(e runc.Exit) chan struct{} {
|
||||
const timeout = 1 * time.Millisecond
|
||||
var (
|
||||
done = make(chan struct{}, 1)
|
||||
timer = time.NewTimer(timeout)
|
||||
success = make(map[chan runc.Exit]struct{})
|
||||
)
|
||||
stop(timer, true)
|
||||
|
||||
go func() {
|
||||
defer close(done)
|
||||
|
||||
for {
|
||||
var (
|
||||
failed int
|
||||
subscribers = m.getSubscribers()
|
||||
)
|
||||
for _, s := range subscribers {
|
||||
s.do(func() {
|
||||
if s.closed {
|
||||
return
|
||||
}
|
||||
if _, ok := success[s.c]; ok {
|
||||
return
|
||||
}
|
||||
timer.Reset(timeout)
|
||||
recv := true
|
||||
select {
|
||||
case s.c <- e:
|
||||
success[s.c] = struct{}{}
|
||||
case <-timer.C:
|
||||
recv = false
|
||||
failed++
|
||||
}
|
||||
stop(timer, recv)
|
||||
})
|
||||
}
|
||||
// all subscribers received the message
|
||||
if failed == 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
return done
|
||||
}
|
||||
|
||||
func stop(timer *time.Timer, recv bool) {
|
||||
if !timer.Stop() && recv {
|
||||
<-timer.C
|
||||
}
|
||||
}
|
||||
|
||||
// exit is the wait4 information from an exited process
|
||||
type exit struct {
|
||||
Pid int
|
||||
Status int
|
||||
}
|
||||
|
||||
// reap reaps all child processes for the calling process and returns their
|
||||
// exit information
|
||||
func reap(wait bool) (exits []exit, err error) {
|
||||
var (
|
||||
ws unix.WaitStatus
|
||||
rus unix.Rusage
|
||||
)
|
||||
flag := unix.WNOHANG
|
||||
if wait {
|
||||
flag = 0
|
||||
}
|
||||
for {
|
||||
pid, err := unix.Wait4(-1, &ws, flag, &rus)
|
||||
if err != nil {
|
||||
if err == unix.ECHILD {
|
||||
return exits, nil
|
||||
}
|
||||
return exits, err
|
||||
}
|
||||
if pid <= 0 {
|
||||
return exits, nil
|
||||
}
|
||||
exits = append(exits, exit{
|
||||
Pid: pid,
|
||||
Status: exitStatus(ws),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const exitSignalOffset = 128
|
||||
|
||||
// exitStatus returns the correct exit status for a process based on if it
|
||||
// was signaled or exited cleanly
|
||||
func exitStatus(status unix.WaitStatus) int {
|
||||
if status.Signaled() {
|
||||
return exitSignalOffset + int(status.Signal())
|
||||
}
|
||||
return status.ExitStatus()
|
||||
}
|
||||
39
vendor/github.com/containerd/containerd/sys/reaper/reaper_utils_linux.go
generated
vendored
39
vendor/github.com/containerd/containerd/sys/reaper/reaper_utils_linux.go
generated
vendored
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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 reaper
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// SetSubreaper sets the value i as the subreaper setting for the calling process
|
||||
func SetSubreaper(i int) error {
|
||||
return unix.Prctl(unix.PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0)
|
||||
}
|
||||
|
||||
// GetSubreaper returns the subreaper setting for the calling process
|
||||
func GetSubreaper() (int, error) {
|
||||
var i uintptr
|
||||
|
||||
if err := unix.Prctl(unix.PR_GET_CHILD_SUBREAPER, uintptr(unsafe.Pointer(&i)), 0, 0, 0); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return int(i), nil
|
||||
}
|
||||
7
vendor/modules.txt
vendored
7
vendor/modules.txt
vendored
@@ -293,7 +293,6 @@ github.com/containerd/containerd/mount
|
||||
github.com/containerd/containerd/namespaces
|
||||
github.com/containerd/containerd/oci
|
||||
github.com/containerd/containerd/pkg/apparmor
|
||||
github.com/containerd/containerd/pkg/atomicfile
|
||||
github.com/containerd/containerd/pkg/cap
|
||||
github.com/containerd/containerd/pkg/cleanup
|
||||
github.com/containerd/containerd/pkg/deprecation
|
||||
@@ -303,13 +302,11 @@ github.com/containerd/containerd/pkg/kmutex
|
||||
github.com/containerd/containerd/pkg/randutil
|
||||
github.com/containerd/containerd/pkg/runtimeoptions/v1
|
||||
github.com/containerd/containerd/pkg/seccomp
|
||||
github.com/containerd/containerd/pkg/shutdown
|
||||
github.com/containerd/containerd/pkg/snapshotters
|
||||
github.com/containerd/containerd/pkg/streaming
|
||||
github.com/containerd/containerd/pkg/transfer
|
||||
github.com/containerd/containerd/pkg/transfer/proxy
|
||||
github.com/containerd/containerd/pkg/transfer/streaming
|
||||
github.com/containerd/containerd/pkg/ttrpcutil
|
||||
github.com/containerd/containerd/pkg/unpack
|
||||
github.com/containerd/containerd/pkg/userns
|
||||
github.com/containerd/containerd/plugin
|
||||
@@ -325,7 +322,6 @@ github.com/containerd/containerd/remotes/errors
|
||||
github.com/containerd/containerd/rootfs
|
||||
github.com/containerd/containerd/runtime/linux/runctypes
|
||||
github.com/containerd/containerd/runtime/v2/runc/options
|
||||
github.com/containerd/containerd/runtime/v2/shim
|
||||
github.com/containerd/containerd/sandbox
|
||||
github.com/containerd/containerd/sandbox/proxy
|
||||
github.com/containerd/containerd/services
|
||||
@@ -337,14 +333,12 @@ github.com/containerd/containerd/snapshots
|
||||
github.com/containerd/containerd/snapshots/overlay/overlayutils
|
||||
github.com/containerd/containerd/snapshots/proxy
|
||||
github.com/containerd/containerd/sys
|
||||
github.com/containerd/containerd/sys/reaper
|
||||
github.com/containerd/containerd/tracing
|
||||
github.com/containerd/containerd/version
|
||||
# github.com/containerd/containerd/api v1.7.19
|
||||
## explicit; go 1.21
|
||||
github.com/containerd/containerd/api/events
|
||||
github.com/containerd/containerd/api/runtime/sandbox/v1
|
||||
github.com/containerd/containerd/api/runtime/task/v2
|
||||
github.com/containerd/containerd/api/services/containers/v1
|
||||
github.com/containerd/containerd/api/services/content/v1
|
||||
github.com/containerd/containerd/api/services/diff/v1
|
||||
@@ -358,7 +352,6 @@ github.com/containerd/containerd/api/services/snapshots/v1
|
||||
github.com/containerd/containerd/api/services/streaming/v1
|
||||
github.com/containerd/containerd/api/services/tasks/v1
|
||||
github.com/containerd/containerd/api/services/transfer/v1
|
||||
github.com/containerd/containerd/api/services/ttrpc/events/v1
|
||||
github.com/containerd/containerd/api/services/version/v1
|
||||
github.com/containerd/containerd/api/types
|
||||
github.com/containerd/containerd/api/types/task
|
||||
|
||||
Reference in New Issue
Block a user