exec method

ExecSession exec({
  1. required String containerId,
  2. required String command,
  3. bool tty = false,
  4. String? name,
})

Implementation

ExecSession exec({required String containerId, required String command, bool tty = false, String? name}) {
  final requestId = const Uuid().v4();
  final session = ExecSession._(requestId: requestId, command: command, containerId: containerId, tty: tty);

  room
      .invoke(toolkit: 'containers', tool: 'exec', input: ToolStreamInput(session.inputStream()))
      .then((output) async {
        if (output is! ToolStreamOutput) {
          throw _unexpectedResponseError(operation: 'exec');
        }

        await for (final chunk in output.stream) {
          if (chunk is ErrorContent) {
            throw RoomServerException(chunk.text, code: chunk.code);
          }
          if (chunk is! BinaryContent) {
            throw _unexpectedResponseError(operation: 'exec');
          }

          final rawChannel = chunk.headers['channel'];
          if (rawChannel is! int) {
            throw RoomServerException('containers.exec returned a chunk without a valid channel');
          }

          if (rawChannel == 1) {
            session._stdoutController.add(chunk.data);
            continue;
          }
          if (rawChannel == 3) {
            final payload = jsonDecode(utf8.decode(chunk.data));
            if (payload is Map && payload['status'] is int) {
              session._close(payload['status'] as int);
              return;
            }
            throw RoomServerException('containers.exec returned an invalid status payload');
          }
        }

        throw RoomServerException('containers.exec stream closed before a status was returned');
      })
      .catchError((Object error) {
        session._closeError(error);
      });

  return session;
}