Skip to content

Commit 1c3a067

Browse files
ACoderLifeRelatedItemSearchUserHofmeisterAn
authored
Add client support for Swarm Logs and Swarm Config (#589)
* expose Swam Config as client.Configs * Expose Swam Service Logs * send SwarmConfigSpec to api * Update src/Docker.DotNet/Endpoints/ISwarmOperations.cs Co-authored-by: Andre Hofmeister <[email protected]> * Update src/Docker.DotNet/Endpoints/ISwarmOperations.cs Co-authored-by: Andre Hofmeister <[email protected]> * rename to standard add logging test * add logging test fix naming convention * Update src/Docker.DotNet/Endpoints/IConfigsOperations.cs Co-authored-by: Andre Hofmeister <[email protected]> * Update src/Docker.DotNet/Endpoints/IConfigsOperations.cs Co-authored-by: Andre Hofmeister <[email protected]> * Update src/Docker.DotNet/Endpoints/ConfigsOperations.cs Co-authored-by: Andre Hofmeister <[email protected]> * Add Config Tests, some Renaming fixes * updated test with retry and increased buffer. Improved cancelation handling. --------- Co-authored-by: Jasim Schluter <[email protected]> Co-authored-by: Andre Hofmeister <[email protected]>
1 parent 3ca9743 commit 1c3a067

File tree

9 files changed

+745
-381
lines changed

9 files changed

+745
-381
lines changed

.gitattributes

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
# Autodetect text files
22
* text=auto
33

4-
# Definitively text files
5-
*.cs text

src/Docker.DotNet/DockerClient.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ internal DockerClient(DockerClientConfiguration configuration, Version requested
3939
System = new SystemOperations(this);
4040
Networks = new NetworkOperations(this);
4141
Secrets = new SecretsOperations(this);
42+
Configs = new ConfigOperations(this);
4243
Swarm = new SwarmOperations(this);
4344
Tasks = new TasksOperations(this);
4445
Volumes = new VolumeOperations(this);
@@ -136,6 +137,8 @@ await sock.ConnectAsync(new Microsoft.Net.Http.Client.UnixDomainSocketEndPoint(p
136137

137138
public ISecretsOperations Secrets { get; }
138139

140+
public IConfigOperations Configs { get; }
141+
139142
public ISwarmOperations Swarm { get; }
140143

141144
public ITasksOperations Tasks { get; }
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Net.Http;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Docker.DotNet.Models;
7+
8+
namespace Docker.DotNet
9+
{
10+
internal class ConfigOperations : IConfigOperations
11+
{
12+
private readonly DockerClient _client;
13+
14+
internal ConfigOperations(DockerClient client)
15+
{
16+
this._client = client;
17+
}
18+
19+
async Task<IList<SwarmConfig>> IConfigOperations.ListConfigsAsync(CancellationToken cancellationToken)
20+
{
21+
var response = await this._client.MakeRequestAsync(this._client.NoErrorHandlers, HttpMethod.Get, "configs", cancellationToken).ConfigureAwait(false);
22+
return this._client.JsonSerializer.DeserializeObject<IList<SwarmConfig>>(response.Body);
23+
}
24+
25+
async Task<SwarmCreateConfigResponse> IConfigOperations.CreateConfigAsync(SwarmCreateConfigParameters body, CancellationToken cancellationToken)
26+
{
27+
if (body == null)
28+
{
29+
throw new ArgumentNullException(nameof(body));
30+
}
31+
32+
var data = new JsonRequestContent<SwarmConfigSpec>(body.Config, this._client.JsonSerializer);
33+
var response = await this._client.MakeRequestAsync(this._client.NoErrorHandlers, HttpMethod.Post, "configs/create", null, data, cancellationToken).ConfigureAwait(false);
34+
return this._client.JsonSerializer.DeserializeObject<SwarmCreateConfigResponse>(response.Body);
35+
}
36+
37+
async Task<SwarmConfig> IConfigOperations.InspectConfigAsync(string id, CancellationToken cancellationToken)
38+
{
39+
if (string.IsNullOrEmpty(id))
40+
{
41+
throw new ArgumentNullException(nameof(id));
42+
}
43+
44+
var response = await this._client.MakeRequestAsync(this._client.NoErrorHandlers, HttpMethod.Get, $"configs/{id}", cancellationToken).ConfigureAwait(false);
45+
return this._client.JsonSerializer.DeserializeObject<SwarmConfig>(response.Body);
46+
}
47+
48+
Task IConfigOperations.RemoveConfigAsync(string id, CancellationToken cancellationToken)
49+
{
50+
if (string.IsNullOrEmpty(id))
51+
{
52+
throw new ArgumentNullException(nameof(id));
53+
}
54+
55+
return this._client.MakeRequestAsync(this._client.NoErrorHandlers, HttpMethod.Delete, $"configs/{id}", cancellationToken);
56+
}
57+
}
58+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System.Collections.Generic;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using Docker.DotNet.Models;
5+
6+
namespace Docker.DotNet
7+
{
8+
public interface IConfigOperations
9+
{
10+
/// <summary>
11+
/// List configs
12+
/// </summary>
13+
/// <remarks>
14+
/// 200 - No error.
15+
/// 500 - Server error.
16+
/// </remarks>
17+
Task<IList<SwarmConfig>> ListConfigsAsync(CancellationToken cancellationToken = default(CancellationToken));
18+
19+
/// <summary>
20+
/// Create a configs
21+
/// </summary>
22+
/// <remarks>
23+
/// 201 - No error.
24+
/// 406 - Server error or node is not part of a swarm.
25+
/// 409 - Name conflicts with an existing object.
26+
/// 500 - Server error.
27+
/// </remarks>
28+
Task<SwarmCreateConfigResponse> CreateConfigAsync(SwarmCreateConfigParameters body, CancellationToken cancellationToken = default(CancellationToken));
29+
30+
/// <summary>
31+
/// Inspect a configs
32+
/// </summary>
33+
/// <remarks>
34+
/// 200 - No error.
35+
/// 404 - Secret not found.
36+
/// 406 - Node is not part of a swarm.
37+
/// 500 - Server error.
38+
/// </remarks>
39+
/// <param name="id">ID of the config.</param>
40+
Task<SwarmConfig> InspectConfigAsync(string id, CancellationToken cancellationToken = default(CancellationToken));
41+
42+
/// <summary>
43+
/// Remove a configs
44+
/// </summary>
45+
/// <remarks>
46+
/// 204 - No error.
47+
/// 404 - Secret not found.
48+
/// 500 - Server error.
49+
/// </remarks>
50+
/// <param name="id">ID of the config.</param>
51+
Task RemoveConfigAsync(string id, CancellationToken cancellationToken = default(CancellationToken));
52+
}
53+
}

src/Docker.DotNet/Endpoints/ISwarmOperations.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Threading.Tasks;
33
using Docker.DotNet.Models;
44
using System.Threading;
5+
using System.IO;
56

67
namespace Docker.DotNet
78
{
@@ -154,6 +155,42 @@ public interface ISwarmOperations
154155
/// <param name="id">ID or name of service.</param>
155156
Task RemoveServiceAsync(string id, CancellationToken cancellationToken = default(CancellationToken));
156157

158+
/// <summary>
159+
/// Gets <c>stdout</c> and <c>stderr</c> logs from services.
160+
/// </summary>
161+
/// <param name="id">The ID or name of the service.</param>
162+
/// <param name="parameters">Specifics of how to perform the operation.</param>
163+
/// <param name="cancellationToken">When triggered, the operation will stop at the next available time, if possible.</param>
164+
/// <returns>A <see cref="Task"/> that will complete once all log lines have been read.</returns>
165+
/// <remarks>
166+
/// This method is only suited for services with the <c>json-file</c> or <c>journald</c> logging driver.
167+
///
168+
/// HTTP GET /services/(id)/logs
169+
///
170+
/// 101 - Logs returned as a stream.
171+
/// 200 - Logs returned as a string in response body.
172+
/// 404 - No such service.
173+
/// 500 - Server error.
174+
/// 503 - Node is not part of a swarm.
175+
/// </remarks>
176+
Task<Stream> GetServiceLogsAsync(string id, ServiceLogsParameters parameters, CancellationToken cancellationToken = default(CancellationToken));
177+
178+
/// <summary>
179+
/// Gets <c>stdout</c> and <c>stderr</c> logs from services.
180+
/// </summary>
181+
/// <param name="id">The ID or name of the service.</param>
182+
/// <param name="tty">Indicates whether the service was created with a TTY. If <see langword="false"/>, the returned stream is multiplexed.</param>
183+
/// <param name="parameters">Specifics of how to perform the operation.</param>
184+
/// <param name="cancellationToken">When triggered, the operation will stop at the next available time, if possible.</param>
185+
/// <returns>
186+
/// A <see cref="Task{TResult}"/> that resolves to a <see cref="MultiplexedStream"/>, which provides the log information.
187+
/// If the service wasn't created with a TTY, this stream is multiplexed.
188+
/// </returns>
189+
/// <remarks>
190+
/// This method is only suited for services with the <c>json-file</c> or <c>journald</c> logging driver.
191+
/// </remarks>
192+
Task<MultiplexedStream> GetServiceLogsAsync(string id, bool tty, ServiceLogsParameters parameters, CancellationToken cancellationToken = default(CancellationToken));
193+
157194
#endregion Services
158195

159196
#region Nodes

0 commit comments

Comments
 (0)