Compare commits

..

8 Commits

Author SHA1 Message Date
Márcio Fernandes 3a3f64a59b modified: .gitea/workflows/deploy.yaml
Casa Home Assistant CI/CD Pipeline (testing) / build (push) Successful in 14s
2025-11-22 02:51:41 +00:00
Márcio Fernandes 160176f905 modified: .gitea/workflows/deploy.yaml 2025-11-22 02:42:52 +00:00
Márcio Fernandes d8e6d72e25 simple kubectl test
Casa Home Assistant CI/CD Pipeline (testing) / build (push) Waiting to run
2025-11-22 02:30:43 +00:00
Márcio Fernandes 1b7b53ddd1 added GITHUB_TEMP env
Casa Home Assistant CI/CD Pipeline (testing) / build (push) Waiting to run
2025-11-22 02:25:39 +00:00
Márcio Fernandes ac33cbfc6d fx actions folder name
Casa Home Assistant CI/CD Pipeline (testing) / build (push) Failing after 14s
2025-11-22 02:20:02 +00:00
Márcio Fernandes cf4dd050ca re enable actions
Casa Home Assistant CI/CD Pipeline (testing) / build (push) Failing after 15s
2025-11-22 02:17:22 +00:00
Márcio Fernandes 473808832b fix runs-on
Casa Home Assistant CI/CD Pipeline (testing) / build (push) Successful in 15s
2025-11-22 02:16:12 +00:00
Márcio Fernandes f29285d800 clean up workflow
Casa Home Assistant CI/CD Pipeline (testing) / build (push) Has been cancelled
2025-11-22 02:13:36 +00:00
20 changed files with 239 additions and 190 deletions
+45
View File
@@ -0,0 +1,45 @@
name: Setup kubectl
description: "Reads kube config from inputs and sets KUBECONFIG"
inputs:
kube_server:
description: "Kubernetes API server address"
required: true
kube_ca_base64:
description: "Base64-encoded CA certificate"
required: true
kube_token:
description: "ServiceAccount token"
required: true
runs:
using: "composite"
steps:
- name: Create kubeconfig
shell: bash
run: |
set -euo pipefail
mkdir -p "${GITHUB_TEMP}/.kube"
cat <<EOF > "${GITHUB_TEMP}/.kube/config"
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority-data: ${{ inputs.kube_ca_base64 }}
server: ${{ inputs.kube_server }}
name: cluster
contexts:
- context:
cluster: cluster
namespace: default
user: user
name: context
current-context: context
users:
- name: user
user:
token: ${{ inputs.kube_token }}
EOF
echo "KUBECONFIG=${GITHUB_TEMP}/.kube/config" >> "${GITHUB_ENV}"
+59
View File
@@ -0,0 +1,59 @@
name: Casa Home Assistant CI/CD Pipeline (testing)
on:
push:
branches:
- fix/*
- main
pull_request:
jobs:
build:
runs-on: casa-vlan-cicd
env:
GITHUB_TEMP: ${{ runner.temp }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Debug runner paths
run: |
echo "Runner temp: ${{ runner.temp }}"
echo "Workspace: ${{ gitea.workspace }}"
ls -l ${{ runner.temp }}
ls -l ${{ gitea.workspace }}
- name: Setup kubectl
uses: ./.gitea/actions/kubectl-setup
with:
kube_server: ${{ secrets.casa_vlan_kube_server }}
kube_ca_base64: ${{ secrets.casa_vlan_kube_ca_base64 }}
kube_token: ${{ secrets.casa_vlan_kube_token }}
- name: Debug runner paths
run: |
echo "Runner temp: ${{ runner.temp }}"
echo "Workspace: ${{ gitea.workspace }}"
ls -l ${{ runner.temp }}
ls -l ${{ gitea.workspace }}
# - name: Deploy Home Assistant
# shell: bash
# run: |
# set -x
# echo "KUBECONFIG=$KUBECONFIG"
# kubectl config view
# kubectl get pods --request-timeout=10s
# - name: Deploy Home Assistant
# shell: bash
# run: |
# set -e
# cd ${{ gitea.workspace }}
# export ENDPOINT_IP="${{ secrets.ENDPOINT_IP }}"
# export SERVICE_PORT=${{ secrets.SERVICE_PORT }}
# export INGRESS_ROUTES_MATCH="${{ secrets.INGRESS_ROUTES_MATCH }}"
# export INGRESS_TLS_SECRET_NAME=${{ secrets.INGRESS_TLS_SECRET_NAME }}
# kubectl apply -f ./deploy/deployment.yaml
# envsubst < ./deploy/service.template.yaml | kubectl apply -f -
+4 -7
View File
@@ -2,9 +2,10 @@
Welcome to my Home Assistant setup repository.
This repository documents and maintains the Home Assistant instance running in my home, hosted on casa server k3s cluster.
Related containers, such as MQTT and speech recognition, are hosted on same cluster.
All essential containers, such as MQTT and speech recognition, are hosted on the same server for seamless integration.
**Table of Contents:**
<!-- omit in toc -->
## Table of Contents
- [Devices](#devices)
- [Broadlink - RM4 Pro](#broadlink---rm4-pro)
@@ -254,8 +255,4 @@ Home Assistant authenticates with Xbox Live through OAuth2 using the Home Assist
## Setup
Using flux for reconciliation.
``` bash
./ops-scripts/apply-flux.sh
```
[Deploy documentation](./deploy/README.md).
+51
View File
@@ -0,0 +1,51 @@
# Home Assistant Deploy
## Namespace
```bash { cwd=../ terminalRows=15 }
# from repo root folder
kubectl create namespace home-assistant
```
## Deployment
### Environments requirements
``` bash
#./deploy/.env
export ENDPOINT_IP="xxx.xxx.xxx.xxxx"
export SERVICE_PORT=xxxx
export INGRESS_ROUTES_MATCH="Host(`xxxx`)"
export INGRESS_TLS_SECRET_NAME=xxxxxx
```
## Test Templates
```bash { cwd=../ terminalRows=15 }
# from repo root folder
source ./deploy/.env \
&& cat ./deploy/deployment.yaml \
&& envsubst < ./deploy/service.template.yaml
```
## Deploy
```bash { cwd=../ terminalRows=15 }
# from repo root folder
source ./deploy/.env \
&& kubectl apply -f ./deploy/deployment.yaml \
&& envsubst < ./deploy/service.template.yaml | kubectl apply -f -
```
## Continuos Deploy
All Environment variables requirements as set as secrets.
[gitea workflow](../.gitea/workflows/deploy.yaml)
## RBAC
```bash { cwd=../ }
kubectl apply -f ./deploy/rbac.yaml
```
-13
View File
@@ -1,13 +0,0 @@
apiVersion: image.toolkit.fluxcd.io/v1
kind: ImagePolicy
metadata:
name: home-assistant
spec:
imageRepositoryRef:
name: home-assistant
filterTags:
pattern: '^latest$'
policy:
alphabetical: {}
digestReflectionPolicy: Always
interval: 24h
-7
View File
@@ -1,7 +0,0 @@
apiVersion: image.toolkit.fluxcd.io/v1
kind: ImageRepository
metadata:
name: home-assistant
spec:
image: homeassistant/home-assistant
interval: 72h
-24
View File
@@ -1,24 +0,0 @@
apiVersion: image.toolkit.fluxcd.io/v1
kind: ImageUpdateAutomation
metadata:
name: home-assistant
spec:
interval: 72h
sourceRef:
kind: GitRepository
name: home-assistant
git:
checkout:
ref:
branch: master
commit:
author:
name: FluxCD
email: flux@local
messageTemplate: |
Update home-assistant image.
push:
branch: master
update:
path: ./deploy/app/statefulset.yaml
strategy: Setters
-10
View File
@@ -1,10 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: home-assistant
resources:
- pvc.yaml
- statefulset.yaml
- service.yaml
- image-policy.yaml
- image-repo.yaml
- image-update-automation.yaml
-11
View File
@@ -1,11 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: home-assistant-config
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
storageClassName: local-path
@@ -1,7 +1,24 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: home-assistant-config
namespace: home-assistant
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: home-assistant
namespace: home-assistant
labels:
app: home-assistant
spec:
@@ -16,19 +33,17 @@ spec:
spec:
dnsPolicy: ClusterFirstWithHostNet # ensures pod uses cluster DNS (CoreDNS) for service discovery even with host networking
hostNetwork: true
nodeName: casa # force deploy to master node cluster
tolerations:
- key: "node-role.kubernetes.io/control-plane" # allow installation on control-plane
operator: "Exists"
effect: "NoSchedule"
# delays start so host have time to start on low memory resources
# initContainers:
# - name: delay-start
# image: busybox:latest
# command: ["sh", "-c", "sleep 60"]
containers:
- name: home-assistant
### Maintained by flux - Image Update Automation
image: homeassistant/home-assistant:latest@sha256:aed891b8f801072302815b4b0fab5adb714182967e9d2e2d4a2be558241c73ad # {"$imagepolicy": "home-assistant:home-assistant"}
imagePullPolicy: IfNotPresent
image: "homeassistant/home-assistant"
env:
- name: TZ
value: Europe/Lisbon
value: Europe/Lisbon # set timezone
volumeMounts:
- name: home-assistant-config
mountPath: /config
-2
View File
@@ -1,2 +0,0 @@
**
!.gitignore
-12
View File
@@ -1,12 +0,0 @@
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: home-assistant
spec:
interval: 1m
sourceRef:
kind: GitRepository
name: home-assistant
path: deploy/app
prune: true
-11
View File
@@ -1,11 +0,0 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: home-assistant
spec:
interval: 1m0s
url: ssh://git@git.limbosolutions.com:2222/marcio.fernandes/homeAssistant.git
ref:
branch: master
secretRef:
name: flux-repo-ssh-credentials
-19
View File
@@ -1,19 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: home-assistant
resources:
- git-repo.yaml
- app-sync.yaml
secretGenerator:
- name: flux-repo-ssh-credentials
namespace: home-assistant
files:
- "identity=./.env.d/flux-repo-ssh-key"
- "known_hosts=./.env.d/flux-repo-ssh-known_hosts"
- "pubkey=./.env.d/flux-repo-ssh-key.pub"
- name: flux-sops-age
namespace: home-assistant
files:
- "age.agekey=./.env.d/age.agekey"
generatorOptions:
disableNameSuffixHash: true
+34
View File
@@ -0,0 +1,34 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: home-assistant
name: ci-cd
rules:
- apiGroups: [""]
resources: ["pods", "services", "secrets", "configmaps", "persistentvolumeclaims", "endpoints"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
- apiGroups: ["traefik.io"]
resources: ["ingressroutes"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-cd
namespace: home-assistant
subjects:
- kind: ServiceAccount
name: casa-ci-cd
namespace: home-assistant
roleRef:
kind: Role
name: ci-cd
apiGroup: rbac.authorization.k8s.io
+7
View File
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: casa-ci-cd
annotations:
kubernetes.io/service-account.name: casa-ci-cd
type: kubernetes.io/service-account-token
+6
View File
@@ -0,0 +1,6 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: casa-ci-cd
namespace: home-assistant
@@ -3,10 +3,11 @@ apiVersion: v1
kind: Service
metadata:
name: home-assistant
namespace: home-assistant
spec:
clusterIP: None
ports:
- port: 8123
- port: ${SERVICE_PORT}
protocol: TCP
---
@@ -15,25 +16,27 @@ apiVersion: v1
kind: Endpoints
metadata:
name: home-assistant
namespace: home-assistant
subsets:
- addresses:
- ip: 192.168.14.9
- ip: ${ENDPOINT_IP}
ports:
- port: 8123
- port: ${SERVICE_PORT}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: home-assistant
namespace: home-assistant
spec:
entryPoints:
- websecure
routes:
- match: Host(`casa.limbosolutions.com`) || Host(`has.casa.limbosolutions.com`)
- match: ${INGRESS_ROUTES_MATCH}
kind: Rule
services:
- name: home-assistant
port: 8123
port: ${SERVICE_PORT}
tls:
secretName: casa-limbosolutions-com-tls
secretName: ${INGRESS_TLS_SECRET_NAME}
-55
View File
@@ -1,55 +0,0 @@
# tests
## logs from loki
```python
# loki-get-last-to-sensor.py
import sys, os, requests, datetime, time, json
url = os.environ.get("LOKI_ADDRESS")
if not url:
print(json.dumps({"state": "error", "log_message": "LOKI_ADDRESS is not set or empty"}))
sys.exit(1)
query = os.environ.get("LOKI_QUERY")
if not query:
print(json.dumps({"state": "error", "log_message": "LOKI_ADDRESS is not set or empty"}))
sys.exit(1)
end = int(time.time()) * 1_000_000_000
start = (int(time.time()) - 24*60*60) * 1_000_000_000
params = {
"query": query,
"limit": 1,
"direction": "backward",
"start": str(start),
"end": str(end),
}
resp = requests.get(url, params=params)
data = resp.json()
try:
ns = int(data["data"]["result"][0]["values"][0][0])
ts = ns / 1_000_000_000
dt = datetime.datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M:%S")
print(json.dumps({
"state": dt,
}))
except Exception:
print(json.dumps({"state": "unknown"}))
```
```yaml
# example of the sensor
name: git_limbosolutions_com_last_pbs_backup
command: >
LOKI_ADDRESS=${LOKI_ADDRESS} LOKI_QUERY="{job=\"git-limbosolutions-com/pbs-backup\"} |= \"INFO: Finished Backup\"" python3 /config/scripts/loki-get-last-to-sensor.py
value_template: "{{ value }}"
```
-4
View File
@@ -1,4 +0,0 @@
#!/bin/bash
set -e
kubectl kustomize deploy/flux | kubectl apply -f -