added initial cloud files to c4k-nextcloud
This commit is contained in:
parent
6732be46a5
commit
1c2f6b89f2
79 changed files with 1512 additions and 571 deletions
42
README.md
42
README.md
|
@ -1,41 +1,5 @@
|
|||
# convention 4 kubernetes: c4k-nextcloud
|
||||
# meissa-cloud
|
||||
|
||||
[![Clojars Project](https://img.shields.io/clojars/v/org.domaindrivenarchitecture/c4k-nextcloud.svg)](https://clojars.org/org.domaindrivenarchitecture/c4k-nextcloud) [![pipeline status](https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/badges/master/pipeline.svg)](https://gitlab.com/domaindrivenarchitecture/c4k-nextcloud/-/commits/master)
|
||||
# backup manuell triggern
|
||||
|
||||
[<img src="https://domaindrivenarchitecture.org/img/delta-chat.svg" width=20 alt="DeltaChat"> chat over e-mail](mailto:buero@meissa-gmbh.de?subject=community-chat) | [<img src="https://meissa-gmbh.de/img/community/Mastodon_Logotype.svg" width=20 alt="team@social.meissa-gmbh.de"> team@social.meissa-gmbh.de](https://social.meissa-gmbh.de/@team) | [Website & Blog](https://domaindrivenarchitecture.org)
|
||||
|
||||
## Purpose
|
||||
|
||||
c4k-nextcloud provides a k8s deployment for nextcloud containing:
|
||||
* adjusted nextcloud docker image
|
||||
* nextcloud
|
||||
* ingress having a letsencrypt managed certificate
|
||||
* postgres database
|
||||
|
||||
The package aims to a low load sceanrio.
|
||||
|
||||
## Status
|
||||
|
||||
This is under development.
|
||||
|
||||
## Manual restore
|
||||
|
||||
1) Scale Nextcloud deployment down:
|
||||
kubectl scale deployment nextcloud --replicas=0
|
||||
|
||||
2) apply backup and restore pod:
|
||||
kubectl apply -f src/main/resources/backup/backup-restore.yaml
|
||||
|
||||
3) exec into pod and execute restore pod
|
||||
kubectl exec -it backup-restore -- /usr/local/bin/restore.sh
|
||||
|
||||
4) Scale Nextcloud deployment up:
|
||||
kubectl scale deployment nextcloud --replicas=1
|
||||
|
||||
5) Update index of Nextcloud:
|
||||
Nextcloud > Settings > System > Advanced > Indexing
|
||||
## License
|
||||
|
||||
Copyright © 2021 meissa GmbH
|
||||
Licensed under the [Apache License, Version 2.0](LICENSE) (the "License")
|
||||
Pls. find licenses of our subcomponents [here](doc/SUBCOMPONENT_LICENSE)
|
||||
# restore manuell triggern
|
|
@ -3,28 +3,26 @@ from pybuilder.core import task, init
|
|||
from ddadevops import *
|
||||
import logging
|
||||
|
||||
name = 'c4k-cloud-backup'
|
||||
name = 'meissa-cloud-backup'
|
||||
MODULE = 'docker'
|
||||
PROJECT_ROOT_PATH = '../..'
|
||||
|
||||
|
||||
class MyBuild(DevopsDockerBuild):
|
||||
pass
|
||||
|
||||
@init
|
||||
def initialize(project):
|
||||
project.build_depends_on('ddadevops>=0.12.4')
|
||||
stage = 'prod'
|
||||
project.build_depends_on('ddadevops>=0.6.1')
|
||||
stage = 'notused'
|
||||
dockerhub_user = environ.get('DOCKERHUB_USER')
|
||||
if not dockerhub_user:
|
||||
dockerhub_user = gopass_field_from_path('meissa/web/docker.com', 'login')
|
||||
dockerhub_password = environ.get('DOCKERHUB_PASSWORD')
|
||||
if not dockerhub_password:
|
||||
dockerhub_password = gopass_password_from_path('meissa/web/docker.com')
|
||||
tag = environ.get('CI_COMMIT_TAG')
|
||||
if not tag:
|
||||
tag = get_tag_from_latest_commit()
|
||||
config = create_devops_docker_build_config(
|
||||
stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password, docker_publish_tag=tag)
|
||||
stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password)
|
||||
build = MyBuild(project, config)
|
||||
build.initialize_build_dir()
|
||||
|
||||
|
@ -39,13 +37,13 @@ def drun(project):
|
|||
build = get_devops_build(project)
|
||||
build.drun()
|
||||
|
||||
@task
|
||||
def test(project):
|
||||
build = get_devops_build(project)
|
||||
build.test()
|
||||
|
||||
@task
|
||||
def publish(project):
|
||||
build = get_devops_build(project)
|
||||
build.dockerhub_login()
|
||||
build.dockerhub_publish()
|
||||
|
||||
@task
|
||||
def test(project):
|
||||
build = get_devops_build(project)
|
||||
build.test()
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
set -o pipefail
|
||||
|
||||
function main() {
|
||||
|
||||
start-maintenance.sh
|
||||
|
||||
file_env AWS_ACCESS_KEY_ID
|
||||
file_env AWS_SECRET_ACCESS_KEY
|
||||
file_env POSTGRES_DB
|
||||
|
@ -10,13 +13,15 @@ function main() {
|
|||
file_env POSTGRES_USER
|
||||
file_env RESTIC_DAYS_TO_KEEP 14
|
||||
|
||||
backup-roles ""
|
||||
backup-roles 'oc_'
|
||||
backup-db-dump
|
||||
backup-fs-from-directory '/var/backups/' 'data/'
|
||||
backup-directory '/var/backups/'
|
||||
|
||||
end-maintenance.sh
|
||||
}
|
||||
|
||||
source /usr/local/lib/functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
source /usr/local/lib/pg-functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
|
||||
main
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
if test -f "/var/backups/config/config.orig"; then
|
||||
|
||||
rm /var/backups/config/config.php
|
||||
mv /var/backups/config/config.orig /var/backups/config/config.php
|
||||
chown www-data:root /var/backups/config/config.php
|
||||
touch /var/backups/config/config.php
|
||||
|
||||
fi
|
|
@ -1,13 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
function main() {
|
||||
file_env POSTGRES_DB
|
||||
file_env POSTGRES_DB
|
||||
file_env POSTGRES_PASSWORD
|
||||
file_env POSTGRES_USER
|
||||
|
||||
create-pg-pass
|
||||
|
||||
/usr/local/bin/backup.sh
|
||||
/usr/local/bin/backup.sh
|
||||
}
|
||||
|
||||
source /usr/local/lib/functions.sh
|
||||
|
|
|
@ -10,6 +10,6 @@ function main() {
|
|||
}
|
||||
|
||||
source /usr/local/lib/functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
source /usr/local/lib/pg-functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
main
|
||||
|
|
|
@ -8,4 +8,5 @@ install -m 0700 /tmp/entrypoint-start-and-wait.sh /
|
|||
install -m 0700 /tmp/init.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/backup.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/restore.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/restic-snapshots.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/start-maintenance.sh /usr/local/bin/
|
||||
install -m 0700 /tmp/end-maintenance.sh /usr/local/bin/
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -o pipefail
|
||||
|
||||
function main() {
|
||||
file_env AWS_ACCESS_KEY_ID
|
||||
file_env AWS_SECRET_ACCESS_KEY
|
||||
|
||||
restic -r ${RESTIC_REPOSITORY}/pg-role snapshots
|
||||
restic -r ${RESTIC_REPOSITORY}/pg-database snapshots
|
||||
restic -r ${RESTIC_REPOSITORY}/files snapshots
|
||||
}
|
||||
|
||||
source /usr/local/lib/functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
|
||||
main
|
|
@ -4,6 +4,8 @@ set -Eeo pipefail
|
|||
|
||||
function main() {
|
||||
|
||||
start-maintenance.sh
|
||||
|
||||
file_env AWS_ACCESS_KEY_ID
|
||||
file_env AWS_SECRET_ACCESS_KEY
|
||||
|
||||
|
@ -11,26 +13,16 @@ function main() {
|
|||
file_env POSTGRES_PASSWORD
|
||||
file_env POSTGRES_USER
|
||||
|
||||
# Im Nextcloud pod: /opt/atlassian-cloud-software-standalone/bin/stop-cloud.sh
|
||||
|
||||
# Restore latest snapshot into /var/backups/restic-restore
|
||||
rm -rf /var/backups/restic-restore
|
||||
restore-directory '/var/backups/restic-restore'
|
||||
|
||||
# Restore data dir backup
|
||||
rm -rf /var/backups/data/*
|
||||
cp -a /var/backups/restic-restore/data/* /var/backups/data
|
||||
|
||||
# Restore db
|
||||
drop-create-db
|
||||
|
||||
restore-roles
|
||||
restore-db
|
||||
restore-directory '/var/backups/'
|
||||
|
||||
# /opt/atlassian-cloud-software-standalone/bin/start-cloud.sh
|
||||
}
|
||||
|
||||
source /usr/local/lib/functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
source /usr/local/lib/pg-functions.sh
|
||||
source /usr/local/lib/file-functions.sh
|
||||
main
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ ! -f "/var/backups/config/config.orig" ]; then
|
||||
|
||||
rm -f /var/backups/config/config.orig
|
||||
cp /var/backups/config/config.php /var/backups/config/config.orig
|
||||
sed -i "s/);/ \'maintenance\' => true,\n);/g" /var/backups/config/config.php
|
||||
chown www-data:root /var/backups/config/config.php
|
||||
touch /var/backups/config/config.php
|
||||
|
||||
fi
|
|
@ -1,7 +1,9 @@
|
|||
FROM c4k-cloud-backup
|
||||
FROM meissa-cloud-backup
|
||||
|
||||
RUN curl -L -o /tmp/serverspec.jar \
|
||||
https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/2.0.0/dda-serverspec-standalone.jar
|
||||
RUN apt update
|
||||
RUN apt -yqq --no-install-recommends --yes install curl default-jre-headless
|
||||
|
||||
RUN curl -L -o /tmp/serverspec.jar https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/2.0.0/dda-serverspec-standalone.jar
|
||||
|
||||
COPY serverspec.edn /tmp/serverspec.edn
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{:file [{:path "/usr/local/bin/init.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/backup.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/restore.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/restic-snapshots.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/start-maintenance.sh" :mod "700"}
|
||||
{:path "/usr/local/bin/end-maintenance.sh" :mod "700"}
|
||||
{:path "/entrypoint.sh" :mod "700"}
|
||||
{:path "/entrypoint-start-and-wait.sh" :mod "700"}]}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
FROM ubuntu:20.04
|
||||
|
||||
ENV CLOUD_HOME="/var/cloud" \
|
||||
DOWNLOAD_URL="https://product-downloads.atlassian.com/software/nextcloud/downloads" \
|
||||
CLOUD_RELEASE="8.8.0"
|
||||
# CLOUD_RELEASE="20.1.0"???
|
||||
ADD resources /tmp/resources
|
||||
RUN /tmp/resources/install.sh
|
||||
|
||||
USER 901:901
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<cloud-database-config>
|
||||
<name>defaultDS</name>
|
||||
<delegator-name>default</delegator-name>
|
||||
<database-type>postgres72</database-type>
|
||||
<schema-name>public</schema-name>
|
||||
<jdbc-datasource>
|
||||
<url>jdbc:postgresql://postgresql-service:5432/cloud</url>
|
||||
<driver-class>org.postgresql.Driver</driver-class>
|
||||
<username>$CLOUD_DB_USER</username>
|
||||
<password>$CLOUD_DB_PASSWORD</password>
|
||||
<pool-min-size>20</pool-min-size>
|
||||
<pool-max-size>20</pool-max-size>
|
||||
<pool-max-wait>30000</pool-max-wait>
|
||||
<validation-query>select 1</validation-query>
|
||||
<min-evictable-idle-time-millis>60000</min-evictable-idle-time-millis>
|
||||
<time-between-eviction-runs-millis>300000</time-between-eviction-runs-millis>
|
||||
<pool-max-idle>20</pool-max-idle>
|
||||
<pool-remove-abandoned>true</pool-remove-abandoned>
|
||||
<pool-remove-abandoned-timeout>300</pool-remove-abandoned-timeout>
|
||||
<pool-test-on-borrow>false</pool-test-on-borrow>
|
||||
<pool-test-while-idle>true</pool-test-while-idle>
|
||||
</jdbc-datasource>
|
||||
</cloud-database-config>
|
|
@ -1,44 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# usage: file_env VAR [DEFAULT]
|
||||
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
|
||||
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
|
||||
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
|
||||
function file_env() {
|
||||
local var="$1"
|
||||
local fileVar="${var}_FILE"
|
||||
local def="${2:-}"
|
||||
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
|
||||
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
|
||||
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
|
||||
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "${varValue}" ]; then
|
||||
export "$var"="${varValue}"
|
||||
elif [ -n "${fileVarValue}" ]; then
|
||||
export "$var"="$(cat "${fileVarValue}")"
|
||||
elif [ -n "${def}" ]; then
|
||||
export "$var"="$def"
|
||||
fi
|
||||
unset "$fileVar"
|
||||
}
|
||||
|
||||
function main() {
|
||||
file_env "FQDN"
|
||||
file_env "DB_USERNAME"
|
||||
file_env "DB_PASSWORD"
|
||||
|
||||
xmlstarlet ed -L -u "/Server/Service/Connector[@proxyName='{subdomain}.{domain}.com']/@proxyName" \
|
||||
-v "$FQDN" /opt/atlassian-cloud-software-standalone/conf/server.xml
|
||||
xmlstarlet ed -L -u "/cloud-database-config/jdbc-datasource/username" \
|
||||
-v "$DB_USERNAME" /app/dbconfig.xml
|
||||
xmlstarlet ed -L -u "/cloud-database-config/jdbc-datasource/password" \
|
||||
-v "$DB_PASSWORD" /app/dbconfig.xml
|
||||
|
||||
install -ocloud -gcloud -m660 /app/dbconfig.xml /var/cloud/dbconfig.xml
|
||||
/opt/atlassian-cloud-software-standalone/bin/setenv.sh run
|
||||
/opt/atlassian-cloud-software-standalone/bin/start-cloud.sh run
|
||||
}
|
||||
|
||||
main
|
|
@ -1,30 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
function main() {
|
||||
|
||||
upgradeSystem
|
||||
apt-get -qqy install curl openjdk-11-jre-headless xmlstarlet > /dev/null
|
||||
|
||||
adduser --system --disabled-login --home ${CLOUD_HOME} --uid 901 --group cloud
|
||||
|
||||
mkdir -p /app
|
||||
|
||||
cd /tmp
|
||||
curl --location ${DOWNLOAD_URL}/atlassian-cloud-software-${CLOUD_RELEASE}.tar.gz \
|
||||
-o atlassian-cloud-software-${CLOUD_RELEASE}.tar.gz
|
||||
tar -xvf atlassian-cloud-software-${CLOUD_RELEASE}.tar.gz -C /tmp/
|
||||
mv /tmp/atlassian-cloud-software-${CLOUD_RELEASE}-standalone \
|
||||
/opt/atlassian-cloud-software-standalone
|
||||
chown -R cloud:cloud /opt/atlassian-cloud-software-standalone
|
||||
|
||||
install -ocloud -gcloud -m744 /tmp/resources/entrypoint.sh /app/entrypoint.sh
|
||||
install -ocloud -gcloud -m744 /tmp/resources/setenv.sh /opt/atlassian-cloud-software-standalone/bin/setenv.sh
|
||||
install -ocloud -gcloud -m660 /tmp/resources/dbconfig.xml /app/dbconfig.xml
|
||||
install -ocloud -gcloud -m660 /tmp/resources/server.xml /opt/atlassian-cloud-software-standalone/conf/server.xml
|
||||
install -ocloud -gcloud -m660 /tmp/resources/logging.properties /opt/atlassian-cloud-software-standalone/conf/logging.properties
|
||||
|
||||
cleanupDocker
|
||||
}
|
||||
|
||||
source /tmp/resources/install_functions.sh
|
||||
main
|
|
@ -1,69 +0,0 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
handlers = java.util.logging.ConsoleHandler
|
||||
|
||||
.handlers = java.util.logging.ConsoleHandler
|
||||
|
||||
############################################################
|
||||
# Handler specific properties.
|
||||
# Describes specific configuration info for Handlers.
|
||||
############################################################
|
||||
|
||||
java.util.logging.ConsoleHandler.level = FINE
|
||||
java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
|
||||
java.util.logging.ConsoleHandler.encoding = UTF-8
|
||||
|
||||
|
||||
############################################################
|
||||
# Facility specific properties.
|
||||
# Provides extra control for each logger.
|
||||
############################################################
|
||||
|
||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
|
||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandler
|
||||
|
||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
|
||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandler
|
||||
|
||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
|
||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.AsyncFileHandler
|
||||
|
||||
# For example, set the org.apache.catalina.util.LifecycleBase logger to log
|
||||
# each component that extends LifecycleBase changing state:
|
||||
#org.apache.catalina.util.LifecycleBase.level = FINE
|
||||
|
||||
# To see debug messages in TldLocationsCache, uncomment the following line:
|
||||
#org.apache.jasper.compiler.TldLocationsCache.level = FINE
|
||||
|
||||
# To see debug messages for HTTP/2 handling, uncomment the following line:
|
||||
#org.apache.coyote.http2.level = FINE
|
||||
|
||||
# To see debug messages for WebSocket handling, uncomment the following line:
|
||||
#org.apache.tomcat.websocket.level = FINE
|
||||
# Suppress clearReferencesThreads and clearThreadLocalMap notifications on shutdown
|
||||
org.apache.catalina.loader.WebappClassLoader.level = OFF
|
||||
|
||||
# Suppress some useless REST messages. See JRADEV-12212.
|
||||
com.sun.jersey.server.impl.application.WebApplicationImpl.level = WARNING
|
||||
com.atlassian.plugins.rest.doclet.level = WARNING
|
||||
com.sun.jersey.api.wadl.config.WadlGeneratorLoader.level = WARNING
|
||||
|
||||
# Suppress log spam about the request body - https://cloud.atlassian.com/browse/JRASERVER-30406
|
||||
com.sun.jersey.spi.container.servlet.WebComponent.level = SEVERE
|
||||
com.sun.jersey.spi.container.servlet.WebComponent.filterFormParameters.level = SEVERE
|
||||
|
||||
# Suppress resources cache full warnings
|
||||
org.apache.catalina.webresources.Cache.level = OFF
|
|
@ -1,114 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<Server port="8005" shutdown="SHUTDOWN">
|
||||
<Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
|
||||
<!--Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/-->
|
||||
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
|
||||
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
|
||||
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
|
||||
|
||||
<Service name="Catalina">
|
||||
<!--
|
||||
==============================================================================================================
|
||||
DEFAULT - Direct connector with no proxy for unproxied access to Nextcloud.
|
||||
|
||||
If using a http/https proxy, comment out this connector.
|
||||
==============================================================================================================
|
||||
-->
|
||||
|
||||
<!-- Relaxing chars because of JRASERVER-67974 -->
|
||||
<!--
|
||||
<Connector port="8080" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^\`"<>"
|
||||
maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
|
||||
maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443"
|
||||
acceptCount="100" disableUploadTimeout="true" bindOnInit="false"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
==============================================================================================================
|
||||
HTTP - Proxying Nextcloud via Apache or Nginx over HTTP
|
||||
|
||||
If you're proxying traffic to Nextcloud over HTTP, uncomment the below connector and comment out the others.
|
||||
Ensure the proxyName and proxyPort are updated with the appropriate information if necessary as per the docs.
|
||||
|
||||
See the following for more information:
|
||||
|
||||
Apache - https://confluence.atlassian.com/x/4xQLM
|
||||
nginx - https://confluence.atlassian.com/x/DAFmGQ
|
||||
==============================================================================================================
|
||||
-->
|
||||
|
||||
<!--
|
||||
<Connector port="8080" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^\`"<>"
|
||||
maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
|
||||
maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true" redirectPort="8443"
|
||||
acceptCount="100" disableUploadTimeout="true" bindOnInit="false" scheme="http"
|
||||
proxyName="<subdomain>.<domain>.com" proxyPort="80"/>
|
||||
|
||||
-->
|
||||
<!--
|
||||
==============================================================================================================
|
||||
HTTPS - Proxying Nextcloud via Apache or Nginx over HTTPS
|
||||
|
||||
If you're proxying traffic to Nextcloud over HTTPS, uncomment the below connector and comment out the others.
|
||||
Ensure the proxyName and proxyPort are updated with the appropriate information if necessary as per the docs.
|
||||
|
||||
See the following for more information:
|
||||
|
||||
Apache - https://confluence.atlassian.com/x/PTT3MQ
|
||||
nginx - https://confluence.atlassian.com/x/DAFmGQ
|
||||
==============================================================================================================
|
||||
-->
|
||||
<Connector port="8080" relaxedPathChars="[]|" relaxedQueryChars="[]|{}^\`"<>"
|
||||
maxThreads="150" minSpareThreads="25" connectionTimeout="20000" enableLookups="false"
|
||||
maxHttpHeaderSize="8192" protocol="HTTP/1.1" useBodyEncodingForURI="true"
|
||||
acceptCount="100" disableUploadTimeout="true" bindOnInit="false" secure="true" scheme="https"
|
||||
proxyName="{subdomain}.{domain}.com" proxyPort="443"/>
|
||||
|
||||
<!--
|
||||
==============================================================================================================
|
||||
AJP - Proxying Nextcloud via Apache over HTTP or HTTPS
|
||||
|
||||
If you're proxying traffic to Nextcloud using the AJP protocol, uncomment the following connector line
|
||||
See the following for more information:
|
||||
|
||||
Apache - https://confluence.atlassian.com/x/QiJ9MQ
|
||||
==============================================================================================================
|
||||
-->
|
||||
|
||||
<!--
|
||||
<Connector port="8009" URIEncoding="UTF-8" enableLookups="false" protocol="AJP/1.3"/>
|
||||
-->
|
||||
|
||||
<Engine name="Catalina" defaultHost="localhost">
|
||||
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
|
||||
|
||||
<Context path="" docBase="${catalina.home}/atlassian-cloud" reloadable="false" useHttpOnly="true">
|
||||
<Resource name="UserTransaction" auth="Container" type="javax.transaction.UserTransaction"
|
||||
factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>
|
||||
<Manager pathname=""/>
|
||||
<JarScanner scanManifest="false"/>
|
||||
<Valve className="org.apache.catalina.valves.StuckThreadDetectionValve" threshold="120" />
|
||||
</Context>
|
||||
|
||||
</Host>
|
||||
<Valve className="org.apache.catalina.valves.AccessLogValve"
|
||||
pattern="%a %{cloud.request.id}r %{cloud.request.username}r %t "%m %U%q %H" %s %b %D "%{Referer}i" "%{User-Agent}i" "%{cloud.request.assession.id}r""/>
|
||||
</Engine>
|
||||
</Service>
|
||||
</Server>
|
|
@ -1,121 +0,0 @@
|
|||
#
|
||||
# If the limit of files that Nextcloud can open is too low, it will be set to this value.
|
||||
#
|
||||
MIN_NOFILES_LIMIT=16384
|
||||
|
||||
#
|
||||
# One way to set the Nextcloud HOME path is here via this variable. Simply uncomment it and set a valid path like /cloud/home. You can of course set it outside in the command terminal. That will also work.
|
||||
#
|
||||
CLOUD_HOME="/var/cloud"
|
||||
|
||||
#
|
||||
# Occasionally Atlassian Support may recommend that you set some specific JVM arguments. You can use this variable below to do that.
|
||||
#
|
||||
JVM_SUPPORT_RECOMMENDED_ARGS=""
|
||||
|
||||
#
|
||||
# You can use variable below to modify garbage collector settings.
|
||||
# For Java 8 we recommend default settings
|
||||
# For Java 11 and relatively small heaps we recommend: -XX:+UseParallelGC
|
||||
# For Java 11 and larger heaps we recommend: -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent
|
||||
#
|
||||
JVM_GC_ARGS="-XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent"
|
||||
|
||||
#
|
||||
# The following 2 settings control the minimum and maximum given to the Nextcloud Java virtual machine. In larger Nextcloud instances, the maximum amount will need to be increased.
|
||||
#
|
||||
JVM_MINIMUM_MEMORY="4096m"
|
||||
JVM_MAXIMUM_MEMORY="4096m"
|
||||
|
||||
#
|
||||
# The following setting configures the size of JVM code cache. A high value of reserved size allows Nextcloud to work with more installed apps.
|
||||
#
|
||||
JVM_CODE_CACHE_ARGS='-XX:InitialCodeCacheSize=32m -XX:ReservedCodeCacheSize=512m'
|
||||
|
||||
#
|
||||
# The following are the required arguments for Nextcloud.
|
||||
#
|
||||
JVM_REQUIRED_ARGS='-Djava.awt.headless=true -Datlassian.standalone=CLOUD -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -Dmail.mime.decodeparameters=true -Dorg.dom4j.factory=com.atlassian.core.xml.InterningDocumentFactory'
|
||||
|
||||
# Uncomment this setting if you want to import data without notifications
|
||||
#
|
||||
#DISABLE_NOTIFICATIONS=" -Datlassian.mail.senddisabled=true -Datlassian.mail.fetchdisabled=true -Datlassian.mail.popdisabled=true"
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------------
|
||||
#
|
||||
# In general don't make changes below here
|
||||
#
|
||||
#-----------------------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------------------
|
||||
# Prevents the JVM from suppressing stack traces if a given type of exception
|
||||
# occurs frequently, which could make it harder for support to diagnose a problem.
|
||||
#-----------------------------------------------------------------------------------
|
||||
JVM_EXTRA_ARGS="-XX:-OmitStackTraceInFastThrow -Djava.locale.providers=COMPAT"
|
||||
|
||||
CURRENT_NOFILES_LIMIT=$( ulimit -Hn )
|
||||
ulimit -Sn $CURRENT_NOFILES_LIMIT
|
||||
ulimit -n $(( CURRENT_NOFILES_LIMIT > MIN_NOFILES_LIMIT ? CURRENT_NOFILES_LIMIT : MIN_NOFILES_LIMIT ))
|
||||
|
||||
PRGDIR=`dirname "$0"`
|
||||
cat "${PRGDIR}"/cloudbanner.txt
|
||||
|
||||
CLOUD_HOME_MINUSD=""
|
||||
if [ "$CLOUD_HOME" != "" ]; then
|
||||
echo $CLOUD_HOME | grep -q " "
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ""
|
||||
echo "--------------------------------------------------------------------------------------------------------------------"
|
||||
echo " WARNING : You cannot have a CLOUD_HOME environment variable set with spaces in it. This variable is being ignored"
|
||||
echo "--------------------------------------------------------------------------------------------------------------------"
|
||||
else
|
||||
CLOUD_HOME_MINUSD=-Dcloud.home=$CLOUD_HOME
|
||||
fi
|
||||
fi
|
||||
|
||||
JAVA_OPTS="-Xms${JVM_MINIMUM_MEMORY} -Xmx${JVM_MAXIMUM_MEMORY} ${JVM_CODE_CACHE_ARGS} ${JAVA_OPTS} ${JVM_REQUIRED_ARGS} ${DISABLE_NOTIFICATIONS} ${JVM_SUPPORT_RECOMMENDED_ARGS} ${JVM_EXTRA_ARGS} ${CLOUD_HOME_MINUSD} ${START_CLOUD_JAVA_OPTS}"
|
||||
|
||||
export JAVA_OPTS
|
||||
|
||||
# DO NOT remove the following line
|
||||
# !INSTALLER SET JAVA_HOME
|
||||
|
||||
echo ""
|
||||
echo "If you encounter issues starting or stopping Nextcloud, please see the Troubleshooting guide at https://docs.atlassian.com/cloud/jadm-docs-088/Troubleshooting+installation"
|
||||
echo ""
|
||||
if [ "$CLOUD_HOME_MINUSD" != "" ]; then
|
||||
echo "Using CLOUD_HOME: $CLOUD_HOME"
|
||||
fi
|
||||
|
||||
# set the location of the pid file
|
||||
if [ -z "$CATALINA_PID" ] ; then
|
||||
if [ -n "$CATALINA_BASE" ] ; then
|
||||
CATALINA_PID="$CATALINA_BASE"/work/catalina.pid
|
||||
elif [ -n "$CATALINA_HOME" ] ; then
|
||||
CATALINA_PID="$CATALINA_HOME"/work/catalina.pid
|
||||
fi
|
||||
fi
|
||||
export CATALINA_PID
|
||||
|
||||
if [ -z "$CATALINA_BASE" ]; then
|
||||
if [ -z "$CATALINA_HOME" ]; then
|
||||
LOGBASE=$PRGDIR
|
||||
LOGTAIL=..
|
||||
else
|
||||
LOGBASE=$CATALINA_HOME
|
||||
LOGTAIL=.
|
||||
fi
|
||||
else
|
||||
LOGBASE=$CATALINA_BASE
|
||||
LOGTAIL=.
|
||||
fi
|
||||
|
||||
PUSHED_DIR=`pwd`
|
||||
cd $LOGBASE
|
||||
cd $LOGTAIL
|
||||
LOGBASEABS=`pwd`
|
||||
cd $PUSHED_DIR
|
||||
|
||||
echo ""
|
||||
echo "Server startup logs are located in $LOGBASEABS/logs/catalina.out"
|
|
@ -1,5 +0,0 @@
|
|||
# START INSTALLER MAGIC ! DO NOT EDIT !
|
||||
CLOUD_USER="cloud" ##
|
||||
# END INSTALLER MAGIC ! DO NOT EDIT !
|
||||
|
||||
export CLOUD_USER
|
|
@ -1,8 +0,0 @@
|
|||
FROM c4k-cloud
|
||||
|
||||
RUN curl -L -o /tmp/serverspec.jar \
|
||||
https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/1.3.4/dda-serverspec-standalone.jar
|
||||
|
||||
COPY serverspec.edn /tmp/serverspec.edn
|
||||
|
||||
RUN java -jar /tmp/serverspec.jar /tmp/serverspec.edn -v
|
|
@ -1,3 +0,0 @@
|
|||
{:file [{:path "/app/entrypoint.sh"}
|
||||
{:path "/var/cloud"}
|
||||
{:path "/opt/atlassian-cloud-software-standalone"}]}
|
|
@ -3,28 +3,26 @@ from pybuilder.core import task, init
|
|||
from ddadevops import *
|
||||
import logging
|
||||
|
||||
name = 'c4k-cloud'
|
||||
name = 'meissa-cloud-app'
|
||||
MODULE = 'docker'
|
||||
PROJECT_ROOT_PATH = '../..'
|
||||
|
||||
|
||||
class MyBuild(DevopsDockerBuild):
|
||||
pass
|
||||
|
||||
@init
|
||||
def initialize(project):
|
||||
project.build_depends_on('ddadevops>=0.12.4')
|
||||
stage = 'prod'
|
||||
project.build_depends_on('ddadevops>=0.6.1')
|
||||
stage = 'notused'
|
||||
dockerhub_user = environ.get('DOCKERHUB_USER')
|
||||
if not dockerhub_user:
|
||||
dockerhub_user = gopass_field_from_path('meissa/web/docker.com', 'login')
|
||||
dockerhub_password = environ.get('DOCKERHUB_PASSWORD')
|
||||
if not dockerhub_password:
|
||||
dockerhub_password = gopass_password_from_path('meissa/web/docker.com')
|
||||
tag = environ.get('CI_COMMIT_TAG')
|
||||
if not tag:
|
||||
tag = get_tag_from_latest_commit()
|
||||
config = create_devops_docker_build_config(
|
||||
stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password, docker_publish_tag=tag)
|
||||
stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password)
|
||||
build = MyBuild(project, config)
|
||||
build.initialize_build_dir()
|
||||
|
||||
|
@ -39,13 +37,13 @@ def drun(project):
|
|||
build = get_devops_build(project)
|
||||
build.drun()
|
||||
|
||||
@task
|
||||
def test(project):
|
||||
build = get_devops_build(project)
|
||||
build.test()
|
||||
|
||||
@task
|
||||
def publish(project):
|
||||
build = get_devops_build(project)
|
||||
build.dockerhub_login()
|
||||
build.dockerhub_publish()
|
||||
|
||||
@task
|
||||
def test(project):
|
||||
build = get_devops_build(project)
|
||||
build.test()
|
8
infrastructure/docker-nextcloud/image/Dockerfile
Normal file
8
infrastructure/docker-nextcloud/image/Dockerfile
Normal file
|
@ -0,0 +1,8 @@
|
|||
FROM nextcloud:19
|
||||
|
||||
# Prepare Entrypoint Script
|
||||
ADD resources /tmp
|
||||
RUN /tmp/install.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
CMD ["apache2-foreground"]
|
191
infrastructure/docker-nextcloud/image/resources/entrypoint.sh
Normal file
191
infrastructure/docker-nextcloud/image/resources/entrypoint.sh
Normal file
|
@ -0,0 +1,191 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# version_greater A B returns whether A > B
|
||||
version_greater() {
|
||||
[ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ]
|
||||
}
|
||||
|
||||
# return true if specified directory is empty
|
||||
directory_empty() {
|
||||
[ -z "$(ls -A "$1/")" ]
|
||||
}
|
||||
|
||||
run_as() {
|
||||
if [ "$(id -u)" = 0 ]; then
|
||||
su -p www-data -s /bin/sh -c "$1"
|
||||
else
|
||||
sh -c "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# usage: file_env VAR [DEFAULT]
|
||||
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
|
||||
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
|
||||
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
|
||||
file_env() {
|
||||
local var="$1"
|
||||
local fileVar="${var}_FILE"
|
||||
local def="${2:-}"
|
||||
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
|
||||
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
|
||||
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
|
||||
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "${varValue}" ]; then
|
||||
export "$var"="${varValue}"
|
||||
elif [ -n "${fileVarValue}" ]; then
|
||||
export "$var"="$(cat "${fileVarValue}")"
|
||||
elif [ -n "${def}" ]; then
|
||||
export "$var"="$def"
|
||||
fi
|
||||
unset "$fileVar"
|
||||
}
|
||||
|
||||
if expr "$1" : "apache" 1>/dev/null; then
|
||||
if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then
|
||||
a2disconf remoteip
|
||||
fi
|
||||
fi
|
||||
|
||||
if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then
|
||||
if [ -n "${REDIS_HOST+x}" ]; then
|
||||
|
||||
echo "Configuring Redis as session handler"
|
||||
{
|
||||
echo 'session.save_handler = redis'
|
||||
# check if redis host is an unix socket path
|
||||
if [ "$(echo "$REDIS_HOST" | cut -c1-1)" = "/" ]; then
|
||||
if [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
|
||||
echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\""
|
||||
else
|
||||
echo "session.save_path = \"unix://${REDIS_HOST}\""
|
||||
fi
|
||||
# check if redis password has been set
|
||||
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
|
||||
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\""
|
||||
else
|
||||
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}\""
|
||||
fi
|
||||
} > /usr/local/etc/php/conf.d/redis-session.ini
|
||||
fi
|
||||
|
||||
installed_version="0.0.0.0"
|
||||
if [ -f /var/www/html/version.php ]; then
|
||||
# shellcheck disable=SC2016
|
||||
installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')"
|
||||
fi
|
||||
# shellcheck disable=SC2016
|
||||
image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')"
|
||||
|
||||
if version_greater "$installed_version" "$image_version"; then
|
||||
echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if version_greater "$image_version" "$installed_version"; then
|
||||
echo "Initializing nextcloud $image_version (image) over $installed_version (installed) ..."
|
||||
if [ "$installed_version" != "0.0.0.0" ]; then
|
||||
echo "Upgrading nextcloud from $installed_version ..."
|
||||
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before
|
||||
fi
|
||||
if [ "$(id -u)" = 0 ]; then
|
||||
rsync_options="-rlDog --chown www-data:root"
|
||||
else
|
||||
rsync_options="-rlD"
|
||||
fi
|
||||
rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/
|
||||
|
||||
for dir in config data custom_apps themes; do
|
||||
if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then
|
||||
rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/
|
||||
fi
|
||||
done
|
||||
rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/
|
||||
echo "Initializing finished"
|
||||
|
||||
#install
|
||||
if [ "$installed_version" = "0.0.0.0" ]; then
|
||||
echo "New nextcloud instance"
|
||||
|
||||
file_env NEXTCLOUD_ADMIN_PASSWORD
|
||||
file_env NEXTCLOUD_ADMIN_USER
|
||||
|
||||
if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then
|
||||
# shellcheck disable=SC2016
|
||||
install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"'
|
||||
if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then
|
||||
# shellcheck disable=SC2016
|
||||
install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"'
|
||||
fi
|
||||
|
||||
file_env MYSQL_DATABASE
|
||||
file_env MYSQL_PASSWORD
|
||||
file_env MYSQL_USER
|
||||
file_env POSTGRES_DB
|
||||
file_env POSTGRES_PASSWORD
|
||||
file_env POSTGRES_USER
|
||||
|
||||
install=false
|
||||
if [ -n "${SQLITE_DATABASE+x}" ]; then
|
||||
echo "Installing with SQLite database"
|
||||
# shellcheck disable=SC2016
|
||||
install_options=$install_options' --database-name "$SQLITE_DATABASE"'
|
||||
install=true
|
||||
elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then
|
||||
echo "Installing with MySQL database"
|
||||
# shellcheck disable=SC2016
|
||||
install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"'
|
||||
install=true
|
||||
elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then
|
||||
echo "Installing with PostgreSQL database"
|
||||
# shellcheck disable=SC2016
|
||||
install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"'
|
||||
install=true
|
||||
fi
|
||||
|
||||
if [ "$install" = true ]; then
|
||||
echo "starting nextcloud installation"
|
||||
echo "$install_options"
|
||||
max_retries=10
|
||||
try=0
|
||||
until run_as "php /var/www/html/occ maintenance:install $install_options" || [ "$try" -gt "$max_retries" ]
|
||||
do
|
||||
echo "retrying install..."
|
||||
try=$((try+1))
|
||||
sleep 20s
|
||||
done
|
||||
if [ "$try" -gt "$max_retries" ]; then
|
||||
echo "installing of nextcloud failed!"
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then
|
||||
echo "setting trusted domains…"
|
||||
NC_TRUSTED_DOMAIN_IDX=1
|
||||
for DOMAIN in $NEXTCLOUD_TRUSTED_DOMAINS ; do
|
||||
DOMAIN=$(echo "$DOMAIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
|
||||
run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=$DOMAIN"
|
||||
run_as "php /var/www/html/occ config:system:set overwritehost --value=$DOMAIN"
|
||||
NC_TRUSTED_DOMAIN_IDX=$(($NC_TRUSTED_DOMAIN_IDX+1))
|
||||
done
|
||||
fi
|
||||
run_as "php /var/www/html/occ config:system:set overwriteprotocol --value=https"
|
||||
else
|
||||
echo "running web-based installer on first connect!"
|
||||
fi
|
||||
fi
|
||||
#upgrade
|
||||
else
|
||||
run_as 'php /var/www/html/occ upgrade'
|
||||
|
||||
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_after
|
||||
echo "The following apps have been disabled:"
|
||||
diff /tmp/list_before /tmp/list_after | grep '<' | cut -d- -f2 | cut -d: -f1
|
||||
rm -f /tmp/list_before /tmp/list_after
|
||||
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$@"
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
apt update && apt -qqy install vim bash-completion less
|
9
infrastructure/docker-nextcloud/image/resources/install.sh
Executable file
9
infrastructure/docker-nextcloud/image/resources/install.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
set -Eeo pipefail
|
||||
|
||||
mkdir /var/data
|
||||
|
||||
install -m 0700 /tmp/install-debug.sh /usr/local/bin/
|
||||
install -m 0544 /tmp/upload-max-limit.ini /usr/local/etc/php/conf.d/
|
||||
install -m 0544 /tmp/memory-limit.ini /usr/local/etc/php/conf.d/
|
||||
install -m 0755 /tmp/entrypoint.sh /
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
memory_limit=5120M
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
post_max_size = 512M
|
||||
upload_max_filesize = 512M
|
11
infrastructure/docker-nextcloud/test/Dockerfile
Normal file
11
infrastructure/docker-nextcloud/test/Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
|||
FROM meissa-cloud-app
|
||||
|
||||
RUN apt update
|
||||
RUN mkdir /usr/share/man/man1/
|
||||
RUN apt -yqq install --no-install-recommends --yes curl default-jre-headless
|
||||
|
||||
RUN curl -L -o /tmp/serverspec.jar https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/2.0.0/dda-serverspec-standalone.jar
|
||||
|
||||
COPY serverspec.edn /tmp/serverspec.edn
|
||||
|
||||
RUN java -jar /tmp/serverspec.jar /tmp/serverspec.edn -v
|
2
infrastructure/docker-nextcloud/test/serverspec.edn
Normal file
2
infrastructure/docker-nextcloud/test/serverspec.edn
Normal file
|
@ -0,0 +1,2 @@
|
|||
{:file [{:path "/var/data"}
|
||||
{:path "/entrypoint.sh" :mod "755"}]}
|
59
main/resources/backup/backup-restore.yaml
Normal file
59
main/resources/backup/backup-restore.yaml
Normal file
|
@ -0,0 +1,59 @@
|
|||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: backup-restore
|
||||
labels:
|
||||
app.kubernetes.io/name: backup-restore
|
||||
app.kubernetes.io/part-of: cloud
|
||||
spec:
|
||||
containers:
|
||||
- name: backup-app
|
||||
image: domaindrivenarchitecture/c4k-cloud-backup
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/entrypoint-start-and-wait.sh"]
|
||||
env:
|
||||
- name: POSTGRES_USER_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-user
|
||||
- name: POSTGRES_DB_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-db
|
||||
- name: POSTGRES_PASSWORD_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-password
|
||||
- name: POSTGRES_HOST
|
||||
value: "postgresql-service:5432"
|
||||
- name: POSTGRES_SERVICE
|
||||
value: "postgresql-service"
|
||||
- name: POSTGRES_PORT
|
||||
value: "5432"
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: eu-central-1
|
||||
- name: AWS_ACCESS_KEY_ID_FILE
|
||||
value: /var/run/secrets/backup-secrets/aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY_FILE
|
||||
value: /var/run/secrets/backup-secrets/aws-secret-access-key
|
||||
- name: RESTIC_REPOSITORY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: backup-config
|
||||
key: restic-repository
|
||||
- name: RESTIC_PASSWORD_FILE
|
||||
value: /var/run/secrets/backup-secrets/restic-password
|
||||
volumeMounts:
|
||||
- name: cloud-data-volume
|
||||
mountPath: /var/backups
|
||||
- name: backup-secret-volume
|
||||
mountPath: /var/run/secrets/backup-secrets
|
||||
readOnly: true
|
||||
- name: cloud-secret-volume
|
||||
mountPath: /var/run/secrets/cloud-secrets
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: cloud-data-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: cloud-pvc
|
||||
- name: cloud-secret-volume
|
||||
secret:
|
||||
secretName: cloud-secret
|
||||
- name: backup-secret-volume
|
||||
secret:
|
||||
secretName: backup-secret
|
||||
restartPolicy: OnFailure
|
9
main/resources/backup/config.yaml
Normal file
9
main/resources/backup/config.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: backup-config
|
||||
labels:
|
||||
app.kubernetes.io/name: backup
|
||||
app.kubernetes.io/part-of: cloud
|
||||
data:
|
||||
restic-repository: restic-repository
|
9
main/resources/backup/configure-as-user.sh
Normal file
9
main/resources/backup/configure-as-user.sh
Normal file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
kubectl delete --ignore-not-found=true -f backup-secret.yml
|
||||
kubectl delete --ignore-not-found=true -f backup-config.yml
|
||||
kubectl delete --ignore-not-found=true -f backup-cron.yml
|
||||
|
||||
kubectl apply -f backup-secret.yml
|
||||
kubectl apply -f backup-config.yml
|
||||
kubectl apply -f backup-cron.yml
|
65
main/resources/backup/cron.yaml
Normal file
65
main/resources/backup/cron.yaml
Normal file
|
@ -0,0 +1,65 @@
|
|||
apiVersion: batch/v1beta1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: cloud-backup
|
||||
labels:
|
||||
app.kubernetes.part-of: cloud
|
||||
spec:
|
||||
schedule: "10 23 * * *"
|
||||
successfulJobsHistoryLimit: 0
|
||||
failedJobsHistoryLimit: 0
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: backup-app
|
||||
image: domaindrivenarchitecture/meissa-cloud-backup
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/entrypoint.sh"]
|
||||
env:
|
||||
- name: POSTGRES_USER_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-user
|
||||
- name: POSTGRES_DB_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-db
|
||||
- name: POSTGRES_PASSWORD_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-password
|
||||
- name: POSTGRES_HOST
|
||||
value: "postgresql-service:5432"
|
||||
- name: POSTGRES_SERVICE
|
||||
value: "postgresql-service"
|
||||
- name: POSTGRES_PORT
|
||||
value: "5432"
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: eu-central-1
|
||||
- name: AWS_ACCESS_KEY_ID_FILE
|
||||
value: /var/run/secrets/backup-secrets/aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY_FILE
|
||||
value: /var/run/secrets/backup-secrets/aws-secret-access-key
|
||||
- name: RESTIC_REPOSITORY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: backup-config
|
||||
key: restic-repository
|
||||
- name: RESTIC_PASSWORD_FILE
|
||||
value: /var/run/secrets/backup-secrets/restic-password
|
||||
volumeMounts:
|
||||
- name: cloud-data-volume
|
||||
mountPath: /var/backups
|
||||
- name: backup-secret-volume
|
||||
mountPath: /var/run/secrets/backup-secrets
|
||||
readOnly: true
|
||||
- name: cloud-secret-volume
|
||||
mountPath: /var/run/secrets/cloud-secrets
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: cloud-data-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: cloud-pvc
|
||||
- name: cloud-secret-volume
|
||||
secret:
|
||||
secretName: cloud-secret
|
||||
- name: backup-secret-volume
|
||||
secret:
|
||||
secretName: backup-secret
|
||||
restartPolicy: OnFailure
|
9
main/resources/backup/secret.yaml
Normal file
9
main/resources/backup/secret.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: backup-secret
|
||||
type: Opaque
|
||||
stringData:
|
||||
aws-access-key-id: aws-access-key-id
|
||||
aws-secret-access-key: aws-secret-access-key
|
||||
restic-password: restic-password
|
13
main/resources/cloud/certificate.yaml
Normal file
13
main/resources/cloud/certificate.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
apiVersion: cert-manager.io/v1alpha2
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: cloud-cert
|
||||
namespace: default
|
||||
spec:
|
||||
secretName: cloud-secret
|
||||
commonName: fqdn
|
||||
dnsNames:
|
||||
- fqdn
|
||||
issuerRef:
|
||||
name: letsencrypt-staging-issuer
|
||||
kind: ClusterIssuer
|
45
main/resources/cloud/cloud-pod.yml.template
Normal file
45
main/resources/cloud/cloud-pod.yml.template
Normal file
|
@ -0,0 +1,45 @@
|
|||
kind: Pod
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: cloud
|
||||
labels:
|
||||
app.kubernetes.io/name: cloud
|
||||
spec:
|
||||
shareProcessNamespace: true
|
||||
containers:
|
||||
- name: cloud-app
|
||||
image: domaindrivenarchitecture/meissa-cloud-app
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
env:
|
||||
- name: NEXTCLOUD_ADMIN_USER_FILE
|
||||
value: /var/run/secrets/cloud-secrets/nextcloud-admin-user
|
||||
- name: NEXTCLOUD_ADMIN_PASSWORD_FILE
|
||||
value: /var/run/secrets/cloud-secrets/nextcloud-admin-password
|
||||
- name: NEXTCLOUD_TRUSTED_DOMAINS
|
||||
value: "{{fqdn}}"
|
||||
- name: POSTGRES_USER_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-user
|
||||
- name: POSTGRES_PASSWORD_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-password
|
||||
- name: POSTGRES_DB_FILE
|
||||
value: /var/run/secrets/cloud-secrets/postgres-db
|
||||
- name: POSTGRES_HOST
|
||||
value: "postgresql-service:5432"
|
||||
volumeMounts:
|
||||
- name: cloud-data-volume
|
||||
mountPath: /var/www/html
|
||||
- name: cloud-secret-volume
|
||||
mountPath: /var/run/secrets/cloud-secrets
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: cloud-data-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: cloud-pvc
|
||||
- name: cloud-secret-volume
|
||||
secret:
|
||||
secretName: cloud-secret
|
||||
- name: backup-secret-volume
|
||||
secret:
|
||||
secretName: backup-secret
|
22
main/resources/cloud/configure-as-user.sh
Normal file
22
main/resources/cloud/configure-as-user.sh
Normal file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
|
||||
kubectl delete --ignore-not-found=true -f cloud-ingress.yml
|
||||
kubectl delete --ignore-not-found=true -f cloud-pod.yml
|
||||
kubectl delete --ignore-not-found=true -f cloud-pvc.yml
|
||||
kubectl delete --ignore-not-found=true -f cloud-service.yml
|
||||
kubectl delete --ignore-not-found=true -f cloud-secret.yml
|
||||
kubectl delete --ignore-not-found=true -f cloud-persistent-volume.yml
|
||||
|
||||
#Wait for postgres to be running
|
||||
while [$POSTGRES = ""]
|
||||
do
|
||||
POSTGRES=$(kubectl get pods --selector=app=postgresql -o jsonpath='{.items[*].metadata.name}')
|
||||
done
|
||||
kubectl wait --for=condition=ready pod/$POSTGRES
|
||||
|
||||
kubectl apply -f cloud-persistent-volume.yml
|
||||
kubectl apply -f cloud-secret.yml
|
||||
kubectl apply -f cloud-service.yml
|
||||
kubectl apply -f cloud-pvc.yml
|
||||
kubectl apply -f cloud-pod.yml
|
||||
kubectl apply -f cloud-ingress.yml
|
26
main/resources/cloud/ingress.yaml
Normal file
26
main/resources/cloud/ingress.yaml
Normal file
|
@ -0,0 +1,26 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-cloud
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-staging-issuer
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "256m"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
namespace: default
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- fqdn
|
||||
secretName: cloud-secret
|
||||
rules:
|
||||
- host: fqdn
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: cloud-service
|
||||
servicePort: 80
|
4
main/resources/cloud/install-as-root.sh.template
Normal file
4
main/resources/cloud/install-as-root.sh.template
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
mkdir -p /var/cloud
|
||||
install -d -m 0777 -o {{user}} -g {{user}} /var/cloud
|
15
main/resources/cloud/persistent-volume.yaml
Normal file
15
main/resources/cloud/persistent-volume.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
kind: PersistentVolume
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: cloud-pv-volume
|
||||
labels:
|
||||
type: local
|
||||
app: cloud
|
||||
spec:
|
||||
storageClassName: manual
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: {{storage-size}}Gi #??? 30Gi?
|
||||
hostPath:
|
||||
path: "/var/cloud"
|
25
main/resources/cloud/pod-running.sh
Executable file
25
main/resources/cloud/pod-running.sh
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
SECONDS=0
|
||||
|
||||
while true; do
|
||||
|
||||
POD_STATUS="$(kubectl get pods --all-namespaces --field-selector=status.phase=Running | grep $1 )";
|
||||
if [ ! -z "$POD_STATUS" ]
|
||||
then
|
||||
# pod = ready is not enough
|
||||
sleep $4
|
||||
break
|
||||
fi
|
||||
|
||||
let duration=$SECONDS/60
|
||||
# pallet needs a regular action, otherwise unwanted timeout after 5 min
|
||||
echo "Seconds waited: ${SECONDS}"
|
||||
if [ "$duration" -ge "$2" ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep $3
|
||||
done
|
||||
|
||||
exit 0
|
16
main/resources/cloud/pvc.yaml
Normal file
16
main/resources/cloud/pvc.yaml
Normal file
|
@ -0,0 +1,16 @@
|
|||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: cloud-pvc
|
||||
labels:
|
||||
app: cloud
|
||||
spec:
|
||||
storageClassName: manual
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: {{storage-size}}Gi #??? 30Gi?
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cloud
|
11
main/resources/cloud/secret.yaml
Normal file
11
main/resources/cloud/secret.yaml
Normal file
|
@ -0,0 +1,11 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: cloud-secret
|
||||
type: Opaque
|
||||
stringData:
|
||||
postgres-db: db-name
|
||||
postgres-user: db-user-name
|
||||
postgres-password: db-user-password
|
||||
nextcloud-admin-user: admin-user
|
||||
nextcloud-admin-password: admin-password
|
9
main/resources/cloud/service.yaml
Normal file
9
main/resources/cloud/service.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cloud-service
|
||||
spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: cloud #???
|
||||
ports:
|
||||
- port: 80
|
15
main/resources/cloud/verify.sh.template
Normal file
15
main/resources/cloud/verify.sh.template
Normal file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo -e "\n====================\n"
|
||||
echo -e "cloud is running, ingress exists"
|
||||
echo -e "\n====================\n"
|
||||
kubectl get all
|
||||
|
||||
echo -e "\n====================\n"
|
||||
echo -e "shows certificate with subject"
|
||||
echo -e "CN={{fqdn}}"
|
||||
echo -e "issuer: CN=Fake LE Intermediate X1"
|
||||
echo -e "\n====================\n"
|
||||
curl --insecure -v https://{{fqdn}}
|
||||
|
||||
echo -e "\n"
|
15
main/resources/postgres/configure-as-user.sh
Normal file
15
main/resources/postgres/configure-as-user.sh
Normal file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
kubectl delete --ignore-not-found=true -f postgres-deployment.yml
|
||||
kubectl delete --ignore-not-found=true -f postgres-pvc.yml
|
||||
kubectl delete --ignore-not-found=true -f postgres-service.yml
|
||||
kubectl delete --ignore-not-found=true -f postgres-config.yml
|
||||
kubectl delete --ignore-not-found=true -f postgres-secret.yml
|
||||
kubectl delete --ignore-not-found=true -f postgres-persistent-volume.yml
|
||||
|
||||
kubectl apply -f postgres-persistent-volume.yml
|
||||
kubectl apply -f postgres-secret.yml
|
||||
kubectl apply -f postgres-config.yml
|
||||
kubectl apply -f postgres-service.yml
|
||||
kubectl apply -f postgres-pvc.yml
|
||||
kubectl apply -f postgres-deployment.yml
|
4
main/resources/postgres/install-as-root.sh.template
Normal file
4
main/resources/postgres/install-as-root.sh.template
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
mkdir -p /var/postgres
|
||||
install -d -m 0777 -o {{user}} -g {{user}} /var/postgres
|
10
main/resources/postgres/postgres-config.yml
Normal file
10
main/resources/postgres/postgres-config.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: postgres-config
|
||||
labels:
|
||||
app: postgres
|
||||
data:
|
||||
postgresql.conf: |
|
||||
max_connections = 1000
|
||||
shared_buffers = 512MB
|
49
main/resources/postgres/postgres-deployment.yml.template
Normal file
49
main/resources/postgres/postgres-deployment.yml.template
Normal file
|
@ -0,0 +1,49 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: postgresql
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgresql
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgresql
|
||||
spec:
|
||||
containers:
|
||||
- image: postgres
|
||||
name: postgresql
|
||||
env:
|
||||
- name: POSTGRES_USER_FILE
|
||||
value: /var/run/secrets/postgres-secrets/postgres-user
|
||||
- name: POSTGRES_DB_FILE
|
||||
value: /var/run/secrets/postgres-secrets/postgres-db
|
||||
- name: POSTGRES_PASSWORD_FILE
|
||||
value: /var/run/secrets/postgres-secrets/postgres-password
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
name: postgresql
|
||||
cmd:
|
||||
volumeMounts:
|
||||
- name: postgresql
|
||||
mountPath: /var/lib/postgresql/data
|
||||
- name: postgres-secret-volume
|
||||
mountPath: /var/run/secrets/postgres-secrets
|
||||
readOnly: true
|
||||
- name: postgres-config-volume
|
||||
mountPath: /etc/postgresql/postgresql.conf
|
||||
subPath: postgresql.conf
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: postgresql
|
||||
persistentVolumeClaim:
|
||||
claimName: postgres-claim
|
||||
- name: postgres-secret-volume
|
||||
secret:
|
||||
secretName: postgres-secret
|
||||
- name: postgres-config-volume
|
||||
configMap:
|
||||
name: postgres-config
|
15
main/resources/postgres/postgres-persistent-volume.yml
Normal file
15
main/resources/postgres/postgres-persistent-volume.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
kind: PersistentVolume
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: postgres-pv-volume
|
||||
labels:
|
||||
type: local
|
||||
app: postgresql
|
||||
spec:
|
||||
storageClassName: manual
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
hostPath:
|
||||
path: "/var/postgres"
|
16
main/resources/postgres/postgres-pvc.yml
Normal file
16
main/resources/postgres/postgres-pvc.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: postgres-claim
|
||||
labels:
|
||||
app: postgresql
|
||||
spec:
|
||||
storageClassName: manual
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgresql
|
9
main/resources/postgres/postgres-secret.yml.template
Normal file
9
main/resources/postgres/postgres-secret.yml.template
Normal file
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: postgres-secret
|
||||
type: Opaque
|
||||
stringData:
|
||||
postgres-db: cloud
|
||||
postgres-user: {{db-user-name}}
|
||||
postgres-password: {{db-user-password}}
|
10
main/resources/postgres/postgres-service.yml
Normal file
10
main/resources/postgres/postgres-service.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgresql-service
|
||||
spec:
|
||||
selector:
|
||||
app: postgresql
|
||||
ports:
|
||||
- port: 5432
|
8
main/resources/postgres/verify.sh
Normal file
8
main/resources/postgres/verify.sh
Normal file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo -e "\n====================\n"
|
||||
echo -e "postgres is running"
|
||||
echo -e "\n====================\n"
|
||||
kubectl get all
|
||||
|
||||
echo -e "\n"
|
61
main/src/meissa/pallet/meissa_cloud/app.clj
Normal file
61
main/src/meissa/pallet/meissa_cloud/app.clj
Normal file
|
@ -0,0 +1,61 @@
|
|||
(ns meissa.pallet.meissa-cloud.app
|
||||
(:require
|
||||
[schema.core :as s]
|
||||
[dda.pallet.commons.secret :as secret]
|
||||
[dda.config.commons.map-utils :as mu]
|
||||
[dda.pallet.core.app :as core-app]
|
||||
[dda.pallet.dda-config-crate.infra :as config-crate]
|
||||
[dda.pallet.dda-user-crate.app :as user]
|
||||
[dda.pallet.dda-k8s-crate.app :as k8s]
|
||||
[meissa.pallet.meissa-cloud.convention :as convention]
|
||||
[meissa.pallet.meissa-cloud.infra :as infra]))
|
||||
|
||||
(def with-cloud infra/with-cloud)
|
||||
|
||||
(def CloudConvention convention/CloudConvention)
|
||||
|
||||
(def CloudConventionResolved convention/CloudConventionResolved)
|
||||
|
||||
(def InfraResult convention/InfraResult)
|
||||
|
||||
(def CloudApp
|
||||
{:group-specific-config
|
||||
{s/Keyword (merge InfraResult
|
||||
user/InfraResult
|
||||
k8s/InfraResult)}})
|
||||
|
||||
(s/defn ^:always-validate
|
||||
app-configuration-resolved :- CloudApp
|
||||
[resolved-convention-config :- CloudConventionResolved
|
||||
& options]
|
||||
(let [{:keys [group-key] :or {group-key infra/facility}} options]
|
||||
(mu/deep-merge
|
||||
(k8s/app-configuration-resolved
|
||||
(convention/k8s-convention-configuration resolved-convention-config) :group-key group-key)
|
||||
{:group-specific-config
|
||||
{group-key
|
||||
(convention/infra-configuration resolved-convention-config)}})))
|
||||
|
||||
(s/defn ^:always-validate
|
||||
app-configuration :- CloudApp
|
||||
[convention-config :- CloudConvention
|
||||
& options]
|
||||
(let [resolved-convention-config (secret/resolve-secrets convention-config CloudConvention)]
|
||||
(apply app-configuration-resolved resolved-convention-config options)))
|
||||
|
||||
(s/defmethod ^:always-validate
|
||||
core-app/group-spec infra/facility
|
||||
[crate-app
|
||||
convention-config :- CloudConventionResolved]
|
||||
(let [app-config (app-configuration-resolved convention-config)]
|
||||
(core-app/pallet-group-spec
|
||||
app-config [(config-crate/with-config app-config)
|
||||
user/with-user
|
||||
k8s/with-k8s
|
||||
with-cloud])))
|
||||
|
||||
(def crate-app (core-app/make-dda-crate-app
|
||||
:facility infra/facility
|
||||
:convention-schema CloudConvention
|
||||
:convention-schema-resolved CloudConventionResolved
|
||||
:default-convention-file "cloud.edn"))
|
93
main/src/meissa/pallet/meissa_cloud/convention.clj
Normal file
93
main/src/meissa/pallet/meissa_cloud/convention.clj
Normal file
|
@ -0,0 +1,93 @@
|
|||
(ns meissa.pallet.meissa-cloud.convention
|
||||
(:require
|
||||
[schema.core :as s]
|
||||
[dda.pallet.commons.secret :as secret]
|
||||
[dda.config.commons.map-utils :as mu]
|
||||
[clojure.spec.alpha :as sp]
|
||||
[clojure.spec.test.alpha :as st]
|
||||
[dda.pallet.dda-k8s-crate.convention :as k8s-convention]
|
||||
[meissa.pallet.meissa-cloud.infra :as infra]
|
||||
[clojure.string :as str]
|
||||
[meissa.pallet.meissa-cloud.convention.bash :as bash]
|
||||
[meissa.pallet.meissa-cloud.convention.bash-php :as bash-php]))
|
||||
|
||||
(def InfraResult {infra/facility infra/MeissaCloudInfra})
|
||||
|
||||
(s/def CloudConvention
|
||||
{:user s/Keyword
|
||||
:external-ip s/Str
|
||||
:fqdn s/Str
|
||||
:cert-manager (s/enum :letsencrypt-prod-issuer :letsencrypt-staging-issuer)
|
||||
:db-user-password secret/Secret
|
||||
:admin-user s/Str
|
||||
:admin-password secret/Secret
|
||||
:storage-size s/Int
|
||||
:restic-repository s/Str
|
||||
:aws-access-key-id secret/Secret
|
||||
:aws-secret-access-key secret/Secret
|
||||
:restic-password secret/Secret
|
||||
(s/optional-key :u18-04) (s/enum true)})
|
||||
|
||||
(def CloudConventionResolved (secret/create-resolved-schema CloudConvention))
|
||||
|
||||
(sp/def ::user keyword?)
|
||||
(sp/def ::external-ip string?)
|
||||
(sp/def ::fqdn string?)
|
||||
(sp/def ::cert-manager #{:letsencrypt-prod-issuer :letsencrypt-staging-issuer})
|
||||
(sp/def ::db-user-password bash-php/bash-php-env-string?)
|
||||
(sp/def ::admin-user bash-php/bash-php-env-string?)
|
||||
(sp/def ::admin-password bash-php/bash-php-env-string?)
|
||||
(sp/def ::storage-size int?)
|
||||
(sp/def ::restic-repository string?)
|
||||
(sp/def ::restic-password bash/bash-env-string?)
|
||||
(sp/def ::aws-access-key-id bash/bash-env-string?)
|
||||
(sp/def ::aws-secret-access-key bash/bash-env-string?)
|
||||
(sp/def ::u18-04 #{true})
|
||||
(def cloud-convention-resolved? (sp/keys :req-un [::user ::external-ip ::fqdn ::cert-manager
|
||||
::db-user-password ::admin-user ::admin-password
|
||||
::storage-size ::restic-repository ::restic-password
|
||||
::aws-access-key-id ::aws-secret-access-key ]
|
||||
:opt-un [::u18-04]))
|
||||
|
||||
(def cloud-spec-resolved nil)
|
||||
|
||||
(s/defn k8s-convention-configuration :- k8s-convention/k8sConventionResolved
|
||||
[convention-config :- CloudConventionResolved]
|
||||
{:pre [(sp/valid? cloud-convention-resolved? convention-config)]}
|
||||
(let [{:keys [cert-manager external-ip user u18-04]} convention-config
|
||||
cluster-issuer (name cert-manager)]
|
||||
(if u18-04
|
||||
{:user user
|
||||
:k8s {:external-ip external-ip
|
||||
:u18-04 true}
|
||||
:cert-manager cert-manager}
|
||||
{:user user
|
||||
:k8s {:external-ip external-ip}
|
||||
:cert-manager cert-manager})))
|
||||
|
||||
|
||||
(s/defn ^:always-validate
|
||||
infra-configuration :- InfraResult
|
||||
[convention-config :- CloudConventionResolved]
|
||||
(let [{:keys [cert-manager fqdn user db-user-password admin-user admin-password storage-size
|
||||
restic-repository aws-access-key-id aws-secret-access-key restic-password]} convention-config
|
||||
cluster-issuer (name cert-manager)
|
||||
db-user-name "cloud"]
|
||||
{infra/facility
|
||||
{:user user
|
||||
:backup {:restic-repository restic-repository
|
||||
:aws-access-key-id aws-access-key-id
|
||||
:aws-secret-access-key aws-secret-access-key
|
||||
:restic-password restic-password}
|
||||
:cloud {:fqdn fqdn
|
||||
:secret-name (str/replace fqdn #"\." "-")
|
||||
:cluster-issuer cluster-issuer
|
||||
:db-name "cloud"
|
||||
:db-user-password db-user-password
|
||||
:db-user-name db-user-name
|
||||
:admin-user admin-user
|
||||
:admin-password admin-password
|
||||
:storage-size (str storage-size)}
|
||||
:postgres {:db-user-password db-user-password
|
||||
:db-user-name db-user-name}}}))
|
||||
|
10
main/src/meissa/pallet/meissa_cloud/convention/bash.clj
Normal file
10
main/src/meissa/pallet/meissa_cloud/convention/bash.clj
Normal file
|
@ -0,0 +1,10 @@
|
|||
(ns meissa.pallet.meissa-cloud.convention.bash
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]))
|
||||
|
||||
(defn bash-env-string?
|
||||
[input]
|
||||
(and (string? input)
|
||||
(not (re-matches #".*['\"\$]+.*" input))))
|
||||
|
||||
(s/def ::plain bash-env-string?)
|
11
main/src/meissa/pallet/meissa_cloud/convention/bash_php.clj
Normal file
11
main/src/meissa/pallet/meissa_cloud/convention/bash_php.clj
Normal file
|
@ -0,0 +1,11 @@
|
|||
(ns meissa.pallet.meissa-cloud.convention.bash-php
|
||||
(:require
|
||||
[clojure.spec.alpha :as s]
|
||||
[meissa.pallet.meissa-cloud.convention.bash :as bash]))
|
||||
|
||||
(defn bash-php-env-string?
|
||||
[input]
|
||||
(and (bash/bash-env-string? input)
|
||||
(not (re-matches #".*[\-\\\\]+.*" input))))
|
||||
|
||||
(s/def ::plain bash-php-env-string?)
|
51
main/src/meissa/pallet/meissa_cloud/infra.clj
Normal file
51
main/src/meissa/pallet/meissa_cloud/infra.clj
Normal file
|
@ -0,0 +1,51 @@
|
|||
(ns meissa.pallet.meissa-cloud.infra
|
||||
(:require
|
||||
[schema.core :as s]
|
||||
[dda.pallet.core.infra :as core-infra]
|
||||
[meissa.pallet.meissa-cloud.infra.backup :as backup]
|
||||
[meissa.pallet.meissa-cloud.infra.cloud :as cloud]
|
||||
[meissa.pallet.meissa-cloud.infra.postgres :as postgres]))
|
||||
|
||||
(def facility :meissa-cloud)
|
||||
|
||||
(def MeissaCloudInfra
|
||||
(merge
|
||||
{:user s/Keyword}
|
||||
backup/MeissaBackupInfra
|
||||
cloud/MeissaCloudInfra
|
||||
postgres/MeissaPostgresInfra))
|
||||
|
||||
(s/defmethod core-infra/dda-init facility
|
||||
[dda-crate config]
|
||||
(let [facility (:facility dda-crate)
|
||||
{:keys [user backup postgres cloud]} config
|
||||
user-str (name user)]
|
||||
(postgres/init facility user-str postgres)
|
||||
(cloud/init facility user-str cloud)
|
||||
(backup/init facility user-str backup)))
|
||||
|
||||
(s/defmethod core-infra/dda-install facility
|
||||
[dda-crate config]
|
||||
(let [facility (:facility dda-crate)
|
||||
{:keys [user backup postgres cloud]} config
|
||||
user-str (name user)]
|
||||
(postgres/install facility user-str postgres)
|
||||
(cloud/install facility user-str cloud)
|
||||
(backup/install facility user-str backup)))
|
||||
|
||||
(s/defmethod core-infra/dda-configure facility
|
||||
[dda-crate config]
|
||||
(let [facility (:facility dda-crate)
|
||||
{:keys [user backup postgres cloud]} config
|
||||
user-str (name user)]
|
||||
(postgres/configure facility user-str postgres)
|
||||
(cloud/configure facility user-str cloud)
|
||||
(backup/configure facility user-str backup)))
|
||||
|
||||
(def meissa-cloud
|
||||
(core-infra/make-dda-crate-infra
|
||||
:facility facility
|
||||
:infra-schema MeissaCloudInfra))
|
||||
|
||||
(def with-cloud
|
||||
(core-infra/create-infra-plan meissa-cloud))
|
39
main/src/meissa/pallet/meissa_cloud/infra/backup.clj
Normal file
39
main/src/meissa/pallet/meissa_cloud/infra/backup.clj
Normal file
|
@ -0,0 +1,39 @@
|
|||
(ns meissa.pallet.meissa-cloud.infra.backup
|
||||
(:require
|
||||
[schema.core :as s]
|
||||
[dda.provision :as p]
|
||||
[dda.provision.pallet :as pp]))
|
||||
|
||||
(s/def Backup
|
||||
{:restic-repository s/Str
|
||||
:aws-access-key-id s/Str
|
||||
:aws-secret-access-key s/Str
|
||||
:restic-password s/Str})
|
||||
|
||||
(def MeissaBackupInfra {:backup Backup})
|
||||
|
||||
(def backup "backup")
|
||||
|
||||
(defn init [facility user config])
|
||||
|
||||
(defn install
|
||||
[facility user config]
|
||||
(let [facility-name (name facility)]
|
||||
(p/provision-log ::pp/pallet facility-name backup
|
||||
::p/info "install")
|
||||
(p/copy-resources-to-user
|
||||
::pp/pallet user facility-name backup
|
||||
[{:filename "backup-secret.yml" :config config}
|
||||
{:filename "backup-config.yml" :config config}
|
||||
{:filename "configure-as-user.sh"}
|
||||
{:filename "backup-restore.yml"}
|
||||
{:filename "backup-cron.yml"}])))
|
||||
|
||||
(defn configure
|
||||
[facility user config]
|
||||
(let [facility-name (name facility)]
|
||||
(p/provision-log ::pp/pallet facility-name backup
|
||||
::p/info "configure")
|
||||
(p/exec-file-on-target-as-user
|
||||
::pp/pallet user facility-name backup "configure-as-user.sh")
|
||||
))
|
57
main/src/meissa/pallet/meissa_cloud/infra/cloud.clj
Normal file
57
main/src/meissa/pallet/meissa_cloud/infra/cloud.clj
Normal file
|
@ -0,0 +1,57 @@
|
|||
(ns meissa.pallet.meissa-cloud.infra.cloud
|
||||
(:require
|
||||
[schema.core :as s]
|
||||
[dda.provision :as p]
|
||||
[dda.provision.pallet :as pp]))
|
||||
|
||||
(s/def Cloud
|
||||
{:fqdn s/Str
|
||||
:secret-name s/Str
|
||||
:cluster-issuer s/Str
|
||||
:db-name s/Str
|
||||
:db-user-name s/Str
|
||||
:db-user-password s/Str
|
||||
:admin-user s/Str
|
||||
:admin-password s/Str
|
||||
:storage-size s/Str})
|
||||
|
||||
(def MeissaCloudInfra {:cloud Cloud})
|
||||
|
||||
(def cloud "cloud")
|
||||
|
||||
(defn init
|
||||
[facility user config]
|
||||
(let [facility-name (name facility)]
|
||||
(p/provision-log ::pp/pallet facility-name cloud
|
||||
::p/info "init")
|
||||
(p/copy-resources-to-tmp
|
||||
::pp/pallet facility-name cloud
|
||||
[{:filename "install-as-root.sh" :config {:user user}}])))
|
||||
|
||||
|
||||
(defn install
|
||||
[facility user config]
|
||||
(let [facility-name (name facility)]
|
||||
(p/provision-log ::pp/pallet facility-name cloud
|
||||
::p/info "install")
|
||||
(p/copy-resources-to-user
|
||||
::pp/pallet user facility-name cloud
|
||||
[{:filename "pod-running.sh"}
|
||||
{:filename "cloud-persistent-volume.yml" :config config}
|
||||
{:filename "cloud-secret.yml" :config config}
|
||||
{:filename "cloud-service.yml"}
|
||||
{:filename "cloud-pvc.yml" :config config}
|
||||
{:filename "cloud-pod.yml" :config config}
|
||||
{:filename "cloud-ingress.yml" :config config}
|
||||
{:filename "configure-as-user.sh"}
|
||||
{:filename "verify.sh" :config config}])
|
||||
(p/exec-file-on-target-as-root
|
||||
::pp/pallet facility-name cloud "install-as-root.sh")))
|
||||
|
||||
(defn configure
|
||||
[facility user config]
|
||||
(let [facility-name (name facility)]
|
||||
(p/provision-log ::pp/pallet facility-name cloud
|
||||
::p/info "configure")
|
||||
(p/exec-file-on-target-as-user
|
||||
::pp/pallet user facility-name cloud "configure-as-user.sh")))
|
47
main/src/meissa/pallet/meissa_cloud/infra/postgres.clj
Normal file
47
main/src/meissa/pallet/meissa_cloud/infra/postgres.clj
Normal file
|
@ -0,0 +1,47 @@
|
|||
(ns meissa.pallet.meissa-cloud.infra.postgres
|
||||
(:require
|
||||
[schema.core :as s]
|
||||
[dda.provision :as p]
|
||||
[dda.provision.pallet :as pp]))
|
||||
|
||||
(s/def Postgres {:db-user-name s/Str :db-user-password s/Str})
|
||||
|
||||
(def MeissaPostgresInfra {:postgres Postgres})
|
||||
|
||||
(def postgres "postgres")
|
||||
|
||||
(defn init
|
||||
[facility user config]
|
||||
(let [facility-name (name facility)]
|
||||
(p/provision-log ::pp/pallet facility-name postgres
|
||||
::p/info "init")
|
||||
(p/copy-resources-to-tmp
|
||||
::pp/pallet facility-name postgres
|
||||
[{:filename "install-as-root.sh" :config {:user user}}])))
|
||||
|
||||
|
||||
(defn install
|
||||
[facility user config]
|
||||
(let [facility-name (name facility)]
|
||||
(p/provision-log ::pp/pallet facility-name postgres
|
||||
::p/info "install")
|
||||
(p/copy-resources-to-user
|
||||
::pp/pallet user facility-name postgres
|
||||
[{:filename "postgres-persistent-volume.yml"}
|
||||
{:filename "postgres-secret.yml" :config config}
|
||||
{:filename "postgres-config.yml"}
|
||||
{:filename "postgres-service.yml"}
|
||||
{:filename "postgres-pvc.yml"}
|
||||
{:filename "postgres-deployment.yml" :config config}
|
||||
{:filename "configure-as-user.sh"}
|
||||
{:filename "verify.sh"}])
|
||||
(p/exec-file-on-target-as-root
|
||||
::pp/pallet facility-name postgres "install-as-root.sh")))
|
||||
|
||||
(defn configure
|
||||
[facility user config]
|
||||
(let [facility-name (name facility)]
|
||||
(p/provision-log ::pp/pallet facility-name postgres
|
||||
::p/info "configure")
|
||||
(p/exec-file-on-target-as-user
|
||||
::pp/pallet user facility-name postgres "configure-as-user.sh")))
|
86
project.clj
86
project.clj
|
@ -1,41 +1,55 @@
|
|||
(defproject org.domaindrivenarchitecture/c4k-cloud "0.1.3-SNAPSHOT"
|
||||
:description "cloud c4k-installation package"
|
||||
:url "https://domaindrivenarchitecture.org"
|
||||
:license {:name "Apache License, Version 2.0"
|
||||
:url "https://www.apache.org/licenses/LICENSE-2.0.html"}
|
||||
:dependencies [[org.clojure/clojure "1.10.3"]
|
||||
[org.clojure/tools.reader "1.3.4"]
|
||||
[org.domaindrivenarchitecture/c4k-common-clj "0.2.8"]]
|
||||
(defproject meissa/meissa-cloud "1.0.2-SNAPSHOT"
|
||||
:description "Crate to install cloud"
|
||||
:url "https://meissa-gmbh.de"
|
||||
:license {:name "meissa commercial license"
|
||||
:url "https://www.meissa-gmbh.de"}
|
||||
:dependencies [[dda/dda-pallet "4.0.3"]
|
||||
[dda/dda-k8s-crate "1.0.1"]
|
||||
[orchestra "2021.01.01-1"]]
|
||||
:target-path "target/%s/"
|
||||
:source-paths ["src/main/cljc"
|
||||
"src/main/clj"]
|
||||
:resource-paths ["src/main/resources"]
|
||||
:repositories [["snapshots" :clojars]
|
||||
["releases" :clojars]]
|
||||
:deploy-repositories [["snapshots" :clojars]
|
||||
["releases" :clojars]]
|
||||
:profiles {:test {:test-paths ["src/test/cljc"]
|
||||
:resource-paths ["src/test/resources"]
|
||||
:dependencies [[dda/data-test "0.1.1"]]}
|
||||
:dev {:plugins [[lein-shell "0.5.0"]]}
|
||||
:uberjar {:aot :all
|
||||
:main dda.c4k-cloud.uberjar
|
||||
:uberjar-name "c4k-cloud-standalone.jar"
|
||||
:dependencies [[org.clojure/tools.cli "1.0.206"]
|
||||
[ch.qos.logback/logback-classic "1.3.0-alpha4"
|
||||
:exclusions [com.sun.mail/javax.mail]]
|
||||
:source-paths ["main/src"]
|
||||
:resource-paths ["main/resources"]
|
||||
:repositories [["clojars" "https://clojars.org/repo"]
|
||||
["snapshots"
|
||||
"https://artifact.prod.meissa-gmbh.de/repository/maven-snapshots/"]
|
||||
["releases"
|
||||
"https://artifact.prod.meissa-gmbh.de/repository/maven-releases/"]]
|
||||
:deploy-repositories [["snapshots" "https://artifact.prod.meissa-gmbh.de/repository/maven-snapshots/"]
|
||||
["releases" "https://artifact.prod.meissa-gmbh.de/repository/maven-releases/"]]
|
||||
:profiles {:dev {:source-paths ["integration/src"
|
||||
"test/src"
|
||||
"uberjar/src"]
|
||||
:resource-paths ["integration/resources"
|
||||
"test/resources"]
|
||||
:dependencies
|
||||
[[org.clojure/test.check "1.1.0"]
|
||||
[dda/data-test "0.1.1"]
|
||||
[dda/pallet "0.9.1" :classifier "tests"]
|
||||
[ch.qos.logback/logback-classic "1.3.0-alpha5"]
|
||||
[org.slf4j/jcl-over-slf4j "2.0.0-alpha1"]]
|
||||
:plugins
|
||||
[[lein-sub "0.3.0"]]
|
||||
:leiningen/reply
|
||||
{:dependencies [[org.slf4j/jcl-over-slf4j "1.8.0-beta2"]]
|
||||
:exclusions [commons-logging]}}
|
||||
:test {:test-paths ["test/src"]
|
||||
:resource-paths ["test/resources"]
|
||||
:dependencies [[dda/pallet "0.9.1" :classifier "tests"]]}
|
||||
:uberjar {:source-paths ["uberjar/src"]
|
||||
:resource-paths ["uberjar/resources"]
|
||||
:aot :all
|
||||
:main meissa.pallet.meissa-cloud.main
|
||||
:uberjar-name "meissa-cloud-standalone.jar"
|
||||
:dependencies [[org.clojure/tools.cli "1.0.194"]
|
||||
[ch.qos.logback/logback-classic "1.3.0-alpha5"]
|
||||
[org.slf4j/jcl-over-slf4j "2.0.0-alpha1"]]}}
|
||||
:release-tasks [["test"]
|
||||
["vcs" "assert-committed"]
|
||||
:release-tasks [["vcs" "assert-committed"]
|
||||
["change" "version" "leiningen.release/bump-version" "release"]
|
||||
["vcs" "commit"]
|
||||
["vcs" "tag"]
|
||||
["change" "version" "leiningen.release/bump-version"]]
|
||||
:aliases {"native" ["shell"
|
||||
"native-image"
|
||||
"--report-unsupported-elements-at-runtime"
|
||||
"--initialize-at-build-time"
|
||||
"-jar" "target/uberjar/c4k-cloud-standalone.jar"
|
||||
"-H:ResourceConfigurationFiles=graalvm-resource-config.json"
|
||||
"-H:Log=registerResource"
|
||||
"-H:Name=target/graalvm/${:name}"]})
|
||||
["deploy"]
|
||||
["uberjar"]
|
||||
["change" "version" "leiningen.release/bump-version"]
|
||||
["vcs" "commit"]
|
||||
["vcs" "push"]]
|
||||
:local-repo-classpath true)
|
||||
|
|
3
targets.edn
Normal file
3
targets.edn
Normal file
|
@ -0,0 +1,3 @@
|
|||
{:existing [{:node-name "cloud"
|
||||
:node-ip "168.119.190.126"}]
|
||||
:provisioning-user {:login "root"}}
|
|
@ -0,0 +1,30 @@
|
|||
{:input {:user :k8s
|
||||
:external-ip "95.217.221.140"
|
||||
:fqdn "cloud.test.meissa-gmbh.de"
|
||||
:cert-manager :letsencrypt-staging-issuer
|
||||
:db-user-password "test1234"
|
||||
:admin-user "root"
|
||||
:admin-password "test1234"
|
||||
:storage-size 50
|
||||
:restic-repository "test4321"
|
||||
:aws-access-key-id "10"
|
||||
:aws-secret-access-key "secret"
|
||||
:restic-password "test4321"}
|
||||
:expected {:meissa-cloud
|
||||
{:user :k8s
|
||||
:backup {:restic-repository "test4321"
|
||||
:aws-access-key-id "10"
|
||||
:aws-secret-access-key "secret"
|
||||
:restic-password "test4321"}
|
||||
:cloud {:fqdn "cloud.test.meissa-gmbh.de"
|
||||
:secret-name "cloud-test-meissa-gmbh-de"
|
||||
:cluster-issuer "letsencrypt-staging-issuer"
|
||||
:db-name "cloud"
|
||||
:db-user-password "test1234"
|
||||
:db-user-name "cloud"
|
||||
:admin-user "root"
|
||||
:admin-password "test1234"
|
||||
:storage-size "50"}
|
||||
:postgres {:db-user-password "test1234"
|
||||
:db-user-name "cloud"}}}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{:input {:user :k8s
|
||||
:external-ip "95.217.221.140"
|
||||
:fqdn "cloud.test.meissa-gmbh.de"
|
||||
:cert-manager :letsencrypt-staging-issuer
|
||||
:db-user-password "test1234"
|
||||
:admin-user "root"
|
||||
:admin-password "test1234"
|
||||
:storage-size 50
|
||||
:restic-repository "cloud"
|
||||
:aws-access-key-id "10"
|
||||
:aws-secret-access-key "secret"
|
||||
:restic-password "test4321"}
|
||||
:expected {:user :k8s, :k8s {:external-ip "95.217.221.140"},
|
||||
:cert-manager :letsencrypt-staging-issuer}}
|
||||
|
||||
{:input {:user :k8s
|
||||
:external-ip "95.217.221.140"
|
||||
:fqdn "cloud.test.meissa-gmbh.de"
|
||||
:cert-manager :letsencrypt-staging-issuer
|
||||
:db-user-password "test1234"
|
||||
:admin-user "root"
|
||||
:admin-password "test1234"
|
||||
:storage-size 50
|
||||
:restic-repository "cloud"
|
||||
:aws-access-key-id "10"
|
||||
:aws-secret-access-key "secret"
|
||||
:restic-password "test4321"
|
||||
:u18-04 true}
|
||||
:expected {:user :k8s, :k8s {:external-ip "95.217.221.140", :u18-04 true}
|
||||
:cert-manager :letsencrypt-staging-issuer}}
|
|
@ -0,0 +1,14 @@
|
|||
{:input {:user :k8s
|
||||
:external-ip "95.217.221.140"
|
||||
:fqdn "cloud.test.meissa-gmbh.de"
|
||||
:cert-manager :letsencrypt-staging-issuer
|
||||
:db-user-password "test1234"
|
||||
:admin-user "root"
|
||||
:admin-password "test1234"
|
||||
:storage-size 50
|
||||
:restic-repository "test4321"
|
||||
:aws-access-key-id "10"
|
||||
:aws-secret-access-key "secret"
|
||||
:restic-password "test4321"}
|
||||
:expected true
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{:input {:user :k8s
|
||||
:external-ip "95.217.221.140"
|
||||
:fqdn "cloud.test.meissa-gmbh.de"
|
||||
:cert-manager :letsencrypt-staging-issuer
|
||||
:db-user-password "test-1234"
|
||||
:admin-user "root"
|
||||
:admin-password "test1234"
|
||||
:storage-size 50
|
||||
:restic-repository "test4321"
|
||||
:aws-access-key-id "10"
|
||||
:aws-secret-access-key "secret"
|
||||
:restic-password "test4321"}
|
||||
:expected false
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{:input {:user :k8s
|
||||
:external-ip "95.217.221.140"
|
||||
:fqdn "cloud.test.meissa-gmbh.de"
|
||||
:cert-manager :letsencrypt-staging-issuer
|
||||
:db-user-password "test1234"
|
||||
:admin-user "root"
|
||||
:admin-password "test1234"
|
||||
:storage-size 50
|
||||
:restic-repository "test4321"
|
||||
:aws-access-key-id "1$0"
|
||||
:aws-secret-access-key "secret"
|
||||
:restic-password "test4321"}
|
||||
:expected false
|
||||
}
|
31
test/src/meissa/pallet/meissa_cloud/app_test.clj
Normal file
31
test/src/meissa/pallet/meissa_cloud/app_test.clj
Normal file
|
@ -0,0 +1,31 @@
|
|||
(ns meissa.pallet.meissa-cloud.app-test
|
||||
(:require
|
||||
[clojure.test :refer :all]
|
||||
[schema.core :as s]
|
||||
[meissa.pallet.meissa-cloud.app :as sut]))
|
||||
|
||||
(s/set-fn-validation! true)
|
||||
|
||||
(s/def test-convention-conf
|
||||
{:user :k8s
|
||||
:external-ip "12.121.111.121"
|
||||
:fqdn "some.domain.de"
|
||||
:cert-manager :letsencrypt-staging-issuer
|
||||
:db-user-password "test1234"
|
||||
:admin-user "root"
|
||||
:admin-password "test1234"
|
||||
:storage-size 50
|
||||
:restic-repository "cloud"
|
||||
:aws-access-key-id "10"
|
||||
:aws-secret-access-key "secret"
|
||||
:restic-password "test4321"})
|
||||
|
||||
(deftest app-config
|
||||
(testing
|
||||
"test plan-def"
|
||||
(is (map? (sut/app-configuration-resolved test-convention-conf)))))
|
||||
|
||||
(deftest plan-def
|
||||
(testing
|
||||
"test plan-def"
|
||||
(is (map? sut/with-cloud))))
|
|
@ -0,0 +1,20 @@
|
|||
(ns meissa.pallet.meissa-cloud.convention.bash-php-test
|
||||
(:require
|
||||
[clojure.test :refer :all]
|
||||
[meissa.pallet.meissa-cloud.convention.bash-php :as sut]))
|
||||
|
||||
|
||||
(deftest test-it
|
||||
(is (= false
|
||||
(sut/bash-php-env-string? 4)))
|
||||
(is (= false
|
||||
(sut/bash-php-env-string? "hal-lo")))
|
||||
(is (= false
|
||||
(sut/bash-php-env-string? "hal--lo")))
|
||||
(is (= false
|
||||
(sut/bash-php-env-string? "hal\\lo")))
|
||||
(is (= true
|
||||
(sut/bash-php-env-string? "test")))
|
||||
(is (= true
|
||||
(sut/bash-php-env-string? "test123")))
|
||||
)
|
22
test/src/meissa/pallet/meissa_cloud/convention/bash_test.clj
Normal file
22
test/src/meissa/pallet/meissa_cloud/convention/bash_test.clj
Normal file
|
@ -0,0 +1,22 @@
|
|||
(ns meissa.pallet.meissa-cloud.convention.bash-test
|
||||
(:require
|
||||
[clojure.test :refer :all]
|
||||
[meissa.pallet.meissa-cloud.convention.bash :as sut]))
|
||||
|
||||
|
||||
(deftest test-it
|
||||
(is (= false
|
||||
(sut/bash-env-string? 4)))
|
||||
(is (= false
|
||||
(sut/bash-env-string? "1$0")))
|
||||
(is (= false
|
||||
(sut/bash-env-string? "'hallo")))
|
||||
(is (= false
|
||||
(sut/bash-env-string? "hallo\"")))
|
||||
(is (= false
|
||||
(sut/bash-env-string? "hall$o")))
|
||||
(is (= true
|
||||
(sut/bash-env-string? "test")))
|
||||
(is (= true
|
||||
(sut/bash-env-string? "test123")))
|
||||
)
|
18
test/src/meissa/pallet/meissa_cloud/convention_test.clj
Normal file
18
test/src/meissa/pallet/meissa_cloud/convention_test.clj
Normal file
|
@ -0,0 +1,18 @@
|
|||
(ns meissa.pallet.meissa-cloud.convention-test
|
||||
(:require
|
||||
[clojure.test :refer :all]
|
||||
[data-test :refer :all]
|
||||
[meissa.pallet.meissa-cloud.convention :as sut]
|
||||
[clojure.spec.alpha :as sp]))
|
||||
|
||||
(defdatatest should-generate-infra-for-convention [input expected]
|
||||
(is (= expected
|
||||
(sut/infra-configuration input))))
|
||||
|
||||
(defdatatest should-generate-k8s-convention [input expected]
|
||||
(is (= expected
|
||||
(sut/k8s-convention-configuration input))))
|
||||
|
||||
(defdatatest should-validate-input [input expected]
|
||||
(is (= expected
|
||||
(sp/valid? sut/cloud-convention-resolved? input))))
|
2
uberjar/resources/localhost-target.edn
Normal file
2
uberjar/resources/localhost-target.edn
Normal file
|
@ -0,0 +1,2 @@
|
|||
{:existing [{:node-name "localhost"
|
||||
:node-ip "127.0.0.1"}]}
|
50
uberjar/resources/logback.xml
Normal file
50
uberjar/resources/logback.xml
Normal file
|
@ -0,0 +1,50 @@
|
|||
<configuration scan="true" scanPeriod="1 seconds" debug="false">
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="PALLETFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>logs/pallet.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>logs/old/pallet.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<maxHistory>3</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%date %level [%thread] %logger{10} %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="clj-ssh.ssh" level="ERROR">
|
||||
<appender-ref ref="PALLETFILE" />
|
||||
</logger>
|
||||
|
||||
<logger name="pallet" level="DEBUG">
|
||||
<appender-ref ref="PALLETFILE" />
|
||||
</logger>
|
||||
|
||||
<logger name="pallet.ssh" level="ERROR">
|
||||
<appender-ref ref="PALLETFILE" />
|
||||
</logger>
|
||||
|
||||
<logger name="pallet.algo" level="ERROR">
|
||||
<appender-ref ref="PALLETFILE" />
|
||||
</logger>
|
||||
|
||||
<logger name="dda" level="DEBUG">
|
||||
<appender-ref ref="PALLETFILE" />
|
||||
</logger>
|
||||
|
||||
<logger name="meissa" level="DEBUG">
|
||||
<appender-ref ref="PALLETFILE" />
|
||||
</logger>
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
57
uberjar/src/meissa/pallet/meissa_cloud/main.clj
Normal file
57
uberjar/src/meissa/pallet/meissa_cloud/main.clj
Normal file
|
@ -0,0 +1,57 @@
|
|||
(ns meissa.pallet.meissa-cloud.main
|
||||
(:gen-class)
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[clojure.tools.cli :as cli]
|
||||
[dda.pallet.core.main-helper :as mh]
|
||||
[dda.pallet.core.app :as core-app]
|
||||
[meissa.pallet.meissa-cloud.app :as app]))
|
||||
|
||||
(def cli-options
|
||||
[["-h" "--help"]
|
||||
["-c" "--configure"]
|
||||
["-t" "--targets example-targets.edn" "edn file containing the targets to install on."
|
||||
:default "localhost-target.edn"]
|
||||
["-v" "--verbose"]])
|
||||
|
||||
(defn usage [options-summary]
|
||||
(str/join
|
||||
\newline
|
||||
["meissa-cloud installs & configures a single host kubernetes cluster with Cloud installed"
|
||||
""
|
||||
"Usage: java -jar meissa-cloud-standalone.jar [options] cloud.edn"
|
||||
""
|
||||
"Options:"
|
||||
options-summary
|
||||
""
|
||||
"cloud.edn"
|
||||
" - follows the edn format."
|
||||
" - has to be a valid CloudConventionConfig"
|
||||
""]))
|
||||
|
||||
(defn -main [& args]
|
||||
(let [{:keys [options arguments errors summary help]} (cli/parse-opts args cli-options)
|
||||
verbose (if (contains? options :verbose) 1 0)]
|
||||
(cond
|
||||
help (mh/exit 0 (usage summary))
|
||||
errors (mh/exit 1 (mh/error-msg errors))
|
||||
(not= (count arguments) 1) (mh/exit 1 (usage summary))
|
||||
(:serverspec options) (if (core-app/existing-serverspec
|
||||
app/crate-app
|
||||
{:convention (first arguments)
|
||||
:targets (:targets options)
|
||||
:verbosity verbose})
|
||||
(mh/exit-test-passed)
|
||||
(mh/exit-test-failed))
|
||||
(:configure options) (if (core-app/existing-configure
|
||||
app/crate-app
|
||||
{:convention (first arguments)
|
||||
:targets (:targets options)})
|
||||
(mh/exit-default-success)
|
||||
(mh/exit-default-error))
|
||||
:default (if (core-app/existing-install
|
||||
app/crate-app
|
||||
{:convention (first arguments)
|
||||
:targets (:targets options)})
|
||||
(mh/exit-default-success)
|
||||
(mh/exit-default-error)))))
|
Loading…
Reference in a new issue