diff --git a/sga/driver/pbs.lua b/sga/driver/pbs.lua index 1f334e4523a19d2b9f836b1c10801cc6f2640e39..da1d18aaa422671c42268b36428b33a38157ca28 100644 --- a/sga/driver/pbs.lua +++ b/sga/driver/pbs.lua @@ -4,13 +4,12 @@ local safer = require("safer") local util = require("sga.util") local exec = require("sga.exec") local schema = require("schema") -local posix = require("posix") local cmds = { nodeinfo = "pbsnodes -a ", qsub = "qsub ", qstat = "qstat -fx ", - qdel = "qdel " + qdel = "qdel ", } --- Type of the SGA, returned to the server during registration. @@ -38,14 +37,13 @@ function pbs.execute_command(self, job, cmd_string) end for _, sandbox_path in ipairs(job.sandboxes) do - local ok, err = lfs.mkdir(sandbox_path) + local ok, err = self.exec:create_dir(sandbox_path) if not ok then - local attr = lfs.attributes(sandbox_path) - if not (attr and attr.mode == "directory") then + if not self.exec:is_dir(sandbox_path) then return nil, "Failed creating job's sandbox "..sandbox_path end end - posix.chmod(sandbox_path, "rwxrwxrwx") + self.exec:chmod(sandbox_path, "rwxrwxrwx") end self.exec:write_file(script_filename, "#!/bin/sh\n"..cmd_string.."\n") @@ -71,15 +69,13 @@ end -- Deletes resources (files) created for a command. -- @param job The job object function pbs.cleanup_job(self, job) - self.exec:remove(job.data.script_filename) - self.exec:remove(job.data.out_filename) - self.exec:remove(job.data.err_filename) - + self.exec:remove_file(job.data.script_filename) + self.exec:remove_file(job.data.out_filename) + self.exec:remove_file(job.data.err_filename) for _, sandbox_path in ipairs(job.sandboxes) do - local attr = lfs.attributes(sandbox_path) - if (attr and attr.mode == "directory") then - local ok, err = util.removedir(sandbox_path) + if self.exec:is_dir(sandbox_path) then + local ok, err = self.exec:remove_dir(sandbox_path) if not ok then self.logger:error("Failed removing job's sandbox "..sandbox_path) end @@ -170,8 +166,8 @@ end pbs.actions = { -- Terminates a command - -- @param job The job object - terminate = function(self, job) + -- @param job The job object + terminate = function(self, job) local data, err = job.data.squeue_data if not data then data, err = qstat(self, job) @@ -187,7 +183,7 @@ pbs.actions = { else return false, "Job is not running" end - end, + end, -- Gets a command current status -- @param job The job object -- @return A table with information for each command component (process) diff --git a/sga/exec.lua b/sga/exec.lua index 6d21a166e383fb844e85377adde3b6c0ca523357..9488c66a27fdb62af3a5729320d92ed643c97477 100644 --- a/sga/exec.lua +++ b/sga/exec.lua @@ -13,7 +13,11 @@ function exec.init(config) local exec_module_schema = schema.Record { read_file = schema.Function, write_file = schema.Function, - remove = schema.Function, + remove_file = schema.Function, + create_dir = schema.Function, + remove_dir = schema.Function, + is_dir = schema.Function, + chmod = schema.Function, run = schema.Function, run_write = schema.Function, run_ok = schema.Function, diff --git a/sga/exec/localhost.lua b/sga/exec/localhost.lua index ad4e52ee165716d305430b31f0e931b255f78898..1b1600a7922701d9f5b59ebc980a910f4d413b3c 100644 --- a/sga/exec/localhost.lua +++ b/sga/exec/localhost.lua @@ -3,6 +3,7 @@ local localhost = {} local async = require("copas.async") local util = require("sga.util") +local posix = require("posix") function localhost.read_file(self, filename) return util.read_file(filename) @@ -12,10 +13,27 @@ function localhost.write_file(self, filename, data) return util.write_file(filename, data) end -function localhost.remove(self, filename) +function localhost.remove_file(self, filename) return os.remove(filename) end +function localhost.create_dir(self, dirname) + return lfs.mkdir(dirname) +end + +function localhost.remove_dir(self, dirname) + return util.removedir(dirname) +end + +function localhost.chmod(self, filename, flags) + return posix.chmod(filename, flags) +end + +function localhost.is_dir(self, dirname) + local attr = lfs.attributes(dirname) + return (attr and attr.mode == "directory") +end + local function in_main_thread() local curr, is_main = coroutine.running() return curr == nil or is_main -- Lua 5.1 and 5.2+ diff --git a/sga/exec/ssh.lua b/sga/exec/ssh.lua index 192210408f1b1411f90923d87b80c57304927a5f..c8aaee303e15402a0c0d106dc92b6861d44d27ac 100644 --- a/sga/exec/ssh.lua +++ b/sga/exec/ssh.lua @@ -17,10 +17,26 @@ function ssh.write_file(self, filename, data) return self:run_write("cat > "..quote(filename), data) end -function ssh.remove(self, filename) +function ssh.remove_file(self, filename) return self:run("rm "..quote(filename)) end +function ssh.create_dir(self, dirname) + return self:run("mkdir "..quote(dirname)) +end + +function ssh.remove_dir(self, dirname) + return self:run("rm -rf "..quote(dirname)) +end + +function ssh.is_dir(self, dirname) + return self:run_ok("test -d "..quote(dirname)) +end + +function ssh.chmod(self, filename, flags) + return self:run("chmod "..flags.." "..quote(filename)) +end + local function wrap_ssh(self, cmdline) return "ssh -p "..self.port.." "..self.host.." "..quote(cmdline) end diff --git a/sga/util.lua b/sga/util.lua index 7c95f05cb2b39365dd2faea9fa0ddb125ad4e811..89560bb632a9e866e6c7fb519072374f715a1568 100644 --- a/sga/util.lua +++ b/sga/util.lua @@ -75,6 +75,32 @@ local function can_open(path, mode) return fd and fd:close() or false end +local function getPermissions(path) + local tmpname = os.tmpname() + local r = "test -r '%s' && echo -n r;" + local w = "test -w '%s' && echo -n w;" + local x = "test -x '%s' && echo -n x" + + local cmd = "("..r..w..x..") > %s" + cmd = string.format(cmd, path, path, path, tmpname) + + os.execute(cmd) + local file = io.open(tmpname, "r") + if not file then + local msg = "Falha na abertura do arquivo temporário. [%s] de saída do comando:%s." + return nil, string.format(msg, tmpname, cmd) + end + local content = file:read("*a") + file:close() + os.remove(tmpname) + + local result = {} + result.r = string.find(content, 'r') ~= nil + result.w = string.find(content, 'w') ~= nil + result.x = string.find(content, 'x') ~= nil + return result +end + function util.list_local_path(path_name) local attrs = lfs.attributes(path_name) local list = {} @@ -109,18 +135,16 @@ function util.check_local_path(path_name) is_dir = attrs.mode == "directory" end end - -- when trying to open a pipe/socket for permission check, the daemon can get stuck - local is_readable = symlink_attrs.mode ~= "named pipe" and symlink_attrs.mode ~= "socket" and can_open(path_name, "r") - local is_writable = symlink_attrs.mode ~= "named pipe" and symlink_attrs.mode ~= "socket" and can_open(path_name, "a") --print(util.debug_table(symlink_attrs)) + local permissions = getPermissions(path_name) or {} return { path = path_name, size_bytes = size, is_dir = is_dir, is_symlink = symlink_attrs.mode == "link", - is_readable = is_readable, - is_writable = is_writable, - is_executable = true, --FIXME not obtainable using lfs + is_readable = permissions.r or false, + is_writable = permissions.w or false, + is_executable = permissions.x or false, link_path = symlink_attrs.target or path_name, } end