Example #1
0
 /// <summary>
 /// コンストラクタ
 /// </summary>
 public TrainingController(
     ITrainingHistoryRepository trainingHistoryRepository,
     IInferenceHistoryRepository inferenceHistoryRepository,
     ITensorBoardContainerRepository tensorBoardContainerRepository,
     IDataSetRepository dataSetRepository,
     ITagRepository tagRepository,
     ITenantRepository tenantRepository,
     INodeRepository nodeRepository,
     ITagLogic tagLogic,
     ITrainingLogic trainingLogic,
     IStorageLogic storageLogic,
     IGitLogic gitLogic,
     IClusterManagementLogic clusterManagementLogic,
     IOptions <ContainerManageOptions> containerOptions,
     IUnitOfWork unitOfWork,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.trainingHistoryRepository      = trainingHistoryRepository;
     this.inferenceHistoryRepository     = inferenceHistoryRepository;
     this.tensorBoardContainerRepository = tensorBoardContainerRepository;
     this.dataSetRepository      = dataSetRepository;
     this.tagRepository          = tagRepository;
     this.tenantRepository       = tenantRepository;
     this.nodeRepository         = nodeRepository;
     this.tagLogic               = tagLogic;
     this.trainingLogic          = trainingLogic;
     this.storageLogic           = storageLogic;
     this.gitLogic               = gitLogic;
     this.clusterManagementLogic = clusterManagementLogic;
     this.containerOptions       = containerOptions.Value;
     this.unitOfWork             = unitOfWork;
 }
        public async Task <IActionResult> UploadPreprocessImage([FromRoute] long id, [FromRoute] long dataId,
                                                                [FromServices] IClusterManagementLogic clusterManagementLogic)
        {
            var history = await preprocessHistoryRepository.GetPreprocessIncludeDataAndPreprocessAsync(id, dataId);

            if (history == null)
            {
                return(JsonNotFound($"Preprocessing History about Preprocess {id} to Data {dataId} is not found."));
            }

            var status = ContainerStatus.Convert(history.Status);

            if (status.Exist() == false)
            {
                return(JsonBadRequest($"A container for the preprocessing does not exist."));
            }

            var events = await clusterManagementLogic.GetEventsAsync(CurrentUserInfo.SelectedTenant, history.Name, false, true);

            if (events.IsSuccess == false)
            {
                return(JsonError(HttpStatusCode.ServiceUnavailable, $"Failed to get container events: {events.Error}"));
            }
            else
            {
                return(JsonOK(events.Value));
            }
        }
 /// <summary>
 /// コンストラクタ
 /// </summary>
 public InferenceController(
     ITrainingHistoryRepository trainingHistoryRepository,
     IInferenceHistoryRepository inferenceHistoryRepository,
     IDataSetRepository dataSetRepository,
     ITenantRepository tenantRepository,
     INodeRepository nodeRepository,
     IDataSetLogic dataSetLogic,
     IInferenceLogic inferenceLogic,
     IStorageLogic storageLogic,
     IGitLogic gitLogic,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.trainingHistoryRepository  = trainingHistoryRepository;
     this.inferenceHistoryRepository = inferenceHistoryRepository;
     this.dataSetRepository          = dataSetRepository;
     this.tenantRepository           = tenantRepository;
     this.nodeRepository             = nodeRepository;
     this.dataSetLogic           = dataSetLogic;
     this.inferenceLogic         = inferenceLogic;
     this.storageLogic           = storageLogic;
     this.gitLogic               = gitLogic;
     this.clusterManagementLogic = clusterManagementLogic;
     this.unitOfWork             = unitOfWork;
 }
 /// <summary>
 /// コンストラクタで各 DI オブジェクトを引数で受け取ります。
 /// </summary>
 public SyncClusterFromDBTimer(
     ITenantRepository tenantRepository,
     IRegistryRepository registryRepository,
     INodeRepository nodeRepository,
     IUnitOfWork unitOfWork,
     IClusterManagementService clusterManagementService,
     GitLabRegistryService gitLabRegistryService,
     DockerHubRegistryService dockerHubRegistryService,
     PrivateDockerRegistryService privateDockerRegistryService,
     NvidiaGPUCloudRegistryService nvidiaGPUCloudRegistryService,
     IClusterManagementLogic clusterManagementLogic,
     IStorageLogic storageLogic,
     IOptions <ContainerManageOptions> containerManageOptions,
     IOptions <SyncClusterFromDBOptions> SyncClusterFromDBOptions,
     ILogger <SyncClusterFromDBTimer> logger
     ) : base(logger, SyncClusterFromDBOptions.Value)
 {
     // 各 DI オブジェクトの設定
     this.tenantRepository              = tenantRepository;
     this.registryRepository            = registryRepository;
     this.nodeRepository                = nodeRepository;
     this.unitOfWork                    = unitOfWork;
     this.clusterManagementService      = clusterManagementService;
     this.gitLabRegistryService         = gitLabRegistryService;
     this.dockerHubRegistryService      = dockerHubRegistryService;
     this.privateDockerRegistryService  = privateDockerRegistryService;
     this.nvidiaGPUCloudRegistryService = nvidiaGPUCloudRegistryService;
     this.clusterManagementLogic        = clusterManagementLogic;
     this.storageLogic                  = storageLogic;
     this.containerManageOptions        = containerManageOptions.Value;
 }
Example #5
0
        public IActionResult EditRegistryToken([FromBody] RegistryCredentialInputModel model,
                                               [FromServices] IRegistryRepository registryRepository,
                                               [FromServices] IClusterManagementLogic clusterManagementLogic)
        {
            //入力値チェック
            if (!ModelState.IsValid)
            {
                return(JsonBadRequest("Invalid inputs."));
            }

            var tenantId = CurrentUserInfo.SelectedTenant.Id;

            //まずは今の情報を取得
            var userRegistryMap = registryRepository.GetUserTenantRegistryMap(CurrentUserInfo.Id, tenantId, model.Id);

            if (userRegistryMap == null)
            {
                //今の値がない場合、紐づけられていない情報を変更しようとしているとみなす。
                return(JsonBadRequest("Couldn't map the registry to the current user & tenant. Please contact a user administrator."));
            }

            //変更
            userRegistryMap.RegistryUserName = model.UserName;
            userRegistryMap.RegistryPassword = model.Password;

            //シークレットを登録する。
            clusterManagementLogic.RegistRegistryToTenantAsync(CurrentUserInfo.SelectedTenant.Name, userRegistryMap);

            unitOfWork.Commit();

            RegistryCredentialOutputModel result = new RegistryCredentialOutputModel(userRegistryMap);

            return(JsonOK(result));
        }
Example #6
0
 public ClusterController(
     ITensorBoardContainerRepository tensorBoardContainerRepository,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.tensorBoardContainerRepository = tensorBoardContainerRepository;
     this.clusterManagementLogic         = clusterManagementLogic;
     this.unitOfWork = unitOfWork;
 }
Example #7
0
 public NodeController(
     INodeRepository nodeRepository,
     IUnitOfWork unitOfWork,
     IClusterManagementLogic clusterManagementLogic,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.nodeRepository         = nodeRepository;
     this.unitOfWork             = unitOfWork;
     this.clusterManagementLogic = clusterManagementLogic;
 }
Example #8
0
 public InferenceLogic(
     IInferenceHistoryRepository inferenceHistoryRepository,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     ICommonDiLogic commonDiLogic) : base(commonDiLogic)
 {
     this.inferenceHistoryRepository = inferenceHistoryRepository;
     this.clusterManagementLogic     = clusterManagementLogic;
     this.unitOfWork = unitOfWork;
 }
Example #9
0
 public NotebookLogic(
     INotebookHistoryRepository notebookHistoryRepository,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     ICommonDiLogic commonDiLogic) : base(commonDiLogic)
 {
     this.notebookHistoryRepository = notebookHistoryRepository;
     this.clusterManagementLogic    = clusterManagementLogic;
     this.unitOfWork = unitOfWork;
 }
        public async Task <IActionResult> GetHistories([FromRoute] long?id, [FromServices] IClusterManagementLogic clusterManagementLogic)
        {
            if (id == null)
            {
                return(JsonBadRequest("Preprocessing ID is required."));
            }

            var preprocessingHistories = await preprocessHistoryRepository.GetPreprocessAllIncludeDataAndPreprocessAsync(id.Value);

            return(JsonOK(preprocessingHistories.ToList().Select(ph => GetUpdatedIndexOutputModelAsync(ph, new HistoriesOutputModel(ph), clusterManagementLogic).Result)));
        }
        public async Task <IActionResult> RunPreprocessHistory([FromRoute] long id, [FromBody] RunPreprocessHistoryInputModel model,
                                                               [FromServices] IDataRepository dataRepository,
                                                               [FromServices] IClusterManagementLogic clusterManagementLogic)
        {
            var validateResult = await ValidateCreatePreprocessHistoryInputModelAsync(id, model.DataId, dataRepository);

            if (validateResult.IsSuccess == false)
            {
                return(validateResult.Error);
            }
            PreprocessHistory preprocessHistory = validateResult.Value;

            preprocessHistory.Cpu       = model.Cpu;
            preprocessHistory.Memory    = model.Memory;
            preprocessHistory.Gpu       = model.Gpu;
            preprocessHistory.Partition = model.Partition;
            preprocessHistory.OptionDic = model.Options ?? new Dictionary <string, string>(); //オプションはnullの可能性があるので、その時は初期化
            if (preprocessHistory.OptionDic.ContainsKey(""))                                  //空文字は除外する
            {
                preprocessHistory.OptionDic.Remove("");
            }

            preprocessHistoryRepository.Add(preprocessHistory);
            unitOfWork.Commit();

            //入力データの詳細情報がないので、取得
            preprocessHistory.InputData = await dataRepository.GetDataIncludeAllAsync(preprocessHistory.InputDataId);

            var result = await clusterManagementLogic.RunPreprocessingContainerAsync(preprocessHistory);

            if (result.IsSuccess == false)
            {
                //コンテナの起動に失敗した状態。エラーを出力して、保存した学習履歴も削除する。
                preprocessHistoryRepository.Delete(preprocessHistory);

                return(JsonError(HttpStatusCode.ServiceUnavailable, "Failed to run preprocessing. The message bellow may be help to resolve: " + result.Error));
            }

            //結果に従い、学習結果を更新する。
            //実行には時間がかかりうるので、DBから最新の情報を取ってくる
            preprocessHistory = await preprocessHistoryRepository.GetByIdAsync(preprocessHistory.Id);

            preprocessHistory.Status = result.Value.Status.Key;
            unitOfWork.Commit();

            if (result.Value.Status.Succeed())
            {
                return(JsonCreated(new HistoriesOutputModel(preprocessHistory)));
            }
            else
            {
                return(JsonError(HttpStatusCode.ServiceUnavailable, $"Failed to run preprocessing. Status={result.Value.Status.Name}. Please contact your server administrator."));
            }
        }
Example #12
0
 public NodeController(
     INodeRepository nodeRepository,
     IUnitOfWork unitOfWork,
     IClusterManagementLogic clusterManagementLogic,
     IOptions <ContainerManageOptions> containerManageOptions,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.nodeRepository         = nodeRepository;
     this.unitOfWork             = unitOfWork;
     this.clusterManagementLogic = clusterManagementLogic;
     this.containerManageOptions = containerManageOptions.Value;
 }
Example #13
0
 public UserController(
     IUserRepository userRepository,
     IRoleRepository roleRepository,
     IUnitOfWork unitOfWork,
     IClusterManagementLogic clusterManagementLogic,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.userRepository         = userRepository;
     this.roleRepository         = roleRepository;
     this.unitOfWork             = unitOfWork;
     this.clusterManagementLogic = clusterManagementLogic;
 }
 public ResourceController(
     ITenantRepository tenantRepository,
     IUserRepository userRepository,
     ICommonDiLogic commonDiLogic,
     IClusterManagementLogic clusterManagementLogic,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.tenantRepository       = tenantRepository;
     this.userRepository         = userRepository;
     this.commonDiLogic          = commonDiLogic;
     this.clusterManagementLogic = clusterManagementLogic;
 }
Example #15
0
 /// <summary>
 /// コンストラクタ
 /// </summary>
 public PreprocessLogic(
     IPreprocessHistoryRepository preprocessHistoryRepository,
     IDataLogic dataLogic,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     ICommonDiLogic commonDiLogic) : base(commonDiLogic)
 {
     this.preprocessHistoryRepository = preprocessHistoryRepository;
     this.dataLogic = dataLogic;
     this.clusterManagementLogic = clusterManagementLogic;
     this.unitOfWork             = unitOfWork;
 }
Example #16
0
 public TrainingLogic(
     ITrainingHistoryRepository trainingHistoryRepository,
     ITensorBoardContainerRepository tensorBoardContainerRepository,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     ICommonDiLogic commonDiLogic) : base(commonDiLogic)
 {
     this.trainingHistoryRepository      = trainingHistoryRepository;
     this.tensorBoardContainerRepository = tensorBoardContainerRepository;
     this.clusterManagementLogic         = clusterManagementLogic;
     this.unitOfWork = unitOfWork;
 }
 public ExperimentController(
     IExperimentRepository experimentRepository,
     IExperimentPreprocessRepository experimentPreprocessRepository,
     IAquariumDataSetRepository aquariumDataSetRepository,
     IDataSetRepository dataSetRepository,
     IGitRepository gitRepository,
     IRegistryRepository registryRepository,
     ITrainingHistoryRepository trainingHistoryRepository,
     ITemplateRepository templateRepository,
     ITemplateVersionRepository templateVersionRepository,
     ITenantRepository tenantRepository,
     INodeRepository nodeRepository,
     ITemplateLogic templateLogic,
     ITagLogic tagLogic,
     IGitLogic gitLogic,
     IClusterManagementLogic clusterManagementLogic,
     IDataSetLogic dataSetLogic,
     IRegistryLogic registryLogic,
     IUnitOfWork unitOfWork,
     IInferenceHistoryRepository inferenceHistoryRepository,
     ITensorBoardContainerRepository tensorBoardContainerRepository,
     ITagRepository tagRepository,
     IStorageLogic storageLogic,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.trainingHistoryRepository      = trainingHistoryRepository;
     this.experimentRepository           = experimentRepository;
     this.experimentPreprocessRepository = experimentPreprocessRepository;
     this.aquariumDataSetRepository      = aquariumDataSetRepository;
     this.dataSetRepository         = dataSetRepository;
     this.gitRepository             = gitRepository;
     this.registryRepository        = registryRepository;
     this.templateRepository        = templateRepository;
     this.templateVersionRepository = templateVersionRepository;
     this.tenantRepository          = tenantRepository;
     this.nodeRepository            = nodeRepository;
     this.templateLogic             = templateLogic;
     this.tagLogic = tagLogic;
     this.gitLogic = gitLogic;
     this.clusterManagementLogic         = clusterManagementLogic;
     this.dataSetLogic                   = dataSetLogic;
     this.registryLogic                  = registryLogic;
     this.inferenceHistoryRepository     = inferenceHistoryRepository;
     this.tensorBoardContainerRepository = tensorBoardContainerRepository;
     this.tagRepository                  = tagRepository;
     this.storageLogic                   = storageLogic;
     this.unitOfWork = unitOfWork;
 }
 public NotebookController(
     INotebookHistoryRepository notebookHistoryRepository,
     IDataSetRepository dataSetRepository,
     INotebookLogic notebookLogic,
     IStorageLogic storageLogic,
     IGitLogic gitLogic,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.notebookHistoryRepository = notebookHistoryRepository;
     this.dataSetRepository         = dataSetRepository;
     this.notebookLogic             = notebookLogic;
     this.storageLogic           = storageLogic;
     this.gitLogic               = gitLogic;
     this.clusterManagementLogic = clusterManagementLogic;
     this.unitOfWork             = unitOfWork;
 }
        public async Task <IActionResult> Delete(long?id,
                                                 [FromServices] IClusterManagementLogic clusterManagementLogic,
                                                 [FromServices] DataAccess.Repositories.Interfaces.TenantRepositories.ITrainingHistoryRepository trainingHistoryRepository)
        {
            //データの入力チェック
            if (id == null)
            {
                return(JsonBadRequest("Invalid inputs."));
            }
            //データの存在チェック
            var registry = await registryRepository.GetByIdAsync(id.Value);

            if (registry == null)
            {
                return(JsonNotFound($"Registry ID {id.Value} is not found."));
            }
            //データの編集可否チェック
            if (registry.IsNotEditable)
            {
                return(JsonBadRequest($"Registry ID {id.Value} is not allowed to delete."));
            }

            //このレジストリを登録しているテナントがいた場合、削除はできない
            var tenant = registryRepository.GetTenant(registry.Id);

            if (tenant != null)
            {
                return(JsonConflict($"Registry {registry.Id}:{registry.Name} is used at Tenant {tenant.Id}:{tenant.Name}."));
            }
            //このレジストリを使った履歴がある場合、削除はできない
            var training = trainingHistoryRepository.Find(t => t.ContainerRegistryId == registry.Id);

            if (training != null)
            {
                return(JsonConflict($"Registry {registry.Id}:{registry.Name} is used at training {training.Id} in Tenant {training.TenantId}."));
            }

            //クラスタ管理サービス側の登録情報は特に削除しない(残っていても問題ない)
            registryRepository.Delete(registry);
            unitOfWork.Commit();

            return(JsonNoContent());
        }
        public async Task <IActionResult> Edit(long?id, [FromBody] CreateInputModel model, //EditとCreateで項目が同じなので、入力モデルを使いまわし
                                               [FromServices] IClusterManagementLogic clusterManagementLogic)
        {
            //データの入力チェック
            if (!ModelState.IsValid || !id.HasValue)
            {
                return(JsonBadRequest("Invalid inputs."));
            }
            //データの存在チェック
            var registry = await registryRepository.GetByIdAsync(id.Value);

            if (registry == null)
            {
                return(JsonNotFound($"Registry ID {id.Value} is not found."));
            }
            //データの編集可否チェック
            if (registry.IsNotEditable)
            {
                return(JsonBadRequest($"Registry ID {id.Value} is not allowed to edit."));
            }

            //同じ名前のレジストリは登録できないので、自分の他に同名の物がいないか、確認する
            var otherRegistry = registryRepository.GetRegistryAll().FirstOrDefault(r => r.Name == model.Name && r.Id != id);

            if (otherRegistry != null)
            {
                return(JsonConflict($"Registry {model.Name} already exists."));
            }

            registry.Name        = model.Name;
            registry.Host        = model.Host;
            registry.PortNo      = model.PortNo.Value;
            registry.ServiceType = model.ServiceType.Value;
            registry.ProjectName = model.ProjectName;
            registry.ApiUrl      = model.ApiUrl;
            registry.RegistryUrl = model.RegistryUrl;

            registryRepository.Update(registry);
            unitOfWork.Commit();

            return(JsonOK(new IndexOutputModel(registry)));
        }
 public TrainingController(
     ITrainingHistoryRepository trainingHistoryRepository,
     IInferenceHistoryRepository inferenceHistoryRepository,
     ITensorBoardContainerRepository tensorBoardContainerRepository,
     IDataSetRepository dataSetRepository,
     ITrainingLogic trainingLogic,
     IStorageLogic storageLogic,
     IGitLogic gitLogic,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.clusterManagementLogic         = clusterManagementLogic;
     this.trainingHistoryRepository      = trainingHistoryRepository;
     this.inferenceHistoryRepository     = inferenceHistoryRepository;
     this.tensorBoardContainerRepository = tensorBoardContainerRepository;
     this.dataSetRepository = dataSetRepository;
     this.trainingLogic     = trainingLogic;
     this.storageLogic      = storageLogic;
     this.gitLogic          = gitLogic;
     this.unitOfWork        = unitOfWork;
 }
Example #22
0
        public static async Task <ContainerStatus> DoGetUpdatedIndexOutputModelAsync(TrainingHistory history,
                                                                                     IClusterManagementLogic clusterManagementLogic, UserInfo currentUserInfo, ITrainingHistoryRepository trainingHistoryRepository,
                                                                                     IUnitOfWork unitOfWork)
        {
            var status = history.GetStatus();

            if (status.Exist())
            {
                //学習がまだ進行中の場合、情報を更新する
                var newStatus = await clusterManagementLogic.GetContainerStatusAsync(history.Key, currentUserInfo.SelectedTenant.Name, false);

                if (status.Key != newStatus.Key)
                {
                    //更新があったので、変更処理
                    await trainingHistoryRepository.UpdateStatusAsync(history.Id, newStatus, false);

                    unitOfWork.Commit();
                    return(newStatus);
                }
            }
            return(status);
        }
 public TenantController(
     ITenantRepository tenantRepository,
     IUserRepository userRepository,
     IRoleRepository roleRepository,
     IRegistryRepository registryRepository,
     IGitRepository gitRepository,
     ICommonDiLogic commonDiLogic,
     IStorageLogic storageLogic,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.tenantRepository       = tenantRepository;
     this.userRepository         = userRepository;
     this.roleRepository         = roleRepository;
     this.registryRepository     = registryRepository;
     this.gitRepository          = gitRepository;
     this.commonDiLogic          = commonDiLogic;
     this.storageLogic           = storageLogic;
     this.clusterManagementLogic = clusterManagementLogic;
     this.unitOfWork             = unitOfWork;
 }
 /// <summary>
 /// コンストラクタ
 /// </summary>
 public PreprocessingController(
     IPreprocessRepository preprocessRepository,
     IPreprocessHistoryRepository preprocessHistoryRepository,
     ITenantRepository tenantRepository,
     IDataRepository dataRepository,
     IPreprocessLogic preprocessLogic,
     ITagLogic tagLogic,
     IGitLogic gitLogic,
     IStorageLogic storageLogic,
     IClusterManagementLogic clusterManagementLogic,
     IUnitOfWork unitOfWork,
     IHttpContextAccessor accessor) : base(accessor)
 {
     this.preprocessRepository        = preprocessRepository;
     this.preprocessHistoryRepository = preprocessHistoryRepository;
     this.tenantRepository            = tenantRepository;
     this.dataRepository         = dataRepository;
     this.preprocessLogic        = preprocessLogic;
     this.tagLogic               = tagLogic;
     this.gitLogic               = gitLogic;
     this.storageLogic           = storageLogic;
     this.clusterManagementLogic = clusterManagementLogic;
     this.unitOfWork             = unitOfWork;
 }
Example #25
0
        public static async Task <(TrainingHistory, IActionResult)> DoCreate(CreateInputModel model,
                                                                             IDataSetRepository dataSetRepository,
                                                                             INodeRepository nodeRepository,
                                                                             ITenantRepository tenantRepository,
                                                                             ITrainingHistoryRepository trainingHistoryRepository,
                                                                             IClusterManagementLogic clusterManagementLogic,
                                                                             IDataSetLogic dataSetLogic,
                                                                             IGitLogic gitLogic,
                                                                             ITagLogic tagLogic,
                                                                             IUnitOfWork unitOfWork,
                                                                             UserInfo currentUserInfo,
                                                                             ModelStateDictionary modelState,
                                                                             string requestUrl,
                                                                             string scriptType,
                                                                             string regisryTokenName,
                                                                             string gitToken
                                                                             )
        {
            //データの入力チェック
            if (!modelState.IsValid)
            {
                return(null,
                       DoJsonBadRequest(typeof(TrainingController), requestUrl, modelState, "Invalid inputs."));
            }
            //データの存在チェック
            var dataSet = await dataSetRepository.GetByIdAsync(model.DataSetId.Value);

            if (dataSet == null)
            {
                return(null,
                       DoJsonNotFound(typeof(TrainingController), requestUrl, modelState,
                                      $"DataSet ID {model.DataSetId} is not found."));
            }
            if (string.IsNullOrEmpty(model.Partition) == false)
            {
                bool existPartition = await nodeRepository.IsEnablePartitionAsync(model.Partition, true);

                if (existPartition == false)
                {
                    return(null,
                           DoJsonNotFound(typeof(TrainingController), requestUrl, modelState,
                                          $"There are no enable nodes with Partition {model.Partition}."));
                }
            }

            // 環境変数名のチェック
            if (model.Options != null && model.Options.Count > 0)
            {
                foreach (var env in model.Options)
                {
                    if (!string.IsNullOrEmpty(env.Key))
                    {
                        // フォーマットチェック
                        if (!Regex.IsMatch(env.Key, "^[-._a-zA-Z][-._a-zA-Z0-9]*$"))
                        {
                            return(null,
                                   DoJsonNotFound(typeof(TrainingController), requestUrl, modelState, $"Invalid envName. Please match the format of '^[-._a-zA-Z][-._a-zA-Z0-9]*$'."));
                        }
                    }
                }
            }

            long?  gitId    = model.GitModel.GitId ?? currentUserInfo.SelectedTenant.DefaultGit?.Id;
            string branch   = model.GitModel.Branch ?? "master";
            string 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(null,
                           DoJsonNotFound(typeof(TrainingController), requestUrl, modelState,
                                          $"The branch {branch} for {gitId.Value}/{model.GitModel.Owner}/{model.GitModel.Repository} is not found."));
                }
            }

            // 各リソースの超過チェック
            Tenant tenant       = tenantRepository.Get(currentUserInfo.SelectedTenant.Id);
            string errorMessage = clusterManagementLogic.CheckQuota(tenant, model.Cpu.Value, model.Memory.Value, model.Gpu.Value);

            if (errorMessage != null)
            {
                return(null, DoJsonBadRequest(typeof(TrainingController), requestUrl, modelState, errorMessage));
            }

            //コンテナの実行前に、学習履歴を作成する(コンテナの実行に失敗した場合、そのステータスをユーザに表示するため)
            var trainingHistory = new TrainingHistory()
            {
                Name                 = model.Name,
                DisplayId            = -1,
                ContainerRegistryId  = model.ContainerImage.RegistryId ?? currentUserInfo.SelectedTenant.DefaultRegistry?.Id,
                ContainerImage       = model.ContainerImage.Image,
                ContainerTag         = model.ContainerImage.Tag, //latestは運用上使用されていないハズなので、そのまま直接代入
                DataSetId            = model.DataSetId.Value,
                EntryPoint           = model.EntryPoint,
                ModelGitId           = gitId.Value,
                ModelRepository      = model.GitModel.Repository,
                ModelRepositoryOwner = model.GitModel.Owner,
                ModelBranch          = branch,
                ModelCommitId        = commitId,
                OptionDic            = model.Options ?? new Dictionary <string, string>(), //オプションはnullの可能性があるので、その時は初期化
                Memo                 = model.Memo,
                Cpu          = model.Cpu.Value,
                Memory       = model.Memory.Value,
                Gpu          = model.Gpu.Value,
                Partition    = model.Partition,
                PortList     = model.Ports,
                Status       = ContainerStatus.Running.Key,
                Zip          = model.Zip,
                LocalDataSet = model.LocalDataSet,
            };

            if (trainingHistory.OptionDic.ContainsKey("")) //空文字は除外する
            {
                trainingHistory.OptionDic.Remove("");
            }
            // 親学習が指定されていれば存在チェック
            if (model.ParentIds != null)
            {
                var maps = new List <TrainingHistoryParentMap>();

                foreach (var parentId in model.ParentIds)
                {
                    var parent = await trainingHistoryRepository.GetByIdAsync(parentId);

                    if (parent == null)
                    {
                        return(null, DoJsonNotFound(typeof(TrainingController), requestUrl, modelState, $"Training ID {parentId} is not found."));
                    }
                    // 学習履歴に親学習を紐づける
                    var map = trainingHistoryRepository.AttachParentAsync(trainingHistory, parent);
                    if (map != null)
                    {
                        maps.Add(map);
                    }
                }

                trainingHistory.ParentMaps = maps;
            }
            //タグの登録
            if (model.Tags != null && model.Tags.Count() > 0)
            {
                tagLogic.CreateTrainingHistoryTags(trainingHistory, model.Tags);
            }

            trainingHistoryRepository.Add(trainingHistory);
            if (dataSet.IsLocked == false)
            {
                dataSet.IsLocked = true;
            }
            unitOfWork.Commit();

            var result = await clusterManagementLogic.RunTrainContainerAsync(trainingHistory, scriptType, regisryTokenName, gitToken);

            if (result.IsSuccess == false)
            {
                //コンテナの起動に失敗した状態。エラーを出力して、保存した学習履歴も削除する。
                await dataSetLogic.ReleaseLockAsync(trainingHistory.DataSetId);

                trainingHistoryRepository.Delete(trainingHistory);
                unitOfWork.Commit();

                return(null, DoJsonError(HttpStatusCode.ServiceUnavailable, "Failed to run training. The message bellow may be help to resolve: " + result.Error,
                                         typeof(TrainingController), requestUrl, modelState));
            }

            //結果に従い、学習結果を更新する。
            //実行には時間がかかりうるので、DBから最新の情報を取ってくる
            trainingHistory = await trainingHistoryRepository.GetByIdAsync(trainingHistory.Id);

            trainingHistory.Configuration = result.Value.Configuration;
            trainingHistory.Status        = result.Value.Status.Key;
            unitOfWork.Commit();

            if (result.Value.Status.Succeed())
            {
                return(trainingHistory,
                       JsonCreated(new SimpleOutputModel(trainingHistory)));
            }
            else
            {
                return(trainingHistory,
                       DoJsonError(HttpStatusCode.ServiceUnavailable, $"Failed to run training. Status={result.Value.Status.Name}. Please contact your server administrator.",
                                   typeof(TrainingController), requestUrl, modelState));
            }
        }
        /// <summary>
        /// ステータスを更新して、出力モデルに変換する
        /// </summary>
        private async Task <HistoriesOutputModel> GetUpdatedIndexOutputModelAsync(PreprocessHistory history, HistoriesOutputModel model, IClusterManagementLogic clusterManagementLogic)
        {
            var status = ContainerStatus.Convert(history.Status);

            model.StatusType = status.StatusType;
            if (status.Exist())
            {
                //コンテナがまだ存在している場合、情報を更新する
                var newStatus = await clusterManagementLogic.GetContainerStatusAsync(history.Name, CurrentUserInfo.SelectedTenant.Name, false);

                if (status.Key != newStatus.Key)
                {
                    //更新があったので、変更処理
                    history.Status = newStatus.Key;
                    unitOfWork.Commit();

                    model.Status     = newStatus.Name;
                    model.StatusType = newStatus.StatusType;
                }
            }
            return(model);
        }
        public async Task <IActionResult> GetDetailHistory([FromRoute] long id, [FromRoute] long?dataId, [FromServices] IClusterManagementLogic clusterManagementLogic)
        {
            if (dataId == null)
            {
                return(JsonBadRequest("Data ID is required."));
            }

            var history = await preprocessHistoryRepository.GetPreprocessIncludeDataAndPreprocessAsync(id, dataId.Value);

            if (history == null)
            {
                return(JsonNotFound($"Preprocessing History about Preprocess {id} to Data {dataId} is not found."));
            }

            var result = new HistoryDetailsOutputModel(history);

            result = await GetUpdatedIndexOutputModelAsync(history, result, clusterManagementLogic) as HistoryDetailsOutputModel;

            result.OutputDataIds = preprocessHistoryRepository.GetPreprocessOutputs(history.Id);
            return(JsonOK(result));
        }
 public async Task <IActionResult> Complete([FromRoute] long id, [FromRoute] long dataId,
                                            [FromServices] IClusterManagementLogic clusterManagementLogic)
 {
     return(await ExitAsync(id, dataId, ContainerStatus.Completed, clusterManagementLogic));
 }
        /// <summary>
        /// 前処理実行を終了させる。
        /// </summary>
        private async Task <IActionResult> ExitAsync(long id, long dataId, ContainerStatus newStatus, IClusterManagementLogic clusterManagementLogic)
        {
            //データの存在チェック
            var preprocessHistory = await preprocessHistoryRepository.GetPreprocessIncludeDataAndPreprocessAsync(id, dataId);

            if (preprocessHistory == null)
            {
                return(JsonNotFound($"Preprocessing History about Preprocess {id} to Data {dataId} is not found."));
            }
            var status = ContainerStatus.Convert(preprocessHistory.Status);

            if (status.IsOpened() == false)
            {
                //終了できるのは開放中のコンテナだけ(ローカルの結果を追加することがあるので、Runningとは限らない)
                return(JsonBadRequest($"Preprocessing History {preprocessHistory.Id} is not opened."));
            }
            if (status.Exist())
            {
                //コンテナが動いていれば、停止する
                await clusterManagementLogic.DeleteContainerAsync(
                    ContainerType.Preprocessing, preprocessHistory.Name, CurrentUserInfo.SelectedTenant.Name, false);
            }

            preprocessHistory.CompletedAt = DateTime.Now;
            preprocessHistory.Status      = newStatus.Key;
            unitOfWork.Commit();

            return(JsonOK(new HistoriesOutputModel(preprocessHistory)));
        }