Add jsonschema for docker formula
Update run_tests.sh to latest version.
Change-Id: Ia5d9407d101c0f71d273423d28c0c56288300e63
Related-prod: #PROD-20623 (PROD:20623)
diff --git a/.kitchen.yml b/.kitchen.yml
index 9b01e51..b0ab87c 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -32,7 +32,7 @@
source:
engine: pip
pillars-from-files:
- docker_debian_repo.sls: tests/pillar/repo_docker.sls
+ docker_debian_repo.sls: tests/repo_docker.sls
dependencies:
- name: linux
repo: git
@@ -80,8 +80,8 @@
pillars-from-files:
docker.sls: tests/pillar/client_container.sls
- - name: host_single
+ - name: host
provisioner:
pillars-from-files:
- docker.sls: tests/pillar/host_single.sls
+ docker.sls: tests/pillar/host.sls
# vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git a/docker/files/daemon.json b/docker/files/daemon.json
index 64de897..68ac943 100644
--- a/docker/files/daemon.json
+++ b/docker/files/daemon.json
@@ -3,7 +3,7 @@
{#- legacy and backward compatibility -#}
{%- if 'experimental' not in host.get('options') and host.experimental is defined %}
- {% do host.update({"experimental": host.experimental}) %}
+ {% do host.options.update({"experimental": host.experimental}) %}
{%- endif -%}
{%- if 'insecure-registries' not in host.get('options') and host.insecure_registries is defined %}
diff --git a/docker/files/registry.yml b/docker/files/registry.yml
index c762e06..6727d01 100644
--- a/docker/files/registry.yml
+++ b/docker/files/registry.yml
@@ -34,7 +34,7 @@
enabled: true
interval: 10s
threshold: 3
-{%- if registry.hook is defined %}
+{%- if registry.hooks is defined %}
hooks:
{%- for type, hook in registry.hooks %}
- type: {{ type }}
diff --git a/docker/schemas/client.yaml b/docker/schemas/client.yaml
new file mode 100644
index 0000000..95e899b
--- /dev/null
+++ b/docker/schemas/client.yaml
@@ -0,0 +1,307 @@
+title: Docker client role
+description: |
+ Docker client role
+type: object
+additionalProperties: false
+
+required:
+- enabled
+
+properties:
+ enabled:
+ description: Enables docker client configuration
+ type: boolean
+ pkgs:
+ description: List of Docker client packages to be installed
+ type: array
+ items:
+ type: string
+ network:
+ description: Docker networks configuration
+ type: object
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: false
+ properties:
+ enabled:
+ type: boolean
+ attachable:
+ type: boolean
+ internal:
+ type: boolean
+ ipv6:
+ type: boolean
+ driver:
+ type: string
+ gateway:
+ type: string
+ iprange:
+ type: string
+ ipamdriver:
+ type: string
+ subnet:
+ type: string
+ opt:
+ description: additional network options
+ type: object
+ additionalProperties: true
+ images:
+ description: List of images to pull to the node
+ type: array
+ items:
+ type: string
+ container:
+ description: Docker containers configuration
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: true
+ properties:
+ image:
+ type: string
+ build:
+ type: string
+ force:
+ type: boolean
+ volumes:
+ type: array
+ items:
+ type: string
+ start:
+ type: boolean
+ user:
+ type: string
+ privileged:
+ type: boolean
+ command:
+ type: string
+ environment:
+ type: object
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ ports:
+ type: array
+ items:
+ type: string
+ volumes_from:
+ type: array
+ items:
+ type: string
+ links:
+ type: array
+ items:
+ type: string
+ restart:
+ description: Restart policy
+ type: string
+ compose:
+ description: Docker compose configuration
+ type: object
+ additionalProperties: false
+ properties:
+ base:
+ description: base directory to store application compose files
+ type: string
+ source:
+ type: object
+ additionalProperties: false
+ properties:
+ engine:
+ description: docker compose installation engine
+ type: string
+ pkgs:
+ description: List of Docker compose packages to be installed
+ type: array
+ items:
+ type: string
+ image:
+ description: Docker compose image
+ type: string
+ version:
+ type: string
+ patternProperties:
+ "^((?!(source|base)$)[A-Za-z0-9_\\-])*$":
+ $ref: "#/definitions/_docker_service"
+ stack:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ $ref: "#/definitions/_docker_service"
+ registry:
+ type: object
+ additionalProperties: false
+ properties:
+ target_registry:
+ type: string
+ image:
+ type: object
+ additionalProperties: false
+ properties:
+ target_registry:
+ type: string
+ registry:
+ type: string
+ name:
+ type: string
+ service:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: false
+ properties:
+ enabled:
+ type: boolean
+ image:
+ type: string
+ command:
+ type: string
+ volume:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: false
+ properties:
+ type:
+ type: string
+ source:
+ type: string
+ environment:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ ports:
+ type: array
+ items:
+ type: string
+ hosts:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: false
+ properties:
+ name:
+ type: string
+ address:
+ type: string
+ label:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ network:
+ type: string
+ replicas:
+ type: [integer, string]
+ user:
+ type: string
+ workdir:
+ type: string
+ mode:
+ type: string
+ endpoint:
+ type: string
+ hostname:
+ type: string
+ constraint:
+ type: string
+ constraints:
+ type: array
+ items:
+ type: string
+ restart:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ update:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ log:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ limit:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ reserve:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ args:
+ type: array
+ items:
+ type: string
+ update_service:
+ type: boolean
+
+
+definitions:
+ _docker_service:
+ type: object
+ additionalProperties: false
+ properties:
+ enabled:
+ type: boolean
+ config:
+ type: object
+ additionalProperties: true
+ service:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: true
+ volume:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: true
+ network:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: true
+ environment:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: string
+ pull:
+ type: boolean
+ user:
+ type: string
+ status:
+ type: string
+ version:
+ type: [number, string]
diff --git a/docker/schemas/host.yaml b/docker/schemas/host.yaml
new file mode 100644
index 0000000..29d5358
--- /dev/null
+++ b/docker/schemas/host.yaml
@@ -0,0 +1,74 @@
+title: Docker host role
+description: |
+ Docker host role
+type: object
+additionalProperties: false
+
+required:
+- enabled
+
+properties:
+ enabled:
+ description: Enables docker host configuration
+ type: boolean
+ pkgs:
+ description: List of Docker packages to be installed
+ type: array
+ items:
+ type: string
+ options:
+ description: Docker configuration options
+ type: object
+ properties:
+ experimental:
+ $ref: "#/definitions/_experimental"
+ insecure_registries:
+ $ref: "#/definitions/insecure_registries"
+ patternProperties:
+ "^[A-Za-z0-9_\\-\\.]*$":
+ type: [array, boolean, string, object]
+ experimental:
+ $ref: "#/definitions/_experimental"
+ insecure_registries:
+ $ref: "#/definitions/insecure_registries"
+ proxy:
+ description: Docker service proxy parameters
+ type: object
+ additionalProperties: false
+ properties:
+ http:
+ type: string
+ https:
+ type: string
+ no_proxy:
+ type: array
+ items:
+ type: string
+ service:
+ description: docker service name
+ type: string
+ registry:
+ type: object
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: false
+ properties:
+ address:
+ type: string
+ user:
+ description: user to login into registry
+ type: string
+ password:
+ description: user password to login into registry
+ type: string
+ system_user:
+ description: docker system user
+ type: string
+
+definitions:
+ _experimental:
+ description: docker experimental options
+ type: object
+ insecure_registries:
+ type: array
diff --git a/docker/schemas/registry.yaml b/docker/schemas/registry.yaml
new file mode 100644
index 0000000..9eb8d11
--- /dev/null
+++ b/docker/schemas/registry.yaml
@@ -0,0 +1,70 @@
+title: Docker registry role
+description: |
+ Docker registry role
+type: object
+additionalProperties: false
+
+properties:
+ enabled:
+ description: Enables docker registry configuration
+ type: boolean
+ pkgs:
+ description: List of Docker registry packages to be installed
+ type: array
+ items:
+ type: string
+ log:
+ type: object
+ additionalProperties: false
+ properties:
+ level:
+ type: string
+ formatter:
+ type: string
+ cache:
+ type: object
+ additionalProperties: false
+ properties:
+ engine:
+ type: string
+ host:
+ type: string
+ port:
+ type: [integer, string]
+ password:
+ type: string
+ db:
+ type: string
+ bind:
+ type: object
+ additionalProperties: false
+ properties:
+ host:
+ type: string
+ port:
+ type: [integer, string]
+ secret:
+ type: string
+ hooks:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: false
+ properties:
+ levels:
+ type: array
+ items:
+ type: string
+ options:
+ type: object
+ additionalProperties: true
+ storage:
+ type: object
+ additionalProperties: false
+ properties:
+ engine:
+ type: string
+ root:
+ type: string
diff --git a/docker/schemas/swarm.yaml b/docker/schemas/swarm.yaml
new file mode 100644
index 0000000..6e1e893
--- /dev/null
+++ b/docker/schemas/swarm.yaml
@@ -0,0 +1,67 @@
+title: Docker swarm role
+description: |
+ Docker swarm role
+type: object
+additionalProperties: false
+
+properties:
+ enabled:
+ description: Enables docker swarm configuration
+ type: boolean
+ network:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^[A-Za-z0-9_\\-]*$":
+ type: object
+ additionalProperties: false
+ properties:
+ enabled:
+ type: boolean
+ attachable:
+ type: boolean
+ internal:
+ type: boolean
+ ipv6:
+ type: boolean
+ driver:
+ type: string
+ gateway:
+ type: string
+ iprange:
+ type: string
+ ipamdriver:
+ type: string
+ subnet:
+ type: string
+ opt:
+ description: additional network options
+ type: object
+ additionalProperties: true
+ role:
+ type: string
+ advertise_addr:
+ type: string
+ bind:
+ type: object
+ additionalProperties: false
+ properties:
+ address:
+ type: string
+ port:
+ type: [integer, string]
+ master:
+ description: docker swarm master parameters to join to
+ type: object
+ additionalProperties: false
+ properties:
+ host:
+ type: string
+ port:
+ type: [integer, string]
+ join_token:
+ type: object
+ additionalProperties: false
+ patternProperties:
+ "^(master|manager)$":
+ type: string
diff --git a/metadata.yml b/metadata.yml
index 4131e83..d2c3f00 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,3 +1,6 @@
name: "docker"
version: "0.2"
source: "https://gerrit.mcp.mirantis.com/salt-formulas/docker"
+dependencies:
+- name: linux
+ source: "https://gerrit.mcp.mirantis.com/salt-formulas/linux"
diff --git a/tests/pillar/client.sls b/tests/pillar/client.sls
new file mode 100644
index 0000000..80d3739
--- /dev/null
+++ b/tests/pillar/client.sls
@@ -0,0 +1,52 @@
+docker:
+ client:
+ enabled: true
+ images:
+ - jenkins:2.7.1
+ - djangoapp:latest
+ - postgres:latest
+ compose:
+ source:
+ engine: pip
+ django_web:
+ # Run up action, any positional argument to docker-compose CLI
+ # If not defined, only docker-compose.yml is generated
+ status: up
+ environment:
+ SOMEVAR: somevalue
+ service:
+ db:
+ image: postgres
+ web:
+ image: djangoapp
+ volumes:
+ - /srv/volumes/django:/srv/django
+ ports:
+ - 8000:8000
+ depends_on:
+ - db
+ container:
+ jenkins:
+ start: false
+ restart: unless-stopped
+ image: jenkins:2.7.1
+ ports:
+ - 8081:8080
+ - 50000:50000
+ environment:
+ JAVA_OPTS: "-Dhudson.footerURL=https://www.example.com"
+ volumes:
+ - /srv/volumes/jenkins:/var/jenkins_home
+ stack:
+ nginx:
+ enabled: true
+ environment:
+ SOMEVAR: somevalue
+ version: 3.3
+ service:
+ nginx:
+ image: nginx
+ volumes:
+ - /srv/volumes/nginx:/srv/nginx
+ ports:
+ - 80:80
diff --git a/tests/pillar/client_container.sls b/tests/pillar/client_container.sls
index 917ed2b..ad80a2e 100644
--- a/tests/pillar/client_container.sls
+++ b/tests/pillar/client_container.sls
@@ -16,4 +16,4 @@
- /srv/volumes/jenkins:/var/jenkins_home
compose:
source:
- engine: pip
\ No newline at end of file
+ engine: pip
diff --git a/tests/pillar/client_images.sls b/tests/pillar/client_images.sls
index 69e4b60..0538c63 100644
--- a/tests/pillar/client_images.sls
+++ b/tests/pillar/client_images.sls
@@ -6,4 +6,4 @@
client:
enabled: true
images:
- - jenkins:2.7.1
\ No newline at end of file
+ - jenkins:2.7.1
diff --git a/tests/pillar/client_deploy.sls b/tests/pillar/client_stack.sls
similarity index 100%
rename from tests/pillar/client_deploy.sls
rename to tests/pillar/client_stack.sls
diff --git a/tests/pillar/host_single_proxy.sls b/tests/pillar/host.sls
similarity index 100%
rename from tests/pillar/host_single_proxy.sls
rename to tests/pillar/host.sls
diff --git a/tests/pillar/host_single.sls b/tests/pillar/host_single.sls
deleted file mode 100644
index 66aa4f9..0000000
--- a/tests/pillar/host_single.sls
+++ /dev/null
@@ -1,12 +0,0 @@
-docker:
- host:
- enabled: true
- options:
- bip: 192.168.0.1/24
- log-driver: json-file
- log-opts:
- size: 50m
- insecure-registry:
- - srv01
- - srv02
- - srv03
diff --git a/tests/pillar/registry.sls b/tests/pillar/registry.sls
new file mode 100644
index 0000000..e336b64
--- /dev/null
+++ b/tests/pillar/registry.sls
@@ -0,0 +1,28 @@
+docker:
+ registry:
+ log:
+ level: debug
+ formatter: json
+ cache:
+ engine: redis
+ host: localhost
+ storage:
+ engine: filesystem
+ root: /srv/docker/registry
+ bind:
+ host: 0.0.0.0
+ port: 5000
+ hooks:
+ mail:
+ levels:
+ - panic
+ # Options are rendered as yaml as is so use hook-specific options here
+ options:
+ smtp:
+ addr: smtp.sendhost.com:25
+ username: sendername
+ password: password
+ insecure: true
+ from: name@sendhost.com
+ to:
+ - name@receivehost.com
diff --git a/tests/pillar/swarm.sls b/tests/pillar/swarm.sls
new file mode 100644
index 0000000..748841c
--- /dev/null
+++ b/tests/pillar/swarm.sls
@@ -0,0 +1,13 @@
+docker:
+ host:
+ enabled: true
+ swarm:
+ advertise_addr: 10.11.0.15
+ network:
+ docker_gwbridge:
+ opt:
+ com.docker.network.bridge.enable_icc: false
+ com.docker.network.bridge.enable_ip_masquerade: true
+ com.docker.network.bridge.name: docker_gwbridge
+ subnet: 10.20.0.0/16
+ role: master
diff --git a/tests/pillar/repo_docker.sls b/tests/repo_docker.sls
similarity index 100%
rename from tests/pillar/repo_docker.sls
rename to tests/repo_docker.sls
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 316692b..461fd8b 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -1,24 +1,40 @@
#!/usr/bin/env bash
+###
+# Script source: https://gerrit.mcp.mirantis.com/#/admin/projects/salt-formulas/cookiecutter-salt-formula
+# Script requirments:
+#apt-get install -y python-yaml virtualenv git
+
+__ScriptVersion="2018.11.21"
+__ScriptName="run_tests.sh"
+__ScriptFullName="$0"
+__ScriptArgs="$*"
+
set -e
[ -n "$DEBUG" ] && set -x
CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
METADATA=${CURDIR}/../metadata.yml
FORMULA_NAME=$(cat $METADATA | python -c "import sys,yaml; print yaml.load(sys.stdin)['name']")
+FORMULA_META_DIR=${CURDIR}/../${FORMULA_NAME}/meta
## Overrideable parameters
PILLARDIR=${PILLARDIR:-${CURDIR}/pillar}
BUILDDIR=${BUILDDIR:-${CURDIR}/build}
VENV_DIR=${VENV_DIR:-${BUILDDIR}/virtualenv}
+MOCK_BIN_DIR=${MOCK_BIN_DIR:-${CURDIR}/mock_bin}
DEPSDIR=${BUILDDIR}/deps
+SCHEMARDIR=${SCHEMARDIR:-"${CURDIR}/../${FORMULA_NAME}/schemas/"}
SALT_FILE_DIR=${SALT_FILE_DIR:-${BUILDDIR}/file_root}
SALT_PILLAR_DIR=${SALT_PILLAR_DIR:-${BUILDDIR}/pillar_root}
SALT_CONFIG_DIR=${SALT_CONFIG_DIR:-${BUILDDIR}/salt}
SALT_CACHE_DIR=${SALT_CACHE_DIR:-${SALT_CONFIG_DIR}/cache}
+SALT_CACHE_EXTMODS_DIR=${SALT_CACHE_EXTMODS_DIR:-${SALT_CONFIG_DIR}/cache_master_extmods}
-SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR}"
+SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR} --log-file=/dev/null"
+
+IGNORE_MODELVALIDATE_MASK=${IGNORE_MODELVALIDATE_MASK:-"novalidate"}
if [ "x${SALT_VERSION}" != "x" ]; then
PIP_SALT_VERSION="==${SALT_VERSION}"
@@ -26,24 +42,38 @@
## Functions
log_info() {
- echo "[INFO] $*"
+ echo -e "[INFO] $*"
}
log_err() {
- echo "[ERROR] $*" >&2
+ echo -e "[ERROR] $*" >&2
}
setup_virtualenv() {
log_info "Setting up Python virtualenv"
+ dependency_check virtualenv
virtualenv $VENV_DIR
source ${VENV_DIR}/bin/activate
python -m pip install salt${PIP_SALT_VERSION}
+ if [[ -f ${CURDIR}/test-requirements.txt ]]; then
+ python -m pip install -r ${CURDIR}/test-requirements.txt
+ fi
+}
+
+setup_mock_bin() {
+ # If some state requires a binary, a lightweight replacement for
+ # such binary can be put into MOCK_BIN_DIR for test purposes
+ if [ -d "${MOCK_BIN_DIR}" ]; then
+ PATH="${MOCK_BIN_DIR}:$PATH"
+ export PATH
+ fi
}
setup_pillar() {
[ ! -d ${SALT_PILLAR_DIR} ] && mkdir -p ${SALT_PILLAR_DIR}
echo "base:" > ${SALT_PILLAR_DIR}/top.sls
for pillar in ${PILLARDIR}/*; do
+ grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
state_name=$(basename ${pillar%.sls})
echo -e " ${state_name}:\n - ${state_name}" >> ${SALT_PILLAR_DIR}/top.sls
done
@@ -53,9 +83,11 @@
[ ! -d ${SALT_FILE_DIR} ] && mkdir -p ${SALT_FILE_DIR}
[ ! -d ${SALT_CONFIG_DIR} ] && mkdir -p ${SALT_CONFIG_DIR}
[ ! -d ${SALT_CACHE_DIR} ] && mkdir -p ${SALT_CACHE_DIR}
+ [ ! -d ${SALT_CACHE_EXTMODS_DIR} ] && mkdir -p ${SALT_CACHE_EXTMODS_DIR}
echo "base:" > ${SALT_FILE_DIR}/top.sls
for pillar in ${PILLARDIR}/*.sls; do
+ grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
state_name=$(basename ${pillar%.sls})
echo -e " ${state_name}:\n - ${FORMULA_NAME}" >> ${SALT_FILE_DIR}/top.sls
done
@@ -63,13 +95,14 @@
cat << EOF > ${SALT_CONFIG_DIR}/minion
file_client: local
cachedir: ${SALT_CACHE_DIR}
+extension_modules: ${SALT_CACHE_EXTMODS_DIR}
verify_env: False
+minion_id_caching: False
file_roots:
base:
- ${SALT_FILE_DIR}
- ${CURDIR}/..
- - /usr/share/salt-formulas/env
pillar_roots:
base:
@@ -79,13 +112,14 @@
}
fetch_dependency() {
+ # example: fetch_dependency "linux:https://github.com/salt-formulas/salt-formula-linux"
dep_name="$(echo $1|cut -d : -f 1)"
dep_source="$(echo $1|cut -d : -f 2-)"
dep_root="${DEPSDIR}/$(basename $dep_source .git)"
dep_metadata="${dep_root}/metadata.yml"
- [ -d /usr/share/salt-formulas/env/${dep_name} ] && log_info "Dependency $dep_name already present in system-wide salt env" && return 0
- [ -d $dep_root ] && log_info "Dependency $dep_name already fetched" && return 0
+ dependency_check git
+ [ -d $dep_root ] && { log_info "Dependency $dep_name already fetched"; return 0; }
log_info "Fetching dependency $dep_name"
[ ! -d ${DEPSDIR} ] && mkdir -p ${DEPSDIR}
@@ -95,6 +129,19 @@
METADATA="${dep_metadata}" install_dependencies
}
+link_modules(){
+ # Link modules *.py files to temporary salt-root
+ local SALT_ROOT=${1:-$SALT_FILE_DIR}
+ local SALT_ENV=${2:-$DEPSDIR}
+
+ mkdir -p "${SALT_ROOT}/_modules/"
+ # from git, development versions
+ find ${SALT_ENV} -maxdepth 3 -mindepth 3 -path '*_modules*' -iname "*.py" -type f -print0 | while read -d $'\0' file; do
+ ln -fs $(readlink -e ${file}) "$SALT_ROOT"/_modules/$(basename ${file}) ;
+ done
+ salt_run saltutil.sync_all
+}
+
install_dependencies() {
grep -E "^dependencies:" ${METADATA} >/dev/null || return 0
(python - | while read dep; do fetch_dependency "$dep"; done) << EOF
@@ -115,21 +162,94 @@
}
prepare() {
- [ -d ${BUILDDIR} ] && mkdir -p ${BUILDDIR}
+ if [[ -f ${BUILDDIR}/.prepare_done ]]; then
+ log_info "${BUILDDIR}/.prepare_done exist, not rebuilding BUILDDIR"
+ return
+ fi
+ [[ -d ${BUILDDIR} ]] && mkdir -p ${BUILDDIR}
- which salt-call || setup_virtualenv
+ [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
+ setup_mock_bin
setup_pillar
setup_salt
install_dependencies
+ link_modules
+ touch ${BUILDDIR}/.prepare_done
+}
+
+lint_releasenotes() {
+ [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
+ source ${VENV_DIR}/bin/activate
+ reno lint ${CURDIR}/../
+}
+
+lint() {
+# lint_releasenotes
+ log_err "TODO: lint_releasenotes"
}
run() {
for pillar in ${PILLARDIR}/*.sls; do
+ grep ${FORMULA_NAME}: ${pillar} &>/dev/null || continue
state_name=$(basename ${pillar%.sls})
+ salt_run grains.set 'noservices' False force=True
+
+ echo "Checking state ${FORMULA_NAME}.${state_name} ..."
salt_run --id=${state_name} state.show_sls ${FORMULA_NAME} || (log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1)
+
+ # Check that all files in 'meta' folder can be rendered using any valid pillar
+ for meta in `find ${FORMULA_META_DIR} -type f`; do
+ meta_name=$(basename ${meta})
+ echo "Checking meta ${meta_name} ..."
+ salt_run --out=quiet --id=${state_name} cp.get_template ${meta} ${SALT_CACHE_DIR}/${meta_name} \
+ || { log_err "Failed to render meta ${meta} using pillar ${FORMULA_NAME}.${state_name}"; exit 1; }
+ cat ${SALT_CACHE_DIR}/${meta_name}
+ done
done
}
+real_run() {
+ for pillar in ${PILLARDIR}/*.sls; do
+ state_name=$(basename ${pillar%.sls})
+ salt_run --id=${state_name} state.sls ${FORMULA_NAME} || { log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1; }
+ done
+}
+
+run_model_validate(){
+ # Run modelschema.model_validate validation.
+ # TEST iterateble, run for `each formula ROLE against each ROLE_PILLARNAME`
+ # Pillars should be named in conviend ROLE_XXX.sls or ROLE.sls
+ # Example:
+ # client.sls client_auth.sls server.sls server_auth.sls
+ if [ -d ${SCHEMARDIR} ]; then
+ # model validator require py modules
+ fetch_dependency "salt:https://github.com/salt-formulas/salt-formula-salt"
+ link_modules
+ salt_run saltutil.clear_cache; salt_run saltutil.refresh_pillar; salt_run saltutil.sync_all;
+ for role in ${SCHEMARDIR}/*.yaml; do
+ role_name=$(basename "${role%*.yaml}")
+ for pillar in $(ls pillar/${role_name}*.sls | grep -v ${IGNORE_MODELVALIDATE_MASK} ); do
+ pillar_name=$(basename "${pillar%*.sls}")
+ local _message="FORMULA:${FORMULA_NAME} ROLE:${role_name} against PILLAR:${pillar_name}"
+ log_info "model_validate ${_message}"
+ # Rendered Example:
+ # python $(which salt-call) --local -c /test1/maas/tests/build/salt --id=maas_cluster modelschema.model_validate maas cluster
+ salt_run -m ${DEPSDIR}/salt-formula-salt --id=${pillar_name} modelschema.model_validate ${FORMULA_NAME} ${role_name} || { log_err "Execution of model_validate ${_message} failed"; exit 1 ; }
+ done
+ done
+ else
+ log_info "${SCHEMARDIR} not found!";
+ fi
+}
+
+dependency_check() {
+ local DEPENDENCY_COMMANDS=$*
+
+ for DEPENDENCY_COMMAND in $DEPENDENCY_COMMANDS; do
+ which $DEPENDENCY_COMMAND > /dev/null || ( log_err "Command \"$DEPENDENCY_COMMAND\" can not be found in default path."; exit 1; )
+ done
+}
+
_atexit() {
RETVAL=$?
trap true INT TERM EXIT
@@ -143,6 +263,10 @@
}
## Main
+
+log_info "Running version: ${__ScriptVersion}"
+log_info "Command line: '${__ScriptFullName} ${__ScriptArgs}'"
+
trap _atexit INT TERM EXIT
case $1 in
@@ -152,11 +276,23 @@
prepare)
prepare
;;
+ lint)
+ lint
+ ;;
run)
run
;;
+ real-run)
+ real_run
+ ;;
+ model-validate)
+ prepare
+ run_model_validate
+ ;;
*)
prepare
+# lint
run
+ run_model_validate
;;
esac
diff --git a/tests/test-requirements.txt b/tests/test-requirements.txt
new file mode 100644
index 0000000..a0f561a
--- /dev/null
+++ b/tests/test-requirements.txt
@@ -0,0 +1,2 @@
+jsonschema
+reno