1
2
3 package main
4
5 import (
6 "context"
7 "sync"
8 "time"
9
10 "github.com/Microsoft/hcsshim/internal/log"
11 eventstypes "github.com/containerd/containerd/api/events"
12 containerd_v1_types "github.com/containerd/containerd/api/types/task"
13 "github.com/containerd/containerd/errdefs"
14 "github.com/containerd/containerd/runtime"
15 "github.com/containerd/containerd/runtime/v2/task"
16 "github.com/pkg/errors"
17 "github.com/sirupsen/logrus"
18 )
19
20 func newWcowPodSandboxExec(ctx context.Context, events publisher, tid, bundle string) *wcowPodSandboxExec {
21 log.G(ctx).WithFields(logrus.Fields{
22 "tid": tid,
23 "eid": tid,
24 "bundle": bundle,
25 }).Debug("newWcowPodSandboxExec")
26
27 wpse := &wcowPodSandboxExec{
28 events: events,
29 tid: tid,
30 bundle: bundle,
31 state: shimExecStateCreated,
32 exitStatus: 255,
33 exited: make(chan struct{}),
34 }
35 return wpse
36 }
37
38 var _ = (shimExec)(&wcowPodSandboxExec{})
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 type wcowPodSandboxExec struct {
55 events publisher
56
57
58
59 tid string
60
61
62
63
64
65
66 bundle string
67
68
69
70 sl sync.Mutex
71 state shimExecState
72 pid int
73 exitStatus uint32
74 exitedAt time.Time
75
76
77 exited chan struct{}
78 }
79
80 func (wpse *wcowPodSandboxExec) ID() string {
81 return wpse.tid
82 }
83
84 func (wpse *wcowPodSandboxExec) Pid() int {
85 wpse.sl.Lock()
86 defer wpse.sl.Unlock()
87 return wpse.pid
88 }
89
90 func (wpse *wcowPodSandboxExec) State() shimExecState {
91 wpse.sl.Lock()
92 defer wpse.sl.Unlock()
93 return wpse.state
94 }
95
96 func (wpse *wcowPodSandboxExec) Status() *task.StateResponse {
97 wpse.sl.Lock()
98 defer wpse.sl.Unlock()
99
100 var s containerd_v1_types.Status
101 switch wpse.state {
102 case shimExecStateCreated:
103 s = containerd_v1_types.StatusCreated
104 case shimExecStateRunning:
105 s = containerd_v1_types.StatusRunning
106 case shimExecStateExited:
107 s = containerd_v1_types.StatusStopped
108 }
109
110 return &task.StateResponse{
111 ID: wpse.tid,
112 ExecID: wpse.tid,
113 Bundle: wpse.bundle,
114 Pid: uint32(wpse.pid),
115 Status: s,
116 Stdin: "",
117 Stdout: "",
118 Stderr: "",
119 Terminal: false,
120 ExitStatus: wpse.exitStatus,
121 ExitedAt: wpse.exitedAt,
122 }
123 }
124
125 func (wpse *wcowPodSandboxExec) Start(ctx context.Context) error {
126 wpse.sl.Lock()
127 defer wpse.sl.Unlock()
128 if wpse.state != shimExecStateCreated {
129 return newExecInvalidStateError(wpse.tid, wpse.tid, wpse.state, "start")
130 }
131
132 wpse.state = shimExecStateRunning
133 wpse.pid = 1
134
135
136
137 return wpse.events.publishEvent(
138 ctx,
139 runtime.TaskStartEventTopic,
140 &eventstypes.TaskStart{
141 ContainerID: wpse.tid,
142 Pid: uint32(wpse.pid),
143 })
144 }
145
146 func (wpse *wcowPodSandboxExec) Kill(ctx context.Context, signal uint32) error {
147 wpse.sl.Lock()
148 defer wpse.sl.Unlock()
149 switch wpse.state {
150 case shimExecStateCreated:
151 wpse.state = shimExecStateExited
152 wpse.exitStatus = 1
153 wpse.exitedAt = time.Now()
154 close(wpse.exited)
155 return nil
156 case shimExecStateRunning:
157
158 wpse.state = shimExecStateExited
159 wpse.exitStatus = 0
160 wpse.exitedAt = time.Now()
161
162
163
164
165 close(wpse.exited)
166 return nil
167 case shimExecStateExited:
168 return errors.Wrapf(errdefs.ErrNotFound, "exec: '%s' in task: '%s' not found", wpse.tid, wpse.tid)
169 default:
170 return newExecInvalidStateError(wpse.tid, wpse.tid, wpse.state, "kill")
171 }
172 }
173
174 func (wpse *wcowPodSandboxExec) ResizePty(ctx context.Context, width, height uint32) error {
175 wpse.sl.Lock()
176 defer wpse.sl.Unlock()
177
178
179 return errors.Wrapf(errdefs.ErrFailedPrecondition, "exec: '%s' in task: '%s' is not a tty", wpse.tid, wpse.tid)
180 }
181
182 func (wpse *wcowPodSandboxExec) CloseIO(ctx context.Context, stdin bool) error {
183 return nil
184 }
185
186 func (wpse *wcowPodSandboxExec) Wait() *task.StateResponse {
187 <-wpse.exited
188 return wpse.Status()
189 }
190
191 func (wpse *wcowPodSandboxExec) ForceExit(ctx context.Context, status int) {
192 wpse.sl.Lock()
193 defer wpse.sl.Unlock()
194 if wpse.state != shimExecStateExited {
195
196 log.G(ctx).WithField("status", status).Debug("wcowPodSandboxExec::ForceExit")
197
198 wpse.state = shimExecStateExited
199 wpse.exitStatus = 1
200 wpse.exitedAt = time.Now()
201
202
203
204
205 close(wpse.exited)
206 }
207 }
208
View as plain text