-
Notifications
You must be signed in to change notification settings - Fork 438
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5140 from DavidKang/feature/obs-factory-without-test
Integrate obs factory
- Loading branch information
Showing
40 changed files
with
3,032 additions
and
58 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
425 changes: 425 additions & 0 deletions
425
src/api/app/assets/stylesheets/webui/obs_factory/application.css
Large diffs are not rendered by default.
Oops, something went wrong.
9 changes: 9 additions & 0 deletions
9
src/api/app/controllers/webui/obs_factory/application_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module Webui::ObsFactory | ||
class ApplicationController < ::Webui::WebuiController | ||
layout 'webui/obs_factory/application' | ||
|
||
rescue_from ::ObsFactory::OpenqaApi::OpenqaFailure do |ex| | ||
render text: "failure in openQA" | ||
end | ||
end | ||
end |
49 changes: 49 additions & 0 deletions
49
src/api/app/controllers/webui/obs_factory/distributions_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
module Webui::ObsFactory | ||
class DistributionsController < ApplicationController | ||
respond_to :html | ||
|
||
before_action :require_distribution, :require_dashboard | ||
|
||
def show | ||
@staging_projects = ::ObsFactory::StagingProjectPresenter.sort(@distribution.staging_projects) | ||
@versions = { source: @distribution.source_version, | ||
totest: @distribution.totest_version, | ||
published: @distribution.published_version } | ||
@ring_prjs = ::ObsFactory::ObsProjectPresenter.wrap(@distribution.ring_projects) | ||
@standard = ::ObsFactory::ObsProjectPresenter.new(@distribution.standard_project) | ||
@live = @distribution.live_project | ||
@live = ::ObsFactory::ObsProjectPresenter.new(@live) unless @live.nil? | ||
@images = ::ObsFactory::ObsProjectPresenter.new(@distribution.images_project) | ||
@openqa_jobs = @distribution.openqa_jobs_for(:totest) | ||
calculate_reviews | ||
# For the breadcrumbs | ||
@project = @distribution.project | ||
end | ||
|
||
protected | ||
|
||
def calculate_reviews | ||
@reviews = {} | ||
@reviews[:review_team] = @distribution.requests_with_reviews_for_group('opensuse-review-team').size | ||
@reviews[:factory_auto] = @distribution.requests_with_reviews_for_group('factory-auto').size | ||
@reviews[:legal_auto] = @distribution.requests_with_reviews_for_group('legal-auto').size | ||
@reviews[:legal_team] = @distribution.requests_with_reviews_for_group('legal-team').size | ||
@reviews[:repo_checker] = @distribution.requests_with_reviews_for_user('repo-checker').size | ||
end | ||
|
||
private | ||
|
||
def require_distribution | ||
@distribution = ::ObsFactory::Distribution.find(params[:project]) | ||
unless @distribution | ||
redirect_to main_app.root_path, flash: { error: "#{params[:project]} is not a valid openSUSE distribution, can't offer dashboard" } | ||
end | ||
end | ||
|
||
def require_dashboard | ||
if @distribution.staging_projects.empty? | ||
redirect_to main_app.root_path, flash: { error: "#{params[:project]} does not offer a dashboard" } | ||
end | ||
end | ||
end | ||
end |
67 changes: 67 additions & 0 deletions
67
src/api/app/controllers/webui/obs_factory/staging_projects_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
module Webui::ObsFactory | ||
class StagingProjectsController < ApplicationController | ||
respond_to :json, :html | ||
|
||
before_action :require_distribution | ||
before_action :require_project_name, only: [:show] | ||
|
||
def index | ||
respond_to do |format| | ||
format.html do | ||
@staging_projects = ::ObsFactory::StagingProjectPresenter.sort(@distribution.staging_projects_all) | ||
@backlog_requests = ::ObsFactory::Request.with_open_reviews_for(by_group: @distribution.staging_manager, target_project: @distribution.name) | ||
@requests_state_new = ::ObsFactory::Request.in_state_new(by_group: @distribution.staging_manager, target_project: @distribution.name) | ||
|
||
staging_project = Project.find_by_name("#{@distribution.project}:Staging") | ||
dashboard_package = Package.find_by_project_and_name(staging_project.name, 'dashboard') | ||
|
||
if dashboard_package && dashboard_package.file_exists?('ignored_requests') | ||
file = ::Backend::Api::Sources::Package.file(staging_project.name, dashboard_package.name, 'ignored_requests') | ||
@ignored_requests = YAML.load(file) | ||
end | ||
|
||
if @ignored_requests | ||
@backlog_requests_ignored = @backlog_requests.select { |req| @ignored_requests.key?(req.number) } | ||
@backlog_requests = @backlog_requests.select { |req| !@ignored_requests.key?(req.number) } | ||
@requests_state_new = @requests_state_new.select { |req| !@ignored_requests.key?(req.number) } | ||
@backlog_requests_ignored.sort! { |x,y| x.package <=> y.package } | ||
else | ||
@backlog_requests_ignored = [] | ||
end | ||
@backlog_requests.sort! { |x,y| x.package <=> y.package } | ||
@requests_state_new.sort! { |x,y| x.package <=> y.package } | ||
# For the breadcrumbs | ||
@project = @distribution.project | ||
end | ||
format.json { render json: @distribution.staging_projects_all } | ||
end | ||
end | ||
|
||
def show | ||
respond_to do |format| | ||
format.html do | ||
@staging_project = ::ObsFactory::StagingProjectPresenter.new(@staging_project) | ||
# For the breadcrumbs | ||
@project = @distribution.project | ||
end | ||
format.json { render json: @staging_project } | ||
end | ||
end | ||
|
||
private | ||
|
||
def require_distribution | ||
@distribution = ::ObsFactory::Distribution.find(params[:project]) | ||
unless @distribution | ||
redirect_to main_app.root_path, flash: { error: "#{params[:project]} is not a valid openSUSE distribution, can't offer dashboard" } | ||
end | ||
end | ||
|
||
def require_project_name | ||
@staging_project = ::ObsFactory::StagingProject.find(@distribution, params[:project_name]) | ||
unless @staging_project | ||
redirect_to main_app.root_path, flash: { error: "#{params[:project_name]} is not a valid staging project" } | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module Webui::ObsFactory::ApplicationHelper | ||
def openqa_links_helper | ||
ObsFactory::OpenqaJob.openqa_links_url | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
require 'open-uri' | ||
|
||
module ObsFactory | ||
|
||
class UnknownDistribution < Exception | ||
end | ||
|
||
# A Distribution. Contains a reference to the corresponding Project object. | ||
class Distribution | ||
include ActiveModel::Model | ||
extend ActiveModel::Naming | ||
extend Forwardable | ||
|
||
SOURCE_VERSION_FILE = { package_name: '000product', filename: 'openSUSE.product' } | ||
RINGS_PREFIX = ":Rings" | ||
|
||
attr_accessor :project, :strategy | ||
|
||
def initialize(project = nil) | ||
self.project = project | ||
self.strategy = distribution_strategy_for_project(project) | ||
end | ||
|
||
def self.attributes | ||
%w(name description staging_projects openqa_version openqa_group | ||
source_version totest_version published_version staging_manager | ||
standard_project live_project images_project ring_projects) | ||
end | ||
|
||
def attributes | ||
Hash[self.class.attributes.map { |a| [a, nil] }] | ||
end | ||
|
||
def_delegators :@strategy, :root_project_name, :url_suffix, :openqa_version, | ||
:openqa_iso, :arch, :openqa_group, :staging_manager | ||
|
||
# Find a distribution by id | ||
# | ||
# @return [Distribution] the distribution | ||
def self.find(id) | ||
project = ::Project.find_by_name(id) | ||
if project | ||
begin | ||
Distribution.new(project) | ||
rescue UnknownDistribution | ||
nil | ||
end | ||
else | ||
nil | ||
end | ||
end | ||
|
||
# Name of the associated project | ||
# | ||
# @return [String] name of the Project object | ||
def name | ||
project.name | ||
end | ||
|
||
# Id of the distribution | ||
# | ||
# @return [String] name | ||
def id | ||
name | ||
end | ||
|
||
# Description of the associated project | ||
# | ||
# @return [String] description of the Project object | ||
def description | ||
project.description | ||
end | ||
|
||
# Version of the distribution used as ToTest | ||
# | ||
# @return [String] version string | ||
def totest_version | ||
Rails.cache.fetch("totest_version_for_#{name}", expires_in: 10.minutes) do | ||
strategy.totest_version | ||
end | ||
end | ||
|
||
# Version of the published distribution | ||
# | ||
# @return [String] version string | ||
def published_version | ||
Rails.cache.fetch("published_version_for_#{name}", expires_in: 10.minutes) do | ||
strategy.published_version | ||
end | ||
end | ||
|
||
# Staging projects associated to the distribution | ||
# | ||
# @return [Array] array of StagingProject objects | ||
def staging_projects | ||
@staging_projects ||= StagingProject.for(self) | ||
end | ||
|
||
# Staging projects associated to the distribution, including non-letter | ||
# | ||
# @return [Array] array of StagingProject objects | ||
def staging_projects_all | ||
@staging_projects ||= StagingProject.for(self, false) | ||
end | ||
|
||
# Version of the distribution used as source | ||
# | ||
# @return [String] version string | ||
def source_version | ||
Rails.cache.fetch("source_version_for_#{name}", expires_in: 10.minutes) do | ||
begin | ||
p = Xmlhash.parse(Backend::Api::Sources::Package.file(name, SOURCE_VERSION_FILE[:package_name], SOURCE_VERSION_FILE[:filename])) | ||
p.get('products').get('product').get('version') | ||
rescue ActiveXML::Transport::NotFoundError | ||
nil | ||
end | ||
end | ||
end | ||
|
||
# openQA jobs related with a given version of the distribution | ||
# | ||
# @param [#to_s] version must be :source, :totest or :published | ||
# @return [Array] list of OpenqaJob objects | ||
def openqa_jobs_for(version) | ||
filter = {distri: 'opensuse', version: strategy.openqa_version, build: send(:"#{version}_version"), group: strategy.openqa_group} | ||
OpenqaJob.find_all_by(filter, exclude_modules: true) | ||
end | ||
|
||
# Requests with some open review targeting the distribution, filtered by | ||
# the group in charge of the open reviews | ||
# | ||
# @param [String] group name of the group | ||
# @return [Array] list of Request objects | ||
def requests_with_reviews_for_group(group) | ||
Request.with_open_reviews_for(by_group: group, target_project: root_project_name) | ||
end | ||
|
||
# Requests with some open review targeting the distribution, filtered by | ||
# the user in charge of the open reviews | ||
# | ||
# @param [String] user name of the user | ||
# @return [Array] list of Request objects | ||
def requests_with_reviews_for_user(user) | ||
Request.with_open_reviews_for(by_user: user, target_project: root_project_name) | ||
end | ||
|
||
# Standard project | ||
# | ||
# @return [ObsProject] standard | ||
def standard_project | ||
if @standard_project.nil? | ||
@standard_project = ObsProject.new(name, 'standard') | ||
@standard_project.exclusive_repository = 'standard' | ||
end | ||
@standard_project | ||
end | ||
|
||
# Live project | ||
# | ||
# @return [ObsProject] live | ||
def live_project | ||
if @live_project.nil? | ||
@live_project = ObsProject.new("#{name}:Live", 'live') | ||
if @live_project.project.nil? | ||
@live_project = nil | ||
else | ||
@live_project.exclusive_repository = 'images' | ||
end | ||
end | ||
@live_project | ||
end | ||
|
||
# Images project | ||
# | ||
# @return [ObsProject] images | ||
def images_project | ||
if @images_project.nil? | ||
@images_project = ObsProject.new(name, 'images') | ||
@images_project.exclusive_repository = 'images' | ||
end | ||
@images_project | ||
end | ||
|
||
# Projects defining the distribution rings | ||
# | ||
# @return [Array] list of ObsProject objects nicknamed with numbers | ||
def ring_projects | ||
@ring_projects ||= strategy.rings.each_with_index.map do |r,idx| | ||
ObsProject.new("#{rings_project_name}:#{idx}-#{r}", "#{idx}-#{r}") | ||
end | ||
end | ||
|
||
# Name of the project used as top-level for the ring projects | ||
# | ||
# @return [String] project name | ||
def rings_project_name | ||
"#{root_project_name}#{RINGS_PREFIX}" | ||
end | ||
|
||
# URL parameter for openqa's /test route to be opened in view | ||
# for given project | ||
# | ||
# @return [String] URL part (e.g. match=A) | ||
def openqa_filter(project) | ||
return strategy.openqa_filter(project) | ||
end | ||
|
||
private | ||
|
||
def distribution_strategy_for_project(project) | ||
s = case project.name | ||
when 'openSUSE:Factory' then DistributionStrategyFactory.new | ||
when 'openSUSE:Factory:PowerPC' then DistributionStrategyFactoryPPC.new | ||
when /^openSUSE:.*/ then DistributionStrategyOpenSUSE.new | ||
when /^SUSE:SLE-12-SP\d:GA/ then DistributionStrategySLE12SP1.new | ||
when /^SUSE:SLE-15:GA/ then DistributionStrategySLE15.new | ||
when /^SUSE:SLE-12-SP.*CASP\d*/ then DistributionStrategyCasp.new | ||
else raise UnknownDistribution | ||
end | ||
s.project = project | ||
s | ||
end | ||
end | ||
end |
Oops, something went wrong.