diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-02-07 23:12:33 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-02-07 23:12:33 +0000 |
commit | b98e65f1fd858a1d0af415554db49a121a76232c (patch) | |
tree | 728f94dd17f88902c6bdf21ff6b17486babb08af /bin | |
parent | f1ffc34c0927840beeb21e1e2d864ce14de5d15e (diff) | |
download | puppet-b98e65f1fd858a1d0af415554db49a121a76232c.tar.gz |
There is now full support for configuration files, and the entire system has been modified to expect their new behaviour. I have not yet run the test across all test hosts, though.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@873 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/puppet | 57 | ||||
-rwxr-xr-x | bin/puppetca | 61 | ||||
-rwxr-xr-x | bin/puppetd | 110 | ||||
-rwxr-xr-x | bin/puppetmasterd | 189 |
4 files changed, 148 insertions, 269 deletions
diff --git a/bin/puppet b/bin/puppet index d8f7d952e..938877dc3 100755 --- a/bin/puppet +++ b/bin/puppet @@ -8,8 +8,7 @@ # = Usage # # puppet [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] -# [-l|--logfile <file>] [-p|--parse-only] <file> -# [-c|--confdir <configuration directory>] [--vardir <var directory>] +# [-l|--logfile <file>] <file> # # = Description # @@ -19,9 +18,11 @@ # # = Options # -# confdir:: -# The configuration root directory, where +puppetmasterd+ defaults to looking -# for all of its configuration files. Defaults to +/etc/puppet+. +# Note that any configuration parameter that's valid in the configuration file +# is also a valid long argument. For example, 'ssldir' is a valid configuration +# parameter, so you can specify '--ssldir <directory>' as an argument. +# +# See the configuration file for the full list of acceptable parameters. # # debug:: # Enable full debugging. @@ -33,13 +34,6 @@ # Where to send messages. Choose between syslog, the console, and a log file. # Defaults to sending messages to the console. # -# parse-only:: -# Just verify syntax, do not apply anything. -# -# vardir:: -# The variable-size directory, used for storing state. Defaults to -# /var/puppet. -# # verbose:: # Print extra information. # @@ -69,18 +63,19 @@ rescue LoadError $haveusage = false end -result = GetoptLong.new( - [ "--confdir", "-c", GetoptLong::REQUIRED_ARGUMENT ], +options = [ [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], - [ "--noop", "-n", GetoptLong::NO_ARGUMENT ], [ "--use-nodes", GetoptLong::NO_ARGUMENT ], - [ "--parse-only", "-p", GetoptLong::NO_ARGUMENT ], - [ "--vardir", GetoptLong::REQUIRED_ARGUMENT ], [ "--version", "-V", GetoptLong::NO_ARGUMENT ] -) +] + +# Add all of the config parameters as valid options. +Puppet.config.addargs(options) + +result = GetoptLong.new(*options) debug = false verbose = false @@ -92,13 +87,11 @@ master = { :Local => true } -Puppet[:logdest] = :console +Puppet::Log.newdestination(:console) begin result.each { |opt,arg| case opt - when "--confdir" - Puppet[:puppetconf] = arg when "--version" puts "%s" % Puppet.version exit @@ -109,24 +102,20 @@ begin puts "No help available unless you have RDoc::usage installed" exit end - when "--noop" - Puppet[:noop] = true when "--use-nodes" master[:UseNodes] = true when "--verbose" verbose = true - when "--parse-only" - parseonly = true when "--debug" debug = true when "--logdest" begin - Puppet[:logdest] = arg + Puppet::Log.newdestination(arg) rescue => detail $stderr.puts detail.to_s end - when "--vardir" - Puppet[:puppetvar] = arg + else + Puppet.config.handlearg(opt, arg) end } rescue GetoptLong::InvalidOption => detail @@ -138,11 +127,19 @@ rescue GetoptLong::InvalidOption => detail end if debug - Puppet[:loglevel] = :debug + Puppet::Log.level = :debug elsif verbose - Puppet[:loglevel] = :info + Puppet::Log.level = :info +end + +# Now parse the config +if Puppet[:config] and File.exists? Puppet[:config] + Puppet.config.parse(Puppet[:config]) end +Puppet.genconfig +Puppet.genmanifest + master[:File] = ARGV.shift begin diff --git a/bin/puppetca b/bin/puppetca index ec76339f0..c3aedf5fe 100755 --- a/bin/puppetca +++ b/bin/puppetca @@ -9,9 +9,7 @@ # = Usage # # puppetca [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] -# [--cadir <ca directory>] [-g|--generate] [-l|--list] -# [-s|--sign] [--ssldir <cert directory>] -# [-c|--confdir <configuration directory>] +# [-g|--generate] [-l|--list] [-s|--sign] # # = Description # @@ -22,15 +20,14 @@ # # = Options # -# all:: -# Operate on all outstanding requests. Only makes sense with '--sign'. +# Note that any configuration parameter that's valid in the configuration file +# is also a valid long argument. For example, 'ssldir' is a valid configuration +# parameter, so you can specify '--ssldir <directory>' as an argument. # -# cadir:: -# Where to look for the ca directory. Defaults to /etc/puppet/ssl/ca. +# See the configuration file for the full list of acceptable parameters. # -# confdir:: -# The configuration root directory, where +puppetmasterd+ defaults to looking -# for all of its configuration files. Defaults to +/etc/puppet+. +# all:: +# Operate on all outstanding requests. Only makes sense with '--sign'. # # debug:: # Enable full debugging. @@ -49,9 +46,6 @@ # Sign an outstanding certificate request. Unless '--all' is specified, # hosts must be listed after all flags. # -# ssldir:: -# The directory in which to store certificates. Defaults to /etc/puppet/ssl. -# # verbose:: # Enable verbosity. # @@ -82,18 +76,20 @@ rescue LoadError $haveusage = false end -result = GetoptLong.new( +options = [ [ "--all", "-a", GetoptLong::NO_ARGUMENT ], - [ "--cadir", GetoptLong::REQUIRED_ARGUMENT ], - [ "--confdir", "-c", GetoptLong::REQUIRED_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--generate", "-g", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--list", "-l", GetoptLong::NO_ARGUMENT ], [ "--sign", "-s", GetoptLong::NO_ARGUMENT ], - [ "--ssldir", GetoptLong::REQUIRED_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ] -) +] + +# Add all of the config parameters as valid options. +Puppet.config.addargs(options) + +result = GetoptLong.new(*options) mode = nil all = false @@ -104,12 +100,8 @@ begin case opt when "--all" all = true - when "--cadir" - Puppet[:cadir] = arg - when "--confdir" - Puppet[:puppetconf] = arg when "--debug" - Puppet[:loglevel] = :debug + Puppet::Log.level = :debug when "--generate" generate = arg mode = :generate @@ -124,10 +116,10 @@ begin mode = :list when "--sign" mode = :sign - when "--ssldir" - Puppet[:ssldir] = arg when "--verbose" - Puppet[:loglevel] = :info + Puppet::Log.level = :info + else + Puppet.config.handlearg(opt, arg) end } rescue GetoptLong::InvalidOption => detail @@ -138,7 +130,22 @@ rescue GetoptLong::InvalidOption => detail exit(1) end -ca = Puppet::SSLCertificates::CA.new() +# Now parse the config +if Puppet[:config] and File.exists? Puppet[:config] + Puppet.config.parse(Puppet[:config]) +end + +Puppet.genconfig +Puppet.genmanifest + +Puppet::Util.chuser + +begin + ca = Puppet::SSLCertificates::CA.new() +rescue => detail + puts detail.to_s + exit(23) +end unless mode $stderr.puts "You must specify --list or --sign" diff --git a/bin/puppetd b/bin/puppetd index e575a8405..742786c8b 100755 --- a/bin/puppetd +++ b/bin/puppetd @@ -9,11 +9,8 @@ # = Usage # # puppetd [-h|--help] [-V|--version] [-d|--debug] [-v|--verbose] -# [--ssldir <cert directory>] [-l|--logdest <syslog|<file>|console>] -# [--fqdn <host name>] [-p|--port <port>] [-o|--onetime] -# [-s|--server <server>] [-i|--ignoreschedules] -# [-w|--waitforcert <seconds>] [-c|--confdir <configuration directory>] -# [--vardir <var directory>] [--centrallogging] +# [-l|--logdest <syslog|<file>|console>] [--fqdn <host name>] +# [-o|--onetime] [-w|--waitforcert <seconds>] [--centrallogging] # # = Description # @@ -30,14 +27,16 @@ # # = Options # +# Note that any configuration parameter that's valid in the configuration file +# is also a valid long argument. For example, 'server' is a valid configuration +# parameter, so you can specify '--server <servername>' as an argument. +# +# See the configuration file for the full list of acceptable parameters. +# # centrallogging:: # Send all produced logs to the central puppetmasterd system. This currently # results in a significant slowdown, so it is not recommended. # -# confdir:: -# The configuration root directory, where +puppetmasterd+ defaults to looking -# for all of its configuration files. Defaults to +/etc/puppet+. -# # debug:: # Enable full debugging. # @@ -51,34 +50,13 @@ # # logdest:: # Where to send messages. Choose between syslog, the console, and a log file. -# Defaults to sending messages to /var/puppet/log/puppet.log, or the console -# if debugging or verbosity is enabled. -# -# port:: -# The port to which to connect on the remote server. Currently defaults to 8139. +# Defaults to sending messages to syslog, or the console if debugging or +# verbosity is enabled. # # onetime:: # Run the configuration once, rather than as a long-running daemon. This is # useful for interactively running puppetd. # -# schedule:: -# What schedule Puppet itself should run on. This dictates how often the -# entire configuration is retrieved and run. The default is named 'puppet', -# and runs every half hour or so. The schedules themselves are defined in the -# configuration, which means that on startup puppetd will always retrieve -# the configuration and then check to see if it's scheduled to run. -# -# server:: -# The remote server from whom to receive the local configuration. Currently -# must also be the certificate authority. Currently defaults to 'puppet'. -# -# ssldir:: -# Where to store and find certificates. Defaults to /etc/puppet/ssl. -# -# vardir:: -# The variable-size directory, used for storing state. Defaults to -# /var/puppet. -# # verbose:: # Turn on verbose reporting. # @@ -91,7 +69,7 @@ # # = Example # -# puppet -s puppet.domain.com +# puppetd --server puppet.domain.com # # = Author # @@ -99,7 +77,7 @@ # # = Copyright # -# Copyright (c) 2005 Reductive Labs, LLC +# Copyright (c) 2005, 2006 Reductive Labs, LLC # Licensed under the GNU Public License @@ -115,24 +93,22 @@ rescue LoadError $haveusage = false end -result = GetoptLong.new( +options = [ [ "--centrallogging", GetoptLong::NO_ARGUMENT ], - [ "--confdir", "-c", GetoptLong::REQUIRED_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--fqdn", "-f", GetoptLong::REQUIRED_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ], - [ "--noop", "-n", GetoptLong::NO_ARGUMENT ], [ "--onetime", "-o", GetoptLong::NO_ARGUMENT ], - [ "--port", "-p", GetoptLong::REQUIRED_ARGUMENT ], - [ "--schedule", "-S", GetoptLong::REQUIRED_ARGUMENT ], - [ "--server", "-s", GetoptLong::REQUIRED_ARGUMENT ], - [ "--ssldir", GetoptLong::REQUIRED_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "--version", "-V", GetoptLong::NO_ARGUMENT ], - [ "--vardir", GetoptLong::REQUIRED_ARGUMENT ], [ "--waitforcert", "-w", GetoptLong::REQUIRED_ARGUMENT ] -) +] + +# Add all of the config parameters as valid options. +Puppet.config.addargs(options) + +result = GetoptLong.new(*options) server = "puppet" fqdn = nil @@ -149,10 +125,10 @@ setdest = false begin result.each { |opt,arg| case opt + # First check to see if the argument is a valid configuration parameter; + # if so, set it. when "--centrallogging" centrallogs = true - when "--confdir" - Puppet[:puppetconf] = arg when "--help" if $haveusage RDoc::usage && exit @@ -164,44 +140,34 @@ begin puts "%s" % Puppet.version exit when "--verbose" - Puppet[:loglevel] = :info - Puppet[:logdest] = :console + Puppet::Log.level = :info + Puppet::Log.newdestination(:console) setdest = true when "--debug" - Puppet[:loglevel] = :debug - Puppet[:logdest] = :console + Puppet::Log.level = :debug + Puppet::Log.newdestination(:console) setdest = true - when "--noop" - Puppet[:noop] = true - when "--schedule" - # This is late-binding -- it'll only look up the schedule name - # when it needs to run - Puppet[:schedule] = arg - when "--ssldir" - Puppet[:ssldir] = arg when "--fqdn" fqdn = arg - when "--server" - server = arg when "--onetime" onetime = true when "--port" args[:Port] = arg when "--logdest" begin - Puppet[:logdest] = arg + Puppet::Log.newdestination(arg) rescue => detail $stderr.puts detail.to_s end - when "--vardir" - Puppet[:puppetvar] = arg when "--waitforcert" waitforcert = arg.to_i + else + Puppet.config.handlearg(opt, arg) end } rescue GetoptLong::InvalidOption => detail + $stderr.puts detail $stderr.puts "Try '#{$0} --help'" - #$stderr.puts detail # FIXME RDoc::usage doesn't seem to work #if $haveusage # RDoc::usage(1,'usage') @@ -209,17 +175,25 @@ rescue GetoptLong::InvalidOption => detail exit(1) end -if Puppet[:loglevel] == :debug or Puppet[:loglevel] == :info +Puppet.genconfig +Puppet.genmanifest + +# Now parse the config +if Puppet[:config] and File.exists? Puppet[:config] + Puppet.config.parse(Puppet[:config]) +end + +if Puppet::Log.level == :debug or Puppet::Log.level == :info args[:Daemonize] = false else args[:Daemonize] = true end unless setdest - Puppet[:logdest] = :syslog + Puppet::Log.newdestination(:syslog) end -args[:Server] = server +args[:Server] = Puppet[:server] if fqdn args[:FQDN] = fqdn end @@ -230,14 +204,12 @@ if centrallogs if args.include?(:Port) logdest += ":" + args[:Port] end - Puppet[:logdest] = logdest + Puppet::Log.newdestination(logdest) end - Puppet.notice "Starting Puppet client version %s" % [Puppet.version] client = Puppet::Client::MasterClient.new(args) - unless client.readcert if waitforcert begin diff --git a/bin/puppetmasterd b/bin/puppetmasterd index 6dc5a3fa9..e0f7da25f 100755 --- a/bin/puppetmasterd +++ b/bin/puppetmasterd @@ -8,59 +8,32 @@ # = Usage # # puppetmasterd [-h|--help] [-d|--debug] [-v|--verbose] [-V|--version] -# [-l|--logdest <syslog|console|<file>>] [--httplog <file>] -# [-m|--manifest <site manifest>] [--noca] [-p|--port <port>] -# [--parseonly] [-s|--ssldir <cert directory>] -# [-c|--confdir <configuration directory>] [--vardir <var dir>] +# [--noca] [--nobucket] # # = Description # -# This is the standalone puppet execution script; use it to execute -# individual scripts that you write. If you need to execute site-wide -# scripts, use +puppetd+ and +puppetmasterd+. +# This is the puppet central daemon. # # = Options # -# autosign:: -# Enable autosign (which presents a potential security problem). If enabled, -# refers to the autosign configuration file at /etc/puppet/autosign.conf to -# determine which hosts should have their certificates signed. +# Note that any configuration parameter that's valid in the configuration file +# is also a valid long argument. For example, 'ssldir' is a valid configuration +# parameter, so you can specify '--ssldir <directory>' as an argument. # -# confdir:: -# The configuration root directory, where +puppetmasterd+ defaults to looking -# for all of its configuration files. Defaults to +/etc/puppet+. +# See the configuration file for the full list of acceptable parameters. # # debug:: # Enable full debugging. Causes the daemon not to go into the background. # -# fsconfig:: -# Where to find the fileserver configuration file. Defaults to -# /etc/puppet/fileserver.conf. If the fileserver config file exists, -# the puppetmasterd daemon will automatically also become a fileserver. -# -# group:: -# Print this help message. -# -# group:: -# The group to run as. Can be either a name or number. Defaults to 'puppet'. -# # help:: # Print this help message. # -# httplog:: -# Where to send http logs (which are currently separate from Puppet logs). -# Defaults to /var/puppet/log/http.log. -# # logdest:: # Where to send messages. Choose between syslog, the console, and a log file. # Defaults to sending messages to /var/puppet/log/puppet.log, or the console # if debugging or verbosity is enabled. # -# manifest:: -# The central site manifest to use for providing clients with their individual -# configurations. Defaults to /etc/puppet/manifests/site.pp. -# -# noca:: +# nobucket:: # Do not function as a file bucket. # # noca:: @@ -69,23 +42,6 @@ # nonodes:: # Do not use individual node designations; each node will receive the result # of evaluating the entire configuration. -# -# parseonly:: -# Just parse the central manifest to verify it is syntactically correct. -# -# port:: -# The port on which to listen. Defaults to 8139. -# -# ssldir:: -# The directory in which to store certificates. Defaults to /etc/puppet/ssl. -# -# user:: -# The user to run as. Can be either a name or number. Defaults to 'user'. -# -# vardir:: -# The variable-size directory, used for storing state. Defaults to -# /var/puppet. -# # verbose:: # Enable verbosity. Causes the daemon not to go into the background. # @@ -109,27 +65,22 @@ require 'getoptlong' require 'puppet' require 'puppet/server' -result = GetoptLong.new( - [ "--autosign", "-a", GetoptLong::NO_ARGUMENT ], - [ "--confdir", "-c", GetoptLong::REQUIRED_ARGUMENT ], +options = [ [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], - [ "--fsconfig", "-f", GetoptLong::REQUIRED_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], - [ "--httplog", GetoptLong::NO_ARGUMENT ], [ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ], - [ "--manifest", "-m", GetoptLong::REQUIRED_ARGUMENT ], [ "--noca", GetoptLong::NO_ARGUMENT ], [ "--nobucket", GetoptLong::NO_ARGUMENT ], [ "--nonodes", GetoptLong::NO_ARGUMENT ], - [ "--parseonly", GetoptLong::NO_ARGUMENT ], - [ "--port", "-p", GetoptLong::REQUIRED_ARGUMENT ], - [ "--ssldir", "-s", GetoptLong::REQUIRED_ARGUMENT ], - [ "--user", "-u", GetoptLong::REQUIRED_ARGUMENT ], - [ "--group", "-g", GetoptLong::REQUIRED_ARGUMENT ], - [ "--vardir", GetoptLong::REQUIRED_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "--version", "-V", GetoptLong::NO_ARGUMENT ] -) +] +Puppet::Log.newdestination(:syslog) + +# Add all of the config parameters as valid options. +Puppet.config.addargs(options) + +result = GetoptLong.new(*options) $haveusage = true @@ -159,21 +110,10 @@ setdest = false begin result.each { |opt,arg| case opt - when "--autosign" - ca[:autosign] = Puppet[:autosign] - when "--confdir" - Puppet[:puppetconf] = arg when "--debug" - Puppet[:debug] = true - Puppet[:logdest] = :console + Puppet::Log.level = :debug + Puppet::Log.newdestination(:console) setdest = true - when "--fsconfig" - unless FileTest.exists?(arg) - $stderr.puts "File server configuration file %s does not exist" % - arg - exit(23) - end - fs[:Config] = arg when "--help" if $haveusage RDoc::usage && exit @@ -181,45 +121,28 @@ begin puts "No help available unless you have RDoc::usage installed" exit end - when "--httplog" - args[:AccessLog] = arg - when "--manifest" - master[:File] = arg when "--noca" haveca = false when "--nobucket" havebucket = false when "--nonodes" master[:UseNodes] = false - when "--parseonly" - parseonly = true - when "--port" - args[:Port] = arg - when "--ssldir" - Puppet[:ssldir] = arg when "--logdest" begin - Puppet[:logdest] = arg + Puppet::Log.newdestination(arg) setdest = true rescue => detail $stderr.puts detail.to_s end - when "--group" - group = arg - when "--user" - user = arg - when "--vardir" - Puppet[:puppetvar] = arg when "--version" puts "%s" % Puppet.version exit when "--verbose" setdest = true - Puppet[:loglevel] = :info - Puppet[:logdest] = :console + Puppet::Log.level = :info + Puppet::Log.newdestination :console else - $stderr.puts "Invalid option '#{opt}'" - exit(1) + Puppet.config.handlearg(opt, arg) end } rescue GetoptLong::InvalidOption => detail @@ -231,44 +154,21 @@ rescue GetoptLong::InvalidOption => detail #end exit(1) end +ca[:autosign] = Puppet[:autosign] -require 'etc' - -if group - if group =~ /^\d+$/ - group = Integer(group) - else - begin - g = Etc.getgrnam(group) - rescue ArgumentError - $stderr.puts "Could not find group %s" % group - end - group = g.gid - end - unless Process.gid == group - Process.egid = group - Process.gid = group - end +# Now parse the config +if Puppet[:config] and File.exists? Puppet[:config] + Puppet.config.parse(Puppet[:config]) end -if user - if user =~ /^\d+$/ - user = Integer(user) - else - begin - u = Etc.getpwnam(user) - rescue ArgumentError - $stderr.puts "Could not find user %s" % user - end - user = u.uid - end - unless Process.uid == user - Process.euid = user - Process.uid = user - end -end +Puppet.genconfig +Puppet.genmanifest + +require 'etc' + +Puppet::Util.chuser -if Puppet[:loglevel] == :debug or Puppet[:loglevel] == :info or parseonly +if Puppet::Log.level == :debug or Puppet::Log.level == :info or parseonly args[:Daemonize] = false else args[:Daemonize] = true @@ -281,7 +181,7 @@ handlers = { } unless setdest - Puppet[:logdest] = :syslog + Puppet::Log.newdestination(:syslog) end if haveca @@ -292,13 +192,11 @@ end # handlers[:FileBucket] = bucket #end -unless fs.include?(:Config) - if File.exists?(Puppet[:fileserverconfig]) - fs[:Config] = Puppet[:fileserverconfig] - #else - # Puppet.notice "File server config %s does not exist; skipping file serving" % - # Puppet[:fileserverconfig] - end +if File.exists?(Puppet[:fileserverconfig]) + fs[:Config] = Puppet[:fileserverconfig] +#else +# Puppet.notice "File server config %s does not exist; skipping file serving" % +# Puppet[:fileserverconfig] end if fs.include?(:Config) @@ -307,8 +205,6 @@ end args[:Handlers] = handlers -Puppet.notice "Starting Puppet server version %s" % [Puppet.version] - begin # use the default, um, everything #server = Puppet::Server.new(:CA => ca) @@ -318,14 +214,21 @@ rescue => detail exit(1) end -if parseonly +if Puppet[:parseonly] # we would have already exited if the file weren't syntactically correct exit(0) end +if args[:Daemonize] + server.daemonize +end + trap(:INT) { server.shutdown } + +Puppet.notice "Starting Puppet server version %s" % [Puppet.version] + begin server.start rescue => detail |