diff --git a/check_this b/check_this index f5ee6df..899a007 100644 --- a/check_this +++ b/check_this @@ -14,3 +14,12 @@ cdebug exec --privileged -it --image nixery.dev/shell/ps/vim/tshark my-distroles https://github.com/iximiuz/cdebug +https://github.com/donaldzou/WGDashboard#-install + +https://learnk8s.io/troubleshooting-deployments + +https://artifacthub.io/ + +https://github.com/kubernetes/git-sync + +https://grpc.io/docs/languages/python/basics/ \ No newline at end of file diff --git a/git_sync/create_volume b/git_sync/create_volume new file mode 100644 index 0000000..a429621 --- /dev/null +++ b/git_sync/create_volume @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv-git + labels: + app: git +spec: + storageClassName: manual + capacity: + storage: 10Gi + accessModes: + - ReadWriteOnce + hostPath: + path: "/mnt/data" \ No newline at end of file diff --git a/git_sync/deployment b/git_sync/deployment new file mode 100644 index 0000000..bec60c3 --- /dev/null +++ b/git_sync/deployment @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app: git-sync + name: git-sync +spec: + replicas: 1 + selector: + matchLabels: + app: git-sync + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: git-sync + spec: + containers: + - image: nginx:latest + name: nginx + resources: {} + volumeMounts: + - name: workdir + mountPath: /usr/share/nginx/html + initContainers: + - image: registry.k8s.io/git-sync/git-sync:v3.6.2 + name: gitsync + args: + - --repo=nutzer26@1:/home/nutzer01/content_repo.git + - --root=/tmp/git/root + - --ssh + - --one-time + volumeMounts: + - name: git-secret + mountPath: /etc/git-secret + - name: workdir + mountPath: "/tmp/git/root" + securityContext: + runAsUser: 65533 + volumes: + - name: workdir + emptyDir: {} + - name: claim-pvc2 + secret: + secretName: git-creds + defaultMode: 0400 + securityContext: + fsGroup: 65533 +status: {} \ No newline at end of file diff --git a/git_sync/git_project/HEAD b/git_sync/git_project/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/git_sync/git_project/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/git_sync/git_project/config b/git_sync/git_project/config new file mode 100644 index 0000000..07d359d --- /dev/null +++ b/git_sync/git_project/config @@ -0,0 +1,4 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = true diff --git a/git_sync/git_project/description b/git_sync/git_project/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/git_sync/git_project/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/git_sync/git_project/hooks/applypatch-msg.sample b/git_sync/git_project/hooks/applypatch-msg.sample new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/git_sync/git_project/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/git_sync/git_project/hooks/commit-msg.sample b/git_sync/git_project/hooks/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/git_sync/git_project/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/git_sync/git_project/hooks/fsmonitor-watchman.sample b/git_sync/git_project/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..ef94fa2 --- /dev/null +++ b/git_sync/git_project/hooks/fsmonitor-watchman.sample @@ -0,0 +1,109 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 1) and a time in nanoseconds +# formatted as a string and outputs to stdout all files that have been +# modified since the given time. Paths must be relative to the root of +# the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $time) = @ARGV; + +# Check the hook interface version + +if ($version == 1) { + # convert nanoseconds to seconds + # subtract one second to make sure watchman will return all changes + $time = int ($time / 1000000000) - 1; +} else { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree; +if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $git_work_tree = Win32::GetCwd(); + $git_work_tree =~ tr/\\/\//; +} else { + require Cwd; + $git_work_tree = Cwd::cwd(); +} + +my $retry = 1; + +launch_watchman(); + +sub launch_watchman { + + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $time but were not transient (ie created after + # $time but no longer exist). + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. + + my $query = <<" END"; + ["query", "$git_work_tree", { + "since": $time, + "fields": ["name"] + }] + END + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + my $json_pkg; + eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; + } or do { + require JSON::PP; + $json_pkg = "JSON::PP"; + }; + + my $o = $json_pkg->new->utf8->decode($response); + + if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) { + print STDERR "Adding '$git_work_tree' to watchman's watch list.\n"; + $retry--; + qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + print "/\0"; + eval { launch_watchman() }; + exit 0; + } + + die "Watchman: $o->{error}.\n" . + "Falling back to scanning...\n" if $o->{error}; + + binmode STDOUT, ":utf8"; + local $, = "\0"; + print @{$o->{files}}; +} diff --git a/git_sync/git_project/hooks/post-update.sample b/git_sync/git_project/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/git_sync/git_project/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/git_sync/git_project/hooks/pre-applypatch.sample b/git_sync/git_project/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/git_sync/git_project/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/git_sync/git_project/hooks/pre-commit.sample b/git_sync/git_project/hooks/pre-commit.sample new file mode 100755 index 0000000..6a75641 --- /dev/null +++ b/git_sync/git_project/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/git_sync/git_project/hooks/pre-merge-commit.sample b/git_sync/git_project/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/git_sync/git_project/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/git_sync/git_project/hooks/pre-push.sample b/git_sync/git_project/hooks/pre-push.sample new file mode 100755 index 0000000..6187dbf --- /dev/null +++ b/git_sync/git_project/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +z40=0000000000000000000000000000000000000000 + +while read local_ref local_sha remote_ref remote_sha +do + if [ "$local_sha" = $z40 ] + then + # Handle delete + : + else + if [ "$remote_sha" = $z40 ] + then + # New branch, examine all commits + range="$local_sha" + else + # Update to existing branch, examine new commits + range="$remote_sha..$local_sha" + fi + + # Check for WIP commit + commit=`git rev-list -n 1 --grep '^WIP' "$range"` + if [ -n "$commit" ] + then + echo >&2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/git_sync/git_project/hooks/pre-rebase.sample b/git_sync/git_project/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/git_sync/git_project/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/git_sync/git_project/hooks/pre-receive.sample b/git_sync/git_project/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/git_sync/git_project/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/git_sync/git_project/hooks/prepare-commit-msg.sample b/git_sync/git_project/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/git_sync/git_project/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/git_sync/git_project/hooks/update.sample b/git_sync/git_project/hooks/update.sample new file mode 100755 index 0000000..80ba941 --- /dev/null +++ b/git_sync/git_project/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --bool hooks.allowunannotated) +allowdeletebranch=$(git config --bool hooks.allowdeletebranch) +denycreatebranch=$(git config --bool hooks.denycreatebranch) +allowdeletetag=$(git config --bool hooks.allowdeletetag) +allowmodifytag=$(git config --bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero="0000000000000000000000000000000000000000" +if [ "$newrev" = "$zero" ]; then + newrev_type=delete +else + newrev_type=$(git cat-file -t $newrev) +fi + +case "$refname","$newrev_type" in + refs/tags/*,commit) + # un-annotated tag + short_refname=${refname##refs/tags/} + if [ "$allowunannotated" != "true" ]; then + echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/git_sync/git_project/info/exclude b/git_sync/git_project/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/git_sync/git_project/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/git_sync/pvc b/git_sync/pvc new file mode 100644 index 0000000..30e17b1 --- /dev/null +++ b/git_sync/pvc @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pvc-claim-2 + labels: + app: git +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi \ No newline at end of file diff --git a/k3d/blue-green/doku b/k3d/blue-green/doku new file mode 100644 index 0000000..f20fc15 --- /dev/null +++ b/k3d/blue-green/doku @@ -0,0 +1,128 @@ +Blue Green Deployment + +create version 1 and 2 and services + +# prepare namespace + + +mkdir ~/blue-green && cd ~/blue-green +kubectl create namespace blue-green +kubectl config set-context --current --namespace blue-green + +# create manifests + +cat >nginx-v1.yaml <nginx-v2.yaml <nginx-svc.yaml <myapp-pod.yaml <myapp-pod-exists.yaml <deployment2.yaml <Dockerfile <pod.yaml <', methods=['GET']) + def get_pool_car(car_id): + pool_car = Pool_Car.query.get(car_id) + return pool_car_schema.jsonify(pool_car) +   + # Delete Product + @app.route('/car/', methods=['DELETE']) + def delete_pool_car(car_id): + pool_car = Pool_Car.query.get(car_id) + db.session.delete(pool_car) + db.session.commit() +   + return pool_car_schema.jsonify(pool_car) +   +   + if __name__ == '__main__': + app.run(debug=True) #port='5002' + +requirements.txt + +requirements.txt + + Flask==1.1.1 + Flask-Cors==3.0.8 + flask-marshmallow==0.10.1 + Flask-SQLAlchemy==2.4.1 + werkzeug==2.0.2 + marshmallow==3.2.2 + SQLAlchemy==1.3.11 + marshmallow-sqlalchemy==0.19.0 + psycopg2-binary==2.8.4 + itsdangerous==2.0.1 + Jinja2==3.0.3 + +Dockerfile + +Dockerfile + + # syntax=docker/dockerfile:1 + FROM python:3.8-slim-buster + WORKDIR /app + COPY requirements.txt requirements.txt + RUN pip3 install --disable-pip-version-check -r requirements.txt + COPY . . + ENV FLASK_APP=python_rest + EXPOSE 5000 + STOPSIGNAL SIGINT + CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"] + +Build app + +docker build -t bee42/carpool:0.1.0 . +curl http://127.0.0.1:5000/v2/_catalog +{"repositories":[]} +docker tag bee42/carpool:0.1.0 127.0.0.1:5000/bee42/carpool:0.1.0 +docker push 127.0.0.1:5000/bee42/carpool:0.1.0 +curl http://127.0.0.1:5000/v2/_catalog +{"repositories":["bee42/carpool"]} +curl http://127.0.0.1:5000/v2/bee42/carpool/tags/list +{"name":"bee42/carpool","tags":["0.1.0"]} + + + +CarPool Deploy Postgres + +New Kubernetes Manifests: + + Persistence Volume + Config Map + +mkdir ~/carpool/postgres && cd ~/carpool/postgres + +# define kubernetes manifests + +postgres-deploy.yaml + +postgres-deploy.yaml + + apiVersion: apps/v1 + kind: Deployment + metadata: + name: postgres + spec: + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: postgres:10.4 + imagePullPolicy: "IfNotPresent" + ports: + - containerPort: 5432 + envFrom: + - configMapRef: + name: postgres-config + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: postgredb + - name: config + mountPath: "/docker-entrypoint-initdb.d" + readOnly: true + volumes: + - name: config + configMap: + name: carpool + items: + - key: "esentricar.sql" + path: "esentricar.sql" + - name: postgredb + persistentVolumeClaim: + claimName: postgres-pv-claim + +postgres-schema-cm.yaml + +postgres-schema-cm.yaml + + apiVersion: v1 + kind: ConfigMap + metadata: + name: carpool + data: + esentricar.sql: | + CREATE DATABASE esentricar; + \c esentricar; + CREATE TABLE cars ( + car_id SERIAL PRIMARY KEY, + license_plate varchar(30) NOT NULL, + car_type varchar(30) NOT NULL, + fuel varchar(30) NOT NULL, + number_of_seats integer NOT NULL + ); + CREATE UNIQUE INDEX cars_license_plate + ON cars (license_plate); + +postgres-config.yaml + +postgres-config.yaml + + apiVersion: v1 + kind: ConfigMap + metadata: + name: postgres-config + labels: + app: postgres + data: + POSTGRES_DB: postgresdb + POSTGRES_USER: postgres + POSTGRES_PASSWORD: cnbc + +postgres-service.yaml + +postgres-service.yaml + + apiVersion: v1 + kind: Service + metadata: + labels: + app: postgres + name: postgres + spec: + ports: + - name: postgres + port: 5432 + protocol: TCP + targetPort: 5432 + selector: + app: postgres + type: ClusterIP + +postgres-pv-claim.yaml + +postgres-pv-claim.yaml + + kind: PersistentVolumeClaim + apiVersion: v1 + metadata: + name: postgres-pv-claim + labels: + app: postgres + spec: + storageClassName: local-path + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + +Create database + +kubectl create namespace carpool +kubectl config set-context --current --namespace=carpool +# apply all manifests +kubectl apply -f . +kubectl get all +kubectl get configmaps +NAME DATA AGE +kube-root-ca.crt 1 21m +postgres-config 3 42s +carpool 1 42s +kubectl get pvc,pv +NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE +persistentvolumeclaim/postgres-pv-claim Bound pvc-e6e7ba0f-ff3e-4bfa-be1b-4db6629d027e 1Gi RWO local-path 84s + +NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE +persistentvolume/pvc-e6e7ba0f-ff3e-4bfa-be1b-4db6629d027e 1Gi RWO Delete Bound carpool/postgres-pv-claim local-path 79s +kubectl describe pv +Name: pvc-e6e7ba0f-ff3e-4bfa-be1b-4db6629d027e +Labels: +Annotations: pv.kubernetes.io/provisioned-by: rancher.io/local-path +Finalizers: [kubernetes.io/pv-protection] +StorageClass: local-path +Status: Bound +Claim: carpool/postgres-pv-claim +Reclaim Policy: Delete +Access Modes: RWO +VolumeMode: Filesystem +Capacity: 1Gi +Node Affinity: + Required Terms: + Term 0: kubernetes.io/hostname in [k3d-cnbc-agent-1] +Message: +Source: + Type: HostPath (bare host directory volume) + Path: /var/lib/rancher/k3s/storage/pvc-e6e7ba0f-ff3e-4bfa-be1b-4db6629d027e_carpool_postgres-pv-claim + HostPathType: DirectoryOrCreate +Events: + +kubectl logs postgres-65974d6d58-72vk5 +The files belonging to this database system will be owned by user "postgres". +This user must also own the server process. + +The database cluster will be initialized with locale "en_US.utf8". +The default database encoding has accordingly been set to "UTF8". +The default text search configuration will be set to "english". + +Data page checksums are disabled. + +fixing permissions on existing directory /var/lib/postgresql/data ... ok +creating subdirectories ... ok +selecting default max_connections ... 100 +selecting default shared_buffers ... 128MB +selecting dynamic shared memory implementation ... posix +creating configuration files ... ok +running bootstrap script ... ok +performing post-bootstrap initialization ... ok +syncing data to disk ... ok + +Success. You can now start the database server using: + + pg_ctl -D /var/lib/postgresql/data -l logfile start + + +WARNING: enabling "trust" authentication for local connections +You can change this by editing pg_hba.conf or using the option -A, or +--auth-local and --auth-host, the next time you run initdb. +waiting for server to start....2022-03-08 12:30:20.872 UTC [42] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" +2022-03-08 12:30:20.901 UTC [43] LOG: database system was shut down at 2022-03-08 12:30:20 UTC +2022-03-08 12:30:20.911 UTC [42] LOG: database system is ready to accept connections + done +server started +CREATE DATABASE + +ALTER ROLE + + +/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/esentricar.sql +CREATE DATABASE +You are now connected to database "esentricar" as user "postgres". +CREATE TABLE +CREATE INDEX + + +2022-03-08 12:30:21.781 UTC [42] LOG: received fast shutdown request +waiting for server to shut down....2022-03-08 12:30:21.783 UTC [42] LOG: aborting any active transactions +2022-03-08 12:30:21.787 UTC [42] LOG: worker process: logical replication launcher (PID 49) exited with exit code 1 +2022-03-08 12:30:21.790 UTC [44] LOG: shutting down +2022-03-08 12:30:21.820 UTC [42] LOG: database system is shut down + done +server stopped + +PostgreSQL init process complete; ready for start up. + +2022-03-08 12:30:21.904 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 +2022-03-08 12:30:21.904 UTC [1] LOG: listening on IPv6 address "::", port 5432 +2022-03-08 12:30:21.909 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" +2022-03-08 12:30:21.929 UTC [79] LOG: database system was shut down at 2022-03-08 12:30:21 UTC +2022-03-08 12:30:21.938 UTC [1] LOG: database system is ready to accept connections + + + + + + + +Carpool Deploy App + + deploy service + create first car + +mkdir ~/carpool/app && cd ~/carpool/app +vi deployment.yaml +vi service.yaml + +Find name of your local registry cnbc-registry + +docker container ls +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +6f83432dbef0 rancher/k3d-proxy:5.3.0 "/bin/sh -c nginx-pr…" 29 hours ago Up 29 hours 0.0.0.0:8580->80/tcp, :::8580->80/tcp, 0.0.0.0:8543->443/tcp, :::8543->443/tcp, 0.0.0.0:8545->6443/tcp k3d-cnbc-serverlb +5f26dbd03241 rancher/k3s:v1.22.6-k3s1 "/bin/k3s agent" 29 hours ago Up 29 hours k3d-cnbc-agent-1 +24d5876390bd rancher/k3s:v1.22.6-k3s1 "/bin/k3s agent" 29 hours ago Up 29 hours k3d-cnbc-agent-0 +b5a50e960917 rancher/k3s:v1.22.6-k3s1 "/bin/k3s server --t…" 29 hours ago Up 29 hours k3d-cnbc-server-0 +8f73928c8294 registry:2 "/entrypoint.sh /etc…" 29 hours ago Up 29 hours 0.0.0.0:5000->5000/tcp cnbc-registry + +deployment.yaml + +deployment.yaml + + apiVersion: apps/v1 + kind: Deployment + metadata: + name: carpool + labels: + app: carpool + spec: + replicas: 1 + selector: + matchLabels: + app: carpool + template: + metadata: + labels: + app: carpool + spec: + containers: + - name: carpool + image: cnbc-registry:5000/bee42/carpool:0.1.0 + imagePullPolicy: Always + env: + - name: FLASK_APP + value: python_rest + +service.yaml + +service.yaml + + apiVersion: v1 + kind: Service + metadata: + labels: + app: carpool + name: carpool + spec: + ports: + - name: http + port: 5000 + protocol: TCP + targetPort: 5000 + selector: + app: carpool + type: ClusterIP + +cd .. +sudo apt install -y tree +tree . +. +├── app +│ ├── deployment.yaml +│ └── service.yaml +├── Dockerfile +├── postgres +│ ├── postgres-config.yaml +│ ├── postgres-deploy.yaml +│ ├── postgres-pv-claim.yaml +│ ├── postgres-schema-cm.yaml +│ └── postgres-service.yaml +├── python_rest.py +└── requirements.txt + +Deploy App carpool + +# create deployment and service manifests +kubectl apply -f app +kubectl get all +NAME READY STATUS RESTARTS AGE +pod/postgres-65974d6d58-72vk5 1/1 Running 0 26m +pod/carpool-67d9fcf5f4-8cwdg 1/1 Running 0 11s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/postgres ClusterIP 10.43.178.140 5432/TCP 26m +service/carpool ClusterIP 10.43.223.216 5000/TCP 11s + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/postgres 1/1 1 1 26m +deployment.apps/carpool 1/1 1 1 11s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/postgres-65974d6d58 1 1 1 26m +replicaset.apps/carpool-67d9fcf5f4 1 1 1 11s + +Access app + +kubectl run curl --tty -i --image curlimages/curl -- /bin/sh +# check registry access +curl cnbc-registry:5000/v2/ +curl cnbc-registry:5000/v2/_catalog +curl http://cnbc-registry:5000/v2/bee42/carpool/tags/list +{"repositories":["bee42/carpool"]} +# create data +cd /tmp +cat >car_1.json <python_rest.py.patch < import os +> +8a11,14 +> user = os.environ.get('POSTGRES_USER', 'postgres') +> db = os.environ.get('POSTGRES_DB', 'esentricar' ) +> passwd = os.environ.get('POSTGRES_PASSWORD', 'cnbc') +> host = os.environ.get('POSTGRES_HOST', 'postgres') +12c18 +< app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:cnbc@postgres:5432/esentricar' +--- +> app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://' + user + ':' + passwd + '@' + host + ':5432/' + db +EOF + +patch -p0 < python_rest.py.patch python_rest.py + +docker build -t bee42/carpool:0.2.0 . +curl http://127.0.0.1:5000/v2/ +docker tag bee42/carpool:0.2.0 127.0.0.1:5000/bee42/carpool:0.2.0 +docker push 127.0.0.1:5000/bee42/carpool:0.2.0 +curl http://127.0.0.1:5000/v2/bee42/carpool/tags/list +{"name":"bee42/carpool","tags":["0.1.0","0.2.0"]} + +app/app-config.yaml + +app-config.yaml + + apiVersion: v1 + kind: ConfigMap + metadata: + name: app-config + labels: + app: carpool + data: + POSTGRES_DB: esentricar + POSTGRES_PASSWORD: cnbc + POSTGRES_USER: postgres + POSTGRES_HOST: postgres + +app/deployment.yaml + +deployment.yaml + + apiVersion: apps/v1 + kind: Deployment + metadata: + name: carpool + labels: + app: carpool + spec: + replicas: 1 + selector: + matchLabels: + app: carpool + template: + metadata: + labels: + app: carpool + spec: + containers: + - name: carpool + image: cnbc-registry:5000/bee42/carpool:0.2.0 + imagePullPolicy: Always + env: + - name: FLASK_APP + value: python_rest + envFrom: + - configMapRef: + name: app-config + +kubectl apply -f app + +# later curl exec +kubectl attach -ti curl +curl http://carpool:5000/car +[{"car_id":1,"car_type":"mini clubman SD","license_plate":"BO-PR-72"}] +# remove all +kubectl get pv +# patch pv if you need the data after redeploy :) + +PV=$(kubectl get pvc -o json -lapp=postgres | jq -r .items[].spec.volumeName) + +kubectl patch pv $PV -p "{\"spec\":{\"persistentVolumeReclaimPolicy\":\"Retain\"}}" + +kubectl delete namespace carpool +kubectl create namespace carpool +kubectl apply -f postgres +kubectl apply -f app + +# Problem: Auto reassociation of pv does't work +kubectl get pv +NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE +pvc-ab3ea061-9180-4e34-95d5-0100a149747d 1Gi RWO Retain Released carpool/postgres-pv-claim local-path 24m +pvc-57cae9ed-3ebe-4181-819a-7a9cfd745606 1Gi RWO Delete Bound carpool/postgres-pv-claim local-path 28s + +kubectl delete namespace carpool +kubectl patch pv $PV --type json -p '[{"op": "remove", "path": "/spec/claimRef/uid"}]' +kubectl create namespace carpool +kubectl apply -f postgres +kubectl apply -f app + +Options define a node port services + +cat ~/carpool/app/node-service.yaml < K3s dev 5.4.0-109-generic containerd://1.5.9-k3s1 +k3d-cnbc-agent-1 Ready worker 30h v1.22.7+k3s1 172.18.0.3 K3s dev 5.4.0-109-generic containerd://1.5.9-k3s1 +k3d-cnbc-server-0 Ready control-plane,master 30h v1.22.7+k3s1 172.18.0.2 K3s dev 5.4.0-109-generic containerd://1.5.9-k3s1 +kubectl apply -f ~/carpool/app/node-service.yaml + +kubectl get service +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +postgres ClusterIP 10.43.173.36 5432/TCP 5m37s +carpool ClusterIP 10.43.41.38 5000/TCP 5m11s +carpool-node NodePort 10.43.44.24 5000:31231/TCP 7s + +curl 172.18.0.3:31231/car +[{"car_id":1,"car_type":"mini clubman SD","license_plate":"BO-PR-72"}] + diff --git a/k8s/carpool/esentricar.sql b/k8s/carpool/esentricar.sql new file mode 100644 index 0000000..99fd2ae --- /dev/null +++ b/k8s/carpool/esentricar.sql @@ -0,0 +1,11 @@ +CREATE DATABASE esentricar; +\c esentricar; +CREATE TABLE cars ( + car_id SERIAL PRIMARY KEY, + license_plate varchar(30) NOT NULL, + car_type varchar(30) NOT NULL, + fuel varchar(30) NOT NULL, + number_of_seats integer NOT NULL +); +CREATE UNIQUE INDEX cars_license_plate +ON cars (license_plate); \ No newline at end of file diff --git a/k8s/carpool/index.env b/k8s/carpool/index.env new file mode 100644 index 0000000..3009d08 --- /dev/null +++ b/k8s/carpool/index.env @@ -0,0 +1 @@ +POSTGRES_PASSWORD=postgres \ No newline at end of file diff --git a/k8s/carpool/postgres-config.yaml b/k8s/carpool/postgres-config.yaml new file mode 100644 index 0000000..b67ed01 --- /dev/null +++ b/k8s/carpool/postgres-config.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-config + labels: + app: postgres +data: + POSTGRES_DB: postgresdb + POSTGRES_USER: postgres + POSTGRES_PASSWORD: cnbc \ No newline at end of file diff --git a/k8s/carpool/postgres-deploy.yaml b/k8s/carpool/postgres-deploy.yaml new file mode 100644 index 0000000..5b40acb --- /dev/null +++ b/k8s/carpool/postgres-deploy.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres +spec: + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + containers: + - name: postgres + image: postgres:10.4 + imagePullPolicy: "IfNotPresent" + ports: + - containerPort: 5432 + envFrom: + - configMapRef: + name: postgres-config + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: postgredb + - name: config + mountPath: "/docker-entrypoint-initdb.d" + readOnly: true + volumes: + - name: config + configMap: + name: carpool + items: + - key: "esentricar.sql" + path: "esentricar.sql" + - name: postgredb + persistentVolumeClaim: + claimName: postgres-pv-claim \ No newline at end of file diff --git a/k8s/carpool/postgres-pv-claim.yaml b/k8s/carpool/postgres-pv-claim.yaml new file mode 100644 index 0000000..4096230 --- /dev/null +++ b/k8s/carpool/postgres-pv-claim.yaml @@ -0,0 +1,13 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: postgres-pv-claim + labels: + app: postgres +spec: + storageClassName: local-path + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi \ No newline at end of file diff --git a/k8s/carpool/postgres-schema-cm.yaml b/k8s/carpool/postgres-schema-cm.yaml new file mode 100644 index 0000000..445d8ed --- /dev/null +++ b/k8s/carpool/postgres-schema-cm.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: carpool +data: + esentricar.sql: | + CREATE DATABASE esentricar; + \c esentricar; + CREATE TABLE cars ( + car_id SERIAL PRIMARY KEY, + license_plate varchar(30) NOT NULL, + car_type varchar(30) NOT NULL, + fuel varchar(30) NOT NULL, + number_of_seats integer NOT NULL + ); + CREATE UNIQUE INDEX cars_license_plate + ON cars (license_plate); \ No newline at end of file diff --git a/k8s/carpool/postgres-service.yaml b/k8s/carpool/postgres-service.yaml new file mode 100644 index 0000000..ae37901 --- /dev/null +++ b/k8s/carpool/postgres-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: postgres + name: postgres +spec: + ports: + - name: postgres + port: 5432 + protocol: TCP + targetPort: 5432 + selector: + app: postgres + type: ClusterIP \ No newline at end of file diff --git a/k8s/carpool/python_rest.py b/k8s/carpool/python_rest.py new file mode 100644 index 0000000..2aab586 --- /dev/null +++ b/k8s/carpool/python_rest.py @@ -0,0 +1,98 @@ +from flask import Flask, request, jsonify +from flask_sqlalchemy import SQLAlchemy +from flask_marshmallow import Marshmallow, fields +from flask_cors import CORS + +# Init app +app = Flask(__name__) + +#enable CORS +CORS(app) +# connect to already existing and running Database +app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:cnbc@postgres:5432/esentricar' + +# not important but otherwise we get a warning every time +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False + +#Init db +db = SQLAlchemy(app) +#Init ma +ma = Marshmallow(app) + +# Pool Car Class/Model +class Pool_Car(db.Model): + + #define table, in our case already existing + __tablename__ = 'cars' + car_id = db.Column(db.Integer, primary_key=True) + license_plate = db.Column(db.String(30), unique=True) + car_type = db.Column(db.String(20)) + fuel = db.Column(db.String(20)) + number_of_seats =db.Column(db.Integer) + + + # set class attributes + def __init__(self, license_plate, car_type, fuel, number_of_seats): + self.license_plate = license_plate + self.car_type = car_type + self.fuel = fuel + self.number_of_seats = number_of_seats + +class Pool_CarSchema(ma.Schema): + class Meta: + fields = ('car_id','license_plate','car_type','fuel','number_of_seats') + +# Init schema +pool_car_schema = Pool_CarSchema() +pool_cars_schema = Pool_CarSchema(many=True) + + +# Create a Pool_Car +@app.route('/car', methods=['POST']) +def add_pool_car(): + # Get request data as json + car_entity = request.get_json() + license_plate= car_entity.get('license_plate') + car_type = car_entity.get('car_type') + fuel = car_entity.get('fuel') + number_of_seats = car_entity.get('number_of_seats') + + new_pool_car = Pool_Car(license_plate, car_type, fuel, number_of_seats) + + db.session.add(new_pool_car) + db.session.commit() + + return pool_car_schema.jsonify(new_pool_car) + +# Get car_id,license_plate,car_type of all products of the table +@app.route('/car', methods=['GET']) +def get_pool_cars(): + all_pool_cars = Pool_Car.query.all() + result = pool_cars_schema.dump(all_pool_cars) + car_list= [] + for item in result: + car_details = { "car_id":None, "license_plate":None, "car_type":None} + car_details['car_id'] = item['car_id'] + car_details['license_plate'] = item['license_plate'] + car_details['car_type'] = item['car_type'] + car_list.append(car_details) + return jsonify(car_list) + +# Get Single Products +@app.route('/car/', methods=['GET']) +def get_pool_car(car_id): + pool_car = Pool_Car.query.get(car_id) + return pool_car_schema.jsonify(pool_car) + +# Delete Product +@app.route('/car/', methods=['DELETE']) +def delete_pool_car(car_id): + pool_car = Pool_Car.query.get(car_id) + db.session.delete(pool_car) + db.session.commit() + + return pool_car_schema.jsonify(pool_car) + + +if __name__ == '__main__': + app.run(debug=True) #port='5002' \ No newline at end of file diff --git a/k8s/carpool/requirements.txt b/k8s/carpool/requirements.txt new file mode 100644 index 0000000..a273034 --- /dev/null +++ b/k8s/carpool/requirements.txt @@ -0,0 +1,11 @@ +Flask==1.1.1 +Flask-Cors==3.0.8 +flask-marshmallow==0.10.1 +Flask-SQLAlchemy==2.4.1 +werkzeug==2.0.2 +marshmallow==3.2.2 +SQLAlchemy==1.3.11 +marshmallow-sqlalchemy==0.19.0 +psycopg2-binary==2.8.4 +itsdangerous==2.0.1 +Jinja2==3.0.3 \ No newline at end of file diff --git a/k8s/carpool/service.yaml b/k8s/carpool/service.yaml new file mode 100644 index 0000000..2ea5dd5 --- /dev/null +++ b/k8s/carpool/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: carpool + name: carpool +spec: + ports: + - name: http + port: 5000 + protocol: TCP + targetPort: 5000 + selector: + app: carpool + type: ClusterIP \ No newline at end of file diff --git a/k8s/config_map b/k8s/config_map new file mode 100644 index 0000000..b347cef --- /dev/null +++ b/k8s/config_map @@ -0,0 +1,82 @@ +kubectl create deploy nginx --image nginx --dry-run=client -o yaml >nginx-deploy.yaml +vi nginx-deploy.yaml +# add volume mounts and volumes from configMap + +# create config Map +echo Linuxhotel >index.html + +kubectl create configmap htdocs --from-file index.html=index.html --dry-run=client -o yaml >htdocs-cm.yaml + +kubectl -n nginx apply -f htdocs-cm.yaml +kubectl -n nginx apply -f nginx-deploy.yaml + +kubectl -n nginx exec -ti nginx-6fc76484c-q8tmd -- /bin/sh +# more /usr/share/nginx/html/index.html + +kubectl edit -n nginx cm htdocs +# change content +apiVersion: v1 +data: + index.html: | + Linuxhotel Cloud Native Base Camp +kind: ConfigMap +metadata: + name: htdocs + +# See it change at running pods! + +kubectl -n nginx exec -ti nginx-6fc76484c-q8tmd -- /bin/sh +# more /usr/share/nginx/html/index.html +Linuxhotel Cloud Native Base Camp + + + + +htdocs-cm.yaml + + apiVersion: v1 + data: + index.html: | + Linuxhotel + kind: ConfigMap + metadata: + creationTimestamp: null + name: htdocs + + + + +nginx-deploy.yaml + + apiVersion: apps/v1 + kind: Deployment + metadata: + creationTimestamp: null + labels: + app: nginx + name: nginx + spec: + replicas: 1 + selector: + matchLabels: + app: nginx + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: nginx + spec: + containers: + - image: nginx + name: nginx + resources: {} + volumeMounts: + - name: htdocs + mountPath: /usr/share/nginx/html + volumes: + - name: htdocs + configMap: + name: htdocs + status: {} + diff --git a/k8s/pods b/k8s/pods index 5f79f4b..7a26af8 100644 --- a/k8s/pods +++ b/k8s/pods @@ -67,4 +67,8 @@ kubectl get rs -o json |jq -r .items[].metadata.annotations.\"deployment.kuberne kubectl get pods kubectl get pod -o yaml | sed 's/\(image: nginx\):.*$/\1:1.19.3/' | kubectl replace -f - -#kubectl get pod web-548df7676c-v48kv -o yaml | sed 's/\(image: nginx\):.*$/\1:1.19.4/' | kubectl replace -f - web-548df7676c-rzp7v \ No newline at end of file +#kubectl get pod web-548df7676c-v48kv -o yaml | sed 's/\(image: nginx\):.*$/\1:1.19.4/' | kubectl replace -f - web-548df7676c-rzp7v + +curl -i -X POST http://carpool:5000/car \ + -H "Content-Type: application/json" \ + --data-binary "@car_2.json" \ No newline at end of file diff --git a/k8s/pvc b/k8s/pvc new file mode 100644 index 0000000..1ad39a1 --- /dev/null +++ b/k8s/pvc @@ -0,0 +1,93 @@ +Retain static PersistentVolumeClaim + +Change Claim to static hostPath volume + +cat >~/carpool/postgres/postgres-pv-claim.yaml <~/carpool/postgres/postgres-pv.yaml < + +kubectl create namespace carpool +kubectl apply -f postgres +kubectl apply -f app +kubectl run curl -ti --image=curlimages/curl -- /bin/sh +cd /tmp +cat >car_1.json < +# remove claim-ref uid and resource version +kubectl create ns carpool +kubectl apply -f postgres +kubectl apply -f app +kubectl run curl -ti --image=curlimages/curl -- /bin/sh +curl http://carpool:5000/car +# data exists +exit + diff --git a/nginx/docker-compose.yml b/nginx/docker-compose.yml index c026817..f95ba32 100644 --- a/nginx/docker-compose.yml +++ b/nginx/docker-compose.yml @@ -9,7 +9,6 @@ services: - /var/cache/nginx - /run read_only: true -  networks: default: driver: bridge diff --git a/traefik/doku b/traefik/doku new file mode 100644 index 0000000..c4a243d --- /dev/null +++ b/traefik/doku @@ -0,0 +1,152 @@ +mkdir ~/traefik && cd ~/traefik +helm repo add traefik https://helm.traefik.io/traefik +helm repo update +helm pull traefik/traefik --untar +cd traefik +tree . + +. +├── Changelog.md +├── Chart.yaml +├── crds +│ ├── ingressroutetcp.yaml +│ ├── ingressrouteudp.yaml +│ ├── ingressroute.yaml +│ ├── middlewarestcp.yaml +│ ├── middlewares.yaml +│ ├── serverstransports.yaml +│ ├── tlsoptions.yaml +│ ├── tlsstores.yaml +│ └── traefikservices.yaml +├── Guidelines.md +├── LICENSE +├── README.md +├── templates +│ ├── daemonset.yaml +│ ├── dashboard-hook-ingressroute.yaml +│ ├── deployment.yaml +│ ├── extra-objects.yaml +│ ├── gatewayclass.yaml +│ ├── gateway.yaml +│ ├── _helpers.tpl +│ ├── hpa.yaml +│ ├── ingressclass.yaml +│ ├── poddisruptionbudget.yaml +│ ├── _podtemplate.tpl +│ ├── pvc.yaml +│ ├── rbac +│ │ ├── clusterrolebinding.yaml +│ │ ├── clusterrole.yaml +│ │ ├── podsecuritypolicy.yaml +│ │ ├── rolebinding.yaml +│ │ ├── role.yaml +│ │ └── serviceaccount.yaml +│ ├── _service.tpl +│ ├── service.yaml +│ ├── tlsoption.yaml +│ └── tlsstore.yaml +└── values.yaml + +3 directories, 37 files + +# install +kubectl create ns traefik-v2 +helm install --namespace=traefik-v2 \ + traefik traefik/traefik +kubectl -n traefik-v2 get all + +cd ../web/ + +cat >ingress-values.yaml <~/carpool/app/ingress.yaml < /dev/null && echo true || echo false)" +HAS_WGET="$(type "wget" &> /dev/null && echo true || echo false)" +HAS_OPENSSL="$(type "openssl" &> /dev/null && echo true || echo false)" +HAS_GPG="$(type "gpg" &> /dev/null && echo true || echo false)" +HAS_GIT="$(type "git" &> /dev/null && echo true || echo false)" + +# initArch discovers the architecture for this system. +initArch() { + ARCH=$(uname -m) + case $ARCH in + armv5*) ARCH="armv5";; + armv6*) ARCH="armv6";; + armv7*) ARCH="arm";; + aarch64) ARCH="arm64";; + x86) ARCH="386";; + x86_64) ARCH="amd64";; + i686) ARCH="386";; + i386) ARCH="386";; + esac +} + +# initOS discovers the operating system for this system. +initOS() { + OS=$(echo `uname`|tr '[:upper:]' '[:lower:]') + + case "$OS" in + # Minimalist GNU for Windows + mingw*|cygwin*) OS='windows';; + esac +} + +# runs the given command as root (detects if we are root already) +runAsRoot() { + if [ $EUID -ne 0 -a "$USE_SUDO" = "true" ]; then + sudo "${@}" + else + "${@}" + fi +} + +# verifySupported checks that the os/arch combination is supported for +# binary builds, as well whether or not necessary tools are present. +verifySupported() { + local supported="darwin-amd64\ndarwin-arm64\nlinux-386\nlinux-amd64\nlinux-arm\nlinux-arm64\nlinux-ppc64le\nlinux-s390x\nwindows-amd64" + if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then + echo "No prebuilt binary for ${OS}-${ARCH}." + echo "To build from source, go to https://github.com/helm/helm" + exit 1 + fi + + if [ "${HAS_CURL}" != "true" ] && [ "${HAS_WGET}" != "true" ]; then + echo "Either curl or wget is required" + exit 1 + fi + + if [ "${VERIFY_CHECKSUM}" == "true" ] && [ "${HAS_OPENSSL}" != "true" ]; then + echo "In order to verify checksum, openssl must first be installed." + echo "Please install openssl or set VERIFY_CHECKSUM=false in your environment." + exit 1 + fi + + if [ "${VERIFY_SIGNATURES}" == "true" ]; then + if [ "${HAS_GPG}" != "true" ]; then + echo "In order to verify signatures, gpg must first be installed." + echo "Please install gpg or set VERIFY_SIGNATURES=false in your environment." + exit 1 + fi + if [ "${OS}" != "linux" ]; then + echo "Signature verification is currently only supported on Linux." + echo "Please set VERIFY_SIGNATURES=false or verify the signatures manually." + exit 1 + fi + fi + + if [ "${HAS_GIT}" != "true" ]; then + echo "[WARNING] Could not find git. It is required for plugin installation." + fi +} + +# checkDesiredVersion checks if the desired version is available. +checkDesiredVersion() { + if [ "x$DESIRED_VERSION" == "x" ]; then + # Get tag from release URL + local latest_release_url="https://github.com/helm/helm/releases" + if [ "${HAS_CURL}" == "true" ]; then + TAG=$(curl -Ls $latest_release_url | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | sed -E 's/.*\/helm\/helm\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1) + elif [ "${HAS_WGET}" == "true" ]; then + TAG=$(wget $latest_release_url -O - 2>&1 | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | sed -E 's/.*\/helm\/helm\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1) + fi + else + TAG=$DESIRED_VERSION + fi +} + +# checkHelmInstalledVersion checks which version of helm is installed and +# if it needs to be changed. +checkHelmInstalledVersion() { + if [[ -f "${HELM_INSTALL_DIR}/${BINARY_NAME}" ]]; then + local version=$("${HELM_INSTALL_DIR}/${BINARY_NAME}" version --template="{{ .Version }}") + if [[ "$version" == "$TAG" ]]; then + echo "Helm ${version} is already ${DESIRED_VERSION:-latest}" + return 0 + else + echo "Helm ${TAG} is available. Changing from version ${version}." + return 1 + fi + else + return 1 + fi +} + +# downloadFile downloads the latest binary package and also the checksum +# for that binary. +downloadFile() { + HELM_DIST="helm-$TAG-$OS-$ARCH.tar.gz" + DOWNLOAD_URL="https://get.helm.sh/$HELM_DIST" + CHECKSUM_URL="$DOWNLOAD_URL.sha256" + HELM_TMP_ROOT="$(mktemp -dt helm-installer-XXXXXX)" + HELM_TMP_FILE="$HELM_TMP_ROOT/$HELM_DIST" + HELM_SUM_FILE="$HELM_TMP_ROOT/$HELM_DIST.sha256" + echo "Downloading $DOWNLOAD_URL" + if [ "${HAS_CURL}" == "true" ]; then + curl -SsL "$CHECKSUM_URL" -o "$HELM_SUM_FILE" + curl -SsL "$DOWNLOAD_URL" -o "$HELM_TMP_FILE" + elif [ "${HAS_WGET}" == "true" ]; then + wget -q -O "$HELM_SUM_FILE" "$CHECKSUM_URL" + wget -q -O "$HELM_TMP_FILE" "$DOWNLOAD_URL" + fi +} + +# verifyFile verifies the SHA256 checksum of the binary package +# and the GPG signatures for both the package and checksum file +# (depending on settings in environment). +verifyFile() { + if [ "${VERIFY_CHECKSUM}" == "true" ]; then + verifyChecksum + fi + if [ "${VERIFY_SIGNATURES}" == "true" ]; then + verifySignatures + fi +} + +# installFile installs the Helm binary. +installFile() { + HELM_TMP="$HELM_TMP_ROOT/$BINARY_NAME" + mkdir -p "$HELM_TMP" + tar xf "$HELM_TMP_FILE" -C "$HELM_TMP" + HELM_TMP_BIN="$HELM_TMP/$OS-$ARCH/helm" + echo "Preparing to install $BINARY_NAME into ${HELM_INSTALL_DIR}" + runAsRoot cp "$HELM_TMP_BIN" "$HELM_INSTALL_DIR/$BINARY_NAME" + echo "$BINARY_NAME installed into $HELM_INSTALL_DIR/$BINARY_NAME" +} + +# verifyChecksum verifies the SHA256 checksum of the binary package. +verifyChecksum() { + printf "Verifying checksum... " + local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}') + local expected_sum=$(cat ${HELM_SUM_FILE}) + if [ "$sum" != "$expected_sum" ]; then + echo "SHA sum of ${HELM_TMP_FILE} does not match. Aborting." + exit 1 + fi + echo "Done." +} + +# verifySignatures obtains the latest KEYS file from GitHub main branch +# as well as the signature .asc files from the specific GitHub release, +# then verifies that the release artifacts were signed by a maintainer's key. +verifySignatures() { + printf "Verifying signatures... " + local keys_filename="KEYS" + local github_keys_url="https://raw.githubusercontent.com/helm/helm/main/${keys_filename}" + if [ "${HAS_CURL}" == "true" ]; then + curl -SsL "${github_keys_url}" -o "${HELM_TMP_ROOT}/${keys_filename}" + elif [ "${HAS_WGET}" == "true" ]; then + wget -q -O "${HELM_TMP_ROOT}/${keys_filename}" "${github_keys_url}" + fi + local gpg_keyring="${HELM_TMP_ROOT}/keyring.gpg" + local gpg_homedir="${HELM_TMP_ROOT}/gnupg" + mkdir -p -m 0700 "${gpg_homedir}" + local gpg_stderr_device="/dev/null" + if [ "${DEBUG}" == "true" ]; then + gpg_stderr_device="/dev/stderr" + fi + gpg --batch --quiet --homedir="${gpg_homedir}" --import "${HELM_TMP_ROOT}/${keys_filename}" 2> "${gpg_stderr_device}" + gpg --batch --no-default-keyring --keyring "${gpg_homedir}/${GPG_PUBRING}" --export > "${gpg_keyring}" + local github_release_url="https://github.com/helm/helm/releases/download/${TAG}" + if [ "${HAS_CURL}" == "true" ]; then + curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" + curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" + elif [ "${HAS_WGET}" == "true" ]; then + wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" + wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" + fi + local error_text="If you think this might be a potential security issue," + error_text="${error_text}\nplease see here: https://github.com/helm/community/blob/master/SECURITY.md" + local num_goodlines_sha=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" 2> "${gpg_stderr_device}" | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)') + if [[ ${num_goodlines_sha} -lt 2 ]]; then + echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256!" + echo -e "${error_text}" + exit 1 + fi + local num_goodlines_tar=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" 2> "${gpg_stderr_device}" | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)') + if [[ ${num_goodlines_tar} -lt 2 ]]; then + echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz!" + echo -e "${error_text}" + exit 1 + fi + echo "Done." +} + +# fail_trap is executed if an error occurs. +fail_trap() { + result=$? + if [ "$result" != "0" ]; then + if [[ -n "$INPUT_ARGUMENTS" ]]; then + echo "Failed to install $BINARY_NAME with the arguments provided: $INPUT_ARGUMENTS" + help + else + echo "Failed to install $BINARY_NAME" + fi + echo -e "\tFor support, go to https://github.com/helm/helm." + fi + cleanup + exit $result +} + +# testVersion tests the installed client to make sure it is working. +testVersion() { + set +e + HELM="$(command -v $BINARY_NAME)" + if [ "$?" = "1" ]; then + echo "$BINARY_NAME not found. Is $HELM_INSTALL_DIR on your "'$PATH?' + exit 1 + fi + set -e +} + +# help provides possible cli installation arguments +help () { + echo "Accepted cli arguments are:" + echo -e "\t[--help|-h ] ->> prints this help" + echo -e "\t[--version|-v ] . When not defined it fetches the latest release from GitHub" + echo -e "\te.g. --version v3.0.0 or -v canary" + echo -e "\t[--no-sudo] ->> install without sudo" +} + +# cleanup temporary files to avoid https://github.com/helm/helm/issues/2977 +cleanup() { + if [[ -d "${HELM_TMP_ROOT:-}" ]]; then + rm -rf "$HELM_TMP_ROOT" + fi +} + +# Execution + +#Stop execution on any error +trap "fail_trap" EXIT +set -e + +# Set debug if desired +if [ "${DEBUG}" == "true" ]; then + set -x +fi + +# Parsing input arguments (if any) +export INPUT_ARGUMENTS="${@}" +set -u +while [[ $# -gt 0 ]]; do + case $1 in + '--version'|-v) + shift + if [[ $# -ne 0 ]]; then + export DESIRED_VERSION="${1}" + else + echo -e "Please provide the desired version. e.g. --version v3.0.0 or -v canary" + exit 0 + fi + ;; + '--no-sudo') + USE_SUDO="false" + ;; + '--help'|-h) + help + exit 0 + ;; + *) exit 1 + ;; + esac + shift +done +set +u + +initArch +initOS +verifySupported +checkDesiredVersion +if ! checkHelmInstalledVersion; then + downloadFile + verifyFile + installFile +fi +testVersion +cleanup diff --git a/traefik/web-helm/.helmignore b/traefik/web-helm/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/traefik/web-helm/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/traefik/web-helm/Chart.yaml b/traefik/web-helm/Chart.yaml new file mode 100644 index 0000000..1174085 --- /dev/null +++ b/traefik/web-helm/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: web-helm +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/traefik/web-helm/templates/NOTES.txt b/traefik/web-helm/templates/NOTES.txt new file mode 100644 index 0000000..751b99d --- /dev/null +++ b/traefik/web-helm/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "web-helm.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "web-helm.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "web-helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "web-helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/traefik/web-helm/templates/_helpers.tpl b/traefik/web-helm/templates/_helpers.tpl new file mode 100644 index 0000000..ab1a398 --- /dev/null +++ b/traefik/web-helm/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "web-helm.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "web-helm.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "web-helm.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "web-helm.labels" -}} +helm.sh/chart: {{ include "web-helm.chart" . }} +{{ include "web-helm.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "web-helm.selectorLabels" -}} +app.kubernetes.io/name: {{ include "web-helm.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "web-helm.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "web-helm.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/traefik/web-helm/templates/deployment.yaml b/traefik/web-helm/templates/deployment.yaml new file mode 100644 index 0000000..8a2fb9a --- /dev/null +++ b/traefik/web-helm/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "web-helm.fullname" . }} + labels: + {{- include "web-helm.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "web-helm.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "web-helm.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "web-helm.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/traefik/web-helm/templates/hpa.yaml b/traefik/web-helm/templates/hpa.yaml new file mode 100644 index 0000000..dc16bed --- /dev/null +++ b/traefik/web-helm/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "web-helm.fullname" . }} + labels: + {{- include "web-helm.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "web-helm.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/traefik/web-helm/templates/ingress.yaml b/traefik/web-helm/templates/ingress.yaml new file mode 100644 index 0000000..6d037d2 --- /dev/null +++ b/traefik/web-helm/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "web-helm.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "web-helm.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/traefik/web-helm/templates/service.yaml b/traefik/web-helm/templates/service.yaml new file mode 100644 index 0000000..f749403 --- /dev/null +++ b/traefik/web-helm/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "web-helm.fullname" . }} + labels: + {{- include "web-helm.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "web-helm.selectorLabels" . | nindent 4 }} diff --git a/traefik/web-helm/templates/serviceaccount.yaml b/traefik/web-helm/templates/serviceaccount.yaml new file mode 100644 index 0000000..1159e64 --- /dev/null +++ b/traefik/web-helm/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "web-helm.serviceAccountName" . }} + labels: + {{- include "web-helm.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/traefik/web-helm/templates/tests/test-connection.yaml b/traefik/web-helm/templates/tests/test-connection.yaml new file mode 100644 index 0000000..fedcbc4 --- /dev/null +++ b/traefik/web-helm/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "web-helm.fullname" . }}-test-connection" + labels: + {{- include "web-helm.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "web-helm.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/traefik/web-helm/values.yaml b/traefik/web-helm/values.yaml new file mode 100644 index 0000000..64663fd --- /dev/null +++ b/traefik/web-helm/values.yaml @@ -0,0 +1,82 @@ +# Default values for web-helm. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: nginx + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {}