1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
|
--
-- (C) 2014-22 - ntop.org
--
local dirs = ntop.getDirs()
local tracker = require "tracker"
local os_utils = {}
local is_windows = ntop.isWindows()
local is_freebsd = ntop.isFreeBSD()
local dirs = ntop.getDirs()
local NTOPCTL_CMD = dirs.bindir.."/ntopctl"
local NTOPNG_CONFIG_TOOL = dirs.bindir.."/ntopng-utils-manage-config"
-- ########################################################
function os_utils.getPathDivider()
if(is_windows) then
return "\\"
else
return "/"
end
end
-- ########################################################
-- Fix path format Unix <-> Windows
function os_utils.fixPath(path)
path = string.gsub(path, "//+", '/') -- removes possibly empty parts of the path
if(is_windows and (string.len(path) > 2)) then
path = string.gsub(path, "/", os_utils.getPathDivider())
end
return(path)
end
-- ########################################################
--! @brief Copy a `source` file to `dest`
function os_utils.copyFile(source, dest)
if not ntop.exists(source) then
return
end
local inp = assert(io.open(source, "rb"))
local out = assert(io.open(dest, "wb"))
local data = inp:read("*all")
out:write(data)
assert(out:close())
end
-- ########################################################
--! @brief Execute a system command and return its output
--! @return the pair (output, ret_code). output will be nil on error.
--! @note error condition is determined from the command exit status
--! @note redirect the stderr of the command if the command is expected to fail
function os_utils.execWithOutput(c, ret_code_success)
local debug = false
local f_name = nil
local f
ret_code_success = ret_code_success or 0
if(is_windows) then
return nil
end
if(debug) then tprint(c) end
if is_freebsd then
f_name = os.tmpname()
os.execute(c.." > "..f_name)
f = io.open(f_name, 'r')
else
f = io.popen(c, 'r')
end
if f == nil then
return nil, -1
end
local ret_string = f:read('*a')
if ret_string ~= nil then
if(debug) then tprint(s) end
end
local rv = { f:close() }
local retcode = ret_code_success
if f_name then
os.remove(f_name)
else
retcode = rv[3]
end
if retcode ~= ret_code_success then
return nil, retcode
end
return ret_string, retcode
end
-- ########################################################
local function ntopctl_cmd(service_name, use_sudo, ...)
if not ntop.exists(NTOPCTL_CMD) then
return nil
end
local cmd = {NTOPCTL_CMD, service_name, ...}
if use_sudo then
table.insert(cmd, 1, "sudo")
end
return table.concat(cmd, " ")
end
--! @brief Execute service control tool and get its output.
--! @return Command output. See os_utils.execWithOutput for details.
function os_utils.ntopctlCmd(service_name, ...)
local cmd = ntopctl_cmd(service_name, true, ...)
if not cmd then return nil end
return os_utils.execWithOutput(cmd)
end
-- ########################################################
--! @brief Check if a service is available into the system.
--! @return true if service is available, false otherwise.
function os_utils.hasService(service_name, ...)
local prefs = ntop.getPrefs()
if not isEmptyString(prefs.user)
and prefs.user ~= "ntopng"
and prefs.user ~= "root" then
return false
end
local has_ntopctl = os_utils.execWithOutput("which ntopctl >/dev/null 2>&1")
if has_ntopctl == nil then
-- ntopctl is not available
return false
end
if not ntop.exists(NTOPNG_CONFIG_TOOL) then
return false
end
local cmd = ntopctl_cmd(service_name, false, "has-service", ...)
if not cmd then return false end
local rv = os_utils.execWithOutput(cmd)
return(rv == "yes\n")
end
-- ########################################################
--! @brief Enable a service
--! @return true if service was enabled successfully, false otherwise
function os_utils.enableService(service_name, ...)
local cmd = ntopctl_cmd(service_name, true, "enable", ...)
if not cmd then return false end
os_utils.execWithOutput(cmd)
return os_utils.isEnabled(service_name)
end
-- ########################################################
--! @brief Disable a service
--! @return true if service was disabled successfully, false otherwise
function os_utils.disableService(service_name, ...)
local cmd = ntopctl_cmd(service_name, true, "disable", ...)
if not cmd then return false end
os_utils.execWithOutput(cmd)
return not os_utils.isEnabled(service_name)
end
-- ########################################################
--! @brief Restart a service
--! @note See os_utils.execWithOutput for return value
function os_utils.restartService(service_name, ...)
local cmd = ntopctl_cmd(service_name, true, "restart", ...)
if not cmd then return false end
os_utils.execWithOutput(cmd)
return(os_utils.serviceStatus(service_name) == "active")
end
-- ########################################################
--! @brief Stop a service
--! @note See os_utils.execWithOutput for return value
function os_utils.stopService(service_name, ...)
local cmd = ntopctl_cmd(service_name, true, "stop", ...)
if not cmd then return false end
os_utils.execWithOutput(cmd)
return(os_utils.serviceStatus(service_name) == "inactive")
end
-- ########################################################
--! @brief Check the service status.
--! @return active|inactive|error
function os_utils.serviceStatus(service_name, ...)
local cmd = ntopctl_cmd(service_name, false, "is-active", ...)
if not cmd then return "error" end
local rv = os_utils.execWithOutput(cmd)
if rv == "active\n" then
return "active"
elseif rv == "inactive\n" then
return "inactive"
else
return "error"
end
end
-- ########################################################
--! @brief List a series of services along with their status
--! @return a table with one or more <service name>="[active|inactive]"
function os_utils.serviceListWithStatus(service_name)
local cmd = ntopctl_cmd(service_name, false, "list")
if not cmd then return "error" end
local rv = os_utils.execWithOutput(cmd) or ""
rv = rv:split("\n") or {}
local res = {}
for _, service in ipairs(rv) do
service = service:split(" ") or {}
if #service == 3 then
local service_name, service_status, service_conf = service[1], service[2], service[3]
res[#res + 1] = {name = service_name, status = service_status, conf = service_conf}
end
end
return res
end
-- ########################################################
--! @brief Check if the service is active
--! @return true if service is active, false otehrwise
function os_utils.isActive(service_name, ...)
return(os_utils.serviceStatus(service_name, ...) == "active")
end
-- ########################################################
function os_utils.isEnabled(service_name, ...)
local cmd = ntopctl_cmd(service_name, false, "is-enabled", ...)
if not cmd then return false end
local rv = os_utils.execWithOutput(cmd)
return(rv == "enabled")
end
-- ########################################################
-- TRACKER HOOK
tracker.track(os_utils, 'enableService')
tracker.track(os_utils, 'disableService')
-- ########################################################
return os_utils
|