Skip to content

Commit e4aed8b

Browse files
feat: Add ResizeExecTtyAsync to IExecOperations (#68)
Co-authored-by: Andre Hofmeister <[email protected]>
1 parent 0a3727d commit e4aed8b

File tree

5 files changed

+121
-6
lines changed

5 files changed

+121
-6
lines changed

src/Docker.DotNet/Endpoints/ExecOperations.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,22 @@ public async Task<MultiplexedStream> StartContainerExecAsync(string id, Containe
6060

6161
return new MultiplexedStream(response, !parameters.TTY);
6262
}
63+
64+
public async Task ResizeExecTtyAsync(string id, ContainerResizeParameters parameters, CancellationToken cancellationToken = default)
65+
{
66+
if (string.IsNullOrEmpty(id))
67+
{
68+
throw new ArgumentNullException(nameof(id));
69+
}
70+
71+
if (parameters == null)
72+
{
73+
throw new ArgumentNullException(nameof(parameters));
74+
}
75+
76+
var queryParameters = new QueryString<ContainerResizeParameters>(parameters);
77+
78+
await _client.MakeRequestAsync([NoSuchContainerHandler], HttpMethod.Post, $"exec/{id}/resize", queryParameters, cancellationToken)
79+
.ConfigureAwait(false);
80+
}
6381
}

src/Docker.DotNet/Endpoints/IExecOperations.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ public interface IExecOperations
77
Task<ContainerExecCreateResponse> CreateContainerExecAsync(string id, ContainerExecCreateParameters parameters, CancellationToken cancellationToken = default);
88

99
Task<MultiplexedStream> StartContainerExecAsync(string id, ContainerExecStartParameters parameters, CancellationToken cancellationToken = default);
10+
11+
Task ResizeExecTtyAsync(string id, ContainerResizeParameters parameters, CancellationToken cancellationToken = default);
1012
}

src/Docker.DotNet/Models/ContainerResizeParameters.Generated.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ namespace Docker.DotNet.Models
22
{
33
public class ContainerResizeParameters // (main.ContainerResizeParameters)
44
{
5-
[QueryStringParameter("h", false)]
6-
public long? Height { get; set; }
5+
[QueryStringParameter("h", true)]
6+
public long Height { get; set; }
77

8-
[QueryStringParameter("w", false)]
9-
public long? Width { get; set; }
8+
[QueryStringParameter("w", true)]
9+
public long Width { get; set; }
1010
}
1111
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
namespace Docker.DotNet.Tests;
2+
3+
[Collection(nameof(TestCollection))]
4+
public class IExecOperationsTests
5+
{
6+
private readonly TestFixture _testFixture;
7+
private readonly ITestOutputHelper _testOutputHelper;
8+
9+
public IExecOperationsTests(TestFixture testFixture, ITestOutputHelper testOutputHelper)
10+
{
11+
_testFixture = testFixture;
12+
_testOutputHelper = testOutputHelper;
13+
}
14+
15+
[Fact]
16+
public async Task ResizeExecTtyAsync_RunningExec_Succeeds()
17+
{
18+
// Given: a running container with a TTY exec session
19+
var createContainerResponse = await _testFixture.DockerClient.Containers.CreateContainerAsync(
20+
new CreateContainerParameters
21+
{
22+
Image = _testFixture.Image.ID,
23+
Entrypoint = CommonCommands.SleepInfinity
24+
},
25+
_testFixture.Cts.Token
26+
);
27+
28+
await _testFixture.DockerClient.Containers.StartContainerAsync(
29+
createContainerResponse.ID,
30+
new ContainerStartParameters(),
31+
_testFixture.Cts.Token
32+
);
33+
34+
var execCreateResponse = await _testFixture.DockerClient.Exec.CreateContainerExecAsync(
35+
createContainerResponse.ID,
36+
new ContainerExecCreateParameters
37+
{
38+
AttachStdout = true,
39+
AttachStderr = true,
40+
AttachStdin = true,
41+
TTY = true,
42+
Cmd = ["/bin/sh"]
43+
},
44+
_testFixture.Cts.Token
45+
);
46+
47+
// Start the exec to make it running (resize only works on a running exec)
48+
using var stream = await _testFixture.DockerClient.Exec.StartContainerExecAsync(
49+
execCreateResponse.ID,
50+
new ContainerExecStartParameters
51+
{
52+
TTY = true
53+
},
54+
_testFixture.Cts.Token
55+
);
56+
57+
// When: resize the exec TTY
58+
await _testFixture.DockerClient.Exec.ResizeExecTtyAsync(
59+
execCreateResponse.ID,
60+
new ContainerResizeParameters
61+
{
62+
Height = 48,
63+
Width = 80
64+
},
65+
_testFixture.Cts.Token
66+
);
67+
68+
// Then: no exception means success
69+
_testOutputHelper.WriteLine("ResizeExecTtyAsync succeeded for running exec session.");
70+
71+
// Verify exec is still running
72+
var execInspect = await _testFixture.DockerClient.Exec.InspectContainerExecAsync(
73+
execCreateResponse.ID,
74+
_testFixture.Cts.Token
75+
);
76+
77+
Assert.True(execInspect.Running);
78+
}
79+
80+
[Fact]
81+
public async Task ResizeExecTtyAsync_NonExistentExecId_ThrowsException()
82+
{
83+
await Assert.ThrowsAsync<DockerContainerNotFoundException>(
84+
() => _testFixture.DockerClient.Exec.ResizeExecTtyAsync(
85+
Guid.NewGuid().ToString("N"),
86+
new ContainerResizeParameters
87+
{
88+
Height = 24,
89+
Width = 80
90+
},
91+
_testFixture.Cts.Token
92+
)
93+
);
94+
}
95+
}

tools/specgen/modeldefs.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ type ContainerRenameParameters struct {
132132

133133
// ContainerResizeParameters for POST /containers/(id)/resize
134134
type ContainerResizeParameters struct {
135-
Height int `rest:"query,h"`
136-
Width int `rest:"query,w"`
135+
Height int `rest:"query,h,required"`
136+
Width int `rest:"query,w,required"`
137137
}
138138

139139
// ContainerRestartParameters for POST /containers/(id)/restart

0 commit comments

Comments
 (0)