Skip to content

Commit 9fa0d61

Browse files
authored
Merge pull request #73 from LabNConsulting/chopps/use-uv
Cleanup unshare inline and new pid namespace, and use uv
2 parents 4f5284b + f42bc56 commit 9fa0d61

File tree

20 files changed

+2099
-2067
lines changed

20 files changed

+2099
-2067
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,27 @@ jobs:
1515
- name: Checkout repository
1616
uses: actions/checkout@v4
1717

18-
- name: Setup python ${{ matrix.python-version }}
19-
uses: actions/setup-python@v5
18+
- name: Install uv and set the python version
19+
uses: astral-sh/setup-uv@v6
2020
with:
2121
python-version: ${{ matrix.python-version }}
22+
enable-cache: true # caches uv’s package cache between runs
2223

23-
- name: Install Poetry
24-
uses: snok/install-poetry@v1
25-
with:
26-
virtualenvs-create: true
27-
virtualenvs-in-project: true
24+
- name: Fix sudoers and verify uv available
25+
run: |
26+
sudo sed -i -e '/secure_path/d' /etc/sudoers
27+
sudo -E uv --version
28+
29+
- name: Install munet project
30+
run: |
31+
uv sync --locked --all-extras --dev
2832
2933
- name: install Qemu
3034
run: |
3135
uname -a
3236
sudo apt-get update -y
3337
sudo apt-get install -y cloud-utils qemu-system-x86
3438
35-
- name: Install munet project
36-
run: poetry install --all-extras --no-interaction
37-
3839
- name: Lint the project
3940
run: make ci-lint
4041

.github/workflows/publish.yml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ jobs:
88
publish:
99
runs-on: ubuntu-latest
1010
steps:
11-
- uses: actions/setup-python@v5
11+
- name: Install uv
12+
uses: astral-sh/setup-uv@v6
1213
with:
13-
python-version: 3.9
14-
- uses: snok/install-poetry@v1
15-
- uses: actions/checkout@v2
16-
- run: poetry config pypi-token.pypi "${{ secrets.PYPI_API_KEY }}"
17-
- name: Publish package
18-
run: poetry publish --build
14+
python-version: 3.12
15+
16+
- uses: actions/checkout@v4
17+
18+
- name: Build Munet package
19+
run: uv build
20+
21+
- name: Publish package to pypi
22+
run: uv publish --token "${{ secrets.PYPI_API_KEY }}"

.github/workflows/testpub.yml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ jobs:
88
runs-on: ubuntu-latest
99
if: github.event.pull_request.merged == true
1010
steps:
11-
- uses: actions/setup-python@v5
11+
- name: Install uv
12+
uses: astral-sh/setup-uv@v6
1213
with:
13-
python-version: 3.9
14-
- uses: snok/install-poetry@v1
14+
python-version: 3.12
15+
1516
- uses: actions/checkout@v4
16-
- run: poetry config repositories.testpypi https://test.pypi.org/legacy/
17-
- run: poetry config pypi-token.testpypi "${{ secrets.TEST_PYPI_API_KEY }}"
18-
- name: publish package (test)
19-
run: poetry publish --dry-run -vvv --no-interaction --build -r testpypi
17+
18+
- name: Build Munet Package
19+
run: uv build
20+
21+
- name: Test publishing package to pypi
22+
run: uv publish --token "${{ secrets.TEST_PYPI_API_KEY }}" --repository-url https://test.pypi.org/legacy/

Makefile

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@ SCHEMA := test-schema.json
66
LOG_CLI := # --log-cli
77
TMP := .testtmp
88

9-
unexport VIRTUAL_ENV
10-
11-
POETRY := env -u VIRTUAL_ENV PATH="$(PATH)" poetry
12-
POETRYRUN := $(POETRY) run
9+
UV := uv
10+
UVRUN := $(UV) run
11+
UVSYNC := $(UV) sync
12+
# PYANG_PLUGIN_BASE := .venv/pyang-json-schema-plugin
13+
PYANG_PLUGIN_DIR := $(PYANG_PLUGIN_BASE)/jsonschema
14+
PYANG_PLUGIN := $(PYANG_PLUGIN_DIR)/jsonschema.py
1315

1416
MAKE_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
1517

1618
all: $(TMP) $(YANG) $(YANG_SCHEMA) doc ci-lint test yang-test
1719

1820
.PHONY: doc
1921
doc:
20-
$(POETRYRUN) $(MAKE) -C doc html
22+
$(UVRUN) $(MAKE) -C doc html
2123

2224
doc-start:
2325
sudo podman run -it --rm -p 8088:80 -d --volume $(MAKE_DIR)/doc/build/html:/usr/share/nginx/html --name sphinx docker.io/nginx
@@ -27,31 +29,32 @@ doc-stop:
2729

2830
# We hand craft this to keep things cleaner
2931
doc-apidoc:
30-
$(POETRYRUN) sphinx-apidoc -f --module-first --ext-doctest --extensions sphinx-prompt -o doc/source/apidoc munet
32+
$(UVRUN) sphinx-apidoc -f --module-first --ext-doctest --extensions sphinx-prompt -o doc/source/apidoc munet
3133

3234
prepare-publish: $(YANG_SCHEMA)
3335

3436
lint:
35-
$(POETRYRUN) pydocstyle ./munet
36-
$(POETRYRUN) pylint ./munet $(shell find ./tests/*/* -name '*.py')
37+
$(UVRUN) pydocstyle ./munet
38+
$(UVRUN) pylint ./munet $(shell find ./tests/*/* -name '*.py')
3739

3840
ci-lint:
39-
$(POETRYRUN) pydocstyle ./munet
40-
$(POETRYRUN) pylint --disable="fixme" ./munet ./tests
41+
$(UVRUN) pydocstyle ./munet
42+
$(UVRUN) pylint --disable="fixme" ./munet ./tests
4143

4244
test: test-validate ci-lint
43-
sudo -E $(POETRYRUN) mutest tests
44-
sudo -E $(POETRYRUN) pytest -s -v --cov=munet --cov-report=xml tests
45+
$(UVRUN) sudo -E mutest tests
46+
$(UVRUN) sudo -E pytest -s -v --cov=munet --cov-report=xml tests
4547

4648
clean:
4749
rm -f *.yang coverage.xml err.out ox-rfc.el
4850
rm -rf .testtmp/schema
51+
rm -rf $(PYANG_PLUGIN_BASE)
4952

5053
run:
51-
sudo -E $(POETRYRUN) python3 -m munet
54+
$(UVRUN) sudo -E python3 -m munet
5255

5356
install:
54-
$(POETRY) install --all-extras
57+
$(UVSYNC) --all-groups
5558

5659
# ====
5760
# YANG
@@ -62,7 +65,7 @@ install:
6265
# -------------------------
6366

6467
ajv = $(or $(and $(shell which ajv),ajv $(1)),)
65-
y2j = $(POETRYRUN) python -c 'import sys; import json; import yaml; json.dump(yaml.safe_load(sys.stdin), sys.stdout, indent=2)' < $(1) > $(2)
68+
y2j = $(UVRUN) python -c 'import sys; import json; import yaml; json.dump(yaml.safe_load(sys.stdin), sys.stdout, indent=2)' < $(1) > $(2)
6669

6770
$(YANG): $(ORG)
6871
sed -n '/#+begin_src yang :exports code/,/^#+end_src/p' $< | sed '/^#/d' >$@
@@ -94,8 +97,11 @@ ox-rfc.el:
9497
# YANG data validation
9598
# --------------------
9699

97-
$(YANG_SCHEMA): $(YANG)
98-
$(POETRYRUN) pyang --plugindir .venv/src/pyang-json-schema-plugin/jsonschema/jsonschema.py --format jsonschema -o $@ $<
100+
#$(PYANG_PLUGIN):
101+
# $(UV) pip install --no-deps --target $(PYANG_PLUGIN_BASE) git+https://github.com/LabNConsulting/pyang-json-schema-plugin.git@labn-master
102+
103+
$(YANG_SCHEMA): $(YANG) # $(PYANG_PLUGIN)
104+
$(UVRUN) pyang --format jsonschema -o $@ $<
99105

100106
$(TMP):
101107
mkdir -p .testtmp
@@ -111,8 +117,8 @@ KINDS_DATA := .testtmp/kinds.json
111117
test-validate: $(YANG_SCHEMA) $(KINDS_DATA) .testtmp/basic.json $(TMP)
112118
@echo "testing basic with yang generated schema"
113119
$(call ajv,--spec=draft2020 -d .testtmp/basic.json -s $(YANG_SCHEMA))
114-
$(POETRYRUN) jsonschema --instance .testtmp/basic.json $(YANG_SCHEMA)
120+
$(UVRUN) jsonschema --instance .testtmp/basic.json $(YANG_SCHEMA)
115121

116122
@echo "testing kinds with yang generated schema"
117123
$(call ajv,--spec=draft2020 -d .testtmp/kinds.json -s $(YANG_SCHEMA))
118-
$(POETRYRUN) jsonschema --instance .testtmp/kinds.json $(YANG_SCHEMA)
124+
$(UVRUN) jsonschema --instance .testtmp/kinds.json $(YANG_SCHEMA)

README.org

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -324,41 +324,36 @@ For most users, it is recommended to install munet through pip (see:
324324
https://munet.readthedocs.io/en/latest/usage.html). However, if you want to run
325325
the unit tests, then you will need to set up your local enviornment:
326326

327-
*** Dependencies
328-
329-
μNET requires the following packages:
327+
*** `sudo -E` configuration
330328

331-
python3 python3-venv
329+
To allow munet to be found when running with `sudo -E` the `secure_path` config
330+
should be disabled in /etc/sudoers:
332331

333-
Automate tests require the following system packages:
332+
#+begin_src shell
333+
$ sudo sed -i -e '/secure_path/s/^/# /' /etc/sudoers
334+
#+end_src
334335

335-
podman
336+
*** Dependencies
336337

337-
Ensure you have poetry setup, the following instructions work around some bugs
338-
with poetry:
338+
Install the [[https://docs.astral.sh/uv/][uv]] python project
339+
manager (either through your system's package manager or directly via the
340+
official installer):
339341

340342
#+begin_src shell
341-
python3 -m venv ~/.poetrybin
342-
source ~/.poetrybin/bin/activate
343-
pip install poetry
344-
pip uninstall keyring
345-
deactivate
343+
curl -LsSf https://astral.sh/uv/install.sh | sh
346344
#+end_src
347345

348-
NOTE: add "~/.poetrybin/bin" to your $PATH
346+
Some of the munet unit tests will require the following system packages which
347+
you should install according to your OS procedures:
348+
349+
podman
349350

350351
Install μNET with dependencies:
351352

352353
#+begin_src shell
353354
make install
354355
#+end_src
355356

356-
NOTE: To run munet or mutest locally, you need to enter the poetry virtual enviornment:
357-
358-
#+begin_src shell
359-
$(poetry env activate)
360-
#+end_src
361-
362357
*** Check your install
363358

364359
make
@@ -367,11 +362,11 @@ NOTE: To run munet or mutest locally, you need to enter the poetry virtual envio
367362

368363
The following uses FRR (see https://frrouting.org)
369364

370-
sudo poetry run munet -c examples/frr/ospf/ospf/munet.yaml
365+
uv run sudo -E munet -c examples/frr/ospf/ospf/munet.yaml
371366

372367
For example:
373368
#+begin_src shell
374-
munet$ sudo poetry run munet -c examples/frr/ospf/ospf/munet.yaml
369+
munet$ uv run sudo -E munet -c examples/frr/ospf/ospf/munet.yaml
375370
2022-09-16 13:37:05,603: INFO: Loaded logging config /home/lberger/Code/github/labn/munet/munet/logconf.yaml
376371
2022-09-16 13:37:05,609: INFO: Loaded config from /home/lberger/Code/github/labn/munet/examples/frr/ospf/ospf/munet.yaml
377372
2022-09-16 13:37:05,623: INFO: Loaded kinds config /home/lberger/Code/github/labn/munet/munet/kinds.yaml

doc/source/api/unshare.rst

Lines changed: 0 additions & 12 deletions
This file was deleted.

doc/source/usage.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,23 @@ Or if you need the latest changes from master:
2323
2424
$ pip install git+https://github.com/LabNConsulting/munet.git#egg=munet
2525
26+
`sudo -E` configuration
27+
-----------------------
28+
29+
sudo/root is required for most uses of munet and mutest; however, when you
30+
install munet as a non-root user (typical) either in your default
31+
environment or in a virtual environment, it may not be found when you `sudo`.
32+
33+
First you should always run with `sudo -E` which carries the user environment
34+
over into the new process running as root. However, it is also common for sudo
35+
to be configured to override the user's `$PATH` even when the `-E` flag is
36+
specified. To make sure this isn't the case you should disable the `Default
37+
secure_path` configuration if present. One way to do that is:
38+
39+
.. code-block:: console
40+
41+
$ sudo sed -i -e '/secure_path/s/^/#/' /etc/sudoers
42+
2643
Running
2744
-------
2845

munet/__main__.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from . import cli
1818
from . import parser
1919
from .args import add_launch_args
20-
from .base import get_event_loop
2120
from .cleanup import cleanup_previous
2221
from .cleanup import is_running_in_rundir
2322
from .compat import PytestConfig
@@ -200,22 +199,16 @@ def main(*args):
200199
logger.critical("No nodes defined in config file")
201200
return 1
202201

203-
loop = None
204202
status = 4
205203
try:
206204
parser.validate_config(config, logger, args)
207205
if args.validate_only:
208206
return 0
209-
# Executes the cmd for each node.
210-
loop = get_event_loop()
211-
status = loop.run_until_complete(async_main(args, config))
207+
status = asyncio.get_event_loop().run_until_complete(async_main(args, config))
212208
except KeyboardInterrupt:
213209
logger.info("Exiting, received KeyboardInterrupt in main")
214210
except Exception as error:
215211
logger.info("Exiting, unexpected exception %s", error, exc_info=True)
216-
finally:
217-
if loop:
218-
loop.close()
219212

220213
return status
221214

0 commit comments

Comments
 (0)