commit 1a68aea83c59e95343fcdff3e3bae63f273a7c65
Author: Greg Sutcliffe <gsutclif@redhat.com>
Date:   Fri Oct 26 17:29:21 2012 +0100

    Fixes #983 - implement 3 state boot

diff --git a/app/models/orchestration/tftp.rb b/app/models/orchestration/tftp.rb
index dd44a51d5..ca63fbf52 100644
--- a/app/models/orchestration/tftp.rb
+++ b/app/models/orchestration/tftp.rb
@@ -79,7 +79,11 @@ module Orchestration::TFTP
       @initrd = os.initrd(arch)
       # work around for ensuring that people can use @host as well, as tftp templates were usually confusing.
       @host = self
-      pxe_render configTemplate({:kind => os.template_kind}).template
+      if build?
+        pxe_render configTemplate({:kind => os.template_kind}).template
+      else
+        pxe_render ConfigTemplate.find_by_name("PXE Localboot Default").template
+      end
     rescue => e
       failure "Failed to generate #{os.template_kind} template: #{e}"
     end
@@ -92,34 +96,31 @@ module Orchestration::TFTP
     end
 
     def queue_tftp_create
-      return unless build
       queue.create(:name => "TFTP Settings for #{self}", :priority => 20,
                    :action => [self, :setTFTP])
+      return unless build
       queue.create(:name => "Fetch TFTP boot files for #{self}", :priority => 25,
                    :action => [self, :setTFTPBootFiles])
     end
 
     def queue_tftp_update
       set_tftp = false
-      if build?
-        # we switched to build mode
-        set_tftp = true unless old.build?
-        # medium or arch changed
-        set_tftp = true if old.medium != medium or old.arch != arch
-        # operating system changed
-        set_tftp = true if os and old.os and (old.os.name != os.name or old.os != os)
-        # MAC address changed
-        if mac != old.mac
-          set_tftp = true
-          # clean up old TFTP reservation file
-          if old.tftp?
-            queue.create(:name => "Remove old TFTP Settings for #{old}", :priority => 19,
-                         :action => [old, :delTFTP])
-          end
+      # we switched build mode
+      set_tftp = true unless old.build? != build?
+      # medium or arch changed
+      set_tftp = true if old.medium != medium or old.arch != arch
+      # operating system changed
+      set_tftp = true if os and old.os and (old.os.name != os.name or old.os != os)
+      # MAC address changed
+      if mac != old.mac
+        set_tftp = true
+        # clean up old TFTP reservation file
+        if old.tftp?
+          queue.create(:name => "Remove old TFTP Settings for #{old}", :priority => 19,
+                       :action => [old, :delTFTP])
         end
       end
       queue_tftp_create  if set_tftp
-      queue_tftp_destroy if !build? and old.build?
     end
 
     def queue_tftp_destroy
diff --git a/app/views/unattended/pxe_local.erb b/app/views/unattended/pxe_local.erb
new file mode 100644
index 000000000..4d41f6cce
--- /dev/null
+++ b/app/views/unattended/pxe_local.erb
@@ -0,0 +1,11 @@
+DEFAULT menu
+PROMPT 0
+MENU TITLE PXE Menu
+TIMEOUT 200
+TOTALTIMEOUT 6000
+ONTIMEOUT local
+
+LABEL local
+     MENU LABEL (local)
+     MENU DEFAULT
+     LOCALBOOT 0
diff --git a/db/migrate/20121026160433_add_localboot_template.rb b/db/migrate/20121026160433_add_localboot_template.rb
new file mode 100644
index 000000000..194dc6b3f
--- /dev/null
+++ b/db/migrate/20121026160433_add_localboot_template.rb
@@ -0,0 +1,12 @@
+class AddLocalbootTemplate < ActiveRecord::Migration
+  def self.up
+    ConfigTemplate.without_auditing {ConfigTemplate.create(
+      :name                => "PXE Localboot Default",
+      :template_kind_id    => TemplateKind.find_by_name("PXELinux"),
+      :operatingsystem_ids => [],
+      :template            => File.read("#{Rails.root}/app/views/unattended/pxe_local.erb"))}
+  end
+
+  def self.down
+  end
+end
diff --git a/test/fixtures/config_templates.yml b/test/fixtures/config_templates.yml
index 59ccae465..fc504cef7 100644
--- a/test/fixtures/config_templates.yml
+++ b/test/fixtures/config_templates.yml
@@ -39,4 +39,10 @@ pxe_default:
    name: PXE Default File
    template: default linux~label linux~kernel <%%= @kernel %>~append initrd=<%%= @initrd %> ksdevice=bootif network kssendmac
    template_kind: pxelinux
-   operatingsystems: centos5_3, redhat
\ No newline at end of file
+   operatingsystems: centos5_3, redhat
+
+pxe_local_default:
+   name: PXE Localboot Default
+   template: DEFAULT menu~PROMPT 0~MENU TITLE PXE Menu~TIMEOUT 200~TOTALTIMEOUT 6000~ONTIMEOUT local~~LABEL local~MENU LABEL (local)~MENU DEFAULT~LOCALBOOT 0
+   template_kind: pxelinux
+   operatingsystems: centos5_3, redhat
diff --git a/test/unit/orchestration/dhcp_test.rb b/test/unit/orchestration/dhcp_test.rb
index 1640c42cb..f03c1f3a7 100644
--- a/test/unit/orchestration/dhcp_test.rb
+++ b/test/unit/orchestration/dhcp_test.rb
@@ -77,7 +77,7 @@ class DhcpOrchestrationTest < ActiveSupport::TestCase
     assert_equal h.mac, h.old.mac
     assert_equal h.name, h.old.name
     assert_equal h.subnet, h.old.subnet
-    assert h.queue.items.empty?
+    assert h.queue.items.select {|x| x.action.last =~ /dhcp/ }.empty?
   end
 
   test "existing host should not change any bmc dhcp settings" do
@@ -87,7 +87,7 @@ class DhcpOrchestrationTest < ActiveSupport::TestCase
     assert_equal h.sp_mac, h.old.sp_mac
     assert_equal h.sp_name, h.old.sp_name
     assert_equal h.sp_subnet, h.old.sp_subnet
-    assert h.queue.items.empty?
+    assert h.queue.items.select {|x| x.action.last =~ /sp_dhcp/ }.empty?
   end
 
   test "when an existing host change its ip address, its dhcp record should be updated" do
diff --git a/test/unit/orchestration/pxe_local_template b/test/unit/orchestration/pxe_local_template
new file mode 100644
index 000000000..4d41f6cce
--- /dev/null
+++ b/test/unit/orchestration/pxe_local_template
@@ -0,0 +1,11 @@
+DEFAULT menu
+PROMPT 0
+MENU TITLE PXE Menu
+TIMEOUT 200
+TOTALTIMEOUT 6000
+ONTIMEOUT local
+
+LABEL local
+     MENU LABEL (local)
+     MENU DEFAULT
+     LOCALBOOT 0
diff --git a/test/unit/orchestration/tftp_test.rb b/test/unit/orchestration/tftp_test.rb
index dcb2900f0..c66f29300 100644
--- a/test/unit/orchestration/tftp_test.rb
+++ b/test/unit/orchestration/tftp_test.rb
@@ -17,15 +17,29 @@ class TFTPOrchestrationTest < ActiveSupport::TestCase
     end
   end
 
-  def test_generate_pxe_template
+  def test_generate_pxe_template_for_build
     if unattended?
       h = hosts(:one)
+      h.setBuild
       as_admin { h.update_attribute :operatingsystem, operatingsystems(:centos5_3) }
       Setting[:foreman_url] = "ahost.com:3000"
 
       template = h.send(:generate_pxe_template).split("~")
       expected = File.open(Pathname.new(__FILE__).parent + "pxe_template").readlines.map(&:strip)
       assert_equal template,expected
+      assert h.build
+    end
+  end
+
+  def test_generate_pxe_template_for_localboot
+    if unattended?
+      h = hosts(:one)
+      as_admin { h.update_attribute :operatingsystem, operatingsystems(:centos5_3) }
+      assert !h.build
+
+      template = h.send(:generate_pxe_template).split("~")
+      expected = File.open(Pathname.new(__FILE__).parent + "pxe_local_template").readlines.map(&:strip)
+      assert_equal template,expected
     end
   end
 end
