Skip to content

Commit

Permalink
Fixes #12633 - Pxegrub2 variant and multiple configs
Browse files Browse the repository at this point in the history
  • Loading branch information
lzap committed Jun 1, 2016
1 parent 185cfbb commit 99fedd2
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 68 deletions.
92 changes: 55 additions & 37 deletions modules/tftp/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,76 +7,95 @@ class Server
# Creates TFTP pxeconfig file
def set mac, config
raise "Invalid parameters received" if mac.nil? || config.nil?

FileUtils.mkdir_p pxeconfig_dir

File.open(pxeconfig_file(mac), 'w') {|f| f.write(config) }
logger.debug "TFTP: entry for #{mac} created successfully"
pxeconfig_file(mac).each do |file|
write_file file, config
end
true
end

# Removes pxeconfig files
def del mac
file = pxeconfig_file(mac)
if File.exist?(file)
FileUtils.rm_f file
logger.debug "TFTP: entry for #{mac} removed successfully"
else
logger.debug "TFTP: Skipping a request to delete a file which doesn't exists"
pxeconfig_file(mac).each do |file|
delete_file file
end
true
end

# Gets the contents of a pxeconfig file
# Gets the contents of one of pxeconfig files
def get mac
file = pxeconfig_file(mac)
if File.exist?(file)
config = File.open(pxeconfig_file(mac), 'r') {|f| f.readlines }
logger.debug "TFTP: entry for #{mac} read successfully"
else
logger.debug "TFTP: Skipping a request to read a file which doesn't exists"
raise "File #{file} not found"
end
config
file = pxeconfig_file(mac).first
read_file(file)
end

# Creates a default menu file
def create_default config
raise "Default config not supplied" if config.nil?

FileUtils.mkdir_p File.dirname pxe_default
File.open(pxe_default, 'w') {|f| f.write(config) }
logger.debug "TFTP: #{pxe_default} entry created successfully"
pxe_default.each do |file|
write_file file, config
end
true
end

protected
# returns the absolute path
# TODO:
def path(p = nil)
p ||= Proxy::TFTP::Plugin.settings.tftproot
return (p =~ /^\//) ? p : Pathname.new(File.expand_path(File.dirname(__FILE__))).join(p).to_s
end

def read_file(file)
raise("File #{file} not found") unless File.exist?(file)
File.open(file, 'r') {|f| f.readlines }
end

def write_file(file, contents)
FileUtils.mkdir_p(File.dirname(file))
File.open(file, 'w') {|f| f.write(contents)}
logger.debug "TFTP: #{file} created successfully"
end

def delete_file(file)
if File.exist?(file)
FileUtils.rm_f file
logger.debug "TFTP: #{file} removed successfully"
else
logger.debug "TFTP: Skipping a request to delete a file which doesn't exists"
end
end
end

class Syslinux < Server
def pxeconfig_dir
"#{path}/pxelinux.cfg"
end
def pxe_default
"#{pxeconfig_dir}/default"
["#{pxeconfig_dir}/default"]
end
def pxeconfig_file mac
"#{pxeconfig_dir}/01-"+mac.gsub(/:/,"-").downcase
["#{pxeconfig_dir}/01-"+mac.gsub(/:/,"-").downcase]
end
end

class Pxegrub < Server
def pxeconfig_dir
path.to_s
"#{path}/grub"
end
def pxe_default
["#{pxeconfig_dir}/menu.lst", "#{pxeconfig_dir}/efidefault"]
end
def pxeconfig_file mac
["#{pxeconfig_dir}/menu.lst.01"+mac.gsub(/:/,"").upcase, "#{pxeconfig_dir}/01-"+mac.gsub(/:/,'-').upcase]
end
end

class Pxegrub2 < Server
def pxeconfig_dir
"#{path}/grub2"
end
def pxe_default
"#{pxeconfig_dir}/boot/grub/menu.lst"
["#{pxeconfig_dir}/grub.cfg"]
end
def pxeconfig_file mac
"#{pxeconfig_dir}/menu.lst.01"+mac.gsub(/:/,"").upcase
["#{pxeconfig_dir}/grub.cfg-"+mac.gsub(/:/,'-').downcase]
end
end

Expand All @@ -85,10 +104,10 @@ def pxeconfig_dir
"#{path}/ztp.cfg"
end
def pxe_default
pxeconfig_dir
[pxeconfig_dir]
end
def pxeconfig_file mac
"#{pxeconfig_dir}/"+mac.gsub(/:/,"").upcase
["#{pxeconfig_dir}/"+mac.gsub(/:/,"").upcase]
end
end

Expand All @@ -97,15 +116,14 @@ def pxeconfig_dir
"#{path}/poap.cfg"
end
def pxe_default
pxeconfig_dir
[pxeconfig_dir]
end
def pxeconfig_file mac
"#{pxeconfig_dir}/"+mac.gsub(/:/,"").upcase
["#{pxeconfig_dir}/"+mac.gsub(/:/,"").upcase]
end
end

def self.fetch_boot_file dst, src

filename = boot_filename(dst, src)
destination = Pathname.new(File.expand_path(filename, Proxy::TFTP::Plugin.settings.tftproot)).cleanpath
tftproot = Pathname.new(Proxy::TFTP::Plugin.settings.tftproot).cleanpath
Expand Down
2 changes: 0 additions & 2 deletions modules/tftp/tftp_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,10 @@ def create_default variant
create_default "syslinux"
end

# Create a new TFTP reservation
post "/:mac" do |mac|
create "syslinux", mac
end

# Delete a record from a network
delete("/:mac") do |mac|
delete "syslinux", mac
end
Expand Down
95 changes: 66 additions & 29 deletions test/tftp/tftp_api_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,60 +14,97 @@ def app

def setup
Proxy::TFTP::Plugin.load_test_settings(:tftproot => "/some/root")
@args = { :pxeconfig => "foo" }
@args = {
:pxeconfig => "foo",
:menu => "bar"
}
end

def test_instantiate_syslinux
obj = app.helpers.instantiate "syslinux", "AA:BB:CC:DD:EE:FF"
assert_equal "Proxy::TFTP::Syslinux", obj.class.name
end

def test_instantiate_pxegrub
obj = app.helpers.instantiate "pxegrub", "AA:BB:CC:DD:EE:FF"
assert_equal "Proxy::TFTP::Pxegrub", obj.class.name
end

def test_instantiate_pxegrub2
obj = app.helpers.instantiate "pxegrub2", "AA:BB:CC:DD:EE:FF"
assert_equal "Proxy::TFTP::Pxegrub2", obj.class.name
end

def test_instantiate_ztp
obj = app.helpers.instantiate "ztp", "AA:BB:CC:DD:EE:FF"
assert_equal "Proxy::TFTP::Ztp", obj.class.name
end

def test_instantiate_poap
obj = app.helpers.instantiate "poap", "AA:BB:CC:DD:EE:FF"
assert_equal "Proxy::TFTP::Poap", obj.class.name
end

def test_instantiate_nonexisting
subject = app
subject.helpers.expects(:log_halt).with(403, "Unrecognized pxeboot config type: Server").at_least(1)
subject.helpers.instantiate "Server", "AA:BB:CC:DD:EE:FF"
end

def test_api_can_fetch_boot_file
Proxy::Util::CommandTask.stubs(:new).returns(true)
FileUtils.stubs(:mkdir_p).returns(true)
Proxy::TFTP.expects(:fetch_boot_file).with('/some/root/boot/file','http://localhost/file').returns(true)
post "/fetch_boot_file", :prefix => '/some/root/boot/file', :path => 'http://localhost/file'
def test_api_can_create_config
mac = "aa:bb:cc:dd:ee:ff"
Proxy::TFTP::Syslinux.any_instance.expects(:set).with(mac, @args[:pxeconfig]).returns(true)
result = post "/#{mac}", @args
assert last_response.ok?
assert_equal '', result.body
end

def test_api_can_create_syslinux_tftp_reservation
mac = "aa:bb:cc:00:11:22"
mac_filename = "aa-bb-cc-dd-ee-ff-00-11-22"
FileUtils.stubs(:mkdir_p).returns(true)
File.stubs(:open).with("/some/root/pxelinux.cfg/#{mac_filename}", 'w').returns(true)
Proxy::TFTP::Syslinux.any_instance.expects(:set).with(mac, args[:pxeconfig])
post "/#{mac}", args
assert last_response.ok?
end

def test_api_can_create_syslinux_tftp_reservation_for_64bit_mac
def test_api_can_create_config_64bit
mac = "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd"
mac_filename = "aa-bb-cc-dd-ee-ff-00-11-22-33-44-55-66-77-88-99-aa-bb-cc-dd"
FileUtils.stubs(:mkdir_p).returns(true)
File.stubs(:open).with("/some/root/pxelinux.cfg/#{mac_filename}", 'w').returns(true)
Proxy::TFTP::Syslinux.any_instance.expects(:set).with(mac, args[:pxeconfig])
post "/#{mac}", args
Proxy::TFTP::Syslinux.any_instance.expects(:set).with(mac, "foo").returns(true)
result = post "/#{mac}", @args
assert last_response.ok?
assert_equal '', result.body
end

def test_api_returns_error_when_invalid_mac
post "/aa:bb:cc:00:11:zz", args
post "/aa:bb:cc:00:11:zz", @args
assert !last_response.ok?
assert_equal "Invalid MAC address: aa:bb:cc:00:11:zz", last_response.body
end

def test_api_can_create_default
params = { :menu => "foobar" }
Proxy::TFTP::Syslinux.any_instance.expects(:create_default).with(params[:menu])
post "/create_default", params
def test_api_can_read_config
mac = "aa:bb:cc:dd:ee:ff"
Proxy::TFTP::Syslinux.any_instance.expects(:get).with(mac).returns('foo')
result = get "/syslinux/#{mac}"
assert last_response.ok?
assert_equal 'foo', result.body
end

private
attr_reader :args
def test_api_can_remove_config
mac = "aa:bb:cc:dd:ee:ff"
Proxy::TFTP::Syslinux.any_instance.expects(:del).with(mac).returns(true)
result = delete "/#{mac}"
assert last_response.ok?
assert_equal '', result.body
end

def test_api_can_create_defatult
Proxy::TFTP::Syslinux.any_instance.expects(:create_default).with(@args[:menu]).returns(true)
post "/create_default", @args
assert last_response.ok?
end

def test_api_can_fetch_boot_file
Proxy::TFTP.expects(:fetch_boot_file).with('/some/root/boot/file','http://localhost/file').returns(true)
post "/fetch_boot_file", :prefix => '/some/root/boot/file', :path => 'http://localhost/file'
assert last_response.ok?
end

def test_api_can_get_servername
Proxy::TFTP::Plugin.settings.stubs(:tftp_servername).returns("servername")
result = get "/serverName"
assert_match /servername/, result.body
assert last_response.ok?
end
end
Loading

0 comments on commit 99fedd2

Please sign in to comment.