about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-03-14 05:48:37 +0000
committerzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-03-14 05:48:37 +0000
commit2f049babd1ac067818b20a5643f70113ec1f3a4b (patch)
tree0d71576efdd90e2ffcaeab83e4bccc2386eb9224
parent8f915bf2e690d0c2db850585c04a729120d79ad2 (diff)
downloadunicorn-2f049babd1ac067818b20a5643f70113ec1f3a4b.tar.gz
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@109 19e92222-5c0b-0410-8929-a290d50e31e9
-rw-r--r--Rakefile4
-rw-r--r--bin/mongrel_rails8
-rw-r--r--bin/mongrel_rails_service8
-rw-r--r--lib/mongrel.rb8
-rw-r--r--projects/gem_plugin/Rakefile2
-rw-r--r--projects/gem_plugin/tools/rakehelp.rb3
-rw-r--r--projects/mongrel_config/Rakefile7
-rw-r--r--projects/mongrel_config/lib/mongrel_config/init.rb47
-rw-r--r--projects/mongrel_config/lib/mongrel_config/win32.rb85
-rw-r--r--projects/mongrel_config/lib/mongrel_config/win32_app.rb251
-rw-r--r--projects/mongrel_config/resources/index_win32.html68
-rw-r--r--projects/mongrel_config/resources/style.css7
-rw-r--r--projects/mongrel_config/test/test_config.rb50
-rw-r--r--projects/mongrel_config/tools/rakehelp.rb3
-rw-r--r--projects/mongrel_status/Rakefile6
-rw-r--r--projects/mongrel_status/tools/rakehelp.rb3
16 files changed, 521 insertions, 39 deletions
diff --git a/Rakefile b/Rakefile
index eab4bf9..3ed6bf7 100644
--- a/Rakefile
+++ b/Rakefile
@@ -32,7 +32,7 @@ end
 setup_extension("http11", "http11")
 
 name="mongrel"
-version="0.3.10.1"
+version="0.3.11"
 
 setup_gem(name, version) do |spec|
   spec.summary = "A small fast HTTP library and server that runs Rails, Camping, and Nitro apps."
@@ -43,7 +43,7 @@ setup_gem(name, version) do |spec|
   spec.files += %w(ext/http11/MANIFEST README Rakefile setup.rb)
 
   spec.add_dependency('daemons', '>= 0.4.2')
-  spec.add_dependency('gem_plugin', '>= 0.2')
+  spec.add_dependency('gem_plugin', '>= 0.2.1')
   spec.required_ruby_version = '>= 1.8.4'
 end
 
diff --git a/bin/mongrel_rails b/bin/mongrel_rails
index 0b48b1f..e66d99e 100644
--- a/bin/mongrel_rails
+++ b/bin/mongrel_rails
@@ -121,7 +121,13 @@ class Start < GemPlugin::Plugin "/commands"
     begin
       # start mongrel processing thread
       server.run
-      STDERR.puts "Server ready."
+
+      if RUBY_PLATFORM !~ /mswin/
+        puts "Server Ready.  Use CTRL-C to quit."
+      else
+        puts "Server Ready.  Use CTRL-Pause/Break to quit."
+      end
+
       server.acceptor.join
     rescue Interrupt
       STDERR.puts "Interrupted."
diff --git a/bin/mongrel_rails_service b/bin/mongrel_rails_service
index 79fecdb..dd6c32b 100644
--- a/bin/mongrel_rails_service
+++ b/bin/mongrel_rails_service
@@ -30,7 +30,7 @@ module GenericCommand
   end
 end
 
-class Install < Mongrel::Plugin "/commands"
+class Install < GemPlugin::Plugin "/commands"
   include Mongrel::Command::Base
 
   # Default every option to nil so only the defined ones get passed to service
@@ -174,7 +174,7 @@ class Install < Mongrel::Plugin "/commands"
   end
 end
 
-class Delete < Mongrel::Plugin "/commands"
+class Delete < GemPlugin::Plugin "/commands"
   include Mongrel::Command::Base
   include GenericCommand
 
@@ -193,7 +193,7 @@ class Delete < Mongrel::Plugin "/commands"
   end
 end
 
-class Start < Mongrel::Plugin "/commands"
+class Start < GemPlugin::Plugin "/commands"
   include Mongrel::Command::Base
   include GenericCommand
   
@@ -218,7 +218,7 @@ class Start < Mongrel::Plugin "/commands"
   end
 end
 
-class Stop < Mongrel::Plugin "/commands"
+class Stop < GemPlugin::Plugin "/commands"
   include Mongrel::Command::Base
   include GenericCommand
   
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 4d80752..32f78bd 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -178,9 +178,11 @@ module Mongrel
       params[Const::CONTENT_TYPE] = params[Const::HTTP_CONTENT_TYPE] if params[Const::HTTP_CONTENT_TYPE]
       params[Const::GATEWAY_INTERFACE]=Const::GATEWAY_INTERFACE_VALUE
       params[Const::REMOTE_ADDR]=socket.peeraddr[3]
-      host,port = params[Const::HTTP_HOST].split(":")
-      params[Const::SERVER_NAME]=host
-      params[Const::SERVER_PORT]=port || 80
+      if params.has_key? Const::HTTP_HOST
+        host,port = params[Const::HTTP_HOST].split(":")
+        params[Const::SERVER_NAME]=host
+        params[Const::SERVER_PORT]=port || 80
+      end
       params[Const::SERVER_PROTOCOL]=Const::SERVER_PROTOCOL_VALUE
       params[Const::SERVER_SOFTWARE]=Const::MONGREL_VERSION
 
diff --git a/projects/gem_plugin/Rakefile b/projects/gem_plugin/Rakefile
index 528f295..ed3fd31 100644
--- a/projects/gem_plugin/Rakefile
+++ b/projects/gem_plugin/Rakefile
@@ -15,7 +15,7 @@ setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']
 desc "Does a full compile, test run"
 task :default => [:test, :package]
 
-version = "0.2"
+version = "0.2.1"
 name="gem_plugin"
 
 setup_gem(name, version) do |spec|
diff --git a/projects/gem_plugin/tools/rakehelp.rb b/projects/gem_plugin/tools/rakehelp.rb
index d8505a2..9ca1265 100644
--- a/projects/gem_plugin/tools/rakehelp.rb
+++ b/projects/gem_plugin/tools/rakehelp.rb
@@ -93,7 +93,8 @@ def setup_gem(pkg_name, pkg_version)
     
   Rake::GemPackageTask.new(spec) do |p|
     p.gem_spec = spec
-    p.need_tar = true
+    # win32 chokes on this
+    p.need_tar = true if RUBY_PLATFORM !~ /mswin/
   end
 end
 
diff --git a/projects/mongrel_config/Rakefile b/projects/mongrel_config/Rakefile
index 77e8b7f..8ba80c3 100644
--- a/projects/mongrel_config/Rakefile
+++ b/projects/mongrel_config/Rakefile
@@ -15,7 +15,7 @@ setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']
 desc "Does a full compile, test run"
 task :default => [:test, :package]
 
-version="0.2.1"
+version="0.3"
 name="mongrel_config"
 
 setup_gem(name, version) do |spec|
@@ -23,13 +23,12 @@ setup_gem(name, version) do |spec|
   spec.description = spec.summary
   spec.test_file = "test/test_config.rb"
   spec.author="Zed A. Shaw"
-  spec.add_dependency('mongrel', '>= 0.3.10.1')
-  spec.add_dependency('gem_plugin', '>= 0.2')
+  spec.add_dependency('mongrel', '>= 0.3.11')
+  spec.add_dependency('gem_plugin', '>= 0.2.1')
   spec.add_dependency('camping', '>= 1.3')
   spec.files += Dir.glob("resources/**/*")
 end
 
-
 task :install => [:test, :package] do
   sh %{sudo gem install pkg/#{name}-#{version}.gem}
 end
diff --git a/projects/mongrel_config/lib/mongrel_config/init.rb b/projects/mongrel_config/lib/mongrel_config/init.rb
index a7fd4d0..623ea03 100644
--- a/projects/mongrel_config/lib/mongrel_config/init.rb
+++ b/projects/mongrel_config/lib/mongrel_config/init.rb
@@ -1,3 +1,4 @@
+require 'rubygems'
 require 'gem_plugin'
 require 'mongrel'
 
@@ -6,23 +7,34 @@ class ConfigTool < GemPlugin::Plugin "/commands"
   include Mongrel::Command::Base
 
   def configure
-    options [
-             ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
-             ['-P', '--pid FILE', "Where to write the PID", :@pid_file, "log/mongrel.pid"],
-             ['-h', '--host ADDR', "Host to bind to for server", :@host, "0.0.0.0"],
-             ['-p', '--port NUMBER', "Port to bind to", :@port, "3001"],
-             ['-u', '--uri URI', "Where to put your config tool", :@uri, "/config"]
-    ]
+    if RUBY_PLATFORM =~ /mswin/
+      options [
+        ['-h', '--host ADDR', "Host to bind to for server", :@host, "0.0.0.0"],
+        ['-p', '--port NUMBER', "Port to bind to", :@port, "3001"],
+        ['-u', '--uri URI', "Where to put your config tool", :@uri, "/config"],
+        ['-R', '--mongrel PATH', "Path to mongrel_rails_service", :@mongrel_script, "c:\\ruby\\bin\\mongrel_rails_service"]
+      ]
+    else
+      options [
+        ['-c', '--chdir PATH', "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
+        ['-P', '--pid FILE', "Where to write the PID", :@pid_file, "log/mongrel.pid"],
+        ['-h', '--host ADDR', "Host to bind to for server", :@host, "0.0.0.0"],
+        ['-p', '--port NUMBER', "Port to bind to", :@port, "3001"],
+        ['-u', '--uri URI', "Where to put your config tool", :@uri, "/config"]
+      ]
+    end
   end
   
   def validate
-    valid?(@uri, "Must give a uri")
-    valid?(@port && @port.to_i > 0, "Must give a valid port")
-    valid?(@host, "Host IP to bind must be given")
-
-    valid_dir? @cwd, "Cannot change to a directory that doesn't exist"
-    Dir.chdir @cwd
-    valid_dir? "log", "Log directory does not exist"
+      valid?(@uri, "Must give a uri")
+      valid?(@port && @port.to_i > 0, "Must give a valid port")
+      valid?(@host, "Host IP to bind must be given")
+      
+    if RUBY_PLATFORM !~ /mswin/    
+      valid_dir? @cwd, "Cannot change to a directory that doesn't exist"
+      Dir.chdir @cwd
+      valid_dir? "log", "Log directory does not exist"
+    end
 
     return @valid
   end
@@ -30,7 +42,12 @@ class ConfigTool < GemPlugin::Plugin "/commands"
 
   def run
     # must require this here since rails and camping don't like eachother
-    require 'mongrel_config/app'
+    if RUBY_PLATFORM =~ /mswin/
+      require 'mongrel_config/win32_app'
+      $mongrel_rails_service = @mongrel_script
+    else
+      require 'mongrel_config/app'
+    end
 
     resources = GemPlugin::Manager.instance.resource "mongrel_config", "/"
     $PID_FILE = @pid_file
diff --git a/projects/mongrel_config/lib/mongrel_config/win32.rb b/projects/mongrel_config/lib/mongrel_config/win32.rb
new file mode 100644
index 0000000..4cdf605
--- /dev/null
+++ b/projects/mongrel_config/lib/mongrel_config/win32.rb
@@ -0,0 +1,85 @@
+require 'win32/service'
+
+
+# Simply abstracts the common stuff that the config tool needs to do
+# when dealing with Win32.  It is a very thin wrapper which may expand
+# later.
+module W32Support
+
+  # Lists all of the services that have "mongrel" in the binary_path_name
+  # of the service.  This detects the mongrel services.
+  def W32Support.list
+    Win32::Service.services.select {|s| s.binary_path_name =~ /mongrel/ }
+  end
+
+  # Just gets the display name of the service.
+  def W32Support.display(name)
+    Win32::Service.getdisplayname(name)
+  end
+
+  # Performs one operations (like :start or :start) which need
+  # to be "monitored" until they're done.  The wait_for parameter
+  # should be a regex for the content of the status like /running/
+  # or /stopped/
+  def W32Support.do_and_wait(service_name, operation, wait_for)
+    status = W32Support.status(service_name)
+    if status =~ wait_for
+      # already running call the block once and leave
+      yield status
+    else
+      # start trying to start it
+      Win32::Service.send(operation, service_name)
+      status = W32Support.status(service_name)
+      while status !~ wait_for
+        yield status
+        status = W32Support.status(service_name)
+      end
+
+      # do one last yield so they know it started
+      yield status
+    end
+  end
+
+  # Starts the requested service and calls a passed in block
+  # until the service is done.  You should sleep for a short
+  # period until it's done or there's an exception.
+  def W32Support.start(service_name)
+    W32Support.do_and_wait(service_name, :start, /running/) do |status|
+      yield status
+    end
+  end
+
+
+  # Stops the service.  Just like W32Support.start is will call
+  # a block while it checks for the service to actually stop.
+  def W32Support.stop(service_name)
+    W32Support.do_and_wait(service_name, :stop, /stopped/) do |status|
+      yield status
+    end
+  end
+
+
+  # Returns the current_state field of the service.
+  def W32Support.status(service_name)
+    Win32::Service.status(service_name).current_state
+  end
+  
+
+  # Deletes the service from the system.  It first tries to stop
+  # the service, and if you pass in a block it will call it while
+  # the service is being stopped.
+  def W32Support.delete(service_name)
+    begin
+      W32Support.stop(service_name) do |status|
+        yield status if block_given?
+      end
+    rescue
+    end
+
+    begin
+      Win32::Service.delete(service_name)
+    rescue
+    end
+  end
+
+end
diff --git a/projects/mongrel_config/lib/mongrel_config/win32_app.rb b/projects/mongrel_config/lib/mongrel_config/win32_app.rb
new file mode 100644
index 0000000..592ee47
--- /dev/null
+++ b/projects/mongrel_config/lib/mongrel_config/win32_app.rb
@@ -0,0 +1,251 @@
+require 'erb'
+require 'camping'
+require 'mongrel/camping'
+require 'yaml'
+require 'thread'
+
+Camping.goes :Configure
+
+require 'mongrel_config/win32'
+
+$service_group = ThreadGroup.new
+$service_logs = ""
+
+module Configure
+  module Controllers
+    class Index < R '/'
+      def get
+        @services = W32Support.list
+        render :list
+      end
+    end
+    
+    class Info < R '/info/(\w+)'
+      def get(name)
+        @services = W32Support.list.select {|s| s.service_name == name }
+        render :info
+      end
+    end
+    
+    class Start < R '/start/(\w+)'
+      def get(service)
+        runner = Thread.new do
+          W32Support.start(service) do |status|
+            $service_logs << "Starting #{service}: #{status}\n"
+            sleep 1
+          end
+        end
+
+        $service_group.add(runner)
+
+        redirect Index
+      end
+    end    
+    
+    class Stop < R '/stop/(\w+)'
+      def get(service)
+        runner = Thread.new do
+          W32Support.stop(service) do |status|
+            $service_logs << "Starting #{service}: #{status}\n"
+            sleep 1
+          end
+        end
+
+        $service_group.add(runner)
+        redirect Index
+      end
+    end
+    
+    # eventually this will also let you see a particular service's logs
+    class Logs < R '/logs'
+      def get
+        render :service_logs
+      end
+    end
+
+    class ClearLogs < R '/clear_logs'
+      def get
+        $service_logs = ""
+        $service_logs << "#{Time.now}: CLEARED"
+
+        redirect Logs
+      end
+    end
+
+    class Install < R '/install'
+      def get
+        render :install_form
+      end
+
+      def post
+        options = []
+        if bad?(input.service_name) or bad?(input.root) or bad?(input.environment) or bad?(input.address) or bad?(input.port)
+          @result = "ERROR: You must fill out all mandatory (*) fields."
+          render :install_result
+        else
+          options << ["-n", input.service_name]
+          options << ["-r", '"' + input.root + '"']
+          options << ["-e", input.environment]
+          options << ["-b", input.address]
+          options << ["-p", input.port]
+          options << ["-d", input.display_name] if good? input.display_name
+          options << ["-m", '"' + input.mime + '"'] if good? input.mime
+          options << ["-P", input.num_procs] if good? input.num_procs
+          options << ["-t", input.timeout] if good? input.timeout
+          options << ["-c", input.cpu] if good? input.cpu
+          
+          begin
+            @result = `ruby #$mongrel_rails_service install #{options.join(' ')}`
+            $service_logs << @result
+          rescue
+            @result = "Failed to start #{input.service_name}: #$!"
+            $service_logs << @result
+          end
+          
+          render :install_result
+        end
+      end
+
+      def good?(field)
+        field and not field.strip.empty?
+      end
+      
+      def bad?(field)
+        not good? field
+      end
+    end
+
+
+    class Delete < R '/delete/(\w+)'
+      def get(name)
+        W32Support.delete(name)
+        $service_logs << "Deleted #{name}\n"
+        redirect Index
+      end
+    end
+  end
+  
+  
+  module Views
+    def layout
+      links = [
+        ["/config", "Status"],
+        ["/config/install", "Install"],
+        ["/config/logs", "Logs"]
+        ]
+      body_content = yield
+      currently_running = _running_procs
+
+      open(GemPlugin::Manager.instance.resource("mongrel_config", "/index_win32.html")) do |f|
+        template = ERB.new(f.read)
+        self << template.result(binding)
+      end
+    end
+    
+
+    def list
+      div :id=>"viewport" do
+        table do
+          tr { th { "Service"}; th { "Status"}; th { "Control" }; th { "Delete" } }
+          @services.each do |s|
+            status = W32Support.status(s.service_name)
+            tr {
+              td { a(s.service_name, :href => "/info/#{s.service_name}") }
+              td { status.capitalize }
+              td {
+                if status =~ /stopped/
+                  a("start",:href => "/start/#{s.service_name}")
+                elsif status =~ /running/
+                  a("stop",:href => "/stop/#{s.service_name}")
+                else
+                  b { "in progress" }
+                end
+              }
+              td {
+                a("delete!",:href => "/delete/#{s.service_name}",
+                  :onclick=>"return confirm('Delete #{s.service_name}?') == '1'")
+              }
+            }
+          end
+        end
+      end
+    end
+    
+
+    def info
+      div :id=>"viewport" do
+        @services.each do |s|
+        
+          h2 { "#{s.service_name} service information" }
+          table do
+            tr { th {"Attribute"}; th {"Value"} }
+            
+            s.each_pair do |memb,obj|
+              name = memb.to_s.tr("_"," ").capitalize
+              tr {
+                td { b { "#{name}: " } }
+                td { obj.inspect }
+              }
+            end
+          end
+        end
+      end
+    end
+
+    def service_logs
+      h2 { "Latest Service Activity Logs" }
+      a("[clear logs]", :href => "/clear_logs")
+
+      div :id=>"viewport" do
+        pre :style=>"font-size: 10pt;" do
+          selv << $service_logs
+        end
+      end
+    end
+
+    def install_form
+      div do
+        h2 { "Install New Mongrel Service" }
+        p { "Items with an * are mandatory.  Leave an item blank to not specify it." }
+        form :action=>"/install", :method=>"POST" do
+          b { "* Service Name: "}; input :name => "service_name"; br
+          b { "* Root: "}; input :name => "root"; br
+          b { "* Environment: "}; input :name => "environment", :value => "development"; br
+          b { "*Address: "}; input :name => "address", :value => "0.0.0.0"; br
+          b { "*Port: "}; input :name => "port", :value => "4000", :size => 6; br
+          b { "Display Name: "}; input :name => "display_name"; br
+          b { "MIME Map File: "};  input :name => "mime"; br
+          b { "Number Processor Threads: "}; input :name => "num_procs", :size => 3; br
+          b { "Request Timeout: "}; input :name => "timeout", :size => 3; br
+          b { "Assigned CPU: " }; input :name => "cpu", :size => 2; br
+
+          p { input :type=>"submit", :value => "INSTALL" }
+        end
+      end
+    end
+
+
+    def install_result
+      div :id=>"viewport" do
+        h2 { "Install Results"}
+        pre do
+          self << @result
+        end
+      end
+    end
+
+    def _running_procs
+      running = []
+      W32Support.list.each {|s| running << s.service_name if s.current_state =~ /running/}
+      running
+    end
+    
+  end
+end
+
+
+
+
+
+
+
diff --git a/projects/mongrel_config/resources/index_win32.html b/projects/mongrel_config/resources/index_win32.html
new file mode 100644
index 0000000..bf8aa12
--- /dev/null
+++ b/projects/mongrel_config/resources/index_win32.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+<title>Mongrel Config Tool</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<link href="/config/resources/style.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="container">
+  <div id="top">
+    <div id="title">Mongrel Config Tool</div>
+  </div>
+  <div id="middle">
+          <div id="nav">
+        <ul>
+              <% links.each do |uri,text| %>
+                 <li><a href="<%= uri %>"><%= text %></a></li>
+                <%end%>
+        </ul>
+      </div>
+          <div id="content">
+          <div id="side">
+            <% if currently_running.length > 0 %>
+            <strong>Running Services</strong> <br />
+            <br />
+                <%= currently_running.join(",") %>
+            <% else %>
+            <strong>No services running.</strong><br />
+            <% end %>
+                <br /><br />
+                <br />
+          <strong>Documentation</strong><br />
+        <br />
+        <a href="http://mongrel.rubyforge.org">Mongrel Home</a> <br />
+        <br />
+
+        <a href="http://mongrel.rubyforge.org/news.html">News</a><br />
+        <br />
+
+        <a href="http://mongrel.rubyforge.org/docs/started.html">Getting Started</a> <br />
+        <br />
+
+        <a href="http://mongrel.rubyforge.org/docs/win32.html">Win32 Guide</a><br />
+        <br />
+
+        <a href="http://mongrel.rubyforge.org/docs/lighttpd.html">Lighttpd Guide</a><br />
+        <br />
+
+        <a href="http://mongrel.rubyforge.org/rdoc/index.html">Mongrel API</a><br />
+        <br />
+
+        <a href="http://api.rubyonrails.org/">Ruby On Rails API</a><br />
+        <br />
+
+        <br /><br />
+      </div>
+
+      <%= body_content %>
+
+      </div>
+        </div>
+          </div>
+          
+  <div id="bottom">&nbsp;</div>
+  
+<div id="footertext">Copyright 2006 &copy; Zed A. Shaw &nbsp; | &nbsp; Design by Kenneth Barbour.</div>
+</body>
+</html>
diff --git a/projects/mongrel_config/resources/style.css b/projects/mongrel_config/resources/style.css
index 4c546f9..c6354ce 100644
--- a/projects/mongrel_config/resources/style.css
+++ b/projects/mongrel_config/resources/style.css
@@ -6,7 +6,6 @@ body {
         background-position: top;
         font-family: "Lucida Grande", Verdana, Halvetica, sans-serif;
         text-align: center;
-
 }
 a:hover {
         color: #990000;
@@ -148,6 +147,12 @@ a {
         text-decoration: underline;
 }
 
+b { font-size: 10pt;  }
+
+#viewport {
+  overflow: auto; width: 400px; height: 320px;
+}
+
 table {
   border-collapse: collapsed;
 }
diff --git a/projects/mongrel_config/test/test_config.rb b/projects/mongrel_config/test/test_config.rb
index 98b4936..f7501b3 100644
--- a/projects/mongrel_config/test/test_config.rb
+++ b/projects/mongrel_config/test/test_config.rb
@@ -1,7 +1,53 @@
 require 'test/unit'
+require 'mongrel_config/init'
+
+class CommandTest < Test::Unit::TestCase
+  def setup
+    @pmgr = GemPlugin::Manager.instance
+  end
+
+  def test_command_loaded
+    assert @pmgr.create("/commands/configtool", "configtool not loaded")
+  end
+
+end
+
+
+# these are only run if we're running on windows
+if RUBY_PLATFORM =~ /mswin/
+  require 'mongrel_config/win32'
+
+  class Win32Test < Test::Unit::TestCase
+    
+    def test_list
+      svcs = W32Support.list
+      assert svcs.length > 0, "No services returned.  Make sure you have one mongrel installed."
+    end
+
+    def test_display_name
+      svcs = W32Support.list
+      svcs.each { |s| W32Support.display(s.service_name) }
+    end
+
+    def test_start_stop
+      svcs = W32Support.list
+      svcs.each { |s|
+        puts "Starting #{W32Support.display(s.service_name)} (might take a while)"
+        i = 1
+        W32Support.start(s.service_name) do |status|
+          print "Starting #{s.service_name}: #{status} (#{i} seconds)\r"
+          sleep 1
+          i += 1
+        end
+
+        W32Support.stop(s.service_name) do |status|
+          puts "Stopping #{s.service_name}: #{status}"
+          sleep 1
+        end
+      }
+    end
 
-class EmptyTest < Test::Unit::TestCase
-  def test_nothing
   end
 end
 
+  
diff --git a/projects/mongrel_config/tools/rakehelp.rb b/projects/mongrel_config/tools/rakehelp.rb
index d8505a2..9ca1265 100644
--- a/projects/mongrel_config/tools/rakehelp.rb
+++ b/projects/mongrel_config/tools/rakehelp.rb
@@ -93,7 +93,8 @@ def setup_gem(pkg_name, pkg_version)
     
   Rake::GemPackageTask.new(spec) do |p|
     p.gem_spec = spec
-    p.need_tar = true
+    # win32 chokes on this
+    p.need_tar = true if RUBY_PLATFORM !~ /mswin/
   end
 end
 
diff --git a/projects/mongrel_status/Rakefile b/projects/mongrel_status/Rakefile
index da1248f..3b14201 100644
--- a/projects/mongrel_status/Rakefile
+++ b/projects/mongrel_status/Rakefile
@@ -15,7 +15,7 @@ setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']
 desc "Does a full compile, test run"
 task :default => [:test, :package]
 
-version="0.2.1"
+version="0.2.2"
 name="mongrel_status"
 
 setup_gem(name, version) do |spec|
@@ -23,8 +23,8 @@ setup_gem(name, version) do |spec|
   spec.description = spec.summary
   spec.test_file = "test/test_empty.rb"
   spec.author="Zed A. Shaw"
-  spec.add_dependency('mongrel', '>= 0.3.10.1')
-  spec.add_dependency('gem_plugin', '>= 0.2')
+  spec.add_dependency('mongrel', '>= 0.3.11')
+  spec.add_dependency('gem_plugin', '>= 0.2.1')
 end
 
 task :install => [:test, :package] do
diff --git a/projects/mongrel_status/tools/rakehelp.rb b/projects/mongrel_status/tools/rakehelp.rb
index d8505a2..9ca1265 100644
--- a/projects/mongrel_status/tools/rakehelp.rb
+++ b/projects/mongrel_status/tools/rakehelp.rb
@@ -93,7 +93,8 @@ def setup_gem(pkg_name, pkg_version)
     
   Rake::GemPackageTask.new(spec) do |p|
     p.gem_spec = spec
-    p.need_tar = true
+    # win32 chokes on this
+    p.need_tar = true if RUBY_PLATFORM !~ /mswin/
   end
 end