@@ -158,34 +158,20 @@ type legacyExecSession struct {
158
158
PID int `json:"pid"`
159
159
}
160
160
161
- // ExecCreate creates a new exec session for the container.
162
- // The session is not started. The ID of the new exec session will be returned.
163
- func (c * Container ) ExecCreate (config * ExecConfig ) (string , error ) {
164
- if ! c .batched {
165
- c .lock .Lock ()
166
- defer c .lock .Unlock ()
167
-
168
- if err := c .syncContainer (); err != nil {
169
- return "" , err
170
- }
171
- }
172
-
173
- // Verify our config
161
+ func (c * Container ) verifyExecConfig (config * ExecConfig ) error {
174
162
if config == nil {
175
- return "" , fmt .Errorf ("must provide a configuration to ExecCreate: %w" , define .ErrInvalidArg )
163
+ return fmt .Errorf ("must provide a configuration to ExecCreate: %w" , define .ErrInvalidArg )
176
164
}
177
165
if len (config .Command ) == 0 {
178
- return "" , fmt .Errorf ("must provide a non-empty command to start an exec session: %w" , define .ErrInvalidArg )
166
+ return fmt .Errorf ("must provide a non-empty command to start an exec session: %w" , define .ErrInvalidArg )
179
167
}
180
168
if config .ExitCommandDelay > 0 && len (config .ExitCommand ) == 0 {
181
- return "" , fmt .Errorf ("must provide a non-empty exit command if giving an exit command delay: %w" , define .ErrInvalidArg )
182
- }
183
-
184
- // Verify that we are in a good state to continue
185
- if ! c .ensureState (define .ContainerStateRunning ) {
186
- return "" , fmt .Errorf ("can only create exec sessions on running containers: %w" , define .ErrCtrStateInvalid )
169
+ return fmt .Errorf ("must provide a non-empty exit command if giving an exit command delay: %w" , define .ErrInvalidArg )
187
170
}
171
+ return nil
172
+ }
188
173
174
+ func (c * Container ) getUniqueExecSessionID () string {
189
175
// Generate an ID for our new exec session
190
176
sessionID := stringid .GenerateRandomID ()
191
177
found := true
@@ -202,20 +188,52 @@ func (c *Container) ExecCreate(config *ExecConfig) (string, error) {
202
188
sessionID = stringid .GenerateRandomID ()
203
189
}
204
190
}
191
+ return sessionID
192
+ }
205
193
206
- // Make our new exec session
194
+ func ( c * Container ) createExecSession ( config * ExecConfig ) ( * ExecSession , error ) {
207
195
session := new (ExecSession )
208
- session .Id = sessionID
196
+ session .Id = c . getUniqueExecSessionID ()
209
197
session .ContainerId = c .ID ()
210
198
session .State = define .ExecStateCreated
211
199
session .Config = new (ExecConfig )
212
200
if err := JSONDeepCopy (config , session .Config ); err != nil {
213
- return "" , fmt .Errorf ("copying exec configuration into exec session: %w" , err )
201
+ return nil , fmt .Errorf ("copying exec configuration into exec session: %w" , err )
214
202
}
215
203
216
204
if len (session .Config .ExitCommand ) > 0 {
217
205
session .Config .ExitCommand = append (session .Config .ExitCommand , []string {session .ID (), c .ID ()}... )
218
206
}
207
+ return session , nil
208
+ }
209
+
210
+ // ExecCreate creates a new exec session for the container.
211
+ // The session is not started. The ID of the new exec session will be returned.
212
+ func (c * Container ) ExecCreate (config * ExecConfig ) (string , error ) {
213
+ if ! c .batched {
214
+ c .lock .Lock ()
215
+ defer c .lock .Unlock ()
216
+
217
+ if err := c .syncContainer (); err != nil {
218
+ return "" , err
219
+ }
220
+ }
221
+
222
+ // Verify our config
223
+ if err := c .verifyExecConfig (config ); err != nil {
224
+ return "" , err
225
+ }
226
+
227
+ // Verify that we are in a good state to continue
228
+ if ! c .ensureState (define .ContainerStateRunning ) {
229
+ return "" , fmt .Errorf ("can only create exec sessions on running containers: %w" , define .ErrCtrStateInvalid )
230
+ }
231
+
232
+ // Make our new exec session
233
+ session , err := c .createExecSession (config )
234
+ if err != nil {
235
+ return "" , err
236
+ }
219
237
220
238
if c .state .ExecSessions == nil {
221
239
c .state .ExecSessions = make (map [string ]* ExecSession )
@@ -232,7 +250,7 @@ func (c *Container) ExecCreate(config *ExecConfig) (string, error) {
232
250
233
251
logrus .Infof ("Created exec session %s in container %s" , session .ID (), c .ID ())
234
252
235
- return sessionID , nil
253
+ return session . Id , nil
236
254
}
237
255
238
256
// ExecStart starts an exec session in the container, but does not attach to it.
@@ -775,6 +793,62 @@ func (c *Container) ExecResize(sessionID string, newSize resize.TerminalSize) er
775
793
return c .ociRuntime .ExecAttachResize (c , sessionID , newSize )
776
794
}
777
795
796
+ func (c * Container ) healthCheckExec (config * ExecConfig , streams * define.AttachStreams ) (exitCode int , retErr error ) {
797
+ if ! c .batched {
798
+ c .lock .Lock ()
799
+
800
+ if err := c .syncContainer (); err != nil {
801
+ return - 1 , err
802
+ }
803
+ }
804
+
805
+ if err := c .verifyExecConfig (config ); err != nil {
806
+ return - 1 , err
807
+ }
808
+
809
+ if ! c .ensureState (define .ContainerStateRunning ) {
810
+ return - 1 , fmt .Errorf ("can only create exec sessions on running containers: %w" , define .ErrCtrStateInvalid )
811
+ }
812
+
813
+ session , err := c .createExecSession (config )
814
+ if err != nil {
815
+ return - 1 , err
816
+ }
817
+
818
+ if c .state .ExecSessions == nil {
819
+ c .state .ExecSessions = make (map [string ]* ExecSession )
820
+ }
821
+ c .state .ExecSessions [session .ID ()] = session
822
+ defer delete (c .state .ExecSessions , session .ID ())
823
+
824
+ opts , err := prepareForExec (c , session )
825
+ if err != nil {
826
+ return - 1 , err
827
+ }
828
+ defer func () {
829
+ if err := c .cleanupExecBundle (session .ID ()); err != nil {
830
+ logrus .Errorf ("Container %s light exec session cleanup error: %v" , c .ID (), err )
831
+ }
832
+ }()
833
+
834
+ pid , attachErrChan , err := c .ociRuntime .ExecContainer (c , session .ID (), opts , streams , nil )
835
+ if err != nil {
836
+ return - 1 , err
837
+ }
838
+
839
+ if ! c .batched {
840
+ c .lock .Unlock ()
841
+ }
842
+
843
+ err = <- attachErrChan
844
+ if err != nil {
845
+ logrus .Errorf ("Container %s light exec session with pid: %d error: %v" , c .ID (), pid , err )
846
+ return - 1 , err
847
+ }
848
+
849
+ return c .readExecExitCode (session .ID ())
850
+ }
851
+
778
852
func (c * Container ) Exec (config * ExecConfig , streams * define.AttachStreams , resize <- chan resize.TerminalSize ) (int , error ) {
779
853
return c .exec (config , streams , resize , false )
780
854
}
0 commit comments