From c93572c500586afcdf66ff796e650249af02451b Mon Sep 17 00:00:00 2001 From: Ted Trask Date: Thu, 16 Jul 2009 16:03:35 +0000 Subject: Rewrote acf-apk-tools to reflect changes for apk-tools in alpine 1.9 New features: update, upgrade, view details, list top level packages Corresponds to removed functions from apk.lua in acf-core version 0.8.0 Bumped version to 0.3.0 --- Makefile | 2 +- apk-available-html.lsp | 34 ++++++++ apk-controller.lua | 24 ++++-- apk-details-html.lsp | 30 +++++++ apk-expert-html.lsp | 23 +++++- apk-html.lsp | 67 --------------- apk-loaded-html.lsp | 62 ++++++++++++++ apk-model.lua | 219 ++++++++++++++++++++++++++++++++++++++++++++++--- apk.roles | 6 +- 9 files changed, 377 insertions(+), 90 deletions(-) create mode 100644 apk-available-html.lsp create mode 100644 apk-details-html.lsp mode change 120000 => 100644 apk-expert-html.lsp delete mode 100644 apk-html.lsp create mode 100644 apk-loaded-html.lsp 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) %> + +

<%= form.label %>

+
+ + + <% if session.permissions.apk.install or session.permissions.apk.upgrade then %> + + <% end %> + + + + +<% for i,packagetable in pairs(form.value) do %> + + <% if session.permissions.apk.install or session.permissions.apk.upgrade then %> + + <% end %> + + + +<% end %> +
ActionPackage NameVersion
+ <% 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 %> + <%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %><%= html.html_escape(packagetable.version) %>
+
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) %> + +

<%= data.label %>

+
+<% +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) +%> +
+ +<% if session.permissions[page_info.controller].install and data.value.installed.value == "" then %> +
Install
+
+> +
+<% elseif session.permissions[page_info.controller].upgrade and data.value.upgrade.value ~= "" then %> +
Upgrade
+
+> +
+<% end %> diff --git a/apk-expert-html.lsp b/apk-expert-html.lsp deleted file mode 120000 index 15b1930..0000000 --- a/apk-expert-html.lsp +++ /dev/null @@ -1 +0,0 @@ -../filedetails-html.lsp \ No newline at end of file diff --git a/apk-expert-html.lsp b/apk-expert-html.lsp new file mode 100644 index 0000000..a991447 --- /dev/null +++ b/apk-expert-html.lsp @@ -0,0 +1,22 @@ +<% 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 %> +

Update / Upgrade

+<% end %> +<% if session.permissions[page_info.controller].updateall then %> +
Update Index
+
+<% end %> +<% if session.permissions[page_info.controller].upgradeall then %> +
Upgrade All
+
+<% end %> diff --git a/apk-html.lsp b/apk-html.lsp deleted file mode 100644 index afc62bd..0000000 --- a/apk-html.lsp +++ /dev/null @@ -1,67 +0,0 @@ -<% local form, viewlibrary, page_info, session = ... %> -<% require("viewfunctions") %> -<% ---[[ DEBUG INFORMATION -io.write("

DEBUGGING

DEBUG INFO: CFE

") -io.write(html.cfe_unpack(form)) -io.write("
") ---]] -%> - -<% displaycommandresults({"delete", "install"}, session) %> - -<% if form.value.loaded then %> -

Loaded Packages

-
- - - <% if session.permissions.apk.delete then %> - - <% end %> - - - - - -<% for i,packagetable in pairs(form.value.loaded.value) do %> - - <% if session.permissions.apk.delete then %> - - <% end %> - - - - -<% end %> -
DeletePackage NameVersionDescription
- <%= html.link{value = "delete?package=" .. packagetable.name, label="Delete"} %> - <%= html.html_escape(packagetable.name) %><%= html.html_escape(packagetable.version) %><%= html.html_escape(packagetable.description) %>
-
-<% end %> - -<% if form.value.available then %> -

Available Packages

-
- - - <% if session.permissions.apk.install then %> - - <% end %> - - - - -<% for i,packagetable in pairs(form.value.available.value) do %> - - <% if session.permissions.apk.install then %> - - <% end %> - - - -<% end %> -
InstallPackage NameVersion
- <%= html.link{value = "install?package=" .. packagetable.name, label="Install"} %> - <%= html.html_escape(packagetable.name) %><%= html.html_escape(packagetable.version) %>
-
-<% end %> diff --git a/apk-loaded-html.lsp b/apk-loaded-html.lsp new file mode 100644 index 0000000..2aae111 --- /dev/null +++ b/apk-loaded-html.lsp @@ -0,0 +1,62 @@ +<% local form, viewlibrary, page_info, session = ... %> +<% require("viewfunctions") %> + +<% displaycommandresults({"delete", "install", "upgrade"}, session) %> + +

<%= html.html_escape(form.label) %>

+

<%= html.html_escape(form.value.toplevel.label) %>

+
+ + + <% if session.permissions.apk.delete or session.permissions.apk.upgrade then %> + + <% end %> + + + + + +<% for i,packagetable in pairs(form.value.toplevel.value) do %> + + <% if session.permissions.apk.delete then %> + + <% end %> + + + + +<% end %> +
ActionPackage NameVersionDescription
+ <%= 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 %> + <%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %><%= html.html_escape(packagetable.version) %><%= html.html_escape(packagetable.description) %>
+
+ +

<%= html.html_escape(form.value.dependant.label) %>

+
+ + + <% if session.permissions.apk.install then %> + + <% end %> + + + + + +<% for i,packagetable in pairs(form.value.dependant.value) do %> + + <% if session.permissions.apk.install then %> + + <% end %> + + + + +<% end %> +
ActionPackage NameVersionDescription
+ <%= html.link{value = "install?package=" .. packagetable.name, label="Install"} %> + <%= html.link{value = "details?package="..packagetable.name, label=packagetable.name} %><%= html.html_escape(packagetable.version) %><%= html.html_escape(packagetable.description) %>
+
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 -- cgit v1.2.3