fix: reject closing already closed lifecycle
Tests / Run Tests (pull_request) Successful in 2m36s
Docker Build and Push / Build and Push Docker Image (push) Has been cancelled
Docker Build and Push / Run Tests (push) Has been cancelled

This commit is contained in:
2026-07-16 15:20:49 +07:00
parent 6aa8c3bd48
commit cbab4f7612
2 changed files with 102 additions and 26 deletions
+35 -26
View File
@@ -80,6 +80,12 @@ func (l *lifecycle) User() string {
func (l *lifecycle) SetChannel(channel ssh.Channel) error {
l.mu.Lock()
defer l.mu.Unlock()
if l.status == types.SessionStatusCLOSED {
return fmt.Errorf("lifecycle is closed")
}
if channel == nil {
return fmt.Errorf("channel cannot be nil")
}
if l.channel != nil {
return fmt.Errorf("channel already set")
}
@@ -100,6 +106,9 @@ func (l *lifecycle) Connection() ssh.Conn {
func (l *lifecycle) SetStatus(status types.SessionStatus) {
l.mu.Lock()
defer l.mu.Unlock()
if l.status == types.SessionStatusCLOSED {
return
}
l.status = status
if status == types.SessionStatusRUNNING && l.startedAt.IsZero() {
l.startedAt = time.Now()
@@ -114,41 +123,41 @@ func (l *lifecycle) IsActive() bool {
func (l *lifecycle) Close() error {
l.mu.Lock()
defer l.mu.Unlock()
if l.status == types.SessionStatusCLOSED {
return l.closeErr
closeErr := l.closeErr
l.mu.Unlock()
return closeErr
}
l.status = types.SessionStatusCLOSED
channel := l.channel
conn := l.conn
l.mu.Unlock()
var errs []error
errs = append(errs, l.closeChannel())
errs = append(errs, l.closeConnection())
if channel != nil {
if err := channel.Close(); err != nil && !isClosedError(err) {
errs = append(errs, err)
}
}
if conn != nil {
if err := conn.Close(); err != nil && !isClosedError(err) {
errs = append(errs, err)
}
}
l.cleanupRegistry()
errs = append(errs, l.cleanupForwarder())
if err := l.cleanupForwarder(); err != nil {
errs = append(errs, err)
}
l.closeErr = errors.Join(errs...)
return l.closeErr
}
closeErr := errors.Join(errs...)
func (l *lifecycle) closeChannel() error {
if l.channel == nil {
return nil
}
if err := l.channel.Close(); err != nil && !isClosedError(err) {
return err
}
return nil
}
l.mu.Lock()
l.closeErr = closeErr
l.mu.Unlock()
func (l *lifecycle) closeConnection() error {
if l.conn == nil {
return nil
}
if err := l.conn.Close(); err != nil && !isClosedError(err) {
return err
}
return nil
return closeErr
}
func (l *lifecycle) cleanupRegistry() {