From 7c30c74d2f3d93ba62ecbfa610bc633e45f0a1a1 Mon Sep 17 00:00:00 2001 From: Nicholas Kuechler Date: Thu, 29 Jan 2026 14:22:24 -0600 Subject: [PATCH] ipa --- .github/workflows/containers.yaml | 3 ++ apps/site/ironic-prometheus-exporter.yaml | 6 +++ charts/argocd-understack/Chart.yaml | 2 +- ...cation-ironic-prometheus-exporter.yaml.tpl | 31 +++++++++++++ charts/argocd-understack/values.yaml | 9 ++++ components/images-openstack.yaml | 16 +++---- .../deployment.yaml | 46 +++++++++++++++++++ .../kustomization.yaml | 7 +++ .../service-monitor.yaml | 16 +++++++ .../ironic-prometheus-exporter/service.yaml | 16 +++++++ .../ironic-prometheus-exporter-pvc.yaml | 25 ++++++++++ components/ironic/kustomization.yaml | 2 + components/ironic/values.yaml | 5 ++ .../ironic-prometheus-exporter/Dockerfile | 35 ++++++++++++++ .../ironic-prometheus-exporter/README.md | 5 ++ .../requirements.txt | 2 + containers/ironic/Dockerfile | 3 +- 17 files changed, 219 insertions(+), 10 deletions(-) create mode 100644 apps/site/ironic-prometheus-exporter.yaml create mode 100644 charts/argocd-understack/templates/application-ironic-prometheus-exporter.yaml.tpl create mode 100644 components/ironic-prometheus-exporter/deployment.yaml create mode 100644 components/ironic-prometheus-exporter/kustomization.yaml create mode 100644 components/ironic-prometheus-exporter/service-monitor.yaml create mode 100644 components/ironic-prometheus-exporter/service.yaml create mode 100644 components/ironic/ironic-prometheus-exporter-pvc.yaml create mode 100644 containers/ironic-prometheus-exporter/Dockerfile create mode 100644 containers/ironic-prometheus-exporter/README.md create mode 100644 containers/ironic-prometheus-exporter/requirements.txt diff --git a/.github/workflows/containers.yaml b/.github/workflows/containers.yaml index 76eb282cc..cb1086df0 100644 --- a/.github/workflows/containers.yaml +++ b/.github/workflows/containers.yaml @@ -13,6 +13,7 @@ on: - "containers/ironic-nautobot-client/**" - "containers/ironic-vnc-client/**" - "containers/understack-tests/**" + - "containers/ironic-prometheus-exporter/**" - "python/**" - ".github/workflows/containers.yaml" - ".github/workflows/build-container-reuse.yaml" @@ -46,6 +47,8 @@ jobs: target: prod - name: nautobot target: prod + - name: ironic-prometheus-exporter + target: prod uses: ./.github/workflows/build-container-reuse.yaml secrets: inherit with: diff --git a/apps/site/ironic-prometheus-exporter.yaml b/apps/site/ironic-prometheus-exporter.yaml new file mode 100644 index 000000000..dac72204e --- /dev/null +++ b/apps/site/ironic-prometheus-exporter.yaml @@ -0,0 +1,6 @@ +--- +component: ironic-prometheus-exporter +componentNamespace: openstack +sources: + - ref: understack + path: 'components/ironic-prometheus-exporter' diff --git a/charts/argocd-understack/Chart.yaml b/charts/argocd-understack/Chart.yaml index 0599dd50a..055daad83 100644 --- a/charts/argocd-understack/Chart.yaml +++ b/charts/argocd-understack/Chart.yaml @@ -21,7 +21,7 @@ version: 0.1.0 # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.16.0" +appVersion: "1.16.1" maintainers: - name: rackerlabs diff --git a/charts/argocd-understack/templates/application-ironic-prometheus-exporter.yaml.tpl b/charts/argocd-understack/templates/application-ironic-prometheus-exporter.yaml.tpl new file mode 100644 index 000000000..cf6d21c62 --- /dev/null +++ b/charts/argocd-understack/templates/application-ironic-prometheus-exporter.yaml.tpl @@ -0,0 +1,31 @@ +{{- if or (eq (include "understack.isEnabled" (list $.Values.global "ironic_prometheus_exporter")) "true") (eq (include "understack.isEnabled" (list $.Values.site "ironic_prometheus_exporter")) "true") }} +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: {{ printf "%s-%s" $.Release.Name "ironic-prometheus-exporter" }} + annotations: + argocd.argoproj.io/compare-options: ServerSideDiff=true,IncludeMutationWebhook=true +spec: + destination: + namespace: openstack + server: {{ $.Values.cluster_server }} + project: understack + sources: + - path: components/ironic-prometheus-exporter + ref: understack + repoURL: {{ include "understack.understack_url" $ }} + targetRevision: {{ include "understack.understack_ref" $ }} + syncPolicy: + automated: + prune: true + selfHeal: true + managedNamespaceMetadata: + annotations: + argocd.argoproj.io/sync-options: Delete=false + syncOptions: + - CreateNamespace=true + - ServerSideApply=true + - RespectIgnoreDifferences=true + - ApplyOutOfSyncOnly=true +{{- end }} diff --git a/charts/argocd-understack/values.yaml b/charts/argocd-understack/values.yaml index cea3900fb..c6b106fcf 100644 --- a/charts/argocd-understack/values.yaml +++ b/charts/argocd-understack/values.yaml @@ -305,6 +305,15 @@ site: # renovate: datasource=helm depName=ironic registryUrl=https://tarballs.opendev.org/openstack/openstack-helm chartVersion: 2025.2.8+01c93d867 + # -- ironic-prometheus-exporter + ironic_prometheus_exporter: + # -- Enable/disable deploying ironic-prometheus-exporter + # @default -- true + enabled: true + # -- Sync wave for deployment ordering + # @default -- 4 + wave: 4 + # -- Neutron (Networking Service) neutron: # -- Enable/disable deploying Neutron diff --git a/components/images-openstack.yaml b/components/images-openstack.yaml index 41cadc93a..af6849ade 100644 --- a/components/images-openstack.yaml +++ b/components/images-openstack.yaml @@ -22,16 +22,16 @@ images: keystone_fernet_setup: "ghcr.io/rackerlabs/understack/keystone:2025.2" # ironic - ironic_api: "ghcr.io/rackerlabs/understack/ironic:2025.2" - ironic_conductor: "ghcr.io/rackerlabs/understack/ironic:2025.2" - ironic_pxe: "ghcr.io/rackerlabs/understack/ironic:2025.2" - ironic_pxe_init: "ghcr.io/rackerlabs/understack/ironic:2025.2" + ironic_api: "ghcr.io/rackerlabs/understack/ironic:pr-1673" + ironic_conductor: "ghcr.io/rackerlabs/understack/ironic:pr-1673" + ironic_pxe: "ghcr.io/rackerlabs/understack/ironic:pr-1673" + ironic_pxe_init: "ghcr.io/rackerlabs/understack/ironic:pr-1673" ironic_pxe_http: "docker.io/nginx:1.29.4" - ironic_db_sync: "ghcr.io/rackerlabs/understack/ironic:2025.2" + ironic_db_sync: "ghcr.io/rackerlabs/understack/ironic:pr-1673" # these want curl which apparently is in the openstack-client image - ironic_manage_cleaning_network: "ghcr.io/rackerlabs/understack/openstack-client:2025.2" - ironic_retrive_cleaning_network: "ghcr.io/rackerlabs/understack/openstack-client:2025.2" - ironic_retrive_swift_config: "ghcr.io/rackerlabs/understack/openstack-client:2025.2" + ironic_manage_cleaning_network: "ghcr.io/rackerlabs/understack/openstack-client:pr-1673" + ironic_retrive_cleaning_network: "ghcr.io/rackerlabs/understack/openstack-client:pr-1673" + ironic_retrive_swift_config: "ghcr.io/rackerlabs/understack/openstack-client:pr-1673" # neutron neutron_db_sync: "ghcr.io/rackerlabs/understack/neutron:2025.2" diff --git a/components/ironic-prometheus-exporter/deployment.yaml b/components/ironic-prometheus-exporter/deployment.yaml new file mode 100644 index 000000000..ee9da022d --- /dev/null +++ b/components/ironic-prometheus-exporter/deployment.yaml @@ -0,0 +1,46 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ironic-prometheus-exporter + namespace: openstack + labels: + app: ironic-prometheus-exporter +spec: + replicas: 1 + selector: + matchLabels: + app: ironic-prometheus-exporter + template: + metadata: + labels: + app: ironic-prometheus-exporter + spec: + containers: + - name: ironic-prometheus-exporter + image: ghcr.io/rackerlabs/understack/ironic-prometheus-exporter:pr-1673 + imagePullPolicy: IfNotPresent + ports: + - name: metrics + containerPort: 8000 + protocol: TCP + volumeMounts: + - name: ironic-prometheus-exporter + mountPath: /opt/stack/node_metrics + readOnly: true + # Uncomment and adjust if your container requires explicit arguments + # args: + # - --metrics-path + # - /opt/stack/node_metrics + # - --port + # - "8000" + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 250m + memory: 256Mi + volumes: + - name: ironic-prometheus-exporter + persistentVolumeClaim: + claimName: pvc-ironic-prometheus-exporter diff --git a/components/ironic-prometheus-exporter/kustomization.yaml b/components/ironic-prometheus-exporter/kustomization.yaml new file mode 100644 index 000000000..c5da2f354 --- /dev/null +++ b/components/ironic-prometheus-exporter/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - deployment.yaml + - service.yaml + - service-monitor.yaml diff --git a/components/ironic-prometheus-exporter/service-monitor.yaml b/components/ironic-prometheus-exporter/service-monitor.yaml new file mode 100644 index 000000000..2291e8b4e --- /dev/null +++ b/components/ironic-prometheus-exporter/service-monitor.yaml @@ -0,0 +1,16 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: ironic-prometheus-exporter + namespace: openstack +spec: + selector: + matchLabels: + app: ironic-prometheus-exporter + namespaceSelector: + matchNames: + - openstack + endpoints: + - port: metrics + interval: 30s + path: /metrics diff --git a/components/ironic-prometheus-exporter/service.yaml b/components/ironic-prometheus-exporter/service.yaml new file mode 100644 index 000000000..1f16f5d73 --- /dev/null +++ b/components/ironic-prometheus-exporter/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: ironic-prometheus-exporter + namespace: openstack + labels: + app: ironic-prometheus-exporter +spec: + type: ClusterIP + selector: + app: ironic-prometheus-exporter + ports: + - name: metrics + port: 8000 + targetPort: 8000 + protocol: TCP diff --git a/components/ironic/ironic-prometheus-exporter-pvc.yaml b/components/ironic/ironic-prometheus-exporter-pvc.yaml new file mode 100644 index 000000000..eff9de5c8 --- /dev/null +++ b/components/ironic/ironic-prometheus-exporter-pvc.yaml @@ -0,0 +1,25 @@ +# apiVersion: v1 +# kind: PersistentVolumeClaim +# metadata: +# labels: +# undercloud.local/purpose: ironic-prometheus-exporter +# name: pvc-ironic-prometheus-exporter +# namespace: openstack +# spec: +# accessModes: +# - ReadWriteOnce +# resources: +# requests: +# storage: 1Gi +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pvc-ironic-prometheus-exporter + namespace: openstack +spec: + storageClassName: ceph-fs-ec + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/components/ironic/kustomization.yaml b/components/ironic/kustomization.yaml index cb86508cd..c3a5bbba9 100644 --- a/components/ironic/kustomization.yaml +++ b/components/ironic/kustomization.yaml @@ -20,3 +20,5 @@ resources: # Alerting - pr-clean-failed-servers.yaml - pr-resource-availability.yaml + # ironic-prometheus-exporter + - ironic-prometheus-exporter-pvc.yaml diff --git a/components/ironic/values.yaml b/components/ironic/values.yaml index 8e52e5a40..538d4c856 100644 --- a/components/ironic/values.yaml +++ b/components/ironic/values.yaml @@ -230,6 +230,8 @@ pod: - name: ironic-etc-snippets mountPath: /etc/ironic/ironic.conf.d readOnly: true + - name: ironic-prometheus-exporter + mountPath: /opt/stack/node_metrics volumes: - name: dnsmasq-ironic persistentVolumeClaim: @@ -247,6 +249,9 @@ pod: name: ironic-ks-etc - name: pod-usr-share-novnc emptyDir: {} + - name: ironic-prometheus-exporter + persistentVolumeClaim: + claimName: pvc-ironic-prometheus-exporter ironic_api: ironic_api: volumeMounts: diff --git a/containers/ironic-prometheus-exporter/Dockerfile b/containers/ironic-prometheus-exporter/Dockerfile new file mode 100644 index 000000000..b38e75a54 --- /dev/null +++ b/containers/ironic-prometheus-exporter/Dockerfile @@ -0,0 +1,35 @@ +FROM python:3.12-slim AS prod + +ENV PIP_NO_CACHE_DIR=off \ + PIP_DISABLE_PIP_VERSION_CHECK=on \ + PIP_DEFAULT_TIMEOUT=100 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + git \ + && apt-get autoremove -y \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +COPY containers/ironic-prometheus-exporter/requirements.txt / + +RUN --mount=type=cache,target=/root/.cache/pip pip install -r /requirements.txt dumb-init==1.2.5 + +RUN useradd -m -d /runner -s /bin/bash runner +WORKDIR /runner +USER runner + +# RUN --mount=type=cache,target=/root/.cache/pip ansible-galaxy collection install -r /requirements.yml + +# ENTRYPOINT ["dumb-init"] +# CMD ["ansible-runner"] +CMD ["python", "-m", "flask", "run"] +# gunicorn3 -b :9608 \ +# --env IRONIC_CONFIG=$IRONIC_CONFIG \ +# --env FLASK_DEBUG=1 -w 4 \ +# --access-logfile=ipe_access.log \ +# --error-logfile=ipe_errors.log \ +# -D ironic_prometheus_exporter.app.wsgi:application +# CMD [ +# "gunicorn", "-b", "0.0.0.0:9608" +# ] diff --git a/containers/ironic-prometheus-exporter/README.md b/containers/ironic-prometheus-exporter/README.md new file mode 100644 index 000000000..39c0a9ca5 --- /dev/null +++ b/containers/ironic-prometheus-exporter/README.md @@ -0,0 +1,5 @@ +# ironic-prometheus-exporter + +``` bash +docker build -t ironic-prometheus-exporter -f containers/ironic-prometheus-exporter/Dockerfile . +``` diff --git a/containers/ironic-prometheus-exporter/requirements.txt b/containers/ironic-prometheus-exporter/requirements.txt new file mode 100644 index 000000000..79876bc1c --- /dev/null +++ b/containers/ironic-prometheus-exporter/requirements.txt @@ -0,0 +1,2 @@ +ironic-prometheus-exporter +gunicorn diff --git a/containers/ironic/Dockerfile b/containers/ironic/Dockerfile index e2aab70eb..b57eb8960 100644 --- a/containers/ironic/Dockerfile +++ b/containers/ironic/Dockerfile @@ -29,7 +29,8 @@ RUN --mount=type=cache,target=/root/.cache/uv \ /src/ironic \ /src/understack/ironic-understack \ /src/understack/understack-flavor-matcher \ - proliantutils==2.16.3 + proliantutils==2.16.3 \ + ironic-prometheus-exporter==4.7.0 COPY containers/ironic/patches /tmp/patches/ RUN cd /var/lib/openstack/lib/python3.12/site-packages && \