diff --git a/src/66/66-rebuild.c b/src/66/66-rebuild.c deleted file mode 100644 index ad4929fb6abe743f2ff2e62bd1ca1bccc964ca78..0000000000000000000000000000000000000000 --- a/src/66/66-rebuild.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * 66-rebuild.c - * - * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org> - * - * All rights reserved. - * - * This file is part of Obarun. It is subject to the license terms in - * the LICENSE file found in the top-level directory of this - * distribution. - * This file may not be copied, modified, propagated, or distributed - * except according to the terms contained in the LICENSE file./ - */ - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -#include <oblibs/log.h> -#include <oblibs/string.h> -#include <oblibs/sastr.h> -#include <oblibs/types.h> -#include <oblibs/directory.h> -#include <oblibs/files.h> - -#include <skalibs/stralloc.h> -#include <skalibs/sgetopt.h> -#include <skalibs/djbunix.h> -#include <skalibs/unix-transactional.h> -#include <skalibs/cdb.h> - -#include <66/ssexec.h> -#include <66/constants.h> -#include <66/utils.h> -#include <66/db.h> -#include <66/svc.h> -#include <66/tree.h> -#include <66/backup.h> -#include <66/resolve.h> -#include <66/parser.h> - -#define USAGE "66-rebuild [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -d ] tree(s)" - -static stralloc WORKDIR = STRALLOC_ZERO ; -static uint8_t DRYRUN = 0 ; -static char *drun = "dry run do: " ; - -static inline void info_help (void) -{ - DEFAULT_MSG = 0 ; - - static char const *help = -"\n" -"options :\n" -" -h: print this help\n" -" -z: use color\n" -" -v: increase/decrease verbosity\n" -" -l: live directory\n" -" -d: dry run\n" -"\n" -"if no tree is given, all trees will be processed.\n" -; - - log_info(USAGE,"\n",help) ; -} - -static void cleanup(void) -{ - log_flow() ; - - int e = errno ; - if (WORKDIR.len) - { - log_trace(DRYRUN ? drun : "","delete temporary directory: ",WORKDIR.s) ; - rm_rf(WORKDIR.s) ; - } - errno = e ; -} - -int tree_is_current(char const *base,char const *treename,uid_t owner) -{ - log_flow() ; - - stralloc sacurr = STRALLOC_ZERO ; - int current = 0 ; - - if (tree_find_current(&sacurr,base,owner)) - { - char name[sacurr.len + 1] ; - if (!ob_basename(name,sacurr.s)) log_dieu_nclean(LOG_EXIT_SYS,&cleanup,"basename of: ",sacurr.s) ; - current = obstr_equal(treename,name) ; - } - stralloc_free(&sacurr) ; - return current ; -} - -int tree_is_enabled(char const *treename) -{ - log_flow() ; - - return tree_cmd_state(VERBOSITY,"-s",treename) ; -} - -void tree_allowed(stralloc *list,char const *base, char const *treename) -{ - log_flow() ; - - stralloc sa = STRALLOC_ZERO ; - size_t treenamelen = strlen(treename), baselen = strlen(base), pos ; - char tmp[baselen + SS_SYSTEM_LEN + 1 + treenamelen + SS_RULES_LEN + 1] ; - - auto_strings(tmp,base,SS_SYSTEM,"/",treename,SS_RULES) ; - - if (!sastr_dir_get(&sa,tmp,"",S_IFREG)) - log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get permissions of tree at: ",tmp) ; - - for (pos = 0 ;pos < sa.len; pos += strlen(sa.s + pos) + 1) - { - char *suid = sa.s + pos ; - uid_t uid = 0 ; - if (!uid0_scan(suid, &uid)) - log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get uid of: ",suid) ; - if (pos) - if (!stralloc_cats(list,",")) log_die_nomem_nclean(&cleanup,"stralloc") ; - if (!get_namebyuid(uid,list)) - log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get name of uid: ",suid) ; - } - if (!stralloc_0(list)) log_die_nomem_nclean(&cleanup,"stralloc") ; - log_trace(DRYRUN ? drun : "","allowed user(s) for tree: ",treename," are: ",list->s) ; - stralloc_free(&sa) ; -} - -void tree_contents(stralloc *list,char const *tree,ssexec_t *info) -{ - log_flow() ; - - size_t treelen = strlen(tree), pos ; - stralloc sa = STRALLOC_ZERO ; - char solve[treelen + SS_SVDIRS_LEN + SS_RESOLVE_LEN + SS_DB_LEN + SS_SRC_LEN + 1] ; - - ss_resolve_t res = RESOLVE_ZERO ; - auto_strings(solve,tree,SS_SVDIRS,SS_RESOLVE) ; - if (!sastr_dir_get(&sa,solve,SS_MASTER + 1,S_IFREG)) - log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get the service resolve files of: ",tree) ; - - auto_strings(solve,tree,SS_SVDIRS) ; - - for (pos = 0 ;pos < sa.len; pos += strlen(sa.s + pos) + 1) - { - char *name = sa.s + pos ; - int logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ; - if (logname > 0) continue ; - - if (!ss_resolve_read(&res,solve,name)) - log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"read resolve file of: ",solve,"/",name) ; - - if (res.disen) - if (!stralloc_catb(list,res.sa.s + res.src,strlen(res.sa.s + res.src) + 1)) - log_diesys_nclean(LOG_EXIT_SYS,&cleanup,"stralloc") ; - - log_trace(DRYRUN ? drun : "","tree: ",info->treename.s," contain service: ",res.sa.s + res.src) ; - } - - stralloc_free(&sa) ; -} - -static int run_cmdline(char const *prog,char const **add,int len,char const *const *envp) -{ - log_flow() ; - - pid_t pid ; - int wstat ; - - char fmt[UINT_FMT] ; - fmt[uint_fmt(fmt, VERBOSITY)] = 0 ; - - int m = 4 + len, i = 0, n = 0 ; - char const *newargv[m] ; - newargv[n++] = prog ; - newargv[n++] = "-v" ; - newargv[n++] = fmt ; - for (;i<len;i++) - newargv[n++] = add[i] ; - newargv[n] = 0 ; - - pid = child_spawn0(newargv[0],newargv,envp) ; - if (waitpid_nointr(pid,&wstat, 0) < 0) - log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"wait for: ",newargv[0]) ; - if (wstat) return 0 ; - - return 1 ; -} - -int main(int argc, char const *const *argv,char const *const *envp) -{ - int r ; - unsigned int nclassic = 0, nlongrun = 0, nbsv = 0 ; - size_t systemlen, optslen = 5, pos, len ; - char tree_opts_create[optslen] ; - char *fdir = 0 ; - - log_color = &log_color_disable ; - - stralloc satree = STRALLOC_ZERO ; - stralloc allow = STRALLOC_ZERO ; - stralloc contents = STRALLOC_ZERO ; - stralloc tree_enabled = STRALLOC_ZERO ; - ssexec_t info = SSEXEC_ZERO ; - - PROG = "66-rebuild" ; - { - subgetopt l = SUBGETOPT_ZERO ; - - for (;;) - { - int opt = subgetopt_r(argc,argv, "hzv:l:d", &l) ; - - if (opt == -1) break ; - switch (opt) - { - case 'h' : info_help(); return 0 ; - case 'v' : if (!uint0_scan(l.arg, &VERBOSITY)) log_usage(USAGE) ; break ; - case 'l' : if (!stralloc_cats(&info.live,l.arg)) log_die_nomem("stralloc") ; - if (!stralloc_0(&info.live)) log_die_nomem("stralloc") ; - break ; - case 'z' : log_color = !isatty(1) ? &log_color_disable : &log_color_enable ; break ; - case 'd' : DRYRUN = 1 ; break ; - default : log_usage(USAGE) ; - } - } - argc -= l.ind ; argv += l.ind ; - } - - info.owner = getuid() ; - - if (!set_ownersysdir(&info.base,info.owner)) log_dieusys(LOG_EXIT_SYS, "set owner directory") ; - - char system[info.base.len + SS_SYSTEM_LEN + 2] ; - auto_strings(system,info.base.s,SS_SYSTEM,"/") ; - systemlen = info.base.len + SS_SYSTEM_LEN + 1 ; - - if (!argc) - { - if (info.owner) - { - /** check if user system dir already exist */ - if (!scan_mode(info.base.s,S_IFDIR)) { - log_info(DRYRUN ? drun : "","No trees exist yet -- Nothing to do") ; - goto exit ; - } - } - if (!sastr_dir_get(&satree,system,SS_BACKUP + 1,S_IFDIR)) - log_dieusys(LOG_EXIT_SYS,"get list of trees at: ",system) ; - - if (!satree.len) - { - log_info(DRYRUN ? drun : "","No trees exist yet -- Nothing to do") ; - goto exit ; - } - } - else - { - int i = 0 ; - size_t arglen = 0 ; - for (;i < argc ; i++) - { - arglen = strlen(argv[i]) ; - char tree[systemlen + arglen + 1] ; - auto_strings(tree,system,argv[i]) ; - r = scan_mode(tree,S_IFDIR) ; - if (r == -1) { errno = EEXIST ; log_diesys(LOG_EXIT_SYS,"conflicting format of: ",tree) ; } - if (!r) log_die(LOG_EXIT_USER,"tree: ",tree," doesn't exist") ; - if (!stralloc_catb(&satree,argv[i],strlen(argv[i]) + 1)) - log_die_nomem("stralloc") ; - } - } - /** keep start order of trees */ - if (!file_readputsa(&tree_enabled,system,"state")) - log_dieusys(LOG_EXIT_SYS,"read contents of file: ",system,"state") ; - - len = satree.len ; - for (pos = 0 ; pos < len; pos += strlen(satree.s + pos) + 1) - { - int dbok = 0 ; - - nclassic = nlongrun = nbsv = 0 ; - info.base.len = info.tree.len = info.treename.len = 0 ; - allow.len = WORKDIR.len = contents.len = 0 ; - auto_strings(tree_opts_create,"-n") ; - optslen = 2 ; - - if (!auto_stra(&info.tree,satree.s + pos)) - log_die_nomem("stralloc") ; - - set_ssinfo(&info) ; - - char tmp[systemlen + SS_BACKUP_LEN + info.treename.len + SS_SVDIRS_LEN + SS_DB_LEN + 1] ; - char current[info.livetree.len + 1 + info.treename.len + 9 + 1] ; - - log_info(DRYRUN ? drun : "","save state of tree: ", info.treename.s) ; - if (tree_is_current(info.base.s,info.treename.s,info.owner)) - { - log_trace(DRYRUN ? drun : "","tree: ",info.treename.s," is marked current") ; - auto_string_from(tree_opts_create,optslen,"c") ; - optslen +=1 ; - } - if (tree_is_enabled(info.treename.s) == 1) - { - log_trace(DRYRUN ? drun : "","tree: ",info.treename.s," is marked enabled") ; - auto_string_from(tree_opts_create,optslen,"E") ; - optslen +=1 ; - } - - tree_allowed(&allow,info.base.s,info.treename.s) ; - - log_info(DRYRUN ? drun : "","save service(s) list of tree: ", info.treename.s) ; - tree_contents(&contents,info.tree.s,&info) ; - - dbok = db_ok(info.livetree.s, info.treename.s) ; - - if (dbok) - { - fdir = 0 ; - - log_trace(DRYRUN ? drun : "","find current source of live db: ",info.livetree.s,"/",info.treename.s) ; - r = db_find_compiled_state(info.livetree.s,info.treename.s) ; - if (r == -1) log_die(LOG_EXIT_SYS,"inconsistent state of: ",info.livetree.s) ; - if (r == 1) { - auto_strings(tmp,system,SS_BACKUP + 1,"/",info.treename.s,SS_DB) ; - } - else auto_strings(tmp,system,info.treename.s,SS_SVDIRS,SS_DB) ; - - log_trace(DRYRUN ? drun : "","created temporary directory at: /tmp") ; - fdir = dir_create_tmp(&WORKDIR,"/tmp",info.treename.s) ; - if (!fdir) log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"create temporary directory") ; - - log_trace(DRYRUN ? drun : "","copy contents of: ",tmp," to: ",WORKDIR.s) ; - if (!hiercopy(tmp,fdir)) log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"copy: ",tmp," to: ",WORKDIR.s) ; - - char new[WORKDIR.len + 1 + info.treename.len + 1] ; - - auto_strings(current,info.livetree.s,"/",info.treename.s,"/compiled") ; - auto_strings(new,WORKDIR.s,"/",info.treename.s) ; - - log_info(DRYRUN ? drun : "","update ",info.livetree.s,"/",info.treename.s," to: ",new) ; - - if (!DRYRUN) - if (!atomic_symlink(new, current, PROG)) - log_dieusys(LOG_EXIT_SYS,"update: ",current," to: ", new) ; - - if (DRYRUN) cleanup() ; - } - - /** finally we can destroy the tree and recreate it*/ - // destroy - { - char const *t[] = { "-l", info.live.s, "-R", info.treename.s } ; - if (DRYRUN) - { - log_info(drun,"66-tree -l ",info.live.s," -R ",info.treename.s) ; - } - else - { - if (!run_cmdline(SS_EXTBINPREFIX "66-tree",t,4,envp)) - log_dieu(LOG_EXIT_SYS,"delete tree: ", info.treename.s) ; - } - } - //create - { - char const *t[] = { "-l", info.live.s, tree_opts_create,"-a",allow.s, info.treename.s } ; - if (DRYRUN) - { - log_info(drun,"66-tree -l ",info.live.s," ",tree_opts_create," -a ",allow.s," ",info.treename.s) ; - } - else - { - if (!run_cmdline(SS_EXTBINPREFIX "66-tree",t,6,envp)) - log_dieu(LOG_EXIT_SYS,"create tree: ", info.treename.s) ; - } - } - // reorganize the trees start order - if (tree_enabled.len) - { - if (!sastr_split_string_in_nline(&tree_enabled)) - log_dieu(LOG_EXIT_SYS,"split elements") ; - unsigned int enabled ; - ssize_t r = sastr_find_element_byname(&tree_enabled,info.treename.s,&enabled) ; - if (r >= 0) - { - char *after_tree = tree_enabled.s + sastr_find_element_byid(&tree_enabled,!enabled ? enabled : enabled - 1) ; - char const *t[] = { "-S", after_tree, info.treename.s } ; - if (DRYRUN) - { - log_info(drun,"66-tree -S ",after_tree," ",info.treename.s) ; - } - else - { - if (!run_cmdline(SS_EXTBINPREFIX "66-tree",t,3,envp)) - log_dieu(LOG_EXIT_SYS,"orders the start order of tree: ", info.treename.s) ; - } - } - } - /* we must reimplement the enable process instead of - * using directly 66-enable. The 66-enable program will use - * is own workdir with an empty tree. At call of db_update(), - * the service already running will be brought down. We don't - * want this behavior. A nope update is necessary. - * So remake the things with the enable API */ - - if (contents.len) - { - stralloc tostart = STRALLOC_ZERO ; - log_info(DRYRUN ? drun : "","enable service(s) of tree: ",info.treename.s) ; - if (!DRYRUN) - { - auto_strings(tmp,system,info.treename.s,SS_SVDIRS) ; - } - else - { - WORKDIR.len = 0 ; - log_trace(drun,"copy: ", info.tree.s,SS_SVDIRS," to a temporary directory") ; - if (!tree_copy(&WORKDIR,info.tree.s,info.treename.s)) - log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"create tmp working directory") ; - /* we need to remove the contain of .resolve directory - * The write process will try to read it and obviously it - * get a wrong information*/ - auto_strings(tmp,WORKDIR.s,SS_RESOLVE) ; - log_trace(drun,"remove directory: ", tmp) ; - if (rm_rf(tmp) < 0) log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"remove: ",tmp) ; - log_trace(drun,"create directory: ", tmp) ; - if (!dir_create_parent(tmp,0755)) - log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"create directory: ",tmp) ; - auto_string_from(tmp,0,WORKDIR.s) ; - - } - - start_parser(&contents,&info,&nbsv,1) ; - start_write(&tostart,&nclassic,&nlongrun,tmp,&gasv,&info,1,0) ; - /** we don't care about nclassic. Classic service are copies - * of original and we retrieve the original at the end of the - * process*/ - if(nlongrun) - { - ss_resolve_graph_t graph = RESOLVE_GRAPH_ZERO ; - r = ss_resolve_graph_src(&graph,tmp,0,1) ; - if (!r) - log_dieu(LOG_EXIT_SYS,"resolve source of graph for tree: ",info.treename.s) ; - - r = ss_resolve_graph_publish(&graph,0) ; - if (r <= 0) - { - if (r < 0) log_die(LOG_EXIT_USER,"cyclic graph detected") ; - log_dieusys(LOG_EXIT_SYS,"publish service graph") ; - } - - if (!ss_resolve_write_master(&info,&graph,tmp,0)) - log_dieusys(LOG_EXIT_SYS,"update inner bundle") ; - - ss_resolve_graph_free(&graph) ; - if (!db_compile(tmp,info.tree.s,info.treename.s,envp)) - log_dieu(LOG_EXIT_SYS,"compile ",tmp,"/",info.treename.s) ; - } - stralloc_free(&tostart) ; - freed_parser() ; - genalloc_free(sv_alltype,&gasv) ; - - } - - if (dbok) - { - auto_strings(tmp,system,info.treename.s,SS_SVDIRS,SS_DB) ; - log_info(DRYRUN ? drun : "","update db: ",info.livetree.s,"/",info.treename.s, " to: ",tmp,"/",info.treename.s) ; - /* Be paranoid here and use db_update instead of atomic_symlink. - * db_update() allow to make a running test and to see - * if the db match exactly the same state. - * We prefer to die in this case instead of leaving an - * inconsistent state. */ - if (!DRYRUN) - if (!db_update(tmp,&info,envp)) - log_dieu(LOG_EXIT_SYS,"update: ",info.livetree.s,"/",info.treename.s," to: ", tmp,"/",info.treename.s) ; - } - - cleanup() ; - - log_info(DRYRUN ? drun : "","tree: ",info.treename.s," rebuild successfully") ; - } - exit: - stralloc_free(&satree) ; - stralloc_free(&allow) ; - stralloc_free(&WORKDIR) ; - stralloc_free(&contents) ; - stralloc_free(&tree_enabled) ; - ssexec_free(&info) ; - return 0 ; -} - diff --git a/src/66/deps-exe/66-rebuild b/src/66/deps-exe/66-rebuild deleted file mode 100644 index f1e60dad80b6949a291fd1320dd53b5888a8da74..0000000000000000000000000000000000000000 --- a/src/66/deps-exe/66-rebuild +++ /dev/null @@ -1,5 +0,0 @@ -${LIB66} --ls6rc --ls6 --loblibs --lskarnet