def copy(modules: List[str], force_disconnect: bool, from_db: str, new_db: str) -> None: """ Create an Odoo database by copying an existing one. This script copies using postgres CREATEDB WITH TEMPLATE. It also copies the filestore. """ new_exists = dbutils.db_exists(new_db) if new_exists: msg = f"Destination database {new_db} already exists." _log.error(msg) return from_exists = dbutils.db_exists(from_db) if not from_exists: msg = f"Source database {from_db} does not exist." _log.error(msg) return if force_disconnect: count = dbutils.terminate_connections(from_db) if count: msg = f"Disconnected {count} active connections from '{new_db}'." _log.warning(msg) dbutils.copy_db(from_db, new_db) odooutils.copy_filestore(from_db, new_db) msg = f"Database and filestore copied from {from_db} to {new_db}." _log.info(msg) if modules: install_modules(modules, new_db)
def test_backup_restore_database(self, main_loaded, db, tmp_path): assert dbutils.terminate_connections(db) == 1 restore = db + "restored" file = tmp_path / "tempfile" dbutils.backup_database(db, file) dbutils.restore_database(restore, file) assert dbutils.db_exists(restore)
def backup(filestore_include: bool, dbname: str, dest: Path) -> Path: """Creates a compressed archive of an odoo instance backup, optionally with filestore included.""" if not dbutils.db_exists(dbname): msg = f"Database {dbname} doesn't exists." _log.error(msg) return with tempfile.TemporaryDirectory(prefix="prepare") as dir: dir = Path(str(dir)) # Convention! db_bkp = dir / "db.dump" fs_bkp = dir / "filestore" dbutils.backup_database(dbname, db_bkp) odooutils.backup_filestore(dbname, fs_bkp) timestamp = datetime.isoformat(datetime.now(), timespec="seconds") archive = dest / f"{timestamp}.{dbname}" archive = shutil.make_archive(archive, "gztar", dir) return Path(archive)
def restore(clear: bool, dbname: str, src: Path) -> None: """Restores an odoo instance backup, from one of the supported archives types: zip, tar, gztar, xztar, bztar.""" exists = dbutils.db_exists(dbname) if exists and not clear: msg = f"Database {dbname} already exists." _log.error(msg) return with _extracted(src) as src: _validate_convention(src) # Keep this here after validation if exists: msg = f"Dropping database & filestore of {dbname} before restoring." _log.warning(msg) try: count = dbutils.terminate_connections(dbname) if count: msg = f"Disconnected {count} active connections from '{dbname}'." _log.warning(msg) dbutils.drop_database(dbname) odooutils.drop_filestore(dbname) except Exception: msg = f"Database & filestore fof {dbname} could not be pruned." _log.error(msg, exc_info=True) return else: msg = f"Database & filestore {dbname} pruned." _log.info(msg) # Convention! db_bkp = src / "db.dump" fs_bkp = src / "filestore" dbutils.restore_database(dbname, db_bkp) odooutils.restore_filestore(dbname, fs_bkp) msg = f"Database & filestore {dbname} restored." _log.info(msg)
def test_copy_db(self, main_loaded, db): assert dbutils.terminate_connections(db) == 1 copy = db + "copy" dbutils.copy_db(db, copy) assert dbutils.db_exists(copy)
def test_drop_database(self, main_loaded, db): assert dbutils.terminate_connections(db) == 1 dbutils.drop_database(db) assert not dbutils.db_exists(db)
def test_terminate_connections_sql(self, db): assert dbutils.db_exists(db) assert dbutils.terminate_connections(db) == 1
def test_db_exists_sql(self, db): assert dbutils.db_exists(db) assert not dbutils.db_exists("no-" + db)