From: Tobias Brunner Date: Fri, 12 Jun 2009 08:21:46 +0000 (+0200) Subject: Initial version of the ruby version of the make-testing script. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a37dd66006986aad321a68574275f0fadbea3f55;p=thirdparty%2Fstrongswan.git Initial version of the ruby version of the make-testing script. --- diff --git a/testing/config/default.yml b/testing/config/default.yml new file mode 100644 index 0000000000..fd1572bfd4 --- /dev/null +++ b/testing/config/default.yml @@ -0,0 +1,135 @@ +# Global configuration file for strongSwan UML testing. +# +# Copyright (C) 2009 Tobias Brunner +# Hochschule fuer Technik Rapperswil +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See . +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +# All tarballs must have on of the following extensions: +# .tar, .tar.gz, .tgz, .tar.bz2, .tbz + +<% testdir=TESTING_ROOT %> + +guests: + defaults: + # the strongswan version to be used. either the name of a strongswan config + # defined below or an inline strongswan config. + strongswan: default +#strongswan: +# source: git + # the kernel to be used. either the name of a kernel config defined below or + # an inline kernel config. + kernel: default + # the masterfs to be used (folder or tarball) + #masterfs: <%= testdir %>/master-fs-20090325.tar.bz2 + masterfs: <%= testdir %>/master + # templates (config files etc.) that are copied to the guests. a directory + # with the guest's name must exist in the directry set here. + templates: <%= testdir %>/hosts + # memory in MB per guest + mem: 64 + # consoles: xterm|pts + consoles: + - xterm + - pts + # allows to customize the values above for each host (options set here + # replace the defaults above for the specified host). Only the hosts listed + # here are actually built. + # possible values are: sun, moon, dave, carol, alice, venus bob and winnetou. + # of course, you can add other hostnames for your own scenarios. + hosts: + - sun: + strongswan: other + - moon: + - dave + - carol: +# kernel: older + - alice: + - venus + - bob: + kernel: already_built + mem: 128 + - winnetou + +# list of kernels +kernels: + default: + # which source is used to build the kernel (none|dir|git|tar) + # where 'dir' is synonymous with 'git' but 'checkout' is ignored + # if this option is omitted, 'none' is assumed + source: git + # if you set source to 'git', set the path to the git repository here + path: /home/tbrunner/kernel/net-next-2.6/ + # if source is 'git', this is the local branch, tag or commit to build. + # a tarball is created from there (using git archive) and that tarball + # is then used to build the kernel. + # if this option is omitted or empty, the build takes place directly in + # the repository. + checkout: 'v2.6.28' + patches: + - /home/tbrunner/workspace/git/src/dumm/patches/mconsole-exec-2.6.28.patch + # kernel configuration file, if no config file is defined, it is assumed + # that the config file is available in the source directory + config: <%= testdir %>/.config-2.6.28 + older: + # tarball source + source: tar + path: <%= testdir %>/linux-2.6.29.4.tar.bz2 + # list of optional kernel patches (.patch, .patch.bz2, .patch.gz extension) + patches: + #- <%= testdir %>/aead_init.patch.bz2 + # kernel configuration file + config: <%= testdir %>/.config-2.6.29 + + already_built: + # if source is not defined or set to 'none' the kernel can be specified + # directly +#source: none + path: /home/tbrunner/tbrunner/testing/umlbuild/linux-uml-2.6.21.1 + +strongswan: + default: + # same as for the kernel (dir|git|tar) + source: git + path: /home/tbrunner/workspace/git/ + checkout: master + # list of configure options + # e.g. eap_aka: yes -> --enable-eap-aka + # or eap_md5: no -> --disable-eap-md5 + options: + - curl: no + - ldap: no + - eap_aka: yes + - eap_sim: yes + - eap_sim_file: yes + - eap_md5: yes + - eap_mschapv2: yes + - eap_identity: yes + - eap_radius: yes + - sql: no + - sqlite: no + - md4: yes # required by eap-mschapv2 + - mediation: yes + - openssl: yes + - blowfish: yes + - twofish: yes + - serpent: yes + - kernel_pfkey: yes + - integrity_test: yes + - leak_detective: yes + - load_tests: yes + other: + source: tar + path: <%= testdir %>/strongswan-4.3.1.tar.gz + options: + - gmp: no + - openssl: yes + diff --git a/testing/lib/config.rb b/testing/lib/config.rb new file mode 100644 index 0000000000..534d1ded21 --- /dev/null +++ b/testing/lib/config.rb @@ -0,0 +1,119 @@ +=begin + Copyright (C) 2009 Tobias Brunner + Hochschule fuer Technik Rapperswil + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. See . + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. +=end + +require 'ostruct' + +require 'kernel_config' +require 'strongswan_config' +require 'guest_config' + +module Dumm + class Config + + # Creates a new Config instance, initialized with the values + # loaded from the config file. + def initialize(file) + @config = read_config(file) + @kernels = prepare_kernels + @strongswan = prepare_strongswan + @guests = prepare_guests + end + + # Return all strongSwan configurations that are referenced by any guest. + def strongswan + @strongswan.select do |name, strongswan| + @guests.any? { |name, guest| strongswan.eql? guest.strongswan } + end + end + + # Return all kernel configurations that are referenced by any guest. + def kernels + @kernels.select do |name, kernel| + @guests.any? { |name, guest| kernel.eql? guest.kernel } + end + end + + # Return all valid guest configurations. + def guests + @guests.reject { |name, guest| guest.invalid } + end + + private + + # Reads the config file. The file is processed with ERB before being + # loaded by YAML and converted into an OpenStruct. + def read_config(file) + require 'yaml' + require 'erb' + OpenStruct.new(YAML::load(ERB.new(IO.read(file)).result)) + end + + # Initializes the kernel configurations. + def prepare_kernels + @config.kernels ||= [] + @kernels = @config.kernels.inject({}) do |h, conf| + name, conf = *conf + h[name] = KernelConfig.new name, OpenStruct.new(conf) + h + end + end + + # Initializes the strongswan configurations. + def prepare_strongswan + @config.strongswan ||= [] + @strongswan = @config.strongswan.inject({}) do |h, conf| + name, conf = *conf + h[name] = StrongswanConfig.new name, OpenStruct.new(conf) + h + end + end + + # Initializes the guest configurations. + def prepare_guests + guests = OpenStruct.new @config.guests + defaults = read_guest_config("guests_defaults", guests.defaults) + guests.hosts ||= [] + @guests = guests.hosts.inject({}) do |h, conf| + name, conf = conf.is_a?(Hash) ? conf.shift : [conf, {}] + conf = read_guest_config("guests_#{name}", conf).delete_if { |k, v| v == nil } + conf = defaults.merge(conf) + h[name] = GuestConfig.new name, OpenStruct.new(conf) + h + end + end + + # Read a guest config and return it as Hash. + def read_guest_config(name, config) + c = OpenStruct.new config + h = OpenStruct.new + h.strongswan = if c.strongswan && c.strongswan.is_a?(Hash) + @strongswan[name] = StrongswanConfig.new name, c.strongswan + else + @strongswan[c.strongswan] + end + h.kernel = if c.kernel && c.kernel.is_a?(Hash) + @kernels[name] = KernelConfig.new name, c.kernel + else + @kernels[c.kernel] + end + h.masterfs = c.masterfs if c.masterfs && (Testing.tarball?(c.masterfs) || File.directory?(c.masterfs)) + h.templates = c.templates if c.templates && (c.templates.empty? || File.directory?(c.templates)) + h.mem = c.mem.to_i if c.mem + h.consoles = c.consoles.select { |c| c =~ /^(xterm|pts)$/ } if c.consoles + h.marshal_dump + end + + end +end diff --git a/testing/lib/console_format.rb b/testing/lib/console_format.rb new file mode 100644 index 0000000000..bdc7dc90aa --- /dev/null +++ b/testing/lib/console_format.rb @@ -0,0 +1,128 @@ +=begin + Copyright (C) 2008 Tobias Brunner + Hochschule fuer Technik Rapperswil + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. See . + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + $Id$ +=end + +# Simplifies formatting console output by using ANSI escape codes + +module Dumm + module ConsoleFormat + @@colors = { + :black => 0, + :red => 1, + :green => 2, + :yellow => 3, + :blue => 4, + :magenta => 5, + :cyan => 6, + :white => 7 + } + @@colors.default = 9 + + @@intensity = { :bold => 1 } + @@intensity.default = 22 + + @@blink = { :slow => 5, :rapid => 6 } + @@blink.default = 25 + + @@underline = { :single => 4, :double => 21 } + @@underline.default = 24 + + @@codes = @@colors.inject({}) { |codes, color| + codes[color[0]] = 30 + color[1] + codes[("b#{color[0]}".to_s).to_sym] = 40 + color[1] + codes + } + @@codes = @@codes.merge(@@intensity).merge(@@blink).merge(@@underline) + @@keywords = @@codes.keys.join("|") + + # returns the text either with or without ansi codes wrapped around + # depending on whether stdout is currently attached to a tty. + # FIXME: what if we want to write the text to a file i.e. not stdout + def self.format_text(text, code, force = false) + STDOUT.isatty || force ? "\e[0#{code}m#{text}\e[0m" : text + end + + # format is a hash with the following parameters: + # - :color: foreground color + # - :background: background color + # - :intensity: :bold + # - :blink: :slow, :rapid + # - :underline: :single, :double + def self.format(text, format = {}, force = false) + code = ";#{@@blink[format[:blink]]}" + code += ";#{@@underline[format[:underline]]}" + code += ";#{@@intensity[format[:intensity]]}" + code += ";3#{@@colors[format[:color]]}" + code += ";4#{@@colors[format[:background]]}" + format_text(text, code, force) + end + + # catches formats of the form: + # red_bwhite("red on white") + # red_bold("red bold") + # red_single("red underline single") + # ... + # background colors start with a 'b' + def self.method_missing(method, text) + method = method.to_s + if method =~ /^(#{@@keywords})(_(#{@@keywords}))*$/ + code = method.split(/_/).inject("") { |c, format| + c += ";#{@@codes[format.to_sym]}" + } + format_text(text, code) + end + end + + module ConsoleFormatWrapper + def self.method_missing(method, text) + ConsoleFormat.__send__ method, text + end + end + + # global shortcut function 'fmt' + module ::Kernel + def fmt(text = nil, format = {}, force = false) + if text + ConsoleFormat.format(text, format, force) + else + ConsoleFormatWrapper + end + end + end + end + + # Test + if __FILE__ == $0 + fmt "blank" + fmt "red", { :color => :red } + fmt.red_bold "red bold" + fmt.red_blue_byellow_single_bold "blue on yellow underline single_bold" + puts ConsoleFormat.format("red", { :color => :red }) + puts ConsoleFormat.format("blue background", { :background => :blue }) + puts ConsoleFormat.format("red on white background", { :color => :red, :background => :white }) + puts ConsoleFormat.format("red bold", { :color => :red, :intensity => :bold }) + puts ConsoleFormat.format("red blink (slow)", { :color => :red, :intensity => :bold, :blink => :slow }) + puts ConsoleFormat.format("red bold blink (rapid)", { :color => :red, :intensity => :bold, :blink => :rapid }) + puts ConsoleFormat.format("green underline single", { :color => :green, :underline => :single }) + puts ConsoleFormat.format("green underline double", { :color => :green, :underline => :double }) + puts ConsoleFormat.red_bold("red bold") + puts ConsoleFormat.red_bwhite_bold("red on white bold") + puts ConsoleFormat.red_single("red underline single") + puts ConsoleFormat.bold_red_single("red underline single bold") + puts ConsoleFormat.black_bwhite("black on white") + end +end + diff --git a/testing/lib/guest_config.rb b/testing/lib/guest_config.rb new file mode 100644 index 0000000000..21ec2e5a5d --- /dev/null +++ b/testing/lib/guest_config.rb @@ -0,0 +1,70 @@ +=begin + Copyright (C) 2009 Tobias Brunner + Hochschule fuer Technik Rapperswil + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. See . + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. +=end + +module Dumm + class GuestConfig + # The name of this guest config. + attr_reader :name + # The strongSwan config. + attr_reader :strongswan + # The kernel config + attr_reader :kernel + # The root directory of this guest (i.e. the diff to the master). + attr_reader :root + # True if this guest config is invalid + attr_reader :invalid + + def initialize(name, config) + @name = name + @needs_build = true + @strongswan, @kernel = config.strongswan, config.kernel + @masterfs, @templates = config.masterfs, config.templates + @mem, @consoles = config.mem, config.consoles + unless @strongswan && @kernel && @masterfs && @mem > 0 && @consoles && !@consoles.empty? + puts "Invalid guest configuration: #{name} #{config.inspect}" + @invalid = true + end + end + + def build + return unless @needs_build + args = "mem=#{@mem}M" + @consoles.each_with_index do |con, i| + args << " con#{i.next}=#{con}" + end + # TODO if the masterfs is a tarball, extract that first + #Dir.chdir(Testing.root) do + # Guest.new @name, @kernel.path || "/home/tbrunner/tbrunner/testing/umlbuild/linux-uml-2.6.21.1", @masterfs, args + #end + Dir.chdir(Testing.guests_dir) do + Dir.mkdir(name, 0775) + Dir.chdir(name) do + File.symlink(@masterfs, 'master') + File.symlink(@kernel.path, 'linux') + Dir.mkdir('diff', 0775) + Dir.mkdir('union', 0775) + File.open('args', 'w') { |f| f.write args } + end + end + @root = File.join(Testing.guests_dir, name, 'diff') + tmpl = File.join(@templates, name) + if File.directory?(tmpl) + FileUtils.cp_r(tmpl + '/.', @root) # '/.' is required to copy the contents of tmpl and not tmpl itself + end + @needs_build = false + end + + end +end diff --git a/testing/lib/kernel_config.rb b/testing/lib/kernel_config.rb new file mode 100644 index 0000000000..183c785d5e --- /dev/null +++ b/testing/lib/kernel_config.rb @@ -0,0 +1,118 @@ +=begin + Copyright (C) 2009 Tobias Brunner + Hochschule fuer Technik Rapperswil + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. See . + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. +=end + +module Dumm + class KernelConfig + # The name of this kernel + attr_reader :name + # The path to the kernel + attr_reader :path + + # Creates a new Kernel instance from the given configuration + def initialize(name, config) + @name = name + @needs_build = true + @source = (config.source || "none").to_sym + @config = config.config if File.file?(config.config || "") + config.patches ||= [] + @patches = config.patches.select { |p| File.exists?(p) && p =~ /\.patch(\.(bz2|gz))?$/ } + case @source + when :git, :dir + unless File.directory?(config.path) + raise "Path '#{config.path}' not found!" + end + @source_path = config.path + unless @source == :dir + raise "'#{@source_path} is not a git repository!" unless Testing.git?(@source_path) + @checkout = config.checkout if Testing.git_tree?(@source_path, config.checkout) + end + when :tar + raise "Tarball '#{config.path}' not found!" unless Testing.tarball?(config.path) + @source_path = config.path + else + raise "Kernel '#{config.path}' not found!" unless File.executable?(config.path) + @path = config.path + @needs_build = false + end + end + + # Build the kernel. + def build + return unless @needs_build + build_path = @source_path + case @source + when :git + if @checkout + tarball = Testing.archive_git(@source_path, @checkout, "kernel-#{@name}", Testing.build_dir) + build_path = Testing.extract_tarball(tarball, Testing.build_dir) + end + when :tar + build_path = Testing.extract_tarball(@source_path, Testing.build_dir) + end + + apply_patches(build_path) + ensure_config(build_path) + @path = File.join(Testing.build_dir, "kernel-#{name}-linux") + build_kernel(build_path, @path) + + # TODO we could remove the directory extracted from a tarball and the + # tarball itself if it was exported from git. + + @needs_build = false + end + + private + + # Apply a list of patches to the given source tree. + def apply_patches(dir) + Dir.chdir(dir) do + @patches.each do |patch| + comp = case patch + when /\.bz2$/: 'bz' + when /\.gz$/: 'z' + else '' + end + `#{comp}cat #{patch} | patch -p1 2>&1` + unless $?.success? + raise "Failed to apply patch '#{patch}' in '#{dir}'!" + end + end + end + end + + # Ensure that we have a kernel config. + def ensure_config(dir) + config = File.join(dir, ".config") + @config ||= config + raise "No kernel config found!" unless File.file?(@config) + FileUtils.copy_file(@config, config) + end + + # Build the kernel and move it to the given location. + def build_kernel(dir, kernel) + Dir.chdir(dir) do + # TODO what about logging + `make clean ARCH=um 2>&1` + # the next command might interact with the user. since '`' redirects + # stdout we would have to use 'system'. currently we use 'yes' to + # chose the default value for new kernel options. + `yes "" | make oldconfig ARCH=um 2>&1` + `make -j 2 linux ARCH=um 2>&1` + FileUtils.mv 'linux', kernel + end + end + + end +end diff --git a/testing/lib/strongswan_config.rb b/testing/lib/strongswan_config.rb new file mode 100644 index 0000000000..44058cec54 --- /dev/null +++ b/testing/lib/strongswan_config.rb @@ -0,0 +1,108 @@ +=begin + Copyright (C) 2009 Tobias Brunner + Hochschule fuer Technik Rapperswil + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. See . + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. +=end + +module Dumm + class StrongswanConfig + # The name of this strongSwan config. + attr_reader :name + + def initialize(name, config) + @name = name + @needs_build = true + @options = config.options + @source = (config.source || "none").to_sym + case @source + when :git, :dir + unless File.directory?(config.path) + raise "Path '#{config.path}' not found!" + end + @source_path = config.path + unless @source == :dir + raise "'#{@source_path} is not a git repository!" unless Testing.git?(@source_path) + @checkout = config.checkout if Testing.git_tree?(@source_path, config.checkout) + end + when :tar + raise "Tarball '#{config.path}' not found!" unless Testing.tarball?(config.path) + @source_path = config.path + else + raise "Specify the source type of strongSwan config '#{name}'" + end + end + + # Build the strongSwan sources. We build them only within the source tree + # if we extracted the sources from a tarball. Otherwise an out-of-tree build + # in a subdir of the testing build dir is done. + def build + return unless @needs_build + @build_path = File.join(Testing.build_dir, "strongswan-#{name}") + case @source + when :git + if @checkout + tarball = Testing.archive_git(@source_path, @checkout, "strongswan-#{@name}", Testing.build_dir) + @source_path = @build_path = Testing.extract_tarball(tarball, Testing.build_dir) + end + when :tar + @source_path = @build_path = Testing.extract_tarball(@source_path, Testing.build_dir) + end + + FileUtils.mkdir_p(@build_path) + configure(@source_path, @build_path) + make(@build_path) + + @needs_build = false + end + + def install(target) + Dir.chdir(@build_path) do + `make install DESTDIR="#{target}" 2>&1` + raise "Failed to install strongSwan '#{name}'!" unless $?.success? + # FIXME is ldconfig required? how do we run this + end + end + + private + + # Run the configure script located in directory 'sources' within the + # directory given as 'build'. autogen.sh is run if configure does not yet + # exist. + def configure(sources, build) + script = File.join(sources, "configure") + unless File.executable?(script) + Dir.chdir(sources) do + `./autogen.sh 2>&1` + raise "Failed to build configure script for strongSwan '#{name}'!" unless $?.success? + end + end + options = [ '--sysconfdir=/etc', '--with-random-device=/dev/urandom' ] + @options.each do |opt| + key, val = opt.shift + options << "--#{val ? 'enable' : 'disable'}-#{key.sub(/_/, '-')}" + end + Dir.chdir(build) do + `#{script} #{options.join(" ")} 2>&1` + raise "Failed to configure strongSwan '#{name}'!" unless $?.success? + end + end + + # Build the strongSwan sources. + def make(build) + Dir.chdir(build) do + `make -j 2>&1` + raise "Failed to build strongSwan '#{name}'!" unless $?.success? + end + end + + end +end diff --git a/testing/lib/testing.rb b/testing/lib/testing.rb new file mode 100644 index 0000000000..7444cd4bc8 --- /dev/null +++ b/testing/lib/testing.rb @@ -0,0 +1,152 @@ +=begin + Copyright (C) 2009 Tobias Brunner + Hochschule fuer Technik Rapperswil + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. See . + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. +=end + +$LOAD_PATH.unshift File.dirname(__FILE__) +require 'config' + +module Dumm + class Testing + class << self + # The base directory. + attr_reader :root + # The build directory. + attr_reader :build_dir + # The guests directory. + attr_reader :guests_dir + # The global Config instance + attr_reader :config + + def init + set_directories! + config_file = "#{root}/config/default.yml" + @config = Config.new(config_file) + end + + # Create the testing environment. + def make + make_kernel + make_guests + make_strongswan + end + + # Check if the given file is a tarball. + def tarball?(file) + file && File.file?(file) && file =~ /(\.tar(\.(bz2|gz))?|\.t[bg]z)$/ + end + + # Returns the name of the tarball without extension and path. + # This is the assumed name of the directory that the tarball extracts to. + def tarball_name(file) + file.sub(/^.*\/([^\/]+)(\.tar(\.(bz2|gz))?|\.t[bg]z)$/, '\1') + end + + # Check the given path for a git repository. If 'tree' is given we check + # that there exists such a point in the git history. + def git?(dir) + return false unless File.directory?(dir) + Dir.chdir(dir) do + !`git status`.empty? + end + end + + # Check that tree points to a valid point in the history of the git + # repository (commit, tag, branch). + def git_tree?(dir, tree) + return false unless File.directory?(dir) + Dir.chdir(dir) do + tree && !tree.empty? && !`git show #{tree}`.empty? + end + end + + # Extract the given tarball in directory 'dir'. The tarball is expected + # to extract into a directory of the same name. Returns the path to the + # extracted directory. + # If the expected directory already exists, nothing is done. + def extract_tarball(file, dir) + target = File.join(dir, tarball_name(file)) + return target if File.directory?(target) + Dir.chdir(dir) do + comp = case file + when /\.(bz2|tbz)$/: 'j' + when /\.(gz|tgz)$/: 'z' + else '' + end + unless system("tar x#{comp}f #{file} 2>&1") + raise "Failed to extract tarball '#{file}'!" + end + unless File.directory?(target) + raise "Tarball '#{file}' extracted to unexpected directory!" + end + end + target + end + + # Uses 'git archive' to build a tarball from the git repository in + # directory 'repo'. 'tree' is the tag, branch or commit from which the + # archive is built. The tarball is written to 'dir'/'name'.tar and it will + # extract to a directory named 'name'. The filename of the tarball is + # returned. + def archive_git(repo, tree, name, dir) + target = File.join(dir, "#{name}.tar") + Dir.chdir(repo) do + unless system("git archive --format=tar --prefix=#{name}/ #{tree} > #{target}") + raise "Failed to build archive from git repository '#{git}'!" + end + end + target + end + + private + + # Sets root to TESTING_ROOT and canonalizes it. Also sets the build + # and guest dir based on the root. + def set_directories! + require 'pathname' + raise 'TESTING_ROOT is not set' unless defined?(::TESTING_ROOT) + raise 'TESTING_ROOT is not a directory' unless File.directory?(::TESTING_ROOT) + @root = Pathname.new(::TESTING_ROOT).realpath.to_s + ::TESTING_ROOT.replace @root + @build_dir = File.join(@root, 'build') + @guests_dir = File.join(@root, 'guests') + end + + # Build all required kernels. + def make_kernel + config.kernels.each do |name, kernel| + kernel.build + end + end + + # Create all the guests. + def make_guests + config.guests.each do |name, guest| + guest.build + end + end + + # Build and install all strongSwan versions. + def make_strongswan + config.strongswan.each do |name, strongswan| + strongswan.build + guests = config.guests.select { |n, g| strongswan.eql? g.strongswan } + guests.each do |name, guest| + strongswan.install guest.root + end + end + end + + end + end +end diff --git a/testing/make-testing.rb b/testing/make-testing.rb new file mode 100755 index 0000000000..a75568b99a --- /dev/null +++ b/testing/make-testing.rb @@ -0,0 +1,62 @@ +#!/usr/bin/ruby + +=begin + Copyright (C) 2009 Tobias Brunner + Hochschule fuer Technik Rapperswil + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. See . + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. +=end + +#require 'dumm' +require 'lib/testing' +require 'fileutils' + +include Dumm + +# are we running as superuser +unless Process.uid == 0 + puts "Please run #{$0} as superuser!" + exit 1 +end + +TESTING_ROOT = File.dirname(__FILE__) + +Testing.init + +def continue?(msg) + puts msg + print "Continue? [Y|n]: " + if gets.capitalize =~ /^N.*/ + exit 1 + end +end + +# cleanup the build dir +build_dir = Testing.build_dir +if File.directory?(build_dir) + continue?("The existing build directory #{build_dir} will be deleted!") + FileUtils.remove_entry_secure(build_dir, force = true) +end +FileUtils.mkdir_p(build_dir) + +# cleanup the guest dir +guests_dir = Testing.guests_dir +if File.directory?(guests_dir) + continue?("All guests in #{guests_dir} will be deleted!") + #Guest.each { |g| g.delete } + FileUtils.remove_entry_secure(guests_dir, force = true) +end +FileUtils.mkdir_p(guests_dir) + +Testing.make + +puts "built" +