summaryrefslogtreecommitdiffstats
path: root/rrdtool-model.lua
blob: 30a65f4ad59c18a68b3f96d27f886cf5388fa06e (plain)
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
module(..., package.seeall)

-- Load libraries
require("modelfunctions")
require("posix")
require("fs")
require("format")
require("date")
require("validator")

-- Set variables
local configfile = "/etc/rrdtool/acf-rrdtool.conf"
local databases = "/etc/rrdtool/databases"
local processname = "rrdtool"
local packagename = "rrdtool"
local header = "rrdtool"
local path="PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "

-- ################################################################################
-- LOCAL FUNCTIONS

-- Function to recursively insert all filenames in a dir into an array
local function recursedir(path, filearray)
	filearray = filearray or {}
	local k,v
	for k,v in pairs(posix.dir(path) or {}) do
		-- Ignore files that begins with a '.'
		if not string.match(v, "^%.") then
			local f = path .. "/" .. v
			-- If subfolder exists, list files in this subfolder
			if (posix.stat(f).type == "directory") then
				recursedir(f, filearray)
			else
				table.insert(filearray, f)
			end
		end
	end
	return filearray
end

local function file_info ( path )
	local st = fs.stat(path)
	local size = st.size or "0"
	local lastmod = st.mtime or "---"
	return lastmod,size
end

local function list_files ()
	local listed_files = {}
	local open_files = {}
	local files = {}
	local k,v
	-- Generate a single table with all the files
	for k,v in pairs{databases} do
		recursedir(v, files)
	end

	-- Loop through each file and present its info
	for k,v in pairs(files) do
		-- Get info on this specific file and put it in a table
		local lastmod,size = file_info(v)
		local filename = cfe({ value=v, label="File name" })
		local filesize = cfe({ value=size, label="File size" })
		local mtime = cfe({ value=lastmod, label="File date" })
		table.insert ( listed_files , cfe({ type="group", value={filename=filename, filesize=filesize, mtime=mtime, label="File details"} }) )
	end
	table.sort(listed_files, function (a,b) return (a.value.filename.value < b.value.filename.value) end )
	return cfe({ type="list", value=listed_files, label="Log files" })

end


local function validfilename(path)
	local files = list_files()
	for k,v in pairs(files.value) do
		if (v["value"]["filename"]["value"] == path) then
			return true, tostring(v["value"]["filename"]["value"])
		end
	end
	return false, "Not a valid filename!"
end

-- ################################################################################
-- PUBLIC FUNCTIONS

function startstop_service(action)
	return modelfunctions.startstop_service(processname, action)
end

function getstatus()
	return modelfunctions.getstatus(processname, packagename, header .. " status")
end

function getconfigfile()
	return modelfunctions.getfiledetails(configfile)
end

function setconfigfile(filedetails)
	return modelfunctions.setfiledetails(filedetails, {configfile})
end

function getrrdlist()
	return list_files()
end

function createnewrrd()
	local newdb = {}
		newdb.filename = cfe({label="Name",value="mydb.rrd",descr="The name of the RRD you want to create. RRD files should end with the extension .rrd. However, RRDtool will accept any filename."})
		newdb.start = cfe({label="Start",value="",descr="Specifies the time in seconds since 1970-01-01 UTC when the first value should be added to the RRD. RRDtool will not accept any data timed before or at the time specified.\
(Your system saids that your current time is '" .. tostring(os.time(os.date("*t"))) .. "' in the format you should specify above. The startvalue should be smaller than your current time.)\
(Default: now - 10s)"})
		newdb.step = cfe({label="Step",value="",descr="Specifies the base interval in seconds with which data will be fed into the RRD.\
(Default: 300)"})
		newdb.ds = cfe({label="Data store(s)",value="",descr="DS:ds-name:GAUGE | COUNTER | DERIVE | ABSOLUTE:heartbeat:min:max \
DS:ds-name:COMPUTE:rpn-expression",type="longtext"})
		newdb.rra = cfe({label="Round Robin Archive(s)",value="",descr="RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows",type="longtext"})
	return {value=newdb}
end

function remove_file(self, path, userid)
	local success = "Failed to delete file"
	local errtxt
	if not (fs.is_file(path)) then
		errtxt = "File doesn't exist!"
	elseif (validfilename(path)) then
		os.remove(path)
		success = "File Deleted"
	else
		errtxt = "Not a valid filename!"
	end
	return cfe({ value=success, label="Delete config file result", errtxt=errtxt })
end

function rrd_info(self, path, userid)
	local success, errtxt
	if (validfilename(path)) then
		local f = io.popen( "/usr/bin/rrdtool info ".. tostring(path) )
		success = f:read("*a") or ""
		f:close()
	end
	return cfe({ value=success, label="rrdtool info ".. tostring(path) , errtxt=errtxt })
end

function savenewrrd(self, configfile, userid)
	path=tostring(databases).."/"..configfile.value.filename.value
	configfile.errtxt = "Failed to create file"
	local path = configfile.value.filename.value
	if not string.find(path, "/") then
		path = databases .. "/" .. path
	elseif not validator.is_valid_filename(path,databases) then
		configfile.value.filename.errtxt = "Not a valid path!\
If you specify path, it should be " .. tostring(databases) .."/"
		return configfile
	end
		if (posix.stat(path)) then
			configfile.value.filename.errtxt = "File already exists"
		elseif not tonumber(configfile.value.start.value) then
			configfile.value.start.errtxt = "Only numeric values!"
			return configfile
		elseif not tonumber(configfile.value.step.value) then
			configfile.value.step.errtxt = "Only numeric values!"
			return configfile
		else
			local start,step
			if (#configfile.value.start.value > 0) then
				start = "--start " .. tostring(configfile.value.start.value) .. " "
			else
				start = ""
			end
			if (#configfile.value.step.value > 0) then
				step = "--step " .. tostring(configfile.value.step.value) .. " "
			else
				step = ""
			end
			local f = io.popen( "/usr/bin/rrdtool create ".. 
			  format.escapespecialcharacters(path) .. " " ..
			  format.escapespecialcharacters(start) ..
			  format.escapespecialcharacters(step) ..
			  tostring(string.gsub(format.dostounix(format.escapespecialcharacters(configfile.value.ds.value)),"\n", " \\\n")) .. " " ..
			  tostring(string.gsub(format.dostounix(format.escapespecialcharacters(configfile.value.rra.value)),"\n", " \\\n")) .. " 2>&1")
			success = f:read("*a") or ""
			f:close()
			configfile.errtxt = tostring(success)
		end

	return configfile
end