From 36c6b455f58f0ec8fb3a45628410715a3bec4cf3 Mon Sep 17 00:00:00 2001 From: Rene Orozco Martinez Date: Tue, 19 May 2026 16:50:25 -0600 Subject: [PATCH 1/5] docs: include server deployment in public documentation --- .../deploy-testflinger-server.rst | 262 ++++++++++++++++++ docs/how-to/administer-server/index.rst | 9 + docs/how-to/index.rst | 3 +- docs/images/testflinger_architecture.png | Bin 0 -> 41964 bytes docs/reuse/links.txt | 5 +- 5 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 docs/how-to/administer-server/deploy-testflinger-server.rst create mode 100644 docs/how-to/administer-server/index.rst create mode 100644 docs/images/testflinger_architecture.png diff --git a/docs/how-to/administer-server/deploy-testflinger-server.rst b/docs/how-to/administer-server/deploy-testflinger-server.rst new file mode 100644 index 000000000..c1b70cf80 --- /dev/null +++ b/docs/how-to/administer-server/deploy-testflinger-server.rst @@ -0,0 +1,262 @@ +.. _howto-deploy-server: + +Deploy a Testflinger Server +=========================== + +This guide outlines the steps to deploy a Testflinger server using Juju and +the Testflinger server charm from Charmhub. + +Architecture +------------ + +The Testflinger server is a Kubernetes (K8s) application deployed using Juju. +As a backend, it uses a MongoDB database that stores all data related to +Testflinger, including job definitions, job results, agent information, +and more. + +The preferred way to deploy MongoDB is to use the MongoDB machine charm, +which deploys a MongoDB instance on a virtual machine (VM). This can +improve performance and reduce resource complexity compared to deploying +MongoDB as a K8s application. + +The following diagram illustrates the architecture of the Testflinger +server deployment: + +.. image:: ../../images/testflinger_architecture.png + :alt: Testflinger server architecture diagram + +Prerequisites +------------- + +The following prerequisites cover the necessary steps to set up K8s and +machine-based Juju environments required for the Testflinger server +deployment. For a detailed guide on how to set up Juju, refer to the +`official Juju documentation `_. + +Dependencies +^^^^^^^^^^^^ + +Install the following dependencies: + +.. code-block:: shell + + $ sudo apt-get install git + $ sudo snap install juju lxd + $ sudo snap install microk8s --channel 1.32-strict + $ sudo snap install terraform --classic + +.. note:: + + Juju requires the strict version of the ``microk8s`` snap to be installed. + +LXD +^^^ + +Make sure LXD is initialized. + +.. code-block:: shell + + $ lxd init --auto + +.. note:: + + Feel free to initialize LXD with a configuration that suits your needs. + + +MicroK8s +^^^^^^^^ + +The Testflinger server deployment depends on the following MicroK8s setup. + +.. code-block:: shell + + $ sudo snap alias microk8s.kubectl kubectl + $ sudo usermod -aG snap_microk8s ubuntu + $ newgrp snap_microk8s # or reboot + $ microk8s status --wait-ready + $ sudo microk8s enable dns hostpath-storage ingress + +Juju +^^^^ + +Set up the Juju controllers needed for the Testflinger server deployment. + +.. code-block:: shell + + # Workaround to get localhost-controller to connect to microk8s + $ server_url=$(microk8s config | grep server | awk '{print $2;}') + $ sed -i "s|server: .*|server: $server_url|g" \ + /var/snap/microk8s/current/credentials/client.config + $ juju bootstrap microk8s microk8s-controller + $ juju bootstrap localhost localhost-controller + $ juju add-cloud microk8s --controller localhost-controller + +Then create the models for the server and database deployments. + +.. code-block:: shell + + $ juju add-model testflinger-db localhost + $ juju add-model testflinger microk8s + +MongoDB deployment +------------------ + +Deploy the MongoDB charm into the ``testflinger-db`` model. + +.. code-block:: shell + + $ juju deploy mongodb --channel 6/stable -m testflinger-db + +Once the deployment is complete, offer the MongoDB endpoint so that it can +be consumed by the Testflinger server application in the K8s model. + +.. code-block:: shell + + $ juju offer testflinger-db.mongodb:database mongodb + +Testflinger server deployment +------------------------------ + +.. tip:: + + The following steps assume you are located in the k8s model, otherwise you can + switch by running ``juju switch testflinger``. + +Juju CLI +^^^^^^^^ + +The following steps outline how to deploy the Testflinger server charm +using the Juju CLI. + +First, consume the MongoDB endpoint offered in the previous step. + +.. code-block:: shell + + $ juju consume localhost:admin/testflinger-db.mongodb + +Deploy the Testflinger server charm. + +.. code-block:: shell + + $ juju deploy testflinger-k8s --channel stable \ + --config jwt_signing_key="" + +.. note:: + + The ``jwt_signing_key`` configuration is required for authenticating + API requests to the Testflinger server. You should generate a secure + random string to use as the signing key. + +.. note:: + + You can also pass the ``-n `` flag to deploy multiple units of the + Testflinger server application. Adjust this number based on your needs + and the resources available in your cluster. + +Relate the Testflinger server application with the MongoDB endpoint. + +.. code-block:: shell + + $ juju integrate testflinger-k8s mongodb + +Monitor the deployment progress until all units are active. + +.. code-block:: shell + + $ juju status --storage --relations --watch 5s + +Once all units are active, deploy and configure the ingress charm to +expose the Testflinger server API. + +.. code-block:: shell + + $ juju deploy nginx-ingress-integrator --trust + $ juju integrate nginx-ingress-integrator testflinger-k8s + $ juju config testflinger-k8s external-hostname=testflinger.local + +The deployment finishes when the status shows ``Ingress IP(s): 127.0.0.1`` +on ``nginx-ingress-integrator``. The IP addresses may differ based on your +Kubernetes cluster setup. + +.. important:: + + The above ingress deployment steps are intended for testing and + development purposes. For production deployments, it is recommended to + use TLS for secure communication. For more information on how to set + up TLS, refer to the + `NGINX Ingress Integrator charm documentation `_. + +Terraform +^^^^^^^^^ + +Testflinger also provides a Terraform module that automates the deployment +of the Testflinger server. The module is located in the +`server/terraform/ `_ directory of the Testflinger +repository. + +Variables +~~~~~~~~~ + +Create a ``terraform.tfvars`` file and define the following variables. + +.. code-block:: text + + jwt_signing_key = "(sensitive value)" + external_hostname = "testflinger.local" + +.. note:: + + Refer to ``server/terraform/variables.tf`` and + ``server/terraform/README.md`` for the full list of available variables + and their descriptions. + +Apply the Terraform plan +~~~~~~~~~~~~~~~~~~~~~~~~ + +Initialize Terraform and apply the plan. + +.. code-block:: shell + + $ terraform init + $ terraform apply # optionally run 'terraform plan' first + +Wait for the Juju units to finish their setup. + +.. code-block:: shell + + $ juju status --storage --relations --watch 5s + +Networking +---------- + +Ensure that your system can resolve and reach the ``external_hostname`` +configured earlier. For local testing, edit ``/etc/hosts`` to define +the name resolution. + +.. code-block:: text + + 127.0.0.1 testflinger.local + +Testflinger CLI +--------------- + +Testflinger CLI defaults to using ``testflinger.canonical.com`` as its +Testflinger server. To override the server being used, pass the +``--server`` flag or edit the ``testflinger-cli.conf`` configuration file. + +First, install Testflinger CLI. + +.. code-block:: shell + + $ sudo snap install testflinger-cli + +Then connect to the server. + +.. code-block:: shell + + $ testflinger-cli --server http://testflinger.local list-agents + +The CLI should not error out, though the list of agents may be empty. + +Refer to the :doc:`/reference/cli-config` reference for details on +configuring the CLI. diff --git a/docs/how-to/administer-server/index.rst b/docs/how-to/administer-server/index.rst new file mode 100644 index 000000000..bb6c14b71 --- /dev/null +++ b/docs/how-to/administer-server/index.rst @@ -0,0 +1,9 @@ +How to administer Testflinger server +==================================== + +This section contains guides on how to deploy and manage Testflinger Server. + +.. toctree:: + :maxdepth: 1 + + deploy-testflinger-server \ No newline at end of file diff --git a/docs/how-to/index.rst b/docs/how-to/index.rst index 06ce519b8..0a67d6c01 100644 --- a/docs/how-to/index.rst +++ b/docs/how-to/index.rst @@ -32,4 +32,5 @@ and outline tasks and best practices for operating and maintaining Testflinger d .. toctree:: :maxdepth: 1 - Administer agent hosts \ No newline at end of file + Administer agent hosts + Administer Testflinger server \ No newline at end of file diff --git a/docs/images/testflinger_architecture.png b/docs/images/testflinger_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..a7435338b5e9a6eb7321d9563cf022d9d2ea37e0 GIT binary patch literal 41964 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

bCEo&JGnjTuw)=2=34L;*j69ZR^1b2|Oy} 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 literal 0 HcmV?d00001 diff --git a/docs/reuse/links.txt b/docs/reuse/links.txt index 30f23168a..0e981f25f 100644 --- a/docs/reuse/links.txt +++ b/docs/reuse/links.txt @@ -4,8 +4,11 @@ .. _HPE Gen11: https://downloads.linux.hpe.com/SDR/repo/fwpp-gen11/ .. _HPE Gen12: https://downloads.linux.hpe.com/SDR/repo/fwpp-gen12/ .. _Juju CLI: https://documentation.ubuntu.com/juju/3.6/reference/juju-cli/list-of-juju-cli-commands/run/ +.. _nginx-ingress-tls: https://documentation.ubuntu.com/nginx-ingress-integrator-charm/latest/how-to/secure-an-ingress-with-tls/ .. _Security Policy: https://github.com/canonical/testflinger/blob/main/SECURITY.md .. _Security reporting and disclosure policy: https://ubuntu.com/security/disclosure-policy .. _snap: https://snapcraft.io/testflinger-cli +.. _testflinger-terraform: https://github.com/canonical/testflinger/tree/main/server/terraform .. _Ubuntu Code of Conduct: https://ubuntu.com/community/ethos/code-of-conduct -.. _Ubuntu Discourse: https://discourse.ubuntu.com/c/certification/165 \ No newline at end of file +.. _Ubuntu Discourse: https://discourse.ubuntu.com/c/certification/165 + From aab4c40c2489851fb30cec8b0fe9b3ce85945698 Mon Sep 17 00:00:00 2001 From: Rene Orozco Martinez Date: Wed, 20 May 2026 11:54:49 -0600 Subject: [PATCH 2/5] docs: update based on sanity check --- .../deploy-testflinger-server.rst | 83 +++++++++++++++--- docs/images/testflinger_architecture.png | Bin 41964 -> 0 bytes docs/images/testflinger_architecture.svg | 1 + docs/reuse/links.txt | 2 - 4 files changed, 70 insertions(+), 16 deletions(-) delete mode 100644 docs/images/testflinger_architecture.png create mode 100644 docs/images/testflinger_architecture.svg diff --git a/docs/how-to/administer-server/deploy-testflinger-server.rst b/docs/how-to/administer-server/deploy-testflinger-server.rst index c1b70cf80..23b246d1c 100644 --- a/docs/how-to/administer-server/deploy-testflinger-server.rst +++ b/docs/how-to/administer-server/deploy-testflinger-server.rst @@ -22,9 +22,24 @@ MongoDB as a K8s application. The following diagram illustrates the architecture of the Testflinger server deployment: -.. image:: ../../images/testflinger_architecture.png +.. image:: ../../images/testflinger_architecture.svg :alt: Testflinger server architecture diagram +In the above diagram, there is a single `Juju Controller `_ +that manages both the K8s and machine `Juju models `_. +In the machine model, only the MongoDB charm is deployed, while in the K8s +model, the Testflinger server charm and the NGINX Ingress Integrator charm +are deployed. + +To allow the Testflinger server to communicate with the MongoDB database we +need to setup a cross-model relation. This is achieved by offering the ``database`` +endpoint from the machine model and consuming it in the K8s model as a SAAS +application. The Testflinger server charm is then related with both +the ingress charm and the MongoDB SAAS via `Juju Integration `_ +to enable API access and database connectivity. For a more detailed guide +on how the cross-model relation is set up, please refer to the +`Juju How to Manage offers guide `_. + Prerequisites ------------- @@ -83,20 +98,15 @@ Set up the Juju controllers needed for the Testflinger server deployment. .. code-block:: shell - # Workaround to get localhost-controller to connect to microk8s - $ server_url=$(microk8s config | grep server | awk '{print $2;}') - $ sed -i "s|server: .*|server: $server_url|g" \ - /var/snap/microk8s/current/credentials/client.config - $ juju bootstrap microk8s microk8s-controller $ juju bootstrap localhost localhost-controller - $ juju add-cloud microk8s --controller localhost-controller + $ microk8s config | juju add-k8s localhost-microk8s --controller localhost-controller Then create the models for the server and database deployments. .. code-block:: shell $ juju add-model testflinger-db localhost - $ juju add-model testflinger microk8s + $ juju add-model testflinger localhost-microk8s MongoDB deployment ------------------ @@ -109,6 +119,8 @@ Deploy the MongoDB charm into the ``testflinger-db`` model. Once the deployment is complete, offer the MongoDB endpoint so that it can be consumed by the Testflinger server application in the K8s model. +For more information on how to use Juju ``offer``, please refer to the +`Juju offer CLI reference `_. .. code-block:: shell @@ -128,11 +140,13 @@ Juju CLI The following steps outline how to deploy the Testflinger server charm using the Juju CLI. -First, consume the MongoDB endpoint offered in the previous step. +First, consume the MongoDB endpoint offered in the previous step. For +more information on how to use Juju ``consume``, please refer to the +`Juju consume CLI reference `_. .. code-block:: shell - $ juju consume localhost:admin/testflinger-db.mongodb + $ juju consume localhost-controller:admin/testflinger-db.mongodb Deploy the Testflinger server charm. @@ -157,7 +171,7 @@ Relate the Testflinger server application with the MongoDB endpoint. .. code-block:: shell - $ juju integrate testflinger-k8s mongodb + $ juju integrate testflinger-k8s:mongodb_client mongodb:database Monitor the deployment progress until all units are active. @@ -172,13 +186,36 @@ expose the Testflinger server API. $ juju deploy nginx-ingress-integrator --trust $ juju integrate nginx-ingress-integrator testflinger-k8s - $ juju config testflinger-k8s external-hostname=testflinger.local + $ juju config testflinger-k8s external_hostname=testflinger.local The deployment finishes when the status shows ``Ingress IP(s): 127.0.0.1`` on ``nginx-ingress-integrator``. The IP addresses may differ based on your -Kubernetes cluster setup. +Kubernetes cluster setup. You can run the `juju status` command to +monitor the status of the deployment and check the assigned ingress IP address. -.. important:: +.. code-block:: shell + + $ juju status --storage --relations + Model Controller Cloud/Region Version SLA Timestamp + testflinger localhost-controller localhost-microk8s/localhost 3.6.21 unsupported 11:49:45-06:00 + + SAAS Status Store URL + mongodb active localhost-controller admin/testflinger-db.mongodb + + App Version Status Scale Charm Channel Rev Address Exposed Message + nginx-ingress-integrator 24.2.0 active 1 nginx-ingress-integrator latest/stable 203 10.152.183.35 no Ingress IP(s): 127.0.0.1 + testflinger-k8s ... active 1 testflinger-k8s latest/stable 288 10.152.183.88 no + + Unit Workload Agent Address Ports Message + nginx-ingress-integrator/0* active idle 10.1.153.199 Ingress IP(s): 127.0.0.1 + testflinger-k8s/0* active idle 10.1.153.198 + + Integration provider Requirer Interface Type Message + mongodb:database testflinger-k8s:mongodb_client mongodb_client regular + nginx-ingress-integrator:nginx-peers nginx-ingress-integrator:nginx-peers nginx-instance peer + nginx-ingress-integrator:nginx-route testflinger-k8s:nginx-route nginx-route regular + +.. warning:: The above ingress deployment steps are intended for testing and development purposes. For production deployments, it is recommended to @@ -194,6 +231,14 @@ of the Testflinger server. The module is located in the `server/terraform/ `_ directory of the Testflinger repository. +.. important:: + + The Terraform module will only deploy the Testflinger server charm, it is + user responsibility to setup a Terraform plan that deploys the Ingress charm + and configures the required relations. For a sample Terraform plan, + please refer to the `server/terraform/dev/main.tf `_ + file in the Testflinger repository. + Variables ~~~~~~~~~ @@ -260,3 +305,13 @@ The CLI should not error out, though the list of agents may be empty. Refer to the :doc:`/reference/cli-config` reference for details on configuring the CLI. + +.. _Juju Consume: https://documentation.ubuntu.com/juju/3.6/reference/juju-cli/list-of-juju-cli-commands/consume/ +.. _Juju Controller: https://documentation.ubuntu.com/juju/3.6/reference/controller/ +.. _Juju Offers Guide: https://documentation.ubuntu.com/juju/3.6/howto/manage-offers/#manage-offers +.. _Juju Integration: https://documentation.ubuntu.com/juju/3.6/reference/relation/ +.. _Juju Model: https://documentation.ubuntu.com/juju/3.6/reference/model/ +.. _Juju Offer: https://documentation.ubuntu.com/juju/3.6/reference/juju-cli/list-of-juju-cli-commands/offer/ +.. _nginx-ingress-tls: https://documentation.ubuntu.com/nginx-ingress-integrator-charm/latest/how-to/secure-an-ingress-with-tls/ +.. _testflinger-terraform: https://github.com/canonical/testflinger/tree/main/server/terraform +.. _testflinger-terraform-dev: https://github.com/canonical/testflinger/blob/main/server/terraform/dev/main.tf \ No newline at end of file diff --git a/docs/images/testflinger_architecture.png b/docs/images/testflinger_architecture.png deleted file mode 100644 index a7435338b5e9a6eb7321d9563cf022d9d2ea37e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41964 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

bCEo&JGnjTuw)=2=34L;*j69ZR^1b2|Oy} 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 diff --git a/docs/images/testflinger_architecture.svg b/docs/images/testflinger_architecture.svg new file mode 100644 index 000000000..98df37750 --- /dev/null +++ b/docs/images/testflinger_architecture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/reuse/links.txt b/docs/reuse/links.txt index 0e981f25f..7ed5e58b2 100644 --- a/docs/reuse/links.txt +++ b/docs/reuse/links.txt @@ -4,11 +4,9 @@ .. _HPE Gen11: https://downloads.linux.hpe.com/SDR/repo/fwpp-gen11/ .. _HPE Gen12: https://downloads.linux.hpe.com/SDR/repo/fwpp-gen12/ .. _Juju CLI: https://documentation.ubuntu.com/juju/3.6/reference/juju-cli/list-of-juju-cli-commands/run/ -.. _nginx-ingress-tls: https://documentation.ubuntu.com/nginx-ingress-integrator-charm/latest/how-to/secure-an-ingress-with-tls/ .. _Security Policy: https://github.com/canonical/testflinger/blob/main/SECURITY.md .. _Security reporting and disclosure policy: https://ubuntu.com/security/disclosure-policy .. _snap: https://snapcraft.io/testflinger-cli -.. _testflinger-terraform: https://github.com/canonical/testflinger/tree/main/server/terraform .. _Ubuntu Code of Conduct: https://ubuntu.com/community/ethos/code-of-conduct .. _Ubuntu Discourse: https://discourse.ubuntu.com/c/certification/165 From d9ef8e26912506384d6c6dc0307a44ae92f7d07e Mon Sep 17 00:00:00 2001 From: Rene Orozco Martinez Date: Wed, 20 May 2026 13:02:24 -0600 Subject: [PATCH 3/5] docs: add maintain section to server --- docs/how-to/administer-server/index.rst | 3 +- .../maintain-testflinger-server.rst | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 docs/how-to/administer-server/maintain-testflinger-server.rst diff --git a/docs/how-to/administer-server/index.rst b/docs/how-to/administer-server/index.rst index bb6c14b71..fc620579f 100644 --- a/docs/how-to/administer-server/index.rst +++ b/docs/how-to/administer-server/index.rst @@ -6,4 +6,5 @@ This section contains guides on how to deploy and manage Testflinger Server. .. toctree:: :maxdepth: 1 - deploy-testflinger-server \ No newline at end of file + deploy-testflinger-server + maintain-testflinger-server \ No newline at end of file diff --git a/docs/how-to/administer-server/maintain-testflinger-server.rst b/docs/how-to/administer-server/maintain-testflinger-server.rst new file mode 100644 index 000000000..c53ef2edf --- /dev/null +++ b/docs/how-to/administer-server/maintain-testflinger-server.rst @@ -0,0 +1,56 @@ +.. _howto-maintain-server: + +Maintain a Testflinger Server +============================= + +This guide outlines how to maintain a Testflinger server deployed with +Juju. To deploy a Testflinger server, please read the +:doc:`deploy-testflinger-server` guide. + +Refresh Testflinger Server +-------------------------- + +For updating the Testflinger server or charm code, you will need to +refresh the charm. + +.. code-block:: shell + + $ juju refresh testflinger-k8s + +.. tip:: + + You can optionally use the ``--channel`` flag to specify a different + channel to refresh from. + +Enable Testflinger Secrets +-------------------------- + +Testflinger server can be configured to allow using secrets to store +sensitive information in job definitions. To enable this feature, you +will need to configure a secret store backend. The following steps +specify how to enable secrets, for detailed information on Testflinger +secrets, please refer to :doc:`../../explanation/secrets`. + +MongoDB Client-Side Field Level Encryption +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To enable MongoDB Client-Side Field Level Encryption (CSFLE) for +secrets, you will need to configure the Testflinger server to use the +existing MongoDB charm deployment as the secret store backend. + +.. code-block:: shell + + $ juju integrate testflinger-k8s:mongodb_keyvault mongodb:database + $ juju config testflinger-k8s \ + testflinger_secrets_master_key="" + +The above command will automatically create a new database in the MongoDB charm +deployment, and allow Testflinger to connect to it. This database will be used +by Testflinger to store the encryption keys which can later be used to decrypt +secrets so that they can be accessed by agents at job runtime. + +.. note:: + + The ``testflinger_secrets_master_key`` is used to encrypt the CSFLE data keys + stored in MongoDB. Generate a secure random base64-encoded string by running + the following command: ``openssl rand -base64 96 | tr -d '\n'`` From 2f8d25c795988ea65e5ea1bedb37ddc1afb167d2 Mon Sep 17 00:00:00 2001 From: Rene Orozco Martinez Date: Wed, 20 May 2026 16:15:40 -0600 Subject: [PATCH 4/5] docs: add copilot suggestions --- docs/how-to/administer-server/deploy-testflinger-server.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/how-to/administer-server/deploy-testflinger-server.rst b/docs/how-to/administer-server/deploy-testflinger-server.rst index 23b246d1c..c574724ce 100644 --- a/docs/how-to/administer-server/deploy-testflinger-server.rst +++ b/docs/how-to/administer-server/deploy-testflinger-server.rst @@ -32,7 +32,7 @@ model, the Testflinger server charm and the NGINX Ingress Integrator charm are deployed. To allow the Testflinger server to communicate with the MongoDB database we -need to setup a cross-model relation. This is achieved by offering the ``database`` +need to set up a cross-model relation. This is achieved by offering the ``database`` endpoint from the machine model and consuming it in the K8s model as a SAAS application. The Testflinger server charm is then related with both the ingress charm and the MongoDB SAAS via `Juju Integration `_ @@ -234,7 +234,7 @@ repository. .. important:: The Terraform module will only deploy the Testflinger server charm, it is - user responsibility to setup a Terraform plan that deploys the Ingress charm + user responsibility to set up a Terraform plan that deploys the Ingress charm and configures the required relations. For a sample Terraform plan, please refer to the `server/terraform/dev/main.tf `_ file in the Testflinger repository. From 7876d029258b9d14a3b2e774888001000fad3750 Mon Sep 17 00:00:00 2001 From: Rene Orozco Martinez Date: Thu, 21 May 2026 17:06:20 -0600 Subject: [PATCH 5/5] add reviewer suggestions on diagram --- docs/images/testflinger_architecture.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/images/testflinger_architecture.svg b/docs/images/testflinger_architecture.svg index 98df37750..9c2ca69f7 100644 --- a/docs/images/testflinger_architecture.svg +++ b/docs/images/testflinger_architecture.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file