diff --git a/jtop/core/memory.py b/jtop/core/memory.py index 2844c780..1bece7e6 100644 --- a/jtop/core/memory.py +++ b/jtop/core/memory.py @@ -290,7 +290,11 @@ def clear_cache(self): out = clear_cache() return True if out else False - def swap_set(self, size, path_swap, on_boot): + @staticmethod + def swap_set(size, path_swap, on_boot): + if os.path.isfile(path_swap): + logger.error("{path_swap} already exist".format(path_swap=path_swap)) + return # Load swap configuration logger.info("Activate {path_swap} auto={on_boot}".format(path_swap=path_swap, on_boot=on_boot)) # Create a swapfile for Ubuntu at the current directory location @@ -316,7 +320,12 @@ def swap_set(self, size, path_swap, on_boot): file_object.write("{swap_string_boot}\n".format(swap_string_boot=swap_string_boot)) file_object.close() - def swap_deactivate(self, path_swap): + @staticmethod + def swap_deactivate(path_swap): + # Check if exist swap + if not os.path.isfile(path_swap): + logger.error("{path_swap} Does not exist".format(path_swap=path_swap)) + return # Disable swap sp.call(shlex.split('swapoff {path_swap}'.format(path_swap=path_swap))) # Remove swap diff --git a/jtop/jetson_swap.py b/jtop/jetson_swap.py new file mode 100644 index 00000000..181c32f7 --- /dev/null +++ b/jtop/jetson_swap.py @@ -0,0 +1,82 @@ +# -*- coding: UTF-8 -*- +# This file is part of the jetson_stats package (https://github.com/rbonghi/jetson_stats or http://rnext.it). +# Copyright (c) 2019-2023 Raffaello Bonghi. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import re +import os +import sys +import argparse +from .terminal_colors import bcolors +from .core.memory import MemoryService, read_swapon +from .core import get_var +# Version match +VERSION_RE = re.compile(r""".*__version__ = ["'](.*?)['"]""", re.S) +COPYRIGHT_RE = re.compile(r""".*__copyright__ = ["'](.*?)['"]""", re.S) + + +def main(): + parser = argparse.ArgumentParser( + description='Create a swap file and enable on boot (require sudo)', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('-d', '--dir', dest="directory", help='Directory to place swapfile', type=str, default='') + parser.add_argument('-n', '--name', dest="name", help='Name swap file', type=str, default='swapfile') + parser.add_argument('-s', '--size', dest="size", help='Size in Gigabytes', type=int, default='8') + parser.add_argument('-a', '--auto', dest="auto", help='Enable swap on boot', action="store_true", default=False) + parser.add_argument('-t', '--status', dest="status", help='Check if the swap is currently active', action="store_true", default=False) + parser.add_argument('--off', dest="off", help='Switch off the swap', action="store_true", default=False) + # Parse arguments + args = parser.parse_args() + # Copyrights + print("Software part of jetson-stats {version} - {copyright}".format(version=get_var(VERSION_RE), copyright=get_var(COPYRIGHT_RE))) + # Status swap + if args.status: + # Print all swap + swap_table = read_swapon() + print("NAME\t\tTYPE\t\tPRIO\t\tSIZE\t\tUSED") + for name, swap in swap_table.items(): + print("{name}\t{type}\t\t{prio}\t\t{size}{unit}\t{used}{unit}".format( + name=name, + type=swap['type'], + prio=swap['prio'], + size=swap['size'], + used=swap['used'], + unit=swap['unit'])) + sys.exit(0) + # Check if running a root + if os.getuid() != 0: + # Quit with error + print(bcolors.fail("Please run with sudo")) + parser.print_help(sys.stderr) + sys.exit(1) + # Define Memory Service + memory_service = MemoryService + # Path swap + size = args.size + auto = args.auto + path_swap = "{directory}/{name}".format(directory=args.directory, name=args.name) + if args.off: + print("Switch off swap {path_swap}".format(path_swap=path_swap)) + memory_service.swap_deactivate(path_swap) + sys.exit(0) + # Create Swap + print("Create swap {path_swap} [{size}GB] - on boot={auto}".format(path_swap=path_swap, size=size, auto=auto)) + # Create swap + memory_service.swap_set(size, path_swap, auto) + + +if __name__ == "__main__": + main() +# EOF diff --git a/scripts/jetson_swap b/scripts/jetson_swap deleted file mode 100755 index 895275cb..00000000 --- a/scripts/jetson_swap +++ /dev/null @@ -1,133 +0,0 @@ -#!/bin/bash - -#NVIDIA Jetson Nano TX1 TX2 TX2i -# Create a swap file and set up permissions -# If a parameter is passed, it should be the place to create the swapfile - -FSTAB="/etc/fstab" -SWAPDIRECTORY="$PWD" -SWAPSIZE=8 -NAME_SWAP="swapfile" -AUTOMOUNT="N" -SWAP_OFF="N" -SWAP_STATUS="N" - - -function usage -{ - echo "usage: createSwapFile [[[-d directory ] [-s size] -a] | [-h] | [--off]]" - echo " -d | --dir Directory to place swapfile" - echo " -n | --name Name swap file" - echo " -s | --size " - echo " -a | --auto Enable swap on boot in $FSTAB " - echo " -t | --status Check if the swap is currently active" - echo " --off Switch off the swap" - echo " -h | --help This message" - echo - echo "Software part of jetson-stats (c) 2019-2023 Raffaello Bonghi" -} - -while [ "$1" != "" ]; do - case $1 in - -d | --dir ) shift - SWAPDIRECTORY=$1 - ;; - -n | --name ) shift - NAME_SWAP=$1 - ;; - -s | --size ) shift - SWAPSIZE=$1 - ;; - -a | --auto ) AUTOMOUNT="Y" - ;; - -t | --status ) SWAP_STATUS="Y" - ;; - --off ) SWAP_OFF="Y" - ;; - -h | --help ) usage - exit - ;; - * ) usage - exit 1 - esac - shift -done - -SWAPLOCATION="$SWAPDIRECTORY/$NAME_SWAP" - -if [ "$SWAP_STATUS" = "Y" ]; then - line_found=$(swapon --show=NAME | grep -x -n "$SWAPLOCATION" | cut -d ':' -f1) - if [ -z "$line_found" ] ; then - exit 0 - fi - # Extract the line where is swap - counter=1 - while read -r line - do - if [[ "$counter" = "$line_found" ]]; then - echo "$line" - exit 0 - fi - counter=$((counter+1)) - done < <(swapon -s) - exit 0 -fi - -if [[ $EUID != 0 ]]; then - tput setaf 1 - echo "Launch with sudo!" - tput sgr0 - - usage - - exit 1 -fi - -# Switch off the swapfile -if [ "$SWAP_OFF" = "Y" ]; then - # Remove from FSTAB if exist - pwdesc=$(echo $SWAPLOCATION | sed 's_/_\\/_g') - if grep -Fxq "$SWAPLOCATION none swap sw 0 0" $FSTAB ; then - echo "Remove swapfile from $FSTAB" - sed -i "/$pwdesc none swap sw 0 0/d" $FSTAB - fi - if [ -f "$SWAPLOCATION" ]; then - echo "Remove swapfile in $SWAPDIRECTORY" - sudo swapoff "$SWAPLOCATION" - sudo rm "$SWAPLOCATION" - exit 0 - else - echo "Swap file does not exist in $SWAPDIRECTORY" - exit 1 - fi -fi - -echo "Creating Swapfile at: " $SWAPDIRECTORY -echo "Swapfile Size: " $SWAPSIZE"G" -echo "Automount: " $AUTOMOUNT - -#Create a swapfile for Ubuntu at the current directory location -fallocate -l $SWAPSIZE"G" $SWAPLOCATION -cd $SWAPDIRECTORY -#List out the file -ls -lh $SWAPLOCATION -# Change permissions so that only root can use it -sudo chmod 600 $SWAPLOCATION -#List out the file -ls -lh $SWAPLOCATION -#Set up the Linux swap area -sudo mkswap $SWAPLOCATION -#Now start using the swapfile -sudo swapon $SWAPLOCATION -#Show that it's now being used -swapon -s - -if [ "$AUTOMOUNT" = "Y" ]; then - if ! grep -Fxq "$SWAPLOCATION none swap sw 0 0" $FSTAB ; then - echo "Modifying $FSTAB to enable on boot" - sudo sh -c 'echo "'$SWAPLOCATION' none swap sw 0 0" >> '$FSTAB'' - echo "Added in $FSTAB \"$SWAPLOCATION none swap sw 0 0\"" - else - echo "Swap already in $FSTAB" - fi -fi diff --git a/setup.py b/setup.py index 7739f90c..6b0b3790 100644 --- a/setup.py +++ b/setup.py @@ -255,7 +255,6 @@ def run(self): # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files data_files=[('jetson_stats', ['services/jtop.service', 'scripts/jtop_env.sh'])], # Install extra scripts - scripts=['scripts/jetson_swap'], cmdclass={'develop': JTOPDevelopCommand, 'install': JTOPInstallCommand}, # The following provide a command called `jtop` @@ -263,6 +262,7 @@ def run(self): 'jtop=jtop.__main__:main', 'jetson_release = jtop.jetson_release:main', 'jetson_config = jtop.jetson_config:main', + 'jetson_swap = jtop.jetson_swap:main', ]}, ) # EOF