aboutsummaryrefslogtreecommitdiffstats
path: root/generate-json.lua
diff options
context:
space:
mode:
authorCarlo Landmeter <clandmeter@gmail.com>2017-11-29 09:28:44 +0100
committerCarlo Landmeter <clandmeter@alpinelinux.org>2017-12-01 18:22:16 +0000
commit44b7203dc9fe828e917eb10e8af98ca366ac53b0 (patch)
tree8c79c1d0923576da3303956c18c13536bdc6d086 /generate-json.lua
downloadalpine-mirror-status-44b7203dc9fe828e917eb10e8af98ca366ac53b0.tar.bz2
alpine-mirror-status-44b7203dc9fe828e917eb10e8af98ca366ac53b0.tar.xz
Initial commit
Diffstat (limited to 'generate-json.lua')
-rwxr-xr-xgenerate-json.lua150
1 files changed, 150 insertions, 0 deletions
diff --git a/generate-json.lua b/generate-json.lua
new file mode 100755
index 0000000..1af51cb
--- /dev/null
+++ b/generate-json.lua
@@ -0,0 +1,150 @@
+#!/usr/bin/lua5.3
+
+local inspect = require("inspect")
+local request = require("http.request")
+local yaml = require("yaml")
+local json = require("cjson")
+local utils = require("utils")
+
+local app_version = "v0.0.1"
+local apkindex_list = "apkindex.list"
+local mirrors_yaml = "https://git.alpinelinux.org/cgit/aports/plain/main/alpine-mirrors/mirrors.yaml"
+local master = "http://rsync.alpinelinux.org/alpine/"
+local output = "_out/mirror-status.json"
+local http_timeout = 3
+
+----
+-- convert apkindex list to a table
+function get_apkindexes()
+ local res = {}
+ local qty = 0
+ for line in io.lines(apkindex_list) do
+ branch, repo, arch = line:match("^alpine/(.*)/(.*)/(.*)/APKINDEX.tar.gz")
+ if type(res[branch]) == "nil" then res[branch] = {} end
+ if type(res[branch][repo]) == "nil" then res[branch][repo] = {} end
+ res[branch][repo][arch] = 1
+ qty = qty + 1
+ end
+ return res, qty
+end
+
+----
+-- convert last-modified header date to timestamp
+function rfc2616_date_to_ts(s)
+ local day,month,year,hour,min,sec
+ local m = { Jan=1, Feb=2, Mar=3, Apr=4, May=5, Jun=6, Jul=7, Aug=8, Sep=9,
+ Oct=10,Nov=11,Dec=12 }
+ local format = "%a+, (%d+) (%a+) (%d+) (%d+):(%d+):(%d+) GMT"
+ local day,month,year,hour,min,sec = s:match(format)
+ return os.time({day=day,month=m[month],year=year,hour=hour,min=min,sec=sec})
+end
+
+----
+-- get a list of http urls from mirrors yaml
+function get_mirrors(uri)
+ local res = {}
+ local headers, stream = assert(request.new_from_uri(uri):go())
+ if headers:get(":status") ~= "200" then
+ error("Failed to get mirrors yaml!")
+ end
+ local y = assert(stream:get_body_as_string())
+ local mirrors = yaml.load(y)
+ for idx, mirror in ipairs(mirrors) do
+ for _,url in ipairs(mirror.urls) do
+ if url:match("http://") then
+ table.insert(res, url)
+ end
+ end
+ end
+ return res
+end
+
+function get_index_status(uri)
+ local res = {}
+ local status, modified
+ local headers = request.new_from_uri(uri):go(http_timeout)
+ if headers then
+ status = headers:get(":status")
+ else
+ return "failed"
+ end
+ if status == "200" then
+ modified = headers:get("last-modified")
+ modified = rfc2616_date_to_ts(modified)
+ end
+ return status, modified
+end
+
+--- write results to json file on disk
+function write_json(t)
+ local f = assert(io.open(output, "w"))
+ local json = assert(json.encode(t))
+ f:write(json)
+ f:close()
+end
+
+--- show a process indicator on stdout
+function progress(num)
+ num = (num < 10) and "0"..num or num
+ io.write(("Indexes left: %s\r"):format(num))
+ io.flush()
+end
+
+-- check all apkindex for specific mirror
+function check_apkindexes(mirror)
+ local indexes, num_indexes = get_apkindexes()
+ local branches = {}
+ local qty = 0
+ local cnt = 0
+ for branch in utils.kpairs(indexes, utils.sort_branch) do
+ local repos = {}
+ for repo in utils.kpairs(indexes[branch], utils.sort_repo) do
+ local archs = {}
+ for arch in utils.kpairs(indexes[branch][repo], utils.sort_arch) do
+ if type(utils.allowed.archs[arch]) == "number" then
+ local uri = ("%s/%s/%s/%s/APKINDEX.tar.gz"):format(mirror, branch, repo, arch)
+ status, modified = get_index_status(uri)
+ table.insert(archs, {name=arch, status=status, modified=modified})
+ if status == "200" then qty = qty+1 end
+ end
+ cnt = cnt + 1
+ progress(num_indexes-cnt)
+ end
+ table.insert(repos, {name=repo, arch=archs})
+ end
+ table.insert(branches, {name=branch, repo=repos})
+ end
+ return branches, qty
+end
+
+function process_mirrors()
+ local res = {}
+ local mirrors = get_mirrors(mirrors_yaml)
+ for idx,mirror in ipairs(mirrors) do
+ local start_time = os.time()
+ res[idx] = {}
+ res[idx].url = mirror
+ print(("[%s/%s] Getting indexes from mirror: %s"):format(idx,
+ #mirrors, mirror))
+ res[idx].branch, res[idx].count = check_apkindexes(mirror)
+ res[idx].duration = os.difftime(os.time(),start_time)
+ end
+ return res
+end
+
+function process_master()
+ print(("Getting indexes from master: %s"):format(master))
+ local res = {}
+ res.url = master
+ res.branch = check_apkindexes(master)
+ return res
+end
+
+write_json(
+ {
+ master = process_master(),
+ mirrors = process_mirrors(),
+ date = os.time(),
+ version = app_version
+ }
+)