-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Tatskaari/init
Initial release
- Loading branch information
Showing
9 changed files
with
342 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: Kubernetes rules | ||
on: | ||
- push | ||
- pull_request | ||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
- name: Run tests | ||
run: ./pleasew test --log_file plz-out/log/test.log | ||
- name: Archive logs | ||
if: always() | ||
uses: actions/upload-artifact@v2 | ||
with: | ||
name: logs | ||
path: | | ||
plz-out/log | ||
release: | ||
needs: | ||
- test | ||
runs-on: ubuntu-latest | ||
if: github.ref == 'refs/heads/master' | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
- name: Release | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
uses: thought-machine/release-action@master |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
# Entries below this point are managed by Please (DO NOT EDIT) | ||
plz-out | ||
.plzconfig.local |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[please] | ||
version = >=17.0.0 | ||
|
||
[PluginDefinition] | ||
Name = k8s | ||
|
||
[Plugin "shell"] | ||
Target = //plugins:shell |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Version 0.1.0 | ||
------------- | ||
* Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
0.1.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
filegroup( | ||
name = "k8s", | ||
srcs = ["k8s.build_defs"], | ||
visibility = ["PUBLIC"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
subinclude("///shell//build_defs:shell") | ||
|
||
"""Rules for building Kubernetes objects.""" | ||
|
||
|
||
def k8s_config(name:str, srcs:list, containers:list=[], params:dict=None, visibility:list=None, | ||
labels:list=[]): | ||
"""Defines some Kubernetes config and performs templating of containers. | ||
|
||
For each k8s_config rule, one genrule per container and two genrules per src are generated: | ||
- The genrule for each container will build the container and store the full name + label | ||
to the output file. | ||
- The first genrule for each source will parse the YAML configs, and extract volume mounts | ||
that are prefixed with /etc/hault/, storing them as JSON output to be consumed by an | ||
external script. | ||
- The second genrule for each source will template the generic config and store the templated | ||
version. | ||
|
||
The final rule is simply a filegroup of the templated configs. | ||
|
||
Args: | ||
name: Name of the rule. | ||
srcs: YAML config files containing the Kubernetes config. | ||
containers: Container dependencies to template into the config file. The config | ||
contains Please build labels to refer to containers which are replaced with | ||
actual locations when the config is built. | ||
These rules will need to be docker_image rules (or something similar). | ||
params: Map defining overrides for shell-substitution variables in srcs; if set, srcs is | ||
passed through envsubst using the defined map. | ||
visibility: Visibility of the rule | ||
labels: Labels for this rule | ||
""" | ||
returned_targets = {} | ||
containers = [c for c in containers if c] | ||
|
||
# Make sure to canonicalise each container (they could be in the form of ':local_container'). | ||
containers = [canonicalise(container) for container in containers] | ||
|
||
# This will template image tags into k8s resource files that reference docker images by build target. | ||
fqns = [f'{c}_fqn' for c in containers] | ||
# Tag with appropriate labels | ||
labels += ['k8s'] + ['container:' + c for c in containers] | ||
|
||
# Template each config YAML and collect them in the filegroup. | ||
rules = [] | ||
|
||
# Now that we have a collection of files, each containing a container name + label, we can | ||
# create a multi-expression sed command to replace a build target with the actual containers. | ||
exports = [f'export {k}={v}' for k,v in params.items()] if params else [] | ||
replacement_command = 'cat' | ||
envsubst_vars = ",".join(['${%s}' % k for k in params.keys()] if params else []) | ||
check_rule = None | ||
if containers: | ||
# Pseudo build rule to check that the specified containers exist in the k8s files. | ||
# Has to be a separate rule because containers might only occur in one of the files. | ||
check_rule = build_rule( | ||
name=name, | ||
tag='check', | ||
cmd='for IMG in %s; do grep "$IMG" $SRCS || (echo "Image $IMG not in k8s files"; exit 1); done' % ' '.join(containers), | ||
srcs=srcs, | ||
) | ||
|
||
# macos sed only supports posix regex expressions so escape sequences like \b don't work | ||
boundary_expr = "\\b" if CONFIG.HOSTOS != 'darwin' else "" | ||
subcommands = ' '.join([ | ||
f'-e "s|{container}{boundary_expr}|$(cat $(location {fqn}))|g"' | ||
for container, fqn in sorted(zip(containers, fqns)) | ||
]) | ||
replacement_command = f'sed {subcommands}' | ||
|
||
for src in srcs: | ||
cleaned_src = src.replace('/', '_').replace(':', '_') | ||
src_tag = cleaned_src.replace('.', '_') | ||
src_genrule_name = f'_{name}#{src_tag}' | ||
if cleaned_src.endswith('_yaml'): | ||
cleaned_src = cleaned_src[:-5] + '.yaml' | ||
rules.append(f':{src_genrule_name}') | ||
genrule( | ||
name = src_genrule_name, | ||
srcs = [src], | ||
outs = ['templated_' + cleaned_src], | ||
cmd = exports + [f"cat $SRCS | {replacement_command} | envsubst '{envsubst_vars}' > $OUT"], | ||
deps = fqns + [check_rule if check_rule else None], | ||
) | ||
|
||
files = filegroup( | ||
name = name, | ||
srcs = rules, | ||
visibility = visibility, | ||
labels = labels, | ||
) | ||
|
||
# Generate a rule to push the configs. | ||
sh_cmd( | ||
name = name + '_push', | ||
cmd = ' && '.join([f'kubectl apply -f $(out_location {x})' for x in rules]), | ||
deps = rules, | ||
labels = ["k8s-push"], | ||
) | ||
|
||
# Generate a rule to cleanup the configs. | ||
sh_cmd( | ||
name = name + '_cleanup', | ||
cmd = ' && '.join([f'kubectl delete --ignore-not-found -f $(out_location {x})' for x in rules]), | ||
deps = rules, | ||
labels = ["k8s-cleanup"], | ||
) | ||
return files |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
#!/bin/sh | ||
|
||
set -e | ||
set -u | ||
|
||
ESC="$(printf '\033')" | ||
|
||
if [ "${NOCOLOR+x}" != 'x' ] || [ "${NO_COLOR+x}" != 'x' ]; then | ||
RED="${ESC}[31m" | ||
GREEN="${ESC}[32m" | ||
YELLOW="${ESC}[33m" | ||
RESET="${ESC}[0m" | ||
else | ||
RED='' | ||
GREEN='' | ||
YELLOW='' | ||
RESET='' | ||
fi | ||
|
||
|
||
DEFAULT_URL_BASE='https://get.please.build' | ||
|
||
OS="$(uname)" | ||
|
||
if [ "${OS}" = 'Darwin' ]; then | ||
# switch between mac amd64/arm64 | ||
ARCH="$(uname -m)" | ||
else | ||
# default to amd64 on other operating systems | ||
# because we only build intel binaries | ||
ARCH='amd64' | ||
fi | ||
|
||
case "${ARCH}" in | ||
aarch64_be|aarch64|armv8b|armv8l) ARCH='arm64' ;; | ||
x86_64) ARCH='amd64' ;; | ||
esac | ||
|
||
has_command () { | ||
command -v "${1}" > /dev/null 2>&1 | ||
} | ||
|
||
get_profile () { | ||
while [ "${#}" -gt 0 ] | ||
do | ||
case "${1}" in | ||
--profile=*) echo "${1#*=}"; return;; | ||
--profile) echo "${2}"; return;; | ||
*) shift;; | ||
esac | ||
done | ||
} | ||
|
||
# Check `PLZ_CONFIG_PROFILE` or fall back to arguments for a profile. | ||
PROFILE="${PLZ_CONFIG_PROFILE:-$(get_profile "${@}")}" | ||
|
||
# Config files on order of precedence high to low. | ||
CONFIGS="$(cat <<- EOS | ||
.plzconfig.local | ||
${PROFILE:+.plzconfig.${PROFILE}} | ||
.plzconfig_${OS}_${ARCH} | ||
.plzconfig | ||
${HOME}/.config/please/plzconfig | ||
/etc/please/plzconfig | ||
EOS | ||
)" | ||
|
||
read_config() { | ||
# Disable globbing to ensure word-splitting is safe. | ||
set -f | ||
|
||
old_ifs="${IFS}" | ||
search_term="${1}" | ||
|
||
IFS=' | ||
' | ||
|
||
# This is intended, we *do* want word-splitting here. | ||
# shellcheck disable=2086 | ||
set -- ${CONFIGS} | ||
|
||
grep -i "${search_term}" "${@}" 2> /dev/null | head -n 1 | ||
|
||
IFS="${old_ifs}" | ||
set +f | ||
} | ||
|
||
# We might already have it downloaded... | ||
LOCATION="$(read_config '^\s*location' | cut -d '=' -f 2 | tr -d ' ')" | ||
|
||
if [ "${LOCATION:+x}" != 'x' ]; then | ||
if [ "${HOME:+x}" != 'x' ]; then | ||
# shellcheck disable=2016 | ||
printf >&2 '%b$HOME not set, not sure where to look for Please.%b\n' "${RED}" "${RESET}" | ||
exit 1 | ||
fi | ||
|
||
LOCATION="${HOME}/.please" | ||
else | ||
# It can contain a literal ~, need to explicitly handle that. | ||
LOCATION="$(echo "${LOCATION}" | sed "s|~|${HOME}|")" | ||
fi | ||
|
||
# If this exists at any version, let it handle any update. | ||
TARGET="${LOCATION}/please" | ||
|
||
if [ -f "${TARGET}" ]; then | ||
# shellcheck disable=2086 | ||
exec "${TARGET}" ${PLZ_ARGS:-} "${@}" | ||
fi | ||
|
||
URL_BASE="$(read_config '^\s*downloadlocation' | cut -d '=' -f 2 | tr -d ' ')" | ||
|
||
if [ "${URL_BASE:+x}" != 'x' ]; then | ||
URL_BASE="${DEFAULT_URL_BASE}" | ||
fi | ||
|
||
URL_BASE="${URL_BASE%/}" | ||
|
||
VERSION="$(read_config '^\s*version[^a-z]')" | ||
VERSION="${VERSION#*=}" # Strip until after first = | ||
VERSION="$(echo "${VERSION}" | tr -d ' ')" # Remove all spaces | ||
VERSION="${VERSION#>=}" # Strip any initial >= | ||
|
||
if has_command curl; then | ||
TRANSFER_TOOL='curl' | ||
TRANSFER_SILENT_OPTS='-fsSL' | ||
TRANSFER_PROGRESS_OPTS='-fSL' | ||
elif has_command wget; then | ||
TRANSFER_TOOL='wget' | ||
TRANSFER_SILENT_OPTS='-qO-' | ||
TRANSFER_PROGRESS_OPTS='-O-' | ||
else | ||
printf >&2 '%bUnable to find a command for network operations%b\n' "${RED}" "${RESET}" | ||
printf >&2 'Please install either curl or wget\n' | ||
exit 1 | ||
fi | ||
|
||
if [ "${VERSION:+x}" != 'x' ]; then | ||
printf >&2 "%bCan't determine version, will use latest.%b\n" "${YELLOW}" "${RESET}" | ||
VERSION=$(${TRANSFER_TOOL} ${TRANSFER_SILENT_OPTS} "${URL_BASE}"/latest_version) | ||
fi | ||
|
||
# Find the os / arch to download. You can do this quite nicely with go env | ||
# but we use this script on machines that don't necessarily have Go itself. | ||
if [ "${OS}" = 'Linux' ]; then | ||
GOOS='linux' | ||
elif [ "${OS}" = 'Darwin' ]; then | ||
GOOS='darwin' | ||
elif [ "${OS}" = 'FreeBSD' ]; then | ||
GOOS='freebsd' | ||
else | ||
printf >&2 '%bUnknown operating system %s%b\n' "${RED}" "${OS}" "${RESET}" | ||
exit 1 | ||
fi | ||
|
||
PLEASE_URL="${URL_BASE}/${GOOS}_${ARCH}/${VERSION}/please_${VERSION}.tar.xz" | ||
DIR="${LOCATION}/${VERSION}" | ||
|
||
# Potentially we could reuse this but it's easier not to really. | ||
if [ ! -d "${DIR}" ]; then | ||
rm -Rf "${DIR}" | ||
fi | ||
|
||
printf >&2 '%bDownloading Please %s to %s...%b\n' "${GREEN}" "${VERSION}" "${DIR}" "${RESET}" | ||
mkdir -p "${DIR}" | ||
${TRANSFER_TOOL} ${TRANSFER_PROGRESS_OPTS} "${PLEASE_URL}" | tar -xJpf- --strip-components=1 -C "${DIR}" | ||
|
||
# Link it all back up a dir | ||
for x in "${DIR}"/*; do | ||
ln -sf "${x}" "${LOCATION}" | ||
done | ||
|
||
printf >&2 '%bShould be good to go now, running plz...%b\n' "${GREEN}" "${RESET}" | ||
# shellcheck disable=2086 | ||
exec "${TARGET}" ${PLZ_ARGS:-} "${@}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
plugin_repo( | ||
name = "shell", | ||
revision = "v0.2.0", | ||
plugin = "shell-rules", | ||
owner = "please-build", | ||
) |