public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Pavlos Ratis" <dastergon@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/security:master commit in: bin/
Date: Mon,  4 Aug 2014 23:45:11 +0000 (UTC)	[thread overview]
Message-ID: <1305653275.22546d7465a9c58a7bb3487d5611b33e93b1f6cc.dastergon@gentoo> (raw)

commit:     22546d7465a9c58a7bb3487d5611b33e93b1f6cc
Author:     Alex Legler <a3li <AT> gentoo <DOT> org>
AuthorDate: Tue May 17 17:27:55 2011 +0000
Commit:     Pavlos Ratis <dastergon <AT> gentoo <DOT> org>
CommitDate: Tue May 17 17:27:55 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/security.git;a=commit;h=22546d74

acutally add the new tool

svn path=/; revision=2228

---
 bin/target | 346 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 346 insertions(+)

diff --git a/bin/target b/bin/target
new file mode 100755
index 0000000..22001dd
--- /dev/null
+++ b/bin/target
@@ -0,0 +1,346 @@
+#!/usr/bin/env ruby
+# Target 2
+# written by Alex Legler <a3li@gentoo.org>
+# dependencies: app-portage/gentoolkit, dev-lang/ruby[ssl], dev-ruby/highline
+# vim: set sw=2 ts=2:
+
+require 'optparse'
+require 'highline'
+require 'fileutils'
+require 'xmlrpc/client'
+
+class Net::HTTP
+	alias_method :old_initialize, :initialize
+	def initialize(*args)
+		old_initialize(*args)
+		@ssl_context = OpenSSL::SSL::SSLContext.new
+		@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
+	end
+end
+
+module GenSec
+	module Target
+		# These architectures don't stabilize packages
+		NOSTABLE_ARCHES = ['mips']
+
+		def main(argv)
+			$opts = {
+				:auth_cache => true,
+				:force => false,
+				:liaisons => false,
+				:username => nil,
+				:prestable => false,
+				:quiet => false
+			}
+
+			$ui = HighLine.new
+
+			bug = nil
+			version = nil
+			slot = nil
+
+			optparse = OptionParser.new do |opts|
+				opts.on('-b', '--bug BUGNO', 'The number of the bug to change') do |b|
+					bug = Integer(b)
+				end
+
+				opts.on('-v', '--version VERSION', 'Use this version as stabilization target') do |v|
+					version = v
+				end
+
+				opts.on('-s', '--slot SLOT', 'Use ebuilds from this slot to find the best ebuild') do |s|
+					slot = s
+				end
+
+				opts.on('-l', '--liaisons', 'CC the arch liaisons instead of arch teams') do
+					$opts[:liaisons] = true
+				end
+
+				opts.on('-p', '--prestable', 'Use prestabling instructions') do
+					$opts[:prestable] = true
+				end
+
+				opts.on('-u', '--username USERNAME', 'Use this user name to log in at Bugzilla') do |username|
+					$opts[:username] = username
+				end
+
+				opts.on_tail('-f', '--force', 'Force the operation. Disables asking for confirmation and version checks.') do
+					$opts[:force] = true
+				end
+
+				opts.on_tail('-q', '--quiet', 'Be less noisy') do
+					$opts[:quiet] = true
+				end
+
+				opts.on_tail('-h', '--help', 'Display this screen') do
+					puts opts
+					exit
+				end
+				
+			end
+
+			optparse.banner = "Usage: #{$0} [options] [package]\n\nAvailable options:\n"
+			cmd_options = optparse.parse!(argv)
+
+			if argv.length > 0
+				package = argv.shift
+			else
+				package = Dir.pwd.split('/').last(2).join('/')
+			end
+
+			metadata = get_metadata(package)
+			do_package(metadata, bug, version, slot)
+		end
+
+		def do_package(metadata, bug, version, slot)
+			if metadata[:package] == nil or metadata[:package] == ''
+				e("No package found.")
+			end
+
+			i("Using #{metadata[:package]}") unless $opts[:quiet]
+			#puts metadata.inspect
+
+			best_version = find_best_version(metadata, slot, version)
+			i("Target version: #{best_version}") unless $opts[:quiet]
+
+			# Cover a custom version string that is not there in the local tree
+			if metadata[:keywords].include? best_version
+				already_stable = filter_unstable(metadata[:keywords][best_version]) - NOSTABLE_ARCHES
+			else
+				already_stable = []
+			end
+
+			need_stable = metadata[:stable_arches] - NOSTABLE_ARCHES
+
+			i("Arches this package was ever stable on: #{$ui.color(need_stable.join(', '), :red, :bold)}") unless $opts[:quiet]
+
+			if already_stable.length > 0
+				i("Target version is already stable on:    #{$ui.color(already_stable.join(', '), :green, :bold)}") unless $opts[:quiet]
+			end
+
+			if $opts[:prestable]
+				msg = "Arch Security Liaisons, please test the attached ebuild and report it stable on this bug.\n"
+			elsif $opts[:liaisons] and not $opts[:prestable]
+				msg = "Arch Security Liaisons, please test and mark stable:\n"
+			else
+				msg = "Arches, please test and mark stable:\n"
+			end
+
+			if not $opts[:prestable]
+				msg += "=%s-%s\n" % [metadata[:package], best_version]
+			end
+
+			msg += "Target keywords : \"%s\"\n" % metadata[:stable_arches].join(' ')
+
+			if already_stable.length > 0 and not $opts[:prestable]
+				msg += "Already stable  : \"%s\"\n" % (already_stable.join(' '))
+				msg += "Missing keywords: \"%s\"\n" % (metadata[:stable_arches] - already_stable).join(' ')
+			end
+
+			puts
+			puts msg
+			puts
+
+			if $opts[:liaisons]
+				require File.join(File.dirname(__FILE__), 'liaisons')
+				cc_list = need_stable.map {|arch| @liaisons[arch]}.flatten.map {|liaison| "#{liaison}@gentoo.org"}
+			else
+				cc_list = need_stable.map {|arch| "#{arch}@gentoo.org" }
+			end
+			puts "CC: %s" % cc_list.join(',')
+			exit if bug == nil
+
+			bugi = bug_info(bug)
+			new_whiteboard = update_whiteboard(bugi['whiteboard'])
+
+			puts "Whiteboard: '%s' -> '%s'" % [bugi['whiteboard'], new_whiteboard]
+			puts
+
+			if $opts[:force] or $ui.agree('Continue? (yes/no)')
+				update_bug(bug, new_whiteboard, cc_list, msg)
+			end
+		end
+
+		# Collects metadata information from equery meta
+		def get_metadata(ebuild = Dir.pwd.split('/').last(2).join('/'))
+			keywords = IO.popen("equery --no-color --no-pipe meta --keywords #{ebuild}")
+			result = {:slots => {}, :keywords => {}, :stable_arches => [], :versions => []}
+
+			keywords.lines.each do |line|
+				if line =~ /^ \* (\S*?)\/(\S*?) \[([^\]]*)\]$/
+					result[:package] = "#{$1}/#{$2}"
+					result[:repo] = $3
+					next
+				end
+
+				if line =~ /^(.*?):(.*?):(.*?)$/
+					version, slot, kws = $1, $2, $3
+					result[:versions] << version
+					result[:slots][slot] = [] unless result[:slots].include? slot
+					result[:slots][slot] << version
+					result[:keywords][version] = []
+
+					kws.strip.split(' ').each do |arch|
+						result[:keywords][version] << arch
+
+						if arch =~ /^[^~]*$/
+							result[:stable_arches] << arch
+						end
+					end
+
+					result[:keywords][version].sort!
+					next
+				end
+
+				raise RuntimeError, "Invalid line in equery output. Aborting."
+			end
+
+			result[:stable_arches].uniq!
+			result[:stable_arches].sort!
+			result
+		end
+
+		# Tries to find the best version following the needed specification
+		def find_best_version(metadata, slot, version)
+			if slot == nil and version == nil
+				return metadata[:versions].reject {|item| item =~ /^9999/}.last
+			elsif slot == nil
+				return version
+			else
+				if version == nil
+					return metadata[:slots][slot].reject {|item| item =~ /^9999/}.last
+				elsif metadata[:slots][slot].include?(version)
+					return version
+				else
+					return false
+				end
+			end
+		end
+
+		def update_whiteboard(old_wb)
+			old_wb.gsub(/(ebuild\+?|upstream\+?|stable)\??/, 'stable').gsub(/stable\/stable/, 'stable')
+		end
+
+		def update_bug(bug, whiteboard, cc_list, comment)
+			i("Updating bug #{bug}...")
+			client = xmlrpc_client
+			did_retry = false
+
+			begin
+				result = client.call('Bug.update', {
+					'ids' => [Integer(bug)],
+					'whiteboard' => whiteboard,
+					'cc' => {'add' => cc_list},
+					'keywords' => {'add' => 'STABLEREQ'},
+					'status' => 'IN_PROGRESS',
+					'comment' => {'body' => comment}
+				})
+
+				i("done!")
+				return true
+			rescue XMLRPC::FaultException => e
+				if did_retry
+					e "Failure updating bug information: #{e.message}"
+					return false
+				end
+
+				if e.faultCode == 410
+					log_in
+					did_retry = true
+					retry
+				else
+					e "Failure updating bug information: #{e.message}"
+				end
+			end
+		end
+
+		def bug_info(bugno)
+			client = xmlrpc_client
+			did_retry = false
+
+			begin
+				result = client.call('Bug.get', {'ids' => [Integer(bugno)]})
+				result['bugs'].first
+			rescue XMLRPC::FaultException => e
+				if did_retry
+					e "Failure reading bug information: #{e.message}"
+					return false
+				end
+
+				if e.faultCode == 410
+					log_in
+					did_retry = true
+					retry
+				else
+					e "Failure reading bug information: #{e.message}"
+				end
+			end
+		end
+
+		def log_in
+			client = xmlrpc_client
+
+			if $opts[:username] == nil
+				user = $ui.ask("Bugzilla login: ")
+			else
+				user = $opts[:username]
+			end
+
+			password = $ui.ask("Password: ") {|q| q.echo = false}
+
+			begin
+				i("Logging in...")
+				result = client.call('User.login', {
+					'login' => user,
+					'password' => password
+				})
+
+				cookie_file = File.join(ENV['HOME'], '.gensec-target-auth')
+				FileUtils.rm(cookie_file) if File.exist?(cookie_file)
+				FileUtils.touch(cookie_file)
+				File.chmod(0600, cookie_file)
+				File.open(cookie_file, 'w') {|f| f.write client.cookie }
+
+				return true
+			rescue XMLRPC::FaultException => e
+				e "Failure logging in: #{e.message}"
+				return false
+			end
+		end
+
+		def xmlrpc_client
+			client = XMLRPC::Client.new('bugs.gentoo.org', '/xmlrpc.cgi', 443, nil, nil, nil, nil, true)
+			client.http_header_extra = {'User-Agent' => "Target/2.0 (arch CC tool; http://security.gentoo.org/)"}
+
+			cookie_file = File.join(ENV['HOME'], '.gensec-target-auth')
+			if File.readable? cookie_file
+				client.cookie = File.read(cookie_file)
+			end
+
+			client
+		end
+
+		# Output and misc methods
+		def i(str)
+			$ui.say($ui.color(" * ", :green, :bold) + str)
+		end
+
+		def w(str)
+			$ui.say($ui.color(" * ", :yellow, :bold) + str)
+		end
+
+		def e(str)
+			$ui.say($ui.color(" * ", :red, :bold) + str)
+			exit 1
+		end
+
+		def filter_unstable(ary)
+			ary.reject {|item| item =~ /^~/}
+		end
+	end
+end
+
+if __FILE__ == $0
+	include GenSec::Target
+	main(ARGV)
+end


             reply	other threads:[~2014-08-04 23:45 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-04 23:45 Pavlos Ratis [this message]
  -- strict thread matches above, loose matches on Subject: below --
2014-08-04 23:45 [gentoo-commits] proj/security:master commit in: bin/ Pavlos Ratis
2014-08-04 23:45 Pavlos Ratis
2014-08-04 23:45 Pavlos Ratis
2016-06-01 17:57 Alex Legler
2017-01-13 10:45 Thomas Deutschmann
2017-01-13 10:45 Thomas Deutschmann
2017-01-16  5:53 Thomas Deutschmann
2017-01-16  5:53 Thomas Deutschmann
2017-04-25 17:44 Thomas Deutschmann
2020-03-04  4:06 Thomas Deutschmann
2020-03-04  4:06 Thomas Deutschmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1305653275.22546d7465a9c58a7bb3487d5611b33e93b1f6cc.dastergon@gentoo \
    --to=dastergon@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox