Add hardlinking with cp -al

This commit is contained in:
Maks Snegov 2021-06-10 22:19:26 +03:00
parent a867dadb75
commit 170b73834b

View File

@ -4,7 +4,6 @@ Module with filesystem-related functions.
import logging import logging
import os import os
import pathlib
import subprocess import subprocess
from typing import Iterable from typing import Iterable
@ -82,18 +81,25 @@ def rsync(src_dir, dst_dir=None):
_lg.info("Updating %s", src_entry) _lg.info("Updating %s", src_entry)
def hardlink_dir(src_dir, dst_dir): def _hardlink_dir_ext(src, dst):
""" """
Make hardlink for a directory with all its content. Make hardlink for a directory using cp -al. Both src and dst should exist.
:param src_dir: path to source directory :param src: absolute path to source directory.
:param dst_dir: path to target directory :param dst: absolute path to target directory.
:return: None :return: None
""" """
_lg.info(f"Recursive hardlinking: {src_dir} -> {dst_dir}") res = subprocess.run(["cp", "-v", "-a", "-l", f"{src}/*", dst])
src_abs = os.path.abspath(src_dir) return res
dst_abs = os.path.abspath(dst_dir)
def recursive_hardlink(src, dst):
def _recursive_hardlink(src, dst):
"""
Do hardlink directory recursively using python only.
Both src and dst directories should exist.
:param src: absolute path to source directory.
:param dst: absolute path to target directory.
:return: None
"""
with os.scandir(src) as it: with os.scandir(src) as it:
ent: os.DirEntry ent: os.DirEntry
for ent in it: for ent in it:
@ -106,7 +112,7 @@ def hardlink_dir(src_dir, dst_dir):
os.chmod(ent_dst_path, ent_stat.st_mode) os.chmod(ent_dst_path, ent_stat.st_mode)
# process directory children # process directory children
recursive_hardlink(ent.path, ent_dst_path) _recursive_hardlink(ent.path, ent_dst_path)
continue continue
if ent.is_file(follow_symlinks=False) or ent.is_symlink(): if ent.is_file(follow_symlinks=False) or ent.is_symlink():
_lg.debug(f"Hardlink file: {ent.path} -> {ent_dst_path}") _lg.debug(f"Hardlink file: {ent.path} -> {ent_dst_path}")
@ -115,6 +121,18 @@ def hardlink_dir(src_dir, dst_dir):
# something that is not a file, symlink or directory # something that is not a file, symlink or directory
raise NotImplementedError(ent.path) raise NotImplementedError(ent.path)
def hardlink_dir(src_dir, dst_dir):
"""
Make hardlink for a directory with all its content.
:param src_dir: path to source directory
:param dst_dir: path to target directory
:return: None
"""
_lg.info(f"Recursive hardlinking: {src_dir} -> {dst_dir}")
src_abs = os.path.abspath(src_dir)
dst_abs = os.path.abspath(dst_dir)
if not os.path.isdir(src_abs): if not os.path.isdir(src_abs):
_lg.error(f"Error reading source directory: {src_dir}") _lg.error(f"Error reading source directory: {src_dir}")
raise RuntimeError(f"Error reading source directory: {src_dir}") raise RuntimeError(f"Error reading source directory: {src_dir}")
@ -125,5 +143,5 @@ def hardlink_dir(src_dir, dst_dir):
_lg.debug(f"Creating directory: {dst_abs}") _lg.debug(f"Creating directory: {dst_abs}")
os.mkdir(dst_abs) os.mkdir(dst_abs)
recursive_hardlink(src_abs, dst_abs) _recursive_hardlink(src_abs, dst_abs)
return return