or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-clients.mdconfiguration.mdindex.mdmonitoring.mdpod-operations.mdutilities.md
tile.json

pod-operations.mddocs/

0

# Pod Operations

1

2

High-level classes for interactive pod operations including command execution, container attachment, port forwarding, and file transfer. These classes provide convenient abstractions over WebSocket-based Kubernetes APIs.

3

4

## Capabilities

5

6

### Exec Class

7

8

Execute commands in pod containers with support for interactive sessions, TTY mode, and stream handling.

9

10

```typescript { .api }

11

/**

12

* Execute commands in pod containers

13

*/

14

class Exec {

15

constructor(config: KubeConfig, wsInterface?: WebSocketInterface);

16

17

/**

18

* Execute a command in a container

19

* @param namespace - Pod namespace

20

* @param podName - Pod name

21

* @param containerName - Container name

22

* @param command - Command to execute (string or array)

23

* @param stdout - Output stream for stdout

24

* @param stderr - Output stream for stderr

25

* @param stdin - Input stream for stdin

26

* @param tty - Enable TTY mode

27

* @param statusCallback - Callback for command status

28

* @returns Promise that resolves to WebSocket connection

29

*/

30

exec(

31

namespace: string,

32

podName: string,

33

containerName: string,

34

command: string | string[],

35

stdout: stream.Writable | null,

36

stderr: stream.Writable | null,

37

stdin: stream.Readable | null,

38

tty: boolean,

39

statusCallback?: (status: V1Status) => void

40

): Promise<WebSocket.WebSocket>;

41

}

42

```

43

44

**Usage Examples:**

45

46

```typescript

47

import { KubeConfig, Exec } from '@kubernetes/client-node';

48

import * as stream from 'stream';

49

50

const kc = new KubeConfig();

51

kc.loadFromDefault();

52

53

const exec = new Exec(kc);

54

55

// Execute a simple command

56

const stdout = new stream.PassThrough();

57

const stderr = new stream.PassThrough();

58

59

stdout.on('data', (data) => {

60

console.log('STDOUT:', data.toString());

61

});

62

63

stderr.on('data', (data) => {

64

console.error('STDERR:', data.toString());

65

});

66

67

try {

68

const ws = await exec.exec(

69

'default', // namespace

70

'my-pod', // pod name

71

'my-container', // container name

72

['ls', '-la', '/'], // command

73

stdout, // stdout stream

74

stderr, // stderr stream

75

null, // stdin stream

76

false, // tty mode

77

(status) => { // status callback

78

console.log('Command status:', status);

79

}

80

);

81

82

// Handle WebSocket events

83

ws.on('close', (code, reason) => {

84

console.log('Connection closed:', code, reason);

85

});

86

} catch (error) {

87

console.error('Exec error:', error);

88

}

89

90

// Interactive shell session with TTY

91

const process = require('process');

92

93

const interactiveExec = async () => {

94

try {

95

const ws = await exec.exec(

96

'default',

97

'my-pod',

98

'my-container',

99

['/bin/bash'], // shell command

100

process.stdout, // stdout to console

101

process.stderr, // stderr to console

102

process.stdin, // stdin from console

103

true // TTY mode for interactive session

104

);

105

106

// Handle process signals

107

process.on('SIGINT', () => {

108

ws.close();

109

});

110

} catch (error) {

111

console.error('Interactive exec error:', error);

112

}

113

};

114

```

115

116

### Attach Class

117

118

Attach to running containers to interact with their primary process.

119

120

```typescript { .api }

121

/**

122

* Attach to running containers

123

*/

124

class Attach {

125

constructor(config: KubeConfig, websocketInterface?: WebSocketInterface);

126

127

/**

128

* Attach to a running container

129

* @param namespace - Pod namespace

130

* @param podName - Pod name

131

* @param containerName - Container name

132

* @param stdout - Output stream for stdout

133

* @param stderr - Output stream for stderr

134

* @param stdin - Input stream for stdin

135

* @param tty - Enable TTY mode

136

* @returns Promise that resolves to WebSocket connection

137

*/

138

attach(

139

namespace: string,

140

podName: string,

141

containerName: string,

142

stdout: stream.Writable | any,

143

stderr: stream.Writable | any,

144

stdin: stream.Readable | any,

145

tty: boolean

146

): Promise<WebSocket.WebSocket>;

147

}

148

```

149

150

**Usage Examples:**

151

152

```typescript

153

import { KubeConfig, Attach } from '@kubernetes/client-node';

154

155

const kc = new KubeConfig();

156

kc.loadFromDefault();

157

158

const attach = new Attach(kc);

159

160

// Attach to container's main process

161

try {

162

const ws = await attach.attach(

163

'default',

164

'my-pod',

165

'my-container',

166

process.stdout, // stdout

167

process.stderr, // stderr

168

process.stdin, // stdin

169

true // TTY mode

170

);

171

172

console.log('Attached to container');

173

174

ws.on('close', () => {

175

console.log('Detached from container');

176

});

177

} catch (error) {

178

console.error('Attach error:', error);

179

}

180

```

181

182

### PortForward Class

183

184

Forward local ports to pod ports for accessing services running inside containers.

185

186

```typescript { .api }

187

/**

188

* Forward local ports to pod ports

189

*/

190

class PortForward {

191

constructor(config: KubeConfig, disconnectOnErr?: boolean, handler?: WebSocketInterface);

192

193

/**

194

* Forward ports to a pod

195

* @param namespace - Pod namespace

196

* @param podName - Pod name

197

* @param targetPorts - Array of port numbers to forward

198

* @param output - Output stream for data

199

* @param err - Error stream

200

* @param input - Input stream for data

201

* @param retryCount - Number of retry attempts

202

* @returns Promise that resolves to WebSocket or connection function

203

*/

204

portForward(

205

namespace: string,

206

podName: string,

207

targetPorts: number[],

208

output: stream.Writable,

209

err: stream.Writable | null,

210

input: stream.Readable,

211

retryCount?: number

212

): Promise<WebSocket.WebSocket | (() => WebSocket.WebSocket | null)>;

213

}

214

```

215

216

**Usage Examples:**

217

218

```typescript

219

import { KubeConfig, PortForward } from '@kubernetes/client-node';

220

import * as net from 'net';

221

222

const kc = new KubeConfig();

223

kc.loadFromDefault();

224

225

const portForward = new PortForward(kc);

226

227

// Forward local port 8080 to pod port 80

228

const forwardPort = async () => {

229

const server = net.createServer((socket) => {

230

portForward.portForward(

231

'default', // namespace

232

'my-pod', // pod name

233

[80], // target ports

234

socket, // output stream

235

null, // error stream

236

socket, // input stream

237

0 // retry count

238

).then((ws) => {

239

console.log('Port forward established');

240

241

socket.on('close', () => {

242

if (typeof ws === 'function') {

243

const connection = ws();

244

if (connection) {

245

connection.close();

246

}

247

} else {

248

ws.close();

249

}

250

});

251

}).catch((error) => {

252

console.error('Port forward error:', error);

253

socket.destroy();

254

});

255

});

256

257

server.listen(8080, () => {

258

console.log('Local server listening on port 8080');

259

console.log('Forwarding to pod my-pod:80');

260

});

261

};

262

263

forwardPort();

264

265

// Simple port forwarding with streams

266

const simplePortForward = async () => {

267

const output = new stream.PassThrough();

268

const input = new stream.PassThrough();

269

270

try {

271

const ws = await portForward.portForward(

272

'default',

273

'my-pod',

274

[3000, 8080], // Forward multiple ports

275

output,

276

process.stderr,

277

input

278

);

279

280

console.log('Port forwarding active');

281

282

// Handle data

283

output.on('data', (data) => {

284

console.log('Received data:', data.toString());

285

});

286

287

} catch (error) {

288

console.error('Port forward failed:', error);

289

}

290

};

291

```

292

293

### Cp Class

294

295

Copy files to and from pod containers using tar-based transfer.

296

297

```typescript { .api }

298

/**

299

* Copy files to/from pod containers

300

*/

301

class Cp {

302

constructor(config: KubeConfig, execInstance?: Exec);

303

304

/**

305

* Copy file from pod to local filesystem

306

* @param namespace - Pod namespace

307

* @param podName - Pod name

308

* @param containerName - Container name

309

* @param srcPath - Source path in container

310

* @param tgtPath - Target path on local filesystem

311

* @returns Promise that resolves when copy is complete

312

*/

313

cpFromPod(

314

namespace: string,

315

podName: string,

316

containerName: string,

317

srcPath: string,

318

tgtPath: string

319

): Promise<void>;

320

321

/**

322

* Copy file from local filesystem to pod

323

* @param namespace - Pod namespace

324

* @param podName - Pod name

325

* @param containerName - Container name

326

* @param srcPath - Source path on local filesystem

327

* @param tgtPath - Target path in container

328

* @returns Promise that resolves when copy is complete

329

*/

330

cpToPod(

331

namespace: string,

332

podName: string,

333

containerName: string,

334

srcPath: string,

335

tgtPath: string

336

): Promise<void>;

337

}

338

```

339

340

**Usage Examples:**

341

342

```typescript

343

import { KubeConfig, Cp } from '@kubernetes/client-node';

344

345

const kc = new KubeConfig();

346

kc.loadFromDefault();

347

348

const cp = new Cp(kc);

349

350

// Copy file from pod to local system

351

const copyFromPod = async () => {

352

try {

353

await cp.cpFromPod(

354

'default', // namespace

355

'my-pod', // pod name

356

'my-container', // container name

357

'/app/config.json', // source path in pod

358

'./local-config.json' // target path locally

359

);

360

361

console.log('File copied from pod successfully');

362

} catch (error) {

363

console.error('Copy from pod failed:', error);

364

}

365

};

366

367

// Copy file from local system to pod

368

const copyToPod = async () => {

369

try {

370

await cp.cpToPod(

371

'default', // namespace

372

'my-pod', // pod name

373

'my-container', // container name

374

'./local-data.txt', // source path locally

375

'/tmp/data.txt' // target path in pod

376

);

377

378

console.log('File copied to pod successfully');

379

} catch (error) {

380

console.error('Copy to pod failed:', error);

381

}

382

};

383

384

// Copy directory from pod

385

const copyDirectoryFromPod = async () => {

386

try {

387

await cp.cpFromPod(

388

'default',

389

'my-pod',

390

'my-container',

391

'/app/logs/', // source directory in pod

392

'./pod-logs/' // target directory locally

393

);

394

395

console.log('Directory copied from pod successfully');

396

} catch (error) {

397

console.error('Directory copy failed:', error);

398

}

399

};

400

401

// Batch file operations

402

const batchOperations = async () => {

403

const operations = [

404

// Backup configuration

405

() => cp.cpFromPod('default', 'my-pod', 'app', '/etc/app/config.yaml', './backups/config.yaml'),

406

407

// Update configuration

408

() => cp.cpToPod('default', 'my-pod', 'app', './new-config.yaml', '/etc/app/config.yaml'),

409

410

// Copy logs

411

() => cp.cpFromPod('default', 'my-pod', 'app', '/var/log/app.log', './logs/app.log')

412

];

413

414

for (const operation of operations) {

415

try {

416

await operation();

417

} catch (error) {

418

console.error('Operation failed:', error);

419

}

420

}

421

};

422

```

423

424

### WebSocket Interface

425

426

All pod operations use WebSocket connections for real-time communication.

427

428

```typescript { .api }

429

/**

430

* WebSocket interface for customizing WebSocket behavior

431

*/

432

interface WebSocketInterface {

433

connect(

434

path: string,

435

textHandler: (text: string) => void,

436

binaryHandler: (binary: Buffer) => void

437

): WebSocket.WebSocket;

438

}

439

440

/**

441

* Default WebSocket handler

442

*/

443

class WebSocketHandler implements WebSocketInterface {

444

connect(

445

path: string,

446

textHandler: (text: string) => void,

447

binaryHandler: (binary: Buffer) => void

448

): WebSocket.WebSocket;

449

}

450

```

451

452

### Error Handling

453

454

Pod operations can fail for various reasons. Always handle errors appropriately:

455

456

```typescript

457

import { ApiException } from '@kubernetes/client-node';

458

459

const handlePodOperation = async () => {

460

try {

461

const ws = await exec.exec(

462

'default',

463

'my-pod',

464

'my-container',

465

['echo', 'hello'],

466

stdout,

467

stderr,

468

null,

469

false

470

);

471

} catch (error) {

472

if (error instanceof ApiException) {

473

console.error('API Error:', error.code);

474

if (error.code === 404) {

475

console.error('Pod not found');

476

} else if (error.code === 403) {

477

console.error('Access denied');

478

}

479

} else {

480

console.error('Network or other error:', error.message);

481

}

482

}

483

};

484

```

485

486

### Advanced Usage

487

488

**Custom WebSocket handling:**

489

490

```typescript

491

import { Exec, WebSocketInterface } from '@kubernetes/client-node';

492

493

class CustomWebSocketHandler implements WebSocketInterface {

494

connect(path: string, textHandler: (text: string) => void, binaryHandler: (binary: Buffer) => void) {

495

// Custom WebSocket implementation

496

const ws = new WebSocket(path);

497

498

ws.on('message', (data) => {

499

if (typeof data === 'string') {

500

textHandler(data);

501

} else {

502

binaryHandler(data as Buffer);

503

}

504

});

505

506

return ws;

507

}

508

}

509

510

const exec = new Exec(kc, new CustomWebSocketHandler());

511

```

512

513

**Stream processing with transforms:**

514

515

```typescript

516

import { Transform } from 'stream';

517

518

const colorOutput = new Transform({

519

transform(chunk, encoding, callback) {

520

// Add color codes to output

521

const colored = `\x1b[32m${chunk.toString()}\x1b[0m`;

522

callback(null, colored);

523

}

524

});

525

526

const ws = await exec.exec(

527

'default',

528

'my-pod',

529

'my-container',

530

['tail', '-f', '/var/log/app.log'],

531

colorOutput.pipe(process.stdout),

532

process.stderr,

533

null,

534

false

535

);

536

```