|
|
71d7061 |
-- This is intended to be run as an RPM scriptlet.
|
|
|
71d7061 |
-- Keep this file in sync with the convert-to-edition
|
|
|
71d7061 |
-- shell script
|
|
|
71d7061 |
|
|
|
71d7061 |
local VARIANT_FILE = "/usr/lib/variant"
|
|
|
71d7061 |
|
|
|
71d7061 |
-- Read in /usr/lib/variant and determine the edition
|
|
|
71d7061 |
local function read_variant()
|
|
|
71d7061 |
local variant
|
|
|
60501f2 |
local f = io.open(VARIANT_FILE, "r")
|
|
|
71d7061 |
if f ~= nil then
|
|
|
71d7061 |
while true do
|
|
|
71d7061 |
local line = f:read()
|
|
|
71d7061 |
if line == nil then
|
|
|
71d7061 |
break
|
|
|
71d7061 |
end
|
|
|
71d7061 |
local m = line:match("^VARIANT_ID=([^\n]+)")
|
|
|
71d7061 |
if m ~= nil then
|
|
|
71d7061 |
variant = m
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
60501f2 |
f:close()
|
|
|
71d7061 |
end
|
|
|
71d7061 |
return variant
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
-- Atomically replace a file with new contents
|
|
|
71d7061 |
local function writefile(path, data)
|
|
|
71d7061 |
local tmp = path .. ".convert-to-edition"
|
|
|
71d7061 |
local f = io.open(tmp, "w+")
|
|
|
71d7061 |
if f == nil then
|
|
|
71d7061 |
return
|
|
|
71d7061 |
end
|
|
|
71d7061 |
f:write(data)
|
|
|
71d7061 |
f:close()
|
|
|
71d7061 |
if not os.rename(tmp, path) then
|
|
|
71d7061 |
os.remove(tmp)
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
-- Forcibly replace a symlink
|
|
|
71d7061 |
local function symlink(from, to)
|
|
|
71d7061 |
os.remove(to)
|
|
|
71d7061 |
assert(posix.symlink(from, to))
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
-- Run a subroutine in a child process
|
|
|
71d7061 |
local function execute(...)
|
|
|
71d7061 |
local pid = posix.fork()
|
|
|
71d7061 |
if pid == 0 then
|
|
|
71d7061 |
posix.exec(...)
|
|
|
71d7061 |
posix.exit(1)
|
|
|
71d7061 |
elseif pid ~= -1 then
|
|
|
71d7061 |
local status = posix.wait(pid)
|
|
|
71d7061 |
if status ~= 0 then
|
|
|
71d7061 |
local program = ...
|
|
|
71d7061 |
error(program .. " exited with status " .. status)
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
-- Remove preset files for other editions
|
|
|
71d7061 |
-- This should never be necessary, but it's best to be safe
|
|
|
71d7061 |
local function clear_presets()
|
|
|
71d7061 |
local path = "/usr/lib/systemd/system-preset"
|
|
|
71d7061 |
for file in posix.files(path) do
|
|
|
58e4ecf |
if file:match("^80%-.*%.preset$") then
|
|
|
71d7061 |
os.remove(path .. "/" .. file)
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
|
|
|
71d7061 |
-- Get a list of presets that need to be enabled or disabled
|
|
|
71d7061 |
-- as part of the installation of this edition
|
|
|
71d7061 |
local function read_presets(path)
|
|
|
71d7061 |
local result = {}
|
|
|
71d7061 |
local f = assert(io.open(path))
|
|
|
71d7061 |
if f ~= nil then
|
|
|
71d7061 |
while true do
|
|
|
71d7061 |
local line = f:read()
|
|
|
71d7061 |
if line == nil then
|
|
|
71d7061 |
break
|
|
|
71d7061 |
end
|
|
|
71d7061 |
local cmd, arg = line:match("^([^ \t]+)[ \t]+([^\n \t]+)")
|
|
|
71d7061 |
if cmd == "enable" or cmd == "disable" then
|
|
|
71d7061 |
result[#result + 1] = arg
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
60501f2 |
f:close()
|
|
|
71d7061 |
end
|
|
|
71d7061 |
return result
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
local function set_variant(variant)
|
|
|
71d7061 |
writefile(VARIANT_FILE, "VARIANT_ID=" .. variant .. "\n")
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
local function set_release(release)
|
|
|
71d7061 |
symlink("./os.release.d/os-release-" .. release, "/usr/lib/os-release")
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
local function set_issue(release)
|
|
|
71d7061 |
symlink("./os.release.d/issue-" .. release, "/usr/lib/issue")
|
|
|
71d7061 |
end
|
|
|
71d7061 |
-- release: the VARIANT_ID for os-release
|
|
|
71d7061 |
-- issue: which /etc/issue file to install
|
|
|
71d7061 |
-- presets: whether this edition has extra presets beyond the
|
|
|
71d7061 |
-- defaults to enable or disable
|
|
|
71d7061 |
local variants = {
|
|
|
71d7061 |
atomichost = {release = "atomichost", issue = "fedora", presets = false},
|
|
|
71d7061 |
cloud = {release = "cloud", issue = "fedora", presets = false},
|
|
|
71d7061 |
nonproduct = {release = "fedora", issue = "fedora", presets = false},
|
|
|
71d7061 |
server = {release = "server", issue = "server", presets = true},
|
|
|
71d7061 |
workstation = {release = "workstation", issue = "fedora", presets = true},
|
|
|
71d7061 |
}
|
|
|
71d7061 |
|
|
|
71d7061 |
-- Call out to systemctl to enable or disable presets
|
|
|
60501f2 |
local function set_presets(edition, apply_presets)
|
|
|
71d7061 |
if variants[edition].presets then
|
|
|
71d7061 |
local target = "/usr/lib/systemd/system-preset/80-" .. edition .. ".preset"
|
|
|
60501f2 |
symlink("../../os.release.d/presets/80-" .. edition .. ".preset", target)
|
|
|
60501f2 |
|
|
|
60501f2 |
if apply_presets then
|
|
|
60501f2 |
local presets = read_presets(target)
|
|
|
60501f2 |
local systemctl = "/usr/bin/systemctl"
|
|
|
60501f2 |
if posix.access(systemctl, "x") then
|
|
|
18e38ac |
--fork off a systemctl call
|
|
|
18e38ac |
local pid = assert(posix.fork())
|
|
|
18e38ac |
if pid == 0 then
|
|
|
18e38ac |
-- Child
|
|
|
18e38ac |
posix.exec(systemctl, "preset", "-q", table.unpack(presets))
|
|
|
18e38ac |
-- In case exec() fails
|
|
|
18e38ac |
os.exit(17)
|
|
|
18e38ac |
else
|
|
|
18e38ac |
-- RPM
|
|
|
18e38ac |
assert(posix.wait(pid))
|
|
|
18e38ac |
end
|
|
|
60501f2 |
end
|
|
|
60501f2 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
60501f2 |
local function convert_to_edition(edition, apply_presets)
|
|
|
71d7061 |
local variant = variants[edition]
|
|
|
71d7061 |
if variant == nil then
|
|
|
71d7061 |
error("undefined edition: " .. edition)
|
|
|
71d7061 |
end
|
|
|
71d7061 |
set_release(variant.release)
|
|
|
71d7061 |
set_issue(variant.issue)
|
|
|
71d7061 |
clear_presets()
|
|
|
71d7061 |
|
|
|
60501f2 |
set_presets(edition, apply_presets)
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
local function install_edition(edition)
|
|
|
71d7061 |
-- Create the variant file if it does not already exist. This needs
|
|
|
71d7061 |
-- to be done on both installation and upgrade, to ensure that we
|
|
|
71d7061 |
-- upgrade from F23 and earlier properly.
|
|
|
71d7061 |
if not posix.access(VARIANT_FILE, "f") then
|
|
|
71d7061 |
set_variant(edition)
|
|
|
71d7061 |
end
|
|
|
71d7061 |
if read_variant() == edition then
|
|
|
71d7061 |
-- (On initial installation only), fix up after %%systemd_post
|
|
|
71d7061 |
-- in packages possibly installed before our preset file was
|
|
|
71d7061 |
-- added
|
|
|
71d7061 |
-- On upgrades, do not enable or disable presets to avoid
|
|
|
71d7061 |
-- surprising the user
|
|
|
60501f2 |
local initial_install = arg[2] == 1
|
|
|
71d7061 |
convert_to_edition(edition, initial_install)
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
|
|
|
71d7061 |
local function uninstall_edition(edition)
|
|
|
71d7061 |
-- If we are uninstalling, we need to reset the variant file and
|
|
|
71d7061 |
-- force the os-release file back to os-release-fedora. We do this
|
|
|
71d7061 |
-- in %%preun so that we don't have any time where the os-release
|
|
|
71d7061 |
-- symlink is dangling (since in %%postun, the os-release-$EDITION
|
|
|
71d7061 |
-- file will have already been removed)
|
|
|
60501f2 |
if arg[2] == 0 then
|
|
|
71d7061 |
if read_variant() == edition then
|
|
|
60501f2 |
set_variant("nonproduct")
|
|
|
71d7061 |
convert_to_edition("nonproduct", false)
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|
|
|
71d7061 |
end
|