From: jiil.hyoun Date: Thu, 29 Nov 2012 07:36:04 +0000 (+0900) Subject: [Title] support distribution lock X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c76886492b9ade85512e719277712fc105edb1d0;p=sdk%2Ftools%2Fsdk-build.git [Title] support distribution lock [Type] Feature [Module] Toolchain / [Priority] Major [Jira#] [Redmine#] [Problem] [Cause] [Solution] [TestCase] Change-Id: Ib42d5e0a35666eaca50815592ee1d11004126d59 --- diff --git a/src/build_server/BinaryUploadProject.rb b/src/build_server/BinaryUploadProject.rb index f913446..e101c48 100644 --- a/src/build_server/BinaryUploadProject.rb +++ b/src/build_server/BinaryUploadProject.rb @@ -161,6 +161,8 @@ class BinaryUploadProject < CommonProject if is_new then db.do "INSERT INTO project_bins VALUES (#{@prj_id},'#{@pkg_name}')" + db.do "INSERT INTO group_project_accesses + VALUES ( (SELECT groups.id FROM groups WHERE groups.name = 'admin'),'#{@prj_id}','UNLOCK')" else db.do "UPDATE project_bins SET pkg_name='#{@pkg_name}' WHERE project_id=#{@prj_id})" end diff --git a/src/build_server/CommonProject.rb b/src/build_server/CommonProject.rb index 61eb39f..efdba93 100644 --- a/src/build_server/CommonProject.rb +++ b/src/build_server/CommonProject.rb @@ -165,7 +165,6 @@ class CommonProject return @prj_id end - def self.create_table(db, inc, post_fix) db.do "CREATE TABLE projects ( id INTEGER PRIMARY KEY #{inc}, @@ -333,7 +332,7 @@ class CommonProject end - public + public def self.get_project_row(name, dist_name, db) row = db.select_one("SELECT * FROM distributions WHERE name='#{dist_name}'") dist_id = row['id'] @@ -341,8 +340,17 @@ class CommonProject return row end + public + def self.get_project_from_pkg_name_row(pkg_name, dist_name, db) + return db.select_one("SELECT projects.id,projects.distribution_id,projects.name,projects.ptype,projects.password + FROM distributions,projects,project_bins + WHERE distributions.name='#{dist_name}' and + distributions.id = projects.distribution_id and + projects.id = project_bins.project_id and + project_bins.pkg_name = '#{pkg_name}'") + end - public + public def self.get_all_project_rows(db) result = [] rows = db.select_all("SELECT projects.name,distributions.name as dist_name,projects.ptype diff --git a/src/build_server/DistributionManager.rb b/src/build_server/DistributionManager.rb index fb70c65..5862f88 100644 --- a/src/build_server/DistributionManager.rb +++ b/src/build_server/DistributionManager.rb @@ -36,9 +36,10 @@ require "RegisterPackageJob.rb" require "packageServer.rb" class PackageDistribution - attr_accessor :name, :pkgsvr_url, :pkgsvr_ip, :pkgsvr_port, :status, :description + attr_accessor :name, :pkgsvr_url, :pkgsvr_ip, :pkgsvr_port, :status, :description, :id def initialize( name, pkgsvr_url, pkgsvr_ip, pkgsvr_port, status ) + @id = -1 @name = name @pkgsvr_url = pkgsvr_url @pkgsvr_ip = pkgsvr_ip @@ -48,24 +49,20 @@ class PackageDistribution end - def self.create_table(db, inc, post_fix) + def self.create_table(db, inc, post_fix) db.do "CREATE TABLE distributions ( id INTEGER PRIMARY KEY #{inc}, name VARCHAR(32) NOT NULL UNIQUE, pkgsvr_url VARCHAR(256), pkgsvr_addr VARCHAR(64), - status VARCHAR(32) NOT NULL DEFAULT 'OPEN', + status VARCHAR(32) NOT NULL DEFAULT 'OPEN', description VARCHAR(256) ) #{post_fix}" end - + def self.load(name, db) row = db.select_one("SELECT * FROM distributions WHERE name='#{name}'") - if not row.nil? then - return load_row(row) - end - - return nil + return ( row.nil? ) ? nil : load_row(row) end @@ -78,23 +75,14 @@ class PackageDistribution def self.load_all(db) - result = [] rows = db.select_all("SELECT * FROM distributions") - rows.each do |row| - result.push load_row(row) - end - - return result + return rows.map{|x| load_row(x)} end def self.load_first(db) row = db.select_one("SELECT * FROM distributions") - if not row.nil? then - return load_row(row) - end - - return nil + return ( row.nil? ) ? nil : load_row(row) end @@ -103,7 +91,8 @@ class PackageDistribution pkgsvr_port = row['pkgsvr_addr'].split(":")[1].to_i new_obj = new(row['name'], row['pkgsvr_url'], pkgsvr_ip, pkgsvr_port, row['status']) new_obj.description = row['description'] - + new_obj.id = row['id'] + return new_obj end @@ -112,7 +101,7 @@ class PackageDistribution dist_addr = @pkgsvr_ip + ":" + @pkgsvr_port.to_s row = db.select_one("SELECT * FROM distributions WHERE name='#{@name}'") if row.nil? then - db.do "INSERT INTO distributions(name, pkgsvr_url, pkgsvr_addr, status, description) VALUES ('#{@name}','#{@pkgsvr_url}','#{dist_addr}','#{@status}', '#{@description}')" + db.do "INSERT INTO distributions(name, pkgsvr_url, pkgsvr_addr, status, description) VALUES ('#{@name}','#{@pkgsvr_url}','#{dist_addr}','#{@status}','#{@description}')" else db.do "UPDATE distributions SET pkgsvr_url='#{@pkgsvr_url}', pkgsvr_addr='#{dist_addr}', status='#{@status}', description='#{@description}' WHERE name='#{@name}'" end @@ -121,11 +110,7 @@ class PackageDistribution def self.get_distribution_id(db, dist_name) row = db.select_one("SELECT * FROM distributions WHERE name='#{dist_name}'") - if row.nil? then - return "NULL" - else - return row['id'] - end + return ( row.nil? ) ? "NULL" : row['id'] end end @@ -141,21 +126,13 @@ class DistributionManager # get default distribution def get_default_distribution_name() dist = get_first_distribution() - if not dist.nil? then - return dist.name - else - return nil - end + return ( dist.nil? ) ? nil : dist.name end def get_default_pkgsvr_url() dist = get_first_distribution() - if not dist.nil? then - return dist.pkgsvr_url - else - return "" - end + return ( dist.nil? ) ? "" : dist.pkgsvr_url end @@ -165,7 +142,6 @@ class DistributionManager @server.get_db_connection() do |db| return get_distribution_internal(name, db) end - return nil end @@ -186,7 +162,6 @@ class DistributionManager new_dist = PackageDistribution.new(name, pkgsvr_url, pkgsvr_ip, pkgsvr_port, "OPEN") new_dist.save(db) end - @server.log.info "Added a new distribution \"#{name}\"" return true end @@ -234,16 +209,16 @@ class DistributionManager dist = get_distribution_internal(name, db) if dist.nil? then return false end - dist.status = value ? "LOCKED" : "OPEN" + dist.status = (value)? "LOCKED" : "OPEN" dist.save(db) end - if result then - if value then + if result then + if value then @server.log.info "The distribution \"#{name}\" is locked!" else @server.log.info "The distribution \"#{name}\" is unlocked!" end - end + end return result end diff --git a/src/build_server/GitBuildProject.rb b/src/build_server/GitBuildProject.rb index 2063dab..be75aab 100644 --- a/src/build_server/GitBuildProject.rb +++ b/src/build_server/GitBuildProject.rb @@ -137,6 +137,8 @@ class GitBuildProject < CommonProject if is_new then db.do "INSERT INTO project_gits VALUES (#{@prj_id},'#{@repository}','#{@branch}')" + db.do "INSERT INTO group_project_accesses + VALUES ( (SELECT groups.id FROM groups WHERE groups.name = 'admin'),'#{@prj_id}','UNLOCK')" else db.do "UPDATE project_gits SET git_repos='#{@repository}',git_branch='#{@branch}' WHERE project_id=#{@prj_id})" end diff --git a/src/build_server/JobManager.rb b/src/build_server/JobManager.rb index 37147c2..b03213f 100644 --- a/src/build_server/JobManager.rb +++ b/src/build_server/JobManager.rb @@ -102,6 +102,16 @@ class JobManager return new_idx end + def is_user_accessable(job,user_id) + result = nil + @server.get_db_connection() do |db| + result = db.select_one "SELECT user_groups.group_id FROM user_groups,group_project_accesses + WHERE user_groups.group_id = group_project_accesses.group_id and + group_project_accesses.project_id = #{job.get_project.get_project_id} and + user_groups.user_id = #{user_id}" + end + return (not result.nil?) + end def create_new_register_job( file_path, dist_name ) return RegisterPackageJob.new( file_path, nil, @server, nil, dist_name ) diff --git a/src/build_server/ProjectManager.rb b/src/build_server/ProjectManager.rb index 25a498e..2a4e9e0 100644 --- a/src/build_server/ProjectManager.rb +++ b/src/build_server/ProjectManager.rb @@ -170,6 +170,32 @@ class ProjectManager return result end + public + def get_project_accessable(project_name, dist_name, user_id) + prj = get_project(project_name, dist_name) + result = nil + @server.get_db_connection() do |db| + result = db.select_one "SELECT user_groups.group_id FROM user_groups,group_project_accesses + WHERE user_groups.user_id = #{user_id} and + user_groups.group_id = group_project_accesses.group_id and + group_project_accesses.project_id = #{prj.get_project_id} and + group_project_accesses.build = 'UNLOCK'" + end + return (not result.nil?) + end + + def get_project_pkg_name_accessable(pkg_name, dist_name, user_id) + result = nil + prj = get_project_from_package_name(pkg_name, dist_name) + @server.get_db_connection() do |db| + result = db.select_one "SELECT user_groups.group_id FROM user_groups,group_project_accesses + WHERE user_groups.user_id = #{user_id} and + user_groups.group_id = group_project_accesses.group_id and + group_project_accesses.project_id = #{prj.get_project_id} and + group_project_accesses.build = 'UNLOCK'" + end + return (not result.nil?) + end # create new job for project # if cannot create, return nil @@ -250,16 +276,9 @@ class ProjectManager def get_project_from_package_name(pkg_name, dist_name) - get_all_projects().each do |prj| - if prj.type != "BINARY" then next end - # check project's distribution - if prj.dist_name != dist_name then next end - # check project provide target package - if prj.pkg_name == pkg_name then - return prj - end + @server.get_db_connection() do |db| + return get_project_from_pkg_name_internal(pkg_name,dist_name,db) end - return nil end @@ -335,4 +354,9 @@ class ProjectManager end end + private + def get_project_from_pkg_name_internal(pkg_name, dist_name, db) + row = CommonProject.get_project_from_pkg_name_row(pkg_name, dist_name, db) + return ( row.nil? ) ? nil : BinaryUploadProject.load(row[:name], dist_name, @server, db) + end end diff --git a/src/build_server/SocketJobRequestListener.rb b/src/build_server/SocketJobRequestListener.rb index ada54f8..81fef09 100644 --- a/src/build_server/SocketJobRequestListener.rb +++ b/src/build_server/SocketJobRequestListener.rb @@ -171,7 +171,6 @@ class SocketJobRequestListener end - # "BUILD" def handle_cmd_build( line, req ) tok = line.split("|").map { |x| x.strip } @@ -231,6 +230,7 @@ class SocketJobRequestListener raise "No user information!" end + # multi build job if project_name_list.count > 1 or os_list.count > 1 then new_job_list = [] @@ -239,6 +239,13 @@ class SocketJobRequestListener if not passwd_list[i].nil? then passwd = passwd_list[i] else passwd = passwd_list[0] end check_build_project(pname,passwd,dist_name,req) + if not check_project_user_id(pname,dist_name,user_id) then + BuildCommServer.send_begin(req) + req.puts "Error: \"#{user_email}\" can't access \"#{pname}\" project!" + req.puts "You are not in project control group" + BuildCommServer.send_end(req) + raise "#{user_email} can't accesse #{pname} project!" + end os_list.each do |os| new_job = create_new_job( pname, os, dist_name ) if new_job.nil? then @@ -285,6 +292,13 @@ class SocketJobRequestListener os = os_list[0] check_build_project(pname,passwd,dist_name,req) + if not check_project_user_id(pname,dist_name,user_id) then + BuildCommServer.send_begin(req) + req.puts "Error: \"#{user_email}\" can't access \"#{pname}\" project!" + req.puts "You are not in project control group" + BuildCommServer.send_end(req) + raise "#{user_email} can't accesse #{pname} project!" + end new_job = create_new_job( pname, os, dist_name ) if new_job.nil? then raise "\"#{pname}\" does not support #{os} in #{dist_name}" @@ -360,6 +374,7 @@ class SocketJobRequestListener case tok[1] # RESOLVE|GIT|project_name|passwd|os|async|dist_name|user_email|verbose when "GIT" + # parse project_name=tok[2] passwd=tok[3] @@ -395,24 +410,33 @@ class SocketJobRequestListener end os = os_list[0] - # create new job - new_job = create_new_job( project_name, os, dist_name ) - if new_job.nil? then - raise "Creating build job failed : #{project_name}, #{os}" - end - @log.info "Received a request for resolving this project : #{project_name}, #{os}" - # check user email user_id = @parent_server.check_user_id_from_email( user_email ) - if user_id != -1 then - new_job.user_id = user_id - else + if user_id == -1 then BuildCommServer.send_begin(req) req.puts "Error: Cannot find the user with \"#{user_email}\"!" BuildCommServer.send_end(req) raise "No user information!" end + # check user accessable + if not check_project_user_id(project_name,dist_name,user_id) then + BuildCommServer.send_begin(req) + req.puts "Error: \"#{user_email}\" can't access \"#{project_name}\" project!" + req.puts "You are not in project control group" + BuildCommServer.send_end(req) + raise "#{user_email} can't accesse #{project_name} project!" + end + + # create new job + new_job = create_new_job( project_name, os, dist_name ) + if new_job.nil? then + raise "Creating build job failed : #{project_name}, #{os}" + end + @log.info "Received a request for resolving this project : #{project_name}, #{os}" + + new_job.user_id = user_id + # resolve new_job.set_resolve_flag() @@ -589,6 +613,13 @@ class SocketJobRequestListener else if cancel_job.cancel_state == "NONE" then # check passwd + if not @parent_server.jobmgr.is_user_accessable(cancel_job,user_id) then + BuildCommServer.send_begin(req) + req.puts "Error: \"#{tok[3]}\" can't access \"#{cancel_job.get_project.name}\" project!" + req.puts "You are not in project control group" + BuildCommServer.send_end(req) + raise "#{tok[3]} can't accesse #{cancel_job.get_project.name} project!" + end if cancel_job.type == "MULTIBUILD" then cancel_job.get_sub_jobs().select{|x| x.cancel_state == "NONE" }.each do |sub| if not check_project_password( sub.get_project, tok[2], req) then @@ -677,7 +708,7 @@ class SocketJobRequestListener end # check distribution - if not check_distribution(dist_name, req) then + if not check_distribution(dist_name, req, true) then raise "The distribution error!!" end @@ -760,6 +791,23 @@ class SocketJobRequestListener raise "No project is defined for this binary : #{filename}!" end + # check user email + user_id = @parent_server.check_user_id_from_email( user_email ) + if user_id == -1 then + BuildCommServer.send_begin(req) + req.puts "Error: Cannot find the user with \"#{user_email}\"!" + BuildCommServer.send_end(req) + raise "No user information!" + end + + if not check_project_pkg_name_user_id(filename, dist_name, user_id) then + BuildCommServer.send_begin(req) + req.puts "Error: \"#{user_email}\" can't regist \"#{filename}\"!" + req.puts "You are not in project control group" + BuildCommServer.send_end(req) + raise "#{user_email} can't regist #{filename}!" + end + # check passwd if not check_project_password(prj, passwd, req) then raise "Project's password is not matched!!" @@ -772,14 +820,6 @@ class SocketJobRequestListener raise "Creating build job failed : #{prj.name}, #{filename}" end - # check user email - user_id = @parent_server.check_user_id_from_email( user_email ) - if user_id == -1 then - BuildCommServer.send_begin(req) - req.puts "Error: Cannot find the user with \"#{user_email}\"!" - BuildCommServer.send_end(req) - raise "No user information!" - end new_job.user_id = user_id # create logger and set @@ -854,6 +894,10 @@ class SocketJobRequestListener end + private + def check_project_user_id(project_name, dist_name, user_id) + return @parent_server.prjmgr.get_project_accessable(project_name, dist_name, user_id) + end private def check_project_exist(project_name, dist_name, req) @@ -869,6 +913,14 @@ class SocketJobRequestListener return prj end + private + def check_project_pkg_name_user_id(file_name, dist_name, user_id) + # get package name + new_name = file_name.sub(/(.*)_(.*)_(.*)\.zip/,'\1,\2,\3') + pkg_name = new_name.split(",")[0] + return @parent_server.prjmgr.get_project_pkg_name_accessable(pkg_name, dist_name, user_id) + end + private def check_project_for_package_file_name(filename, dist_name, req) # get package name @@ -887,7 +939,6 @@ class SocketJobRequestListener return prj end - private def check_project_password(prj, passwd, req) @@ -904,14 +955,13 @@ class SocketJobRequestListener private - def check_distribution(dist_name, req) + def check_distribution(dist_name, req, only_exist = false) dist = @parent_server.distmgr.get_distribution(dist_name) if dist.nil? then BuildCommServer.send_begin(req) req.puts "Error: The distribution \"#{dist_name}\" does not exist!" BuildCommServer.send_end(req) - return false - elsif dist.status != "OPEN" then + elsif dist.status != "OPEN" and not only_exist then BuildCommServer.send_begin(req) req.puts "Error: The distribution \"#{dist_name}\" is locked!" BuildCommServer.send_end(req) @@ -952,19 +1002,17 @@ class SocketJobRequestListener result.push svr_os end end + elsif @parent_server.supported_os_list.include?(os) then + result.push os else - if not @parent_server.supported_os_list.include?(os) then - BuildCommServer.send_begin(req) - req.puts "Error: Unsupported OS name \"#{os}\" is used!" - req.puts "Error: Check the following supported OS list. " - @parent_server.supported_os_list.each do |os_name| - req.puts " * #{os_name}" - end - BuildCommServer.send_end(req) - return nil - else - result.push os + BuildCommServer.send_begin(req) + req.puts "Error: Unsupported OS name \"#{os}\" is used!" + req.puts "Error: Check the following supported OS list. " + @parent_server.supported_os_list.each do |os_name| + req.puts " * #{os_name}" end + BuildCommServer.send_end(req) + return nil end end