Beispiel #1
0
        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());
        }
Beispiel #2
0
        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);
            }
        }