Skip to content

Develop #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ Froster is a user-friendly archiving tool for teams that move data between highe

```
sudo apt-get update
sudo apt-get install -y curl pipx git gcc lib32gcc-s1 unzip
sudo apt-get install -y curl pipx git gcc lib32gcc-s1 unzip fuse3
```

### On RHEL

```
sudo yum update
sudo yum install -y curl pipx git gcc lib32gcc-s1 unzip
sudo yum install -y curl pipx git gcc lib32gcc-s1 unzip fuse3
```

### On HPC machine

Please contact your administrator to install these packages:
```
curl pipx git gcc lib32gcc-s1 unzip
curl pipx git gcc lib32gcc-s1 unzip fuse3
```

</br>
Expand Down
59 changes: 41 additions & 18 deletions froster/froster.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
from textual.widgets import DataTable, Footer, Button

__app__ = 'Froster, a user friendly S3/Glacier archiving tool'
__version__ = '0.10.2'
__version__ = '0.10.4'


class ConfigManager:
Expand Down Expand Up @@ -88,7 +88,9 @@ def __init__(self):
# Initialize the variables that check if specific configuration sections have been initialized
self.user_init = False
self.aws_init = False
self.nih_init = False
self.s3_init = False
self.configuration_done = False

# Whoami
self.whoami = getpass.getuser()
Expand Down Expand Up @@ -193,6 +195,9 @@ def __init__(self):
# NIH configuration
self.is_nih = config.getboolean('NIH', 'is_nih', fallback=None)

# Set nih init flag
self.nih_init = True if self.is_nih is not None else False

# Current S3 Bucket name
self.bucket_name = config.get(
'S3', 'bucket_name', fallback=None)
Expand Down Expand Up @@ -241,6 +246,10 @@ def __init__(self):
self.ec2_last_instance = config.get(
'CLOUD', 'ec2_last_instance', fallback=None)

if self.user_init and self.aws_init and self.s3_init and self.nih_init:
self.configuration_done = True


def __repr__(self):
''' Return a string representation of the object'''

Expand Down Expand Up @@ -4664,26 +4673,33 @@ def convert_size(self, size_bytes):

def _archive_json_add_entry(self, key, value):
'''Add a new entry to the archive JSON file'''
try:

# Initialize the data dictionary in case archive_json does not exist
data = {}
# Initialize the data dictionary in case archive_json does not exist
data = {}

# Read the archive JSON file
if os.path.isfile(self.archive_json):
with open(self.archive_json, 'r') as file:
try:
data = json.load(file)
except:
print('Error in Archiver._archive_json_add_entry():')
print(f'Cannot read {self.archive_json}, file corrupt?')
return False
# Read the archive JSON file
if os.path.isfile(self.archive_json):
with open(self.archive_json, 'r') as file:
try:
data = json.load(file)
except:
print('Error in Archiver._archive_json_add_entry():')
print(
f'Cannot read {self.archive_json}, file corrupt?')
return

# Add the new entry to the data dictionary
data[key] = value
# Add the new entry to the data dictionary
data[key] = value

# Write the updated data dictionary to the archive JSON file
with open(self.archive_json, 'w') as file:
json.dump(data, file, indent=4)
# Create the directory for the archive JSON file if it does not exist
os.makedirs(os.path.dirname(self.archive_json), exist_ok=True)

# Write the updated data dictionary to the archive JSON file
with open(self.archive_json, 'w') as file:
json.dump(data, file, indent=4)
except:
print_error()

def _is_folder_archived(self, folder):
'''Check if an entry exists in the archive JSON file'''
Expand Down Expand Up @@ -5221,7 +5237,7 @@ def _run_rclone_command(self, command, background=False):

# This is the solution i found to prevent the popen subprocess to throw errors due
# our particular usage of rclone.
output = True
output = False

if output:
# Print output in stdout
Expand Down Expand Up @@ -6558,6 +6574,13 @@ def main():
if cfg.is_shared and cfg.shared_dir:
cfg.assure_permissions_and_group(cfg.shared_dir)

# Do not allow other commands rather than config if the configuration is not set
if not cfg.configuration_done and args.subcmd not in ['config', 'cnf']:
print('\nFroster is not full configured yet.\n')
print('Run "froster config" for a full new configuration.')
print('Run "froster config --help" for more information.\n')
sys.exit(1)

# call a function for each sub command in our CLI
if args.subcmd in ['config', 'cnf']:
subcmd_config(args, cfg, aws)
Expand Down
21 changes: 21 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,19 @@ check_apt_dependencies() {
echo
exit 1
fi

# Check if fuse3 is installed
if [[ -z $(command -v fusermount3) ]]; then
echo "Error: fusermount3 is not installed."
echo
echo "Please install fuse3"
echo "In most linux distros you can install the latest version of fuse3 by running the following commands:"
echo " sudo apt update"
echo " sudo apt install -y fuse3"
echo
exit 1
fi

}

# Backup older installations (if any) but keep the froster-archive.json and config.ini files
Expand Down Expand Up @@ -260,14 +273,17 @@ install_pwalk() {
rm -rf ${pwalk_path} >/dev/null 2>&1

# Gather pwalk repository files
echo " Downloading pwalk files"
curl -s -L ${pwalk_repository} | tar xzf - >/dev/null 2>&1 &
spinner $!

# Compile pwalk tool and put exec file in froster's binaries folder
echo " Compiling pwalk"
gcc -pthread ${pwalk_path}/pwalk.c ${pwalk_path}/exclude.c ${pwalk_path}/fileProcess.c -o ${pwalk_path}/pwalk >/dev/null 2>&1 &
spinner $!

# Move pwalk to froster's binaries folder
echo " Moving pwalk to froster's binaries folder"
if [ -d "${HOME}/.local/share/pipx" ]; then
mv ${pwalk_path}/pwalk ${HOME}/.local/share/pipx/venvs/froster/bin/pwalk >/dev/null 2>&1
elif [ -d "${HOME}/.local/pipx" ]; then
Expand All @@ -280,6 +296,7 @@ install_pwalk() {
fi

# Delete downloaded pwalk files
echo " Cleaning up pwalk installation files"
rm -rf ${pwalk_path} >/dev/null 2>&1

echo " ...pwalk installed"
Expand Down Expand Up @@ -310,14 +327,17 @@ install_rclone() {
rm -rf rclone-current-linux-*.zip rclone-v*/ >/dev/null 2>&1

# Download the rclone zip file
echo " Downloading rclone files"
curl -LO $rclone_url >/dev/null 2>&1 &
spinner $!

# Extract the zip file
echo " Extracting rclone files"
unzip rclone-current-linux-*.zip >/dev/null 2>&1 &
spinner $!

# Move rclone to froster's binaries folder
echo " Moving rclone to froster's binaries folder"
if [ -d "${HOME}/.local/share/pipx" ]; then
mv rclone-v*/rclone ${HOME}/.local/share/pipx/venvs/froster/bin/rclone >/dev/null 2>&1
elif [ -d "${HOME}/.local/pipx" ]; then
Expand All @@ -330,6 +350,7 @@ install_rclone() {
fi

# Remove the downloaded zip file
echo " Cleaning up rclone installation files"
rm -rf rclone-current-linux-*.zip rclone-v*/ >/dev/null 2>&1

echo " ...rclone installed"
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='froster',
version='0.10.2',
version='0.10.4',
license='MIT',
packages=find_packages(),
install_requires=[
Expand Down
Loading