Files
scylladb/dist/common/scripts/scylla_swap_setup
Yaniv Michael Kaul af8eaa9ea5 scripts: fixes flagged by CodeQL/PyLens
Unused imports, unused variables and such.
Initially, there were no functional changes, just to get rid of some standard CodeQL warnings.

I've then broken the CI, as apparently there's a install time(!?) Python script creation for the sole purpose of product
naming. I changed it - we have it in etcdir, as SCYLLA-PRODUCT-FILE.
So added (copied from a different script) a get_product() helper function in scylla_util.py and used it instead.

While at it, also fixed the too broad import from scylla_util, which 'forced' me to also fix other specific imports (such as shutil).

Improvement - no need to backport.
Signed-off-by: Yaniv Kaul <yaniv.kaul@scylladb.com>

Closes scylladb/scylladb#27883
2026-01-09 15:13:12 +02:00

122 lines
3.9 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2019-present ScyllaDB
#
#
# SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
import os
import sys
import argparse
import psutil
from pathlib import Path
from scylla_util import swap_exists, out, systemd_unit
from subprocess import run
def GB(n):
return n * 1024 * 1024 * 1024
def to_GB(n):
return '{:.2f}'.format(n / 1024 / 1024 / 1024)
def find_mount_point(path):
path = path.absolute()
while not path.is_mount():
path = path.parent
return path
def get_fs_type(path):
mnt = find_mount_point(path)
for part in psutil.disk_partitions():
if part.mountpoint == str(mnt):
return part.fstype
return None
if __name__ == '__main__':
if os.getuid() > 0:
print('Requires root permission.')
sys.exit(1)
parser = argparse.ArgumentParser(description='Configure swap for Scylla.')
parser.add_argument('--swap-directory',
help='specify swapfile directory', default='/')
parser.add_argument('--swap-size', type=int,
help='specify swapfile size in GB')
parser.add_argument('--swap-size-bytes', type=int,
help='specify swapfile size in bytes')
args = parser.parse_args()
if swap_exists():
print('swap already configured, exiting setup')
sys.exit(1)
if args.swap_size and args.swap_size_bytes:
print("Cannot specify both --swap-size and --swap-size-bytes")
sys.exit(1)
swap_directory = Path(args.swap_directory)
swapfile = swap_directory / 'swapfile'
if swapfile.exists():
print('swapfile {} already exists'.format(swapfile))
sys.exit(1)
swapunit_bn = out('systemd-escape -p --suffix=swap {}'.format(swapfile))
swapunit = Path('/etc/systemd/system/{}'.format(swapunit_bn))
if swapunit.exists():
print('swap unit {} already exists'.format(swapunit))
sys.exit(1)
diskfree = psutil.disk_usage(args.swap_directory).free
if args.swap_size or args.swap_size_bytes:
if args.swap_size:
swapsize = GB(args.swap_size)
else:
swapsize = args.swap_size_bytes
if swapsize > diskfree:
print('swap directory {} does not have enough disk space. {}GB space required.'.format(args.swap_directory, to_GB(swapsize)))
sys.exit(1)
else:
memtotal = psutil.virtual_memory().total
# Scylla document says 'swap size should be set to either total_mem/3 or
# 16GB - lower of the two', so we need to compare 16g vs memtotal/3 and
# choose lower one
# see: https://docs.scylladb.com/faq/#do-i-need-to-configure-swap-on-a-scylla-node
swapsize = GB(16) if GB(16) < int(memtotal / 3) else int(memtotal / 3)
# We should not fill entire disk space with swapfile, it's safer to limit
# swap size 50% of diskfree
half_of_diskfree = int(diskfree / 2)
if swapsize > half_of_diskfree:
# out of disk space, abort setup
if half_of_diskfree <= GB(1):
print('swap directory {} does not have enough disk space.')
sys.exit(1)
swapsize = half_of_diskfree
swapsize_mb = int(swapsize / 1024 / 1024)
fs_type = get_fs_type(swap_directory)
if fs_type == 'ext4':
run(f'fallocate -l {swapsize_mb}MiB {swapfile}', shell=True, check=True)
else:
run('dd if=/dev/zero of={} bs=1M count={}'.format(swapfile, swapsize_mb), shell=True, check=True)
swapfile.chmod(0o600)
run('mkswap -f {}'.format(swapfile), shell=True, check=True)
unit_data = '''
[Unit]
Description=swapfile
[Swap]
What={}
[Install]
WantedBy=multi-user.target
'''[1:-1].format(swapfile)
with swapunit.open('w') as f:
f.write(unit_data)
systemd_unit.reload()
swap = systemd_unit(swapunit_bn)
swap.enable()
swap.start()