-
Notifications
You must be signed in to change notification settings - Fork 264
/
fetch-latest-releases.lua
executable file
·152 lines (131 loc) · 3.82 KB
/
fetch-latest-releases.lua
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
#!/usr/bin/lua5.3
-- script to fetch and parse latest-releases.yaml from master site
-- and fetch the latest minirootfs images for all available branches
local request = require("http.request")
local cqueues = require("cqueues")
local yaml = require("lyaml")
local lfs = require("lfs")
local m = {}
m.mirror = os.getenv("MIRROR") or "https://cz.alpinelinux.org/alpine"
function m.fatal(...)
m.errormsg(...)
os.exit(1)
end
function m.fetch(url)
local headers, stream = request.new_from_uri(url):go()
if not headers then
m.fatal("Error: %s: %s", url, stream)
end
local body = stream:get_body_as_string()
return headers:get(":status"), body
end
function m.errormsg(...)
local msg = string.format(...)
io.stderr:write(string.format("%s\n", msg))
return nil, msg
end
function m.fetch_file(url, outfile)
local headers, stream = request.new_from_uri(url):go()
if not headers then
m.fatal("Error: %s: %s", url, stream)
end
if headers:get(":status") ~= "200" then
m.fatal("Error: HTTP %s: %s", headers:get(":status"), url)
end
local partfile = string.format("%s.part", outfile)
local f, errmsg = io.open(partfile, "w")
if not f then
return errormsg("Error: %s: %s:", file, errmsg)
end
local ok, errmsg, errnum = stream:save_body_to_file(f)
f:close()
if not ok then
return errormsg("Error: %s: %s", errmsg, url)
end
return os.rename(partfile, outfile)
end
function m.mkdockerfile(dir, rootfsfile)
local filename = string.format("%s/Dockerfile", dir)
local f, err = io.open(filename, "w")
if not f then
m.fatal("Error: %s: %s", filename, err)
end
f:write(string.format('FROM scratch\nADD %s /\nCMD ["/bin/sh"]\n', rootfsfile))
f:close()
end
function m.minirootfs_image(images)
for _, img in pairs(images) do
if img.flavor == "alpine-minirootfs" then
return img
end
end
return nil
end
function m.get_minirootfs(images, destdir)
local img = m.minirootfs_image(images)
if destdir then
local url = string.format("%s/%s/releases/%s/%s", m.mirror, img.branch, img.arch, img.file)
local archdir = string.format("%s/%s", destdir, img.arch)
local ok, errmsg = lfs.mkdir(archdir)
m.fetch_file(url, string.format("%s/%s", archdir, img.file))
m.mkdockerfile(archdir, img.file)
print(img.file)
end
return { version = img.version, file = img.file, sha512 = img.sha512 }
end
-- get array of minirootsfs releases --
function m.get_releases(branch, destdir)
local arches = { "aarch64", "armhf", "armv7", "loongarch64", "ppc64le", "riscv64", "s390x", "x86", "x86_64" }
local t = {}
local loop = cqueues.new()
for _, arch in pairs(arches) do
loop:wrap(function()
local url = string.format("%s/%s/releases/%s/latest-releases.yaml", m.mirror, branch, arch)
local status, body = m.fetch(url)
if status == "200" then
t[arch] = m.get_minirootfs((yaml.load(body)), destdir)
end
end)
end
loop:loop()
return t
end
function m.equal_versions(releases)
local prev = nil
for arch, img in pairs(releases) do
if prev == nil then
prev = img.version
end
if prev ~= img.version then
return false, arch
end
prev = img.version
end
return true
end
-- return functions as module for unit testing
if not string.match(arg[0], "fetch%-latest%-releases") then
return m
end
local branch = arg[1] or "edge"
local destdir = arg[2] or "out"
lfs.mkdir(destdir)
local version
local releases = m.get_releases(branch, destdir)
if next(releases) == nil then
m.fatal("No releases found on %s/%s/releases", m.mirror, branch)
end
if not m.equal_versions(releases) then
m.fatal("not all versions are equal")
end
local f = io.open(string.format("%s/checksums.sha512", destdir), "w")
for arch, rel in pairs(releases) do
local line = string.format("%s %s/%s\n", rel.sha512, arch, rel.file)
f:write(line)
version = rel.version
end
f:close()
-- write version
f = io.open(string.format("%s/VERSION", destdir), "w")
f:write(version)
f:close()