summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--apk-available-html.lsp34
-rw-r--r--apk-controller.lua24
-rw-r--r--apk-details-html.lsp30
-rw-r--r--[l---------]apk-expert-html.lsp23
-rw-r--r--apk-loaded-html.lsp (renamed from apk-html.lsp)41
-rw-r--r--apk-model.lua219
-rw-r--r--apk.roles6
8 files changed, 333 insertions, 46 deletions
diff --git a/Makefile b/Makefile
index 30fcc84..35fd038 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
APP_NAME=apk-tools
PACKAGE=acf-$(APP_NAME)
-VERSION=0.2.0
+VERSION=0.3.0
APP_DIST=\
apk* \
diff --git a/apk-available-html.lsp b/apk-available-html.lsp
new file mode 100644
index 0000000..808a513
--- /dev/null
+++ b/apk-available-html.lsp
@@ -0,0 +1,34 @@
+<% local form, viewlibrary, page_info, session = ... %>
+<% require("viewfunctions") %>
+
+<% displaycommandresults({"upgrade", "install"}, session) %>
+
+<H1><%= form.label %></H1>
+<DL>
+<TABLE>
+ <TR style="background:#eee;font-weight:bold;">
+ <% if session.permissions.apk.install or session.permissions.apk.upgrade then %>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Action</TD>
+ <% end %>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Package Name</TD>
+ <TD style="white-space:nowrap;" WIDTH="90%" class="header">Version</TD>
+ </TR>
+
+<% for i,packagetable in pairs(form.value) do %>
+ <TR>
+ <% if session.permissions.apk.install or session.permissions.apk.upgrade then %>
+ <TD style="padding-right:20px;white-space:nowrap;">
+ <% if session.permissions.apk.install and not packagetable.upgrade then %>
+ <%= html.link{value = "install?package=" .. packagetable.name, label="Install "} %>
+ <% end %>
+ <% if session.permissions.apk.upgrade and packagetable.upgrade then %>
+ <%= html.link{value = "upgrade?package=" .. packagetable.name, label="Upgrade "} %>
+ <% end %>
+ </TD>
+ <% end %>
+ <TD><%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %></TD>
+ <TD><%= html.html_escape(packagetable.version) %></TD>
+ </TR>
+<% end %>
+</TABLE>
+</DL>
diff --git a/apk-controller.lua b/apk-controller.lua
index 8ceace3..e3dcf75 100644
--- a/apk-controller.lua
+++ b/apk-controller.lua
@@ -5,16 +5,16 @@ module (..., package.seeall)
default_action = "loaded"
-read = function(self)
- return self.model.get_packages()
-end
-
loaded = function(self)
- return cfe({ type="group", value={loaded=self.model.get_loaded_packages()} })
+ return self.model.get_loaded_packages()
end
available = function(self)
- return cfe({ type="group", value={available=self.model.get_available_packages()} })
+ return self.model.get_available_packages()
+end
+
+details = function(self)
+ return self.model.get_package_details(self.clientdata.package)
end
delete = function(self)
@@ -25,6 +25,18 @@ install = function(self)
return self:redirect_to_referrer(self.model.install_package(self.clientdata.package or "", self.sessiondata))
end
+upgrade = function(self)
+ return self:redirect_to_referrer(self.model.upgrade_package(self.clientdata.package or "", self.sessiondata))
+end
+
expert = function(self)
return controllerfunctions.handle_form(self, self.model.get_configfile, self.model.update_configfile, self.clientdata, "Save", "Edit Configuration", "Configuration Saved")
end
+
+updateall = function(self)
+ return self:redirect_to_referrer(self.model.update_all())
+end
+
+upgradeall = function(self)
+ return self:redirect_to_referrer(self.model.upgrade_all())
+end
diff --git a/apk-details-html.lsp b/apk-details-html.lsp
new file mode 100644
index 0000000..af1cf6b
--- /dev/null
+++ b/apk-details-html.lsp
@@ -0,0 +1,30 @@
+<% local data, viewlibrary, page_info, session = ...
+require("viewfunctions")
+%>
+
+<% displaycommandresults({"install", "upgrade"}, session) %>
+
+<H1><%= data.label %></H1>
+<DL>
+<%
+displayitem(data.value.package)
+displayitem(data.value.installed)
+displayitem(data.value.version)
+displayitem(data.value.comment)
+displayitem(data.value.webpage)
+displayitem(data.value.size)
+displayitem(data.value.upgrade)
+%>
+</DL>
+
+<% if session.permissions[page_info.controller].install and data.value.installed.value == "" then %>
+<DL><DT>Install</DT>
+<DD><form action="install" method="POST">
+<input class="hidden" type="hidden" name="package" value=<%= data.value.package.value %>>
+<input class="submit" type="submit" value="Install"></form></DD></DL>
+<% elseif session.permissions[page_info.controller].upgrade and data.value.upgrade.value ~= "" then %>
+<DL><DT>Upgrade</DT>
+<DD><form action="upgrade" method="POST">
+<input class="hidden" type="hidden" name="package" value=<%= data.value.package.value %>>
+<input class="submit" type="submit" value="Upgrade"></form></DD></DL>
+<% end %>
diff --git a/apk-expert-html.lsp b/apk-expert-html.lsp
index 15b1930..a991447 120000..100644
--- a/apk-expert-html.lsp
+++ b/apk-expert-html.lsp
@@ -1 +1,22 @@
-../filedetails-html.lsp \ No newline at end of file
+<% local form, viewlibrary, page_info, session = ... %>
+<% require("viewfunctions") %>
+
+<% displaycommandresults({"updateall", "upgradeall"}, session) %>
+
+<%
+local pattern = string.gsub(page_info.prefix..page_info.controller, "[%(%)%.%%%+%-%*%?%[%]%^%$]", "%%%1")
+local func = haserl.loadfile(page_info.viewfile:gsub(pattern..".*$", "/") .. "filedetails-html.lsp")
+func(form, viewlibrary, page_info, session)
+%>
+
+<% if session.permissions[page_info.controller].updateall or session.permissions[page_info.controller].upgradeall then %>
+<H2>Update / Upgrade</H2>
+<% end %>
+<% if session.permissions[page_info.controller].updateall then %>
+ <DL><DT>Update Index</DT>
+ <DD><form action="updateall" method="POST"><input class="submit" type="submit" value="Update"></form></DD></DL>
+<% end %>
+<% if session.permissions[page_info.controller].upgradeall then %>
+ <DL><DT>Upgrade All</DT>
+ <DD><form action="upgradeall" method="POST"><input class="submit" type="submit" value="Upgrade"></form></DD></DL>
+<% end %>
diff --git a/apk-html.lsp b/apk-loaded-html.lsp
index afc62bd..2aae111 100644
--- a/apk-html.lsp
+++ b/apk-loaded-html.lsp
@@ -1,67 +1,62 @@
<% local form, viewlibrary, page_info, session = ... %>
<% require("viewfunctions") %>
-<%
---[[ DEBUG INFORMATION
-io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
-io.write(html.cfe_unpack(form))
-io.write("</span>")
---]]
-%>
-<% displaycommandresults({"delete", "install"}, session) %>
+<% displaycommandresults({"delete", "install", "upgrade"}, session) %>
-<% if form.value.loaded then %>
-<H1>Loaded Packages</H1>
+<H1><%= html.html_escape(form.label) %></H1>
+<H2><%= html.html_escape(form.value.toplevel.label) %></H2>
<DL>
<TABLE>
<TR style="background:#eee;font-weight:bold;">
- <% if session.permissions.apk.delete then %>
- <TD style="padding-right:20px;white-space:nowrap;" class="header">Delete</TD>
+ <% if session.permissions.apk.delete or session.permissions.apk.upgrade then %>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Action</TD>
<% end %>
<TD style="padding-right:20px;white-space:nowrap;" class="header">Package Name</TD>
<TD style="padding-right:20px;white-space:nowrap;" class="header">Version</TD>
<TD style="white-space:nowrap;" class="header">Description</TD>
</TR>
-<% for i,packagetable in pairs(form.value.loaded.value) do %>
+<% for i,packagetable in pairs(form.value.toplevel.value) do %>
<TR>
<% if session.permissions.apk.delete then %>
<TD style="padding-right:20px;white-space:nowrap;">
- <%= html.link{value = "delete?package=" .. packagetable.name, label="Delete"} %>
+ <%= html.link{value = "delete?package=" .. packagetable.name, label="Delete "} %>
+ <% if session.permissions.apk.upgrade and packagetable.upgrade then %>
+ <%= html.link{value = "upgrade?package=" .. packagetable.name, label="Upgrade "} %>
+ <% end %>
</TD>
<% end %>
- <TD><%= html.html_escape(packagetable.name) %></TD>
+ <TD><%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %></TD>
<TD><%= html.html_escape(packagetable.version) %></TD>
<TD><%= html.html_escape(packagetable.description) %></TD>
</TR>
<% end %>
</TABLE>
</DL>
-<% end %>
-<% if form.value.available then %>
-<H1>Available Packages</H1>
+<H2><%= html.html_escape(form.value.dependant.label) %></H2>
<DL>
<TABLE>
<TR style="background:#eee;font-weight:bold;">
<% if session.permissions.apk.install then %>
- <TD style="padding-right:20px;white-space:nowrap;" class="header">Install</TD>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Action</TD>
<% end %>
<TD style="padding-right:20px;white-space:nowrap;" class="header">Package Name</TD>
- <TD style="white-space:nowrap;" WIDTH="90%" class="header">Version</TD>
+ <TD style="padding-right:20px;white-space:nowrap;" class="header">Version</TD>
+ <TD style="white-space:nowrap;" class="header">Description</TD>
</TR>
-<% for i,packagetable in pairs(form.value.available.value) do %>
+<% for i,packagetable in pairs(form.value.dependant.value) do %>
<TR>
<% if session.permissions.apk.install then %>
<TD style="padding-right:20px;white-space:nowrap;">
<%= html.link{value = "install?package=" .. packagetable.name, label="Install"} %>
</TD>
<% end %>
- <TD><%= html.html_escape(packagetable.name) %></TD>
+ <TD><%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %></TD>
<TD><%= html.html_escape(packagetable.version) %></TD>
+ <TD><%= html.html_escape(packagetable.description) %></TD>
</TR>
<% end %>
</TABLE>
</DL>
-<% end %>
diff --git a/apk-model.lua b/apk-model.lua
index 66a9a30..e23ecc2 100644
--- a/apk-model.lua
+++ b/apk-model.lua
@@ -4,26 +4,170 @@ require("apk")
require("modelfunctions")
local configfile = "/etc/apk/repositories"
+local worldfile = "/var/lib/apk/world"
-get_all_packages = function()
- -- read in all of the packages
- return cfe({ type="list", value=apk.get_all(), label="All Packages"})
+local path = "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin "
+
+local repo = nil
+local install_cache = false
+local toplevel
+
+-- ################################################################################
+-- LOCAL FUNCTIONS
+
+local function gettoplevel()
+ if not toplevel then
+ toplevel = {}
+ local top = format.string_to_table(fs.read_file(worldfile) or "", "%s+")
+ for i,name in ipairs(top) do
+ toplevel[name] = i
+ end
+ end
+ return toplevel
+end
+
+local run_apk_cmd = function(cmd)
+ local c = path.."apk "..cmd.." 2>&1"
+ local f = io.popen(c)
+ local cmdresult = f:read("*a")
+ f:close()
+ return cmdresult
+end
+
+local reload_installed = function()
+ if repo then
+ -- clear out installed info
+ for name,value in pairs(repo) do
+ if value then
+ value.installed = nil
+ value.comment = nil
+ end
+ end
+ -- read in which are installed
+ local f = io.popen(path.."apk info -vv 2>/dev/null")
+ for line in f:lines() do
+ local name, ver, comment = string.match(line, "(%S+)%-(%d+%S*)%s+%-%s+(.*)")
+ if not repo[name] then
+ repo[name] = {}
+ end
+ repo[name].installed = ver
+ repo[name].comment = comment
+ end
+ f:close()
+ install_cache = true
+ end
+ return repo
end
+local repository = function()
+ if not repo then
+ -- read in all of the packages
+ local f = io.popen(path.."apk search 2>/dev/null")
+ repo = {}
+ install_cache = false
+ for line in f:lines() do
+ local name, ver = string.match(line, "(.*)%-(%d+.*)")
+ if name then
+ repo[name] = {}
+ repo[name].version = ver
+ end
+ end
+ f:close()
+ end
+ if not install_cache then
+ reload_installed()
+ end
+ return repo
+end
+
+-- Find all the packages that depend on this package (using recursion)
+-- package is the name of the package
+-- tab saves dependants for already processed packages
+-- saved marks when package included in output
+-- output is the output
+function find_dependants(package)
+ repo = repo or repository()
+ if not repo[package] then
+ return {}
+ end
+ if not repo[package].dependants then
+ repo[package].dependants = {}
+ local cmd = path .. "apk info -R "..package
+ local f = io.popen(cmd)
+ for line in f:lines() do
+ if not line:find("depends on:") and not line:find("^%s*$") then
+ table.insert(repo[package].dependants, line)
+ for i,dep in ipairs(find_dependants(line, saved, output)) do
+ table.insert(repo[package].dependants, dep)
+ end
+ end
+ end
+ end
+ return repo[package].dependants
+end
+
+local function upgrade_available(package)
+ local retval = false
+ repo = repo or repository()
+ if repo[package] and repo[package].version > repo[package].installed then
+ retval = true
+ else -- check the dependants
+ for i,dep in ipairs(find_dependants(package)) do
+ if repo[dep] and repo[dep].version > repo[dep].installed then
+ retval = true
+ break
+ end
+ end
+ end
+ return retval
+end
+
+-- ################################################################################
+-- PUBLIC FUNCTIONS
+
get_loaded_packages = function()
+ repo = repository()
+ toplevel = gettoplevel()
+
-- read in the loaded packages
- return cfe({ type="list", value=apk.get_loaded(), label="Loaded Packages"})
+ local top = cfe({ type="list", value={}, label="Top Level Packages"})
+ local depend = cfe({ type="list", value={}, label="Dependant Packages"})
+ for name,value in pairs(repo) do
+ if value.installed then
+ local temp = {}
+ temp.name = name
+ temp.version = value.installed
+ temp.description = value.comment
+ if toplevel[name] then
+ temp.upgrade = upgrade_available(name)
+ top.value[#top.value+1] = temp
+ else
+ depend.value[#depend.value+1] = temp
+ end
+ end
+ end
+ table.sort(top.value, function(a,b) return (a.name < b.name) end)
+ table.sort(depend.value, function(a,b) return (a.name < b.name) end)
+ return cfe({ type="group", value={toplevel=top, dependant=depend}, label="Loaded Packages" })
end
get_available_packages = function()
- -- available are all except loaded
- return cfe({ type="list", value=apk.get_available(), label="Available Packages" })
-end
-
-get_packages = function()
- local loaded = get_loaded_packages()
- local available = get_available_packages()
- return cfe({ type="group", value={loaded=loaded, available=available} })
+ repo = repository()
+ -- available are all except same version installed
+ local available = cfe({ type="list", value={}, label="Available Packages" })
+ for name,value in pairs(repo) do
+ if value.version ~= value.installed then
+ local temp = {}
+ temp.name = name
+ temp.version = value.version
+ if value.installed and value.version > value.installed then
+ temp.upgrade = true
+ end
+ available.value[#available.value + 1] = temp
+ end
+ end
+ table.sort(available.value, function(a,b) return (a.name < b.name) end)
+ return available
end
delete_package = function(package, sessiondata)
@@ -46,6 +190,18 @@ install_package = function(package,sessiondata)
return cfe({ value=cmdresult, label="Result of Install" })
end
+upgrade_package = function(package)
+ return cfe({ value=run_apk_cmd("add -u "..package), label="Result of Package Upgrade" })
+end
+
+update_all = function()
+ return cfe({ value=run_apk_cmd("update"), label="Result of Update" })
+end
+
+upgrade_all = function()
+ return cfe({ value=run_apk_cmd("upgrade"), label="Result of Upgrade" })
+end
+
get_configfile = function()
return modelfunctions.getfiledetails(configfile)
end
@@ -53,3 +209,42 @@ end
update_configfile = function(newconfig)
return modelfunctions.setfiledetails(newconfig, {configfile})
end
+
+get_package_details = function(package)
+ repo = repo or repository()
+ local details = {}
+ details.package = cfe({ value=package, label="Package" })
+ details.version = cfe({ label="Available Version" })
+ details.installed = cfe({ label="Installed Version" })
+ details.comment = cfe({ label="Description" })
+ details.webpage = cfe({ label="Web Page" })
+ details.size = cfe({ label="Size" })
+ details.upgrade = cfe({ label="Upgrade Details" })
+ if not repo[package] then
+ details.package.errtxt = "Invalid package"
+ else
+ details.version.value = repo[package].version
+ if repo[package].installed then
+ --details.installed.value = string.match(cmdresult[1], "%S*")
+ details.installed.value = repo[package].installed
+ details.comment.value = repo[package].comment
+ local cmdresult = format.string_to_table(run_apk_cmd("info -ws "..package), "\n")
+ details.webpage.value = cmdresult[2] or ""
+ details.size.value = cmdresult[5] or ""
+ local dependants = find_dependants(package)
+ table.insert(dependants, 1, package)
+ local revdeps = {}
+ details.upgrade.value = {}
+ for i,val in ipairs(dependants) do
+ if not revdeps[val] then
+ revdeps[val] = true
+ if repo[val].version > repo[val].installed then
+ table.insert(details.upgrade.value, val.." "..repo[val].installed.." -> "..repo[val].version)
+ end
+ end
+ end
+ details.upgrade.value = table.concat(details.upgrade.value, "\n")
+ end
+ end
+ return cfe({ type="group", value=details, label="Package Details" })
+end
diff --git a/apk.roles b/apk.roles
index 3c1f2b0..d7b4e34 100644
--- a/apk.roles
+++ b/apk.roles
@@ -1,3 +1,3 @@
-USER=apk:loaded,apk:available
-EXPERT=apk:expert,apk:delete,apk:install
-ADMIN=apk:loaded,apk:available,apk:expert,apk:delete,apk:install,apk:read
+USER=apk:loaded,apk:available,apk:details
+EXPERT=apk:expert,apk:delete,apk:install,apk:upgrade,apk:updateall,apk:upgradeall
+ADMIN=apk:loaded,apk:available,apk:details,apk:expert,apk:delete,apk:install,apk:upgrade,apk:updateall,apk:upgradeall