Skip to content
This repository has been archived by the owner on Feb 22, 2022. It is now read-only.

Commit

Permalink
[stable/jenkins] Add support for namespace specification
Browse files Browse the repository at this point in the history
Signed-off-by: Nico Rikken <nico@nicorikken.eu>
  • Loading branch information
nicorikken committed Jul 2, 2019
1 parent cfb732f commit 21ec22e
Show file tree
Hide file tree
Showing 25 changed files with 70 additions and 25 deletions.
2 changes: 1 addition & 1 deletion stable/jenkins/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v1
name: jenkins
home: https://jenkins.io/
version: 1.3.3
version: 1.3.4
appVersion: lts
description: Open source continuous integration server. It supports multiple SCM tools
including CVS, Subversion and Git. It can execute Apache Ant and Apache Maven-based
Expand Down
3 changes: 2 additions & 1 deletion stable/jenkins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ The following tables list the configurable parameters of the Jenkins chart and t
| `checkDeprecation` | Checks for deprecated values used | `true` |
| `clusterZone` | Override the cluster name for FQDN resolving | `cluster.local` |
| `nameOverride` | Override the resource name prefix | `jenkins` |
| `fullnameOverride` | Override the full resource names | `jenkins-{release-name}` (or `jenkins` if release-name is `jenkins`) |
| `fullnameOverride` | Override the deployment namespace | Not set (`Release.Namespace`) |
| `namespaceOverride` | Override the full resource names | `jenkins-{release-name}` (or `jenkins` if release-name is `jenkins`) |
| `master.componentName` | Jenkins master name | `jenkins-master` |
| `master.image` | Master image name | `jenkins/jenkins` |
| `master.imageTag` | Master image tag | `lts` |
Expand Down
14 changes: 7 additions & 7 deletions stable/jenkins/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
1. Get your '{{ .Values.master.adminUser }}' user password by running:
printf $(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "jenkins.fullname" . }} -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
printf $(kubectl get secret --namespace {{ template "jenkins.namespace" . }} {{ template "jenkins.fullname" . }} -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo

{{- if .Values.master.ingress.hostName }}

2. Visit http://{{ .Values.master.ingress.hostName }}
{{- else }}
2. Get the Jenkins URL to visit by running these commands in the same shell:
{{- if contains "NodePort" .Values.master.serviceType }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "jenkins.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
export NODE_PORT=$(kubectl get --namespace {{ template "jenkins.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "jenkins.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ template "jenkins.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT/login

{{- else if contains "LoadBalancer" .Values.master.serviceType }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "jenkins.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "jenkins.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}")
You can watch the status of by running 'kubectl get svc --namespace {{ template "jenkins.namespace" . }} -w {{ template "jenkins.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ template "jenkins.namespace" . }} {{ template "jenkins.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}")
echo http://$SERVICE_IP:{{ .Values.master.servicePort }}/login

{{- else if contains "ClusterIP" .Values.master.serviceType }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/component={{ .Values.master.componentName }}" -l "app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export POD_NAME=$(kubectl get pods --namespace {{ template "jenkins.namespace" . }} -l "app.kubernetes.io/component={{ .Values.master.componentName }}" -l "app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo http://127.0.0.1:{{ .Values.master.servicePort }}
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME {{ .Values.master.servicePort }}:{{ .Values.master.servicePort }}
kubectl --namespace {{ template "jenkins.namespace" . }} port-forward $POD_NAME {{ .Values.master.servicePort }}:{{ .Values.master.servicePort }}

{{- end }}
{{- end }}
Expand Down
24 changes: 24 additions & 0 deletions stable/jenkins/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ Expand the name of the chart.
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Allow the release namespace to be overridden for multi-namespace deployments in combined charts.
*/}}
{{- define "jenkins.namespace" -}}
{{- if .Values.namespaceOverride -}}
{{- .Values.namespaceOverride -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}

{{- define "jenkins.master.slaveKubernetesNamespace" -}}
{{- if .Values.master.slaveKubernetesNamespace -}}
{{- .Values.master.slaveKubernetesNamespace -}}
{{- else -}}
{{- if .Values.namespaceOverride -}}
{{- .Values.namespaceOverride -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
{{- end -}}


{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
Expand Down
9 changes: 5 additions & 4 deletions stable/jenkins/templates/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down Expand Up @@ -92,7 +93,7 @@ data:
<envVars>
<org.csanchez.jenkins.plugins.kubernetes.ContainerEnvVar>
<key>JENKINS_URL</key>
<value>http://{{ template "jenkins.fullname" . }}.{{.Release.Namespace}}.svc.{{.Values.clusterZone}}:{{.Values.master.servicePort}}{{ default "" .Values.master.jenkinsUriPrefix }}</value>
<value>http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.master.servicePort}}{{ default "" .Values.master.jenkinsUriPrefix }}</value>
</org.csanchez.jenkins.plugins.kubernetes.ContainerEnvVar>
</envVars>
</org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate>
Expand Down Expand Up @@ -125,10 +126,10 @@ data:
</templates>
<serverUrl>https://kubernetes.default</serverUrl>
<skipTlsVerify>false</skipTlsVerify>
<namespace>{{ default .Release.Namespace .Values.master.slaveKubernetesNamespace }}</namespace>
<namespace>{{ template "jenkins.master.slaveKubernetesNamespace" . }}</namespace>
{{- if .Values.master.slaveKubernetesNamespace }}
<jenkinsUrl>http://{{ template "jenkins.fullname" . }}.{{.Release.Namespace}}:{{.Values.master.servicePort}}{{ default "" .Values.master.jenkinsUriPrefix }}</jenkinsUrl>
<jenkinsTunnel>{{ template "jenkins.fullname" . }}-agent.{{.Release.Namespace}}:{{ .Values.master.slaveListenerPort }}</jenkinsTunnel>
<jenkinsUrl>http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}:{{.Values.master.servicePort}}{{ default "" .Values.master.jenkinsUriPrefix }}</jenkinsUrl>
<jenkinsTunnel>{{ template "jenkins.fullname" . }}-agent.{{ template "jenkins.namespace" . }}:{{ .Values.master.slaveListenerPort }}</jenkinsTunnel>
{{- else }}
<jenkinsUrl>http://{{ template "jenkins.fullname" . }}:{{.Values.master.servicePort}}{{ default "" .Values.master.jenkinsUriPrefix }}</jenkinsUrl>
<jenkinsTunnel>{{ template "jenkins.fullname" . }}-agent:{{ .Values.master.slaveListenerPort }}</jenkinsTunnel>
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/home-pvc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ metadata:
{{ toYaml .Values.persistence.annotations | indent 4 }}
{{- end }}
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/jcasc-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.fullname" $root }}-jenkins-config-{{ $key }}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": {{ template "jenkins.name" $root}}
"helm.sh/chart": {{ $.Chart.Name }}-{{ $.Chart.Version }}
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/jenkins-agent-svc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ apiVersion: v1
kind: Service
metadata:
name: {{ template "jenkins.fullname" . }}-agent
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
3 changes: 2 additions & 1 deletion stable/jenkins/templates/jenkins-backup-cronjob.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: {{ template "jenkins.fullname" . }}-backup
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -29,7 +30,7 @@ spec:
args:
- simple-backup
- -n
- {{ .Release.Namespace }}
- {{ template "jenkins.namespace" . }}
- -l
- app.kubernetes.io/instance={{ .Release.Name }}
- --container
Expand Down
5 changes: 4 additions & 1 deletion stable/jenkins/templates/jenkins-backup-rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "jenkins.fullname" . }}-backup
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -14,6 +15,7 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ template "jenkins.fullname" . }}-backup
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -32,6 +34,7 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ template "jenkins.fullname" . }}-backup
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -45,5 +48,5 @@ roleRef:
subjects:
- kind: ServiceAccount
name: {{ template "jenkins.fullname" . }}-backup
namespace: {{ .Release.Namespace }}
namespace: {{ template "jenkins.namespace" . }}
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/jenkins-master-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/jenkins-master-ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
apiVersion: {{ .Values.master.ingress.apiVersion }}
kind: Ingress
metadata:
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
2 changes: 2 additions & 0 deletions stable/jenkins/templates/jenkins-master-networkpolicy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ kind: NetworkPolicy
apiVersion: {{ .Values.networkPolicy.apiVersion }}
metadata:
name: "{{ .Release.Name }}-{{ .Values.master.componentName }}"
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down Expand Up @@ -31,6 +32,7 @@ kind: NetworkPolicy
apiVersion: {{ .Values.networkPolicy.apiVersion }}
metadata:
name: "{{ .Release.Name }}-{{ .Values.agent.componentName }}"
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/jenkins-master-route.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
apiVersion: route.openshift.io/v1
kind: Route
metadata:
namespace: {{ template "jenkins.namespace" . }}
labels:
app: {{ template "jenkins.fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
3 changes: 2 additions & 1 deletion stable/jenkins/templates/jenkins-master-servicemonitor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ kind: ServiceMonitor

metadata:
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -22,7 +23,7 @@ spec:
jobLabel: {{ template "jenkins.fullname" . }}
namespaceSelector:
matchNames:
- "{{ $.Release.Namespace }}"
- "{{ template "jenkins.namespace" $ }}"
selector:
matchLabels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/jenkins-master-svc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ apiVersion: v1
kind: Service
metadata:
name: {{template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/jobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.fullname" . }}-jobs
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
12 changes: 6 additions & 6 deletions stable/jenkins/templates/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ $serviceName }}-schedule-agents
namespace: {{ .Values.master.slaveKubernetesNamespace | default .Release.Namespace}}
namespace: {{ template "jenkins.master.slaveKubernetesNamespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -26,7 +26,7 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $serviceName }}-schedule-agents
namespace: {{ .Values.master.slaveKubernetesNamespace | default .Release.Namespace}}
namespace: {{ template "jenkins.master.slaveKubernetesNamespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -40,7 +40,7 @@ roleRef:
subjects:
- kind: ServiceAccount
name: {{ template "jenkins.serviceAccountName" .}}
namespace: {{ .Release.Namespace }}
namespace: {{ template "jenkins.namespace" . }}

---

Expand All @@ -51,7 +51,7 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ template "jenkins.fullname" . }}-casc-reload
namespace: {{ .Release.Namespace}}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -69,7 +69,7 @@ apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $serviceName }}-watch-configmaps
namespace: {{ .Release.Namespace}}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand All @@ -83,7 +83,7 @@ roleRef:
subjects:
- kind: ServiceAccount
name: {{ template "jenkins.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
namespace: {{ template "jenkins.namespace" . }}

{{- end}}

Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ apiVersion: v1
kind: Secret
metadata:
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"helm.sh/chart": "{{ .Chart.Name }}-{{ .Chart.Version }}"
Expand Down
4 changes: 1 addition & 3 deletions stable/jenkins/templates/service-account-agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "jenkins.serviceAccountAgentName" . }}
{{- if .Values.master.slaveKubernetesNamespace }}
namespace: {{ .Values.master.slaveKubernetesNamespace }}
{{ end }}
namespace: {{ template "jenkins.master.slaveKubernetesNamespace" . }}
{{- if .Values.serviceAccountAgent.annotations }}
annotations:
{{ toYaml .Values.serviceAccountAgent.annotations | indent 4 }}
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/service-account.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "jenkins.serviceAccountName" . }}
namespace: {{ template "jenkins.namespace" . }}
{{- if .Values.serviceAccount.annotations }}
annotations:
{{ toYaml .Values.serviceAccount.annotations | indent 4 }}
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/tests/jenkins-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-ui-test-{{ randAlphaNum 5 | lower }}"
namespace: {{ template "jenkins.namespace" . }}
annotations:
"helm.sh/hook": test-success
spec:
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/templates/tests/test-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.fullname" . }}-tests
namespace: {{ template "jenkins.namespace" . }}
data:
run.sh: |-
@test "Testing Jenkins UI is accessible" {
Expand Down
1 change: 1 addition & 0 deletions stable/jenkins/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# See templates/_helpers.tpl
# nameOverride:
# fullnameOverride:
# namespaceOverride:

# For FQDN resolving of the master service. Change this value to match your existing configuration.
# ref: /~https://github.com/kubernetes/dns/blob/master/docs/specification.md
Expand Down

0 comments on commit 21ec22e

Please sign in to comment.