{"id":28569607,"url":"https://github.com/abilian/smo-h3ni","last_synced_at":"2025-06-10T17:15:38.553Z","repository":{"id":297282217,"uuid":"996239788","full_name":"abilian/smo-h3ni","owner":"abilian","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-04T18:46:42.000Z","size":306,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"h3ni","last_synced_at":"2025-06-04T23:45:10.645Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abilian.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-04T16:55:36.000Z","updated_at":"2025-06-04T18:46:43.000Z","dependencies_parsed_at":"2025-06-04T23:55:27.498Z","dependency_job_id":null,"html_url":"https://github.com/abilian/smo-h3ni","commit_stats":null,"previous_names":["abilian/smo-h3ni"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abilian%2Fsmo-h3ni","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abilian%2Fsmo-h3ni/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abilian%2Fsmo-h3ni/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abilian%2Fsmo-h3ni/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abilian","download_url":"https://codeload.github.com/abilian/smo-h3ni/tar.gz/refs/heads/h3ni","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abilian%2Fsmo-h3ni/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259114708,"owners_count":22807255,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-10T17:15:14.482Z","updated_at":"2025-06-10T17:15:38.544Z","avatar_url":"https://github.com/abilian.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SMO\n\n\u003e This is a forked version of the original Nephele SMO repository. The original repository is located at: https://gitlab.eclipse.org/eclipse-research-labs/nephele-project/smo\n\u003e This is a work in progress. The development plan is outlined in the [TODO.md](./TODO.md) file.\n\nBuild status: [![builds.sr.ht status](https://builds.sr.ht/~sfermigier/smo-h3ni.svg)](https://builds.sr.ht/~sfermigier/smo-h3ni?)\n\n\n## TOC\n\n\u003c!-- toc --\u003e\n\n- [Prerequisites](#prerequisites)\n- [Getting started](#getting-started)\n- [Container/Artifact registry](#containerartifact-registry)\n  * [Docker container images](#docker-container-images)\n    + [Docker settings](#docker-settings)\n    + [Containerd (Kubernetes) settings](#containerd-kubernetes-settings)\n  * [OCI artifacts](#oci-artifacts)\n- [Full example](#full-example)\n- [File structure](#file-structure)\n- [NFVCL API](#nfvcl-api)\n\n\u003c!-- tocstop --\u003e\n\n---\n\n(Original README below)\n\nThis repository hosts the Synergetic Meta-Orchestrator consisting of a Flask REST API that is responsible for translating intent formulations, constructing and enforcing deployment plans for Hyper Distributed Application Graphs.\n\n## Prerequisites\nThe following assumptions are made:\n- The Kubernetes cluster uses the containerd runtime as CRI\n- Karmada and Submariner have been installed to the cluster\n- The Prometheus CRDs need to be installed in the Karmada Control plane in order for the Service Monitors to work. If not installed,  either install them like this specifying the right version:\n```bash\n# Define the Prometheus Operator version\nVERSION=\"v0.78.2\"\n\n# Base URL for the Prometheus Operator CRDs\nBASE_URL=\"https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/$VERSION/example/prometheus-operator-crd\"\n\n# Kubeconfig file of the Karmada control plane\nKUBECONFIG=\"~/.kube/karmada-apiserver.config\"\n\n# Apply each CRD with server-side apply\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_alertmanagerconfigs.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_alertmanagers.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_podmonitors.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_probes.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_prometheusagents.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_prometheuses.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_prometheusrules.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_scrapeconfigs.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_servicemonitors.yaml --kubeconfig $KUBECONFIG\nkubectl apply --server-side -f $BASE_URL/monitoring.coreos.com_thanosrulers.yaml --kubeconfig $KUBECONFIG\n\n# Create the monitoring namespace\nkubectl create ns monitoring --kubeconfig $KUBECONFIG\n```\nor delete all `servicemonitor.yaml` files from all the helmcharts.\n\n## Getting started\nThe config files inside the `config` directory contain: the database credentials, the Karmada config and the NFVCL URL\n- The database credentials can be set to whatever the user prefers but the credentials in the `flask.env` and `postgres.env` files must match\n- Regarding the Karmada config, the docker compose YAML mounts the `~/.kube` directory inside the container meaning that the SMO expects the karmada kubeconfig file to be inside that directory. Afterwards, the user can specify the name of the config file in the `KARMADA_KUBECONFIG` environment variable of the `config/flask.env` file.\n- The NVFCL URL is optional and only relevant if the NFVCL API is used\n- The `hdarctl` binary has to be available in the path. You can run for example:\n    ```bash\n    wget https://gitlab.eclipse.org/eclipse-research-labs/nephele-project/nephele-development-sandbox/-/raw/main/tools/hdarctl\n    sudo chmod u+x hdarctl\n    sudo mv hdarctl /usr/local/bin\n    ```\n\nTo deploy, use docker compose:\n```bash\ndocker compose up\n```\nThe SMO API is available by default at port 8000 and the Swagger API is accesible at the `/docs` endpoint (http://localhost:8000/docs)\n\n## Container/Artifact registry\nWhile the Nephele platform works with a Hyper-Distributed Application Registry (HDAR), for testing purposes we can run a Distribution container/artifact registry. A docker compose file is located inside the `registry` directory:\n- Start up: `docker compose up -d`\n- Tear down: `docker compose down -v`\nThe Distribution registry runs in port `5000` where container images and OCI artifacts can be pushed\n### Docker container images\n#### Docker settings\nThe registry can be used to host Docker images. For the container images to be accessible from Kubernetes, the images need to be tagged with the host's IP. Additionally the docker daemon has to be configured to communicate with the registry through HTTP. This can be done by adding:\n```json\n{\n  \"insecure-registries\" : [\"\u003cHost-IP\u003e:5000\"]\n}\n```\nto the `/etc/docker/daemon.json` file. Afterwards:\n- Image creation:\n    - New image creation: `docker build -t \u003cHost-IP\u003e:5000/\u003cimage-tag\u003e`\n    - Tag an already existing image: `docker tag \u003cexisting-image\u003e \u003cHost-IP\u003e:5000/\u003cimage-tag\u003e`\n- Image push: `docker push \u003cHost-IP\u003e:5000/\u003cimage-tag\u003e`\n- Image pull: `docker pull \u003cHost-IP\u003e:5000/\u003cimage-tag\u003e`\n\n#### Containerd (Kubernetes) settings\nAdditionally, since Kubernetes uses containerd, we also need to configure it to use an insecure registry. We first modify `/etc/containerd/config.toml` and define a config path:\n```toml\n    [plugins.\"io.containerd.grpc.v1.cri\".registry]\n      config_path = \"/etc/containerd/certs.d\"\n```\nThen create the `/etc/containerd/certs.d` directory and inside it create two directories:\n- `/etc/containerd/certs.d/docker.io/`\n- `/etc/containerd/certs.d/\u003cHost-IP\u003e:5000/`\n\nThen create the file `/etc/containerd/certs.d/docker.io/hosts.toml` with the content:\n```toml\nserver = \"https://registry-1.docker.io\"\n[host.\"https://{docker.mirror.url}\"]\n  capabilities = [\"pull\", \"resolve\"]\n```\nFinally, create the `/etc/containerd/certs.d/\u003cHost-IP\u003e:5000/hosts.toml` with the content:\n```toml\nserver = \"https://registry-1.docker.io\"\n[host.\"http://\u003cHost-IP\u003e:5000\"]\n  capabilities = [\"pull\", \"resolve\", \"push\"]\n  skip_verify = true\n```\n\n### OCI artifacts\nHelmchart artifacts can be created using the `hdarctl` tool that can be found [here](https://gitlab.eclipse.org/eclipse-research-labs/nephele-project/nephele-development-sandbox/-/raw/main/tools/hdarctl). The `hdarctl` tool can package Hyper-Distributed Application Graphs, VO helmcharts and Application helmcharts and also push them to the OCI registry.\n- Package artifact: `hdarctl package tar \u003cartifact-directory\u003e`\n- Push artifact under a specific project: `hdarctl push \u003cartifact\u003e-\u003cversion\u003e.tar.gz http://localhost:5000/\u003cproject\u003e`\n- Install artifact with an arbitrary release name: `helm install \u003crelease-name\u003e --plain-http oci://localhost:5000/\u003cproject\u003e/\u003cartifact\u003e`\n\n## Full example\nA full example can be found in the `examples/brussels-demo` directory. The steps to deploy the example are:\n1. Setup the Docker and Containerd daemons to use insecure registries as described [above](#docker-container-images)\n2. Start the container/artifact registry `docker compose -f registry/docker-compose.yaml up -d`\n3. Start the SMO in detached mode `docker compose up -d`\n4. Cd to the `examples/brussels-demo` directory\n5. Edit the Makefile with the proper IPs\n6. Run `make push-images` to push the Docker images of the services to the registry\n7. Run `make change-ips` to change th IPs of the helmcharts and the descriptor\n8. Run `make push-artifacts` to push the helmcharts to the artifact registry\n9. Change the variables inside the `create-existing-artifact.sh` bash script\n10. Run the `create-existing-artifact.sh` bash script to request the Graph deployment from the SMO\n\nTo delete the graph run the `delete.sh` script.\n\n## File structure\nThe directory structure of the codebase is as follows:\n```\nsrc/\n├── errors\n├── models\n├── routes\n├── services\n├── utils\n├── app.py\n└── config.py\n```\n- `errors`: custom errors and handlers\n- `models`: db models\n- `routes`: app blueprints\n- `services`: business logic for the routes\n- `utils`: misc\n- `app.py`: the Flask application\n- `config.py`: the Flask application configuration files\n\n\n## NFVCL API\nTo create a new Kubernetes Cluster using the NFVCL API using an Openstack-powered infrastructure:\n- `POST` to `/smo_vims` a json like:\n    ```json\n    {\n        \"mgmt_network\": {\n            \"cidr\": \"X.X.X.X/24\",\n            \"gateway\": \"X.X.X.X\",\n            \"name\": \"openstack_network_name\"\n        },\n        \"pop_area\": 0,\n        \"service_network\": {\n            \"cidr\": \"X.X.X.X/24\",\n            \"gateway\": \"X.X.X.X\",\n            \"name\": \"openstack_network_name\"\n        },\n        \"topology\": \"topology_name\",\n        \"use_floating_ip\": true,\n        \"vim_name\": \"vim_name\",\n        \"vim_password\": \"openstack_password\",\n        \"vim_tenant_name\": \"openstack_project\",\n        \"vim_type\": \"openstack\",\n        \"vim_url\": \"http://X.X.X.X:5000/v3\",\n        \"vim_user\": \"openstack_user\"\n    }\n    ```\n- `POST` to `/clusters`:\n    ```json\n    {\n        \"pop_area\": 0,\n        \"vim_name\": \"vim_name\"\n    }\n    ```\nAfter the above, the SMO will make requests to the NFVCL API to create a new Kubernetes cluster.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabilian%2Fsmo-h3ni","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabilian%2Fsmo-h3ni","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabilian%2Fsmo-h3ni/lists"}