def test_backup_offline(self): """ Backup service offline, delete files, restore and check. """ ntacls.backup_offline(self.service_root, self.tarfile_path, self.samdb_conn, self.smb_conf_path) self._check_tarfile() self.smb_helper.delete_tree() ntacls.backup_restore(self.tarfile_path, self.service_root, self.samdb_conn, self.smb_conf_path) self._check_tree() # compare ntacls after restored self.assertDictEqual(self.original_ntacls, self.smb_helper.get_ntacls())
def test_backup_offline(self): """ Backup service offline, delete files, restore and check. """ ntacls.backup_offline( self.service_root, self.tarfile_path, self.samdb_conn, self.smb_conf_path) self._check_tarfile() self.smb_helper.delete_tree() ntacls.backup_restore( self.tarfile_path, self.service_root, self.samdb_conn, self.smb_conf_path) self._check_tree() # compare ntacls after restored self.assertDictEqual( self.original_ntacls, self.smb_helper.get_ntacls())
def run(self, sambaopts=None, targetdir=None): logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(logging.StreamHandler(sys.stdout)) # Get the absolute paths of all the directories we're going to backup lp = sambaopts.get_loadparm() paths = samba.provision.provision_paths_from_lp(lp, lp.get('realm')) if not (paths.samdb and os.path.exists(paths.samdb)): raise CommandError('No sam.db found. This backup ' + 'tool is only for AD DCs') check_targetdir(logger, targetdir) samdb = SamDB(url=paths.samdb, session_info=system_session(), lp=lp) sid = get_sid_for_restore(samdb) backup_dirs = [ paths.private_dir, paths.state_dir, os.path.dirname(paths.smbconf) ] # etc dir logger.info('running backup on dirs: {}'.format(backup_dirs)) # Recursively get all file paths in the backup directories all_files = [] for backup_dir in backup_dirs: for (working_dir, _, filenames) in os.walk(backup_dir): if working_dir.startswith(paths.sysvol): continue for filename in filenames: if filename in all_files: continue # Assume existing backup files are from a previous backup. # Delete and ignore. if filename.endswith(self.backup_ext): os.remove(os.path.join(working_dir, filename)) continue all_files.append(os.path.join(working_dir, filename)) # Backup secrets, sam.ldb and their downstream files self.backup_secrets(paths.private_dir, lp, logger) self.backup_smb_dbs(paths.private_dir, samdb, lp, logger) # Open the new backed up samdb, flag it as backed up, and write # the next SID so the restore tool can add objects. # WARNING: Don't change this code unless you know what you're doing. # Writing to a .bak file only works because the DN being # written to happens to be top level. samdb = SamDB(url=paths.samdb + self.backup_ext, session_info=system_session(), lp=lp) time_str = get_timestamp() add_backup_marker(samdb, "backupDate", time_str) add_backup_marker(samdb, "sidForRestore", sid) # Now handle all the LDB and TDB files that are not linked to # anything else. Use transactions for LDBs. for path in all_files: if not os.path.exists(path + self.backup_ext): if path.endswith('.ldb'): logger.info('Starting transaction on solo db: ' + path) ldb_obj = Ldb(path, lp=lp) ldb_obj.transaction_start() logger.info(' running tdbbackup on the same file') self.offline_tdb_copy(path) ldb_obj.transaction_cancel() elif path.endswith('.tdb'): logger.info('running tdbbackup on lone tdb file ' + path) self.offline_tdb_copy(path) # Now make the backup tar file and add all # backed up files and any other files to it. temp_tar_dir = tempfile.mkdtemp(dir=targetdir, prefix='INCOMPLETEsambabackupfile') temp_tar_name = os.path.join(temp_tar_dir, "samba-backup.tar.bz2") tar = tarfile.open(temp_tar_name, 'w:bz2') logger.info('running offline ntacl backup of sysvol') sysvol_tar_fn = 'sysvol.tar.gz' sysvol_tar = os.path.join(temp_tar_dir, sysvol_tar_fn) backup_offline(paths.sysvol, sysvol_tar, samdb, paths.smbconf) tar.add(sysvol_tar, sysvol_tar_fn) os.remove(sysvol_tar) create_log_file(temp_tar_dir, lp, "offline", "localhost", True) backup_fn = os.path.join(temp_tar_dir, "backup.txt") tar.add(backup_fn, os.path.basename(backup_fn)) os.remove(backup_fn) logger.info('building backup tar') for path in all_files: arc_path = self.get_arc_path(path, paths) if os.path.exists(path + self.backup_ext): logger.info(' adding backup ' + arc_path + self.backup_ext + ' to tar and deleting file') tar.add(path + self.backup_ext, arcname=arc_path) os.remove(path + self.backup_ext) elif path.endswith('.ldb') or path.endswith('.tdb'): logger.info(' skipping ' + arc_path) else: logger.info(' adding misc file ' + arc_path) tar.add(path, arcname=arc_path) tar.close() os.rename( temp_tar_name, os.path.join(targetdir, 'samba-backup-{}.tar.bz2'.format(time_str))) os.rmdir(temp_tar_dir) logger.info('Backup succeeded.')