From 89f92d265a5a028004fda5ded3ab870b632dfb2f Mon Sep 17 00:00:00 2001 From: Alexey Berezhok Date: Sat, 15 Nov 2025 22:54:56 +0300 Subject: [PATCH] =?UTF-8?q?-=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BE=D0=B6=D0=B8=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B8=20-=20=D0=98=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BE?= =?UTF-8?q?=D0=BA=20=D1=81=D0=BE=D1=80=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BD=D0=BE=D0=B2=D1=8B=D1=85=20=D0=BF=D0=B0=D0=BA?= =?UTF-8?q?=D0=B5=D1=82=D0=BE=D0=B2=20=D0=B2=20repoview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 1 - VERSION | 4 ++ app.rb | 15 +++++- classes/config.rb | 8 +++ classes/db.rb | 8 +++ classes/mock.rb | 67 ++++++++++++++++---------- classes/projects.rb | 27 +++++------ classes/repomanage.rb | 6 +-- config.ini | 3 ++ docs/mock-gui/docs/userguide/builds.md | 9 +++- locks/build | 0 views/buildslist.erb | 16 +++++- views/prjbuildslist.erb | 18 ++++++- views/prjbuildslistgit.erb | 16 +++++- 14 files changed, 147 insertions(+), 51 deletions(-) create mode 100644 locks/build diff --git a/Gemfile b/Gemfile index 759b7db..2b64674 100644 --- a/Gemfile +++ b/Gemfile @@ -36,4 +36,3 @@ gem "ffi", "~> 1.17" gem "ptools", "~> 1.5" gem "ostruct", "~> 0.6.1" - diff --git a/VERSION b/VERSION index ef067fb..74cc3d2 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,7 @@ +0.3-1 +* Добавлена возможность добавлять сборки в состоянии ожидания +* Изменена сортировка пакетов в repoview + 0.2-1 * Добавлена поддержка проектов для тестовых сборок (версия меняется каждую сборку) * Доработан вывод repoview diff --git a/app.rb b/app.rb index 130202e..224fc25 100644 --- a/app.rb +++ b/app.rb @@ -38,6 +38,7 @@ end cfg = IniConfig.new() db = DBase.new(cfg) +db.cancel_hang_builds set :bind, "0.0.0.0" set :port, cfg.get_port @@ -780,7 +781,7 @@ get "/gitbld/:id/:git_id" do @git_name = git_info[:reponame] @proj_id = params["id"] - @build_id = prj.build_projects_git(prj_info[:id], git_info[:id], cfg.get_counter_path) + @build_id = prj.build_projects_git(prj_info[:id], git_info[:id], cfg.get_counter_path, cfg.get_build_lock_path) if @build_id == 0 print_error_page(503, "Ошибка создания или получения информации о сборке, возможно проблемы с файлом блокировки") @@ -963,6 +964,18 @@ get "/buildinfof/:build_id" do end end +get "/buildterm/:build_id" do + build_info = db.get_build_info(params["build_id"]) + if build_info.nil? + print_error_page(503, "Сборки не сущестует") + else + if build_info[:result] == 3 + db.update_build_task_status(params["build_id"], 4) + end + redirect back + end +end + get "/buildinfofraw" do if params["file"].nil? || !File.exist?(params["file"]) print_error_page(503, "Файл не найден") diff --git a/classes/config.rb b/classes/config.rb index 98e12ec..6c0cf3d 100644 --- a/classes/config.rb +++ b/classes/config.rb @@ -71,6 +71,14 @@ class IniConfig end end + def get_build_lock_path() + unless @config["build"]["path"].nil? + @config["build"]["path"].to_s + else + "locks/build" + end + end + def get_items_per_page() unless @config["pages"]["items_per_page"].nil? res = @config["pages"]["items_per_page"].to_i diff --git a/classes/db.rb b/classes/db.rb index 0be51fb..1c2f977 100644 --- a/classes/db.rb +++ b/classes/db.rb @@ -249,6 +249,10 @@ class DBase BuildTask.where(id: build_id.to_i).update(result: status.to_i) end + def get_build_task_status(build_id) + BuildTask.where(id: build_id.to_i).first + end + def update_build_task_error_log(build_id, path) BuildTask.where(id: build_id.to_i).update(errlogpath: path) end @@ -384,4 +388,8 @@ class DBase def delete_git_by_id(id) Repos.where(id: id.to_i).delete end + + def cancel_hang_builds() + BuildTask.where(result: [0, 3]).update(result: 4) + end end diff --git a/classes/mock.rb b/classes/mock.rb index 0c31d42..e2fe583 100644 --- a/classes/mock.rb +++ b/classes/mock.rb @@ -267,7 +267,7 @@ class MockManager end end - def build_task() + def build_task(build_lock) @error = false @db.before_fork spock = Spork.spork(:logger => log) do @@ -275,33 +275,48 @@ class MockManager old_stdout = $stdout.dup $stdout = File.open(@process_log, "w") @log = Logger.new($stdout) - if @spec == "" - @error = true - @log.error("Не могу найти spec файл") - end - begin - prepare_structure if @error == false - prepare_src if @error == false - prepare_source if @error == false - prepare_src_rpm if @error == false - build_rpm if @error == false - save_logs - save_rpms if @error == false - rescue => e - @error = true - puts e - end - $stdout = old_stdout - @log.close - save_prg_log - clean_build - if @error - @db.update_build_task_status(@build_id, 1) - else - @db.update_build_task_status(@build_id, 2) + + File.open(build_lock,"wb") do |global_lock| + global_lock.flock(File::LOCK_EX) + global_lock.rewind + build_info = @db.get_build_task_status(build_id) + unless build_info.nil? + if build_info[:result].to_i == 4 + return + end + end + @db.update_build_task_status(@build_id, 0) + + if @spec == "" + @error = true + @log.error("Не могу найти spec файл") + end + begin + prepare_structure if @error == false + prepare_src if @error == false + prepare_source if @error == false + prepare_src_rpm if @error == false + build_rpm if @error == false + save_logs + save_rpms if @error == false + rescue => e + @error = true + puts e + end + $stdout = old_stdout + @log.close + save_prg_log + clean_build + if @error + @db.update_build_task_status(@build_id, 1) + else + @db.update_build_task_status(@build_id, 2) + end + global_lock.flock(File::LOCK_UN) + end end @db.after_fork - spock + end end diff --git a/classes/projects.rb b/classes/projects.rb index 7b7a8c5..a36482e 100644 --- a/classes/projects.rb +++ b/classes/projects.rb @@ -269,7 +269,7 @@ class ProjectsActions spec_file end - def build_projects_git(prj_id, git_id, counter_file) + def build_projects_git(prj_id, git_id, counter_file, build_lock) bld_id = 0 build_ok = true proj_path = get_project_path(prj_id) @@ -283,20 +283,16 @@ class ProjectsActions File.open(lockf_path, File::RDWR | File::CREAT) do |f| result = f.flock(File::LOCK_EX | File::LOCK_NB) if result == false - #Файл заблокирован считать id и вывести сведения о сборке + # Файл заблокирован считать id и вывести сведения о сборке build_ok = false build_id = f.gets - unless build_id.nil? - build_id = build_id.strip.to_i - end - if build_id > 0 + build_id = build_id.strip.to_i unless build_id.nil? + if build_id.positive? build_info = @db.get_build_task_process_log(build_id) - unless build_info.nil? - bld_id = build_info[:id] - end + bld_id = build_info[:id] unless build_info.nil? end else - #Сборка завершилась, но каталог не подчистился + # Сборка завершилась, но каталог не подчистился FileUtils.rm_rf(prepare_path) f.flock(File::LOCK_UN) build_ok = true @@ -306,17 +302,17 @@ class ProjectsActions #Верная ситуация if build_ok + build_path = File.join(proj_path, PROJECTS_STRUCTURE[:LOGS], git_name[:reponame]) Dir.mkdir(prepare_path) lockf_path = File.join(prepare_path, "lock") File.open(lockf_path, File::RDWR | File::CREAT) do |f| f.flock(File::LOCK_EX) f.rewind - #Начинаем сборку - build_path = File.join(proj_path, PROJECTS_STRUCTURE[:LOGS], git_name[:reponame]) + #Начинаем сборку + @db.create_build_task(prj_id, git_id, build_path) + build_id = @db.last_id repo_path = File.join(proj_path, PROJECTS_STRUCTURE[:REPO]) git_source = File.join(proj_path, PROJECTS_STRUCTURE[:SRC], git_name[:reponame]) - @db.create_build_task(prj_id, git_id, build_path) - build_id = @db.last_id f.puts(build_id) f.flush proj_info = get_project(prj_id) @@ -325,7 +321,8 @@ class ProjectsActions mock = MockManager.new(prepare_path, get_project_config(prj_id), counter_file, @db, build_path, repo_path, git_source, build_id, prep_script, spec_file, repo_lock, git_id, tmp_bld) bld_id = build_id @db.update_build_task_error_log(build_id, mock.get_build_process_log) - mock.build_task + @db.update_build_task_status(build_id, 3) + mock.build_task(build_lock) end end bld_id diff --git a/classes/repomanage.rb b/classes/repomanage.rb index 8c2c1c1..9b0fcbd 100644 --- a/classes/repomanage.rb +++ b/classes/repomanage.rb @@ -142,9 +142,9 @@ class RepoManager if nresult.key?("SRPMS") last_update_src = nresult["SRPMS"].map do |record| { fname: record[:fname], stat: record[:stat] } - end.sort_by! do |item| - [item[:stat], -item[:fname].downcase.ord] - end.map do |record| + end.sort_by do |item| + [item[:stat], item[:fname].downcase.ord] + end.reverse.map do |record| if record[:stat].nil? ["нет даты", record[:fname]] else diff --git a/config.ini b/config.ini index 638326e..3ece03e 100644 --- a/config.ini +++ b/config.ini @@ -12,6 +12,9 @@ old = 3 [counter] path = "locks/counter" +[build] +path = "locks/build" + [configs] hide=open,amazon,anolis,circle,custom,euro,fedora,mageia,navy,alma,rocky selected=msvsphere diff --git a/docs/mock-gui/docs/userguide/builds.md b/docs/mock-gui/docs/userguide/builds.md index ada1764..ac984d3 100644 --- a/docs/mock-gui/docs/userguide/builds.md +++ b/docs/mock-gui/docs/userguide/builds.md @@ -8,7 +8,14 @@ ![Список сборок2](../img/mockgui_build10.png) -Где можно увидеть вес файлы логов с ошибками и без, пакеты собранные при сборке и т.д. +Где можно увидеть все файлы логов с ошибками и без, пакеты собранные при сборке и т.д. + +Сборка может находится в таком состоянии: +* Идет сборка - проект собирается +* Ожидает сборки - одновременно может происходить только одна сборка, поэтому все проекты требующие сборки будут ожидать очереди. В этот момент сборку можно отменить +* Отменена - сборка была запланирована, но потом отменена +* Ошибка сборки - сборка завершилась с ошибкой +* Сборка успешно завершена - успешная сборка с пакетами Список сборок может быть: * общим diff --git a/locks/build b/locks/build new file mode 100644 index 0000000..e69de29 diff --git a/views/buildslist.erb b/views/buildslist.erb index 4305287..d0bb067 100644 --- a/views/buildslist.erb +++ b/views/buildslist.erb @@ -25,6 +25,12 @@ when 2 st = "Сборка успешно завершена" cl = "text-bg-success" + when 3 + st = "Ожидает сборки" + cl = "text-bg-secondary" + when 4 + st = "Отменена" + cl = "text-bg-light" else st = "Неизвестно" cl = "text-bg-light" @@ -39,7 +45,15 @@ <%= st %> - Детальнее + + <% if item[:state] == 3 %> + Отменить + <% elsif item[:state] == 4 %> + Нет информации + <% else %> + Детальнее + <% end %> + <% end %> diff --git a/views/prjbuildslist.erb b/views/prjbuildslist.erb index 244efc5..96d3cc5 100644 --- a/views/prjbuildslist.erb +++ b/views/prjbuildslist.erb @@ -26,11 +26,17 @@ when 2 st = "Сборка успешно завершена" cl = "text-bg-success" + when 3 + st = "Ожидает сборки" + cl = "text-bg-secondary" + when 4 + st = "Отменена" + cl = "text-bg-light" else st = "Неизвестно" cl = "text-bg-light" end - %> + %> end <%= item[:buildid] %> <%= item[:prjname] %> @@ -40,7 +46,15 @@ <%= st %> - Детальнее + + <% if item[:state] == 3 %> + Отменить + <% elsif item[:state] == 4 %> + Нет информации + <% else %> + Детальнее + <% end %> + <% end %> diff --git a/views/prjbuildslistgit.erb b/views/prjbuildslistgit.erb index 033c002..364d7e4 100644 --- a/views/prjbuildslistgit.erb +++ b/views/prjbuildslistgit.erb @@ -26,6 +26,12 @@ when 2 st = "Сборка успешно завершена" cl = "text-bg-success" + when 3 + st = "Ожидает сборки" + cl = "text-bg-secondary" + when 4 + st = "Отменена" + cl = "text-bg-light" else st = "Неизвестно" cl = "text-bg-light" @@ -40,7 +46,15 @@ <%= st %> - Детальнее + + <% if item[:state] == 3 %> + Отменить + <% elsif item[:state] == 4 %> + Нет информации + <% else %> + Детальнее + <% end %> + <% end %>