Compare commits

...
61 Commits
Author SHA1 Message Date
Iurii b4514b880d + 2024-04-18 20:48:42 +03:00
Iurii e092924c08 + 2024-04-18 20:47:04 +03:00
Iurii e7f0e04b1d + 2024-04-18 20:46:27 +03:00
Iurii 9a61e543c7 + 2024-04-18 20:12:41 +03:00
Iurii 0ee51eda60 + 2024-04-18 20:03:44 +03:00
Iurii 95a672af4f + 2024-04-15 22:10:48 +03:00
Iurii b609f62b14 + 2024-04-15 21:59:45 +03:00
Iurii 9967235640 + 2024-04-15 21:51:58 +03:00
Iurii 095c657d63 + 2024-04-15 21:48:35 +03:00
Iurii 2d49b17a72 + 2024-04-15 21:46:26 +03:00
Iurii 96cc58fe7f + 2024-04-15 21:46:06 +03:00
Iurii df748e5990 + 2024-04-15 21:44:55 +03:00
Iurii a4eb09e4a7 + 2024-04-15 21:33:04 +03:00
Iurii e1b3c2a4fc + 2024-04-15 21:31:38 +03:00
Iurii 8e3d004434 + 2024-04-15 21:30:17 +03:00
Iurii acf1c6a892 + 2024-04-15 21:29:35 +03:00
Iurii fce7f8b28b + 2024-04-15 21:28:36 +03:00
Iurii 8fbb9de3a4 +
ci/woodpecker/push/build Pipeline failed
2024-04-15 21:24:49 +03:00
Iurii 33ba079ae4 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 21:20:06 +03:00
Iurii f20a5828ec +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 21:06:36 +03:00
Iurii 46c0e3b542 +
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/manual/build Pipeline was successful
2024-04-15 21:04:04 +03:00
Iurii 1ecce8636c +
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/manual/build Pipeline was successful
2024-04-15 21:00:35 +03:00
Iurii d68d760b5e +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 20:46:44 +03:00
Iurii b3f4edea5b +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 20:44:03 +03:00
Iurii 26282d2c3d +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 20:41:49 +03:00
Iurii 548541e4d3 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 20:25:06 +03:00
Iurii 1835ad3188 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 20:03:56 +03:00
Iurii 52500d23ed +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 20:01:53 +03:00
Iurii 4c9df6c6a4 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 20:00:29 +03:00
Iurii 3d7b977f50 +
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
2024-04-15 19:51:28 +03:00
Iurii f45ce65c74 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 19:41:00 +03:00
Iurii 3fa7cec025 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 19:35:55 +03:00
Iurii 1d97160776 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 19:29:38 +03:00
Iurii 6dfa8ac2e4 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 19:28:20 +03:00
Iurii f87f90bfa9 +
ci/woodpecker/push/build Pipeline was successful
2024-04-15 19:20:50 +03:00
Iurii 8cc63244de +
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/publish Pipeline failed
2024-04-15 19:19:45 +03:00
Iurii cb7ef4667c +
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/publish Pipeline failed
2024-04-15 19:11:31 +03:00
Iurii e15e4db16d + 2024-04-15 19:08:52 +03:00
Iurii 372827821a + 2024-04-15 19:08:04 +03:00
Iurii 43d6546e2a +
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-15 18:58:35 +03:00
Iurii 7c5911ffa8 +
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-14 23:37:42 +03:00
Iurii 38bf7e204e +
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-14 23:27:50 +03:00
Iurii 7a4ed46cb5 +
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-14 22:11:23 +03:00
Iurii 1a9d3ce1e4 +
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-14 21:59:47 +03:00
Iurii e481ed08d8 + 2024-04-14 21:57:39 +03:00
Iurii 0fbd021569 +
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/deployment/woodpecker Pipeline was successful
ci/woodpecker/manual/woodpecker Pipeline was successful
2024-04-14 21:50:26 +03:00
Iurii 4aef7e6f7c + 2024-04-14 21:34:00 +03:00
Iurii 68ee0ed6f6 + 2024-04-14 21:29:50 +03:00
Iurii cced3d91f3 +
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-14 17:56:41 +03:00
Iurii e81dfe21cf + 2024-04-14 17:54:44 +03:00
Iurii f1834a91d8 +
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/deployment/woodpecker Pipeline was successful
2024-04-14 17:48:55 +03:00
Iurii 41e65eb778 +
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-14 17:47:32 +03:00
Iurii fd975299ac +
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-14 16:59:06 +03:00
Iurii 55308c534f +
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-14 16:50:06 +03:00
Iurii f28d0fe221 +
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/manual/woodpecker Pipeline was successful
2024-04-14 16:01:18 +03:00
Iurii c0262fd84a +
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-14 15:55:41 +03:00
iu 391fa66490 Добавить .woodpecker.yaml
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-14 12:48:03 +00:00
Iurii ef254ecb12 fix. Удаление файла при возврате пространства 2024-04-01 21:51:13 +03:00
iu 6e80f9fba2 Merge pull request 'develop' (#2) from develop into main
Reviewed-on: #2
2024-03-31 09:34:22 +00:00
iu 8e22979c39 + Параметры, работа в режиме демона 2024-03-31 12:27:24 +03:00
iu 17d3e3bf7b fix: Корректировка вычисления Use%, как это делает df 2024-03-31 11:11:16 +03:00
5 changed files with 111 additions and 17 deletions
+2
View File
@@ -160,3 +160,5 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
/mnt/
/img
+24
View File
@@ -0,0 +1,24 @@
steps:
- name: build
image: git.zunet.ru/iu/nuitka:v215
commands:
- nuitka3 src/main.py -o baloon
- ls -lh
- file baloon
- name: release
# image: woodpeckerci/plugin-gitea-release
image: plugins/gitea-release
settings:
base_url: https://git.zunet.ru
files:
- "baloon"
api_key:
from_secret: SEC1
target: main
title: Ti ${CI_COMMIT_TAG##v}
when:
- event: tag
ref: refs/tags/v*
Executable
BIN
View File
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
FROM python:3
RUN pip install -U nuitka
+81 -16
View File
@@ -2,33 +2,98 @@
import os import os
from shutil import disk_usage from shutil import disk_usage
import time import time
import argparse
BS = 1024**2 BS = 1024**2
def set_utilization(du, utilization_percent=0.6, baloon_filename='baloon'): def set_utilization(fs, utilization_percent=0.6, baloon_filename='baloon', hysteresis_percent=0.01, quiet=False):
fs = os.path.realpath(du) fs = os.path.realpath(fs)
du = disk_usage(fs) du = disk_usage(fs)
print(f'total: {int(du.total/ 2**30)}GB, used: {int(du.used/ 2**30)}GB, free: {int(du.free/ 2**30)}GB') if utilization_percent < 0.1 or utilization_percent > 0.9:
to_be_wasted = int((du.total * utilization_percent) - du.used) raise ValueError('utilization_percent must be between 0.1 and 0.9')
print(f'to_be_wasted: {int(to_be_wasted/ 2**30)}GB') if hysteresis_percent < 0 or hysteresis_percent > 0.1:
if to_be_wasted < 0: raise ValueError('hysteresis_percent must be between 0 and 0.1')
hysteresis = int(du.total * hysteresis_percent)
if hysteresis < BS: hysteresis = BS
to_be_wasted = int(((du.used+du.free) * utilization_percent) - ((du.used+du.free) - du.free))
baloon_filename = os.path.join(fs, baloon_filename)
if not quiet:
print(f'hysteresis: {hysteresis}bytes')
print(f'total: {round(du.total/ 2**30, 3)}GB, used: {round(du.used/ 2**30, 3)}GB, free: {round(du.free/ 2**30, 3)}GB usage: {round(du.used * 100 / (du.used+du.free), 3)}%')
print(f'to_be_wasted: {round(to_be_wasted/ 2**30, 3)}GB ')
if to_be_wasted < -hysteresis:
to_be_trimmed = abs(to_be_wasted) to_be_trimmed = abs(to_be_wasted)
baloon_size = os.path.getsize(os.path.join(fs, baloon_filename)) baloon_size = os.path.getsize(baloon_filename)
if baloon_size> to_be_trimmed: if baloon_size > to_be_trimmed:
os.truncate(os.path.join(fs, baloon_filename), baloon_size - to_be_trimmed) os.truncate(baloon_filename, baloon_size - to_be_trimmed)
else: print(f'can\'t trim {baloon_size} > {to_be_trimmed}') if not quiet: print(f'trimmed {to_be_trimmed} Bytes')
elif to_be_wasted > 0: else:
with open(os.path.join(fs, baloon_filename) , 'ab') as f: if os.path.exists(baloon_filename):
os.remove(baloon_filename)
if not quiet and to_be_trimmed > baloon_size: print(f'can\'t trim {to_be_trimmed - baloon_size} Bytes')
elif to_be_wasted > hysteresis:
with open(baloon_filename , 'ab') as f:
last = 0 last = 0
writed = to_be_wasted
while to_be_wasted > 0: while to_be_wasted > 0:
if time.time() - last > 1: if time.time() - last > 1:
print('\r', end='') if not quiet: print(f'left {int(to_be_wasted/ 2**30)}GB \r', end='')
print(f'left {int(to_be_wasted/ 2**30)}GB ', end='')
last = time.time() last = time.time()
write_size = min(to_be_wasted, BS) write_size = min(to_be_wasted, BS)
f.write(b'x' * write_size) f.write(b'x' * write_size)
to_be_wasted -= write_size to_be_wasted -= write_size
print('Done ') if not quiet: print(f'Done, added {writed} bytes')
if not quiet:
du = disk_usage(fs)
print(f'total: {round(du.total/ 2**30, 3)}GB, used: {round(du.used/ 2**30, 3)}GB, free: {round(du.free/ 2**30, 3)}GB usage: {round(du.used * 100 / (du.used+du.free), 3)}%')
def hysteresis_type(arg):
MAX_VAL = 10
MIN_VAL = 0
try:
f = float(arg)
except ValueError:
raise argparse.ArgumentTypeError("Must be a floating point number")
if f < MIN_VAL or f > MAX_VAL:
raise argparse.ArgumentTypeError("Argument must be < " + str(MAX_VAL) + " and > " + str(MIN_VAL))
return f
set_utilization('.') parser = argparse.ArgumentParser(description='Baloon utilize your disk space')
parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0')
parser.add_argument('-u', '--utilization', type=int, metavar="[10-90]", choices=range(10, 91), help='percentage of utilization', default=60)
parser.add_argument('-b', '--baloon', type=str, metavar="baloon", help='name of the baloon file', default='baloon')
parser.add_argument('-s', '--hysteresis', type=hysteresis_type, metavar="[0-10]", help='hysteresis, in percentage of disk size', default=1)
parser.add_argument('-f', '--fs', type=str, action='append', metavar="fs", help='path to the filesystem', required=True)
parser.add_argument('-d', '--daemon', action='store_true', help='daemon mode')
parser.add_argument('-i', '--interval', type=int, help='interval in seconds to work in daemon mode', default=60*60)
args = parser.parse_args()
fss = []
baloon_filename = args.baloon
hysteresis_percent = args.hysteresis/100.0
utilization_percent = args.utilization/100.0
daemon_mode = args.daemon
daemon_mode_interval = args.interval
for fs in args.fs:
fs = os.path.realpath(fs)
if not os.path.isdir(fs):
raise ValueError(f'{fs} is not a directory')
fss.append(fs)
if not daemon_mode:
for p in vars(args):
print(f'{p}: {getattr(args, p)}')
for fs in fss:
set_utilization(fs, utilization_percent, baloon_filename, hysteresis_percent)
else:
while True:
for fs in fss:
if os.path.isdir(fs):
try:
set_utilization(fs=fs, utilization_percent=utilization_percent, baloon_filename=baloon_filename, hysteresis_percent=hysteresis_percent, quiet=True)
except Exception as e:
pass
time.sleep(daemon_mode_interval)