From 32dc08607d66da5bcaaa28010c702041607cb770 Mon Sep 17 00:00:00 2001 From: Lucas Guillermou Date: Fri, 31 Jan 2025 10:27:19 +0100 Subject: [PATCH 1/2] Add reload option to dev.start --- development/docker-compose.yml | 24 +++++++++++++----------- tasks/dev.py | 11 ++++++++++- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/development/docker-compose.yml b/development/docker-compose.yml index d8a2395134..ba2e85c1b9 100644 --- a/development/docker-compose.yml +++ b/development/docker-compose.yml @@ -116,17 +116,6 @@ services: target: backend image: "${IMAGE_NAME}:${IMAGE_VER}" pull_policy: always - command: > - gunicorn --config backend/infrahub/serve/gunicorn_config.py -w ${WEB_CONCURRENCY:-4} --logger-class infrahub.serve.log.GunicornLogger infrahub.server:app - depends_on: - database: - condition: service_healthy - message-queue: - condition: service_healthy - cache: - condition: service_healthy - task-manager: - condition: service_healthy environment: <<: *infrahub_config INFRAHUB_INTERNAL_ADDRESS: "http://server:8000" @@ -145,6 +134,19 @@ services: INFRAHUB_DB_PORT: 7687 INFRAHUB_DB_PROTOCOL: bolt INFRAHUB_STORAGE_DRIVER: local + # INFRAHUB_SERVER_COMMAND is defined while running with reload option as it requires to run server using `uvicorn`. + COMMAND: ${INFRAHUB_SERVER_COMMAND:- gunicorn --config backend/infrahub/serve/gunicorn_config.py -w ${WEB_CONCURRENCY:-4} --logger-class infrahub.serve.log.GunicornLogger infrahub.server:app} + command: > + sh -c "$$COMMAND" + depends_on: + database: + condition: service_healthy + message-queue: + condition: service_healthy + cache: + condition: service_healthy + task-manager: + condition: service_healthy volumes: - "storage_data:/opt/infrahub/storage" tty: true diff --git a/tasks/dev.py b/tasks/dev.py index bfe39a2ae0..e04815a0f0 100644 --- a/tasks/dev.py +++ b/tasks/dev.py @@ -1,5 +1,6 @@ from __future__ import annotations +import os from typing import TYPE_CHECKING from invoke.tasks import task @@ -172,8 +173,16 @@ def status( @task(optional=["database"]) -def start(context: Context, database: str = INFRAHUB_DATABASE, wait: bool = False) -> None: +def start(context: Context, database: str = INFRAHUB_DATABASE, wait: bool = False, reload: bool = False) -> None: """Start a local instance of Infrahub within docker compose.""" + + if reload: + # Need to use `uvicorn` instead of `gunicorn` for reload option because of this issue: + # https://github.com/benoitc/gunicorn/issues/2339 + os.environ["INFRAHUB_SERVER_COMMAND"] = ( + "uvicorn infrahub.server:app --host 0.0.0.0 --port 8000 --workers 4 --timeout-keep-alive 90 --reload" + ) + start_services(context=context, database=database, namespace=NAMESPACE, wait=wait) From ca89edc5b94262b08624b91e6110e8e68a3d214b Mon Sep 17 00:00:00 2001 From: Pete Crocker Date: Sun, 16 Feb 2025 10:34:10 +0000 Subject: [PATCH 2/2] node vs. generic (#5765) * node vs. generic * add link --- docs/docs/topics/schema.mdx | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/docs/topics/schema.mdx b/docs/docs/topics/schema.mdx index 2f57d8a0fd..86909828dd 100644 --- a/docs/docs/topics/schema.mdx +++ b/docs/docs/topics/schema.mdx @@ -25,14 +25,28 @@ To help with the development process of a schema definition file, you can levera ## Schema definition -### Namespace, Node, Attributes, Relationships, and Generics +### Node, Attributes, Relationships, and Generics The schema is composed of 4 primary types of objects: `Nodes`- that are themselves composed of `Attributes` and `Relationships` and finally `Generics`. -- A `Node` in Infrahub represents a `Model`. +- A `Node` in Infrahub represents a `Model`. Nodes are instances of a specific object within your infrastructure. Nodes have attributes that define specific values, such as text or numbers, and relationships that link them to other nodes. - An `Attribute` represents a direct value associated with a `Node` like a `Text`, a `Number` etc ... - A `Relationship` represents a link between 2 `Node`, a `Relationship` can be of cardinality `one` or `many`. -- A `Generic` can be used to share some attributes between multiple `Node`, if you're familiar with programming concept, it's close to class inheritance. +- A `Generic` can be used to share attributes and relationships between different types of `Node`s. They can connect multiple types of nodes to the same relationship or define attributes and relationships on a specific list of nodes. Generics are similar to class inheritance in programming languages like Java or Python. + +### Nodes vs. Generics + +Use a `Node` when you need to represent a concrete object in your infrastructure model with specific attributes and relationships. + +Use a `Generic` when you want to share common attributes or relationships across multiple node types. This helps to avoid redundancy and ensures consistency across your schema. For example, if you have different types of network interfaces (physical, logical) that share common attributes like name and description, you can define a `Generic` interface with these attributes and have the specific interface types inherit from it. + +`Generic`s can also be used to connect multiple types of Nodes to the same relationship. + +When deciding between a `Node` and `Generic`, remember that computed attributes can only be used on `Nodes`, not `Generics`. + +If a `Generic`'s properties are updated after the `Node` has been created, these updates will not be propagated to the `Node`; users must manually update `Nodes` if they want to reflect changes made to `Generic`s. See [Inherited properties](#inherited-properties) for more information. + +### Node example In the example below, the node `Person` has 2 attributes (`name` and `description`) and the node `Car` has 1 attribute (`model`) and 1 relationship to `Person`, identified by `owner`.