#
# dcast: Create slave dir for network mount in /tftpboot.

require 'find'
require 'ftools'
require 'fileutils'
require "nodes_class"
require "create_shell"
require "hardlink"

def disk_partition(tftpboot, swapsize, rootsize)
  etc = tftpboot + "/boot/etc/dcast/"

  FileUtils.mkdir_p(etc)
  open(etc + "zero", "w"){|io|
    io.puts "0\t0"
    io.puts "0\t0"
  }

  open(etc + "hda.out", "w"){|io|
    swapbyte = swapsize.to_i / 8
    io.puts "1,#{swapbyte},82"
    if rootsize != "-"
      rootbyte = rootsize.to_i / 8      
      io.puts "#{swapbyte + 1},#{swapbyte + 1 + rootbyte},83,*"
    else
      io.puts "#{swapbyte + 1},-,83,*"
    end
  }
end

def mkdir_tftpboot(tftpboot, kernel, master_ip)
  Array dirs = ["/bin", "/lib", "/sbin", "/usr", "/var"]

  tftpboot_b = tftpboot + "/boot/"
  FileUtils.mkdir_p(tftpboot_b) if !File.exist?(tftpboot_b)
  $stdout.sync = true

  $stdout.print "Making dir for diskless boot."

  # /etc
  hostname = tftpboot_b + "/etc/hostname"
  resolv = tftpboot_b + "/etc/resolv.conf"
  hosts = tftpboot_b + "/etc/hosts"
  interfaces = tftpboot_b + "/etc/network/interfaces"
  fstab = tftpboot_b + "/etc/fstab"
  exports = tftpboot_b + "/etc/exports"
  mtab = tftpboot_b + "/etc/mtab"

  FileUtils.cp_r("/etc/", tftpboot_b + "/etc")

  File.unlink(hostname) if File.exist?(hostname)      # /etc/hostname
  File.unlink(resolv) if File.exist?(resolv)          # /etc/resolv.conf
  File.unlink(hosts) if File.exist?(hosts)            # /etc/hosts
  File.unlink(mtab) if File.exist?(mtab)              # /etc/mtab
  system("touch #{mtab}")
  FileUtils.cp(tftpboot_b + "../diskless/etc/hosts", hosts)
  File.unlink(interfaces) if File.exist?(interfaces)  # /etc/network/interfaces
  FileUtils.cp(tftpboot_b + "../diskless/etc/network/interfaces", interfaces)
  File.unlink(fstab) if File.exist?(fstab)            # /etc/fstab
  FileUtils.cp(tftpboot_b + "../diskless/etc/fstab", fstab)
  File.unlink(exports) if File.exist?(exports)        # /etc/exports
  FileUtils.cp(tftpboot_b + "../diskless/etc/exports", exports)

  # Disk partition
  slave = Nodes.new("slave")
  disk_partition(tftpboot, slave.swap_size, slave.root_size)
  
 # nfs mount shell
  nfs_sh = tftpboot_b + "/etc/init.d/dcast-nfsmount"
  open(nfs_sh, "w"){|io|
    io.puts "IP=$(/sbin/ifconfig | grep -A1 eth0 | tail -1 | awk -F: '{print $2}' | awk '{print $1}')"
    io.puts "mount #{master_ip}:#{tftpboot}/$IP/etc /etc"
  }
  FileUtils.chmod(0755, nfs_sh)
  FileUtils.ln_s("../init.d/dcast-nfsmount", tftpboot_b + "/etc/rcS.d/S46dcast-nfsmount")

  detect_disk_shell(tftpboot + "/boot/etc/init.d/dcast-detect.sh")
  disk_partition_shell(tftpboot + "/boot/etc/init.d/dcast-diskfull.sh")
  write_hd_flag(tftpboot + "/boot/etc/init.d/dcast-hdflag.sh")
  FileUtils.ln_s("../init.d/dcast-hdflag.sh", tftpboot + "/boot/etc/rc2.d/S99dcast-hdflag.sh")
  nfsroot(tftpboot + "/boot/etc/init.d/dcast-nfsroot.sh")
  FileUtils.ln_s("../init.d/dcast-nfsroot.sh", tftpboot + "/boot/etc/rcS.d/S34dcast-nfsroot.sh")
  FileUtils.mkdir_p(tftpboot + "/slave/")
  $stdout.print "."

  # /dev
  IO.popen("cp -a /dev #{tftpboot_b + "/dev"} 2> /dev/null")
  $stdout.print "."
  
  # /usr /var
  FileUtils.mkdir_p(tftpboot_b)
  dirs.each{|dir|
    case dir
    when "/usr" then
      FileUtils.mkdir_p(tftpboot_b + "/usr")
      Dir.glob("/usr/*").each{|lsdir|
        if (lsdir != "/usr/games") && (lsdir != "/usr/doc") && (lsdir != "/usr/info") && (lsdir != "/usr/src")
          hard_link(lsdir, tftpboot_b)
          $stdout.print "."
        end
      }
    when "/var" then
      FileUtils.mkdir_p(tftpboot_b + "/var")
      FileUtils.mkdir_p(tftpboot_b + "/var.ro/lib")

      Dir.glob("/var/*").each{|lsdir|
        if lsdir != "/var/cache"
          hard_link(lsdir, tftpboot_b)
        else
          FileUtils.mkdir_p(tftpboot_b + "/var/cache/locate/")
        end
      }

      Array var_dirs = ["local","lock","log","mail","run","spool","tmp","yp"]
      var_dirs.each{|dir|
        if FileTest.directory?(tftpboot_b + "/var/" + dir)
          FileUtils.mv(tftpboot_b + "/var/" + dir, tftpboot_b + "/var.ro/")
          system("cd #{tftpboot_b + "/var"} ; ln -s /ram/var/" + dir)
        end
      }

      if FileTest.directory?(tftpboot_b + "/var/lib/nfs")
        FileUtils.mv(tftpboot_b + "/var/lib/nfs", tftpboot_b + "/var.ro/lib/")
        system("cd #{tftpboot_b + "/var"} ; ln -s /ram/var/lib/nfs lib")
      end

      $stdout.print "."
    else # except /usr and /var
      hard_link(dir, tftpboot_b)
      $stdout.print "."
    end
  }

  # /etc/network/ifstate
  system("ln -sf /ram/ifstate #{tftpboot_b + "/etc/network/ifstate"}")

  # Make dirs (eg. /home, /mnt)
  mkdirs = Array.new
  unmkdirs = ["/tftpboot", "/lost+found", "/etc", "/dev", "/tmp"]

  Dir.glob("/*").each{|lsdir|
    if FileTest.directory?(lsdir)
      mkdirs.push(lsdir)
    end
  }
  mkdirs = mkdirs - unmkdirs - dirs
  mkdirs.each{|dir|
    FileUtils.mkdir_p(tftpboot_b + dir)
  }

  # /ram
  FileUtils.mkdir_p(tftpboot_b + "/ram") if !FileTest.directory?(tftpboot_b + "/ram")

  # /tmp
  system("cd #{tftpboot_b} ; ln -s /ram/tmp")

  # kernel
  FileUtils.cp(kernel, tftpboot_b + "/bzImage")

  $stdout.puts ". Done."
end
