public async Task <IActionResult> Rerun(long?id, [FromBody] RerunInputModel model, [FromServices] INodeRepository nodeRepository) { //データの入力チェック if (!ModelState.IsValid) { return(JsonBadRequest("Invalid inputs.")); } //データの存在チェック var notebookHistory = await notebookHistoryRepository.GetIncludeAllAsync(id.Value); if (notebookHistory == null) { return(JsonNotFound($"Notebook ID {id} is not found.")); } //ステータスのチェック if (notebookHistory.GetStatus().Exist()) { return(JsonNotFound($"Notebook ID {id} is already running.")); } //データセットが指定されていれば存在チェック if (model.DataSetId.HasValue) { var dataSet = await dataSetRepository.GetByIdAsync(model.DataSetId.Value); if (dataSet == null) { return(JsonNotFound($"DataSet ID {model.DataSetId} is not found.")); } } if (string.IsNullOrEmpty(notebookHistory.Partition) == false) { bool existPartition = await nodeRepository.IsEnablePartitionAsync(notebookHistory.Partition, true); if (existPartition == false) { return(JsonNotFound($"There are no enable nodes with Partition {notebookHistory.Partition}.")); } } if (notebookHistory.ModelGitId != null) { //gitリポジトリ名が指定されていれば、ブランチ、コミットIDを設定。指定されていなければnull long? gitId = notebookHistory.ModelGitId ?? CurrentUserInfo.SelectedTenant.DefaultGit?.Id; string branch = null; string commitId = null; if (!string.IsNullOrEmpty(notebookHistory.ModelRepository)) { branch = notebookHistory.ModelBranch ?? "master"; commitId = notebookHistory.ModelCommitId; //コミットIDが指定されていなければ、ブランチのHEADからコミットIDを取得する if (string.IsNullOrEmpty(commitId)) { commitId = await gitLogic.GetCommitIdAsync(gitId.Value, notebookHistory.ModelRepository, notebookHistory.ModelRepositoryOwner, branch); if (string.IsNullOrEmpty(commitId)) { //コミットIDが特定できなかったらエラー return(JsonNotFound($"The branch {branch} for {gitId.Value}/{notebookHistory.ModelRepositoryOwner}/{notebookHistory.ModelRepository} is not found.")); } } } } // 現状のノートブック履歴IDに紐づいている親学習をすべて外す。 notebookHistoryRepository.DetachParentToNotebookAsync(notebookHistory); // 親学習が指定されていれば存在チェック if (model.ParentIds != null) { var maps = new List <NotebookHistoryParentTrainingMap>(); foreach (var parentId in model.ParentIds) { var parent = await trainingHistoryRepository.GetByIdAsync(parentId); if (parent == null) { return(JsonNotFound($"Training ID {parentId} is not found.")); } // ノートブック履歴に親学習を紐づける var map = notebookHistoryRepository.AttachParentToNotebookAsync(notebookHistory, parent); if (map != null) { maps.Add(map); } } notebookHistory.ParentTrainingMaps = maps; } //コンテナの実行前に、ノートブック履歴を更新する(コンテナの実行に失敗した場合、そのステータスをユーザに表示するため) notebookHistory.DataSetId = model.DataSetId; notebookHistory.Cpu = model.Cpu.Value; notebookHistory.Memory = model.Memory.Value; notebookHistory.Gpu = model.Gpu.Value; notebookHistory.Status = ContainerStatus.Running.Key; notebookHistory.StartedAt = DateTime.Now; notebookHistory.CompletedAt = null; notebookHistory.ExpiresIn = model.ExpiresIn; notebookHistoryRepository.Update(notebookHistory); unitOfWork.Commit(); var result = await clusterManagementLogic.RunNotebookContainerAsync(notebookHistory); // TODO:暫定的に親学習はnull if (result.IsSuccess == false) { //コンテナの起動に失敗した状態。エラーを出力して、保存したノートブック履歴も削除する。 notebookHistory.Status = ContainerStatus.Killed.Key; notebookHistory.CompletedAt = DateTime.Now; notebookHistoryRepository.Update(notebookHistory); unitOfWork.Commit(); return(JsonError(HttpStatusCode.ServiceUnavailable, "Failed to run notebook. The message bellow may be help to resolve: " + result.Error)); } //結果に従い、ノートブック結果を更新する。 //実行には時間がかかりうるので、DBから最新の情報を取ってくる notebookHistory = await notebookHistoryRepository.GetByIdAsync(notebookHistory.Id); notebookHistory.Configuration = result.Value.Configuration; notebookHistory.Status = result.Value.Status.Key; unitOfWork.Commit(); if (result.Value.Status.Succeed()) { return(JsonCreated(new SimpleOutputModel(notebookHistory))); } else { return(JsonError(HttpStatusCode.ServiceUnavailable, $"Failed to run notebook. Status={result.Value.Status.Name}. Please contact your server administrator.")); } }
public async Task <IActionResult> Rerun(long?id, [FromBody] RerunInputModel model) { // データの入力チェック if (!ModelState.IsValid) { return(JsonBadRequest("Invalid inputs.")); } // データの存在チェック var notebookHistory = await notebookHistoryRepository.GetIncludeAllAsync(id.Value); if (notebookHistory == null) { return(JsonNotFound($"Notebook ID {id} is not found.")); } // ステータスのチェック if (notebookHistory.GetStatus().Exist()) { return(JsonNotFound($"Notebook ID {id} is already running.")); } // データセットが指定されていれば存在チェック if (model.DataSetId.HasValue) { var dataSet = await dataSetRepository.GetByIdAsync(model.DataSetId.Value); if (dataSet == null) { return(JsonNotFound($"DataSet ID {model.DataSetId} is not found.")); } } // ノートブック無期限フラグのチェック Tenant tenant = tenantRepository.Get(CurrentUserInfo.SelectedTenant.Id); if (tenant.AvailableInfiniteTimeNotebook == false && model.ExpiresIn == 0) { return(JsonBadRequest($"Tenant [{tenant.DisplayName}] is not allowed to run infinite time.")); } if (string.IsNullOrEmpty(notebookHistory.Partition) == false) { bool existPartition = await nodeRepository.IsEnablePartitionAsync(notebookHistory.Partition, true); if (existPartition == false) { return(JsonNotFound($"There are no enable nodes with Partition {notebookHistory.Partition}.")); } } // コンテナが指定されているかチェック if (model.ContainerImage != null) { notebookHistory.ContainerRegistryId = model.ContainerImage.RegistryId ?? CurrentUserInfo.SelectedTenant.DefaultRegistry?.Id; notebookHistory.ContainerImage = model.ContainerImage.Image; notebookHistory.ContainerTag = model.ContainerImage.Tag; // latestは運用上使用されていないハズなので、そのまま直接代入 } else { // コンテナイメージの設定がない場合デフォルトのイメージを設定 notebookHistory.ContainerRegistryId = null; notebookHistory.ContainerImage = "kamonohashi/jupyterlab"; notebookHistory.ContainerTag = "tensorflow-2.2.0"; } // gitが指定されているかチェック if (model.GitModel != null) { // gitリポジトリ名が指定されていれば、ブランチ、コミットIDを設定。指定されていなければnull long? gitId = model.GitModel.GitId ?? CurrentUserInfo.SelectedTenant.DefaultGit?.Id; string branch = null; string commitId = null; if (!string.IsNullOrEmpty(model.GitModel.Repository)) { branch = model.GitModel.Branch ?? "master"; commitId = model.GitModel.CommitId; // コミットIDが指定されていなければ、ブランチのHEADからコミットIDを取得する if (string.IsNullOrEmpty(commitId)) { commitId = await gitLogic.GetCommitIdAsync(gitId.Value, model.GitModel.Repository, model.GitModel.Owner, branch); if (string.IsNullOrEmpty(commitId)) { // コミットIDが特定できなかったらエラー return(JsonNotFound($"The branch {branch} for {gitId.Value}/{model.GitModel.Owner}/{model.GitModel.Repository} is not found.")); } } } // git情報を設定 notebookHistory.ModelGitId = gitId.Value; notebookHistory.ModelRepository = model.GitModel.Repository; notebookHistory.ModelRepositoryOwner = model.GitModel.Owner; notebookHistory.ModelBranch = branch; notebookHistory.ModelCommitId = commitId; } else { // gitが未指定の場合は各項目にnullを設定する notebookHistory.ModelGitId = null; notebookHistory.ModelRepository = null; notebookHistory.ModelRepositoryOwner = null; notebookHistory.ModelBranch = null; notebookHistory.ModelCommitId = null; } // JupyterLabのバージョンが指定されているかチェック if (string.IsNullOrEmpty(model.JupyterLabVersion)) { // null または 空文字 の場合はデフォルトのバージョンを指定 notebookHistory.JupyterLabVersion = "2.3.1"; } else { notebookHistory.JupyterLabVersion = model.JupyterLabVersion; } // 各リソースの超過チェック string errorMessage = clusterManagementLogic.CheckQuota(tenant, model.Cpu.Value, model.Memory.Value, model.Gpu.Value); if (errorMessage != null) { return(JsonBadRequest(errorMessage)); } // 現状のノートブック履歴IDに紐づいている親学習をすべて外す。 notebookHistoryRepository.DetachParentToNotebookAsync(notebookHistory); // 親学習が指定されていれば存在チェック if (model.ParentIds != null) { var maps = new List <NotebookHistoryParentTrainingMap>(); foreach (var parentId in model.ParentIds) { var parent = await trainingHistoryRepository.GetByIdAsync(parentId); if (parent == null) { return(JsonNotFound($"Training ID {parentId} is not found.")); } // ノートブック履歴に親学習を紐づける var map = notebookHistoryRepository.AttachParentToNotebookAsync(notebookHistory, parent); if (map != null) { maps.Add(map); } } notebookHistory.ParentTrainingMaps = maps; } // 現状のノートブック履歴IDに紐づいている親推論をすべて外す。 notebookHistoryRepository.DetachParentInferenceToNotebookAsync(notebookHistory); // 親推論が指定されていれば存在チェック if (model.InferenceIds != null) { var maps = new List <NotebookHistoryParentInferenceMap>(); foreach (var parentId in model.InferenceIds) { var parenInferencet = await inferenceHistoryRepository.GetByIdAsync(parentId); if (parenInferencet == null) { return(JsonNotFound($"Inference ID {parentId} is not found.")); } // ノートブック履歴に親学習を紐づける var map = notebookHistoryRepository.AttachParentInferenceToNotebookAsync(notebookHistory, parenInferencet); if (map != null) { maps.Add(map); } } notebookHistory.ParentInferenceMaps = maps; } // コンテナの実行前に、ノートブック履歴を更新する(コンテナの実行に失敗した場合、そのステータスをユーザに表示するため) notebookHistory.DataSetId = model.DataSetId; notebookHistory.Cpu = model.Cpu.Value; notebookHistory.Memory = model.Memory.Value; notebookHistory.Gpu = model.Gpu.Value; notebookHistory.Status = ContainerStatus.Running.Key; notebookHistory.StartedAt = DateTime.Now; notebookHistory.CompletedAt = null; notebookHistory.ExpiresIn = model.ExpiresIn; notebookHistory.LocalDataSet = model.LocalDataSet; notebookHistory.EntryPoint = model.EntryPoint; notebookHistoryRepository.Update(notebookHistory); unitOfWork.Commit(); var result = await clusterManagementLogic.RunNotebookContainerAsync(notebookHistory); if (result.IsSuccess == false) { // コンテナの起動に失敗した状態。エラーを出力して、保存したノートブック履歴も削除する。 notebookHistory.Status = ContainerStatus.Killed.Key; notebookHistory.CompletedAt = DateTime.Now; notebookHistoryRepository.Update(notebookHistory); unitOfWork.Commit(); return(JsonError(HttpStatusCode.ServiceUnavailable, "Failed to run notebook. The message bellow may be help to resolve: " + result.Error)); } // 結果に従い、ノートブック結果を更新する。 // 実行には時間がかかりうるので、DBから最新の情報を取ってくる notebookHistory = await notebookHistoryRepository.GetByIdAsync(notebookHistory.Id); notebookHistory.Configuration = result.Value.Configuration; notebookHistory.Status = result.Value.Status.Key; unitOfWork.Commit(); if (result.Value.Status.Succeed()) { return(JsonCreated(new SimpleOutputModel(notebookHistory))); } else { return(JsonError(HttpStatusCode.ServiceUnavailable, $"Failed to run notebook. Status={result.Value.Status.Name}. Please contact your server administrator.")); } }