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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 testMysqlService(self): # first start the service if it isn't running already_running = self.dispatcher.service_running( snap.backends.services.adapters.mysql.Mysql.DAEMON) if not already_running: self.dispatcher.start_service( snap.backends.services.adapters.mysql.Mysql.DAEMON) # create a test database snap.backends.services.adapters.mysql.Mysql.create_db('snaptest') # restore to original state if not already_running: self.dispatcher.stop_service( snap.backends.services.adapters.mysql.Mysql.DAEMON) backend = snap.backends.services.adapters.mysql.Mysql() backend.backup(self.basedir) # ensure the process is in its original state currently_running = self.dispatcher.service_running( snap.backends.services.adapters.mysql.Mysql.DAEMON) self.assertEqual(already_running, currently_running) # assert the db dump exists and has the db dump self.assertTrue(os.path.isfile(self.basedir + "/dump.mysql")) c = FileManager.read_file(self.basedir + "/dump.mysql") self.assertEqual(1, len(re.findall('CREATE DATABASE.*snaptest', c))) # finally cleanup self.dispatcher.start_service( snap.backends.services.adapters.mysql.Mysql.DAEMON) snap.backends.services.adapters.mysql.Mysql.drop_db('snaptest') # stop the service, backup the datadir self.dispatcher.stop_service( snap.backends.services.adapters.mysql.Mysql.DAEMON) shutil.copytree( snap.backends.services.adapters.mysql.Mysql.DATADIR, snap.backends.services.adapters.mysql.Mysql.DATADIR + ".bak") # test restore backend.restore(self.basedir) # ensure service is running, datadir has been initialized self.assertTrue( self.dispatcher.service_running( snap.backends.services.adapters.mysql.Mysql.DAEMON)) self.assertTrue( os.path.isdir(snap.backends.services.adapters.mysql.Mysql.DATADIR)) # ensure the db exists self.assertTrue( snap.backends.services.adapters.mysql.Mysql.db_exists('snaptest')) # stop the service, restore the db self.dispatcher.stop_service( snap.backends.services.adapters.mysql.Mysql.DAEMON) shutil.rmtree(snap.backends.services.adapters.mysql.Mysql.DATADIR) shutil.move( snap.backends.services.adapters.mysql.Mysql.DATADIR + ".bak", snap.backends.services.adapters.mysql.Mysql.DATADIR) # XXX dirty hack make sure the datadir is owned by mysql data_dir = None if snap.osregistry.OS.yum_based(): data_dir = snap.backends.services.adapters.mysql.Mysql.DATADIR elif snap.osregistry.OS.apt_based(): data_dir = snap.backends.services.adapters.mysql.Mysql.DATADIR elif snap.osregistry.OS.is_windows(): data_dir = snap.backends.services.adapters.mysql.Mysql.DATADIR snap.osregistry.OSUtils.chown(data_dir, username='******') # cleanup, restore to original state if already_running: self.dispatcher.start_service( snap.backends.services.adapters.mysql.Mysql.DAEMON)
def testMysqlService(self): # first start the service if it isn't running already_running = self.dispatcher.service_running(snap.backends.services.adapters.mysql.Mysql.DAEMON) if not already_running: self.dispatcher.start_service(snap.backends.services.adapters.mysql.Mysql.DAEMON) # create a test database snap.backends.services.adapters.mysql.Mysql.create_db("snaptest") # restore to original state if not already_running: self.dispatcher.stop_service(snap.backends.services.adapters.mysql.Mysql.DAEMON) backend = snap.backends.services.adapters.mysql.Mysql() backend.backup(self.basedir) # ensure the process is in its original state currently_running = self.dispatcher.service_running(snap.backends.services.adapters.mysql.Mysql.DAEMON) self.assertEqual(already_running, currently_running) # assert the db dump exists and has the db dump self.assertTrue(os.path.isfile(self.basedir + "/dump.mysql")) c = FileManager.read_file(self.basedir + "/dump.mysql") self.assertEqual(1, len(re.findall("CREATE DATABASE.*snaptest", c))) # finally cleanup self.dispatcher.start_service(snap.backends.services.adapters.mysql.Mysql.DAEMON) snap.backends.services.adapters.mysql.Mysql.drop_db("snaptest") # stop the service, backup the datadir self.dispatcher.stop_service(snap.backends.services.adapters.mysql.Mysql.DAEMON) shutil.copytree( snap.backends.services.adapters.mysql.Mysql.DATADIR, snap.backends.services.adapters.mysql.Mysql.DATADIR + ".bak", ) # test restore backend.restore(self.basedir) # ensure service is running, datadir has been initialized self.assertTrue(self.dispatcher.service_running(snap.backends.services.adapters.mysql.Mysql.DAEMON)) self.assertTrue(os.path.isdir(snap.backends.services.adapters.mysql.Mysql.DATADIR)) # ensure the db exists self.assertTrue(snap.backends.services.adapters.mysql.Mysql.db_exists("snaptest")) # stop the service, restore the db self.dispatcher.stop_service(snap.backends.services.adapters.mysql.Mysql.DAEMON) shutil.rmtree(snap.backends.services.adapters.mysql.Mysql.DATADIR) shutil.move( snap.backends.services.adapters.mysql.Mysql.DATADIR + ".bak", snap.backends.services.adapters.mysql.Mysql.DATADIR, ) # XXX dirty hack make sure the datadir is owned by mysql data_dir = None if snap.osregistry.OS.yum_based(): data_dir = snap.backends.services.adapters.mysql.Mysql.DATADIR elif snap.osregistry.OS.apt_based(): data_dir = snap.backends.services.adapters.mysql.Mysql.DATADIR elif snap.osregistry.OS.is_windows(): data_dir = snap.backends.services.adapters.mysql.Mysql.DATADIR snap.osregistry.OSUtils.chown(data_dir, username="******") # cleanup, restore to original state if already_running: self.dispatcher.start_service(snap.backends.services.adapters.mysql.Mysql.DAEMON)