This includes logging and command-line arguments to control its
behavior, and an initscript to start and stop it.

Signed-off-by: Chris Lalancette <[email protected]>
---
 conf/deltacloud-image_builder_service           |   79 ++++++++++++
 src/image_builder_service/image_builder_service |  157 ++++++++++++++++-------
 2 files changed, 189 insertions(+), 47 deletions(-)
 create mode 100755 conf/deltacloud-image_builder_service

diff --git a/conf/deltacloud-image_builder_service 
b/conf/deltacloud-image_builder_service
new file mode 100755
index 0000000..b1ba4dc
--- /dev/null
+++ b/conf/deltacloud-image_builder_service
@@ -0,0 +1,79 @@
+#!/bin/bash
+#
+#
+# deltacloud-image_builder_service       startup script for 
deltacloud-image_builder_service
+#
+# chkconfig: - 97 03
+# description: deltacloud-image_builder_service builds cloud images
+#    from the Deltacloud Aggregator db
+
+[ -r /etc/sysconfig/deltacloud-rails ] && . /etc/sysconfig/deltacloud-rails
+
+[ -r /etc/sysconfig/deltacloud-aggregator ] && . 
/etc/sysconfig/deltacloud-aggregator
+
+DELTACLOUD_DIR="${DELTACLOUD_DIR:-/usr/share/deltacloud-aggregator}"
+BUILDER_LOG="${BUILDER_LOG:-/var/log/deltacloud-aggregator/image_builder_service.log}"
+BUILDER_PID="${BUILDER_PID:-/var/run/deltacloud-aggregator/image_builder_service.pid}"
+BUILDER_LOCKFILE="${BUILDER_LOCKFILE:-/var/lock/subsys/deltacloud-image_builder_service}"
+USER="${USER:-dcloud}"
+GROUP="${GROUP:-dcloud}"
+
+BUILDER_PATH=/usr/share/deltacloud-aggregator/image_builder_service
+BUILDER_PROG=image_builder_service
+
+. /etc/init.d/functions
+
+start() {
+    echo -n "Starting deltacloud-image_builder_service: "
+
+    daemon --user=$USER $BUILDER_PATH/$BUILDER_PROG
+    RETVAL=$?
+    if [ $RETVAL -eq 0 ] && touch $BUILDER_LOCKFILE ; then
+      echo_success
+      echo
+    else
+      echo_failure
+      echo
+    fi
+}
+
+stop() {
+    echo -n "Shutting down deltacloud-image_builder_service: "
+    killproc -p $BUILDER_PID $BUILDER_PROG
+    RETVAL=$?
+    if [ $RETVAL -eq 0 ] && rm -f $BUILDER_LOCKFILE ; then
+      echo_success
+      echo
+    else
+      echo_failure
+      echo
+    fi
+}
+
+case "$1" in
+    start)
+      start
+     ;;
+    stop)
+      stop
+      ;;
+    restart)
+      stop
+      start
+      ;;
+    reload)
+      ;;
+    force-reload)
+      restart
+      ;;
+    status)
+     status $BUILDER_PROG
+     RETVAL=$?
+     ;;
+    *)
+      echo "Usage: deltacloud-image_builder_service 
{start|stop|restart|status}"
+      exit 1
+  ;;
+esac
+
+exit $RETVAL
diff --git a/src/image_builder_service/image_builder_service 
b/src/image_builder_service/image_builder_service
index e2be26c..a1224d3 100644
--- a/src/image_builder_service/image_builder_service
+++ b/src/image_builder_service/image_builder_service
@@ -1,3 +1,4 @@
+#!/usr/bin/env ruby
 #
 # Copyright (C) 2010 Red Hat, Inc.
 #
@@ -27,34 +28,95 @@ $: << File.join(File.dirname(__FILE__), "../dutils")
 require 'dutils'
 require "image_builder_console"
 require 'logger'
+require 'optparse'
 
+help = false
+daemon = true
+builder_pid_dir = "/var/run/deltacloud-aggregator"
+builder_log_dir = "/var/log/deltacloud-aggregator"
+timeout = 8
 
-#TODO: Figure out why logger does not work, w or w/o the class below
-class Logger
-  def format_message(severity, timestamp, progname, msg)
-    "#{severity} #{timestamp} (#{$$}) #{msg}\n"
+optparse = OptionParser.new do |opts|
+
+  opts.banner = <<BANNER
+Usage:
+image_builder_service [options]
+
+Options:
+BANNER
+  opts.on( '-f', '--pid-file PATH', "Use PATH to the image_builder_service pid 
directory (defaults to #{builder_pid_dir})") do |newpath|
+    builder_pid_dir = newpath
+  end
+  opts.on( '-h', '--help', '') { help = true }
+  opts.on( '-l', '--log PATH', "Use PATH to the image_builder_service log 
directory (defaults to #{builder_log_dir}).  Use '-' for stdout") do |newpath|
+    builder_log_dir = newpath
+  end
+  opts.on( '-n', '--nodaemon', 'Do not daemonize (useful in combination with 
-l for debugging)') { daemon = false }
+  opts.on( '-t', '--timeout SEC', 'Sleep for SEC between each poll for a new 
job (default is #{timeout})') do |newtime|
+    timeout = newtime
+  end
+end
+
+begin
+  optparse.parse!
+rescue OptionParser::InvalidOption => e
+  puts "Invalid option #{e.args}"
+  puts
+  puts optparse
+  exit(1)
+end
+
+if help
+  puts optparse
+  exit(0)
+end
+
+# setup the logger
+if builder_log_dir == '-'
+  BUILDER_LOG_FILE = STDOUT
+else
+  BUILDER_LOG_FILE = "#{builder_log_dir}/image_builder_service.log"
+end
+logger = Logger.new(BUILDER_LOG_FILE)
+logger.level = Logger::DEBUG
+
+# daemonize
+if daemon
+  # note that this requires 'active_support', which we get for free from dutils
+  Process.daemon
+end
+
+begin
+  BUILDER_PID_FILE = "#{builder_pid_dir}/image_builder_service.pid"
+  FileUtils.mkdir_p File.dirname(BUILDER_PID_FILE)
+  open(BUILDER_PID_FILE, "w") {|f| f.write(Process.pid) }
+  File.chmod(0644, BUILDER_PID_FILE)
+rescue => e
+  logger.error "#{e.backtrace.shift}: #{e.message}"
+  e.backtrace.each do |step|
+    logger.error "\tfrom #{step}"
   end
 end
 
 #TODO: Make this whole thing less fragile
 class ImageBuilderService
-  def initialize()
+  def initialize(logger, timeout)
+    @log = logger
+    @timeout = timeout.to_i
     @console ||= ImageBuilderConsole.new
     @activebuilds ||= []
+    @log.warn "Image Builder Service initialized..."
     poll
-    log = Logger.new(STDOUT)
-    log.warn "Service initialized..."
-    puts log.inspect
   end
 
   def check_for_queued
     queue = Image.find(:all, :conditions => {:status => Image::STATE_QUEUED})
     cur_builds = Image.find(:all, :conditions => "build_id IS NOT NULL AND 
status != 'complete'")
     if queue.size > 0 || cur_builds.size > 0
-      puts "========================================"
-      puts "Queued Builds: " + queue.size.to_s
-      puts "All Incomplete Builds: " + cur_builds.size.to_s
-      puts "========================================"
+      @log.debug "========================================"
+      @log.debug "Queued Builds: " + queue.size.to_s
+      @log.debug "All Incomplete Builds: " + cur_builds.size.to_s
+      @log.debug "========================================"
     end
     cur_builds.size > queue.size ? find_orphaned(cur_builds) :
     queue.each {|t|
@@ -64,9 +126,9 @@ class ImageBuilderService
 
   def build(image)
     #targets.each do |t|
-      puts "========================================"
-      puts "target: " + image.target + ", status: " + image.status
-      puts "========================================"
+      @log.debug "========================================"
+      @log.debug "target: " + image.target + ", status: " + image.status
+      @log.debug "========================================"
       # FIXME: this should be contained elsewhere (probably Image model) so we
       # can keep logic out of here.  Also, this currently only handles one
       # account, we will need to be able to specify at some point.
@@ -77,9 +139,9 @@ class ImageBuilderService
         update_build_list(ab, image)
         image.build_id = ab.object_id.to_s
         image.save!
-        puts "========================================"
-        puts "Build id saved as: " + image.build_id
-        puts "========================================"
+        @log.debug "========================================"
+        @log.debug "Build id saved as: " + image.build_id
+        @log.debug "========================================"
       end
     #end
   end
@@ -96,18 +158,18 @@ class ImageBuilderService
       end
     end
     if cur_builds.size > 0
-      puts "========================================"
-      puts "There appear to be " + cur_builds.size.to_s + " untracked builds."
-      puts "Attempting to get status updates...."
-      puts "========================================"
+      @log.debug "========================================"
+      @log.debug "There appear to be " + cur_builds.size.to_s + " untracked 
builds."
+      @log.debug "Attempting to get status updates...."
+      @log.debug "========================================"
       found = []
       cur_builds.each do |t|
         found << {:ab => @console.find_build(t.build_id),
                   :target => t }
       end
-      puts "========================================"
-      puts "Retrieved " + found.size.to_s + " builds to update."
-      puts "========================================"
+      @log.debug "========================================"
+      @log.debug "Retrieved " + found.size.to_s + " builds to update."
+      @log.debug "========================================"
       found.each do |f|
         update_build_list(f[:ab], f[:target])
       end
@@ -115,14 +177,14 @@ class ImageBuilderService
   end
 
   def update_agg(obj,new_status)
-    puts "========================================"
-    puts "Getting ar object to update using " + obj[:build].target.inspect + " 
and " + obj[:ar_id].inspect + " ..."
-    puts "========================================"
+    @log.debug "========================================"
+    @log.debug "Getting ar object to update using " + 
obj[:build].target.inspect + " and " + obj[:ar_id].inspect + " ..."
+    @log.debug "========================================"
     image = Image.find(:first, :conditions => { :target => 
obj[:build].target.to_s,
                                                               :template_id => 
obj[:ar_id].to_i })
-    puts "========================================"
-    puts "Updating with status: " + new_status
-    puts "========================================"
+    @log.debug "========================================"
+    @log.debug "Updating with status: " + new_status
+    @log.debug "========================================"
     image.status = new_status
     if new_status == 'complete'
       ri = image.replicated_images.first
@@ -132,25 +194,26 @@ class ImageBuilderService
       ri.save!
     end
     image.save!
-    puts "========================================"
-    puts "database updated!"
-    puts "========================================"
+    @log.debug "========================================"
+    @log.debug "database updated!"
+    @log.debug "========================================"
   end
 
   private
   def poll()
-      loop do
-        check_for_queued
-        @activebuilds.delete_if do |ab|
-          cur_status = @console.check_status(ab[:build])
-          update_agg(ab, cur_status) unless cur_status.eql?(ab[:status])
-          puts "========================================"
-          puts "Status for target " + ab[:build].target + ": " + cur_status
-          puts "Builds in array: " + check_build_num.to_s
-          puts "========================================"
-          cur_status.eql?("complete")
-        end
-        sleep 8
+    loop do
+      check_for_queued
+      @activebuilds.delete_if do |ab|
+        cur_status = @console.check_status(ab[:build])
+        update_agg(ab, cur_status) unless cur_status.eql?(ab[:status])
+        @log.debug "========================================"
+        @log.debug "Status for target " + ab[:build].target + ": " + cur_status
+        @log.debug "Builds in array: " + check_build_num.to_s
+        @log.debug "========================================"
+        cur_status.eql?("complete")
+      end
+      sleep @timeout
+
       end
   end
 
@@ -164,4 +227,4 @@ class ImageBuilderService
   end
 end
 
-ImageBuilderService.new
+ImageBuilderService.new(logger, timeout)
-- 
1.7.2.3

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to