2022-06-23 02:20:56 +00:00
#!/usr/bin/python3
2022-08-11 13:56:39 +00:00
import argparse
2023-06-28 17:21:43 +00:00
from itertools import cycle
2022-06-23 02:20:56 +00:00
import json
2022-12-30 10:47:28 +00:00
import sys
2023-05-03 11:33:16 +00:00
import tempfile
2023-06-25 10:12:19 +00:00
import time
2022-11-17 17:08:20 +00:00
2022-11-18 10:27:57 +00:00
from argparse import Namespace
2022-06-23 02:20:56 +00:00
from concurrent . futures import ProcessPoolExecutor
2022-11-17 17:08:20 +00:00
from helpers . cmd import random_payload
2022-12-29 14:52:55 +00:00
from helpers . frostfs_cli import create_container , upload_object
2022-06-23 02:20:56 +00:00
2023-05-23 16:04:38 +00:00
ERROR_WRONG_CONTAINERS_COUNT = 1
ERROR_WRONG_OBJECTS_COUNT = 2
2022-12-30 10:47:28 +00:00
MAX_WORKERS = 50
2024-07-02 17:45:31 +00:00
DEFAULT_POLICY = " REP 2 IN X CBF 2 SELECT 2 FROM * AS X "
2024-11-15 08:13:06 +00:00
DEFAULT_RULES = [ " allow Object.* * " ]
2022-12-30 10:47:28 +00:00
2022-08-11 13:56:39 +00:00
parser = argparse . ArgumentParser ( )
2022-06-23 02:20:56 +00:00
parser . add_argument ( ' --size ' , help = ' Upload objects size in kb ' )
parser . add_argument ( ' --containers ' , help = ' Number of containers to create ' )
2024-07-31 16:11:33 +00:00
parser . add_argument ( ' --retry ' , default = 20 , help = ' Maximum number of retries to create a container ' )
2022-06-23 02:20:56 +00:00
parser . add_argument ( ' --out ' , help = ' JSON file with output ' )
parser . add_argument ( ' --preload_obj ' , help = ' Number of pre-loaded objects ' )
2022-12-15 13:32:34 +00:00
parser . add_argument ( ' --wallet ' , help = ' Wallet file path ' )
parser . add_argument ( ' --config ' , help = ' Wallet config file path ' )
2022-08-11 13:56:39 +00:00
parser . add_argument (
" --policy " ,
2024-07-02 17:45:31 +00:00
help = f " Container placement policy. Default is { DEFAULT_POLICY } " ,
action = " append "
2022-08-11 13:56:39 +00:00
)
2023-06-28 17:21:43 +00:00
parser . add_argument ( ' --endpoint ' , help = ' Nodes addresses separated by comma. ' )
2022-06-23 02:20:56 +00:00
parser . add_argument ( ' --update ' , help = ' Save existed containers ' )
2023-07-13 12:50:03 +00:00
parser . add_argument ( ' --ignore-errors ' , help = ' Ignore preset errors ' , action = ' store_true ' )
2022-12-30 10:47:28 +00:00
parser . add_argument ( ' --workers ' , help = ' Count of workers in preset. Max = 50, Default = 50 ' , default = 50 )
2023-08-08 15:57:06 +00:00
parser . add_argument ( ' --sleep ' , help = ' Time to sleep between containers creation and objects upload (in seconds), '
2023-06-25 10:12:19 +00:00
' Default = 8 ' , default = 8 )
2024-01-24 13:25:39 +00:00
parser . add_argument ( ' --local ' , help = ' Create containers that store data on provided endpoints. Warning: additional empty containers may be created. ' , action = ' store_true ' )
2024-11-15 08:13:06 +00:00
parser . add_argument (
' --rule ' ,
help = ' Rule attached to created containers. All entries of CONTAINER_ID will be replaced with id of created container. ' ,
action = " append " )
2022-06-23 02:20:56 +00:00
2022-11-17 17:08:20 +00:00
args : Namespace = parser . parse_args ( )
2022-06-23 02:20:56 +00:00
print ( args )
def main ( ) :
2023-06-28 17:21:43 +00:00
containers = [ ]
2022-12-30 10:47:28 +00:00
objects_list = [ ]
2022-06-23 02:20:56 +00:00
2022-11-18 10:27:57 +00:00
endpoints = args . endpoint . split ( ' , ' )
2024-07-02 17:45:31 +00:00
if not args . policy :
args . policy = [ DEFAULT_POLICY ]
2022-11-18 10:27:57 +00:00
2024-07-31 16:11:33 +00:00
container_creation_retry = args . retry
2022-12-15 13:32:34 +00:00
wallet = args . wallet
wallet_config = args . config
2022-12-30 10:47:28 +00:00
workers = int ( args . workers )
2023-05-23 16:04:38 +00:00
objects_per_container = int ( args . preload_obj )
2024-11-15 08:13:06 +00:00
rules = args . rule
if not rules :
rules = DEFAULT_RULES
2023-07-13 12:50:03 +00:00
ignore_errors = args . ignore_errors
2022-06-23 02:20:56 +00:00
if args . update :
# Open file
with open ( args . out ) as f :
data_json = json . load ( f )
2023-06-28 17:21:43 +00:00
containers = data_json [ ' containers ' ]
containers_count = len ( containers )
2022-06-23 02:20:56 +00:00
else :
2023-05-23 16:04:38 +00:00
containers_count = int ( args . containers )
print ( f " Create containers: { containers_count } " )
2022-12-30 10:47:28 +00:00
with ProcessPoolExecutor ( max_workers = min ( MAX_WORKERS , workers ) ) as executor :
2024-11-15 08:13:06 +00:00
containers_runs = [ executor . submit ( create_container , endpoint , policy , container_creation_retry , wallet , wallet_config , rules , args . local )
2024-07-02 17:45:31 +00:00
for _ , endpoint , policy in
zip ( range ( containers_count ) , cycle ( endpoints ) , cycle ( args . policy ) ) ]
2022-06-23 02:20:56 +00:00
for run in containers_runs :
2023-06-28 17:21:43 +00:00
container_id = run . result ( )
if container_id :
containers . append ( container_id )
2022-06-23 02:20:56 +00:00
print ( " Create containers: Completed " )
2023-06-28 17:21:43 +00:00
print ( f " > Containers: { containers } " )
2024-04-01 13:10:04 +00:00
if containers_count > 0 and len ( containers ) != containers_count :
2023-06-28 17:21:43 +00:00
print ( f " Containers mismatch in preset: expected { containers_count } , created { len ( containers ) } " )
2022-12-30 10:47:28 +00:00
if not ignore_errors :
2023-05-23 16:04:38 +00:00
sys . exit ( ERROR_WRONG_CONTAINERS_COUNT )
2022-06-23 02:20:56 +00:00
2023-06-25 10:12:19 +00:00
if args . sleep != 0 :
print ( f " Sleep for { args . sleep } seconds " )
time . sleep ( args . sleep )
2022-06-23 02:20:56 +00:00
print ( f " Upload objects to each container: { args . preload_obj } " )
2023-05-03 11:33:16 +00:00
payload_file = tempfile . NamedTemporaryFile ( )
random_payload ( payload_file , args . size )
2022-06-23 02:20:56 +00:00
print ( " > Create random payload: Completed " )
2023-06-28 17:21:43 +00:00
total_objects = objects_per_container * containers_count
with ProcessPoolExecutor ( max_workers = min ( MAX_WORKERS , workers ) ) as executor :
objects_runs = [ executor . submit ( upload_object , container , payload_file . name ,
endpoint , wallet , wallet_config )
for _ , container , endpoint in
zip ( range ( total_objects ) , cycle ( containers ) , cycle ( endpoints ) ) ]
for run in objects_runs :
result = run . result ( )
2023-07-19 11:55:44 +00:00
if result :
2023-06-28 17:21:43 +00:00
container_id = result [ 0 ]
endpoint = result [ 1 ]
object_id = result [ 2 ]
objects_list . append ( { ' container ' : container_id , ' object ' : object_id } )
print ( f " > Uploaded object { object_id } for container { container_id } via endpoint { endpoint } . " )
2022-06-23 02:20:56 +00:00
print ( " Upload objects to each container: Completed " )
2023-05-23 16:04:38 +00:00
if total_objects > 0 and len ( objects_list ) != total_objects :
print ( f " Objects mismatch in preset: expected { total_objects } , created { len ( objects_list ) } " )
2022-12-30 10:47:28 +00:00
if not ignore_errors :
2023-05-23 16:04:38 +00:00
sys . exit ( ERROR_WRONG_OBJECTS_COUNT )
2022-12-30 10:47:28 +00:00
2023-06-28 17:21:43 +00:00
data = { ' containers ' : containers , ' objects ' : objects_list , ' obj_size ' : args . size + " Kb " }
2022-06-23 02:20:56 +00:00
2022-10-25 15:01:08 +00:00
with open ( args . out , ' w+ ' ) as f :
2022-10-25 15:06:43 +00:00
json . dump ( data , f , ensure_ascii = False , indent = 2 )
2022-06-23 02:20:56 +00:00
2022-12-30 10:47:28 +00:00
print ( " Result: " )
2023-06-28 17:21:43 +00:00
print ( f " > Total Containers has been created: { len ( containers ) } . " )
2022-12-30 10:47:28 +00:00
print ( f " > Total Objects has been created: { len ( objects_list ) } . " )
2022-06-23 02:20:56 +00:00
if __name__ == " __main__ " :
main ( )