dc70cb
#!/usr/bin/lua
dc70cb
-- rpm call
dc70cb
-- lua -- copy_jdk_configs.lua   --currentjvm "%{uniquesuffix %{nil}}" --jvmdir "%{_jvmdir %{nil}}" --origname "%{name}" --origjavaver "%{javaver}" --arch "%{_arch}" --debug true
dc70cb
--test call
dc70cb
--lua -- copy_jdk_configs.lua   --currentjvm "java-1.8.0-openjdk-1.8.0.65-3.b17.fc22.x86_64" --jvmdir "/usr/lib/jvm" --origname "java-1.8.0-openjdk" --origjavaver "1.8.0" --arch "x86_64" --debug true  --jvmDestdir /home/jvanek/Desktop
dc70cb
a897ee
local caredFiles = {"jre/lib/calendars.properties",
a897ee
              "jre/lib/content-types.properties",
a897ee
              "jre/lib/flavormap.properties",
a897ee
              "jre/lib/logging.properties",
a897ee
              "jre/lib/net.properties",
a897ee
              "jre/lib/psfontj2d.properties",
a897ee
              "jre/lib/sound.properties",
a897ee
              "jre/lib/deployment.properties",
a897ee
              "jre/lib/deployment.config",
a897ee
              "jre/lib/security/US_export_policy.jar",
a897ee
              "jre/lib/security/unlimited/US_export_policy.jar",
a897ee
              "jre/lib/security/limited/US_export_policy.jar",
a897ee
              "jre/lib/security/policy/unlimited/US_export_policy.jar",
a897ee
              "jre/lib/security/policy/limited/US_export_policy.jar",
a897ee
              "jre/lib/security/java.policy",
a897ee
              "jre/lib/security/java.security",
a897ee
              "jre/lib/security/local_policy.jar",
a897ee
              "jre/lib/security/unlimited/local_policy.jar",
a897ee
              "jre/lib/security/limited/local_policy.jar",
a897ee
              "jre/lib/security/policy/unlimited/local_policy.jar",
a897ee
              "jre/lib/security/policy/limited/local_policy.jar",
a897ee
              "jre/lib/security/nss.cfg",
a897ee
              "jre/lib/security/cacerts",
a897ee
              "jre/lib/security/blacklisted.certs",
a897ee
              "jre/lib/ext",
e4e3d1
              "jre/lib/security/blacklist",
e4e3d1
              "jre/lib/security/javaws.policy",
a897ee
              "lib/security",
a897ee
              "conf",
a897ee
              "lib/ext"}
a897ee
a897ee
-- before import to allow run from spec
a897ee
if (arg[1] == "--list") then 
a897ee
  for i,file in pairs(caredFiles) do
a897ee
    print(file)
a897ee
  end
a897ee
  return 0;
a897ee
end  
a897ee
dc70cb
-- yum install lua-posix
dc70cb
local posix = require "posix"
dc70cb
dc70cb
-- the one we are installing
dc70cb
local currentjvm = nil
dc70cb
local jvmdir = nil
dc70cb
local jvmDestdir = nil
dc70cb
local origname = nil
dc70cb
local origjavaver = nil
dc70cb
local arch = nil
dc70cb
local debug = false;
dc70cb
local temp = nil;
a897ee
local dry = false;
dc70cb
dc70cb
for i=1,#arg,2 do 
dc70cb
  if (arg[i] == "--help" or arg[i] == "-h") then 
dc70cb
    print("all but jvmDestdir and debug are mandatory")
dc70cb
    print("  --currentjvm")
dc70cb
    print("    NVRA of currently installed java")
dc70cb
    print("  --jvmdir") 
dc70cb
    print("    Directory where to find this kind of virtual machine. Generally /usr/lib/jvm")
dc70cb
    print("  --origname")
dc70cb
    print("    convinient switch to determine jdk. Generally java-1.X.0-vendor")
dc70cb
    print("  --origjavaver")
dc70cb
    print("    convinient switch to determine jdk's version. Generally 1.X.0")
dc70cb
    print("  --arch")
dc70cb
    print("    convinient switch to determine jdk's arch")
dc70cb
    print("  --jvmDestdir")
dc70cb
    print("    Migration/testing switch. Target Mostly same as jvmdir, but you may wont to copy ouside it.")
dc70cb
    print("  --debug")
a897ee
    print("    Enables printing out whats going on. true/false. False by default")
dc70cb
    print("  --temp")
dc70cb
    print("    optional file to save intermediate result - directory configs were copied from")
a897ee
    print("  --dry")
a897ee
    print("    true/fase if true, then no changes will be written to disk except one tmp file. False by default")
a897ee
    print("  **** specil parasm ****")
a897ee
    print("  --list")
a897ee
    print("    if present on cmdline, list all cared files and exists")
dc70cb
    os.exit(0)
dc70cb
  end
dc70cb
  if (arg[i] == "--currentjvm") then 
dc70cb
    currentjvm=arg[i+1]
dc70cb
  end
dc70cb
  if (arg[i] == "--jvmdir") then 
dc70cb
    jvmdir=arg[i+1]
dc70cb
  end
dc70cb
  if (arg[i] == "--origname") then 
dc70cb
    origname=arg[i+1]
dc70cb
  end
dc70cb
  if (arg[i] == "--origjavaver") then 
dc70cb
    origjavaver=arg[i+1]
dc70cb
  end
dc70cb
  if (arg[i] == "--arch") then 
dc70cb
    arch=arg[i+1]
dc70cb
  end
dc70cb
  if (arg[i] == "--jvmDestdir") then 
dc70cb
    jvmDestdir=arg[i+1]
dc70cb
  end
dc70cb
  if (arg[i] == "--debug") then 
dc70cb
--no string, boolean, workaround
dc70cb
    if (arg[i+1] == "true") then
dc70cb
     debug = true
dc70cb
    end
dc70cb
  end
a897ee
  if (arg[i] == "--dry") then 
a897ee
--no string, boolean, workaround
a897ee
    if (arg[i+1] == "true") then
a897ee
     dry = true
a897ee
    end
a897ee
  end
dc70cb
  if (arg[i] == "--temp") then 
dc70cb
    temp=arg[i+1]
dc70cb
  end
dc70cb
end
dc70cb
dc70cb
if (jvmDestdir == nil) then
dc70cb
jvmDestdir = jvmdir
dc70cb
end
dc70cb
dc70cb
dc70cb
if (debug) then
dc70cb
  print("--currentjvm:");
dc70cb
  print(currentjvm);
dc70cb
  print("--jvmdir:");
dc70cb
  print(jvmdir);
dc70cb
  print("--jvmDestdir:");
dc70cb
  print(jvmDestdir);
dc70cb
  print("--origname:");
dc70cb
  print(origname);
dc70cb
  print("--origjavaver:");
dc70cb
  print(origjavaver);
dc70cb
  print("--arch:");
dc70cb
  print(arch);
dc70cb
  print("--debug:");
dc70cb
  print(debug);
dc70cb
end
dc70cb
a897ee
local function debugOneLinePrint(string)
a897ee
  if (debug) then
a897ee
    print(string)
a897ee
  end;
a897ee
end
a897ee
dc70cb
dc70cb
--trasnform substitute names to lua patterns
dc70cb
local name = string.gsub(string.gsub(origname, "%-", "%%-"), "%.", "%%.")
dc70cb
local javaver = string.gsub(origjavaver, "%.", "%%.")
dc70cb
dc70cb
local jvms = { }
dc70cb
a897ee
function getPath(str,sep)
a897ee
    sep=sep or '/'
a897ee
    return str:match("(.*"..sep..")")
a897ee
end
dc70cb
dc70cb
function splitToTable(source, pattern)
dc70cb
  local i1 = string.gmatch(source, pattern) 
dc70cb
  local l1 = {}
dc70cb
  for i in i1 do
dc70cb
    table.insert(l1, i)
dc70cb
  end
dc70cb
  return l1
dc70cb
end
dc70cb
a897ee
local function slurp(path)
a897ee
    local f = io.open(path)
a897ee
    local s = f:read("*a")
a897ee
    f:close()
a897ee
    return s
a897ee
end
a897ee
a897ee
function trim(s)
a897ee
  return (s:gsub("^%s*(.-)%s*$", "%1"))
a897ee
end
a897ee
a897ee
local function dirWithParents(path)
a897ee
  local s = ""
a897ee
  local dirs = splitToTable(path, "[^/]+") 
a897ee
  for i,d in pairs(dirs) do
a897ee
    if (i == #dirs) then
a897ee
      break
a897ee
    end
a897ee
    s = s.."/"..d
a897ee
    local stat2 = posix.stat(s, "type");
a897ee
    if (stat2 == nil) then
a897ee
      debugOneLinePrint(s.." does not exists, creating")
a897ee
      if (not dry) then
a897ee
        posix.mkdir(s)
a897ee
      end
a897ee
    else
a897ee
      debugOneLinePrint(s.." exists,not creating")
a897ee
    end
a897ee
  end
a897ee
end
a897ee
a897ee
a897ee
debugOneLinePrint("started")
a897ee
dc70cb
dc70cb
foundJvms = posix.dir(jvmdir);
dc70cb
if (foundJvms == nil) then
a897ee
  debugOneLinePrint("no, or nothing in "..jvmdir.." exit")
dc70cb
  return
dc70cb
end
dc70cb
a897ee
debugOneLinePrint("found "..#foundJvms.."jvms")
dc70cb
dc70cb
for i,p in pairs(foundJvms) do
dc70cb
-- regex similar to %{_jvmdir}/%{name}-%{javaver}*%{_arch} bash command
dc70cb
  if (string.find(p, name.."%-"..javaver..".*"..arch) ~= nil ) then
a897ee
    debugOneLinePrint("matched:  "..p)
dc70cb
    if (currentjvm ==  p) then
a897ee
      debugOneLinePrint("this jdk is already installed. exiting lua script")
dc70cb
      return
dc70cb
    end ;
dc70cb
    if (string.match(p, ".*-debug$")) then
dc70cb
      print(p.." matched but seems to be debug variant. Skipping")
dc70cb
    else
dc70cb
      table.insert(jvms, p)
dc70cb
    end
dc70cb
  else
a897ee
    debugOneLinePrint("NOT matched:  "..p)
dc70cb
  end
dc70cb
end
dc70cb
dc70cb
if (#jvms <=0) then 
a897ee
  debugOneLinePrint("no matching jdk in "..jvmdir.." exit")
dc70cb
  return
dc70cb
end;
dc70cb
a897ee
debugOneLinePrint("matched "..#jvms.." jdk in "..jvmdir)
dc70cb
dc70cb
--full names are like java-1.7.0-openjdk-1.7.0.60-2.4.5.1.fc20.x86_64
dc70cb
table.sort(jvms , function(a,b) 
dc70cb
-- version-sort
dc70cb
-- split on non word: . - 
dc70cb
  local l1 = splitToTable(a, "[^%.-]+") 
dc70cb
  local l2 = splitToTable(b, "[^%.-]+") 
dc70cb
  for x = 1, math.min(#l1, #l2) do
dc70cb
    local l1x = tonumber(l1[x])
dc70cb
    local l2x = tonumber(l2[x])
dc70cb
    if (l1x ~= nil and l2x ~= nil)then
dc70cb
--if hunks are numbers, go with them 
dc70cb
      if (l1x < l2x) then return true; end
dc70cb
      if (l1x > l2x) then return false; end
dc70cb
    else
dc70cb
      if (l1[x] < l2[x]) then return true; end
dc70cb
      if (l1[x] > l2[x]) then return false; end
dc70cb
    end
dc70cb
-- if hunks are equals then move to another pair of hunks
dc70cb
  end
dc70cb
return a
dc70cb
dc70cb
end)
dc70cb
dc70cb
if (debug) then
dc70cb
  print("sorted lsit of jvms")
dc70cb
  for i,file in pairs(jvms) do
dc70cb
    print(file)
dc70cb
  end
dc70cb
end
dc70cb
dc70cb
latestjvm = jvms[#jvms]
dc70cb
dc70cb
if ( temp ~= nil ) then
dc70cb
  src=jvmdir.."/"..latestjvm
a897ee
  debugOneLinePrint("temp declared as "..temp.." saving used dir of "..src)
dc70cb
  file = io.open (temp, "w")
dc70cb
  file:write(src)
dc70cb
  file:close()
dc70cb
end 
dc70cb
dc70cb
a897ee
local readlinkOutput=os.tmpname()
a897ee
dc70cb
for i,file in pairs(caredFiles) do
dc70cb
  local SOURCE=jvmdir.."/"..latestjvm.."/"..file
dc70cb
  local DEST=jvmDestdir.."/"..currentjvm.."/"..file
a897ee
  debugOneLinePrint("going to copy "..SOURCE)
a897ee
  debugOneLinePrint("to  "..DEST)
dc70cb
  local stat1 = posix.stat(SOURCE, "type");
dc70cb
  if (stat1 ~= nil) then
a897ee
  debugOneLinePrint(SOURCE.." exists")
a897ee
  dirWithParents(DEST)
dc70cb
-- Copy with -a to keep everything intact
dc70cb
    local exe = "cp".." -ar "..SOURCE.." "..DEST
a897ee
    local linkExe = "readlink".." -f "..SOURCE.." > "..readlinkOutput
a897ee
    debugOneLinePrint("executing "..linkExe)
a897ee
    os.remove(readlinkOutput)
a897ee
    os.execute(linkExe)
a897ee
    local link=trim(slurp(readlinkOutput))
a897ee
    debugOneLinePrint("  ...link is "..link)
a897ee
    if (not ((link) == (SOURCE))) then
a897ee
      debugOneLinePrint("WARNING link "..link.." where file "..SOURCE.." expected!")
a897ee
      debugOneLinePrint("Will try to copy link target rather then link itself!")
a897ee
--replacing  any NVRA by future NVRA (still execting to have NVRA for any multiple-installable targets
a897ee
-- lua stubbornly consider dash as inteval. Replacing by dot to match X-Y more correct as X.Y rather then not at all
a897ee
      local linkDest=string.gsub(link, latestjvm:gsub("-", "."), currentjvm)
a897ee
      debugOneLinePrint("attempting to copy "..link.." to "..linkDest)
a897ee
      if (link == linkDest) then
a897ee
        debugOneLinePrint("Those are identical files! Nothing to do!")
a897ee
      else
a897ee
        local exe2 = "cp".." -ar "..link.." "..linkDest
a897ee
        dirWithParents(linkDest)
a897ee
        debugOneLinePrint("executing "..exe2)
a897ee
        if (not dry) then
a897ee
          os.execute(exe2)
a897ee
        end
a897ee
      end
a897ee
    else
a897ee
      debugOneLinePrint("executing "..exe)
a897ee
      if (not dry) then
a897ee
        os.execute(exe)
a897ee
      end
a897ee
    end
dc70cb
  else
a897ee
    debugOneLinePrint(SOURCE.." does not exists")
dc70cb
  end
dc70cb
end