brightbox-boxgrinder-plugins 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/Manifest +0 -1
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/brightbox-boxgrinder-plugins.gemspec +11 -12
- data/lib/brightbox-boxgrinder-plugins.rb +0 -1
- data/lib/delivery/bbcloud-delivery-plugin.rb +51 -9
- data/lib/platform/bbcloud-platform-plugin.rb +66 -39
- metadata +7 -11
- data/lib/os/sl-plugin.rb +0 -57
data/CHANGELOG
CHANGED
data/Manifest
CHANGED
data/README.md
CHANGED
@@ -4,11 +4,11 @@ This archive integrates the Boxgrinder project [boxgrinder.org](http://www.boxgr
|
|
4
4
|
|
5
5
|
### Supported OSes
|
6
6
|
|
7
|
-
Brightbox supports all the OSs that Boxgrinder can generate
|
7
|
+
Brightbox supports all the OSs that Boxgrinder can generate.
|
8
8
|
|
9
9
|
### Requirements
|
10
10
|
|
11
|
-
* A RPM based build machine -
|
11
|
+
* A RPM based build machine - use the current public Boxgrinder appliance registered on the Brightbox cloud
|
12
12
|
* This plugin gem installed.
|
13
13
|
|
14
14
|
### Installing
|
data/Rakefile
CHANGED
@@ -30,7 +30,7 @@ Echoe.new("brightbox-boxgrinder-plugins") do |p|
|
|
30
30
|
p.author = "Neil Wilson"
|
31
31
|
p.email = "hello@brightbox.co.uk"
|
32
32
|
p.summary = "Brightbox Cloud support for Boxgrinder"
|
33
|
-
p.url = "http://
|
33
|
+
p.url = "http://brightbox.com"
|
34
34
|
p.runtime_dependencies = ['brightbox-cli']
|
35
35
|
end
|
36
36
|
|
@@ -1,25 +1,24 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
5
|
-
s.version = "0.0.
|
4
|
+
s.name = "brightbox-boxgrinder-plugins"
|
5
|
+
s.version = "0.0.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Neil Wilson"]
|
9
|
-
s.date =
|
10
|
-
s.description =
|
11
|
-
s.email =
|
12
|
-
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "lib/brightbox-boxgrinder-plugins.rb", "lib/delivery/bbcloud-delivery-plugin.rb", "lib/
|
13
|
-
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.md", "Rakefile", "lib/brightbox-boxgrinder-plugins.rb", "lib/delivery/bbcloud-delivery-plugin.rb", "lib/
|
14
|
-
s.homepage =
|
9
|
+
s.date = "2012-06-27"
|
10
|
+
s.description = "Brightbox Cloud support for Boxgrinder"
|
11
|
+
s.email = "hello@brightbox.co.uk"
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "lib/brightbox-boxgrinder-plugins.rb", "lib/delivery/bbcloud-delivery-plugin.rb", "lib/platform/bbcloud-platform-plugin.rb", "lib/platform/src/rc_local"]
|
13
|
+
s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.md", "Rakefile", "lib/brightbox-boxgrinder-plugins.rb", "lib/delivery/bbcloud-delivery-plugin.rb", "lib/platform/bbcloud-platform-plugin.rb", "lib/platform/src/rc_local", "brightbox-boxgrinder-plugins.gemspec"]
|
14
|
+
s.homepage = "http://brightbox.com"
|
15
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Brightbox-boxgrinder-plugins", "--main", "README.md"]
|
16
16
|
s.require_paths = ["lib"]
|
17
|
-
s.rubyforge_project =
|
18
|
-
s.rubygems_version =
|
19
|
-
s.summary =
|
17
|
+
s.rubyforge_project = "Brightbox Cloud"
|
18
|
+
s.rubygems_version = "1.8.15"
|
19
|
+
s.summary = "Brightbox Cloud support for Boxgrinder"
|
20
20
|
|
21
21
|
if s.respond_to? :specification_version then
|
22
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
22
|
s.specification_version = 3
|
24
23
|
|
25
24
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
@@ -21,9 +21,20 @@ require 'boxgrinder-build/plugins/base-plugin'
|
|
21
21
|
|
22
22
|
module BoxGrinder
|
23
23
|
class BbcloudDeliveryPlugin < BasePlugin
|
24
|
+
|
25
|
+
plugin :type => :delivery, :name => :bbcloud, :full_name => "Brightbox Cloud Image Registration Service"
|
26
|
+
def after_init
|
27
|
+
set_default_config_value('description', default_description)
|
28
|
+
set_default_config_value('name', default_name)
|
29
|
+
set_default_config_value('username', default_username)
|
30
|
+
set_default_config_value('mode', default_mode)
|
31
|
+
set_default_config_value('public', default_public)
|
32
|
+
validate_mode
|
33
|
+
validate_public
|
34
|
+
end
|
24
35
|
|
25
36
|
def execute( type = :bbcloud )
|
26
|
-
@log.info "Adding '#{@
|
37
|
+
@log.info "Adding '#{@plugin_config['name']}' appliance to Brightbox Cloud..."
|
27
38
|
@log.info "Using Brightbox account id #{account}"
|
28
39
|
upload
|
29
40
|
register_image
|
@@ -32,14 +43,14 @@ module BoxGrinder
|
|
32
43
|
def upload
|
33
44
|
@log.info "Uploading to #{ftp_hash['library_ftp_host']} with secure FTP"
|
34
45
|
if system curl_command
|
35
|
-
@log.info "Appliance #{@
|
46
|
+
@log.info "Appliance #{@plugin_config['name']} uploaded."
|
36
47
|
else
|
37
48
|
raise "An error occurred while uploading files."
|
38
49
|
end
|
39
50
|
end
|
40
51
|
|
41
52
|
def register_image
|
42
|
-
@log.info "Registering appliance as #{image_id} under account #{account} with the name '#{
|
53
|
+
@log.info "Registering appliance as #{image_id} under account #{account} with the name '#{@plugin_config['name']}'"
|
43
54
|
@log.info "Run 'brightbox-images show #{image_id}' to check registration progress"
|
44
55
|
end
|
45
56
|
|
@@ -53,7 +64,7 @@ module BoxGrinder
|
|
53
64
|
end
|
54
65
|
|
55
66
|
def account
|
56
|
-
@account ||= @exec_helper.execute("brightbox-accounts -s list").split[0]
|
67
|
+
@account ||= @exec_helper.execute("brightbox-accounts -s list 2>/dev/null").split[0]
|
57
68
|
rescue RuntimeError => e
|
58
69
|
@log.error e.message
|
59
70
|
raise PluginValidationError, "Make sure the that brightbox cloud API tools are installed. Use 'brightbox-config client_add' to add the api client details for your account."
|
@@ -72,18 +83,49 @@ module BoxGrinder
|
|
72
83
|
end
|
73
84
|
|
74
85
|
def curl_command
|
75
|
-
"curl -# -u #{ftp_hash['library_ftp_user']}:#{ftp_hash['library_ftp_password']} --ftp-ssl-control -T #{disk_image} ftp://#{ftp_hash['library_ftp_host']}/incoming/#{target_name}"
|
86
|
+
"curl #{if ENV['INSECURE'] then "-k" end} -# -u #{ftp_hash['library_ftp_user']}:#{ftp_hash['library_ftp_password']} --ftp-ssl-control -T #{disk_image} ftp://#{ftp_hash['library_ftp_host']}/incoming/#{target_name}"
|
76
87
|
end
|
77
88
|
|
78
|
-
def
|
79
|
-
|
89
|
+
def default_name
|
90
|
+
@appliance_config.name
|
91
|
+
end
|
92
|
+
|
93
|
+
def default_description
|
94
|
+
@appliance_config.summary
|
95
|
+
end
|
96
|
+
|
97
|
+
def default_mode
|
98
|
+
'virtio'
|
99
|
+
end
|
100
|
+
|
101
|
+
def default_username
|
102
|
+
'brightbox'
|
103
|
+
end
|
104
|
+
|
105
|
+
def default_public
|
106
|
+
'false'
|
107
|
+
end
|
108
|
+
|
109
|
+
def validate_mode
|
110
|
+
case @plugin_config['mode']
|
111
|
+
when 'compatibility', 'virtio'
|
112
|
+
else
|
113
|
+
raise PluginValidationError, "Valid values for #{@plugin_info[:full_name]} plugin 'mode' option are 'compatibility' or 'virtio'"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def validate_public
|
118
|
+
case @plugin_config['public']
|
119
|
+
when 'true', 'false'
|
120
|
+
else
|
121
|
+
raise PluginValidationError, "Valid values for #{@plugin_info[:full_name]} plugin 'public' option are 'true' or 'false'"
|
122
|
+
end
|
80
123
|
end
|
81
124
|
|
82
125
|
def register_image_command
|
83
|
-
"brightbox-images register -a #{@appliance_config.hardware.arch} -s #{target_name} -n '#{
|
126
|
+
"brightbox-images register -a #{@appliance_config.hardware.arch} -s #{target_name} -n '#{@plugin_config['name']}' -d '#{@plugin_config['description']}' -u '#{@plugin_config['username']}' -m '#{@plugin_config['mode']}' -p '#{@plugin_config['public']}'"
|
84
127
|
end
|
85
128
|
|
86
129
|
end
|
87
130
|
end
|
88
131
|
|
89
|
-
plugin :class => BoxGrinder::BbcloudDeliveryPlugin, :type => :delivery, :name => :bbcloud, :full_name => "Brightbox Cloud Image Registration Service"
|
@@ -18,48 +18,48 @@
|
|
18
18
|
# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
19
19
|
|
20
20
|
require 'boxgrinder-build/plugins/base-plugin'
|
21
|
-
require 'boxgrinder-build/helpers/linux-helper'
|
22
21
|
require 'tempfile'
|
23
22
|
|
24
23
|
module BoxGrinder
|
25
24
|
class BbcloudPlatformPlugin < BasePlugin
|
26
|
-
|
27
|
-
register_deliverable(:disk => "#{deliverable_name}.gz")
|
28
|
-
|
29
|
-
register_supported_os('fedora', ['13', '14', '15'])
|
30
|
-
register_supported_os('centos', ['5'])
|
31
|
-
register_supported_os('rhel', ['5', '6'])
|
32
|
-
register_supported_os('sl', ['5', '6'])
|
33
|
-
end
|
25
|
+
plugin :type => :platform, :name => :bbcloud, :full_name => "Brightbox Cloud"
|
34
26
|
|
35
|
-
def
|
36
|
-
"#{
|
27
|
+
def after_init
|
28
|
+
register_deliverable(:disk => "#{deliverable_name}.qcow2")
|
29
|
+
set_default_config_value('username', default_user)
|
30
|
+
@appliance_config.packages |= %w{cloud-init} if has_cloud_init?
|
37
31
|
end
|
38
32
|
|
39
33
|
def execute
|
40
|
-
@linux_helper = LinuxHelper.new(:log => @log)
|
41
|
-
|
42
34
|
@log.info "Converting #{@appliance_config.name} appliance image to use Brightbox metadata services"
|
43
35
|
|
44
|
-
@
|
36
|
+
@log.debug "Using qemu-img to convert the image to qcow2 format..."
|
37
|
+
@image_helper.convert_disk(@previous_deliverables.disk, :qcow2, @deliverables.disk)
|
38
|
+
@log.debug "Conversion done."
|
45
39
|
|
46
|
-
@
|
47
|
-
|
40
|
+
@log.debug "Adding metadata customisations"
|
41
|
+
@image_helper.customize([@deliverables.disk], :automount => true) do |guestfs, guestfs_helper|
|
48
42
|
add_default_user(guestfs)
|
49
|
-
disable_root_password(
|
50
|
-
|
43
|
+
disable_root_password(guestfs_helper)
|
44
|
+
set_default_timezone(guestfs_helper)
|
45
|
+
change_ssh_configuration(guestfs_helper)
|
46
|
+
if has_cloud_init?
|
47
|
+
customise_cloud_init(guestfs_helper)
|
48
|
+
else
|
49
|
+
update_rc_local(guestfs)
|
50
|
+
end
|
51
51
|
execute_post(guestfs_helper)
|
52
52
|
end
|
53
|
-
|
54
|
-
@log.info "Image converted to Brightbox format, compressing"
|
55
|
-
@exec_helper.execute("gzip --fast -v #{uncompressed_disk_name}")
|
56
|
-
@log.info "Disk compressed"
|
53
|
+
@log.debug "Added customisations"
|
57
54
|
end
|
58
55
|
|
59
|
-
def
|
60
|
-
@
|
56
|
+
def has_cloud_init?
|
57
|
+
@appliance_config.os.name == 'fedora' and @appliance_config.os.version >= '16'
|
61
58
|
end
|
62
59
|
|
60
|
+
def customise_cloud_init(guestfs_helper)
|
61
|
+
guestfs_helper.sh("sed -i 's/^user: ec2-user$/user: #{@plugin_config['username']}/' /etc/cloud/cloud.cfg")
|
62
|
+
end
|
63
63
|
|
64
64
|
def execute_post(guestfs_helper)
|
65
65
|
if @appliance_config.post['bbcloud']
|
@@ -68,7 +68,7 @@ module BoxGrinder
|
|
68
68
|
end
|
69
69
|
@log.debug "Post commands from appliance definition file executed."
|
70
70
|
else
|
71
|
-
@log.debug "No commands specified, skipping."
|
71
|
+
@log.debug "No Post commands specified, skipping."
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
@@ -76,41 +76,68 @@ module BoxGrinder
|
|
76
76
|
"brightbox"
|
77
77
|
end
|
78
78
|
|
79
|
+
def deliverable_name
|
80
|
+
"#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}-#{@appliance_config.os.name}-#{@appliance_config.os.version}"
|
81
|
+
end
|
82
|
+
|
79
83
|
def add_default_user(guestfs)
|
80
|
-
@log.debug "Adding #{
|
81
|
-
guestfs.
|
82
|
-
|
83
|
-
|
84
|
+
@log.debug "Adding #{@plugin_config['username']} user..."
|
85
|
+
unless guestfs.fgrep(@plugin_config['username'], "/etc/passwd").empty?
|
86
|
+
@log.debug("#{@plugin_config['username']} already exists, skipping.")
|
87
|
+
return
|
88
|
+
end
|
89
|
+
guestfs.sh("useradd #{@plugin_config['username']}")
|
90
|
+
guestfs.sh("echo -e '#{@plugin_config['username']}\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers")
|
91
|
+
@log.debug "User #{@plugin_config['username']} added."
|
84
92
|
end
|
85
93
|
|
86
|
-
def disable_root_password(
|
94
|
+
def disable_root_password(guestfs_helper)
|
87
95
|
@log.debug "Disabling root password"
|
88
|
-
|
89
|
-
@log.
|
96
|
+
guestfs_helper.sh("usermod -L root")
|
97
|
+
@log.info "root password disabled - use sudo from #{@plugin_config['username']} account"
|
90
98
|
end
|
91
99
|
|
92
|
-
def
|
93
|
-
@log.debug "
|
100
|
+
def update_rc_local(guestfs)
|
101
|
+
@log.debug "Updating '/etc/rc.d/rc.local' file..."
|
94
102
|
rc_local = Tempfile.new('rc_local')
|
95
|
-
|
103
|
+
|
104
|
+
if guestfs.exists("/etc/rc.d/rc.local") == 1
|
105
|
+
# We're appending
|
106
|
+
rc_local << guestfs.read_file("/etc/rc.d/rc.local")
|
107
|
+
else
|
108
|
+
# We're creating new file
|
109
|
+
rc_local << "#!/bin/bash\n\n"
|
110
|
+
end
|
111
|
+
|
112
|
+
rc_local << File.read("#{File.dirname(__FILE__)}/src/rc_local")
|
96
113
|
rc_local.flush
|
97
114
|
|
98
|
-
guestfs.upload(rc_local.path, "/etc/rc.local")
|
115
|
+
guestfs.upload(rc_local.path, "/etc/rc.d/rc.local")
|
99
116
|
|
100
117
|
rc_local.close
|
101
|
-
@log.debug "'/etc/rc.local' file uploaded."
|
102
118
|
end
|
103
119
|
|
104
|
-
def
|
120
|
+
def change_ssh_configuration(guestfs_helper)
|
105
121
|
guestfs_helper.augeas do
|
106
122
|
# disable password authentication
|
107
123
|
set("/etc/ssh/sshd_config", "PasswordAuthentication", "no")
|
108
124
|
|
109
125
|
# disable root login
|
110
126
|
set("/etc/ssh/sshd_config", "PermitRootLogin", "no")
|
127
|
+
|
128
|
+
# Switch off GSS Authentication
|
129
|
+
set("/etc/ssh/sshd_config", "GSSAPIAuthentication", "no")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def set_default_timezone(guestfs_helper)
|
134
|
+
guestfs_helper.augeas do
|
135
|
+
set("/etc/sysconfig/clock", "UTC", "True")
|
136
|
+
set("/etc/sysconfig/clock", "ZONE", "Etc/UTC")
|
111
137
|
end
|
138
|
+
guestfs_helper.guestfs.cp("/usr/share/zoneinfo/UTC", "/etc/localtime")
|
112
139
|
end
|
140
|
+
|
113
141
|
end
|
114
142
|
end
|
115
143
|
|
116
|
-
plugin :class => BoxGrinder::BbcloudPlatformPlugin, :type => :platform, :name => :bbcloud, :full_name => "Brightbox Cloud"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brightbox-boxgrinder-plugins
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Neil Wilson
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
19
|
-
default_executable:
|
18
|
+
date: 2012-06-27 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: brightbox-cli
|
@@ -44,7 +43,6 @@ extra_rdoc_files:
|
|
44
43
|
- README.md
|
45
44
|
- lib/brightbox-boxgrinder-plugins.rb
|
46
45
|
- lib/delivery/bbcloud-delivery-plugin.rb
|
47
|
-
- lib/os/sl-plugin.rb
|
48
46
|
- lib/platform/bbcloud-platform-plugin.rb
|
49
47
|
- lib/platform/src/rc_local
|
50
48
|
files:
|
@@ -55,12 +53,10 @@ files:
|
|
55
53
|
- Rakefile
|
56
54
|
- lib/brightbox-boxgrinder-plugins.rb
|
57
55
|
- lib/delivery/bbcloud-delivery-plugin.rb
|
58
|
-
- lib/os/sl-plugin.rb
|
59
56
|
- lib/platform/bbcloud-platform-plugin.rb
|
60
57
|
- lib/platform/src/rc_local
|
61
58
|
- brightbox-boxgrinder-plugins.gemspec
|
62
|
-
|
63
|
-
homepage: http://beta.brightbox.com
|
59
|
+
homepage: http://brightbox.com
|
64
60
|
licenses: []
|
65
61
|
|
66
62
|
post_install_message:
|
@@ -95,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
91
|
requirements: []
|
96
92
|
|
97
93
|
rubyforge_project: Brightbox Cloud
|
98
|
-
rubygems_version: 1.
|
94
|
+
rubygems_version: 1.8.15
|
99
95
|
signing_key:
|
100
96
|
specification_version: 3
|
101
97
|
summary: Brightbox Cloud support for Boxgrinder
|
data/lib/os/sl-plugin.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
# Brightbox - Boxgrinder Scientific Linux OS Plugin
|
2
|
-
# Copyright (c) 2011, Brightbox Systems
|
3
|
-
# Author: Neil Wilson
|
4
|
-
#
|
5
|
-
# This is free software; you can redistribute it and/or modify it
|
6
|
-
# under the terms of the GNU Lesser General Public License as
|
7
|
-
# published by the Free Software Foundation; either version 3 of
|
8
|
-
# the License, or (at your option) any later version.
|
9
|
-
#
|
10
|
-
# This software is distributed in the hope that it will be useful,
|
11
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
-
# Lesser General Public License for more details.
|
14
|
-
#
|
15
|
-
# You should have received a copy of the GNU Lesser General Public
|
16
|
-
# License along with this software; if not, write to the Free
|
17
|
-
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
18
|
-
# 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
19
|
-
|
20
|
-
require 'boxgrinder-build/plugins/os/rhel/rhel-plugin'
|
21
|
-
|
22
|
-
module BoxGrinder
|
23
|
-
class ScientificLinuxPlugin < RHELPlugin
|
24
|
-
|
25
|
-
SL_REPOS = {
|
26
|
-
"5" => {
|
27
|
-
"base" => {
|
28
|
-
"baseurl" => "http://ftp.scientificlinux.org/linux/scientific/#OS_VERSION#x/#BASE_ARCH#/SL/"
|
29
|
-
},
|
30
|
-
"updates" => {
|
31
|
-
"baseurl" => "http://ftp.scientificlinux.org/linux/scientific/#OS_VERSION#x/#BASE_ARCH#/updates/security/"
|
32
|
-
}
|
33
|
-
},
|
34
|
-
"6" => {
|
35
|
-
"base" => {
|
36
|
-
"baseurl" => "http://ftp.scientificlinux.org/linux/scientific/#OS_VERSION#x/#BASE_ARCH#/os/"
|
37
|
-
},
|
38
|
-
"updates" => {
|
39
|
-
"baseurl" => "http://ftp.scientificlinux.org/linux/scientific/#OS_VERSION#x/#BASE_ARCH#/updates/security/"
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
|
44
|
-
|
45
|
-
def after_init
|
46
|
-
super
|
47
|
-
register_supported_os('sl', ['5', '6'])
|
48
|
-
end
|
49
|
-
|
50
|
-
def execute(appliance_definition_file)
|
51
|
-
build_rhel(appliance_definition_file, SL_REPOS)
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
plugin :class => BoxGrinder::ScientificLinuxPlugin, :type => :os, :name => :sl, :full_name => "Scientific Linux", :versions => ["5", "6"]
|