@@ -158,34 +158,20 @@ type legacyExecSession struct {
158158 PID int `json:"pid"`
159159}
160160
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 {
174162 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 )
176164 }
177165 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 )
179167 }
180168 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 )
187170 }
171+ return nil
172+ }
188173
174+ func (c * Container ) getUniqueExecSessionID () string {
189175 // Generate an ID for our new exec session
190176 sessionID := stringid .GenerateRandomID ()
191177 found := true
@@ -202,20 +188,52 @@ func (c *Container) ExecCreate(config *ExecConfig) (string, error) {
202188 sessionID = stringid .GenerateRandomID ()
203189 }
204190 }
191+ return sessionID
192+ }
205193
206- // Make our new exec session
194+ func ( c * Container ) createExecSession ( config * ExecConfig ) ( * ExecSession , error ) {
207195 session := new (ExecSession )
208- session .Id = sessionID
196+ session .Id = c . getUniqueExecSessionID ()
209197 session .ContainerId = c .ID ()
210198 session .State = define .ExecStateCreated
211199 session .Config = new (ExecConfig )
212200 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 )
214202 }
215203
216204 if len (session .Config .ExitCommand ) > 0 {
217205 session .Config .ExitCommand = append (session .Config .ExitCommand , []string {session .ID (), c .ID ()}... )
218206 }
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+ }
219237
220238 if c .state .ExecSessions == nil {
221239 c .state .ExecSessions = make (map [string ]* ExecSession )
@@ -232,7 +250,7 @@ func (c *Container) ExecCreate(config *ExecConfig) (string, error) {
232250
233251 logrus .Infof ("Created exec session %s in container %s" , session .ID (), c .ID ())
234252
235- return sessionID , nil
253+ return session . Id , nil
236254}
237255
238256// 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
775793 return c .ociRuntime .ExecAttachResize (c , sessionID , newSize )
776794}
777795
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+
778852func (c * Container ) Exec (config * ExecConfig , streams * define.AttachStreams , resize <- chan resize.TerminalSize ) (int , error ) {
779853 return c .exec (config , streams , resize , false )
780854}
0 commit comments