From 40290dcac16cd5db2298685183d40f149a443674 Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Mon, 22 Jan 2024 16:36:57 +0000 Subject: [PATCH 01/21] fixes --- src/aux/operations_ids.py | 13 +++++++------ src/main.py | 18 +++++++++++------- src/nef_operations/operations.py | 12 +++++------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/aux/operations_ids.py b/src/aux/operations_ids.py index daa8fb4..5848dcf 100644 --- a/src/aux/operations_ids.py +++ b/src/aux/operations_ids.py @@ -8,14 +8,15 @@ class OPERATION(Enum): ### NEF - LOGIN = '1' + NEF_AUTHENTICATION = 'Def19Sec9' + AUTHENTICATION_WITH_5GS = 'Def115G1' CREATE_UE = '2' GET_UES = '3' - SUBSCRIPTION = '4' - UE_PATH_LOSS = '5' - SERVING_CELL_INFO = '6' - HANDOVER = '9' - SUBSCRIBE_QOS_EVENT = "def115G7" + NEF_LOCATION_SUBSCRIPTION = 'Def115G2' + UE_PATH_LOSS = 'Def115G5' + SERVING_CELL_INFO = 'Def115G6' + HANDOVER = 'Def115G3' + SUBSCRIBE_QOS_EVENT = "Def115G7" E2E_SINGLE_UE_LATENCY_AND_THROUGHPUT = "Def14Perf1" E2E_MULTIPLE_UE_LATENCY_AND_THROUGHPUT = "Def14Perf2" ### AVAILABILITY diff --git a/src/main.py b/src/main.py index 2497aa7..cee2ec9 100644 --- a/src/main.py +++ b/src/main.py @@ -87,7 +87,8 @@ async def start_test( ue_count: int = None, target: str = None): try: - if operation_id == OPERATION.LOGIN.value: + if operation_id == OPERATION.NEF_AUTHENTICATION.value or\ + operation_id == OPERATION.AUTHENTICATION_WITH_5GS: token = nef_operations.login( ip=variables.VARIABLES["NEF_IP"], port=variables.VARIABLES["NEF_PORT"], @@ -119,13 +120,16 @@ async def start_test( ) return JSONResponse(content="Got UEs", status_code=200) - if operation_id == OPERATION.SUBSCRIPTION.value: + if operation_id == OPERATION.NEF_LOCATION_SUBSCRIPTION.value: nef_operations.subscribe_event( ip=variables.VARIABLES["NEF_IP"], port=variables.VARIABLES["NEF_PORT"], - callback_url=variables.VARIABLES["SUBS1_CALLBACK_URL"], - monitoring_type=variables.VARIABLES["SUBS1_MONITORING_TYPE"], - monitoring_expire_time=variables.VARIABLES["SUBS1_MONITORING_EXPIRE_TIME"], + callback_url=variables.VARIABLES["SUBS_CALLBACK_URL"], + monitoring_type=variables.VARIABLES["SUBS_MONITORING_TYPE"], + monitoring_expire_time=variables.VARIABLES[ + "SUBS_MONITORING_EXPIRE_TIME" + ], + external_id=variables.VARIABLES["SUBS_EXTERNAL_ID"], token = variables.VARIABLES["AUTH_TOKEN"] ) return JSONResponse(content="Subscription Done", status_code=200) @@ -133,7 +137,7 @@ async def start_test( nef_operations.get_ue_path_loss( ip=variables.VARIABLES["NEF_IP"], port=variables.VARIABLES["NEF_PORT"], - ue_supi=variables.VARIABLES["UE1_SUPI"], + ue_supi=variables.VARIABLES["UE1_SUPI"], token = variables.VARIABLES["AUTH_TOKEN"] ) return JSONResponse(content="Got UE Path Loss Information", status_code=200) @@ -310,7 +314,7 @@ async def start_test( nef_operations.subscribe_qos_event( ip=variables.VARIABLES["NEF_IP"], port=variables.VARIABLES["NEF_PORT"], - callback_url=variables.VARIABLES["SUBS1_CALLBACK_URL"], + callback_url=variables.VARIABLES["SUBS_CALLBACK_URL"], token = variables.VARIABLES["AUTH_TOKEN"] ) return JSONResponse(content="QoS Subscription Done", status_code=200) diff --git a/src/nef_operations/operations.py b/src/nef_operations/operations.py index 7c61f07..e2128c4 100644 --- a/src/nef_operations/operations.py +++ b/src/nef_operations/operations.py @@ -104,7 +104,7 @@ def get_ues(ip, port, token): def subscribe_event (ip, port, callback_url, monitoring_type, - monitoring_expire_time, token): + monitoring_expire_time, external_id, token): url = f"http://{ip}:{port}/nef/api/v1/3gpp-monitoring-event/" \ "v1/netapp/subscriptions" @@ -115,7 +115,7 @@ def subscribe_event (ip, port, callback_url, monitoring_type, headers["Content-Type"] = "application/json" monitoring_payload = { - "externalId": "123456789@domain.com", + "externalId": external_id, "notificationDestination": callback_url, "monitoringType": monitoring_type, "maximumNumberOfReports": 1, @@ -170,7 +170,7 @@ def create_ue(ip, port, ue_name, ue_description, def get_ue_path_loss(ip, port, ue_supi, token): print("starting....") - url = f"http://{ip}:{port}/api/v1/UEs/{ue_supi}/path_losses" + url = f"http://{ip}:{port}/test/api/v1/UEs/{ue_supi}/path_losses" headers = {} headers["accept"] = "application/json" @@ -192,7 +192,7 @@ def get_serving_cell_info(ip, port, ue_supi, token): ip, port, ue_supi, token ) - url = f"http://{ip}:{port}/api/v1/UEs/{ue_supi}/serving_cell" + url = f"http://{ip}:{port}/test/api/v1/UEs/{ue_supi}/serving_cell" headers = {} headers["accept"] = "application/json" @@ -241,9 +241,7 @@ def subscribe_qos_event (ip, port, callback_url, token): headers["Content-Type"] = "application/json" monitoring_payload = { - "ipv4Addr": "10.0.0.0", - "ipv6Addr": "0:0:0:0:0:0:0:0", - "macAddr": "22-00-00-00-00-00", + "ipv4Addr": "10.0.0.1", "notificationDestination": callback_url, "snssai": { "sst": 1, From 9c6245eb87c3645c8464de387cb4c3348add5c5d Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Mon, 22 Jan 2024 16:55:47 +0000 Subject: [PATCH 02/21] cleanup done --- src/aux/operations_ids.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aux/operations_ids.py b/src/aux/operations_ids.py index 5848dcf..34cdc3e 100644 --- a/src/aux/operations_ids.py +++ b/src/aux/operations_ids.py @@ -20,8 +20,8 @@ class OPERATION(Enum): E2E_SINGLE_UE_LATENCY_AND_THROUGHPUT = "Def14Perf1" E2E_MULTIPLE_UE_LATENCY_AND_THROUGHPUT = "Def14Perf2" ### AVAILABILITY - E2E_UE_PERFORMANCE = '7' - E2E_UE_RTT_PERFORMANCE = '8' + # E2E_UE_PERFORMANCE = '7' + # E2E_UE_RTT_PERFORMANCE = '8' MAX_HOPS = "Def14Perf13" MAX_CONNECTIONS = "Def14Perf11" NEF_CALLBACK_MAX_CONNECTIONS = "Def14Perf7" \ No newline at end of file From 3ae67a3ae110c266f7f236e5150f7f59850dc795 Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Mon, 22 Jan 2024 16:59:58 +0000 Subject: [PATCH 03/21] minor fix --- src/nef_operations/operations.py | 35 +------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/nef_operations/operations.py b/src/nef_operations/operations.py index e2128c4..71fa971 100644 --- a/src/nef_operations/operations.py +++ b/src/nef_operations/operations.py @@ -230,7 +230,7 @@ def get_ue_handover_event(ip, port, ue_supi, token): if response.status_code not in [200, 201, 409]: response.raise_for_status() -def subscribe_qos_event (ip, port, callback_url, token): +def subscribe_qos_event (ip, port, callback_url, token, monitoring_payload): url = f"http://{ip}:{port}/nef/api/v1/3gpp-as-session-with-qos/" \ "v1/netapp/subscriptions" @@ -240,39 +240,6 @@ def subscribe_qos_event (ip, port, callback_url, token): headers["Authorization"] = "Bearer " + token headers["Content-Type"] = "application/json" - monitoring_payload = { - "ipv4Addr": "10.0.0.1", - "notificationDestination": callback_url, - "snssai": { - "sst": 1, - "sd": "000001" - }, - "dnn": "province1.mnc01.mcc202.gprs", - "qosReference": 9, - "altQoSReferences": [ - 0 - ], - "usageThreshold": { - "duration": 0, - "totalVolume": 0, - "downlinkVolume": 0, - "uplinkVolume": 0 - }, - "qosMonInfo": { - "reqQosMonParams": [ - "DOWNLINK" - ], - "repFreqs": [ - "EVENT_TRIGGERED" - ], - "latThreshDl": 0, - "latThreshUl": 0, - "latThreshRp": 0, - "waitTime": 0, - "repPeriod": 0 - } - } - response = requests.post( url=url, headers=headers, From b8efee5ac7fb2e14a2a77f6f5bc29dca5616e0ce Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Mon, 22 Jan 2024 17:06:19 +0000 Subject: [PATCH 04/21] Minor Update --- src/nef_operations/operations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nef_operations/operations.py b/src/nef_operations/operations.py index cae61f2..70fbd85 100644 --- a/src/nef_operations/operations.py +++ b/src/nef_operations/operations.py @@ -234,7 +234,7 @@ def subscribe_qos_event (ip, port, callback_url, token, monitoring_payload): url = f"http://{ip}:{port}/nef/api/v1/3gpp-as-session-with-qos/" \ "v1/netapp/subscriptions" - + headers = {} headers["accept"] = "application/json" headers["Authorization"] = "Bearer " + token From e1055101ffbfbe4a124b31bea38a78591d5cfd8a Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Mon, 22 Jan 2024 18:42:37 +0000 Subject: [PATCH 05/21] Added the needed business logic for the MiniAPI to get a specific UE's RSRP --- src/aux/operations_ids.py | 1 + src/main.py | 14 ++++++++++++-- src/nef_operations/operations.py | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/aux/operations_ids.py b/src/aux/operations_ids.py index 34cdc3e..1c1d62b 100644 --- a/src/aux/operations_ids.py +++ b/src/aux/operations_ids.py @@ -19,6 +19,7 @@ class OPERATION(Enum): SUBSCRIBE_QOS_EVENT = "Def115G7" E2E_SINGLE_UE_LATENCY_AND_THROUGHPUT = "Def14Perf1" E2E_MULTIPLE_UE_LATENCY_AND_THROUGHPUT = "Def14Perf2" + ACQUISITION_OF_RSRP = "Def115G4" ### AVAILABILITY # E2E_UE_PERFORMANCE = '7' # E2E_UE_RTT_PERFORMANCE = '8' diff --git a/src/main.py b/src/main.py index 25572a5..c263126 100644 --- a/src/main.py +++ b/src/main.py @@ -142,14 +142,24 @@ async def start_test( token = variables.VARIABLES["AUTH_TOKEN"] ) return JSONResponse(content="Got UE Path Loss Information", status_code=200) + + if operation_id == OPERATION.ACQUISITION_OF_RSRP.value: + nef_operations.get_ue_path_loss( + ip=variables.VARIABLES["NEF_IP"], + port=variables.VARIABLES["NEF_PORT"], + ue_supi=variables.VARIABLES["UE1_SUPI"], + token = variables.VARIABLES["AUTH_TOKEN"] + ) + return JSONResponse(content="Got UE Path Loss Information", status_code=200) + if operation_id == OPERATION.SERVING_CELL_INFO.value: - nef_operations.get_serving_cell_info( + nef_operations.get_rsrp_info( ip=variables.VARIABLES["NEF_IP"], port=variables.VARIABLES["NEF_PORT"], ue_supi=variables.VARIABLES["UE1_SUPI"], token = variables.VARIABLES["AUTH_TOKEN"] ) - return JSONResponse(content="Got UE Serving Cell Information", status_code=200) + return JSONResponse(content="Got UE RSRP Information", status_code=200) if operation_id == OPERATION.HANDOVER.value: nef_operations.get_ue_handover_event( diff --git a/src/nef_operations/operations.py b/src/nef_operations/operations.py index 70fbd85..095304a 100644 --- a/src/nef_operations/operations.py +++ b/src/nef_operations/operations.py @@ -212,6 +212,32 @@ def get_serving_cell_info(ip, port, ue_supi, token): ip, port, ue_supi, token ) +def get_rsrp_info(ip, port, ue_supi, token): + # To get the Serving Cell Info, we required to start a new UE Movement Loop + create_ue_movement_loop( + ip, port, ue_supi, token + ) + + url = f"http://{ip}:{port}/test/api/v1/UEs/{ue_supi}/rsrps" + + headers = {} + headers["accept"] = "application/json" + headers["Authorization"] = "Bearer " + token + headers["Content-Type"] = "application/json" + + response = requests.get( + url=url, + headers=headers, + ) + + print("Get UE Serving Cell Information", response.text) + if response.status_code not in [200, 201, 409]: + response.raise_for_status() + + stop_ue_movement_loop( + ip, port, ue_supi, token + ) + def get_ue_handover_event(ip, port, ue_supi, token): print("starting....") url = f"http://{ip}:{port}/test/api/v1/UEs/{ue_supi}/handovers" From 0c7a739b734d1a7c33f8b22be4f6ffdbb9c348b7 Mon Sep 17 00:00:00 2001 From: Eduardo Santos Date: Sun, 4 Feb 2024 14:53:17 +0000 Subject: [PATCH 06/21] Added documentation on how to run the miniAPI + minor fix --- Dockerfile.api | 2 +- README.md | 55 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/Dockerfile.api b/Dockerfile.api index 1082e7f..2f68316 100644 --- a/Dockerfile.api +++ b/Dockerfile.api @@ -1,7 +1,7 @@ FROM --platform=linux/amd64 python:3.9-slim RUN apt-get update && \ - apt-get install iperf3 hping3 iputils-ping net-tools -y + apt-get install iperf3 hping3 iputils-ping net-tools nmap -y COPY ./src /app/src COPY requirements.txt /app diff --git a/README.md b/README.md index 7da4352..6a1c48a 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,56 @@ ## How to run -1. Requirements -- docker -- docker-compose +1. To run the miniAPI and make it fully operational, we first need to install some OS-level dependencies: -2. Run ```bash -docker-compose up +sudo apt update + +# Install dependencies - iperf3, ss, ping, netstat, and nmap +sudo apt install iperf3 iproute2 iputils-ping net-tools nmap -y +``` + +2. Then, clone the repository: + +```bash +cd ~ +git clone https://github.com/5gasp/NetworkAppControl-MiniAPI.git +cd ~/NetworkAppControl-MiniAPI/ ``` + +3. Now, we need to install the miniAPI requirements. This can be done on the host or using a virtual environment. + +* On host: +```bash +sudo apt install python3-pip -y +pip3 install --upgrade pip +pip3 install -r requirements.txt +``` + +* Using venv: + +```bash +sudo apt install python3.10-venv -y +cd ~/NetworkAppControl-MiniAPI/ +python3 -m venv venv +source venv/bin/activate +pip install --upgrade pip +pip install -r requirements.txt +``` + +4. Finally, run the miniAPI: + +```bash +cd ~/NetworkAppControl-MiniAPI/src +python3 -m uvicorn main:app --host=0.0.0.0 --port=3001 +``` + +### Run using Docker + +1. Docker must be installed on the OS. You can find the official tutorial on how to install Docker [here](https://docs.docker.com/desktop/install/linux-install/). + +2. Run: +```bash +cd ~/NetworkAppControl-MiniAPI/ +docker compose up +``` \ No newline at end of file From 219697f1a076be3f2da70b6c23bcdd0534e73cee Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Sun, 4 Feb 2024 17:18:37 +0000 Subject: [PATCH 07/21] Updated README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6a1c48a..796e932 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ git clone https://github.com/5gasp/NetworkAppControl-MiniAPI.git cd ~/NetworkAppControl-MiniAPI/ ``` -3. Now, we need to install the miniAPI requirements. This can be done on the host or using a virtual environment. +3. Now, you need to install the miniAPI requirements. This can be done on the host or using a virtual environment. +The following commands may be used to install the miniAPI requirements in an Ubuntu 22.04. If you use a different OS, you may need to follow an alternative approach. * On host: ```bash @@ -31,7 +32,7 @@ pip3 install -r requirements.txt * Using venv: ```bash -sudo apt install python3.10-venv -y +sudo apt install python3.10-venv -y # Depending on your Ubuntu version, you may have to update this command cd ~/NetworkAppControl-MiniAPI/ python3 -m venv venv source venv/bin/activate From a71b2eccb7dd2bb86c24182ba5f60464b15a8d41 Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Sun, 4 Feb 2024 17:19:41 +0000 Subject: [PATCH 08/21] Updated the docker-compose file to expose port 5201 - the port used by iPerf3 server --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 511276c..c37221c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,4 +9,5 @@ services: context: . dockerfile: Dockerfile.api ports: - - "3001:3001" \ No newline at end of file + - "3001:3001" + - "5201:5201" \ No newline at end of file From c1d993a6c03864ef1ce176bd7ec00c00bc3b45d6 Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Thu, 15 Feb 2024 16:20:58 +0000 Subject: [PATCH 09/21] updated results files location --- src/main.py | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/main.py b/src/main.py index c263126..46b4a24 100644 --- a/src/main.py +++ b/src/main.py @@ -19,12 +19,10 @@ from aux.operations_ids import OPERATION from nef_operations import operations as nef_operations from performance_operations import operations as perf_operations -from fastapi.staticfiles import StaticFiles models.Base.metadata.create_all(bind=engine) app = FastAPI() -app.mount("/static", StaticFiles(directory="static"), name="static") RUNNING_PROCESSES = { OPERATION.MAX_CONNECTIONS.value: [], @@ -173,10 +171,10 @@ async def start_test( if operation_id == OPERATION.E2E_SINGLE_UE_LATENCY_AND_THROUGHPUT.value: # Delete old results file if os.path.exists( - f'./static/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}' + f'/tmp/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}' ): os.remove( - f'./static/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}' + f'/tmp/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}' ) error_message = None @@ -221,10 +219,10 @@ async def start_test( if operation_id == OPERATION.E2E_MULTIPLE_UE_LATENCY_AND_THROUGHPUT.value: # Delete old results file if os.path.exists( - f'./static/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}' + f'/tmp/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}' ): os.remove( - f'./static/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}' + f'/tmp/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}' ) error_message = None @@ -275,8 +273,8 @@ async def start_test( if operation_id == OPERATION.MAX_HOPS.value: # Delete old results file - if os.path.exists(f'./static/{variables.MAX_HOPS_RESULTS}'): - os.remove(f'./static/{variables.MAX_HOPS_RESULTS}') + if os.path.exists(f'/tmp/{variables.MAX_HOPS_RESULTS}'): + os.remove(f'/tmp/{variables.MAX_HOPS_RESULTS}') # Start the number of hops until target process max_hops_process = perf_operations.start_max_hops_computing( @@ -294,11 +292,11 @@ async def start_test( if operation_id == OPERATION.MAX_CONNECTIONS.value: # Delete old results file - if os.path.exists(f'./static/{variables.MAX_CONNECTIONS_RESULTS}'): - os.remove(f'./static/{variables.MAX_CONNECTIONS_RESULTS}') + if os.path.exists(f'/tmp/{variables.MAX_CONNECTIONS_RESULTS}'): + os.remove(f'/tmp/{variables.MAX_CONNECTIONS_RESULTS}') # Start the netstat loop netstat_process = perf_operations.start_netstat_command( - output_file=f'./static/{variables.MAX_CONNECTIONS_RESULTS}' + output_file=f'/tmp/{variables.MAX_CONNECTIONS_RESULTS}' ) # If we can start a monitoring process everything is ok @@ -335,15 +333,15 @@ async def start_test( if operation_id == OPERATION.NEF_CALLBACK_MAX_CONNECTIONS.value: # Delete old results file if os.path.exists( - f'./static/{variables.NEF_CALLBACK_MAX_CONNECTIONS_RESULTS}' + f'/tmp/{variables.NEF_CALLBACK_MAX_CONNECTIONS_RESULTS}' ): os.remove( - f'./static/{variables.NEF_CALLBACK_MAX_CONNECTIONS_RESULTS}' + f'/tmp/{variables.NEF_CALLBACK_MAX_CONNECTIONS_RESULTS}' ) # Start the netstat loop netstat_process = perf_operations.start_netstat_command( - output_file=f'./static/{variables.NEF_CALLBACK_MAX_CONNECTIONS_RESULTS}' + output_file=f'/tmp/{variables.NEF_CALLBACK_MAX_CONNECTIONS_RESULTS}' ) # If we can start a monitoring process everything is ok @@ -385,12 +383,12 @@ async def get_report(operation_id: str): if operation_id == OPERATION.MAX_CONNECTIONS.value: return FileResponse( - path=f'./static/{variables.MAX_CONNECTIONS_RESULTS}' + path=f'/tmp/{variables.MAX_CONNECTIONS_RESULTS}' ) if operation_id == OPERATION.NEF_CALLBACK_MAX_CONNECTIONS.value: return FileResponse( - path=f'./static/{variables.NEF_CALLBACK_MAX_CONNECTIONS_RESULTS}' + path=f'/tmp/{variables.NEF_CALLBACK_MAX_CONNECTIONS_RESULTS}' ) if operation_id in [ @@ -400,7 +398,7 @@ async def get_report(operation_id: str): # The test may still be running when the user requests its results try: with open( - f'./static/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}', + f'/tmp/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}', "r" ) as file: data = json.load(file) @@ -425,13 +423,13 @@ async def get_report(operation_id: str): if operation_id == OPERATION.MAX_HOPS.value: # The test may still be running when the user requests its results - if not os.path.exists(f'./static/{variables.MAX_HOPS_RESULTS}'): + if not os.path.exists(f'/tmp/{variables.MAX_HOPS_RESULTS}'): return JSONResponse( content=f"The Max Hops Performance Test is not finished yet!", status_code=404 ) - with open(f'./static/{variables.MAX_HOPS_RESULTS}', "r") as file: + with open(f'/tmp/{variables.MAX_HOPS_RESULTS}', "r") as file: data = json.load(file) return JSONResponse( content=data, From ed62cef97914fdbab77600796b46fb8122a7d2f5 Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Thu, 15 Feb 2024 16:31:15 +0000 Subject: [PATCH 10/21] updated results files location --- src/aux/ping_wrapper.py | 4 +- src/performance_operations/operations.py | 8 +- src/static/client_output_Def14Perf1.json | 222 +++++++++++++++++++++++ 3 files changed, 228 insertions(+), 6 deletions(-) create mode 100644 src/static/client_output_Def14Perf1.json diff --git a/src/aux/ping_wrapper.py b/src/aux/ping_wrapper.py index c3a7671..aadadc0 100644 --- a/src/aux/ping_wrapper.py +++ b/src/aux/ping_wrapper.py @@ -21,7 +21,7 @@ def run(self): self.transmitter.count = PING_TIMEOUT res = self.transmitter.ping() res = self.parser.parse(res).as_dict() - with open(f'./static/{variables.E2E_RTT_RESULTS}', 'w') as json_file: + with open(f'/tmp/{variables.E2E_RTT_RESULTS}', 'w') as json_file: json.dump(res, json_file) @@ -39,7 +39,7 @@ def run_hping(self): # Parse the output parsed_output = parse_hping_output(output) - with open(f'./static/{variables.E2E_RTT_RESULTS}', 'w') as json_file: + with open(f'/tmp/{variables.E2E_RTT_RESULTS}', 'w') as json_file: json.dump(parsed_output, json_file) except subprocess.CalledProcessError as e: print(f"Error running hping3: {e}") diff --git a/src/performance_operations/operations.py b/src/performance_operations/operations.py index c3d10a5..f2b785c 100644 --- a/src/performance_operations/operations.py +++ b/src/performance_operations/operations.py @@ -14,7 +14,7 @@ def create_process_group(): def start_iperf_client(target_ip, number_of_streams): command = f"iperf3 -t 5 -c {target_ip} -P {number_of_streams} -J > "\ - f"./static/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}" + f"/tmp/{variables.E2E_SINGLE_UE_THROUGHPUT_AND_LATENCY}" # Run the command as a background process process = subprocess.Popen( @@ -64,7 +64,7 @@ def start_ping(target_ip, runs): for run in range(runs): command = f"ping -c 5 {target_ip} | grep time= | "\ "awk '{print $7}' | cut -d'=' -f2 > "\ - f"./static/{variables.E2E_SINGLE_UE_LATENCY_BASE_NAME}_{i}.json" + f"/tmp/{variables.E2E_SINGLE_UE_LATENCY_BASE_NAME}_{i}.json" # Run the command as a background process process = subprocess.Popen( @@ -84,7 +84,7 @@ def compute_max_hops(target): if response == 0: print(f"Reached {target} with {ttl} hops!") with open( - f'./static/{variables.MAX_HOPS_RESULTS}', + f'/tmp/{variables.MAX_HOPS_RESULTS}', 'w' ) as json_file: json.dump( @@ -103,7 +103,7 @@ def compute_max_hops(target): # Finally, create an output file for the unsuccessful test cases with open( - f'./static/{variables.MAX_HOPS_RESULTS}', + f'/tmp/{variables.MAX_HOPS_RESULTS}', 'w' ) as json_file: json.dump( diff --git a/src/static/client_output_Def14Perf1.json b/src/static/client_output_Def14Perf1.json new file mode 100644 index 0000000..8d4f2af --- /dev/null +++ b/src/static/client_output_Def14Perf1.json @@ -0,0 +1,222 @@ +{ + "start": { + "connected": [{ + "socket": 5, + "local_host": "10.255.28.151", + "local_port": 39158, + "remote_host": "10.255.28.223", + "remote_port": 5201 + }], + "version": "iperf 3.7", + "system_info": "Linux mini-api-5gasp-tests 5.4.0-128-generic #144-Ubuntu SMP Tue Sep 20 11:00:04 UTC 2022 x86_64", + "timestamp": { + "time": "Thu, 15 Feb 2024 16:27:34 GMT", + "timesecs": 1708014454 + }, + "connecting_to": { + "host": "10.255.28.223", + "port": 5201 + }, + "cookie": "ydacyxpyi5upw4faclj2mc53545g6hmmgfiy", + "tcp_mss_default": 1448, + "sock_bufsize": 0, + "sndbuf_actual": 16384, + "rcvbuf_actual": 131072, + "test_start": { + "protocol": "TCP", + "num_streams": 1, + "blksize": 131072, + "omit": 0, + "duration": 5, + "bytes": 0, + "blocks": 0, + "reverse": 0, + "tos": 0 + } + }, + "intervals": [{ + "streams": [{ + "socket": 5, + "start": 0, + "end": 1.000088, + "seconds": 1.0000879764556885, + "bytes": 1437602144, + "bits_per_second": 11499805439.876293, + "retransmits": 0, + "snd_cwnd": 3305784, + "rtt": 1266, + "rttvar": 86, + "pmtu": 1500, + "omitted": false, + "sender": true + }], + "sum": { + "start": 0, + "end": 1.000088, + "seconds": 1.0000879764556885, + "bytes": 1437602144, + "bits_per_second": 11499805439.876293, + "retransmits": 0, + "omitted": false, + "sender": true + } + }, { + "streams": [{ + "socket": 5, + "start": 1.000088, + "end": 2.000092, + "seconds": 1.0000040531158447, + "bytes": 1490288640, + "bits_per_second": 11922260797.695856, + "retransmits": 0, + "snd_cwnd": 3305784, + "rtt": 933, + "rttvar": 189, + "pmtu": 1500, + "omitted": false, + "sender": true + }], + "sum": { + "start": 1.000088, + "end": 2.000092, + "seconds": 1.0000040531158447, + "bytes": 1490288640, + "bits_per_second": 11922260797.695856, + "retransmits": 0, + "omitted": false, + "sender": true + } + }, { + "streams": [{ + "socket": 5, + "start": 2.000092, + "end": 3.000078, + "seconds": 0.99998599290847778, + "bytes": 1546649600, + "bits_per_second": 12373370114.927637, + "retransmits": 0, + "snd_cwnd": 3305784, + "rtt": 745, + "rttvar": 95, + "pmtu": 1500, + "omitted": false, + "sender": true + }], + "sum": { + "start": 2.000092, + "end": 3.000078, + "seconds": 0.99998599290847778, + "bytes": 1546649600, + "bits_per_second": 12373370114.927637, + "retransmits": 0, + "omitted": false, + "sender": true + } + }, { + "streams": [{ + "socket": 5, + "start": 3.000078, + "end": 4.000079, + "seconds": 1.0000009536743164, + "bytes": 1612185600, + "bits_per_second": 12897472500.01173, + "retransmits": 0, + "snd_cwnd": 3305784, + "rtt": 925, + "rttvar": 169, + "pmtu": 1500, + "omitted": false, + "sender": true + }], + "sum": { + "start": 3.000078, + "end": 4.000079, + "seconds": 1.0000009536743164, + "bytes": 1612185600, + "bits_per_second": 12897472500.01173, + "retransmits": 0, + "omitted": false, + "sender": true + } + }, { + "streams": [{ + "socket": 5, + "start": 4.000079, + "end": 5.000113, + "seconds": 1.000033974647522, + "bytes": 1440481280, + "bits_per_second": 11523458734.55126, + "retransmits": 0, + "snd_cwnd": 3305784, + "rtt": 997, + "rttvar": 201, + "pmtu": 1500, + "omitted": false, + "sender": true + }], + "sum": { + "start": 4.000079, + "end": 5.000113, + "seconds": 1.000033974647522, + "bytes": 1440481280, + "bits_per_second": 11523458734.55126, + "retransmits": 0, + "omitted": false, + "sender": true + } + }], + "end": { + "streams": [{ + "sender": { + "socket": 5, + "start": 0, + "end": 5.000113, + "seconds": 5.000113, + "bytes": 7527207264, + "bits_per_second": 12043259444.736549, + "retransmits": 0, + "max_snd_cwnd": 3305784, + "max_rtt": 1266, + "min_rtt": 745, + "mean_rtt": 973, + "sender": true + }, + "receiver": { + "socket": 5, + "start": 0, + "end": 5.000922, + "seconds": 5.000113, + "bytes": 7525791376, + "bits_per_second": 12039046201.480446, + "sender": true + } + }], + "sum_sent": { + "start": 0, + "end": 5.000113, + "seconds": 5.000113, + "bytes": 7527207264, + "bits_per_second": 12043259444.736549, + "retransmits": 0, + "sender": true + }, + "sum_received": { + "start": 0, + "end": 5.000922, + "seconds": 5.000922, + "bytes": 7525791376, + "bits_per_second": 12039046201.480446, + "sender": true + }, + "cpu_utilization_percent": { + "host_total": 47.023792298730328, + "host_user": 1.1153866431884591, + "host_system": 45.908286731707435, + "remote_total": 42.132813119262266, + "remote_user": 2.8921654187445878, + "remote_system": 39.240726768417829 + }, + "sender_tcp_congestion": "cubic", + "receiver_tcp_congestion": "cubic" + } +} From 61a54de4136b376fe62d43775d678a839e662692 Mon Sep 17 00:00:00 2001 From: Rafael Direito Date: Thu, 15 Feb 2024 16:38:23 +0000 Subject: [PATCH 11/21] removed results file --- src/static/client_output_Def14Perf1.json | 222 ----------------------- 1 file changed, 222 deletions(-) delete mode 100644 src/static/client_output_Def14Perf1.json diff --git a/src/static/client_output_Def14Perf1.json b/src/static/client_output_Def14Perf1.json deleted file mode 100644 index 8d4f2af..0000000 --- a/src/static/client_output_Def14Perf1.json +++ /dev/null @@ -1,222 +0,0 @@ -{ - "start": { - "connected": [{ - "socket": 5, - "local_host": "10.255.28.151", - "local_port": 39158, - "remote_host": "10.255.28.223", - "remote_port": 5201 - }], - "version": "iperf 3.7", - "system_info": "Linux mini-api-5gasp-tests 5.4.0-128-generic #144-Ubuntu SMP Tue Sep 20 11:00:04 UTC 2022 x86_64", - "timestamp": { - "time": "Thu, 15 Feb 2024 16:27:34 GMT", - "timesecs": 1708014454 - }, - "connecting_to": { - "host": "10.255.28.223", - "port": 5201 - }, - "cookie": "ydacyxpyi5upw4faclj2mc53545g6hmmgfiy", - "tcp_mss_default": 1448, - "sock_bufsize": 0, - "sndbuf_actual": 16384, - "rcvbuf_actual": 131072, - "test_start": { - "protocol": "TCP", - "num_streams": 1, - "blksize": 131072, - "omit": 0, - "duration": 5, - "bytes": 0, - "blocks": 0, - "reverse": 0, - "tos": 0 - } - }, - "intervals": [{ - "streams": [{ - "socket": 5, - "start": 0, - "end": 1.000088, - "seconds": 1.0000879764556885, - "bytes": 1437602144, - "bits_per_second": 11499805439.876293, - "retransmits": 0, - "snd_cwnd": 3305784, - "rtt": 1266, - "rttvar": 86, - "pmtu": 1500, - "omitted": false, - "sender": true - }], - "sum": { - "start": 0, - "end": 1.000088, - "seconds": 1.0000879764556885, - "bytes": 1437602144, - "bits_per_second": 11499805439.876293, - "retransmits": 0, - "omitted": false, - "sender": true - } - }, { - "streams": [{ - "socket": 5, - "start": 1.000088, - "end": 2.000092, - "seconds": 1.0000040531158447, - "bytes": 1490288640, - "bits_per_second": 11922260797.695856, - "retransmits": 0, - "snd_cwnd": 3305784, - "rtt": 933, - "rttvar": 189, - "pmtu": 1500, - "omitted": false, - "sender": true - }], - "sum": { - "start": 1.000088, - "end": 2.000092, - "seconds": 1.0000040531158447, - "bytes": 1490288640, - "bits_per_second": 11922260797.695856, - "retransmits": 0, - "omitted": false, - "sender": true - } - }, { - "streams": [{ - "socket": 5, - "start": 2.000092, - "end": 3.000078, - "seconds": 0.99998599290847778, - "bytes": 1546649600, - "bits_per_second": 12373370114.927637, - "retransmits": 0, - "snd_cwnd": 3305784, - "rtt": 745, - "rttvar": 95, - "pmtu": 1500, - "omitted": false, - "sender": true - }], - "sum": { - "start": 2.000092, - "end": 3.000078, - "seconds": 0.99998599290847778, - "bytes": 1546649600, - "bits_per_second": 12373370114.927637, - "retransmits": 0, - "omitted": false, - "sender": true - } - }, { - "streams": [{ - "socket": 5, - "start": 3.000078, - "end": 4.000079, - "seconds": 1.0000009536743164, - "bytes": 1612185600, - "bits_per_second": 12897472500.01173, - "retransmits": 0, - "snd_cwnd": 3305784, - "rtt": 925, - "rttvar": 169, - "pmtu": 1500, - "omitted": false, - "sender": true - }], - "sum": { - "start": 3.000078, - "end": 4.000079, - "seconds": 1.0000009536743164, - "bytes": 1612185600, - "bits_per_second": 12897472500.01173, - "retransmits": 0, - "omitted": false, - "sender": true - } - }, { - "streams": [{ - "socket": 5, - "start": 4.000079, - "end": 5.000113, - "seconds": 1.000033974647522, - "bytes": 1440481280, - "bits_per_second": 11523458734.55126, - "retransmits": 0, - "snd_cwnd": 3305784, - "rtt": 997, - "rttvar": 201, - "pmtu": 1500, - "omitted": false, - "sender": true - }], - "sum": { - "start": 4.000079, - "end": 5.000113, - "seconds": 1.000033974647522, - "bytes": 1440481280, - "bits_per_second": 11523458734.55126, - "retransmits": 0, - "omitted": false, - "sender": true - } - }], - "end": { - "streams": [{ - "sender": { - "socket": 5, - "start": 0, - "end": 5.000113, - "seconds": 5.000113, - "bytes": 7527207264, - "bits_per_second": 12043259444.736549, - "retransmits": 0, - "max_snd_cwnd": 3305784, - "max_rtt": 1266, - "min_rtt": 745, - "mean_rtt": 973, - "sender": true - }, - "receiver": { - "socket": 5, - "start": 0, - "end": 5.000922, - "seconds": 5.000113, - "bytes": 7525791376, - "bits_per_second": 12039046201.480446, - "sender": true - } - }], - "sum_sent": { - "start": 0, - "end": 5.000113, - "seconds": 5.000113, - "bytes": 7527207264, - "bits_per_second": 12043259444.736549, - "retransmits": 0, - "sender": true - }, - "sum_received": { - "start": 0, - "end": 5.000922, - "seconds": 5.000922, - "bytes": 7525791376, - "bits_per_second": 12039046201.480446, - "sender": true - }, - "cpu_utilization_percent": { - "host_total": 47.023792298730328, - "host_user": 1.1153866431884591, - "host_system": 45.908286731707435, - "remote_total": 42.132813119262266, - "remote_user": 2.8921654187445878, - "remote_system": 39.240726768417829 - }, - "sender_tcp_congestion": "cubic", - "receiver_tcp_congestion": "cubic" - } -} From e5a3c17d9c77bf31461d0c2fd61ea62f17a595bb Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Thu, 4 Jan 2024 14:54:58 +0100 Subject: [PATCH 12/21] added __init.py__ to performance_operations/ --- src/performance_operations/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/performance_operations/__init__.py diff --git a/src/performance_operations/__init__.py b/src/performance_operations/__init__.py new file mode 100644 index 0000000..e69de29 From 8cb3b97900a1f9a823971638b6287afbf8ffda6e Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Thu, 4 Jan 2024 14:59:32 +0100 Subject: [PATCH 13/21] created miniapi/ and populated it with main.py, static/ and variable.json --- src/{ => miniapi}/main.py | 0 src/{ => miniapi}/static/.gitkeep | 0 src/{ => miniapi}/variables.json | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/{ => miniapi}/main.py (100%) rename src/{ => miniapi}/static/.gitkeep (100%) rename src/{ => miniapi}/variables.json (100%) diff --git a/src/main.py b/src/miniapi/main.py similarity index 100% rename from src/main.py rename to src/miniapi/main.py diff --git a/src/static/.gitkeep b/src/miniapi/static/.gitkeep similarity index 100% rename from src/static/.gitkeep rename to src/miniapi/static/.gitkeep diff --git a/src/variables.json b/src/miniapi/variables.json similarity index 100% rename from src/variables.json rename to src/miniapi/variables.json From d9fc16f05c26d44a38372217caab00c069c85699 Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Fri, 5 Jan 2024 15:12:39 +0100 Subject: [PATCH 14/21] __init__.py for miniapi module --- src/miniapi/__init__.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/miniapi/__init__.py diff --git a/src/miniapi/__init__.py b/src/miniapi/__init__.py new file mode 100644 index 0000000..715a399 --- /dev/null +++ b/src/miniapi/__init__.py @@ -0,0 +1,19 @@ +def run(): + import uvicorn + import argparse + + parser = argparse.ArgumentParser( + 'Run the MiniAPI server') + parser.add_argument('--bind', + '-b', + type=str, + default='127.0.0.1', + help='interface to bind to') + parser.add_argument('--port', + '-p', + type=int, + default=3001, + help='Port number of the Rx AtBridge service on the server') + args = parser.parse_args() + + uvicorn.run("miniapi.main:app", host=args.bind, port=args.port, reload=False) From e024096ba6d2aced2af022f0433ce38e6fb7ac12 Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Fri, 5 Jan 2024 09:59:30 +0100 Subject: [PATCH 15/21] added setup.py --- setup.py | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 setup.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..2b43bed --- /dev/null +++ b/setup.py @@ -0,0 +1,186 @@ +"""A setuptools based setup module. + +See: +https://packaging.python.org/guides/distributing-packages-using-setuptools/ +https://github.com/pypa/sampleproject +""" + +# Always prefer setuptools over distutils +from setuptools import setup, find_packages +import pathlib + +here = pathlib.Path(__file__).parent.resolve() + +# Get the long description from the README file +long_description = (here / "README.md").read_text(encoding="utf-8") + +# Arguments marked as "Required" below must be included for upload to PyPI. +# Fields marked as "Optional" may be commented out. + +setup( + # This is the name of your project. The first time you publish this + # package, this name will be registered for you. It will determine how + # users can install this project, e.g.: + # + # $ pip install sampleproject + # + # And where it will live on PyPI: https://pypi.org/project/sampleproject/ + # + # There are some restrictions on what makes a valid project name + # specification here: + # https://packaging.python.org/specifications/core-metadata/#name + name="miniapi", # Required + # Versions should comply with PEP 440: + # https://www.python.org/dev/peps/pep-0440/ + # + # For a discussion on single-sourcing the version across setup.py and the + # project code, see + # https://packaging.python.org/guides/single-sourcing-package-version/ + version="0.0.1", # Required + # This is a one-line description or tagline of what your project does. This + # corresponds to the "Summary" metadata field: + # https://packaging.python.org/specifications/core-metadata/#summary + description="API to trigger the NEF tests of the 5GASP Project", # Optional + # This is an optional longer description of your project that represents + # the body of text which users will see when they visit PyPI. + # + # Often, this is the same as your README, so you can just read it in from + # that file directly (as we have already done above) + # + # This field corresponds to the "Description" metadata field: + # https://packaging.python.org/specifications/core-metadata/#description-optional + long_description=long_description, # Optional + # Denotes that our long_description is in Markdown; valid values are + # text/plain, text/x-rst, and text/markdown + # + # Optional if long_description is written in reStructuredText (rst) but + # required for plain-text or Markdown; if unspecified, "applications should + # attempt to render [the long_description] as text/x-rst; charset=UTF-8 and + # fall back to text/plain if it is not valid rst" (see link below) + # + # This field corresponds to the "Description-Content-Type" metadata field: + # https://packaging.python.org/specifications/core-metadata/#description-content-type-optional + long_description_content_type="text/markdown", # Optional (see note above) + # This should be a valid link to your project's main homepage. + # + # This field corresponds to the "Home-Page" metadata field: + # https://packaging.python.org/specifications/core-metadata/#home-page-optional + url="https://github.com/5gasp/NetworkAppControl-MiniAPI", # Optional + # This should be your name or the name of the organization which owns the + # project. + # TODO: Set the authors' names + #author="A. Random Developer", # Optional + # This should be a valid email address corresponding to the author listed + # above. + # TODO: Set the authors' emails + #author_email="author@example.com", # Optional + # Classifiers help users find your project by categorizing it. + # + # For a list of valid classifiers, see https://pypi.org/classifiers/ + classifiers=[ # Optional + # How mature is this project? Common values are + # 3 - Alpha + # 4 - Beta + # 5 - Production/Stable + "Development Status :: 4 - Alpha", + # Indicate who your project is intended for + "Intended Audience :: Developers", + #"Topic :: Software Development :: Build Tools", + # Pick your license as you wish + "License :: OSI Approved :: GPLv3 License", + # Specify the Python versions you support here. In particular, ensure + # that you indicate you support Python 3. These classifiers are *not* + # checked by 'pip install'. See instead 'python_requires' below. + "Programming Language :: Python :: 3", + # "Programming Language :: Python :: 3.6", + # "Programming Language :: Python :: 3.7", + # "Programming Language :: Python :: 3.8", + ], + # This field adds keywords for your project which will appear on the + # project page. What does your project relate to? + # + # Note that this is a list of additional keywords, separated + # by commas, to be used to assist searching for the distribution in a + # larger catalog. + keywords="5GASP, MiniAPI, NEF", # Optional + # When your source code is in a subdirectory under the project root, e.g. + # `src/`, it is necessary to specify the `package_dir` argument. + package_dir={"": "src"}, # Optional + # You can just specify package directories manually here if your project is + # simple. Or you can use find_packages(). + # + # Alternatively, if you just want to distribute a single Python file, use + # the `py_modules` argument instead as follows, which will expect a file + # called `my_module.py` to exist: + # + # py_modules=["my_module"], + # + packages=find_packages(where="src"), # Required + # Specify which Python versions you support. In contrast to the + # 'Programming Language' classifiers above, 'pip install' will check this + # and refuse to install the project if the version does not match. See + # https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires + # TODO: Verify compatible versions + python_requires=">=3.5, <4", + # This field lists other packages that your project depends on to run. + # Any package you put here will be installed by pip when your project is + # installed, so they must be valid existing projects. + # + # For an analysis of "install_requires" vs pip's requirements files see: + # https://packaging.python.org/discussions/install-requires-vs-requirements/ + # TODO: Verify compatible versions + # install_requires=["peppercorn"], # Optional + install_requires=[ + "fastapi==0.95.2", + "uvicorn==0.22.0", + "pydantic==2.5.2", + "pydantic_core==2.14.5", + "sqlalchemy==2.0.15", + "requests==2.31.0", + "urllib3==1.26.6", + "pingparsing==1.4.1", + "SQLAlchemy==2.0.23", + ], + # List additional groups of dependencies here (e.g. development + # dependencies). Users will be able to install these using the "extras" + # syntax, for example: + # + # $ pip install sampleproject[dev] + # + # Similar to `install_requires` above, these must be valid existing + # projects. + extras_require={ # Optional + "dev": ["check-manifest"], + "test": ["coverage"], + }, + # If there are data files included in your packages that need to be + # installed, specify them here. + package_data={ # Optional + "sample": ["package_data.dat"], + }, + # Entry points. The following would provide a command called `sample` which + # executes the function `main` from this package when invoked: + entry_points={ # Optional + "console_scripts": [ + "miniapi=miniapi:run", + ], + }, + # entry_points={"console_scripts": ["fastapi-csv=fastapi_csv.cli:typer_app"],}, + # List additional URLs that are relevant to your project as a dict. + # + # This field corresponds to the "Project-URL" metadata fields: + # https://packaging.python.org/specifications/core-metadata/#project-url-multiple-use + # + # Examples listed include a pattern for specifying where the package tracks + # issues, where the source is hosted, where to say thanks to the package + # maintainers, and where to support the project financially. The key is + # what's used to render the link text on PyPI. + # TODO: Verify compatible versions + project_urls={ # Optional + # "Bug Reports": "https://github.com/pypa/sampleproject/issues", + # "Funding": "https://donate.pypi.org", + # "Say Thanks!": "http://saythanks.io/to/example", + "Source": "https://github.com/5gasp/NetworkAppControl-MiniAPI", + }, +) + From c3921a132b978cbcf9e8ce7460357923beb40835 Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Fri, 5 Jan 2024 10:17:42 +0100 Subject: [PATCH 16/21] added debian/ with minimal content --- debian/changelog | 5 +++++ debian/compat | 1 + debian/control | 13 +++++++++++++ debian/miniapi.service | 10 ++++++++++ debian/postinst | 7 +++++++ debian/rules | 11 +++++++++++ 6 files changed, 47 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/miniapi.service create mode 100644 debian/postinst create mode 100755 debian/rules diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..89903b3 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +miniapi (0.0.1) unstable; urgency=low + + * b'ded7578 Minor fix\n' + + -- Christophe COUTURIER Sat, 30 Dec 2023 19:47:56 +0000 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..9d60796 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +11 \ No newline at end of file diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..d5cc0b6 --- /dev/null +++ b/debian/control @@ -0,0 +1,13 @@ +Source: miniapi +Section: python +Priority: extra +Maintainer: None +Build-Depends: debhelper (>= 11~), dh-python, python3, python3-setuptools, python3-pydantic +Standards-Version: 3.9.5 + +Package: miniapi +Architecture: any +Pre-Depends: dpkg (>= 1.16.1), python3-minimal, ${misc:Pre-Depends} +Depends: ${python3:Depends}, ${misc:Depends}, python3-pip +Description: API to trigger the NEF tests of the 5GASP Project + API to trigger the NEF tests of the 5GASP Project diff --git a/debian/miniapi.service b/debian/miniapi.service new file mode 100644 index 0000000..2733b3e --- /dev/null +++ b/debian/miniapi.service @@ -0,0 +1,10 @@ +[Unit] +Description=5GASP MiniAPI +After=network-online.target + +[Service] +Type=simple +ExecStart=/usr/bin/miniapi -b 0.0.0.0 -p 3001 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 0000000..579b5db --- /dev/null +++ b/debian/postinst @@ -0,0 +1,7 @@ +#! /usr/bin/env bash + +### This is the uggly way... +# It would be more debian spirit compliant to create debian packages +# to install those packages and to put these packages as dependecies of +# our own package. +python3 -m pip install sqlalchemy pingparsing pydantic_core==2.14.5 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..9916443 --- /dev/null +++ b/debian/rules @@ -0,0 +1,11 @@ +#!/usr/bin/make -f + +#export DH_VERBOSE = 1 +export PYBUILD_NAME = miniapi +export PYBUILD_DISABLE_python2=1 + +override_dh_builddeb: + dh_builddeb -- -Zgzip # for old debian version that do not support zstd compression + +%: + dh $@ --with python3 --buildsystem=pybuild From 7f0a29e1c819bcb471548b3263ad493f5372958c Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Fri, 5 Jan 2024 10:36:09 +0100 Subject: [PATCH 17/21] .pybuild/ in .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index f23d157..a8d6e8b 100644 --- a/.gitignore +++ b/.gitignore @@ -267,3 +267,6 @@ $RECYCLE.BIN/ *.db # End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,python,venv,macos,windows + +# For buildpackage: +.pybuild/ From 94345dbdd319b7342b2e23a21b1adf70c2070b0f Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Mon, 8 Jan 2024 15:52:35 +0100 Subject: [PATCH 18/21] changelog for v0.0.2 (upstream c775644) --- debian/changelog | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 89903b3..f74a926 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -miniapi (0.0.1) unstable; urgency=low +miniapi (0.0.2) unstable; urgency=low - * b'ded7578 Minor fix\n' + * Integration of upstream version c775644 (Sat Jan 6 12:05:14 2024) - -- Christophe COUTURIER Sat, 30 Dec 2023 19:47:56 +0000 + -- Christophe COUTURIER Fri, 5 Jan 2024 10:36:09 +0100 \ No newline at end of file From f128f5566329b27a7b36021286c568129f08980a Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Mon, 15 Jan 2024 17:10:10 +0100 Subject: [PATCH 19/21] added README-Debian-packaging.md --- README-Debian-packaging.md | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 README-Debian-packaging.md diff --git a/README-Debian-packaging.md b/README-Debian-packaging.md new file mode 100644 index 0000000..8127b47 --- /dev/null +++ b/README-Debian-packaging.md @@ -0,0 +1,59 @@ +# Debian Packaging of NetworkAppControl-MiniAPI + +This file explains how to package the MiniAPI as a Debian package. + +According to the [Debian packaging guidelines](https://wiki.debian.org/GitPackaging): +- The upstream code of the project lies in the `upstream/latest` + branch. In our case, we'll use the `main` branch for that. +- The packaging code lies in the `debian/latest` branch. In this branch, + - The `src/` directory contains the source code from upstream with + slight modifications to make it easier to package. Basically: + - The main code of MiniAPI is turned into a python module + - We add an `__init__.py` to the `miniapi` module to let start the + MiniAPI from the command line. + - We use the python setup tools to package the python code. So that + debian helper (or dpkg-build) can easily build the package. + - The `debian/` directory contains the files to set up the deb + package (including the systemctl files to start the miniAPI as a + linux daemon) + + + +## Instal git-buildpackage and other dependencies for the build phase + +```sh +sudo apt install -y git-buildpackage +sudo apt install -y dh-python python3-setuptools python3-pydantic +``` + + +## Run git-buildpackage + +*Note:* By default, git-buildpackage will try to sign the package with +the author's GPG key. For that: +* Either edit the author email in the `debian/changelog` of the + `debian/latest` branch. This suppose that you have a GPG key for this + email already installed on your system... +* Or pass the `-uc -us` parameters to git-buildpackage to skip the + signature . + +```sh +git checkout debian/latest +gbp buildpackage --git-ignore-branch --git-ignore-new +``` +The compilation results (`.deb`, `.tgz`, etc) will be placed in the +parent folder. This can be changed with the `--git-export-dir=XXXX` +parameter. + + +## Rebasing when new version is available + +```sh +# Retrieve the last upstream version +git checkout main +git pull + +# Rebase the debian/latest on main +git checkout debian/latest +git rebase main +``` \ No newline at end of file From 11bba46f8194a0096a9daf1cc4db9efe8288214c Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Fri, 16 Feb 2024 16:03:46 +0100 Subject: [PATCH 20/21] deb package v0.0.3 (main: 7465ff7) --- debian/changelog | 7 +++++++ debian/control | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index f74a926..ae87cc8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +miniapi (0.0.3) unstable; urgency=low + + * Integration of upstream version 7465ff7 (Mon Feb 5 09:00:04 2024) + * Added dependencies: iperf3, iproute2, iputils-ping, net-tools, nmap + + -- Christophe COUTURIER Wed, 14 Feb 2024 14:58:09 +0100 + miniapi (0.0.2) unstable; urgency=low * Integration of upstream version c775644 (Sat Jan 6 12:05:14 2024) diff --git a/debian/control b/debian/control index d5cc0b6..9df163c 100644 --- a/debian/control +++ b/debian/control @@ -8,6 +8,6 @@ Standards-Version: 3.9.5 Package: miniapi Architecture: any Pre-Depends: dpkg (>= 1.16.1), python3-minimal, ${misc:Pre-Depends} -Depends: ${python3:Depends}, ${misc:Depends}, python3-pip +Depends: ${python3:Depends}, ${misc:Depends}, python3-pip, iperf3, iproute2, iputils-ping, net-tools, nmap Description: API to trigger the NEF tests of the 5GASP Project API to trigger the NEF tests of the 5GASP Project From db685d3cb16dc152a02924ba10a0be7ae6f765b8 Mon Sep 17 00:00:00 2001 From: Christophe COUTURIER Date: Fri, 16 Feb 2024 16:39:04 +0100 Subject: [PATCH 21/21] deb package v0.0.4 (main: ff41b2e) --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index ae87cc8..f315665 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +miniapi (0.0.4) unstable; urgency=low + + * Integration of upstream version ff41b2e (Thu Feb 15 16:40:27 2024) + + -- Christophe COUTURIER Thu, 15 Feb 2024 20:54:00 +0100 + miniapi (0.0.3) unstable; urgency=low * Integration of upstream version 7465ff7 (Mon Feb 5 09:00:04 2024)