Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/8653 fix quickstart failures #141

Merged
merged 91 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
0502806
release hacks
sanderr Jan 17, 2025
2442ec8
default
sanderr Jan 17, 2025
d209614
fix
sanderr Jan 17, 2025
0d31ffe
no sudo
sanderr Jan 17, 2025
64993d4
fixes
sanderr Jan 17, 2025
2228169
Revert "fixes"
sanderr Jan 17, 2025
338e59b
removed outdated pip url
sanderr Jan 17, 2025
ebbef80
Revert "removed outdated pip url"
sanderr Jan 17, 2025
a43f622
setup.sh
sanderr Jan 17, 2025
3fb0435
async fix
sanderr Jan 17, 2025
c5f8fdf
OSS fixes
sanderr Jan 17, 2025
dec3585
attempt
sanderr Jan 17, 2025
86b1da5
Revert "attempt"
sanderr Jan 17, 2025
d7fda7a
Reapply "attempt"
sanderr Jan 17, 2025
75d0094
Revert "Reapply "attempt""
sanderr Jan 17, 2025
d616ff0
Reapply "Reapply "attempt""
sanderr Jan 17, 2025
2cf773b
wait
sanderr Jan 17, 2025
ce14f99
wip
Hugo-Inmanta Jan 20, 2025
77e2640
wip
Hugo-Inmanta Jan 20, 2025
3eef27b
wip
Hugo-Inmanta Jan 20, 2025
6c04519
wip
Hugo-Inmanta Jan 20, 2025
77fe8a1
wip
Hugo-Inmanta Jan 20, 2025
9df5444
wip
Hugo-Inmanta Jan 21, 2025
5fef7b9
wip
Hugo-Inmanta Jan 21, 2025
49a048d
wip
Hugo-Inmanta Jan 21, 2025
74e3771
wip
Hugo-Inmanta Jan 22, 2025
a0c8155
wip
Hugo-Inmanta Jan 22, 2025
f8fd8aa
wip
Hugo-Inmanta Jan 22, 2025
19607f9
wip
Hugo-Inmanta Jan 22, 2025
5248dd3
wip
Hugo-Inmanta Jan 22, 2025
1a13c52
wip
Hugo-Inmanta Jan 22, 2025
acd7ecc
wip
Hugo-Inmanta Jan 22, 2025
fff15b9
wip
Hugo-Inmanta Jan 22, 2025
1b1f3d5
wip
Hugo-Inmanta Jan 22, 2025
2626de8
wip
Hugo-Inmanta Jan 23, 2025
568aa51
wip
Hugo-Inmanta Jan 23, 2025
820da0a
wip
Hugo-Inmanta Jan 23, 2025
0ed5c7d
wip
Hugo-Inmanta Jan 23, 2025
cd17924
wip
Hugo-Inmanta Jan 23, 2025
3c22224
wip
Hugo-Inmanta Jan 23, 2025
8cdfbdf
wip
Hugo-Inmanta Jan 23, 2025
e385394
wip
Hugo-Inmanta Jan 23, 2025
94a184c
wip
Hugo-Inmanta Jan 23, 2025
f788e84
wip
Hugo-Inmanta Jan 23, 2025
112da96
wip
Hugo-Inmanta Jan 23, 2025
0998da5
wip
Hugo-Inmanta Jan 23, 2025
1964e42
wip
Hugo-Inmanta Jan 23, 2025
d10df94
wip
Hugo-Inmanta Jan 23, 2025
d308b0a
wip
Hugo-Inmanta Jan 23, 2025
773f3bd
wip
Hugo-Inmanta Jan 23, 2025
624358a
wip
Hugo-Inmanta Jan 23, 2025
217f7dc
wip
Hugo-Inmanta Jan 23, 2025
bef1d80
wip
Hugo-Inmanta Jan 23, 2025
bfdb574
wip
Hugo-Inmanta Jan 23, 2025
c42124b
wip
Hugo-Inmanta Jan 23, 2025
5a9e765
wip
Hugo-Inmanta Jan 23, 2025
227b896
wip
Hugo-Inmanta Jan 23, 2025
f57c3c9
wip
Hugo-Inmanta Jan 23, 2025
4d1b2fb
wip
Hugo-Inmanta Jan 23, 2025
70ace1e
wip
Hugo-Inmanta Jan 23, 2025
4f0d32c
wip
Hugo-Inmanta Jan 23, 2025
b61a268
wip
Hugo-Inmanta Jan 23, 2025
f81c189
wip
Hugo-Inmanta Jan 23, 2025
3dfebe2
wip
Hugo-Inmanta Jan 23, 2025
d95f1ff
wip
Hugo-Inmanta Jan 23, 2025
54e9745
wip
Hugo-Inmanta Jan 23, 2025
6879b9b
wip
Hugo-Inmanta Jan 23, 2025
72f5130
wip
Hugo-Inmanta Jan 23, 2025
9514f0a
wip
Hugo-Inmanta Jan 23, 2025
5e0beb1
wip
Hugo-Inmanta Jan 23, 2025
81701dd
wip
Hugo-Inmanta Jan 24, 2025
d1e3752
cleanup
Hugo-Inmanta Jan 24, 2025
88618d0
fix
Hugo-Inmanta Jan 24, 2025
601368d
remove code dir binding from topology file
Hugo-Inmanta Jan 30, 2025
650b6a7
refactor dev version logic
Hugo-Inmanta Jan 30, 2025
2062d8f
wip
Hugo-Inmanta Jan 31, 2025
64f2fed
remove redundant workdir argument
Hugo-Inmanta Jan 31, 2025
b7e514b
wip
Hugo-Inmanta Jan 31, 2025
ee0c4bd
wip
Hugo-Inmanta Jan 31, 2025
31cc1c4
wip
Hugo-Inmanta Jan 31, 2025
0499788
wip
Hugo-Inmanta Jan 31, 2025
4b56cd3
wip
Hugo-Inmanta Jan 31, 2025
d527eea
wip
Hugo-Inmanta Jan 31, 2025
04f4ac7
add log archiving back
Hugo-Inmanta Feb 3, 2025
341458f
remove setup.sh
Hugo-Inmanta Feb 3, 2025
402ae54
wip
Hugo-Inmanta Feb 3, 2025
c8fb9dc
wip
Hugo-Inmanta Feb 3, 2025
12f97eb
wip
Hugo-Inmanta Feb 3, 2025
051719d
wip
Hugo-Inmanta Feb 4, 2025
545d00c
fix brittle logic
Hugo-Inmanta Feb 4, 2025
0ac01c7
revert unbuffered option removal
Hugo-Inmanta Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Networking/SR Linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ A:spine#

## Applying the examples

In order to run the provided examples, you need to prepare a development environment using **Python 3.9** by creating a `Python virtual environment` and installing the required packages:
In order to run the provided examples, you need to prepare a development environment using **Python 3.12** by creating a `Python virtual environment` and installing the required packages:

Check the current Python version:

```bash
$ python3 -V
Python 3.9.10
$ python3 --version
Python 3.12.8
```

Create a virtual environment and install `Inmanta`:
Expand Down
20 changes: 14 additions & 6 deletions Networking/SR Linux/ci/Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**@
* Updates the topology.yml so that the lab environement
* Updates the topology.yml so that the lab environment
* uses the same version as the specified Python package of the OSS product
*/
def update_topology() {
Expand All @@ -22,7 +22,7 @@ def convert_python_version_to_docker_tag() {
def year = matcher.group(1)
def minor = matcher.group(2)
def patch = matcher.group(3) ?: ""
def rc = matcher.group(4) ?: ""
def rc = matcher.group(4) ?: ""
// Constructing the formatted version
def formattedVersion = "${year}.${minor}${patch}"
if (rc) {
Expand Down Expand Up @@ -82,8 +82,8 @@ pipeline {
sudo docker pull ghcr.io/nokia/srlinux:latest
sudo clab deploy -t containerlab/topology.yml --reconfigure
# Get python version used to build the container
python_version=$(docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' clab-srlinux-inmanta-server | grep -P "^PYTHON_VERSION=" | sed 's/[^=]*=//')
python_version=$(docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' clab-srlinux-inmanta-server | grep -P "^PYTHON_VERSION=" | sed 's/[^=]*=//' | cut -d . -f 1-2)

if [ -n "$version" ]; then
if [[ $version == *dev ]]; then
constraint="~=${version::-3}.0.dev"
Expand All @@ -97,8 +97,16 @@ pipeline {
# Leave constraint undefined if version is not defined
constraint=""
fi

ci/do_test_deployment_and_verify.sh ${python_version} ${constraint}

# Create python environment
python${python_version} -m venv venv

venv/bin/pip install -U pip

# install inmanta-dev-dependencies[extension] rather than pytest-inmanta-extensions directly to
# help pip find matching candidates (see inmanta/infra-tickets#180)
venv/bin/pip install "inmanta${constraint}" inmanta-dev-dependencies[extension]
venv/bin/python -u ci/do_test_deployment_and_verify.py
arnaudsjs marked this conversation as resolved.
Show resolved Hide resolved
'''
}
}
Expand Down
211 changes: 211 additions & 0 deletions Networking/SR Linux/ci/do_test_deployment_and_verify.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to additionally request review from someone of the solutions team for this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have anything specific in mind to pay attention to ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just whether this is a good approach to validate that everything was deployed. But looking it over once more, I don't think it necessarily has to be someone from the solutions team. I would add a second reviewer, but rather for the full PR, not just this file.

Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
import asyncio
import functools
import logging
import subprocess
import sys
import time

from inmanta.config import Config
from inmanta.protocol.endpoints import Client
from inmanta_tests.utils import retry_limited
from packaging.version import Version

logging.basicConfig(level=logging.DEBUG)

HOST = ("172.30.0.100", "57400")

INTERFACE_PATH = "srl_nokia-interfaces:interface"
NS_INSTANCE_PATH = "srl_nokia-network-instance:network-instance"
OSPF_PATH = "srl_nokia-ospf:ospf"


async def main():
try:
await do_deploy_and_validate_config()
finally:
fetch_logs()


async def do_deploy_and_validate_config():

# Create client

Config.set("client_rest_transport", "host", "172.30.0.3")
Config.set("client_rest_transport", "port", "8888")
client = Client(name="client")

async def is_inmanta_server_up() -> bool:
status = await client.get_server_status()
if status.code == 200:
orchestator_version = Version(status.result["data"]["version"])
print(f"Orchestrator version: {orchestator_version}.")
return True
return False

print("Waiting until the Inmanta server has finished starting...")
await retry_limited(is_inmanta_server_up, timeout=60, interval=1)

print("Creating project env-test")
result = await client.create_project("env-test")
assert result.code == 200
project_id = result.result["project"]["id"]

print("Creating environment dev in project env-test")
result = await client.create_environment(project_id=project_id, name="dev")
assert result.code == 200
environment_id = result.result["environment"]["id"]

async def install_project() -> None:
cmd = [
sys.executable,
"-m",
"inmanta.app",
"-vvv",
"project",
"install",
"--host",
"172.30.0.3",
]
subprocess.check_call(cmd)

async def deploy_and_check(file: str, expected_resources: set[str]):
"""
Export a given .cf file and check that the deployed
resources are as expected.
"""
print(f"Checking successful deploy of {file}")
cmd = [
sys.executable,
"-m",
"inmanta.app",
"-vvv",
"export",
"-f",
file,
"--host",
"172.30.0.3",
"-e",
environment_id,
]
subprocess.check_call(cmd)

async def done_deploying(expected_resources: set[str]) -> bool:
if not expected_resources:
return True
result = await client.resource_list(tid=environment_id, deploy_summary=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a race condition between the export command and this resource_list() command. The export command releases the version, but this happens asynchronously, so the resource_list() might be executed before the version is released. This way we might be checking an outdated state.

Copy link
Contributor Author

@Hugo-Inmanta Hugo-Inmanta Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something but I think this is currently acceptable since the done_deploying check is performed inside a retry_limited and the expected_resources parameter holds the version we want to check for ? ie

  1. we release version N
  2. we keep checking until resources for version N were correctly deployed

Copy link
Contributor

@arnaudsjs arnaudsjs Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the done_deploying method does an assert on the expected_resources, which means that it raises an exception in case of failure. The retry_limited doesn't catch this exception so it will crash. If we change this assertion to an if-condition that returns False in case of a mismatch, I agree with the above-mentioned statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof nice catch

assert result.code == 200
if result.result["metadata"]["deploy_summary"]["by_state"][
"deployed"
] != len(expected_resources):
return False

return {
res["resource_version_id"] for res in result.result["data"]
} == expected_resources

await retry_limited(
functools.partial(done_deploying, expected_resources),
timeout=20,
interval=1,
)

def make_expected_rids(version: int) -> set[str]:
return {
f"yang::GnmiResource[spine,name=global],v={version}",
f"yang::GnmiResource[leaf2,name=global],v={version}",
f"yang::GnmiResource[leaf1,name=global],v={version}",
f"std::AgentConfig[internal,agentname=spine],v={version}",
f"std::AgentConfig[internal,agentname=leaf2],v={version}",
f"std::AgentConfig[internal,agentname=leaf1],v={version}",
}

await install_project()

await deploy_and_check("main.cf", set())
await deploy_and_check("interfaces.cf", make_expected_rids(version=2))
await deploy_and_check("ospf.cf", make_expected_rids(version=3))

validate_config()


def fetch_config(gc):
result = gc.get(path=["interface", "network-instance"], encoding="json_ietf")

notifications = result["notification"]

interface_result = None
ospf_result = None
for response in notifications:
if list(response["update"][0]["val"].keys())[0] == INTERFACE_PATH:
interface_result = response["update"][0]["val"][INTERFACE_PATH][0]
if list(response["update"][0]["val"].keys())[0] == NS_INSTANCE_PATH:
ospf_result = response["update"][0]["val"][NS_INSTANCE_PATH][0]

return interface_result, ospf_result


def validate_config() -> None:
# Only available after inmanta project install
from pygnmi.client import gNMIclient

with gNMIclient(
target=HOST,
username="admin",
password="NokiaSrl1!",
insecure=False,
skip_verify=True,
) as gc:
interface_result, ospf_result = fetch_config(gc)

assert interface_result is not None
assert ospf_result is not None

router_id = ospf_result["protocols"][OSPF_PATH]["instance"][0]["router-id"]
assert router_id == "10.20.30.100"

sub_int_ip_address = interface_result["subinterface"][0]["ipv4"]["address"][0][
"ip-prefix"
]
assert sub_int_ip_address == "10.10.11.1/30"

# Check if we see the two neighbours
neigbours = ["10.20.30.210", "10.20.30.220"]
count = 0
while neigbours and count < 60:
for interface in ospf_result["protocols"][OSPF_PATH]["instance"][0]["area"][
0
]["interface"]:
if "neighbor" not in interface or len(interface["neighbor"]) == 0:
count += 1
break

if interface["neighbor"][0]["router-id"] in neigbours:
neigbours.remove(interface["neighbor"][0]["router-id"])

if not neigbours:
break

interface_result, ospf_result = fetch_config(gc)
time.sleep(1)

print("[+] Deployment was successful!")


def fetch_logs():
subprocess.check_call(
"sudo docker logs clab-srlinux-inmanta-server >server.log", shell=True
)
subprocess.check_call(
"sudo docker logs clab-srlinux-postgres >postgres.log", shell=True
)
subprocess.check_call(
"sudo docker exec -i clab-srlinux-inmanta-server sh -c cat /var/log/inmanta/resource-*.log >resource-actions.log",
shell=True,
)
subprocess.check_call(
"sudo docker exec -i clab-srlinux-inmanta-server sh -c cat /var/log/inmanta/agent-*.log >agents.log",
shell=True,
)


asyncio.run(main())
61 changes: 0 additions & 61 deletions Networking/SR Linux/ci/do_test_deployment_and_verify.sh

This file was deleted.

Loading