@@ -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.
@@ -757,6 +775,59 @@ func (c *Container) ExecResize(sessionID string, newSize resize.TerminalSize) er
757
775
return c .ociRuntime .ExecAttachResize (c , sessionID , newSize )
758
776
}
759
777
778
+ func (c * Container ) healthCheckExec (config * ExecConfig , streams * define.AttachStreams ) (exitCode int , retErr error ) {
779
+ if ! c .batched {
780
+ c .lock .Lock ()
781
+ defer c .lock .Unlock ()
782
+
783
+ if err := c .syncContainer (); err != nil {
784
+ return - 1 , err
785
+ }
786
+ }
787
+
788
+ if err := c .verifyExecConfig (config ); err != nil {
789
+ return - 1 , err
790
+ }
791
+
792
+ if ! c .ensureState (define .ContainerStateRunning ) {
793
+ return - 1 , fmt .Errorf ("can only create exec sessions on running containers: %w" , define .ErrCtrStateInvalid )
794
+ }
795
+
796
+ session , err := c .createExecSession (config )
797
+ if err != nil {
798
+ return - 1 , err
799
+ }
800
+
801
+ if c .state .ExecSessions == nil {
802
+ c .state .ExecSessions = make (map [string ]* ExecSession )
803
+ }
804
+ c .state .ExecSessions [session .ID ()] = session
805
+ defer delete (c .state .ExecSessions , session .ID ())
806
+
807
+ opts , err := prepareForExec (c , session )
808
+ if err != nil {
809
+ return - 1 , err
810
+ }
811
+ defer func () {
812
+ if err := c .cleanupExecBundle (session .ID ()); err != nil {
813
+ logrus .Errorf ("Container %s light exec session cleanup error: %v" , c .ID (), err )
814
+ }
815
+ }()
816
+
817
+ pid , attachErrChan , err := c .ociRuntime .ExecContainer (c , session .ID (), opts , streams , nil )
818
+ if err != nil {
819
+ return - 1 , err
820
+ }
821
+
822
+ err = <- attachErrChan
823
+ if err != nil {
824
+ logrus .Errorf ("Container %s light exec session with pid: %d error: %v" , c .ID (), pid , err )
825
+ return - 1 , err
826
+ }
827
+
828
+ return c .readExecExitCode (session .ID ())
829
+ }
830
+
760
831
func (c * Container ) Exec (config * ExecConfig , streams * define.AttachStreams , resize <- chan resize.TerminalSize ) (int , error ) {
761
832
return c .exec (config , streams , resize , false )
762
833
}
0 commit comments