From 964e61f0461a526b54e33dcaeee0a8e1f1f54cb2 Mon Sep 17 00:00:00 2001 From: GZTime Date: Mon, 12 Sep 2022 19:14:58 +0800 Subject: [PATCH] fix: docker service --- GZCTF/Controllers/EditController.cs | 6 ++++ GZCTF/Services/DockerService.cs | 44 +++++++++++++++-------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/GZCTF/Controllers/EditController.cs b/GZCTF/Controllers/EditController.cs index a056b98c2..2b68377e0 100644 --- a/GZCTF/Controllers/EditController.cs +++ b/GZCTF/Controllers/EditController.cs @@ -1,5 +1,6 @@ using CTFServer.Extensions; using CTFServer.Middlewares; +using CTFServer.Models; using CTFServer.Models.Request.Edit; using CTFServer.Models.Request.Game; using CTFServer.Models.Request.Info; @@ -23,6 +24,7 @@ namespace CTFServer.Controllers; [ProducesResponseType(typeof(RequestResponse), StatusCodes.Status403Forbidden)] public class EditController : Controller { + private readonly ILogger logger; private readonly UserManager userManager; private readonly IPostRepository postRepository; private readonly IGameNoticeRepository gameNoticeRepository; @@ -33,6 +35,7 @@ public class EditController : Controller private readonly IContainerRepository containerRepository; public EditController(UserManager _userManager, + ILogger _logger, IPostRepository _postRepository, IContainerRepository _containerRepository, IChallengeRepository _challengeRepository, @@ -41,6 +44,7 @@ public EditController(UserManager _userManager, IContainerService _containerService, IFileRepository _fileService) { + logger = _logger; fileService = _fileService; userManager = _userManager; gameRepository = _gameRepository; @@ -582,6 +586,8 @@ public async Task CreateTestContainer([FromRoute] int id, [FromRo challenge.TestContainer = container; await challengeRepository.SaveAsync(token); + logger.Log($"成功创建测试容器 {container.ContainerId}", user, TaskStatus.Success); + return Ok(ContainerInfoModel.FromContainer(container)); } diff --git a/GZCTF/Services/DockerService.cs b/GZCTF/Services/DockerService.cs index ec0f9c782..b85acf495 100644 --- a/GZCTF/Services/DockerService.cs +++ b/GZCTF/Services/DockerService.cs @@ -24,8 +24,6 @@ public DockerService(IOptions _options, IOptions _ DockerClientConfiguration cfg = string.IsNullOrEmpty(this.options.Uri) ? new() : new(new Uri(this.options.Uri)); // TODO: Docker Auth Required - // TODO: Docker Swarm Support - dockerClient = cfg.CreateClient(); // Auth for registry @@ -72,7 +70,7 @@ public async Task DestroyContainer(Container container, CancellationToken token } catch (Exception e) { - logger.LogError(e, "删除容器失败"); + logger.LogError(e, $"容器 {container.ContainerId} 删除失败"); return; } @@ -164,7 +162,7 @@ private ServiceCreateParameters GetServiceCreateParameters(ContainerConfig confi } catch (Exception e) { - logger.LogError(e.Message, e); + logger.LogError(e, $"容器 {parameters.Service.Name} 删除失败"); return null; } @@ -174,13 +172,20 @@ private ServiceCreateParameters GetServiceCreateParameters(ContainerConfig confi Image = config.Image, }; - var res = await dockerClient.Swarm.InspectServiceAsync(serviceRes.ID, token); - - if (res?.Endpoint?.Ports is null || res.Endpoint.Ports.Count == 0) + retry = 0; + SwarmService? res; + do { - logger.SystemLog($"容器 {parameters.Service.Name} 创建后未获取到端口暴露信息,这可能是意料外的行为", TaskStatus.Fail, LogLevel.Warning); - return null; - } + res = await dockerClient.Swarm.InspectServiceAsync(serviceRes.ID, token); + retry++; + if (retry == 3) + { + logger.SystemLog($"容器 {parameters.Service.Name} 创建后未获取到端口暴露信息,创建失败", TaskStatus.Fail, LogLevel.Warning); + return null; + } + if (res is not { Endpoint.Ports.Count: > 0 }) + await Task.Delay(500, token); + } while (res is not { Endpoint.Ports.Count: > 0 }); var port = res.Endpoint.Ports.First(); @@ -222,17 +227,14 @@ await dockerClient.Images.CreateImageAsync(new() return null; } - if (containerRes is null) + try { - try - { - containerRes = await dockerClient.Containers.CreateContainerAsync(parameters, token); - } - catch (Exception e) - { - logger.LogError(e.Message, e); - return null; - } + containerRes ??= await dockerClient.Containers.CreateContainerAsync(parameters, token); + } + catch (Exception e) + { + logger.LogError(e.Message, e); + return null; } Container container = new() @@ -250,7 +252,7 @@ await dockerClient.Images.CreateImageAsync(new() retry++; if (retry == 3) { - logger.SystemLog($"启动容器实例 {container.Id[..12]} ({config.Image.Split("/").LastOrDefault()}) 失败", TaskStatus.Fail, LogLevel.Warning); + logger.SystemLog($"启动容器实例 {container.Id} ({config.Image.Split("/").LastOrDefault()}) 失败", TaskStatus.Fail, LogLevel.Warning); return null; } if (!started)