public async Task <IActionResult> Index(string uuid, NewProjectViewModel newPorject) { if (uuid == "New") { if (newPorject == null) { return(BadRequest()); } if (!ModelState.IsValid) { return(View("New", newPorject)); } var version = _context.MinecraftVersions .Include(v => v.ForgeVersions) .Where(v => v.Id == newPorject.MinecraftVersionId) .SelectMany(v => v.ForgeVersions, (mv, fv) => CreateVersionTuple(mv, fv)) .FirstOrDefault(v => v.forgeVersion.Id == newPorject.ForgeVersionId); if (version.minecraftVersion == null || version.forgeVersion == null) { return(BadRequest()); } // Check valid zip is exists var forgeZipFile = _storageSetting.GetForgeStorageSetting().GetForgeZipFile(version.minecraftVersion, version.forgeVersion); if (!forgeZipFile.Exists) { return(StatusCode(StatusCodes.Status500InternalServerError, "Specified template of Minecraft and Forge version is not found.")); } try { var safeUser = await _context.SafeUsers .SingleOrDefaultAsync(m => m.Id == _userManager.GetUserId(HttpContext.User)); var now = DateTime.UtcNow; var accessRight = await _context.AccessRights.AddAsync(new AccessRight { User = safeUser, Level = AccessRightLevel.Owner.Level }); var createdProject = await _context.Projects.AddAsync(new Project { Name = newPorject.Name, Description = newPorject.Description, MinecraftVersion = version.minecraftVersion, ForgeVersion = version.forgeVersion, CreatedAt = now, UpdatedAt = now, AccessRights = new List <AccessRight> { accessRight.Entity } }); await _context.SaveChangesAsync(); // Expand zip file var projectId = createdProject.Entity.Id; var targetDir = _storageSetting.GetProjectStorageSetting().GetRootDirectory().ResolveDir(projectId); ZipFile.ExtractToDirectory(forgeZipFile.FullName, targetDir.FullName); return(RedirectToAction(nameof(Index), "Projects", new RouteValueDictionary { { "uuid", projectId } })); } catch (Exception e) { _logger.LogError(e, "An error occurred in creating new project."); return(StatusCode(StatusCodes.Status500InternalServerError, "An internal error occurred.")); } } return(NotFound()); }
private async Task StartBuildInternal(Project project, string userId, int buildId) { var destination = new DirectoryInfo(Path.GetTempPath()).ResolveDir("portal_artifact").ResolveDir(project.Id).ResolveDir(buildId.ToString()); if (!destination.Exists) { destination.Create(); } _logger.LogInformation("Creating container..."); var repo = _dockerSetting.ImageName; var tag = $"mc-{project.MinecraftVersion.Version}-{project.MinecraftVersion.DockerImageVersion}"; var container = await _client.Containers.CreateContainerAsync(new CreateContainerParameters { //Name = "portal-build-daemon", Image = $"{repo}:{tag}", HostConfig = new HostConfig { Binds = new List <string> { $"{_storageSetting.GetProjectStorageSetting().GetRootDirectory().ResolveDir(project.Id).FullName}:{_dockerSetting.SourceDir}:ro", $"{destination.FullName}:{_dockerSetting.BuildDir}:rw" } }, AttachStdout = true, AttachStderr = true, Tty = true }); var buffer = new byte[_dockerSetting.OutputBufferSize]; using (var stream = await _client.Containers.AttachContainerAsync(container.ID, true, new ContainerAttachParameters { Stdout = true, Stderr = true, Stream = true })) { await _client.Containers.StartContainerAsync(container.ID, new ContainerStartParameters()); ReadResult result; do { result = await stream.ReadOutputAsync(buffer, 0, buffer.Length, default(CancellationToken)); var text = Encoding.UTF8.GetString(buffer, 0, result.Count); Console.Write(result.Target + text); _connectionManager.SendMessage(project.Id, userId, text); } while (!result.EOF); } _logger.LogInformation("Build finished. Removing container..."); await _client.Containers.RemoveContainerAsync(container.ID, new ContainerRemoveParameters()); _logger.LogInformation("Container removed."); var artifactFile = Util.FindBuildArtifact(destination); if (artifactFile == null) { _logger.LogWarning($"Artifact file not found. ( project: {project.Id}, buildId: {buildId})"); return; } await _storageSetting.GetArtifactStorageSetting().AfterBuildAsync(project.Id, artifactFile, buildId); if (_dockerSetting.DeleteTempAfterBuild) { destination.Delete(true); } }