def backup(self): ''' peform the backup operation, recording installed packages and copying new/modified files ''' if config.options.log_level_at_least('normal'): callback.snapcallback.message("Creating snapshot") self.check_permission() # temp directory used to construct tarball construct_dir = tempfile.mkdtemp() FileManager.make_dir(construct_dir) backends = self.load_backends() configured_targets = backends.keys() for target in SnapshotTarget.BACKENDS: # load from SnapshotTarget to preserve order if target in configured_targets: backend = backends[target] includes = config.options.target_includes[target] excludes = config.options.target_excludes[target] backend.backup(construct_dir, include=includes, exclude=excludes) SnapFile(snapfile=config.options.snapfile, snapdirectory=construct_dir, encryption_password=config.options.encryption_password).compress() if config.options.log_level_at_least('normal'): callback.snapcallback.message("Snapshot completed") FileManager.rm_dir(construct_dir)
def testBackupRepos(self): snapshot_target = snap.backends.repos.syum.Syum() snapshot_target.backup(self.fs_root) self.assertTrue(os.path.exists(self.fs_root + "/etc/yum.conf")) for repo in os.listdir("/etc/yum.repos.d"): self.assertTrue(os.path.exists(self.fs_root + "/etc/yum.repos.d/" + repo)) repos = [] self.assertTrue(os.path.exists(self.fs_root + "/repos.xml")) record = ReposRecordFile(self.fs_root + "/repos.xml") record_repos = record.read() for repo in record_repos: repos.append(repo.url) # verify repos contents urls = [] for yum_repo in FileManager.get_all_files(include=['/etc/yum.repos.d']): baseurl = re.compile('baseurl=(.*)\n') mirrorlist = re.compile('mirrorlist=(.*)\n') contents = FileManager.read_file(yum_repo) for match in baseurl.findall(contents): urls.append(match) for match in mirrorlist.findall(contents): urls.append(match) for url in urls: self.assertIn(url, repos)
def extract(self): '''extract the snapfile into the snapdirectory @raises - MissingFileError if the snapfile does not exist ''' # decrypt the file if we've set a key if not snap.osregistry.OS.is_windows() and self.encryption_key != None: if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message("Decyrpting snapfile") Crypto.decrypt_file(self.encryption_key, self.snapfile, self.snapfile + ".dec") FileManager.mv(self.snapfile + ".dec", self.snapfile) # open the tarball tarball = tarfile.open(self.snapfile) # temp store the working directory, before changing to the snapdirectory cwd = os.getcwd() os.chdir(self.snapdirectory) # extract files from it for tarinfo in tarball: tarball.extract(tarinfo) # close it out tarball.close() if snap.config.options.log_level_at_least('normal'): snap.callback.snapcallback.message("Snapfile " + self.snapfile + " opened") # restore the working directory os.chdir(cwd)
def testRmDir(self): temp_dir_path = os.path.join(os.path.dirname(__file__), "data", "temp-dir") os.mkdir(temp_dir_path) FileManager.rm_dir(temp_dir_path) self.assertFalse(os.path.exists(temp_dir_path))
def backup(self): ''' peform the backup operation, recording installed packages and copying new/modified files ''' if config.options.log_level_at_least('normal'): callback.snapcallback.message("Creating snapshot") self.check_permission() # temp directory used to construct tarball construct_dir = tempfile.mkdtemp() FileManager.make_dir(construct_dir) backends = self.load_backends() configured_targets = backends.keys() for target in SnapshotTarget.BACKENDS: # load from SnapshotTarget to preserve order if target in configured_targets: backend = backends[target] includes = config.options.target_includes[target] excludes = config.options.target_excludes[target] backend.backup(construct_dir, include=includes, exclude=excludes) SnapFile( snapfile=config.options.snapfile, snapdirectory=construct_dir, encryption_password=config.options.encryption_password).compress() if config.options.log_level_at_least('normal'): callback.snapcallback.message("Snapshot completed") FileManager.rm_dir(construct_dir)
def restore(self): ''' perform the restore operation, restoring packages and files recorded ''' if config.options.log_level_at_least('normal'): callback.snapcallback.message("Restoring Snapshot") self.check_permission() # temp directory used to extract tarball construct_dir = tempfile.mkdtemp() FileManager.make_dir(construct_dir) SnapFile(snapfile=config.options.snapfile, snapdirectory=construct_dir, encryption_password=config.options.encryption_password).extract() backends = self.load_backends() configured_targets = backends.keys() for target in SnapshotTarget.BACKENDS: # load from SnapShotTarget to preserve order if target in configured_targets: backend = backends[target] backend.restore(construct_dir) if config.options.log_level_at_least('normal'): callback.snapcallback.message("Restore completed") FileManager.rm_dir(construct_dir)
def restore(self): ''' perform the restore operation, restoring packages and files recorded ''' if config.options.log_level_at_least('normal'): callback.snapcallback.message("Restoring Snapshot") self.check_permission() # temp directory used to extract tarball construct_dir = tempfile.mkdtemp() FileManager.make_dir(construct_dir) SnapFile( snapfile=config.options.snapfile, snapdirectory=construct_dir, encryption_password=config.options.encryption_password).extract() backends = self.load_backends() configured_targets = backends.keys() for target in SnapshotTarget.BACKENDS: # load from SnapShotTarget to preserve order if target in configured_targets: backend = backends[target] backend.restore(construct_dir) if config.options.log_level_at_least('normal'): callback.snapcallback.message("Restore completed") FileManager.rm_dir(construct_dir)
def testEncryptDecrypt(self): temp_file_path = os.path.join(os.path.dirname(__file__), "data/cfile") f = open(temp_file_path, 'w') f.write("foobar") f.close() key = Crypto.generate_key("secret_key") Crypto.encrypt_file(key, temp_file_path) self.assertTrue(os.path.exists(temp_file_path + ".enc")) contents = FileManager.read_file(temp_file_path + ".enc") # TODO should do a better verification that it's actually encrypted properly self.assertTrue(contents != "foobar") os.remove(temp_file_path) Crypto.decrypt_file(key, temp_file_path + ".enc") contents = FileManager.read_file(temp_file_path) self.assertTrue(contents == "foobar") os.remove(temp_file_path) os.remove(temp_file_path + ".enc")
def testGetAllSubdirectories(self): data_path = os.path.join(os.path.dirname(__file__), "data") subdirs = FileManager.get_all_subdirectories(data_path, recursive=True) self.assertIn(os.path.join(data_path, "tmp"), subdirs) self.assertIn(os.path.join(data_path, "tmp", "subdir"), subdirs) subdirs = FileManager.get_all_subdirectories(data_path, recursive=False) self.assertIn(os.path.join(data_path, "tmp"), subdirs) self.assertNotIn(os.path.join(data_path, "tmp/subdir"), subdirs)
def testIptablesService(self): # manually backup iptalbes to restore after the test f = file(self.basedir + "/iptables-backup", 'w') popen = subprocess.Popen("iptables-save", stdout=f) popen.wait() self.assertEqual(0, popen.returncode) # flush the filter table (removes all rules) popen = subprocess.Popen(["iptables", "-F"]) popen.wait() self.assertEqual(0, popen.returncode) # allow port 22 traffic popen = subprocess.Popen([ "iptables", "-A", "INPUT", "-p", "tcp", "--dport", "22", "-j", "ACCEPT" ]) popen.wait() self.assertEqual(0, popen.returncode) # perform the backup backend = snap.backends.services.adapters.iptables.Iptables() backend.backup(self.basedir) # assert we have our rule self.assertTrue(os.path.isfile(self.basedir + "/iptables.rules")) c = FileManager.read_file(self.basedir + "/iptables.rules") self.assertEqual( 1, len(re.findall('-A INPUT -p tcp -m tcp --dport 22 -j ACCEP', c))) # again flush the filter table popen = subprocess.Popen(["iptables", "-F"]) popen.wait() self.assertEqual(0, popen.returncode) # perform the restoration backend.restore(self.basedir) # assert that we have registered port 22 f = file(self.basedir + "/iptables-running", 'w') popen = subprocess.Popen(["iptables", "-nvL"], stdout=f) popen.wait() self.assertEqual(0, popen.returncode) c = re.sub("\s+", " ", FileManager.read_file(self.basedir + "/iptables-running")) self.assertEqual(1, len(re.findall( "ACCEPT.*tcp dpt:22", c))) # TODO prolly could be a better regex # finally fiush the chain one last time and restore the original rules popen = subprocess.Popen(["iptables", "-F"]) popen.wait() self.assertEqual(0, popen.returncode) popen = subprocess.Popen( ["iptables-restore", self.basedir + "/iptables-backup"]) popen.wait() self.assertEqual(0, popen.returncode)
def testReadFile(self): temp_file_path = os.path.join(os.path.dirname(__file__), "data", "read-file") f = open(temp_file_path, 'w') f.write('foobar') f.close() c = FileManager.read_file(temp_file_path) FileManager.rm(temp_file_path) self.assertEqual("foobar", c)
def testMakeDirAndExists(self): temp_dir_path = os.path.join(os.path.dirname(__file__), "data", "temp-dir") FileManager.make_dir(temp_dir_path) self.assertTrue(os.path.exists(temp_dir_path)) self.assertTrue(os.path.isdir(temp_dir_path)) self.assertTrue(FileManager.exists(temp_dir_path)) os.removedirs(temp_dir_path) self.assertFalse(os.path.exists(temp_dir_path)) self.assertFalse(FileManager.exists(temp_dir_path))
def testRmAndExists(self): temp_file_path = os.path.join(os.path.dirname(__file__), "data", "temp-file") f = open(temp_file_path, 'w') f.write("foo") f.close() self.assertTrue(os.path.exists(temp_file_path)) self.assertTrue(os.path.isfile(temp_file_path)) self.assertTrue(FileManager.exists(temp_file_path)) FileManager.rm(temp_file_path) self.assertFalse(os.path.exists(temp_file_path)) self.assertFalse(FileManager.exists(temp_file_path))
def testGetAllFiles(self): data_path = os.path.join(os.path.dirname(__file__), "data", "tmp") files = FileManager.get_all_files(include=[data_path]) self.assertIn(os.path.join(data_path, "file1"), files) self.assertIn(os.path.join(data_path, "subdir", "file2"), files) files = FileManager.get_all_files( include=[data_path], exclude=[os.path.join(data_path, 'subdir')]) self.assertIn(os.path.join(data_path, "file1"), files) self.assertNotIn(os.path.join(data_path, "subdir", "file2"), files) files = FileManager.get_all_files(include=[data_path], recursive=False) self.assertIn(os.path.join(data_path, "file1"), files) self.assertNotIn(os.path.join(data_path, "subdir", "file2"), files)
def testMv(self): temp_source_file_path = os.path.join(os.path.dirname(__file__), "data", "temp-source-file") temp_dest_file_path = os.path.join(os.path.dirname(__file__), "data", "temp-dest-file") f = open(temp_source_file_path, 'w') f.write("foo") f.close() self.assertTrue(os.path.isfile(temp_source_file_path)) FileManager.mv(temp_source_file_path, temp_dest_file_path) self.assertFalse(os.path.isfile(temp_source_file_path)) self.assertTrue(os.path.isfile(temp_dest_file_path)) os.remove(temp_dest_file_path)
def compress(self): '''create a snapfile from the snapdirectory @raises - MissingFileError - if the snapfile cannot be created ''' # if snapfile == '-' write to stdout snapfileo = None if self.snapfile == '-': snapfileo = sys.stdout else: snapfileo = open(self.snapfile, 'w') # create the tarball tarball = tarfile.open(fileobj=snapfileo, mode="w:gz") # temp store the working directory, before changing to the snapdirectory cwd = os.getcwd() os.chdir(self.snapdirectory) seperator = snap.osregistry.OS.get_path_seperator() # copy directories into snapfile for sdir in FileManager.get_all_subdirectories(os.getcwd(), recursive=True): partialpath = sdir.replace(self.snapdirectory + seperator, "") tarball.addfile(self.__prepare_file_for_tarball(tarball, sdir, partialpath)) # copy files into snapfile for tfile in FileManager.get_all_files(include=[os.getcwd()]): partialpath = tfile.replace(self.snapdirectory + seperator, "") if os.path.exists(tfile): tarball.addfile(self.__prepare_file_for_tarball(tarball, tfile, partialpath), file(tfile, 'rb')) # finish up tarball creation tarball.close() if self.snapfile != '-': snapfileo.close() # encrypt the snapshot if we've set a key if not snap.osregistry.OS.is_windows() and self.encryption_key != None: if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message("Encyrpting snapfile") Crypto.encrypt_file(self.encryption_key, self.snapfile, self.snapfile + ".enc") FileManager.mv(self.snapfile + ".enc", self.snapfile) if snap.config.options.log_level_at_least('normal'): snap.callback.snapcallback.message("Snapfile " + self.snapfile + " created") # restore the working directory os.chdir(cwd)
def testGetAllFiles(self): data_path = os.path.join(os.path.dirname(__file__), "data", "tmp") files = FileManager.get_all_files(include=[data_path]) self.assertIn(os.path.join(data_path, "file1"), files) self.assertIn(os.path.join(data_path, "subdir", "file2"), files) files = FileManager.get_all_files(include=[data_path], exclude=[os.path.join(data_path, 'subdir')]) self.assertIn(os.path.join(data_path, "file1"), files) self.assertNotIn(os.path.join(data_path, "subdir", "file2"), files) files = FileManager.get_all_files(include=[data_path], recursive=False) self.assertIn(os.path.join(data_path, "file1"), files) self.assertNotIn(os.path.join(data_path, "subdir", "file2"), files)
def testIptablesService(self): # manually backup iptalbes to restore after the test f = file(self.basedir + "/iptables-backup", "w") popen = subprocess.Popen("iptables-save", stdout=f) popen.wait() self.assertEqual(0, popen.returncode) # flush the filter table (removes all rules) popen = subprocess.Popen(["iptables", "-F"]) popen.wait() self.assertEqual(0, popen.returncode) # allow port 22 traffic popen = subprocess.Popen(["iptables", "-A", "INPUT", "-p", "tcp", "--dport", "22", "-j", "ACCEPT"]) popen.wait() self.assertEqual(0, popen.returncode) # perform the backup backend = snap.backends.services.adapters.iptables.Iptables() backend.backup(self.basedir) # assert we have our rule self.assertTrue(os.path.isfile(self.basedir + "/iptables.rules")) c = FileManager.read_file(self.basedir + "/iptables.rules") self.assertEqual(1, len(re.findall("-A INPUT -p tcp -m tcp --dport 22 -j ACCEP", c))) # again flush the filter table popen = subprocess.Popen(["iptables", "-F"]) popen.wait() self.assertEqual(0, popen.returncode) # perform the restoration backend.restore(self.basedir) # assert that we have registered port 22 f = file(self.basedir + "/iptables-running", "w") popen = subprocess.Popen(["iptables", "-nvL"], stdout=f) popen.wait() self.assertEqual(0, popen.returncode) c = re.sub("\s+", " ", FileManager.read_file(self.basedir + "/iptables-running")) self.assertEqual(1, len(re.findall("ACCEPT.*tcp dpt:22", c))) # TODO prolly could be a better regex # finally fiush the chain one last time and restore the original rules popen = subprocess.Popen(["iptables", "-F"]) popen.wait() self.assertEqual(0, popen.returncode) popen = subprocess.Popen(["iptables-restore", self.basedir + "/iptables-backup"]) popen.wait() self.assertEqual(0, popen.returncode)
def __file_modified(self,file_name): '''return true if package has been modified since installation, else false''' # if the file isn't tracked by the package system if not file_name in self.installed_file_packages: return True pkg = self.installed_file_packages[file_name] modified_time = os.stat(file_name).st_mtime # seems that comparing the modified_time against this time is the only way togo # http://lists.netisland.net/archives/plug/plug-2008-02/msg00205.html pkg_modified_time = os.stat('/var/lib/dpkg/info/' + pkg.name + '.list').st_mtime if modified_time > pkg_modified_time: return True # finally if the file is a deb conffile, we just assume its modified since # there is no way to determine if the file was modified before the package # was updated (see the link above) conf_file='/var/lib/dpkg/info/' + pkg.name + '.conffiles' if os.path.isfile(conf_file): c = FileManager.read_file(conf_file) if len(re.findall(file_name, c)) > 0: return True return False
def restore(self, basedir): '''restore the packages from the snapfile''' # if package record file isn't found, simply return if not os.path.isfile(os.path.join(basedir, "packages.xml")): return if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message("Restoring software on windows") # read files from the record file record = PackagesRecordFile(os.path.join(basedir, "packages.xml")) packages = record.read() # TODO restore registry? # restore program files for pkg_file in FileManager.get_all_files( include=[os.path.join(basedir, "windows-packages")]): partial_path = pkg_file.replace( os.path.join(basedir, "windows-packages") + "\\", "") try: SFile(partial_path).copy_to( path_prefix=os.path.join(basedir, "windows-packages")) except: if snap.config.options.log_level_at_least('normal'): snap.callback.snapcallback.message( "Failed to restore windows package file " + partial_path)
def backup(self, basedir, include=[], exclude=[]): """backup the files modified outside the apt package system""" if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message("Backing up files using apt backend"); if len(include) == 0: include = ['/'] for additional_exclude in ['/proc', '/sys', '/selinux']: if not additional_exclude in exclude: exclude.append(additional_exclude) # remove duplicates include = list(set(include)) exclude = list(set(exclude)) # determine which files have been modified since installation # and copy those to basedir sfiles = [] files = FileManager.get_all_files(include, exclude) for tfile in files: if self.__file_modified(tfile): if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message("Backing up file " + tfile); sfile = SFile(tfile) sfile.copy_to(basedir) sfiles.append(sfile) # write record file to basedir record = FilesRecordFile(basedir + "/files.xml") record.write(sfiles)
def compress(self): '''create a snapfile from the snapdirectory @raises - MissingFileError - if the snapfile cannot be created ''' # create the tarball tarball = tarfile.open(self.snapfile, "w:gz") # temp store the working directory, before changing to the snapdirectory cwd = os.getcwd() os.chdir(self.snapdirectory) seperator = snap.osregistry.OS.get_path_seperator() # copy directories into snapfile for sdir in FileManager.get_all_subdirectories(os.getcwd(), recursive=True): partialpath = sdir.replace(self.snapdirectory + seperator, "") tarball.addfile( self.__prepare_file_for_tarball(tarball, sdir, partialpath)) # copy files into snapfile for tfile in FileManager.get_all_files(include=[os.getcwd()]): partialpath = tfile.replace(self.snapdirectory + seperator, "") if os.path.exists(tfile): tarball.addfile( self.__prepare_file_for_tarball(tarball, tfile, partialpath), file(tfile, 'rb')) # finish up tarball creation tarball.close() # encrypt the snapshot if we've set a key if not snap.osregistry.OS.is_windows() and self.encryption_key != None: if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message("Encyrpting snapfile") Crypto.encrypt_file(self.encryption_key, self.snapfile, self.snapfile + ".enc") FileManager.mv(self.snapfile + ".enc", self.snapfile) if snap.config.options.log_level_at_least('normal'): snap.callback.snapcallback.message("Snapfile " + self.snapfile + " created") # restore the working directory os.chdir(cwd)
def backup(self, basedir, include=[], exclude=[]): '''backup yum configuration and repositories''' # first backup the yum config SFile("/etc/yum.conf").copy_to(basedir) # then backup the individual repo files for yum_repo in FileManager.get_all_files(include=['/etc/yum.repos.d']): SFile(yum_repo).copy_to(basedir)
def restore(self, basedir): '''restore yum configuration and repositories''' # return if we cannot find require files if not os.path.isdir(basedir + "/etc/apt"): return # restore the apt config to /etc/apt for apt_conf in FileManager.get_all_files(include=[basedir + "/etc/apt"]): partial_path = apt_conf.replace(basedir + "/", "") SFile(partial_path).copy_to(self.fs_root, path_prefix=basedir)
def testWriteServicesRecordFile(self): file_path = os.path.join(os.path.dirname(__file__), "data/services-out.xml") services = [Service(name="foo"), Service(name="baz")] service_record_file = ServicesRecordFile(file_path) service_record_file.write(services) contents = FileManager.read_file(file_path) self.assertEqual("<services><service>foo</service><service>baz</service></services>", contents) os.remove(file_path)
def restore(self, basedir): '''restore yum configuration and repositories''' # return if we cannot find require files if not os.path.isdir(basedir + "/etc/apt"): return # restore the apt config to /etc/apt for apt_conf in FileManager.get_all_files( include=[basedir + "/etc/apt"]): partial_path = apt_conf.replace(basedir + "/", "") SFile(partial_path).copy_to(self.fs_root, path_prefix=basedir)
def testWriteServicesRecordFile(self): file_path = os.path.join(os.path.dirname(__file__), "data/services-out.xml") services = [Service(name='foo'), Service(name='baz')] service_record_file = ServicesRecordFile(file_path) service_record_file.write(services) contents = FileManager.read_file(file_path) self.assertEqual("<services><service>foo</service><service>baz</service></services>", contents) os.remove(file_path)
def backup(self, basedir, include=[], exclude=[]): '''backup apt configuration and repositories''' # backup the apt config in /etc/apt repos = [] for apt_conf in FileManager.get_all_files(include=['/etc/apt']): SFile(apt_conf).copy_to(basedir) repos.append(Repo()) # FIXME parse repo info # write record file to basedir record = ReposRecordFile(basedir + "/repos.xml") record.write(repos)
def db_exists(dbname): '''helper to return boolean indicating if the db w/ the specified name exists''' mysql_password = snap.config.options.service_options['mysql_password'] # retrieve list of db names from mysql c = FileManager.capture_output([Mysql.MYSQL_CMD, "-e", "show databases", "-u", "root", "-p" + mysql_password]) # determine if the specified one is among them has_db = len(re.findall(dbname, c)) return has_db
def testWriteReposRecordFile(self): file_path = os.path.join(os.path.dirname(__file__), "data/repos-out.xml") repos = [Repo(name='yum.morsi.org', url='http://yum.morsi.org'), Repo(name='apt.morsi.org', url='http://apt.morsi.org')] repo_record_file = ReposRecordFile(file_path) repo_record_file.write(repos) contents = FileManager.read_file(file_path) self.assertEqual("<repos><repo>http://yum.morsi.org</repo><repo>http://apt.morsi.org</repo></repos>", contents) os.remove(file_path)
def get_packages(): # retrieve list of installed software c = FileManager.capture_output(["reg", "query", "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "/s"]) # parse install locations out of this packages = [] for match in re.finditer(r"InstallLocation\s*REG_SZ[ \t]*([a-zA-Z][^\n]+)\r\n", c): install_location = match.group(1) packages.append(Package(install_location)) return packages
def testWriteFilesRecordFile(self): path1 = os.path.join("some", "path") path2 = os.path.join("another", "path") self.dest = os.path.join(os.path.dirname(__file__), "data", "files-out.xml") files = [SFile(path=path1), SFile(path=path2)] files_record_file = FilesRecordFile(self.dest) files_record_file.write(files) contents = FileManager.read_file(self.dest) self.assertEqual("<files><file>" + path1 + "</file><file>" + path2 + "</file></files>", contents)
def db_exists(dbname): '''helper to return boolean indicating if the db w/ the specified name exists''' # get the env containing the postgres password penv = Postgresql.set_pgpassword_env() # retrieve list of db names from postgres c = FileManager.capture_output([Postgresql.PSQL_CMD, "--username", "postgres", "-t", "-c", "select datname from pg_database"], env=penv) # determine if the specified one is among them has_db = len(re.findall(dbname, c)) return has_db
def testWritePackageRecordFile(self): file_path = os.path.join(os.path.dirname(__file__), "data/packages-out.xml") packages = [Package(name='foo', version='1'), Package(name='baz', version='0.1'), Package(name='bar')] package_record_file = PackagesRecordFile(file_path) package_record_file.write(packages) contents = FileManager.read_file(file_path) self.assertEqual("<packages><package>foo</package><package>baz</package><package>bar</package></packages>", contents) os.remove(file_path)
def restore(self, basedir): '''restore yum configuration and repositories''' # return if we cannot find require files if not os.path.isdir(basedir + "/etc/yum.repos.d"): return # first restore yum configuration SFile("etc/yum.conf").copy_to(self.fs_root, path_prefix=basedir) # then restore individual repos for yum_repo in FileManager.get_all_files(include=[basedir + "/etc/yum.repos.d"]): partial_path = yum_repo.replace(basedir + "/" , "") SFile(partial_path).copy_to(self.fs_root, path_prefix=basedir)
def backup(self, basedir, include=[], exclude=[]): '''backup yum configuration and repositories''' # first backup the yum config SFile("/etc/yum.conf").copy_to(basedir) # then backup the individual repo files repos = [] for yum_repo in FileManager.get_all_files(include=['/etc/yum.repos.d']): SFile(yum_repo).copy_to(basedir) # parse/extract repo info baseurl = re.compile('baseurl=(.*)\n') mirrorlist = re.compile('mirrorlist=(.*)\n') contents = FileManager.read_file(yum_repo) for match in baseurl.findall(contents): repos.append(Repo(url=match)) for match in mirrorlist.findall(contents): repos.append(Repo(url=match)) # write record file to basedir record = ReposRecordFile(basedir + "/repos.xml") record.write(repos)
def db_exists(dbname): '''helper to return boolean indicating if the db w/ the specified name exists''' mysql_password = snap.config.options.service_options['mysql_password'] # retrieve list of db names from mysql c = FileManager.capture_output([ Mysql.MYSQL_CMD, "-e", "show databases", "-u", "root", "-p" + mysql_password ]) # determine if the specified one is among them has_db = len(re.findall(dbname, c)) return has_db
def testWriteFilesRecordFile(self): path1 = os.path.join("some", "path") path2 = os.path.join("another", "path") self.dest = os.path.join(os.path.dirname(__file__), "data", "files-out.xml") files = [SFile(path=path1), SFile(path=path2)] files_record_file = FilesRecordFile(self.dest) files_record_file.write(files) contents = FileManager.read_file(self.dest) self.assertEqual( "<files><file>" + path1 + "</file><file>" + path2 + "</file></files>", contents)
def get_packages(): # retrieve list of installed software c = FileManager.capture_output([ "reg", "query", "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "/s" ]) # parse install locations out of this packages = [] for match in re.finditer( r"InstallLocation\s*REG_SZ[ \t]*([a-zA-Z][^\n]+)\r\n", c): install_location = match.group(1) packages.append(Package(install_location)) return packages
def restore(self, basedir): '''restore yum configuration and repositories''' # return if we cannot find require files if not os.path.isdir(basedir + "/etc/apt"): return # read files from the record file # tho we don't do anything with this info here record = ReposRecordFile(basedir + "/repos.xml") repos = record.read() # restore the apt config to /etc/apt for apt_conf in FileManager.get_all_files(include=[basedir + "/etc/apt"]): partial_path = apt_conf.replace(basedir + "/", "") SFile(partial_path).copy_to(self.fs_root, path_prefix=basedir)
def db_exists(dbname): '''helper to return boolean indicating if the db w/ the specified name exists''' # get the env containing the postgres password penv = Postgresql.set_pgpassword_env() # retrieve list of db names from postgres c = FileManager.capture_output([ Postgresql.PSQL_CMD, "--username", "postgres", "-t", "-c", "select datname from pg_database" ], env=penv) # determine if the specified one is among them has_db = len(re.findall(dbname, c)) return has_db
def testWritePackageRecordFile(self): file_path = os.path.join(os.path.dirname(__file__), "data/packages-out.xml") packages = [ Package(name='foo', version='1'), Package(name='baz', version='0.1'), Package(name='bar') ] package_record_file = PackagesRecordFile(file_path) package_record_file.write(packages) contents = FileManager.read_file(file_path) self.assertEqual( "<packages><package>foo</package><package>baz</package><package>bar</package></packages>", contents) os.remove(file_path)
def backup(self, basedir, include=[], exclude=[]): '''backup the packages installed locally''' if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message("Backing up software on windows"); packages = Win.get_packages() # backup program files for pkg in packages: for pkg_file in FileManager.get_all_files(include=[pkg.name]): SFile(pkg_file).copy_to(os.path.join(basedir, "windows-packages")) # TODO Backup registry? # write record file to basedir record = PackagesRecordFile(os.path.join(basedir, "packages.xml")) record.write(packages)
def restore(self, basedir): '''restore yum configuration and repositories''' # return if we cannot find require files if not os.path.isdir(basedir + "/etc/yum.repos.d"): return # read files from the record file # tho we don't do anything with this info here record = ReposRecordFile(basedir + "/repos.xml") repos = record.read() # first restore yum configuration SFile("etc/yum.conf").copy_to(self.fs_root, path_prefix=basedir) # then restore individual repos for yum_repo in FileManager.get_all_files(include=[basedir + "/etc/yum.repos.d"]): partial_path = yum_repo.replace(basedir + "/" , "") SFile(partial_path).copy_to(self.fs_root, path_prefix=basedir)
def backup(self, basedir, include=[], exclude=[]): '''backup the packages installed locally''' if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message( "Backing up software on windows") packages = Win.get_packages() # backup program files for pkg in packages: for pkg_file in FileManager.get_all_files(include=[pkg.name]): SFile(pkg_file).copy_to( os.path.join(basedir, "windows-packages")) # TODO Backup registry? # write record file to basedir record = PackagesRecordFile(os.path.join(basedir, "packages.xml")) record.write(packages)
def testSFileCopyTo(self): basedir = os.path.join(os.path.dirname(__file__), "data") self.source_dir = os.path.join(basedir, "source", "subdir") self.dest_dir = os.path.join(basedir, "dest") os.makedirs(self.source_dir) f = open(os.path.join(self.source_dir, "foo"), 'w') f.write("foo") f.close() dest_file = os.path.join(self.dest_dir, self.source_dir, "foo") sfile = SFile(path=os.path.join(self.source_dir, "foo")) sfile.copy_to(self.dest_dir) self.assertTrue(os.path.exists(dest_file)) contents = FileManager.read_file(dest_file) self.assertEqual("foo", contents) shutil.rmtree(os.path.join(basedir, "source"))
def backup(self, basedir, include=[], exclude=[]): """backup the files modified outside the apt package system""" if snap.config.options.log_level_at_least('verbose'): snap.callback.snapcallback.message("Backing up files on windows") # get list of hard drives if len(include) == 0: drives = [] c = FileManager.capture_output(["fsutil", "fsinfo", "drives"]) drives = c.split()[1:] # loop through each drive and determine which are available for drive in drives: include_drive = True try: os.listdir(drive) except WindowsError, e: include_drive = False if include_drive: include.append(drive)
def lookup(): '''lookup and return the current operating system we are running as''' # TODO other operating system checks if FileManager.exists('/etc/fedora-release'): return 'fedora' elif FileManager.exists('/etc/redhat-release'): return 'rhel' elif FileManager.exists('/etc/centos-release'): return 'centos' elif FileManager.exists("/proc/version"): c = FileManager.read_file("/proc/version") if len(re.findall('Ubuntu', c)) > 0: return 'ubuntu' elif len(re.findall('Debian', c)) > 0: return 'debian' elif FileManager.exists('C:\\'): return 'windows' return None
def testCaptureOutputWithStdout(self): out = FileManager.capture_output(['expr', '1', '/', '0']) self.assertEqual("expr: division by zero\n", out)