X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fvunify.cc;fp=src%2Fvunify.cc;h=0000000000000000000000000000000000000000;hb=780710c3d80b8776944dd1fc65a0fda64f399db0;hp=2b0cac98f83e3207570526cbf648109b3eb50f73;hpb=8cf13bb177d92c93eb73dc8939777150536c2d00;p=util-vserver.git diff --git a/src/vunify.cc b/src/vunify.cc deleted file mode 100644 index 2b0cac9..0000000 --- a/src/vunify.cc +++ /dev/null @@ -1,388 +0,0 @@ -// $Id: vunify.cc,v 1.1.4.1 2003/10/30 15:16:30 ensc Exp $ - -// Copyright (C) 2003 Enrico Scholz -// based on vunify.cc by Jacques Gelinas -// -// This program 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 2, 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. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - -/* - This utility is used to unify (using hard links) two or more - virtual servers. - It compares the each vserver with the first one and for every - common package (RPM, same version), it does a hard link on non - configuration file. It turns the file immutable after that. -*/ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "vutil.h" - -using namespace std; - -static bool undo = false; - -static int ext2flags = EXT2_IMMUTABLE_FILE_FL | EXT2_IMMUTABLE_LINK_FL; -struct EXCLDIR{ - string prefix; - int len; - EXCLDIR(const char *s) - { - prefix = s; - prefix += '/'; - len = prefix.size(); - } -}; -static vector excldirs; -static vector incldirs; - - -static void usage() -{ - cerr << - "vunify version " << VERSION << - "\n\n" - "vunify [ options ] reference-server vservers ... -- packages\n" - "vunify [ options ] reference-server vservers ... -- ALL\n" - "\n" - "--test: Show what will be done, do not do it.\n" - "--undo: Put back the file in place, using copies from the\n" - " reference server.\n" - "--debug: Prints some debugging messages.\n" - "--noflags: Do not put any immutable flags on the file\n" - "--immutable: Set the immutable_file bit on the files.\n" - "--immutable-mayunlink: Sets the immutable_link flag on files.\n" - "\n" - "--excldir: None of the files under a given directory will be unified\n" - "\tThe directory is expressed in absolute/logical form (relative\n" - "\tto the vserver root (ex: /var/log)\n" - "\n" - "--incldir: All the files under a given directory will be unified\n" - "\tThe directory is expressed in absolute/logical form (relative\n" - "\tto the vserver root (ex: /var/log)\n" - "\n" - "By default, the immutable_file and immutable_link flags are\n" - "set on the files. So if you want no immutable flags, you must\n" - "use --noflags. If you want a single flag, you must use\n" - "--noflags first, then the --immutable or --immutable-mayunlink\n" - "flag.\n" - ; -} - -static bool vunify_inside (vector &dirs, const char *path) -{ - bool found = false; - for (unsigned i=0; i files; // Files to unify - // This is loaded on demand - PACKAGE_UNI(string &_name, string &_version) - : PACKAGE(_name,_version) - { - } - PACKAGE_UNI(const char *_name, const char *_version) - : PACKAGE (_name,_version) - { - } - PACKAGE_UNI(const string &line) - : PACKAGE (line) - { - } - // Load the file member of the package, but exclude configuration file - void loadfiles(const string &ref) - { - if (files.empty()){ - if (debug) cout << "Loading files for package " << name << endl; - string namever; - namever = name + '-' + version; - FILE *fin = vutil_execdistcmd (K_UNIFILES,ref,namever.c_str()); - if (fin != NULL){ - char tmp[1000]; - while (fgets(tmp,sizeof(tmp)-1,fin)!=NULL){ - int last = strlen(tmp)-1; - if (last >= 0 && tmp[last] == '\n') tmp[last] = '\0'; - bool must_unify = false; - int type = 0; // K_UNIFILES only report unify-able files - if(type == 0 && !vunify_inside(excldirs,tmp)){ - must_unify = true; - }else if(vunify_inside(incldirs,tmp)){ - must_unify = true; - } - if (must_unify){ - files.push_front (tmp); - }else if (debug){ - cout << "Package " << name << " exclude " << tmp << endl; - } - } - } - if (debug) cout << "Done\n"; - } - } -}; - - -static ostream & operator << (ostream &c, const PACKAGE_UNI &p) -{ - return c << p.name << "-" << p.version; -} - -template - void printit(T a){ - cout << "xx " << a << endl; - } - -template - class printer{ - string title; - public: - printer (const char *_title): title(_title){} - void operator()(T a){ - cout << title << " " << a << endl; - } - }; - - -/* - Load the list of all packages in a vserver -*/ -static void vunify_loadallpkg (string &refserver, list &packages) -{ - FILE *fin = vutil_execdistcmd (K_PKGVERSION,refserver,NULL); - if (fin != NULL){ - char line[1000]; - while (fgets(line,sizeof(line)-1,fin)!=NULL){ - // fprintf (stderr,"line: %s",line); - int last = strlen(line)-1; - if (last >= 0 && line[last] == '\n') line[last] = '\0'; - packages.push_back (PACKAGE_UNI(line)); - } - pclose (fin); - } -} - -/* - Object to unify a file - The file is first removed, then a hard link is made and then - the immutable flag is done -*/ -class file_unifier{ - string &ref_server,&target_server; - int &ret; - public: - file_unifier(string &_ref, string &_target, int &_ret) - : ref_server(_ref),target_server(_target), ret(_ret) - {} - void operator()(const string &file) - { - string refpath = VROOTDIR "/" + ref_server + file; - string dstpath = VROOTDIR "/" + target_server + file; - if (debug) cout << "Unify " << refpath << " -> " << dstpath << endl; - struct stat st; - if (stat(refpath.c_str(),&st)==-1){ - if (debug) cout << "File " << refpath << " does not exist, ignored\n"; - }else if (setext2flag(refpath.c_str(),false,ext2flags)==-1){ - ret = -1; - }else if (vbuild_unlink(dstpath.c_str())==-1){ - ret = -1; - cerr << "Can't delete file " << dstpath - << " (" << strerror(errno) << ")\n"; - }else{ - if (undo){ - if (vbuild_file_copy(refpath.c_str(),dstpath.c_str(),st)==-1){ - ret = -1; - cerr << "Can't copy file " << refpath << " to " << dstpath - << " (" << strerror(errno) << ")\n"; - } - }else{ - if (vbuild_link(refpath.c_str(),dstpath.c_str())==-1){ - ret = -1; - cerr << "Can't link file " << refpath << " to " << dstpath - << " (" << strerror(errno) << ")\n"; - } - } - // We put back the original immutable because other vservers - // may be unified on it. - if (setext2flag(refpath.c_str(),true,ext2flags)==-1){ - ret = -1; - } - } - } -}; -#if 0 -// Check if two package have the same name (but potentially different version) -class same_name{ - PACKAGE_UNI &pkg; -public: - same_name(PACKAGE_UNI &_pkg) : pkg(_pkg) {} - bool operator()(const PACKAGE_UNI &p) - { - return pkg.name == p.name; - } -}; -#endif -// Predicate to decide if a package must be unified -class package_unifier{ -public: - string &ref_server,&target_server; - list &target_packages; - int &ret; - package_unifier(string &_ref, - string &_target, - list &_target_packages, - int &_ret) - : ref_server(_ref),target_server(_target) - , target_packages(_target_packages) , ret(_ret) - {} - void operator()(PACKAGE_UNI &pkg) - { - if (find(target_packages.begin(),target_packages.end(),pkg) - !=target_packages.end()){ - // Ok, the package is also in the target vserver - cout << "Unify pkg " << pkg << " from " << ref_server << " to " - << target_server << endl; - - if (!testmode || debug){ - pkg.loadfiles(ref_server); - for_each (pkg.files.begin(),pkg.files.end() - ,file_unifier(ref_server,target_server,ret)); - } - }else if (testmode){ - // The package is missing, in test mode we provide more information - if (find_if(target_packages.begin(),target_packages.end(),same_name(pkg)) - !=target_packages.end()){ - cout << pkg << " exist in server " << target_server << " not unified\n"; - }else{ - cout << pkg << " does not exist in server " << target_server << endl; - } - } - } -}; - -// For each vserver, find the common packages and unify them -class server_unifier{ -public: - list &ref_packages; - string &ref_server; - int &ret; - server_unifier(string _ref_server, list &_packages, int &_ret) - : ref_packages(_packages),ref_server(_ref_server), ret(_ret) - {} - void operator()(string serv) - { - list pkgs; - vunify_loadallpkg (serv,pkgs); - for_each(ref_packages.begin(),ref_packages.end() - ,package_unifier(ref_server,serv,pkgs,ret)); - } -}; -class deleteif{ -public: - char **argv0,**argvn; - deleteif(char **_argv0, char **_argvn): argv0(_argv0),argvn(_argvn){} - bool operator()(const PACKAGE_UNI &pkg) - { - bool found = false; - for (char **pt = argv0; pt < argvn; pt++){ - if (pkg.name == *pt){ - found = true; - break; - } - } - return !found; - } -}; - -int main (int argc, char *argv[]) -{ - int ret = -1; - int i; - for (i=1; i vservers; - for (; i("vservers")); - if (i == argc || strcmp(argv[i],"--")!=0){ - usage(); - }else{ - i++; - if (i < argc){ - list packages; - vunify_loadallpkg (refserv,packages); - if (i != argc-1 || strcmp(argv[i],"ALL")!=0){ - // We keep only the packages supplied on the command line - packages.remove_if(deleteif (argv+i,argv+argc)); - } - ret = 0; - umask (0); - for_each (vservers.begin(),vservers.end(),server_unifier(refserv,packages,ret)); - }else{ - usage(); - } - } - } - return ret; -} - - - -