def complete_batch(cls, labbook: LabBook, txid: str, cancel: bool = False, rollback: bool = False) -> None: """ Indicate a batch upload is finished and sweep all new files. Args: labbook: Subject labbook txid: Transaction id (correlator) cancel: Indicate transaction finished but due to cancellation rollback: Undo all local changes if cancelled (default False) Returns: None """ if cancel and rollback: logger.warning(f"Cancelled tx {txid}, doing git reset") call_subprocess(['git', 'reset', '--hard'], cwd=labbook.root_dir) else: logger.info(f"Done batch upload {txid}, cancelled={cancel}") if cancel: logger.warning("Sweeping aborted batch upload.") m = "Cancelled upload `{txid}`. " if cancel else '' labbook.sweep_uncommitted_changes(upload=True, extra_msg=m, show=True)
def delete_files(cls, labbook: LabBook, section: str, relative_paths: List[str]) -> None: """Delete file (or directory) from inside lb section. The list of paths is deleted in series. Only provide "parent" nodes in the file tree. This is because deletes on directories will remove all child objects, so subsequent deletes of individual files will then fail. Args: labbook(LabBook): Subject LabBook section(str): Section name (code, input, output) relative_paths(list(str)): a list of relative paths from labbook root to target Returns: None """ labbook.validate_section(section) if not isinstance(relative_paths, list): raise ValueError("Must provide list of paths to remove") for file_path in relative_paths: relative_path = LabBook.make_path_relative(file_path) target_path = os.path.join(labbook.root_dir, section, relative_path) if not os.path.exists(target_path): raise ValueError( f"Attempted to delete non-existent path at `{target_path}`" ) else: labbook.git.remove(target_path, force=True, keep_file=False) if os.path.exists(target_path): raise IOError(f"Failed to delete path: {target_path}") labbook.sweep_uncommitted_changes(show=True)
def stop_container(cls, labbook: LabBook, username: Optional[str] = None) -> Tuple[LabBook, bool]: """ Stop the given labbook. Returns True in the second field if stopped, otherwise False (False can simply imply no container was running). Args: labbook: Subject labbook username: Optional username of active user Returns: A tuple of (Labbook, boolean indicating whether a container was successfully stopped). """ owner = InventoryManager().query_owner(labbook) n = infer_docker_image_name(labbook_name=labbook.name, owner=owner, username=username) logger.info(f"Stopping {str(labbook)} ({n})") try: stopped = stop_labbook_container(n) finally: # Save state of LB when container turned off. labbook.sweep_uncommitted_changes() return labbook, stopped
def migrate_labbook_untracked_space(labbook: LabBook) -> None: gitignore_path = os.path.join(labbook.root_dir, '.gitignore') gitignored_lines = open(gitignore_path).readlines() has_untracked_dir = any( ['output/untracked' in l.strip() for l in gitignored_lines]) if not has_untracked_dir: with open(gitignore_path, 'a') as gi_file: gi_file.write('\n\n# Migrated - allow untracked area\n' 'output/untracked\n') labbook.sweep_uncommitted_changes(extra_msg="Added untracked area") # Make the untracked directory -- makedirs is no-op if already exists untracked_path = os.path.join(labbook.root_dir, 'output/untracked') if not os.path.exists(untracked_path): os.makedirs(untracked_path, exist_ok=True)