From f839f62725b1e0fed8576beb38e63a4bf97d47d6 Mon Sep 17 00:00:00 2001 From: Tobias Ulmer Date: Wed, 26 Feb 2014 15:46:50 +0100 Subject: [PATCH] Move e2project config handling into project module. Signed-off-by: Tobias Ulmer --- local/Makefile | 2 +- local/e2-ls-project.lua | 5 +- local/e2build.lua | 37 +++---- local/e2tool.lua | 95 +++-------------- local/project.lua | 204 ++++++++++++++++++++++++++++++++++++ plugins/collect_project.lua | 7 +- 6 files changed, 246 insertions(+), 104 deletions(-) create mode 100644 local/project.lua diff --git a/local/Makefile b/local/Makefile index 3cfa2d4..7da1dd6 100644 --- a/local/Makefile +++ b/local/Makefile @@ -41,7 +41,7 @@ LOCALLUATOOLS = e2-build e2-dlist e2-dsort e2-fetch-sources \ e2-build-numbers e2-cf e2-help LOCALLUALIBS= digest.lua e2build.lua e2tool.lua environment.lua \ - policy.lua scm.lua licence.lua chroot.lua + policy.lua scm.lua licence.lua chroot.lua project.lua LOCALTOOLS = $(LOCALLUATOOLS) .PHONY: all install uninstall local install-local doc install-doc diff --git a/local/e2-ls-project.lua b/local/e2-ls-project.lua index 1a1c1dc..195f8dc 100644 --- a/local/e2-ls-project.lua +++ b/local/e2-ls-project.lua @@ -40,6 +40,7 @@ local licence = require("licence") local policy = require("policy") local scm = require("scm") local chroot = require("chroot") +local project = require("project") local function e2_ls_project(arg) local rc, re = e2lib.init() @@ -168,7 +169,7 @@ local function e2_ls_project(arg) if opts.dot or opts["dot-sources"] then local arrow = "->" - console.infof("digraph \"%s\" {\n", info.project.name) + console.infof("digraph \"%s\" {\n", project.name()) for _, r in pairs(results) do local res = info.results[r] local deps, re = e2tool.dlist(info, r) @@ -208,7 +209,7 @@ local function e2_ls_project(arg) --------------- project name local s1 = "|" local s2 = "|" - p0(s1, s2, info.project.name) + p0(s1, s2, project.name()) --------------- servers local s1 = "|" diff --git a/local/e2build.lua b/local/e2build.lua index aca1226..5e21f2c 100644 --- a/local/e2build.lua +++ b/local/e2build.lua @@ -42,6 +42,7 @@ local strict = require("strict") local tools = require("tools") local transport = require("transport") local chroot = require("chroot") +local project = require("project") -- Table driving the build process, see documentation at the bottom. local build_process = {} @@ -53,7 +54,7 @@ local function linklast(info, r, return_flags) local e = err.new("creating link to last results") -- calculate the path to the result local server, location = res.build_mode.storage(info.project_location, - info.project.release_id) + project.release_id()) local buildid, re = e2tool.buildid(info, r) if not buildid then @@ -127,7 +128,7 @@ local function result_available(info, r, return_flags) return true, nil end local server, location = - res.build_mode.storage(info.project_location, info.project.release_id) + res.build_mode.storage(info.project_location, project.release_id()) local dep_set = res.build_mode.dep_set(buildid) -- cache the result @@ -215,20 +216,14 @@ function e2build.build_config(info, r) buildconfig.PATCHLEVEL, e2lib.globals.osenv["USER"]) local builddir = "tmp/e2" - bc.base = e2lib.join(tmpdir, info.project.name, r) + bc.base = e2lib.join(tmpdir, project.name(), r) bc.c = e2lib.join(bc.base, "chroot") bc.chroot_marker = e2lib.join(bc.base, "e2factory-chroot") bc.chroot_lock = e2lib.join(bc.base, "e2factory-chroot-lock") - bc.T = e2lib.join(tmpdir, info.project.name, r, "chroot", builddir) + bc.T = e2lib.join(tmpdir, project.name(), r, "chroot", builddir) bc.Tc = e2lib.join("/", builddir) bc.r = r - if info.chroot_call_prefix[info.project.chroot_arch] == "" then - -- escape only if non-empty, otherwise we fail to start "''" - tab.chroot_call_prefix = "" - else - tab.chroot_call_prefix = - e2lib.shquote(info.chroot_call_prefix[info.project.chroot_arch]) - end + bc.chroot_call_prefix = info.chroot_call_prefix[project.chroot_arch()] bc.buildlog = string.format("%s/log/build.%s.log", info.root, r) bc.scriptdir = "script" bc.build_driver = "" @@ -239,8 +234,8 @@ function e2build.build_config(info, r) bc.builtin_env = environment.new() bc.builtin_env:set("E2_TMPDIR", bc.Tc) bc.builtin_env:set("E2_RESULT", r) - bc.builtin_env:set("E2_RELEASE_ID", info.project.release_id) - bc.builtin_env:set("E2_PROJECT_NAME", info.project.name) + bc.builtin_env:set("E2_RELEASE_ID", project.release_id()) + bc.builtin_env:set("E2_PROJECT_NAME", project.name()) bc.builtin_env:set("E2_BUILDID", buildid) bc.builtin_env:set("T", bc.Tc) bc.builtin_env:set("r", r) @@ -368,12 +363,15 @@ function e2build.enter_playground(info, r, chroot_command) end cmd = { - res.build_config.chroot_call_prefix, e2_su, "chroot_2_3", res.build_config.base, } + if #res.build_config.chroot_call_prefix > 0 then + table.insert(cmd, 1, res.build_config.chroot_call_prefix) + end + if chroot_command then table.insert(cmd, "/bin/sh") table.insert(cmd, "-c") @@ -461,7 +459,6 @@ local function runbuild(info, r, return_flags) e2tool.set_umask(info) local cmd = { - res.build_config.chroot_call_prefix, e2_su, "chroot_2_3", res.build_config.base, @@ -471,6 +468,10 @@ local function runbuild(info, r, return_flags) res.build_config.build_driver_file) } + if #res.build_config.chroot_call_prefix > 0 then + table.insert(cmd, 1, res.build_config.chroot_call_prefix) + end + rc, re = e2lib.callcmd_capture(cmd, logto) if not rc then eio.fclose(out) @@ -560,7 +561,7 @@ function e2build.unpack_result(info, r, dep, destdir) local dep_set = d.build_mode.dep_set(buildid) local server, location = - d.build_mode.storage(info.project_location, info.project.release_id) + d.build_mode.storage(info.project_location, project.release_id()) e2lib.logf(3, "searching for dependency %s in %s:%s", dep, server, location) local location1 = e2lib.join(location, dep, dep_set, "result.tar") local cache_flags = {} @@ -915,7 +916,7 @@ local function deploy(info, r, tmpdir) end table.insert(files, "checksums") local server, location = res.build_mode.deploy_storage( - info.project_location, info.project.release_id) + info.project_location, project.release_id()) -- do not re-deploy if this release was already done earlier local location1 = e2lib.join(location, r, "checksums") @@ -1035,7 +1036,7 @@ local function store_result(info, r, return_flags) return false, e:cat(re) end local server, location = res.build_mode.storage(info.project_location, - info.project.release_id) + project.release_id()) local buildid, re = e2tool.buildid(info, r) if not buildid then diff --git a/local/e2tool.lua b/local/e2tool.lua index 70dd804..2726763 100644 --- a/local/e2tool.lua +++ b/local/e2tool.lua @@ -50,6 +50,7 @@ local tools = require("tools") local transport = require("transport") local url = require("url") local chroot = require("chroot") +local project = require("project") -- Build function table, see end of file for details. local e2tool_ftab = {} @@ -377,7 +378,7 @@ local function check_result(info, resultname) end end end - for _,r in ipairs(info.project.deploy_results) do + for r in project.deploy_results_iter() do if r == resultname then res._deploy = true break @@ -932,76 +933,6 @@ local function load_result_configs(info) return true end ---- Read project configuration file. --- @return True on success, false on error. --- @return Error object on failure. -local function read_project_config(info) - - --- Project configuration table (e2project). - -- @table info.project - -- @field release_id Release identifier, usually a git tag (string). - -- @field name Name of project (string). - -- @field deploy_results List of results that should be archived on - -- --release builds (table containing strings). - -- @field default_results List of results that are built by default - -- (table containing strings). - -- @field chroot_arch Chroot architecture (string). - - local rc, re, e - - rc, re = load_user_config(info, e2lib.join(info.root, "proj/config"), - info, "project", "e2project") - if not rc then - return false, re - end - - e = err.new("in project configuration:") - if not info.project.release_id then - e:append("key is not set: release_id") - end - if not info.project.name then - e:append("key is not set: name") - end - if not info.project.default_results then - e2lib.warnf("WDEFAULT", "in project configuration:") - e2lib.warnf("WDEFAULT", - "default_results is not set. Defaulting to empty list.") - info.project.default_results = {} - end - rc, re = e2lib.vrfy_listofstrings(info.project.deploy_results, - "deploy_results", true, true) - if not rc then - e:append("deploy_results is not a valid list of strings") - e:cat(re) - end - rc, re = e2lib.vrfy_listofstrings(info.project.default_results, - "default_results", true, false) - if not rc then - e:append("default_results is not a valid list of strings") - e:cat(re) - end - if not info.project.chroot_arch then - e2lib.warnf("WDEFAULT", "in project configuration:") - e2lib.warnf("WDEFAULT", " chroot_arch defaults to x86_32") - info.project.chroot_arch = "x86_32" - end - if not info.chroot_call_prefix[info.project.chroot_arch] then - e:append("chroot_arch is set to an invalid value") - end - local host_system_arch, re = e2lib.get_sys_arch() - if not host_system_arch then - e:cat(re) - elseif info.project.chroot_arch == "x86_64" and - host_system_arch ~= "x86_64" then - e:append("running on x86_32: switching to x86_64 mode is impossible.") - end - if e:getcount() > 1 then - return false, e - end - - return true -end - --- check source. local function check_source(info, sourcename) local src = info.sources[sourcename] @@ -1054,12 +985,12 @@ local function check_project_info(info) if not rc then return false, e:cat(re) end - for _, r in ipairs(info.project.default_results) do + for r in project.default_results_iter() do if not info.results[r] then e:append("default_results: No such result: %s", r) end end - for _, r in ipairs(info.project.deploy_results) do + for r in project.deploy_results_iter() do if not info.results[r] then e:append("deploy_results: No such result: %s", r) end @@ -1192,7 +1123,7 @@ function e2tool.collect_project_info(info, skip_load_config) end -- read project configuration - rc, re = read_project_config(info) + rc, re = project.load_project_config(info) if not rc then return false, e:cat(re) end @@ -1303,7 +1234,7 @@ function e2tool.collect_project_info(info, skip_load_config) local dirty, mismatch rc, re, mismatch = generic_git.verify_head_match_tag(info.root, - info.project.release_id) + project.release_id()) if not rc then if mismatch then e:append("project repository tag does not match " .. @@ -1326,7 +1257,7 @@ function e2tool.collect_project_info(info, skip_load_config) if e2option.opts["check-remote"] then rc, re = generic_git.verify_remote_tag( - e2lib.join(info.root, ".git"), info.project.release_id) + e2lib.join(info.root, ".git"), project.release_id()) if not rc then e:append("verifying remote tag failed") return false, e:cat(re) @@ -1435,7 +1366,11 @@ end -- @return Error object on failure. -- @see e2tool.dlist_recursive function e2tool.dsort(info) - return e2tool.dlist_recursive(info, info.project.default_results) + local dr = {} + for r in project.default_results_iter() do + table.insert(dr, r) + end + return e2tool.dlist_recursive(info, dr) end --- verify that a file addressed by server name and location matches the @@ -1505,11 +1440,11 @@ local function projid(info) if not rc then return false, re end end end - rc, re = hash.hash_line(hc, info.project.release_id) + rc, re = hash.hash_line(hc, project.release_id()) if not rc then return false, re end - rc, re = hash.hash_line(hc, info.project.name) + rc, re = hash.hash_line(hc, project.name()) if not rc then return false, re end - rc, re = hash.hash_line(hc, info.project.chroot_arch) + rc, re = hash.hash_line(hc, project.chroot_arch()) if not rc then return false, re end rc, re = hash.hash_line(hc, buildconfig.VERSION) if not rc then return false, re end diff --git a/local/project.lua b/local/project.lua new file mode 100644 index 0000000..79f58c7 --- /dev/null +++ b/local/project.lua @@ -0,0 +1,204 @@ +--- Project module. Handle e2project configuration. +-- @module local.project + +-- Copyright (C) 2007-2014 emlix GmbH, see file AUTHORS +-- +-- This file is part of e2factory, the emlix embedded build system. +-- For more information see http://www.e2factory.org +-- +-- e2factory is a registered trademark of emlix GmbH. +-- +-- e2factory is free software: you can redistribute it and/or modify it under +-- the terms of the GNU General Public License as published by the +-- Free Software Foundation, either version 3 of the License, or (at your +-- option) any later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +-- more details. + +local project = {} +local e2lib = require("e2lib") +local e2tool = require("e2tool") +local err = require("err") +local strict = require("strict") + +local _prj = {} +local _config_loaders = {} + +--- Check and load e2project callback function signature. +-- @function load_project_config_cb +-- @param prj Unchecked e2project table. Remove all keys that are private +-- to your use. +-- @return True on success, false on error +-- @return Error object on failure. + +--- Register a function that gets called when the project config is +-- loaded. Functions get called in order of registration. +-- @param func load_project_config_cb function. +-- @return True on success, false on error. +-- @return Error object on failure. +-- @see load_project_config_cb +function project.register_load_project_config(func) + assert(type(func) == "function") + table.insert(_config_loaders, func) + + return true +end + +--- Main e2project config check and init callback. +-- @param prj e2project table. +-- @return True on success, false on error. +-- @return Error object on failure. +local function load_prj_cfg(prj) + local rc, re, e, info + + info = e2tool.info() + assert(info) + + rc, re = e2lib.vrfy_dict_exp_keys(prj, "e2project", + { "name", "release_id", "deploy_results", + "default_results", "chroot_arch" }) + if not rc then + return false, re + end + + if not prj.release_id then + return false, err.new("key is not set: release_id") + end + if not prj.name then + return false, err.new("key is not set: name") + end + if not prj.default_results then + e2lib.warnf("WDEFAULT", "in project configuration:") + e2lib.warnf("WDEFAULT", + "default_results is not set. Defaulting to empty list.") + prj.default_results = {} + end + rc, re = e2lib.vrfy_listofstrings(prj.deploy_results, + "deploy_results", true, true) + if not rc then + e = err.new("deploy_results is not a valid list of strings") + e:cat(re) + return false, e + end + + rc, re = e2lib.vrfy_listofstrings(prj.default_results, + "default_results", true, false) + if not rc then + e = err.new("default_results is not a valid list of strings") + e:cat(re) + return false, e + end + + if not prj.chroot_arch then + e2lib.warnf("WDEFAULT", "in project configuration:") + e2lib.warnf("WDEFAULT", " chroot_arch defaults to x86_32") + prj.chroot_arch = "x86_32" + end + if not info.chroot_call_prefix[prj.chroot_arch] then + return false, err.new("chroot_arch is set to an invalid value") + end + if prj.chroot_arch == "x86_64" and e2lib.host_system_arch ~= "x86_64" then + return false, + err.new("running on x86_32: switching to x86_64 mode is impossible.") + end + + _prj = prj + return true +end + +--- Initialise the project module, load and check proj/config. Needs to be +-- called before using name() etc. +-- @param info Info table. +-- @return True on success, false on error. +-- @return Error object on failure. +function project.load_project_config(info) + local rc, re, e + local path, prj + + -- register the main e2project load_project_config function last + rc, re = project.register_load_project_config(load_prj_cfg) + if not rc then + return false, re + end + + path = e2lib.join(info.root, "proj/config") + + prj = nil + local g = { + e2project = function(data) prj = data end, + env = info.env, + string = e2lib.safe_string_table(), + } + + rc, re = e2lib.dofile2(path, g) + if not rc then + return false, re + end + + e = err.new("in project configuration:") + + if type(prj) ~= "table" then + return false, e:append("Invalid or empty e2project configuration") + end + + for _,load_project_config_cb in ipairs(_config_loaders) do + rc, re = load_project_config_cb(prj) + if not rc then + return false, e:cat(re) + end + end + + return true +end + +--- Get project name. +-- @return Name. +function project.name() + assert(type(_prj.name) == "string") + return _prj.name +end + +--- Get project ReleaseID. +-- @return ReleaseID as a string. +function project.release_id() + assert(type(_prj.release_id) == "string") + return _prj.release_id +end + +--- Get chroot architecture. For multi-arch systems. +-- @return Chroot architecture as a string. +function project.chroot_arch() + assert(type(_prj.chroot_arch) == "string") + return _prj.chroot_arch +end + +--- Iterator that returns the deploy results as string. +-- @return Iterator function. +function project.deploy_results_iter() + assert(type(_prj.deploy_results) == "table") + local i = 0 + + return function () + i = i + 1 + return _prj.deploy_results[i] + end +end + +--- Iterator that returns the default results as string. +-- @return Iterator function. +function project.default_results_iter() + assert(type(_prj.default_results) == "table") + local i = 0 + + return function () + i = i + 1 + return _prj.default_results[i] + end +end + +return strict.lock(project) + +-- vim:sw=4:sts=4:et: diff --git a/plugins/collect_project.lua b/plugins/collect_project.lua index fdc8053..2f99200 100644 --- a/plugins/collect_project.lua +++ b/plugins/collect_project.lua @@ -31,6 +31,7 @@ local scm = require("scm") local strict = require("strict") local licence = require("licence") local chroot = require("chroot") +local project = require("project") --- Collect_project result config. This result config table lives in -- info.results[resultname]. The fields are merged with e2tool.result @@ -257,11 +258,11 @@ local function build_collect_project(info, resultname, return_flags) -- write project configuration out = { - string.format("name='%s'\n", info.project.name), - string.format("release_id='%s'\n", info.project.release_id), + string.format("name='%s'\n", project.name()), + string.format("release_id='%s'\n", project.release_id()), string.format("default_results='%s'\n", res.collect_project_default_result), - string.format("chroot_arch='%s'\n", info.project.chroot_arch) + string.format("chroot_arch='%s'\n", project.chroot_arch()) } local file, destdir -- 2.39.5