├── .gitignore
├── OWNERS
├── OWNERS_ALIASES
├── README.md
├── book
├── the-devops-2-6-toolkit.epub
├── the-devops-2-6-toolkit.mobi
└── the-devops-2-6-toolkit.pdf
└── manuscript
├── 00-pre-preface.md
├── 01-preface.md
├── 02-intro.md
├── 02-intro.sh
├── 03-quickstart.md
├── 03-quickstart.sh
├── 04-import.md
├── 04-import.sh
├── 05-buildpacks.md
├── 05-buildpacks.sh
├── 06-env.md
├── 06-env.sh
├── 07-dev.md
├── 07-dev.sh
├── 08-pr.md
├── 08-pr.sh
├── 09-promote.md
├── 09-promote.sh
├── 10-versioning.md
├── 10-versioning.sh
├── 11-serverless.md
├── 12-prow.md
├── 12-prow.sh
├── 13-pipeline-extension-model.md
├── 13-pipeline-extension-model.sh
├── 14-upgrade.md
├── 14-upgrade.sh
├── 15-advanced-pipelines.md
├── 15-advanced-pipelines.sh
├── 16-serverless-apps.md
├── 16-serverless-apps.sh
├── 17-progressive-delivery.md
├── 17-progressive-delivery.sh
├── 18-boot.md
├── 18-boot.sh
├── 19-apps.md
├── 19-apps.sh
├── 20-ui.md
├── 20-ui.sh
├── 99-advanced-pipelines-2.md
├── 99-boot-upgrade.md
├── 99-cloudbees.md
├── 99-codified-infrastructure.md
├── 99-deploy-avanced.md
├── 99-docker-registry.md
├── 99-git-server.md
├── 99-gitlab.md
├── 99-integration-with-uptimerobot.md
├── 99-jenkins-prometheus.md
├── 99-kaniko.md
├── 99-minishift.md
├── 99-multi-cluster.md
├── 99-nfs.md
├── 99-pipeline-from-scratch.md
├── 99-platforms.md
├── 99-rbac.md
├── 99-registry.md
├── 99-security.md
├── 99-skaffold.md
├── 99-sonobuoy.md
├── 99-teams.md
├── 99-the-end.md
├── Book.txt
├── Sample.txt
├── TODO.md
├── images
├── ch00
│ └── gitops-model.png
├── ch02
│ └── jx-console-environments.png
├── ch03
│ ├── github-go-demo-6-releases.png
│ ├── github-go-demo-6-webhooks.png
│ ├── github-go-demo-6.png
│ └── jx-console-go-demo-6.png
├── ch04
│ ├── github-go-demo-6.png
│ ├── import-build-staging.png
│ └── import-pr.png
├── ch06
│ ├── gitops-agents.png
│ ├── gitops-agents.xml
│ ├── gitops-apps.png
│ ├── gitops-apps.xml
│ ├── gitops-env.png
│ ├── gitops-env.xml
│ ├── gitops-full-flow.png
│ ├── gitops-full-flow.xml
│ ├── gitops-registries.png
│ ├── gitops-registries.xml
│ ├── gitops-webhooks.png
│ └── gitops-webhooks.xml
├── ch07
│ ├── devpod-ksync.png
│ ├── devpod-ksync.xml
│ ├── devpod-vscode.png
│ ├── devpod-vscode.xml
│ ├── devpod.png
│ ├── devpod.xml
│ └── vs-code-jx.png
├── ch08
│ ├── issue-commit-msg.png
│ ├── pr-all-checks.png
│ ├── pr.drawio
│ └── pr.png
├── ch10
│ └── versioning-github-releases.png
├── ch11
│ ├── prow-ui.png
│ ├── serverless-flow-pipeline-operator.drawio
│ ├── serverless-flow-pipeline-operator.png
│ ├── serverless-flow-prow.drawio
│ ├── serverless-flow-prow.png
│ ├── serverless-flow-tekton.drawio
│ ├── serverless-flow-tekton.png
│ ├── serverless-flow.drawio
│ ├── serverless-flow.png
│ ├── serverless-static-agents.drawio
│ ├── serverless-static-agents.png
│ ├── serverless-static.drawio
│ ├── serverless-static.png
│ ├── serverless-teams-recovery.drawio
│ ├── serverless-teams-recovery.png
│ ├── serverless-teams.drawio
│ ├── serverless-teams.png
│ ├── serverless.drawio
│ └── serverless.png
├── ch12
│ ├── prow-assign.png
│ ├── prow-collaborator.png
│ ├── prow-lgtm-own-pr.png
│ ├── prow-pr-label-hold.png
│ ├── prow-pr-merged.png
│ └── prow-pr.png
├── ch13
│ └── prow-failed.png
├── ch14
│ ├── jenkins-x-platform.png
│ └── upgraded-webhook.png
├── ch15
│ ├── codecov-github-pr-checks.png
│ └── codecov-github-pr.png
├── ch17
│ ├── blue-green.drawio
│ ├── blue-green.png
│ ├── canary-grafana.png
│ ├── canary-rollback.drawio
│ ├── canary-rollback.png
│ ├── canary-rollout.drawio
│ ├── canary-rollout.png
│ ├── knative-request.drawio
│ ├── knative-request.png
│ ├── knative-scale-to-three.drawio
│ ├── knative-scale-to-three.png
│ ├── knative-scale-to-zero.drawio
│ ├── knative-scale-to-zero.png
│ ├── recreate.drawio
│ ├── recreate.png
│ ├── rolling-update.drawio
│ └── rolling-update.png
├── ch18
│ └── jx-boot-github.png
└── ch19
│ ├── app-dependencies-shared-env.drawio
│ ├── app-dependencies-shared-env.png
│ ├── app-dependencies-shared.drawio
│ ├── app-dependencies-shared.png
│ ├── app-dependencies.drawio
│ └── app-dependencies.png
├── joost
└── README.md
├── kaniko.yaml
└── scripts
├── aks
├── aks-jx-gloo.sh
├── aks-jx-serverless-gloo.sh
├── aks-jx-serverless.sh
└── aks-jx.sh
├── alibaba
└── alibaba-serverless.sh
├── do
└── do-jx.sh
├── eks
├── eks-jx-boot.sh
├── eks-jx-gloo.sh
├── eks-jx-serverless.sh
├── eks-jx.sh
└── eks.sh
├── gke
├── gke-jx-boot.sh
├── gke-jx-gloo.sh
├── gke-jx-kaniko.sh
├── gke-jx-serverless-gloo.sh
├── gke-jx-serverless.sh
├── gke-jx.sh
└── gke.sh
├── jx
├── install-gke.sh
├── install-serverless.sh
└── install.sh
└── minikube
├── minikube-istio.sh
├── minikube-jx.sh
└── minikube.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | /jx-go
2 | /myvalues.yaml
3 | .DS_Store
4 | .idea/
5 | /tmp
6 | /companies
--------------------------------------------------------------------------------
/OWNERS:
--------------------------------------------------------------------------------
1 | approvers:
2 | - vfarcic
3 | reviewers:
4 | - vfarcic
5 |
--------------------------------------------------------------------------------
/OWNERS_ALIASES:
--------------------------------------------------------------------------------
1 | aliases:
2 | - vfarcic
3 | best-approvers:
4 | - vfarcic
5 | best-reviewers:
6 | - vfarcic
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [The DevOps 2.6 Toolkit: Jenkins X](https://leanpub.com/the-devops-2-6-toolkit)
2 |
3 | The links to the last published version of the book:
4 | * [epub](book/the-devops-2-6-toolkit.epub)
5 | * [mobi](book/the-devops-2-6-toolkit.mobi)
6 | * [pdf](book/the-devops-2-6-toolkit.pdf)
7 |
--------------------------------------------------------------------------------
/book/the-devops-2-6-toolkit.epub:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/book/the-devops-2-6-toolkit.epub
--------------------------------------------------------------------------------
/book/the-devops-2-6-toolkit.mobi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/book/the-devops-2-6-toolkit.mobi
--------------------------------------------------------------------------------
/book/the-devops-2-6-toolkit.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/book/the-devops-2-6-toolkit.pdf
--------------------------------------------------------------------------------
/manuscript/01-preface.md:
--------------------------------------------------------------------------------
1 | # Preface
2 |
3 | When I finished the last book ("The DevOps 2.5 Toolkit: Monitoring, Logging, and Auto-Scaling Kubernetes"), I wanted to take a break from writing for a month or two. I thought that would clear my mind and help me decide which subject to tackle next. Those days were horrible. I could not make up my mind. So many cool and useful tech is emerging and being adopted. I was never as undecided as those weeks. Which should be my next step?
4 |
5 | I could explore serverless. That's definitely useful, and it might be considered the next big thing. Or I could dive into Istio. It is probably the biggest and the most important project sitting on top of Kubernetes. Or I could tackle some smaller subjects. Kaniko is the missing link in continuous delivery. Building containers might be the only thing we still do on the host level, and Kaniko allows us to move that process inside containers. How about security scanning? It is one of the things that are mandatory in most organizations, and yet I did not include it in "The DevOps 2.4 Toolkit: Continuous Deployment To Kubernetes". Then there is Skaffold, Prow, Knative, and quite a few other tools that are becoming stable and very useful.
6 |
7 | And then it struck me. Jenkins X does all those things and many more. I intentionally excluded it from "The DevOps 2.4 Toolkit: Continuous Deployment To Kubernetes" because at that time (the first half of 2018) it was still too green and it was changing all the time. It was far from stable. But the situation in early 2019 is different. While the project still evolves at a rapid pace and there are quite a few things left to do and polish, Jenkins X is being adopted by many. It has proved its usefulness. Its community is rising, its popularity is enormous, and it is one of the Kubernetes darlings.
8 |
9 | So, the decision was made. This book will be dedicated to Jenkins X.
10 |
11 | As with other books, the idea is to go deep into the subject. While the first few chapters might (intentionally) seem very basic, we'll explore Jenkins X and many related tools in-depth, and we'll try to see the bigger picture. What is it? What does it do, and how does it do it? How does it affect our processes? How can we combine it with the things we already have, and which tools should be changed? Is it only about continuous delivery? Does it affect local development? Does it change how we operate Kubernetes?
12 |
13 | As with all other books, I do not know in advance where this subject will lead me. I do not plan (much) in advance, and I did not write an index of everything I want to cover. Time will tell what will be the final scope.
14 |
15 | What matters is that I want you to be successful, and I hope that this book will help you with your career path.
16 |
17 | I> If you explore [jenkins-x.io](https://jenkins-x.io/), you might notice some similarities between the content there and in this book. What you read here is not a copy from what's there. Instead, I decided to contribute part of the chapters to the community.
18 |
19 | Eventually, you might get stuck and will need help. Or you might want to write a review or comment on the book's content. Please join the [DevOps20](http://slack.devops20toolkit.com/) Slack workspace and post your thoughts, ask questions, or participate in a discussion. If you prefer a more one-on-one conversation, you can use Slack to send me a private message or send an email to viktor@farcic.com. All the books I have written are very dear to me, and I want you to have a good experience reading them. Part of that experience is the option to reach out to me. Don't be shy.
20 |
21 | Please note that this one, just as the previous books, is self-published. I believe that having no intermediaries between the writer and the reader is the best way to go. It allows me to write faster, update the book more frequently, and have more direct communication with you. Your feedback is part of the process. No matter whether you purchased the book while only a few or all chapters were written, the idea is that it will never be truly finished. As time passes, it will require updates so that it is aligned with the change in technology or processes. When possible, I will try to keep it up to date and release updates whenever that makes sense. Eventually, things might change so much that updates are not a good option anymore, and that will be a sign that a whole new book is required. **I will keep writing as long as I continue getting your support.**
22 |
23 | # About the Author
24 |
25 | Viktor Farcic is a Developer Advocate at [CloudBees](https://www.cloudbees.com/), a member of the [Docker Captains](https://www.docker.com/community/docker-captains) group, and author.
26 |
27 | He has coded using a plethora of languages, starting with Pascal (yes, he is old), Basic (before it got Visual prefix), ASP (before it got .NET suffix), C, C++, Perl, Python, ASP.NET, Visual Basic, C#, JavaScript, Java, Scala, etc. He never worked with Fortran. His current favorite is Go.
28 |
29 | His big passions are containers, distributed systems, microservices, continuous delivery (CD), continuous deployment (CDP), and test-driven development (TDD).
30 |
31 | He often speaks at community gatherings and conferences.
32 |
33 | He wrote [The DevOps Toolkit Series](http://www.devopstoolkitseries.com/) and [Test-Driven Java Development](https://www.packtpub.com/application-development/test-driven-java-development).
34 |
35 | His random thoughts and tutorials can be found in his blog [TechnologyConversations.com](https://technologyconversations.com/).
36 |
37 | # Dedication
38 |
39 | To Sara and Eva.
40 |
--------------------------------------------------------------------------------
/manuscript/03-quickstart.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/8d1f6e34ba9fdecb5eea49fe6b80979e
2 |
3 | ################################################
4 | # Creating A Kubernetes Cluster With Jenkins X #
5 | ################################################
6 |
7 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
8 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
9 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
10 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
11 |
12 | #################################
13 | # Creating A Quickstart Project #
14 | #################################
15 |
16 | jx create quickstart
17 |
18 | jx create quickstart \
19 | --filter golang-http \
20 | --project-name jx-go
21 |
22 | open "https://github.com/jenkins-x-quickstarts"
23 |
24 | ls -1 ~/.jx/draft/packs/github.com/jenkins-x-buildpacks/jenkins-x-kubernetes/packs
25 |
26 | ls -1 ~/.jx/draft/packs/github.com/jenkins-x-buildpacks/jenkins-x-kubernetes/packs/go
27 |
28 | ######################################
29 | # Exploring Quickstart Project Files #
30 | ######################################
31 |
32 | GH_USER=[...]
33 |
34 | open "https://github.com/$GH_USER/jx-go"
35 |
36 | cd jx-go
37 |
38 | ls -1
39 |
40 | cat Makefile
41 |
42 | cat Dockerfile
43 |
44 | cat skaffold.yaml
45 |
46 | ls -1 charts
47 |
48 | ls -1 charts/jx-go
49 |
50 | cat jenkins-x.yml
51 |
52 | open "https://github.com/$GH_USER/jx-go/settings/hooks"
53 |
54 | ####################################################################################
55 | # Retrieving Jenkins X Activities, Logs, Pipelines, Applications, And Environments #
56 | ####################################################################################
57 |
58 | jx get activities
59 |
60 | jx get activities --filter jx-go --watch
61 |
62 | jx get build logs
63 |
64 | jx get build logs --filter jx-go
65 |
66 | jx get build logs \
67 | --filter $GH_USER/jx-go/master
68 |
69 | jx get pipelines
70 |
71 | jx get applications
72 |
73 | jx get env
74 |
75 | jx get applications --env staging
76 |
77 | jx get applications --env production
78 |
79 | open "https://github.com/$GH_USER/jx-go/releases"
80 |
81 | ADDR=$(kubectl --namespace jx-staging \
82 | get ingress jx-go \
83 | -o jsonpath="{.spec.rules[0].host}")
84 |
85 | curl "http://$ADDR"
86 |
87 | #############
88 | # What Now? #
89 | #############
90 |
91 | cd ..
92 |
93 | hub delete -y \
94 | $GH_USER/environment-jx-rocks-staging
95 |
96 | hub delete -y \
97 | $GH_USER/environment-jx-rocks-production
98 |
99 | hub delete -y $GH_USER/jx-go
100 |
101 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
102 |
103 | rm -rf jx-go
104 |
--------------------------------------------------------------------------------
/manuscript/04-import.sh:
--------------------------------------------------------------------------------
1 | # Links to gists for creating a cluster with jx
2 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
3 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
4 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
5 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
6 |
7 | open "https://github.com/vfarcic/go-demo-6"
8 |
9 | GH_USER=[...]
10 |
11 | git clone \
12 | https://github.com/$GH_USER/go-demo-6.git
13 |
14 | cd go-demo-6
15 |
16 | git pull
17 |
18 | git checkout orig
19 |
20 | git merge -s ours master --no-edit
21 |
22 | git checkout master
23 |
24 | git merge orig
25 |
26 | rm -rf charts
27 |
28 | git push
29 |
30 | jx repo --batch-mode
31 |
32 | ls -1
33 |
34 | jx import --batch-mode
35 |
36 | ls -1
37 |
38 | jx get activities \
39 | --filter go-demo-6 \
40 | --watch
41 |
42 | jx get applications
43 |
44 | STAGING_ADDR=[...]
45 |
46 | curl "$STAGING_ADDR/demo/hello"
47 |
48 | kubectl --namespace jx-staging logs \
49 | -l app=jx-go-demo-6
50 |
51 | echo "dependencies:
52 | - name: mongodb
53 | alias: go-demo-6-db
54 | version: 5.3.0
55 | repository: https://kubernetes-charts.storage.googleapis.com
56 | condition: db.enabled
57 | " | tee charts/go-demo-6/requirements.yaml
58 |
59 | echo "go-demo-6-db:
60 | replicaSet:
61 | enabled: true
62 | " | tee -a charts/go-demo-6/values.yaml
63 |
64 | git add .
65 |
66 | git commit \
67 | --message "Added dependencies"
68 |
69 | git push
70 |
71 | jx get activity \
72 | --filter go-demo-6 \
73 | --watch
74 |
75 | kubectl --namespace jx-staging get pods
76 |
77 | kubectl --namespace jx-staging \
78 | describe pod \
79 | -l app=jx-go-demo-6
80 |
81 | cat charts/go-demo-6/values.yaml
82 |
83 | git add .
84 |
85 | git commit \
86 | --message "Added dependencies"
87 |
88 | git push
89 |
90 | jx get activity \
91 | --filter go-demo-6 \
92 | --watch
93 |
94 | kubectl --namespace jx-staging get pods
95 |
96 | curl "$STAGING_ADDR/demo/hello"
97 |
98 | cd ..
99 |
100 | hub delete -y \
101 | $GH_USER/environment-jx-rocks-staging
102 |
103 | hub delete -y \
104 | $GH_USER/environment-jx-rocks-production
105 |
106 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
107 |
--------------------------------------------------------------------------------
/manuscript/05-buildpacks.sh:
--------------------------------------------------------------------------------
1 | # Links to gists for creating a cluster with jx
2 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
3 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
4 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
5 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
6 |
7 | open "https://github.com/jenkins-x-buildpacks/jenkins-x-kubernetes"
8 |
9 | GH_USER=[...]
10 |
11 | git clone https://github.com/$GH_USER/jenkins-x-kubernetes
12 |
13 | cd jenkins-x-kubernetes
14 |
15 | ls -1 packs
16 |
17 | ls -1 packs/go
18 |
19 | cp -R packs/go packs/go-mongo
20 |
21 | cat packs/go-mongo/charts/templates/deployment.yaml \
22 | | sed -e \
23 | 's@ports:@env:\
24 | - name: DB\
25 | value: {{ template "fullname" . }}-db\
26 | ports:@g' \
27 | | tee packs/go-mongo/charts/templates/deployment.yaml
28 |
29 | echo "dependencies:
30 | - name: mongodb
31 | alias: REPLACE_ME_APP_NAME-db
32 | version: 5.3.0
33 | repository: https://kubernetes-charts.storage.googleapis.com
34 | condition: db.enabled
35 | " | tee packs/go-mongo/charts/requirements.yaml
36 |
37 | echo "REPLACE_ME_APP_NAME-db:
38 | replicaSet:
39 | enabled: true
40 | " | tee -a packs/go-mongo/charts/values.yaml
41 |
42 | ls -1 packs/go-mongo/preview
43 |
44 | cat packs/go-mongo/preview/requirements.yaml
45 |
46 | cat packs/go-mongo/preview/requirements.yaml \
47 | | sed -e \
48 | 's@ # !! "alias@- name: mongodb\
49 | alias: preview-db\
50 | version: 5.3.0\
51 | repository: https://kubernetes-charts.storage.googleapis.com\
52 | \
53 | # !! "alias@g' \
54 | | tee packs/go-mongo/preview/requirements.yaml
55 |
56 | echo '
57 | ' | tee -a packs/go-mongo/preview/requirements.yaml
58 |
59 | git add .
60 |
61 | git commit \
62 | --message "Added go-mongo build pack"
63 |
64 | git push
65 |
66 | jx edit buildpack \
67 | --url https://github.com/$GH_USER/jenkins-x-kubernetes \
68 | --ref master \
69 | --batch-mode
70 |
71 | cd ..
72 |
73 | cd go-demo-6
74 |
75 | jx delete application \
76 | $GH_USER/go-demo-6 \
77 | --batch-mode
78 |
79 | kubectl --namespace jx delete act \
80 | --selector owner=$GH_USER \
81 | --selector sourcerepository=go-demo-6
82 |
83 | git pull
84 |
85 | git checkout orig
86 |
87 | git merge -s ours master --no-edit
88 |
89 | git checkout master
90 |
91 | git merge orig
92 |
93 | rm -rf charts
94 |
95 | git push
96 |
97 | jx import --pack go-mongo --batch-mode
98 |
99 | ls -1 ~/.jx/draft/packs/github.com/$GH_USER/jenkins-x-kubernetes/packs
100 |
101 | jx get activity \
102 | --filter go-demo-6 \
103 | --watch
104 |
105 | kubectl --namespace jx-staging get pods
106 |
107 | kubectl --namespace jx-staging \
108 | describe pod \
109 | --selector app=jx-go-demo-6
110 |
111 | cat charts/go-demo-6/values.yaml
112 |
113 | cat charts/go-demo-6/values.yaml \
114 | | sed -e \
115 | 's@probePath: /@probePath: /demo/hello?health=true@g' \
116 | | tee charts/go-demo-6/values.yaml
117 |
118 | echo '
119 | probePath: /demo/hello?health=true' \
120 | | tee -a charts/preview/values.yaml
121 |
122 | git add .
123 |
124 | git commit \
125 | --message "Fixed the probe"
126 |
127 | git push
128 |
129 | jx get activity \
130 | --filter go-demo-6 \
131 | --watch
132 |
133 | kubectl --namespace jx-staging get pods
134 |
135 | jx get applications
136 |
137 | STAGING_ADDR=[...]
138 |
139 | curl "$STAGING_ADDR/demo/hello"
140 |
141 | cat jenkins-x.yml \
142 | | sed -e \
143 | 's@buildPack: go-mongo@buildPack: go@g' \
144 | | tee jenkins-x.yml
145 |
146 | git add .
147 |
148 | git commit -m "Reverted to the go buildpack"
149 |
150 | git push
151 |
152 | cd ..
153 |
154 | GH_USER=[...]
155 |
156 | hub delete -y \
157 | $GH_USER/environment-jx-rocks-staging
158 |
159 | hub delete -y \
160 | $GH_USER/environment-jx-rocks-production
161 |
162 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
163 |
--------------------------------------------------------------------------------
/manuscript/06-env.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/bfac9a1397d7b61dcfc9ec9112d7e433
2 |
3 | # Links to gists for creating a cluster with jx
4 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
5 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
6 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
7 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
8 |
9 | cd go-demo-6
10 |
11 | git pull
12 |
13 | git checkout buildpack-tekton
14 |
15 | git merge -s ours master --no-edit
16 |
17 | git checkout master
18 |
19 | git merge buildpack-tekton
20 |
21 | git push
22 |
23 | # If GKE
24 | export REGISTRY_OWNER=$PROJECT
25 |
26 | # If EKS or AKS
27 | # Replace `[...]` with your GitHub user
28 | export REGISTRY_OWNER=[...]
29 |
30 | cat charts/go-demo-6/Makefile \
31 | | sed -e \
32 | "s@vfarcic@$REGISTRY_OWNER@g" \
33 | | sed -e \
34 | "s@devops-26@$REGISTRY_OWNER@g" \
35 | | tee charts/go-demo-6/Makefile
36 |
37 | cat charts/preview/Makefile \
38 | | sed -e \
39 | "s@vfarcic@$REGISTRY_OWNER@g" \
40 | | sed -e \
41 | "s@devops-26@$REGISTRY_OWNER@g" \
42 | | tee charts/preview/Makefile
43 |
44 | cat skaffold.yaml \
45 | | sed -e \
46 | "s@vfarcic@$REGISTRY_OWNER@g" \
47 | | sed -e \
48 | "s@devops-26@$REGISTRY_OWNER@g" \
49 | | tee skaffold.yaml
50 |
51 | jx import --batch-mode
52 |
53 | jx get activity \
54 | --filter go-demo-6 \
55 | --watch
56 |
57 | jx get env
58 |
59 | jx get env --promote Auto
60 |
61 | GH_USER=[...]
62 |
63 | git clone \
64 | https://github.com/$GH_USER/environment-jx-rocks-staging.git
65 |
66 | cd environment-jx-rocks-staging
67 |
68 | ls -1
69 |
70 | cat Makefile
71 |
72 | cat env/requirements.yaml
73 |
74 | jx create env \
75 | --name pre-production \
76 | --label Pre-Production \
77 | --namespace jx-pre-production \
78 | --promotion Manual \
79 | --batch-mode
80 |
81 | jx get env
82 |
83 | jx delete env pre-production
84 |
85 | hub delete -y \
86 | $GH_USER/environment-jx-pre-production
87 |
88 | cd ..
89 |
90 | rm -rf environment-jx-rocks-*
91 |
92 | GH_USER=[...]
93 |
94 | hub delete -y \
95 | $GH_USER/environment-jx-rocks-staging
96 |
97 | hub delete -y \
98 | $GH_USER/environment-jx-rocks-production
99 |
100 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
101 |
--------------------------------------------------------------------------------
/manuscript/07-dev.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/50fac90cc10ebc67b36ea07687e8df75
2 |
3 | # Links to gists for creating a cluster with jx
4 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
5 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
6 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
7 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
8 |
9 | cd go-demo-6
10 |
11 | git pull
12 |
13 | git checkout buildpack-tekton
14 |
15 | git merge -s ours master --no-edit
16 |
17 | git checkout master
18 |
19 | git merge buildpack
20 |
21 | git push
22 |
23 | # If GKE
24 | export REGISTRY_OWNER=$PROJECT
25 |
26 | # If EKS or AKS
27 | # Replace `[...]` with your GitHub user
28 | export REGISTRY_OWNER=[...]
29 |
30 | cat charts/go-demo-6/Makefile \
31 | | sed -e \
32 | "s@vfarcic@$REGISTRY_OWNER@g" \
33 | | sed -e \
34 | "s@devops-26@$REGISTRY_OWNER@g" \
35 | | tee charts/go-demo-6/Makefile
36 |
37 | cat charts/preview/Makefile \
38 | | sed -e \
39 | "s@vfarcic@$REGISTRY_OWNER@g" \
40 | | sed -e \
41 | "s@devops-26@$REGISTRY_OWNER@g" \
42 | | tee charts/preview/Makefile
43 |
44 | cat skaffold.yaml \
45 | | sed -e \
46 | "s@vfarcic@$REGISTRY_OWNER@g" \
47 | | sed -e \
48 | "s@devops-26@$REGISTRY_OWNER@g" \
49 | | tee skaffold.yaml
50 |
51 | jx import --pack go --batch-mode
52 |
53 | jx get activities \
54 | --filter go-demo-6 \
55 | --watch
56 |
57 | cd go-demo-6
58 |
59 | jx create devpod --label go --batch-mode
60 |
61 | jx rsh --devpod
62 |
63 | cd go-demo-6
64 |
65 | ls -1
66 |
67 | make linux
68 |
69 | cat skaffold.yaml
70 |
71 | cat skaffold.yaml \
72 | | sed -e 's@DIGEST_HEX@UUID@g' \
73 | | tee skaffold.yaml
74 |
75 | echo $DOCKER_REGISTRY
76 |
77 | env
78 |
79 | kubectl create \
80 | -f https://raw.githubusercontent.com/vfarcic/k8s-specs/master/helm/tiller-rbac.yml \
81 | --record --save-config
82 |
83 | helm init --service-account tiller
84 |
85 | export UUID=$(uuidgen)
86 |
87 | skaffold run --profile dev
88 |
89 | echo $SKAFFOLD_DEPLOY_NAMESPACE
90 |
91 | kubectl -n $SKAFFOLD_DEPLOY_NAMESPACE \
92 | get pods
93 |
94 | cat watch.sh
95 |
96 | cat watch.sh | sed -e \
97 | 's@skaffold@UUID=$(uuidgen) skaffold@g' \
98 | | tee watch.sh
99 |
100 | chmod +x watch.sh
101 |
102 | nohup ./watch.sh &
103 |
104 | exit
105 |
106 | export GH_USER=[...]
107 |
108 | kubectl --namespace jx-edit-$GH_USER \
109 | port-forward service/go-demo-6 \
110 | 8085:80 &
111 |
112 | curl "http://localhost:8085/demo/hello"
113 |
114 | kubectl port-forward \
115 | service/$GH_USER-go-ide 8086:80 &
116 |
117 | open "http://localhost:8086"
118 |
119 | kubectl --namespace jx-edit-$GH_USER \
120 | port-forward service/go-demo-6 \
121 | 8087:80 &
122 |
123 | curl "http://localhost:8087/demo/hello"
124 |
125 | pkill kubectl
126 |
127 | jx delete devpod $GH_USER-go
128 |
129 | echo 'unittest:
130 | CGO_ENABLED=$(CGO_ENABLED) $(GO) \\
131 | test --run UnitTest -v
132 | ' | tee -a Makefile
133 |
134 | cat watch.sh |
135 | sed -e \
136 | 's@linux \&\& skaffold@linux \&\& make unittest \&\& skaffold@g' \
137 | | sed -e \
138 | 's@skaffold@UUID=$(uuidgen) skaffold@g' \
139 | | tee watch.sh
140 |
141 | jx sync --daemon
142 |
143 | jx create devpod \
144 | --label go \
145 | --sync \
146 | --batch-mode
147 |
148 | jx rsh --devpod
149 |
150 | unset GOPATH
151 |
152 | go mod init
153 |
154 | helm init --client-only
155 |
156 | chmod +x watch.sh
157 |
158 | ./watch.sh
159 |
160 | kubectl --namespace jx-edit-$GH_USER \
161 | port-forward service/go-demo-6 \
162 | 8085:80 &
163 |
164 | curl "localhost:8085/demo/hello"
165 |
166 | cat main.go | sed -e \
167 | 's@hello, world@hello, devpod with tests@g' \
168 | | tee main.go
169 |
170 | cat main_test.go | sed -e \
171 | 's@hello, world@hello, devpod with tests@g' \
172 | | tee main_test.go
173 |
174 | kubectl --namespace jx-edit-$GH_USER \
175 | port-forward service/go-demo-6 \
176 | 8086:80 &
177 |
178 | curl "localhost:8085/demo/hello"
179 |
180 | git add .
181 |
182 | git commit \
183 | --message "devpod"
184 |
185 | git push
186 |
187 | jx get activity \
188 | --filter go-demo-6 \
189 | --watch
190 |
191 | jx get applications
192 |
193 | STAGING_URL=[...]
194 |
195 | curl "$STAGING_URL/demo/hello"
196 |
197 | jx delete devpod
198 |
199 | cd ..
200 |
201 | pkill kubectl
202 |
203 | GH_USER=[...]
204 |
205 | hub delete -y \
206 | $GH_USER/environment-jx-rocks-staging
207 |
208 | hub delete -y \
209 | $GH_USER/environment-jx-rocks-production
210 |
211 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
212 |
--------------------------------------------------------------------------------
/manuscript/08-pr.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/fabed5404bec733ed5eb264124e90721
2 |
3 | # Links to gists for creating a cluster with jx
4 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
5 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
6 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
7 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
8 |
9 | cd go-demo-6
10 |
11 | git pull
12 |
13 | git checkout dev-tekton
14 |
15 | git merge -s ours master --no-edit
16 |
17 | git checkout master
18 |
19 | git merge dev-tekton
20 |
21 | git push
22 |
23 | # If GKE
24 | export REGISTRY_OWNER=$PROJECT
25 |
26 | # If EKS or AKS
27 | # Replace `[...]` with your GitHub user
28 | export REGISTRY_OWNER=[...]
29 |
30 | cat charts/go-demo-6/Makefile \
31 | | sed -e \
32 | "s@vfarcic@$REGISTRY_OWNER@g" \
33 | | sed -e \
34 | "s@devops-26@$REGISTRY_OWNER@g" \
35 | | tee charts/go-demo-6/Makefile
36 |
37 | cat charts/preview/Makefile \
38 | | sed -e \
39 | "s@vfarcic@$REGISTRY_OWNER@g" \
40 | | sed -e \
41 | "s@devops-26@$REGISTRY_OWNER@g" \
42 | | tee charts/preview/Makefile
43 |
44 | cat skaffold.yaml \
45 | | sed -e \
46 | "s@vfarcic@$REGISTRY_OWNER@g" \
47 | | sed -e \
48 | "s@devops-26@$REGISTRY_OWNER@g" \
49 | | tee skaffold.yaml
50 |
51 | jx import --batch-mode
52 |
53 | jx get activities \
54 | --filter go-demo-6 \
55 | --watch
56 |
57 | git checkout -b my-pr
58 |
59 | cat main.go | sed -e \
60 | "s@hello, devpod with tests@hello, PR@g" \
61 | | tee main.go
62 |
63 | cat main_test.go | sed -e \
64 | "s@hello, devpod with tests@hello, PR@g" \
65 | | tee main_test.go
66 |
67 | echo "
68 |
69 | db:
70 | enabled: false
71 |
72 | preview-db:
73 | persistence:
74 | enabled: false" \
75 | | tee -a charts/preview/values.yaml
76 |
77 | git add .
78 |
79 | git commit \
80 | --message "This is a PR"
81 |
82 | git push --set-upstream origin my-pr
83 |
84 | jx create pullrequest \
85 | --title "My PR" \
86 | --body "This is the text that describes the PR
87 | and it can span multiple lines" \
88 | --batch-mode
89 |
90 | jx get previews
91 |
92 | PR_ADDR=[...]
93 |
94 | curl "$PR_ADDR/demo/hello"
95 |
96 | cat charts/go-demo-6/values.yaml
97 |
98 | echo "
99 | usePassword: false" \
100 | | tee -a charts/go-demo-6/values.yaml
101 |
102 | echo "
103 | usePassword: false" \
104 | | tee -a charts/preview/values.yaml
105 |
106 | git add .
107 |
108 | git commit \
109 | --message "Removed MongoDB password"
110 |
111 | git push
112 |
113 | jx get activity \
114 | --filter go-demo-6 \
115 | --watch
116 |
117 | jx get applications
118 |
119 | STAGING_ADDR=[...] # Replace `[...]` with the URL
120 |
121 | curl "$STAGING_ADDR/demo/hello"
122 |
123 | git checkout master
124 |
125 | git pull
126 |
127 | kubectl get cronjobs
128 |
129 | jx get previews
130 |
131 | jx gc previews
132 |
133 | jx get previews
134 |
135 | cd ..
136 |
137 | GH_USER=[...]
138 |
139 | hub delete -y \
140 | $GH_USER/environment-jx-rocks-staging
141 |
142 | hub delete -y \
143 | $GH_USER/environment-jx-rocks-production
144 |
145 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
146 |
--------------------------------------------------------------------------------
/manuscript/09-promote.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/cba4f52d90d4d47fcb068a052077c953
2 |
3 | # Links to gists for creating a cluster with jx
4 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
5 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
6 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
7 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
8 |
9 | cd go-demo-6
10 |
11 | git pull
12 |
13 | git checkout pr-tekton
14 |
15 | git merge -s ours master --no-edit
16 |
17 | git checkout master
18 |
19 | git merge pr-tekton
20 |
21 | git push
22 |
23 | # If GKE
24 | export REGISTRY_OWNER=$PROJECT
25 |
26 | # If EKS or AKS
27 | # Replace `[...]` with your GitHub user
28 | export REGISTRY_OWNER=[...]
29 |
30 | cat charts/go-demo-6/Makefile \
31 | | sed -e \
32 | "s@vfarcic@$REGISTRY_OWNER@g" \
33 | | sed -e \
34 | "s@devops-26@$REGISTRY_OWNER@g" \
35 | | tee charts/go-demo-6/Makefile
36 |
37 | cat charts/preview/Makefile \
38 | | sed -e \
39 | "s@vfarcic@$REGISTRY_OWNER@g" \
40 | | sed -e \
41 | "s@devops-26@$REGISTRY_OWNER@g" \
42 | | tee charts/preview/Makefile
43 |
44 | cat skaffold.yaml \
45 | | sed -e \
46 | "s@vfarcic@$REGISTRY_OWNER@g" \
47 | | sed -e \
48 | "s@devops-26@$REGISTRY_OWNER@g" \
49 | | tee skaffold.yaml
50 |
51 | jx import --batch-mode
52 |
53 | jx get activities \
54 | --filter go-demo-6 \
55 | --watch
56 |
57 | jx get applications --env production
58 |
59 | jx get applications --env staging
60 |
61 | VERSION=[...]
62 |
63 | jx promote go-demo-6 \
64 | --version $VERSION \
65 | --env production \
66 | --batch-mode
67 |
68 | jx get applications --env production
69 |
70 | PROD_ADDR=[...]
71 |
72 | curl "$PROD_ADDR/demo/hello"
73 |
74 | cd ..
75 |
76 | GH_USER=[...]
77 |
78 | hub delete -y \
79 | $GH_USER/environment-jx-rocks-staging
80 |
81 | hub delete -y \
82 | $GH_USER/environment-jx-rocks-production
83 |
84 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
85 |
--------------------------------------------------------------------------------
/manuscript/10-versioning.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/c7f4de887ea45232ea64400264340a73
2 |
3 | # Links to gists for creating a cluster with jx
4 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
5 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
6 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
7 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
8 |
9 | cd go-demo-6
10 |
11 | git checkout master
12 |
13 | # If GKE
14 | export REGISTRY_OWNER=$PROJECT
15 |
16 | # If EKS or AKS
17 | # Replace `[...]` with your GitHub user
18 | export REGISTRY_OWNER=[...]
19 |
20 | cat charts/go-demo-6/Makefile \
21 | | sed -e \
22 | "s@vfarcic@$REGISTRY_OWNER@g" \
23 | | sed -e \
24 | "s@devops-26@$REGISTRY_OWNER@g" \
25 | | tee charts/go-demo-6/Makefile
26 |
27 | cat charts/preview/Makefile \
28 | | sed -e \
29 | "s@vfarcic@$REGISTRY_OWNER@g" \
30 | | sed -e \
31 | "s@devops-26@$REGISTRY_OWNER@g" \
32 | | tee charts/preview/Makefile
33 |
34 | cat skaffold.yaml \
35 | | sed -e \
36 | "s@vfarcic@$REGISTRY_OWNER@g" \
37 | | sed -e \
38 | "s@devops-26@$REGISTRY_OWNER@g" \
39 | | tee skaffold.yaml
40 |
41 | jx import --batch-mode
42 |
43 | jx get activities \
44 | --filter go-demo-6 \
45 | --watch
46 |
47 | cd ..
48 |
49 | jx get applications
50 |
51 | jx create devpod --label go --batch-mode
52 |
53 | jx rsh -d
54 |
55 | cd go-demo-6
56 |
57 | curl -L \
58 | -o /usr/local/bin/jx-release-version \
59 | https://github.com/jenkins-x/jx-release-version/releases/download/v1.0.17/jx-release-version-linux
60 |
61 | chmod +x \
62 | /usr/local/bin/jx-release-version
63 |
64 | git tag
65 |
66 | jx-release-version
67 |
68 | git tag v1.0.0
69 |
70 | jx-release-version
71 |
72 | exit
73 |
74 | jx delete devpod
75 |
76 | git add .
77 |
78 | git commit \
79 | --message "Finally 1.0.0"
80 |
81 | git push
82 |
83 | jx get activities \
84 | --filter go-demo-6 \
85 | --watch
86 |
87 | jx get applications --env staging
88 |
89 | GH_USER=[...]
90 |
91 | open "https://github.com/$GH_USER/go-demo-6/releases"
92 |
93 | echo "A silly change" | tee README.md
94 |
95 | git add .
96 |
97 | git commit \
98 | --message "A silly change"
99 |
100 | git push
101 |
102 | jx get activity \
103 | --filter go-demo-6 \
104 | --watch
105 |
106 | cd ..
107 |
108 | GH_USER=[...]
109 |
110 | hub delete -y \
111 | $GH_USER/environment-jx-rocks-staging
112 |
113 | hub delete -y \
114 | $GH_USER/environment-jx-rocks-production
115 |
116 | rm -rf environment-jx-rocks-production
117 |
118 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
119 |
--------------------------------------------------------------------------------
/manuscript/12-prow.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/ac2407f0aab33e65e9ca8f247b6451bf
2 |
3 | # Links to gists for creating a cluster with jx
4 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
5 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
6 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
7 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
8 |
9 | GH_USER=[...]
10 |
11 | jx delete application \
12 | $GH_USER/jx-serverless \
13 | --batch-mode
14 |
15 | jx create quickstart \
16 | --filter golang-http \
17 | --project-name jx-prow \
18 | --batch-mode
19 |
20 | cd jx-prow
21 |
22 | jx get activities \
23 | --filter jx-prow \
24 | --watch
25 |
26 | git checkout -b chat-ops
27 |
28 | echo "ChatOps" | tee README.md
29 |
30 | git add .
31 |
32 | git commit \
33 | --message "My first PR with prow"
34 |
35 | git push --set-upstream origin chat-ops
36 |
37 | jx create pullrequest \
38 | --title "PR with prow" \
39 | --body "What I can say?" \
40 | --batch-mode
41 |
42 | git checkout master
43 |
44 | cat OWNERS
45 |
46 | GH_USER=[...]
47 |
48 | GH_APPROVER=[...]
49 |
50 | echo "approvers:
51 | - $GH_USER
52 | - $GH_APPROVER
53 | reviewers:
54 | - $GH_USER
55 | - $GH_APPROVER
56 | " | tee OWNERS
57 |
58 | git add .
59 |
60 | git commit \
61 | --message "Added an owner"
62 |
63 | git push
64 |
65 | open "https://github.com/$GH_USER/jx-prow/settings/collaboration"
66 |
67 | git checkout master
68 |
69 | git pull
70 |
71 | git checkout -b my-pr
72 |
73 | echo "My PR" | tee README.md
74 |
75 | git add .
76 |
77 | git commit \
78 | --message "My second PR with prow"
79 |
80 | git push --set-upstream origin my-pr
81 |
82 | jx create pullrequest \
83 | --title "My PR" \
84 | --body "What I can say?" \
85 | --batch-mode
86 |
87 | kubectl --namespace jx \
88 | describe cm plugins
89 |
90 | cd ..
91 |
92 | GH_USER=[...]
93 |
94 | hub delete -y \
95 | $GH_USER/environment-jx-rocks-staging
96 |
97 | hub delete -y \
98 | $GH_USER/environment-jx-rocks-production
99 |
100 | hub delete -y $GH_USER/jx-prow
101 |
102 | rm -rf jx-prow
103 |
104 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
105 |
--------------------------------------------------------------------------------
/manuscript/13-pipeline-extension-model.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/ca1d91973560dc0bd385c471437069ab
2 |
3 | # Links to gists for creating a cluster with jx
4 | # gke-jx-serverless.sh: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
5 | # eks-jx-serverless.sh: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
6 | # aks-jx-serverless.sh: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
7 | # install-serverless.sh: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
8 |
9 | GH_USER=[...]
10 |
11 | jx delete application \
12 | $GH_USER/jx-prow \
13 | --batch-mode
14 |
15 | cd go-demo-6
16 |
17 | git pull
18 |
19 | git checkout versioning-tekton
20 |
21 | git merge -s ours master --no-edit
22 |
23 | git checkout master
24 |
25 | git merge versioning-tekton
26 |
27 | git push
28 |
29 | cd ..
30 |
31 | cd go-demo-6
32 |
33 | # If GKE
34 | export REGISTRY_OWNER=$PROJECT
35 |
36 | # If EKS or AKS
37 | # Replace `[...]` with your GitHub user
38 | export REGISTRY_OWNER=[...]
39 |
40 | cat charts/go-demo-6/Makefile \
41 | | sed -e \
42 | "s@vfarcic@$REGISTRY_OWNER@g" \
43 | | sed -e \
44 | "s@devops-26@$REGISTRY_OWNER@g" \
45 | | tee charts/go-demo-6/Makefile
46 |
47 | cat charts/preview/Makefile \
48 | | sed -e \
49 | "s@vfarcic@$REGISTRY_OWNER@g" \
50 | | sed -e \
51 | "s@devops-26@$REGISTRY_OWNER@g" \
52 | | tee charts/preview/Makefile
53 |
54 | cat skaffold.yaml \
55 | | sed -e \
56 | "s@vfarcic@$REGISTRY_OWNER@g" \
57 | | sed -e \
58 | "s@devops-26@$REGISTRY_OWNER@g" \
59 | | tee skaffold.yaml
60 |
61 | cd ..
62 |
63 | cd go-demo-6
64 |
65 | jx import --batch-mode
66 |
67 | jx get activities \
68 | --filter go-demo-6 \
69 | --watch
70 |
71 | cd ..
72 |
73 | cd go-demo-6
74 |
75 | cat jenkins-x.yml
76 |
77 | buildPack: go
78 |
79 | open "https://github.com/jenkins-x-buildpacks/jenkins-x-kubernetes"
80 |
81 | curl "https://raw.githubusercontent.com/jenkins-x-buildpacks/jenkins-x-kubernetes/master/packs/go/pipeline.yaml"
82 |
83 | curl "https://raw.githubusercontent.com/jenkins-x-buildpacks/jenkins-x-classic/master/packs/go/pipeline.yaml"
84 |
85 | jx get activities \
86 | --filter go-demo-6 \
87 | --watch
88 |
89 | git checkout -b extension
90 |
91 | cat charts/go-demo-6/values.yaml \
92 | | sed -e \
93 | 's@replicaCount: 1@replicaCount: 3@g' \
94 | | tee charts/go-demo-6/values.yaml
95 |
96 | cat functional_test.go \
97 | | sed -e \
98 | 's@fmt.Sprintf("http://@fmt.Sprintf("@g' \
99 | | tee functional_test.go
100 |
101 | cat production_test.go \
102 | | sed -e \
103 | 's@fmt.Sprintf("http://@fmt.Sprintf("@g' \
104 | | tee production_test.go
105 |
106 | echo "buildPack: go
107 | pipelineConfig:
108 | pipelines:
109 | pullRequest:
110 | build:
111 | preSteps:
112 | - command: make unittest" \
113 | | tee jenkins-x.yml
114 |
115 | cat jenkins-x.yml
116 |
117 | git add .
118 |
119 | git commit \
120 | --message "Trying to extend the pipeline"
121 |
122 | git push --set-upstream origin extension
123 |
124 | jx create pullrequest \
125 | --title "Extensions" \
126 | --body "What I can say?" \
127 | --batch-mode
128 |
129 | PR_ADDR=[...] # e.g., `https://github.com/vfarcic/go-demo-6/pull/56`
130 |
131 | BRANCH=[...] # e.g., `PR-56`
132 |
133 | jx get build logs \
134 | --filter go-demo-6 \
135 | --branch $BRANCH
136 |
137 | echo 'functest:
138 | CGO_ENABLED=$(CGO_ENABLED) $(GO) \\
139 | test -test.v --run FunctionalTest \\
140 | --cover
141 | ' | tee -a Makefile
142 |
143 | echo ' promote:
144 | steps:
145 | - command: ADDRESS=`jx get preview --current 2>&1` make functest' | \
146 | tee -a jenkins-x.yml
147 |
148 | cat jenkins-x.yml
149 |
150 | git add .
151 |
152 | git commit \
153 | --message "Trying to extend the pipeline"
154 |
155 | git push
156 |
157 | jx get build logs \
158 | --filter go-demo-6 \
159 | --branch $BRANCH
160 |
161 | echo ' - command: ADDRESS=http://this-domain-does-not-exist.com make functest' | \
162 | tee -a jenkins-x.yml
163 |
164 | git add .
165 |
166 | git commit \
167 | --message "Added sully tests"
168 |
169 | git push
170 |
171 | jx get build logs \
172 | --filter go-demo-6 \
173 | --branch $BRANCH
174 |
175 | open "$PR_ADDR"
176 |
177 | cat jenkins-x.yml \
178 | | sed '$ d' \
179 | | tee jenkins-x.yml
180 |
181 | git add .
182 |
183 | git commit \
184 | --message "Removed the silly test"
185 |
186 | git push
187 |
188 | cd ..
189 |
190 | GH_USER=[...]
191 |
192 | git clone \
193 | https://github.com/$GH_USER/environment-jx-rocks-staging.git
194 |
195 | cd environment-jx-rocks-staging
196 |
197 | cat jenkins-x.yml
198 |
199 | curl https://raw.githubusercontent.com/jenkins-x-buildpacks/jenkins-x-kubernetes/master/packs/environment/pipeline.yaml
200 |
201 | cat jenkins-x.yml \
202 | | sed -e \
203 | 's@pipelines: {}@pipelines:\
204 | release:\
205 | postBuild:\
206 | steps:\
207 | - command: echo "Running integ tests!!!"@g' \
208 | | tee jenkins-x.yml
209 |
210 | cat jenkins-x.yml
211 |
212 | git add .
213 |
214 | git commit \
215 | --message "Added integ tests"
216 |
217 | git push
218 |
219 | jx get build logs \
220 | --filter environment-jx-rocks-staging \
221 | --branch master
222 |
223 | open "$PR_ADDR"
224 |
225 | cd ..
226 |
227 | GH_USER=[...]
228 |
229 | hub delete -y \
230 | $GH_USER/environment-jx-rocks-staging
231 |
232 | hub delete -y \
233 | $GH_USER/environment-jx-rocks-production
234 |
235 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
236 |
237 | rm -rf environment-jx-rocks-staging
238 |
--------------------------------------------------------------------------------
/manuscript/14-upgrade.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/00404a74924beadda4143ac26e8fbaa1
2 |
3 | # Links to gists for creating Jenkins X cluster
4 | # gke-jx-serverless.sh: https://gist.github.com/a04269d359685bbd00a27643b5474ace
5 | # eks-jx-serverless.sh: https://gist.github.com/69a4cbc65d8cb122d890add5997c463b
6 | # aks-jx-serverless.sh: https://gist.github.com/a7cb7a28b7e84590fbb560b16a0ee98c
7 | # install-serverless.sh: https://gist.github.com/f592c72486feb0fb1301778de08ba31d
8 |
9 | open "https://github.com/jenkins-x/jenkins-x-versions"
10 |
11 | PLATFORM_VERSION=[...]
12 |
13 | NAMESPACE=$(kubectl config view \
14 | --minify \
15 | --output jsonpath="{..namespace}")
16 |
17 | cd go-demo-6
18 |
19 | git pull
20 |
21 | git checkout extension-model-$NAMESPACE
22 |
23 | git merge -s ours master --no-edit
24 |
25 | git checkout master
26 |
27 | git merge extension-model-$NAMESPACE
28 |
29 | git push
30 |
31 | cd ..
32 |
33 | cd go-demo-6
34 |
35 | jx import --pack go --batch-mode
36 |
37 | cd ..
38 |
39 | jx version
40 |
41 | jx upgrade platform --help
42 |
43 | jx upgrade platform --batch-mode
44 |
45 | jx version
46 |
47 | jx get addons
48 |
49 | jx upgrade addons
50 |
51 | jx get addons
52 |
53 | jx get applications
54 |
55 | STAGING_ADDR=[...]
56 |
57 | curl "$STAGING_ADDR/demo/hello"
58 |
59 | LB_IP=$(kubectl \
60 | --namespace kube-system \
61 | get svc jxing-nginx-ingress-controller \
62 | -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
63 |
64 | echo $LB_IP
65 |
66 | DOMAIN=$LB_IP.nip.io
67 |
68 | DOMAIN=[...]
69 |
70 | jx upgrade ingress \
71 | --cluster true \
72 | --domain $DOMAIN
73 |
74 | jx get applications --env staging
75 |
76 | STAGING_ADDR=[...]
77 |
78 | curl "$STAGING_ADDR/demo/hello"
79 |
80 | cd go-demo-6
81 |
82 | jx repo --batch-mode
83 |
84 | echo "I am too lazy to write a README" \
85 | | tee README.md
86 |
87 | git add .
88 |
89 | git commit -m "Checking webhooks"
90 |
91 | git push
92 |
93 | jx get activities \
94 | --filter go-demo-6 \
95 | --watch
96 |
97 | jx get applications --env staging
98 |
99 | NAMESPACE=$(kubectl config view \
100 | --minify \
101 | --output jsonpath="{..namespace}")
102 |
103 | jx upgrade ingress \
104 | --namespaces $NAMESPACE-staging \
105 | --urltemplate "{{.Service}}.staging.{{.Domain}}"
106 |
107 | jx get applications --env staging
108 |
109 | VERSION=[...]
110 |
111 | STAGING_ADDR=[...]
112 |
113 | curl "$STAGING_ADDR/demo/hello"
114 |
115 | jx promote go-demo-6 \
116 | --version $VERSION \
117 | --env production \
118 | --batch-mode
119 |
120 | jx get applications --env production
121 |
122 | jx upgrade ingress \
123 | --domain $DOMAIN \
124 | --namespaces $NAMESPACE-production \
125 | --urltemplate "{{.Service}}.{{.Domain}}"
126 |
127 | jx get applications --env production
128 |
129 | cd ..
130 |
131 | GH_USER=[...]
132 |
133 | ENVIRONMENT=[...]
134 |
135 | hub delete -y \
136 | $GH_USER/environment-tekton-staging
137 |
138 | hub delete -y \
139 | $GH_USER/environment-tekton-production
140 |
141 | rm -rf environment-tekton-production
142 |
143 | rm -rf ~/.jx/environments/$GH_USER/environment-tekton-*
144 |
--------------------------------------------------------------------------------
/manuscript/18-boot.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/8af2cdfe9ffad2beac9c1e89cf863a46
2 |
3 | # Links to gists for creating a Kubernetes cluster
4 | # gke.sh: https://gist.github.com/1b7a1c833bae1d5da02f4fd7b3cd3c17
5 | # eks.sh: https://gist.github.com/3eaa9b10cb59424fc0447a563112f32e
6 |
7 | open "https://github.com/jenkins-x/jenkins-x-boot-config"
8 |
9 | CLUSTER_NAME=[...] # e.g., jx-gke
10 |
11 | GH_USER=[...]
12 |
13 | git clone \
14 | https://github.com/jenkins-x/jenkins-x-boot-config.git \
15 | environment-$CLUSTER_NAME-dev
16 |
17 | cd environment-$CLUSTER_NAME-dev
18 |
19 | cat jx-requirements.yml
20 |
21 | # Open requirements.yaml in an editor
22 |
23 | # Set `cluster.clusterName`
24 | # Set `cluster.environmentGitOwner`
25 | # Set `cluster.project` (if GKE)
26 | # Set `cluster.provider
27 | # Set `cluster.zone`
28 | # Set `secretStorage` to `vault`
29 | # Set `storage.logs.enabled` to `true`
30 | # Set `storage.reports.enabled` to `true`
31 | # Set `storage.repository.enabled` to `true`
32 |
33 | # If EKS
34 | export IAM_USER=[...] # e.g., jx-boot
35 |
36 | # If EKS
37 | echo "vault:
38 | aws:
39 | autoCreate: true
40 | iamUserName: \"$IAM_USER\"" \
41 | | tee -a jx-requirements.yml
42 |
43 | # If EKS
44 | cat jx-requirements.yml \
45 | | sed -e \
46 | 's@zone@region@g' \
47 | | tee jx-requirements.yml
48 |
49 | cat jx-requirements.yml
50 |
51 | jx boot
52 |
53 | git --no-pager diff origin/master..HEAD
54 |
55 | cat env/parameters.yaml
56 |
57 | cat jenkins-x.yml
58 |
59 | cat jx-requirements.yml
60 |
61 | jx get pipelines -o yaml
62 |
63 | echo "A trivial change" \
64 | | tee -a README.md
65 |
66 | git add .
67 |
68 | git commit -m "A trivial change"
69 |
70 | git push
71 |
72 | jx get activities \
73 | --filter environment-$CLUSTER_NAME-dev \
74 | --watch
75 |
76 | kubectl get namespaces
77 |
78 | jx get env
79 |
80 | cd ..
81 |
82 | jx create quickstart \
83 | --filter golang-http
84 |
85 | jx get activity \
86 | --filter jx-boot/master \
87 | --watch
88 |
89 | jx get activity \
90 | --filter environment-$CLUSTER_NAME-staging/master \
91 | --watch
92 |
93 | kubectl get namespaces
94 |
95 | hub delete -y \
96 | $GH_USER/environment-$CLUSTER_NAME-staging
97 |
98 | hub delete -y \
99 | $GH_USER/environment-$CLUSTER_NAME-production
100 |
101 | hub delete -y \
102 | $GH_USER/jx-boot
103 |
104 | rm -rf jx-boot
105 |
--------------------------------------------------------------------------------
/manuscript/20-ui.sh:
--------------------------------------------------------------------------------
1 | # Links to gists for creating a Kubernetes cluster with Jenkins X
2 | # gke-jx-boot.sh: https://gist.github.com/1eff2069aa68c4aee29c35b94dd9467f
3 |
4 | jx add app jx-app-ui
5 |
6 | jx get activities \
7 | --filter environment-$CLUSTER_NAME-dev/master \
8 | --watch
9 |
10 | UI_ADDR=$(kubectl get ing jxui \
11 | --output jsonpath="{.spec.rules[0].host}")
12 |
13 | open "http://$UI_ADDR"
14 |
15 | GH_USER=[...]
16 |
17 | hub delete -y \
18 | $GH_USER/environment-$CLUSTER_NAME-staging
19 |
20 | hub delete -y \
21 | $GH_USER/environment-$CLUSTER_NAME-production
22 |
--------------------------------------------------------------------------------
/manuscript/99-cloudbees.md:
--------------------------------------------------------------------------------
1 | ```bash
2 | jx create addon cloudbees --basic
3 |
4 | jx cloudbees
5 | ```
--------------------------------------------------------------------------------
/manuscript/99-deploy-avanced.md:
--------------------------------------------------------------------------------
1 | ```bash
2 | cd k8s-specs
3 |
4 | git pull
5 |
6 | minikube start --vm-driver=virtualbox
7 |
8 | minikube addons enable ingress
9 |
10 | kubectl config current-context
11 |
12 | cat deploy/go-demo-3-bg.yml
13 |
14 | kubectl create -f deploy/go-demo-3-bg.yml
15 |
16 | IP=$(minikube ip)
17 |
18 | PORT=$(kubectl get svc go-demo-3-api \
19 | -o jsonpath="{.spec.ports[0].nodePort}")
20 |
21 | curl -i "http://$IP:$PORT/demo/hello"
22 |
23 | kubectl set image \
24 | -f deploy/go-demo-3-db.yml \
25 | db=mongo:3.4 \
26 | --record
27 |
28 | kubectl get deployments \
29 | -l service=go-demo-3,type=api
30 |
31 | # TODO: Continue
32 |
33 | minikube delete
34 | ```
35 |
36 | ## TODO
37 |
38 | - [ ] Code
39 | - [ ] Write
40 | - [ ] Compare with Swarm
41 | - [ ] Text Review
42 | - [ ] Diagrams
43 | - [ ] Code Review
44 | - [ ] Gist
45 | - [ ] Review the title
46 | - [ ] Proofread
47 | - [ ] Add to Book.txt
48 | - [ ] Publish on LeanPub.com
49 | - [ ] Publish on TechnologyConversations.com
--------------------------------------------------------------------------------
/manuscript/99-git-server.md:
--------------------------------------------------------------------------------
1 | ## TODO
2 |
3 | - [ ] Code
4 | - [ ] Write
5 | - [ ] Code review static GKE
6 | - [ ] Code review serverless GKE
7 | - [ ] Code review static EKS
8 | - [ ] Code review serverless EKS
9 | - [ ] Code review static AKS
10 | - [ ] Code review serverless AKS
11 | - [ ] Code review existing static cluster
12 | - [ ] Code review existing serverless cluster
13 | - [ ] Text review
14 | - [ ] Gist
15 | - [ ] Review titles
16 | - [ ] Proofread
17 | - [ ] Diagrams
18 | - [ ] Add to slides
19 | - [ ] Publish on TechnologyConversations.com
20 | - [ ] Add to Book.txt
21 | - [ ] Publish on LeanPub.com
22 |
23 | # Git Servers
24 |
25 | TODO: Use `--git-provider-kind` with `jx create cluster` and `jx install`
26 | TODO: Try with `--no-default-environments`
27 |
28 | ## Creating A Kubernetes Cluster With Jenkins X
29 |
30 | TODO: Repos other than GitHub do not yet work with serverless.
31 |
32 | TODO: Rewrite
33 |
34 | W> You might be used to the fact that until now we were always using the same Gists to create a cluster or install Jenkins X in an existing one. Those that follow are different.
35 |
36 | If you kept the cluster from the previous chapter and it contains serverless Jenkinss X, you can skip this section. Otherwise, we'll need to create a new Jenkins X cluster.
37 |
38 | I> All the commands from this chapter are available in the [TODO:](TODO:) Gist.
39 |
40 | For your convenience, the Gists that will create a new Jenkins X cluster or install it inside an existing one are as follows.
41 |
42 | * Create a new **GKE** cluster: [gke-jx-serverless.sh](https://gist.github.com/a04269d359685bbd00a27643b5474ace)
43 | * Create a new **EKS** cluster: [eks-jx-serverless.sh](https://gist.github.com/69a4cbc65d8cb122d890add5997c463b)
44 | * Create a new **AKS** cluster: [aks-jx-serverless.sh](https://gist.github.com/a7cb7a28b7e84590fbb560b16a0ee98c)
45 | * Use an **existing** cluster: [install-serverless.sh](https://gist.github.com/f592c72486feb0fb1301778de08ba31d)
46 |
47 | Now we can explore TODO:.
48 |
49 | ## Git
50 |
51 | ```bash
52 | jx create quickstart \
53 | --filter golang-http \
54 | --project-name jx-git \
55 | --batch-mode
56 |
57 | cd jx-git
58 |
59 | jx get activities \
60 | --filter jx-git \
61 | --watch
62 |
63 | jx get git
64 |
65 | # It could be `bitbucket`, `bitbucketcloud`, `github` Enterprise, etc
66 | jx create git server \
67 | --kind gitlab \
68 | --name gitlab \
69 | --url https://gitlab.com
70 |
71 | jx get git
72 |
73 | API_TOKEN=[...]
74 |
75 | GITLAB_USER=[...]
76 |
77 | jx create git token \
78 | --name gitlab \
79 | --api-token $API_TOKEN \
80 | $GITLAB_USER
81 |
82 | jx create env \
83 | --name pre-production \
84 | --label Pre-Production \
85 | --namespace jx-pre-production \
86 | --promotion Auto \
87 | --git-provider-kind gitlab \
88 | --git-username $GITLAB_USER \
89 | --batch-mode
90 |
91 | echo "Something else" | tee README.md
92 |
93 | git add .
94 |
95 | git commit \
96 | --message "Testing the new repo"
97 |
98 | git push
99 |
100 | jx get activities \
101 | --filter jx-git \
102 | --watch
103 |
104 | # TODO: Merge of pre-prod to master is not automatic and it hangs indefinitely when merged manually. Maybe it's related to https://github.com/jenkins-x/jx/issues/2410, https://github.com/jenkins-x/jx/issues/3788
105 |
106 | # Change an env.
107 |
108 | # Create a new app in GitLab
109 | ```
110 |
111 | ## What Now?
112 |
113 | TODO: Rewrite
114 |
115 | Now you need to decide whether to continue using the cluster or to destroy it. If you choose to destroy it or to uninstall Jenkins X, you'll find the instructions at the bottom of the Gist you chose at the beginning of this chapter.
116 |
117 | If you destroyed the cluster or you uninstalled Jenkins X, please remove the repositories and the local files we created. You can use the commands that follow for that.
118 |
119 | W> Please replace `[...]` with your GitHub user before executing the commands that follow.
120 |
121 | ```bash
122 | cd ..
123 |
124 | GH_USER=[...]
125 |
126 | hub delete -y \
127 | $GH_USER/environment-jx-rocks-staging
128 |
129 | hub delete -y \
130 | $GH_USER/environment-jx-rocks-production
131 |
132 | hub delete -y $GH_USER/jx-git
133 |
134 | rm -rf environment-jx-rocks-production
135 |
136 | rm -rf jx-git
137 |
138 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
139 |
140 | # TODO: Delete environment-jx-pre-production manually
141 | ```
142 |
--------------------------------------------------------------------------------
/manuscript/99-gitlab.md:
--------------------------------------------------------------------------------
1 | ```bash
2 | # Create a Kubernetes cluster
3 |
4 | # Install Ingress
5 |
6 | # Install tiller
7 |
8 | helm repo add gitlab https://charts.gitlab.io/
9 |
10 | helm repo update
11 |
12 | LB_IP=[...] # Replace `[...]` with the IP of your load balancer
13 |
14 | helm upgrade --install gitlab gitlab/gitlab \
15 | --namespace gitlab \
16 | --set global.hosts.domain=$LB_IP.nip.io \
17 | --set global.hosts.https=false \
18 | --values helm/gitlab-values.yaml \
19 | --timeout 900 --wait
20 |
21 | kubectl -n gitlab get secret \
22 | gitlab-gitlab-initial-root-password \
23 | -o jsonpath="{.data.password}" \
24 | | base64 --decode; echo
25 |
26 | # Copy the output
27 |
28 | open "http://gitlab.$LB_IP.nip.io"
29 |
30 | # Sign in with user `root` and the password from the copied output
31 |
32 | # Navigate to gravar > "Settings"
33 | # Select "Access Token" from the left-hand menu
34 | # Type `jx` as the Name, select the *api* checkbox
35 | # Click the *Create personal access token* button
36 |
37 | GL_TOKEN=[...] # Replace `[...]` with the token
38 |
39 | # jx create git server \
40 | # -k gitlab \
41 | # -n gitlab \
42 | # -u http://gitlab.$LB_IP.nip.io/
43 |
44 | PROVIDER=[...] # Change `[...]` to t your k8s provider (e.g., `aks`, `eks`, `gke`)
45 |
46 | INGRESS_NS=ingress-nginx
47 |
48 | INGRESS_DEP=nginx-ingress-controller
49 |
50 | # The command that follows uses `-b` to run in the batch mode and it assumes that this is not the first time you create a cluster with `jx`.
51 | # If that's not the case and this is indeed the first time you're creating a `jx` cluster, it will not have some of the default values like GitHub user and the installation might fail.
52 |
53 | jx install \
54 | --provider $PROVIDER \
55 | --external-ip $LB_IP \
56 | --domain jenkinx.$LB_IP.nip.io \
57 | --default-admin-password=admin \
58 | --ingress-namespace $INGRESS_NS \
59 | --ingress-deployment $INGRESS_DEP \
60 | --tiller-namespace kube-system \
61 | --default-environment-prefix jx-rocks \
62 | --git-provider-kind gitlab \
63 | --git-provider-url http://gitlab.$LB_IP.nip.io \
64 | --git-username root \
65 | --git-api-token $GL_TOKEN \
66 | -b
67 |
68 | # TODO: Switch to prow
69 |
70 | # Paste the token when asked for `API Token`
71 |
72 | open "http://jenkinx.$LB_IP.nip.io"
73 | ```
--------------------------------------------------------------------------------
/manuscript/99-integration-with-uptimerobot.md:
--------------------------------------------------------------------------------
1 | ```bash
2 |
3 | ```
--------------------------------------------------------------------------------
/manuscript/99-jenkins-prometheus.md:
--------------------------------------------------------------------------------
1 | ## Jenkins
2 |
3 | ```bash
4 | JENKINS_ADDR=jenkins.$LB_IP.nip.io
5 |
6 | # TODO: Add prometheus plugin to the values
7 |
8 | helm install helm/jenkins \
9 | --name jenkins \
10 | --namespace cd \
11 | --set jenkins.Master.HostName=$JENKINS_ADDR \
12 | --set jenkins.Master.CredentialsXmlSecret="" \
13 | --set jenkins.Master.SecretsFilesSecret=""
14 |
15 | kubectl -n cd \
16 | rollout status \
17 | deployment jenkins
18 |
19 | JENKINS_PASS=$(kubectl -n cd \
20 | get secret jenkins \
21 | -o jsonpath="{.data.jenkins-admin-password}" \
22 | | base64 --decode; echo)
23 |
24 | echo $JENKINS_PASS
25 |
26 | open "http://$JENKINS_ADDR"
27 | ```
28 |
--------------------------------------------------------------------------------
/manuscript/99-minishift.md:
--------------------------------------------------------------------------------
1 | ## CJE2
2 |
3 | ```bash
4 | brew cask install minishift
5 |
6 | brew install openshift-cli
7 |
8 | minishift start \
9 | --memory 10240 \
10 | --disk-size 20480 \
11 | --cpus 3
12 |
13 | IP=$(minishift ip)
14 |
15 | echo $IP
16 |
17 | NAME=$(echo $IP | tr '.' '-')
18 |
19 | echo $NAME
20 |
21 | open "https://$IP:8443"
22 |
23 | # Ignore SSL warning
24 |
25 | # User/pass = developer/developer or admin/admin
26 |
27 | oc config get-contexts
28 |
29 | oc config set current-context \
30 | default/$NAME:8443/system:admin
31 |
32 | open "https://downloads.cloudbees.com/cje2/latest/"
33 |
34 | # Copy the link to cje2_*openshift.tgz
35 |
36 | RELEASE_URL=[...]
37 |
38 | curl -o cje.tgz $RELEASE_URL
39 |
40 | tar -xvf cje.tgz
41 |
42 | cd cje2-openshift
43 |
44 | ls -l
45 |
46 | cat cje.yml
47 |
48 | oc create ns cje
49 |
50 | CJE_DNS=cjoc-cje.$IP.nip.io
51 |
52 | echo $CJE_DNS
53 |
54 | oc get pv
55 |
56 | oc describe pv pv0010
57 |
58 | cat cje.yml
59 |
60 | cat cje.yml \
61 | | sed -e \
62 | "s@insecureEdgeTerminationPolicy: Redirect@insecureEdgeTerminationPolicy: Allow@g" \
63 | | sed -e \
64 | "s@https://cje.example.com@http://$CJE_DNS@g" \
65 | | sed -e \
66 | "s@namespace: myproject@namespace: cje@g" \
67 | | oc -n cje \
68 | create -f - --save-config --record
69 |
70 | oc -n cje rollout status sts cjoc
71 |
72 | oc -n cje get all
73 |
74 | oc get pv | grep Bound
75 |
76 | open "http://$CJE_DNS/cjoc"
77 |
78 | oc -n cje exec cjoc-0 -- \
79 | cat /var/jenkins_home/secrets/initialAdminPassword
80 |
81 | # TODO: Create a master with 1GB and 0.5 CPU
82 |
83 | oc -n cje get events -w
84 |
85 | oc -n cje get all
86 |
87 | oc get pv | grep Bound
88 |
89 | # TODO: Create a new Pipeline job called *my-job*
90 | ```
91 |
92 | ```groovy
93 | podTemplate(
94 | label: 'kubernetes',
95 | containers: [
96 | containerTemplate(name: 'maven', image: 'maven:alpine', ttyEnabled: true, command: 'cat'),
97 | containerTemplate(name: 'golang', image: 'golang:alpine', ttyEnabled: true, command: 'cat')
98 | ]
99 | ) {
100 | node('kubernetes') {
101 | container('maven') {
102 | stage('build') {
103 | sh 'mvn --version'
104 | }
105 | stage('unit-test') {
106 | sh 'java -version'
107 | }
108 | }
109 | container('golang') {
110 | stage('deploy') {
111 | sh 'go version'
112 | }
113 | }
114 | }
115 | }
116 | ```
117 |
118 | ```bash
119 | # TODO: Run the job *my-job*
120 |
121 | oc -n cje get pods
122 |
123 | # TODO: Present different stages of the *jenkins-slave-* Pod
124 |
125 | # TODO: Display the results in UI
126 |
127 | # TODO: Delete a master
128 |
129 | oc get pv
130 |
131 | # oc create ns build
132 |
133 | # Update the job
134 | ```
135 |
136 | ## What Now?
137 |
138 | ```bash
139 | minishift delete -f --clear-cache
140 |
141 | kubectl config delete-cluster $NAME:8443
142 |
143 | kubectl config delete-cluster 127-0-0-1:8443
144 |
145 | kubectl config delete-context /$NAME:8443/developer
146 |
147 | kubectl config delete-context default/$NAME:8443/system:admin
148 |
149 | kubectl config delete-context minishift
150 |
151 | kubectl config delete-context myproject/$NAME:8443/developer
152 |
153 | kubectl config delete-context myproject/$NAME:8443/system:admin
154 |
155 | kubectl config delete-context default/127-0-0-1:8443/system:admin
156 |
157 | kubectl config unset users.developer/$NAME:8443
158 |
159 | kubectl config unset users.system:admin/$NAME:8443
160 |
161 | kubectl config unset users.system:admin/127-0-0-1:8443
162 |
163 | kubectl config view
164 | ```
--------------------------------------------------------------------------------
/manuscript/99-multi-cluster.md:
--------------------------------------------------------------------------------
1 | https://jenkins-x.io/getting-started/multi-cluster/
--------------------------------------------------------------------------------
/manuscript/99-nfs.md:
--------------------------------------------------------------------------------
1 | ```bash
2 | cd storage/nfs
3 |
4 | vagrant up nfs
5 |
6 | vagrant ssh nfs
7 |
8 | sudo apt-get update
9 |
10 | sudo apt-get install -y \
11 | nfs-kernel-server
12 |
13 | sudo mkdir /var/nfs/general -p
14 |
15 | sudo chown nobody:nogroup /var/nfs/general
16 |
17 | echo "/var/nfs/general *(rw,sync,no_subtree_check)" \
18 | | sudo tee -a /etc/exports
19 |
20 | sudo systemctl restart nfs-kernel-server
21 |
22 | sudo ufw status # If should be inactive
23 |
24 | # sudo ufw allow from * to any port nfs
25 |
26 | # sudo ufw status
27 |
28 | exit
29 |
30 | # Create a cluster
31 |
32 | kubectl create \
33 | -f https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/auth/serviceaccount.yaml
34 |
35 | kubectl create \
36 | -f https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/auth/clusterrole.yaml
37 |
38 | kubectl create \
39 | -f https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/auth/clusterrolebinding.yaml
40 |
41 | NFS_SERVER_ADDR=[...]
42 |
43 | curl https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/deployment.yaml \
44 | | sed -e "s@10.10.10.60@$NFS_SERVER_ADDR@g" \
45 | | sed -e "s@/ifs/kubernetes@/var/nfs/general@g" \
46 | | kubectl create -f -
47 |
48 | # kubectl patch deployment nfs-client-provisioner \
49 | # -p '{"spec":{"template":{"spec":{"serviceAccount":"nfs-client-provisioner"}}}}'
50 |
51 | kubectl create \
52 | -f https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/class.yaml
53 |
54 | kubectl create \
55 | -f https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/test-claim.yaml
56 |
57 | kubectl create \
58 | -f https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/test-pod.yaml
59 |
60 | # Confirm that the file was created in the NFS server
61 |
62 | kubectl delete \
63 | -f https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/test-pod.yaml
64 |
65 | kubectl delete \
66 | -f https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/test-claim.yaml
67 |
68 | # Confirm that the folder renamed to archived-???
69 | ```
--------------------------------------------------------------------------------
/manuscript/99-pipeline-from-scratch.md:
--------------------------------------------------------------------------------
1 | ## TODO
2 |
3 | - [ ] Code
4 | - [ ] Write
5 | - [X] Code review static GKE
6 | - [ ] Code review serverless GKE
7 | - [ ] Code review static EKS
8 | - [ ] Code review serverless EKS
9 | - [ ] Code review static AKS
10 | - [ ] Code review serverless AKS
11 | - [ ] Code review existing static cluster
12 | - [ ] Code review existing serverless cluster
13 | - [ ] Text review
14 | - [ ] Gist
15 | - [ ] Review titles
16 | - [ ] Proofread
17 | - [ ] Diagrams
18 | - [ ] Add to slides
19 | - [ ] Publish on TechnologyConversations.com
20 | - [ ] Add to Book.txt
21 | - [ ] Publish on LeanPub.com
22 |
23 | # Serverless Pipelines From Scratch
24 |
25 | ## Creating A Kubernetes Cluster With Jenkins X
26 |
27 | TODO: Viktor: This text is from some other change. Rewrite it.
28 |
29 | If you kept the cluster from the previous chapter, you can skip this section. Otherwise, we'll need to create a new Jenkins X cluster.
30 |
31 | I> All the commands from this chapter are available in the [TODO: Viktor](TODO: Viktor) Gist.
32 |
33 | For your convenience, the Gists from the previous chapter are available below as well.
34 |
35 | * Create a new **GKE** cluster: [gke-jx-serverless.sh](https://gist.github.com/a04269d359685bbd00a27643b5474ace)
36 | * Create a new **EKS** cluster: [eks-jx-serverless.sh](https://gist.github.com/69a4cbc65d8cb122d890add5997c463b)
37 | * Create a new **AKS** cluster: [aks-jx-serverless.sh](https://gist.github.com/a7cb7a28b7e84590fbb560b16a0ee98c)
38 | * Use an **existing** cluster: [install-serverless.sh](https://gist.github.com/f592c72486feb0fb1301778de08ba31d)
39 |
40 | TODO: Intro to the next section
41 |
42 | ## Something
43 |
44 | TODO: devops-toolkit repo README.md
45 |
46 | ## What Now?
47 |
48 | TODO: Viktor: Rewrite
49 |
50 | Now is a good time for you to take a break.
51 |
52 | If you created a cluster only for the purpose of the exercises we executed, please destroy it. We'll start the next, and each other chapter from scratch as a way to save you from running your cluster longer than necessary and pay more than needed to your hosting vendor. If you created the cluster or installed Jenkins X using one of the Gists from the beginning of this chapter, you'll find the instructions on how to destroy the cluster or uninstall everything at the bottom.
53 |
54 | If you did choose to destroy the cluster or to uninstall Jenkins X, please remove the repositories we created as well as the local files. You can use the commands that follow for that. Just remember to replace `[...]` with your GitHub user.
55 |
56 | ```bash
57 | cd ..
58 |
59 | GH_USER=[...]
60 |
61 | hub delete -y \
62 | $GH_USER/environment-tekton-staging
63 |
64 | hub delete -y \
65 | $GH_USER/environment-tekton-production
66 |
67 | rm -rf ~/.jx/environments/$GH_USER/environment-tekton-*
68 | ```
69 |
70 | Finally, you might be planning to move into the next chapter right away. If that's the case, there are no cleanup actions to do. Just keep reading.
71 |
--------------------------------------------------------------------------------
/manuscript/99-rbac.md:
--------------------------------------------------------------------------------
1 | ```bash
2 |
3 | ```
4 |
5 | ## What Now?
6 |
7 | ```bash
8 | cd ..
9 |
10 | GH_USER=[...]
11 |
12 | hub delete -y \
13 | $GH_USER/environment-jx-rocks-staging
14 |
15 | hub delete -y \
16 | $GH_USER/environment-jx-rocks-production
17 |
18 | rm -rf ~/.jx/environments/$GH_USER/environment-jx-rocks-*
19 | ```
--------------------------------------------------------------------------------
/manuscript/99-registry.md:
--------------------------------------------------------------------------------
1 | ## Create a cluster and a registry
2 |
3 | ```bash
4 | export RANDOM_STRING=$(date +%Y%m%d%H%M%S)
5 |
6 | export RESOURCE_GROUP=rg-$RANDOM_STRING
7 |
8 | export ACR_NAME=acr$RANDOM_STRING
9 |
10 | export CLUSTER_NAME=aks-$RANDOM_STRING
11 |
12 | # NOTE: Using `az`, but it should be `terraform`
13 |
14 | az group create \
15 | --name $RESOURCE_GROUP \
16 | --location eastus
17 |
18 | az acr create \
19 | --name $ACR_NAME \
20 | --resource-group $RESOURCE_GROUP \
21 | --sku basic
22 |
23 | az aks get-versions --location eastus
24 |
25 | export K8S_VERSION=[...]
26 |
27 | az aks create \
28 | --name $CLUSTER_NAME \
29 | --resource-group $RESOURCE_GROUP \
30 | --generate-ssh-keys \
31 | --attach-acr $ACR_NAME \
32 | --node-count 3 \
33 | --node-vm-size Standard_A2_v2 \
34 | --enable-cluster-autoscaler \
35 | --max-count 6
36 | --min-count 3
37 |
38 | az aks get-credentials \
39 | --resource-group $RESOURCE_GROUP \
40 | --name $CLUSTER_NAME \
41 | --file kubeconfig
42 |
43 | export KUBECONFIG=$PWD/kubeconfig
44 |
45 | kubectl get nodes
46 | ```
47 |
48 | ## Test the registry from a laptop
49 |
50 | ```bash
51 | export ACR_SERVER=$ACR_NAME.azurecr.io
52 |
53 | az acr login --name $ACR_NAME
54 |
55 | docker image pull alpine
56 |
57 | docker image tag alpine $ACR_SERVER/alpine
58 |
59 | docker image push $ACR_SERVER/alpine
60 | ```
61 |
62 | ## Test the registry from the cluster
63 |
64 | ```bash
65 | kubectl run alpine \
66 | --image $ACR_SERVER/alpine \
67 | --generator run-pod/v1 \
68 | -- sleep 10000
69 |
70 | kubectl get pods
71 | ```
72 |
73 | ## Install JX
74 |
75 | ```bash
76 | git clone \
77 | https://github.com/jenkins-x/jenkins-x-boot-config.git \
78 | environment-$CLUSTER_NAME-dev
79 |
80 | cd environment-$CLUSTER_NAME-dev
81 |
82 | export GH_OWNER=[...] # Replace `[...]` with the GitHub owner
83 |
84 | cat jx-requirements.yml \
85 | | sed -e "s@clusterName: \"\"@clusterName: $CLUSTER_NAME@g" \
86 | | sed -e "s@environmentGitOwner: \"\"@environmentGitOwner: $GH_OWNER@g" \
87 | | sed -e "s@provider: gke@provider: kubernetes\\
88 | registry: $ACR_SERVER@g" \
89 | | tee jx-requirements.yml
90 |
91 | cat ~/.docker/config.json
92 |
93 | export REGISTRY_AUTH=[...] # Replace `[...]` with the `auth` value from `~/.docker/config.json`
94 |
95 | export REGISTRY_IDENTITYTOKEN=[...] # Replace `[...]` with the `identitytoken` value from `~/.docker/config.json`
96 |
97 | mkdir -p ~/.jx/localSecrets/$CLUSTER_NAME
98 |
99 | echo "registry_auth: \"$REGISTRY_AUTH\"
100 | registry_identitytoken: \"$REGISTRY_IDENTITYTOKEN\"" \
101 | | tee ~/.jx/localSecrets/$CLUSTER_NAME/registry.yaml
102 |
103 | echo "jenkins-x-platform:
104 | PipelineSecrets:
105 | DockerConfig: |-
106 | {
107 | \"auths\":{
108 | \"$ACR_SERVER\":
109 | {
110 | \"auth\": {{ .Parameters.registry.registry_auth | quote}},
111 | \"identitytoken\": {{ .Parameters.registry.registry_identitytoken | quote}}
112 | }
113 | }
114 | }
115 | docker-registry:
116 | enabled: false" \
117 | | tee kubeProviders/kubernetes/values.tmpl.yaml
118 |
119 | # The `env/parameters.yaml` file does not exist.
120 | # It is created only after the boot is run so we cannot modify it right away.
121 | # TODO: Provide means to add values to `env/parameters.yaml` without running `jx boot`.
122 |
123 | jx boot
124 |
125 | # It will fail in the `install-jenkins-x` step
126 |
127 | echo "registry:
128 | registry_auth: local:$CLUSTER_NAME/registry:registry_auth
129 | registry_identitytoken: local:$CLUSTER_NAME/registry:registry_identitytoken" \
130 | | tee -a env/parameters.yaml
131 |
132 | jx boot --start-step install-jenkins-x
133 |
134 | # Subsequential executions of the boot eliminate the additions to `env/parameters.yaml`.
135 | # TODO: Figure out a different way to provide that info, or stop recreating `env/parameters.yaml`.
136 | ```
137 |
138 | ## Validate JX setup
139 |
140 | ```bash
141 | kubectl get secret jenkins-docker-cfg -o yaml
142 |
143 | export CONFIG_JSON=[...] # Replace `[...]` with the `config.json` value
144 |
145 | echo $CONFIG_JSON | base64 -d
146 |
147 | cat ~/.docker/config.json
148 |
149 | # Compare the two outputs
150 |
151 | cd ..
152 |
153 | jx create quickstart \
154 | --filter golang-http \
155 | --project-name jx-go \
156 | --batch-mode
157 |
158 | jx get activities \
159 | --filter jx-go \
160 | --watch
161 |
162 | jx get activities \
163 | --filter environment-$CLUSTER_NAME-staging \
164 | --watch
165 |
166 | kubectl --namespace jx-staging get pods
167 |
168 | export ADDR=$(kubectl \
169 | --namespace jx-staging \
170 | get ing jx-go \
171 | --output jsonpath="{.spec.rules[0].host}")
172 |
173 | curl $ADDR
174 | ```
--------------------------------------------------------------------------------
/manuscript/99-skaffold.md:
--------------------------------------------------------------------------------
1 | ```bash
2 | # If not already inside *go-demo-6*
3 | cd go-demo-6
4 |
5 | # TODO: Restroy from buildpacks branch
6 |
7 | # Only if destroyed the cluster in the previous chapter
8 | jx import --pack go-mongo --batch-mode
9 |
10 | # Only if destroyed the cluster in the previous chapter
11 | jx get activity -f go-demo-6 -w
12 |
13 | # Requirement: Go
14 | go get github.com/cespare/reflex
15 |
16 | make linux
17 |
18 | # Requirement: Docker Desktop (macOS or Windows) or Docker Server (Linux)
19 | docker image build -t go-demo-6 .
20 |
21 | # It requires quite a few tools to be installed and it's not continuous (there's no watcher)
22 |
23 | jx create devpod --reuse -b
24 |
25 | ls -l
26 |
27 | make linux
28 |
29 | cat skaffold.yaml
30 |
31 | echo $DOCKER_REGISTRY
32 |
33 | skaffold build -p dev
34 |
35 |
36 |
37 | jx create devpod --sync --reuse -b
38 |
39 | DH_USER=[...]
40 |
41 | # docker login -u $DH_USER
42 |
43 | kubectl -n jx get ing
44 |
45 | export DOCKER_REGISTRY=$(kubectl -n jx \
46 | get ing docker-registry \
47 | -o jsonpath="{.spec.rules[0].host}")
48 |
49 | skaffold build -p dev
50 |
51 | cat watch.sh
52 |
53 | ./watch.sh
54 |
55 | skaffold run -p dev
56 |
57 | chmod +x watch.sh
58 |
59 | ./watch.sh
60 |
61 | echo '
62 | - name: local
63 | build:
64 | artifacts:
65 | - docker:
66 | dockerfile: Dockerfile-dev
67 | tagPolicy:
68 | envTemplate:
69 | template: "go-demo-6:{{.DIGEST_HEX}}"
70 | local: {}
71 | deploy:
72 | helm:
73 | releases:
74 | - name: go-demo-6
75 | chartPath: charts/go-demo-6
76 | setValueTemplates:
77 | image.repository: go-demo-6
78 | image.tag: "{{.DIGEST_HEX}}"
79 | service.type: NodePort
80 | service.externalPort: 8080' \
81 | | tee -a skaffold.yaml
82 |
83 | cat skaffold.yaml
84 | ```
85 |
86 | * Open a second terminal
87 |
88 | ```bash
89 | skaffold dev -p local
90 | ```
91 |
92 | * Go back to the first terminal
93 |
94 | ```bash
95 | kubectl get pods
96 |
97 | # If Docker for Desktop
98 | ADDR=localhost
99 |
100 | # If Minikube
101 | ADDR=$(minikube ip)
102 |
103 | # If Docker for Desktop
104 | PORT=8080
105 |
106 | # If Minikube
107 | PORT=$(kubectl get svc go-demo-6 \
108 | -o jsonpath="{.spec.ports[0].nodePort}")
109 |
110 | curl "http://$ADDR:$PORT/demo/hello"
111 | ```
112 |
113 | * Go back to the second terminal
114 | * Press `ctrl+c`
115 | * Go back to the first terminal
116 |
117 | ```bash
118 | kubectl get pods
119 |
120 | # If Docker Desktop
121 | # Quit Docker Desktop
122 |
123 | # If Minikube
124 | minikube delete
125 | ```
126 |
127 | * Switch back to the remote context
128 |
--------------------------------------------------------------------------------
/manuscript/99-teams.md:
--------------------------------------------------------------------------------
1 | ```bash
2 | jx get teams
3 |
4 | jx team something
5 |
6 | kubectl get pods
7 |
8 | kubectl get secret \
9 | jenkins \
10 | -o jsonpath="{.data.jenkins-admin-password}" \
11 | | base64 --decode; echo
12 |
13 | jx console
14 |
15 | jx create env
16 | ```
--------------------------------------------------------------------------------
/manuscript/Book.txt:
--------------------------------------------------------------------------------
1 | 01-preface.md
2 | 02-intro.md
3 | 03-quickstart.md
4 | 04-import.md
5 | 05-buildpacks.md
6 | 06-env.md
7 | 07-dev.md
8 | 08-pr.md
9 | 09-promote.md
10 | 10-versioning.md
11 | 12-prow.md
12 | 13-pipeline-extension-model.md
13 | 15-advanced-pipelines.md
14 | 16-serverless-apps.md
15 | 17-progressive-delivery.md
16 | 18-boot.md
17 | 99-the-end.md
--------------------------------------------------------------------------------
/manuscript/Sample.txt:
--------------------------------------------------------------------------------
1 | 01-preface.md
2 | 02-intro.md
3 | 03-quickstart.md
4 | 04-import.md
--------------------------------------------------------------------------------
/manuscript/TODO.md:
--------------------------------------------------------------------------------
1 | ## Book
2 |
3 | - [X] 01-preface.md
4 | - [X] 02-intro.md
5 | - [X] 03-quickstart.md
6 | - [X] 04-import.md
7 | - [X] 05-buildpacks.md
8 | - [X] 06-env.md
9 | - [X] 07-dev.md
10 | - [X] 08-pr.md
11 | - [X] 09-promote.md
12 | - [X] 10-versioning.md
13 | - [X] 11-serverless.md
14 | - [X] 12-prow.md
15 | - [X] 13-pipeline-extension-model.md
16 | - [-] 14-upgrade.md
17 | - [X] 15-advanced-pipelines.md
18 | - [X] 16-serverless-apps.md
19 | - [X] 17-progressive-delivery.md
20 | - [X] 18-boot.md
21 | - [X] 19-apps.md
22 | - [X] 99-the-end.md
23 | - [ ] Move 18-boot.md to 02-intro.md
24 | - [ ] Replace `jx create cluster` and `jx install` with `jx boot`
25 | - [ ] Remove *At the time of this writing (April 2020),...*
26 | - [ ] Remove *At the time of this writing (May 2019) `/retest` and `/test this` commands...*
27 | - [ ] Remove *At the time of this writing (September 2019),...* warning
28 | - [ ] Remove *For now (April 2019)* paragraph
29 | - [ ] Remove *There is a bug (undocumented feature) in...* warning
30 | - [ ] Remove *If you do see the new domain...* warning
31 | - [ ] Rewrite *At the time of this writing (July 2019)...*
32 | - [ ] Change *At the time of this writing (October 2019)...* to the "real" month in 99-the-end.md
33 | - [ ] Remove *At the time of this writing (October 2019)...*
34 | - [ ] Rewrite *Finally, at the time of this writing (October 2019)...*
35 | - [ ] Rewrite *But, at the time of this writing (October 2019)...*
36 | - [ ] Rewrite *As mentioned at the beginning of this chapter...*
37 | - [ ] Rewrite the bullet point starting with *Set `clusterName` to the name of your cluster...*
38 | - [ ] Replace `jx create cluster` with `jx boot` in the workshop
39 | - [ ] Monitor [https://github.com/jenkins-x/jx/issues/5782](https://github.com/jenkins-x/jx/issues/5782)
40 | - [ ] Remove *The `--auto-merge` argument might not work due to the...*
41 | - [ ] Remove *At the time of this writing (November 2019)...*
42 | - [ ] 99-lighthouse.md
43 | - [ ] Replace prow with lighthouse across the book
44 | - [ ] Switch from `jx create addon` to `jx add app` in the existing chapters
45 | - [ ] 99-boot-upgrade.md
46 | - [ ] 99-vault.md
47 | - [ ] Add the book to the jx docs
48 | - [ ] Add AKS to 18-boot.md
49 | - [ ] 99-jx-create-domain.md
50 | - [ ] 99-multi-cluster.md
51 | - [ ] jenkins-x.io
52 | - [ ] 99-ui.md
53 | - [ ] 99-distribution.md
54 | - [ ] 99-contributors.md (Joost, Darin, Carlos)
55 | - [ ] 99-monitoring-with-prometheus.md
56 | - [ ] 99-logging.md
57 | - [ ] 99-feature-flags-rollout.md
58 | - [ ] 99-container-registry.md
59 | - [ ] 99-other-quickstart-buildpacks.md
60 | - [ ] 99-nexus-integration.md
61 | - [ ] 99-share-jx-access.md
62 | - [ ] 99-advanced-pipelines-2.md
63 | - [ ] 99-env-in-separate-cluster.md
64 | - [ ] 99-gitops.md
65 | - [ ] 99-ui.md
66 | - [ ] 99-build-notifications.md
67 | - [ ] 99-ng-arg.md
68 | - [ ] 99-security.md
69 | - [ ] 99-chatops-from-slack-to-jx.md
70 | - [ ] 99-rbac.md
71 | - [ ] 99-apps.md
72 | - [ ] 99-git-server.md
73 | - [ ] 99-prow2.md (`/retest` command, the location of the PR message, connection with issues, change PR approval rules, change plugins)
74 | - [ ] 99-running-multiple-pipelines.md (https://github.com/jenkins-x/prow-config-tekton/blob/master/prow/config.yaml#L628-L646)
75 | - [ ] 99-integration-with-uptimerobot.md
76 | - [ ] 99-codified-infrastructure.md
77 | - [ ] 99-cjxd.md
78 |
79 | ## Course
80 |
81 | - [ ] 01-preface.md
82 | - [ ] 02-intro.md
83 | - [ ] 03-quickstart.md
84 | - [ ] 04-import.md
85 | - [ ] 05-buildpacks.md
86 | - [ ] 06-env.md
87 | - [ ] 07-dev.md
88 | - [ ] 08-pr.md
89 | - [ ] 09-promote.md
90 | - [ ] 10-versioning.md
91 | - [ ] 11-serverless.md
92 | - [ ] 12-prow.md
93 | - [ ] 13-pipeline-extension-model.md
94 | - [-] 14-upgrade.md
95 | - [ ] 15-advanced-pipelines.md
96 | - [ ] 16-serverless-apps.md
97 | - [ ] 17-progressive-delivery.md
98 | - [ ] 18-boot.md
99 | - [ ] 19-apps.md
100 | - [ ] 99-the-end.md
101 |
102 | ## YouTube Live
103 |
104 | - [ ] Intro with a counter
105 | - [ ] Discussion with a guest
106 | - [ ] Terminal share of the host
107 | - [ ] Browser share of the host
108 | - [ ] Screen-share of the guest
109 | - [ ] Comments from YouTube to the screen
110 |
111 | ## TODO
112 |
113 | - [ ] Code
114 | - [ ] Write
115 | - [ ] Code review static GKE
116 | - [ ] Code review serverless GKE
117 | - [ ] Code review static EKS
118 | - [ ] Code review serverless EKS
119 | - [ ] Code review static AKS
120 | - [ ] Code review serverless AKS
121 | - [ ] Code review existing static cluster
122 | - [ ] Code review existing serverless cluster
123 | - [ ] Text review
124 | - [ ] Gist
125 | - [ ] Review titles
126 | - [ ] Proofread
127 | - [ ] Diagrams
128 | - [ ] Add to slides
129 | - [ ] Publish on TechnologyConversations.com
130 | - [ ] Add to Book.txt
131 | - [ ] Publish on LeanPub.com
132 |
--------------------------------------------------------------------------------
/manuscript/images/ch00/gitops-model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch00/gitops-model.png
--------------------------------------------------------------------------------
/manuscript/images/ch02/jx-console-environments.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch02/jx-console-environments.png
--------------------------------------------------------------------------------
/manuscript/images/ch03/github-go-demo-6-releases.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch03/github-go-demo-6-releases.png
--------------------------------------------------------------------------------
/manuscript/images/ch03/github-go-demo-6-webhooks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch03/github-go-demo-6-webhooks.png
--------------------------------------------------------------------------------
/manuscript/images/ch03/github-go-demo-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch03/github-go-demo-6.png
--------------------------------------------------------------------------------
/manuscript/images/ch03/jx-console-go-demo-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch03/jx-console-go-demo-6.png
--------------------------------------------------------------------------------
/manuscript/images/ch04/github-go-demo-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch04/github-go-demo-6.png
--------------------------------------------------------------------------------
/manuscript/images/ch04/import-build-staging.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch04/import-build-staging.png
--------------------------------------------------------------------------------
/manuscript/images/ch04/import-pr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch04/import-pr.png
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-agents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch06/gitops-agents.png
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-agents.xml:
--------------------------------------------------------------------------------
1 | 7VrRcps4FP0aP7YDCDB+TNxuOp3uTmby0PZRBoE1EYgVInb69SuBsEHCrUMMbJ3iB6OLJKxzD0f3XrMA63R/x2C+/ZtGiCwcK9ovwIeF49j2yhJf0vJcW5ZeUBsShiPV6Wh4wD+QMqpxSYkjVHQ6ckoJx3nXGNIsQyHv2CBjdNftFlPSvWsOE2QYHkJITOtXHPFtbQ0862j/hHCybe5sW+pKCpvOylBsYUR3LRP4uABrRimvz9L9GhEJXoNLPe6vE1cPP4yhjJ8zYI2+lv+uHnBw9w5+ofsfiEXxOzXLEySlWvAd5ur38ucGBEbLLEJyHnsBbndbzNFDDkN5dSfcLmxbnhJ1+QkxjgWANwQnmbBxKjvENOPKu7Yv2uq+oi/an1yQfYBJ8AvRFHH2LLo0AxpkFbWAVzd3Rz/ZvuqybftoqYxQcSM5TH2ET5woBF+ApmOgeZPnwiDWYTGU09cBG2NC1pRQVo0FsSc/wl5wRh9R64pfHQr0lr0+LgS+2wV/2QO+0wM+GAt79wT2zvVjb9tzg++dAP+fNwC+Nzf4Qk919L/T0oBc7D+5PC1TchNyCc1Bqr/ADSL3tMAcUynZG8o5TUUHIi/cwvAxqRzWdkJ1nJT7lvdoyQnOhJuaDdoaZzvQ/NI0W24BPV7xR/PKyvCK4RKURTcyRhGtkMCiwKFGfA0ltMf8m0Twvada3zutD3sFb9V4bjXuEcNiXYg1tkys8Vu70ZpJNo9TVa1mrnoJKDKCJs1LYpm0ZCE6g7YcsgTxX+2qpttbjvV6HNvYGCKQ46fu7+3ztrrDPcViJadYZTzF9TLVoHb0pc2z0lQj0OapUTDmqah3WPQrIhPrDxsvw0Z3Tjb6XodFOonOJaPtaWy0JmajmXb8YeMgNnpzsnHZZePqUmx0J2YjMNi4JmUhCfF7JMJAT4TN0Mezemjg6h67XCIcGJB+RtkjzoopINXyhchDQeT25QuBswH+pZzgdp+GvoR42moEGLrnF+KB44PE136J9P4PZPZMla3pPJfM2lrsCIZu+3owC/RgdmShBabQHlTBKvL6m6M0pwxW+N7TSJrKQuiDrPtKNyMWU5bKM5wjmVhWhEZ58X7h+EQgf7sRuu0n/ECVFt3F4827TO5qQkbFfF0BUSaoFIegmPcIUYqjSN6kV8COEjdW6utrWUqf+AQ9DB0t+wVmOU4483Xir8s6REEc9paBwgBt4nGg9pZdqGevewKz9nadSM9f5QRmoe1KoZ69pgmWbwXq1exQj1io/M3iwSZt+WVACGatArl6HKenEOcGhK4eWTrTBoTu0AzlLVNv1pKPZ3ezXCN7PZd6XqDp4MQlSHfEEuTVUs+/TupNXG90nRGoN5BGQyg7C/WW81JPY4yeNw+m3sR/A7pmBeZn1FO1jwgW20OQ/fK/YKYiU11emosjYHmhoMzTXzDRq/SDOSKax9cN6+7HlzbBx/8A
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-apps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch06/gitops-apps.png
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-apps.xml:
--------------------------------------------------------------------------------
1 | 7VhNc5swEP01HNPhw/jj6Dipe0g7nvEhyVGBNWgiWCqEjfPrK4EwX2biNnY90wYfzD6tFva9ZwlsOIsoX3KShN/RB2bYpp8bzp1h25Y1M+WXQvYlMjFnJRBw6uukGljTN9Cgnhdk1Ie0lSgQmaBJG/QwjsETLYxwjrt22gZZ+6oJCaAHrD3C+ugj9UVYolPXrPFvQIOwurJl6pGIVMkaSEPi464BOfeGs+CIojyL8gUwRV7FSznv68Do4cY4xOKUCQt4zH7O1nS6vCEPmL8B9zc3usqWsEw3vKRC36/YVyRwzGIfVB3LcG53IRWwToinRndSdomFImJ6eAtcUEngnNEglphAlbDBWGh1rbGM9XVlLuSDDVkHmqS/ACMQfC9TqgkVs9pajluGu1ona6xTwqZGEw0S7Y3gULqmT55oBn+DTbvH5jxJJCD7MDkk+DFiN5SxBTLkxVxn46qPxFPB8RUaI+Pi0KQ38PI4E/mjNvmTI+TbR8h3LsX9aIB7+9/n3rKuTb47QP6P/4B899rky/W0y/4zZj3K5f6TqNMsYnNPKGoOS/UDeQG2wpQKimrJfkEhMJIJTA3cEu81KARrilAcg8t9Qz3MBKOxlKnaoM3LbAcdXaqwIYtzRJXxxVSZ9VTpSQKxP1fPKDLyGElT6nWM32EJciqeFINfXB09t6K7XNNbBPtGsAJOZV/AKyyWPT41g0YlFdaliqiqVbYAfu+hqaOSbBMz7sEJthWEByDe21X7sjeEdY8IW2EcGBF0277fY2rrK6yQyk6GXNX7FZdt6knNp69OnVln1Zh26pQs9OoU1js0/YEnE/PTjedx4+iabhy7LRd1TXSqGS2340bzL7ux/9rx6cY/cqN7TTdO2m6cncuNo3O5UYb1+3WZXv9L4dz/Ag==
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-env.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch06/gitops-env.png
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-env.xml:
--------------------------------------------------------------------------------
1 | 7VtNc6M4EP01rpo9JAUSH/bR8WSytTW7ldocZnKUQcaqYOQFOXbm169khAEJjx0G0MQJPhg1QlivX7e6W3gEZ6vdXYrWy79piOMRsMLdCH4eAWDbE4t/CclLLvGtSS6IUhLKTqXggfzAUijvizYkxFmtI6M0ZmRdFwY0SXDAajKUpnRb77agcf2paxRhTfAQoFiXfiMhW+bSsWuV8j8xiZbFk21LXlmhorMUZEsU0m1FBG9HcJZSyvKz1W6GYwFegUt+35cjVw8/LMUJO+eGGf62+W/yQMZ3V+gr3f3Aabi4kqM8o3gjJ3xHmPy97KUAIaWbJMRiHHsEb7ZLwvDDGgXi6parncuWbBXLy884ZYQDOI1JlHAZo6LDgiZMatf2eFs+l/fFu6MTsg8wcX5husIsfeFdihsKZCW1oJs3t6WebE92WVZ0BG3ZEUluRIehS/j4iUTwFWgCDc3pes0FfB5Witf014BdkDie0Zim+3vhwhUfLs9YSp9w5Yq3PyToFXl+dAS+UwffbwAfNIFv9YS9cwR7cPnY27Zp8N0j4P/zDsB3TYPP/amK/iPdaJDz9WctTjereBowAc3BVX9Fcxzf04wwQoXLnlPG6Ip3iMWFGxQ8RXuFVZWwP466+4r26IbFJOFqKhZoq5/lQNFL0ayoBTZoxetNKxNNK5pKcBJORYzCW0GMsowECvEVlPCOsO8CwWtXth5rrc87Ce++8VJp3OOU8HnhtJAlfI7fq43KSKJZDrVvFWPlU8ChFjQpWuLTpJs0wGfQlqE0wuzUqqqrvaJYt0GxhSzFMWLkuf57m7Qtn3BPCZ/JMVZpVpxPU95Ujb6UcSaK1xgr4+QoaOPsqXeY9C9EJtYHG7tho2OSjZ5bY5FKonPJaLsKG62B2ainHR9sbMVG1yQb/TobJ12x0RmYjVBj4yzeZIIQbyMRhmoirIc+rtVAA0fVWHeJ8FiD9C+cPJEkGwJSJV8IXTwOnaZ8YQzm0OtKCU7dGpoS4qZqhO33pQTYds3PuMGxVs7Xfo3r/Q3c7JleNqezKTdrK7EjbLvsq8EsVIPZnh0t1B3tNBE4BkuUcHWK0m6pNlHTDcXXpwRvcxQxyg69UCJYkDyTlCYrrvk/xNOzPbtpyv0Jb4ked4Rdj4AXc5XczLlD9yJ24FDFDrjdszrF684ioQlWPIsUIemKYrxgDR5qRcJQPKTRs5W+r6ecGHpK+uLrS8MhFalSV6VYd05Jr9PdU6GtTyjKtdhhpShEeLwIGitFwRjPFwrooBvQXb8OuvHSKNTLcxeH+biO+aSB58NirhflLg5ztaZhGSe6f/Gge5YCOjDO9B4LnW8snizSnpMBJTRaRXLUOFBNQc4NKB01MgXDBpRO2wznPVPPaMnItetZspb9nks9dcEfuoTp9FjCvFjqeZdJvYHrlQ7ogXotadSGskao55ulnsIYdde5NfUG3kZ09ArOz6gnSyQhypaHIPucLRwzZMrLU6Y4cqWo1nHAtduOJVChm/aSQ98s0dOwf3FEsiLb6OxFoAX2gsYMLPQnc0utqXWVgQHVBk2nvU7HGRio2mJtO9X+qS2Wi0i5bjzWlo3eY5GiAnB6G9/oguD5HS0InmrqA5f0XT0Mvk2eR+/ilVdgvPTi6pFgjj54B+h7xtF/XTD0OrdbC4H8M3NA+/fPAV2jlS91awaoBauz/a4aBKjJZN9+V99Gyy3/5vItH1rGLV/fUPuw/JOWD0xaPnTr1R9gw3aWDxQXAoGSpfVt+frG4gf3TnLviId549wD44G5d9mJPVTW9InpxN7VX6O8JLzViL7H9wd4s/ynbW4O5f+V4e3/
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-full-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch06/gitops-full-flow.png
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-full-flow.xml:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-registries.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch06/gitops-registries.png
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-registries.xml:
--------------------------------------------------------------------------------
1 | 7Vtdc5s4FP01nuk+JAOID/vRcdt0drI7mclDm0cZZKyJQF4hx05//QoQXxJuHGygdeI8xLpIAp17uLr3gCdgEe1vGdys/6EBIhPLCPYT8HliWaY5M8S/1PKSWzxjlhtChgPZqTI84J9IGuW4cIsDlDQ6ckoJx5um0adxjHzesEHG6K7ZbUVJ86wbGCLN8OBDolu/44Cvc+vUMSr7N4TDdXFm05BHIlh0loZkDQO6q5nAlwlYMEp5/i3aLxBJwStwycd9PXC0vDCGYn7MgAX6vv1v9oCnt1fwju5/IhasruQsz5Bs5YJvMZfXy18KEBjdxgFK5zEn4Ga3xhw9bKCfHt0JtwvbmkdEHn5GjGMB4JzgMBY2TtMOKxpz6V3TFW15XtEX7Q8uyCxhEvxCNEKcvYguxYACWUkt4OTNXeUn05Vd1nUfedIIJTfCcuoKPvFFIvgGNC0NzflmIwxiHQZDG3oasCtMyIISyrKxYOWkf8KecEafUO2Im30k6DV7/jkT+HYTfK8FfKsFfNAX9vYB7K3Lx940xwbfOQD+v+8AfGds8EU8VdF/pFsNcrH/bNKv24jMfZ5CU4bqO7hE5J4mmGOahuwl5ZxGogNJD9xA/ynMHFZ3QvY5GO5r3qNbTnAs3FRs0EY/24Hil6JZcwto8Yrbm1dmmlc0l6A4mKc5imj5BCYJ9hXiKyihPeY/UgSvHdl6bLQ+7yW8WeOl1rhHDIt1IVbYYrHGH/VGbaa0WU2VtYq58iWgQEuaFC+JZdIt89ERtOWQhYi/tqvqbq851mlxbGFjiECOn5vX2+ZteYZ7isVKDrFKu4vzZcpB9exLmWemRI2pMk+OgjZPRr1y0SdkJsYHG8/DRntMNrpOg0UqiY4lo+kobDQGZqNednywsRMbnTHZ6DXZODsXG+2B2Qg0Ni7INkkJ8WcUwkAthPXUxzFaaGCrHjtfITzVIP0bxU84ToaAVKkXAgdNA7utXphaS+Ceywl2825oK4iHVSNA1z0/ETcc7xR8zbeE3t8gzB4ZZXM6jxVmTSV3BF23fTWZBWoy23OgBXqgnWejljiGDKMkvRSGMoZSJmKCmC/O8AuxuHdFh+uJ5RKB7s1SxGY35CUdapQWtzBvsrV538c0RkqQkCYoowpBK94SbCIcBOlJWoNUFcZ6Km+Bq1Qinh7ly6qiEeV7iy+65HZPU6d9gqFY1F+nhXo1iEM0Xfmtoo8/RcuVArp1HtAdrwn66Con0JW2i8N82sR81sLzYTHX9bWLw1yVJ4zRie5dPOiuoYBujc70HjXLPyw1LCqYV3NDMKogZKspnVpNHJsb2mqSaQ2bG9pdi5X3TL1R1R/HbBa8WiF7LPXUDX9oNdLuUY28WOq5l0m9gaVH2+qBeh1p1IWyo1DPG5d6CmPUB8idqTfwE0FbF2N+RT0pkQQwWZdJ9tufxgxFplxpGosjV4prbdu6drqxxFWkfVOV7Ptmia43LISrIY7TpyMGjtLXJ0uF7kVj0Env+ayQ67dWZYE3WxqqznauUlh94j/6y1W2rj98QyS6LNhVopcv5owHu65A3OElg9lVXxLy2kY0OuH1p4cnZUXWwQ3J/OWGVGVSVfL0WD/Wf0JeyGCvv5Yyai1oK1KW3fU1KVUTs4aWIc6sgL0L6o2akLvemRJyV8nstfjWM/UKPD6o9wbqjSpDnI16nvIGlKXqGZ2pJ5rVL4zy7tXvtMCX/wE=
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-webhooks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch06/gitops-webhooks.png
--------------------------------------------------------------------------------
/manuscript/images/ch06/gitops-webhooks.xml:
--------------------------------------------------------------------------------
1 | 7VlLU9swEP41OcLYUZzHMQRKD7TDTA7AUdiKrUH2urJMEn59JVt+SQ6EkpBpizngXT1sfd+3K60zQIt4c81xGv2AgLDB0Ak2A3Q5GA5dd+bIf8qzLT0TZ1Y6Qk4D3alxLOkL0U49LsxpQLJORwHABE27Th+ShPii48Ocw7rbbQWs+9QUh8RyLH3MbO8dDURUeqee0/i/ExpG1ZNdR7fEuOqsHVmEA1i3XOhqgBYcQJR38WZBmAKvwqUc921Ha/1inCRinwELcpf/mi3p9PoM38DmhfBgdaZnecYs1wu+pkK/r9hWIHDIk4CoedwBulhHVJBlin3Vupa0S18kYqabnwkXVAI4ZzRMpE+A6rCCRGh23bG09XNlX7LZuSC3hknqi0BMBN/KLtWAClktLeSV5rrhyR3rLlGbo4l2Yq2NsJ66gU/eaATfgebQQnOeptIh1+FwksLHgF1RxhbAgBdj0cpTf9KfCQ5PpNUyLi4NestfXgcCf9QFf9ID/rAHfHQs7Ec7sB/++9i77qnB93aA//M/AN87Nfgyn5roP0BuQS73n1Td5jGb+0JBU6fqG/xI2C1kVFBQKfsRhIBYdmCq4QL7T2FBWJuE4tqZ7lvsQS4YTSRN1QbtHGc7MHipzBYtqIeV8dFYmVmsWJSQJJirM4q0fIazjPqG8A2UyIaKe4Xguaeth451udHwFsa2ZdwSTuW6CK98iVzjfdtozaTMZqrCquYql0AC69BksCSXCTn3yR6yFZiHRLy1q9q0t4j1eoitfJwwLOhz93372NZPuAUqV7JLVVYUl8vUg9qnL2OemZE1psY8JQrWPIX06kV/4GTifKnxMGocnVKNY6+jIlNE+4rR9Qw1Op+sRrvs+FLjH6nRO6UaJ101zg6lxtEnqxFZalywPFOC+DsKYWQWwvbRx3N6ZDAyGTtcIWxXYwcLcPc94b0jlIefGcv7HnPQKWPZLGuQGYR7R7Nx0rHSwrGj2a6G5tk28SMOCeTZQH0qjOM8kZFZVDuSGdmUh5GCmjxGAE/ZuSVWGZyiK89u8ZlAQoxKVbuwjn5GVqInKcQ0CNRDepNJk26OVDPVn8Iqsqpc2C5mR32qmx4rc0zelTk0yAHOojotv5ZD6nxwPvE6KeFg+eDtOB+fMs6R88Zmu3ecm9I5WJxLs/kqXnZvfltAV78B
--------------------------------------------------------------------------------
/manuscript/images/ch07/devpod-ksync.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch07/devpod-ksync.png
--------------------------------------------------------------------------------
/manuscript/images/ch07/devpod-ksync.xml:
--------------------------------------------------------------------------------
1 | 5Vpdd5s4EP01fkwOIL78mNjZds+2e7Kb0233UUZjo0YgF+TY7q9fCQQGiWxcFzdJ6zwYjUZC3Du6zMiZoFm2e1PgdfqeE2ATzyG7CZpPPM91g1h+Kcu+toRTvzasCkq008FwR7+CNjrauqEEyp6j4JwJuu4bE57nkIieDRcF3/bdlpz177rGK7AMdwlmtvUjJSKtrXHgHOxvga7S5s6uo3sy3DhrQ5liwrcdE7qZoFnBuaivst0MmAKvwaUe99sjve3CCsjFMQO+YOeffAN/lUv39oJ+2aRv39OLZnEPmG30E+vVin0DwZLnYsYZL6omcpwwnM0m6PoBCkElUleMrnLZJ/i6Y32HF8BueUkF5ap3wYXgmXRgRkci1w9y7mus52kNqciYbLvykm8EoznMWpYdaVxSxjoLm1UfaS9Fwe+h0xPGsXuNZM+qwITC4XFynkPHPKeFnL1eVs4LRaCerOHeU5YUrxU02W6lYv4yB7HlxX15yfC6xsCmRrOlwIFdx6SpegM8A1HspYvuRU5QD9H7Jorq5vYQhF4Tamk3ABtGsQ78VTv1ITbkhQ6PbwkVK1JmbFMqpsyAKfgmJ0A0S9uUCrhb40T1biVifWaHo2gEBL1pH0HPsSH0g8CGsNWe0SFEFoSfd7L9J86grAB6HEn3VCSNTbIM1N/gJqk+akR/v9efkaLaNzhBR4Z1fC5KfFv/gusPdzd/T4L5hby8/vD7u/nt1ewP2ZZ+t5x8H0kmHUsIk2SIDhJNF44zEuyhAXtow+6GA7Cjc8EeWbDfl/s8GRVbgiFeDmIbJjEslufB1nV8C9t4ANrmRTs6tNOn3+iQkyuVG6mXLcNlSZM+kLCj4pOWb3X9r7q+DHRrvut0zfdNI5eL/9RtdEap5mFY1WrGPUpByTdFAk/HkMDFCsTTWxxIL9OzCe0QFgwQ1tgKYFjQh35+OMSivsMtp/LJ2nhxUT9efD/qT1E/tx7VzefMiSJjU8fGRDUw1kSSebzvuK2VQ/n4gr2p0w9wN/zfdZn+XuwZMV2v4BDhLQenB71r57GfdxdAqLg46Pkv9aoNAiM8psjW/Ggg/XHPlv64rkXS6dJ0GQUddXJfmDb5R2pTg/ULESdk5MxoeqI4+Uaih0yVG0mc/Ni8T/wDxMYuhcbOC0kAMfGHtCP2FqjSjjE0IupLNfKOzF3OphB2hfRKkY0NZNFzI2sXOq8UWSO9QP5zIxv8JMiGjoFs8NzIhj8Lsq6BbPjcyNr19ytF1jOQjZ4ZWc/OcfXJhqO+0oLn9CvIjMZhXBYQ8lviVrW3VC5YpowpL0HdJa8a6jKRVQKmuTpplRas0p8lL7KydZjDg6Tv0uJPgij6JPXJ0MffXea0qTmLZ7AUA/VORglRNxmMif7xrypx9M86rj/SK8CZ9kiPYotzNxogPTzXkUtTxxxZ2GiMCS7TdnMNljhet8Rpq5rBEudRWJ8sVRrHF1KCBEZGH55YgSDXPLYwtvxIFUgQeEPrPXZZfffz1CuenaF8xCJJK0GheUkJGFIiLxYbyoiSGJyrJoE14/uy5hdwWUmW4Kq/6iVSHgQoz84RiwNyUyswBc1Auyq5U5qW4nwF5S+jWQiZhar9omp/eOpuqwidS7Ts7GoU0fohmhW8LM3y+uQGp4qWdZzhHXds8rRSyObhXw1q98M/bKCb/wA=
--------------------------------------------------------------------------------
/manuscript/images/ch07/devpod-vscode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch07/devpod-vscode.png
--------------------------------------------------------------------------------
/manuscript/images/ch07/devpod-vscode.xml:
--------------------------------------------------------------------------------
1 | 5Vrbdto4FP0aHsmyLN94TEym7Zp2VmayeplHYQmsVliuLQLM149ky2BJTkMplKQlK2AdXb330fY5ghFMl5tXFSrzdxwTNvI9vBnB6cj3AYyA/FCWbWuJw7g1LCqKdaO94Z7+R7TR09YVxaQ2GgrOmaClacx4UZBMGDZUVXxtNptzZs5aogVxDPcZYq71I8Uib61J6O3trwld5N3MwNM1S9Q11oY6R5iveyZ4O4Jpxblor5ablDAFXodL2++PR2p3C6tIIQ7p8BV5H4oV+bueg7sx/brKX7+j425xD4it9B3r1YptB8GcFyLljFdNEXpeFKXpCN48kEpQidQ1o4tC1gle9qxv0YywO15TQbmqnXEh+FI2YFZFJtdP5Ng3SI+zM+RiyWQZyEu+EowWJN2x7EnjnDLWW1javKS9FhX/Qno1UZKAGyhrFhXClOxvp+AF6ZmntJKjt8sqeKUI1IN13PvKkqNSQbPcLJTPXxVErHn1pb5iqGwxcKnRbClwyKZn0lS9InxJRLWVTXQt9MK2S7dv9LZZ753Q71wt7ztgxyjSjr/YDb33DXmh3eN7XMXxlJStasWU7TAVXxWYYM3SOqeC3JcoU7VriZjJ7LAXnQBBf2Ii6HsuhEEYuhDutOfkEEIHws8bWf4LLUndAPQ4kuBYJK1NMg/V3+AmaV6qh7nf29eJvDqwOIEHunVyLkoCV//Cm/f3t/+MwulYXt68f/N2ened/inLst0dxz9Gkk3HnERZNkQHjiczzzsR7JEFe+TCDqIB2OG5YI8d2D/cy3Iq4wfVtVBzyv+ZeoB/U2G+H3KMSDIfhDzKEjKbnwfySeIgngwBHp0J8MnTz3lS4GsVMalHMEN1TTMTR7Kh4pMWdXX9r7q+CnVpuulVTbddoZCL/9Qv9Hqp4r5bU+r6PcpAzVdVRp72LIGqBRFPb3yCjfjP5bNHWDhAWGerCEOCPphR4xCLeoY7TuWd7dwFQNNdgiA2h2jvW/fqR3n2QLG11RNroBYYZyDJPNr2mpWqQf34gv2JZ8wDQPTNddnt/cS3fLpdwd7Ddxwc7/TAjW4/b8YEUzHeq/xv9QAOQ8s9JtB9EsQDQRE4W1AEgEPS8dJ0FYc9dQLPTJuCA7Wpw/qZiBO0Imk4OVKcAiv8g7bKnUicgsSeJ/kJYuMmSKeOFnFIEhwMaUfiz2CjHafQiNiUaugHB8UuZ8s8gZs3vVBkEwtZeGlk3fTnhSJrhRcwuDSy4S+CbORZyIaXRjb6VZAFFrLRpZF1s/IXiqxvIRtfGFnfjXHTHBULUqvZKnXmgcqSUYmq7+HmFJqp+xFcveWqXgLZtG7ORlrTlDxIfq4cgiRKwmTBRFufevep0abuCJ6RuRhIaJYUYzXJIOnmqa/KYfS3OSA4kcZ7E4PV2D1SAfFQFOyfi1U34nO46GUuGmOM6ny3ewZzGL+fw+zSlsEc5lFYn8xFuobPJMcIrZA9OjLFgMA+l7D29IlSjLDzKnO9hy7LbH6ehMR3Q5CPSGS5Ok+VMlLT5qy1LyXyYraiDDeqVDRaRErGt3XLL0F1I0GNKqGmFkt5EI1q9c5QPCI3dSNfdEl0UyVf8iNrVe+30SwI7UzUfRLtvm/qb6sYnku03PDpJKL1UzQrfF6a5ZvkhseKlnNe4R92LvK0Usji/hcGbfP97zTg7f8=
--------------------------------------------------------------------------------
/manuscript/images/ch07/devpod.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch07/devpod.png
--------------------------------------------------------------------------------
/manuscript/images/ch07/devpod.xml:
--------------------------------------------------------------------------------
1 | 5Vpbd6M2EP41Pqd9sA8gbn5MnL2d7vakTbe7+ygjYZTFiAj51l9fSdwl0ni9OD5p7AfQaBDDN6OPGYkJWKz37xjMk08U4XTiWGg/ATcTx7FtLxQHKTmUEn/uloIVI6hSagV35B9cCa1KuiEIFz1FTmnKSd4XRjTLcMR7MsgY3fXVYpr275rDFTYEdxFMTekXgnhSSkPPauXvMVkl9Z1tq+pZw1q5EhQJRHTXEYE3E7BglPLybL1f4FSCV+NSXvf2kd7GMIYzfswFD9D6O9vgP4rYvp2Sh03y/hOZ1sZtYbqpnriylh9qCGKa8QVNKVNNYFm+v1hMwPUWM04EUlcpWWWij9O8I/0Ilzi9pQXhhMreJeWcroVCqnVEwn4sxr6G1TiNIOHrVLRtcUo3PCUZXjRetoQwJmnaMWyhfkJecEa/406PH4b2NRA9KwYRwe3jZDTDHfENYWL00qyMMunAarDa946UJDCX0Kz3KxnzswzzHWXfi1kK8xKDClOBBN4/6i27iQExeTBdY84OQqW6AFheeUk1b4KgbO7aIHTqUEu6AVh7FFaBv2qGbmNDnFTh8QOhYj8dKTUyZK1mVdeBPxMs1zD6vmJ0k6GOT2P1EyrqZldF3sYFrBsx2WNUq4h2wrmkjSsJhPM2QpkzI4I4YpIhzGaRuKPzFkEOxUHKC3GUwT+FO1wIFEXTDuYSxhXh0+JhI7w5tZ1wlmerEVzuB86s73QbmF73B5zun8vnjuHzRbop5OzUXa/cI8FWHtglhOO7HEaydydmyTHBMAKEzrwPoGOZALqeZyLYvG9GhxAYEN7vRft3uMaFAuhxJO1TkdSIMfbkf5AY1U9e0ef48jcSk7maTwaCepDKwnO5xDWZzLv+fPfmz4l3MxWn158/fLy5vVr8JtpC75ain3OS7o4Y+1E05A4UzJeWNRLsvga7b8JuD5EJOBfs3tMvEJyhK5m0ySwghUVBoj6SeE/4V8kxM69qfev03Owr+lGNQ93IhPFfazXZ+NaOIJvtZapVX1cah5GRH2oeEA9ANyzCT786OWQrzJ8KTNOjHY95Aw6rZQynkJNt39whL1Z3uKVEPEgTMLaWcbhu0B+ifMzqqm6iqQ3k1SlIHXmh0x+oxMEYSHgeHjpquVQoHjc4sMDgfdoYLUdsI7bB9PQgDobpfPHxw8Tx4VrO/GxZtK+zkTgDQRzGg5zhRyFexufhDNtyDc4IByLQcc9EGfMRKaNDGC19PEEZ1sUoI3gRlAFGogw70F5WoTbQSJThzPvUZNv+f9ql6z8LxdhmTX6/n2Ikao42T3lVKaTnaeExB2YuEwyk9fbZ0nr7iHL4+GwmOCGduRw3uUdyk20Ne/V5yAlotSCYn0hOrlbAAJ3lRiInN9TvEz4D2Zgl/tj1DvJwiNwh7gidJVDcMQZHBH2qBs6RucvZGMKs/F8osqGGLLg0smYB/0KR1dIL4F4aWbNGf5nI+paGrHdpZP3/C7K2hqx/aWTNkvyFIqutm4Dgwsg6Zo6rFjuwFECORS5jpVSUDuIoEFPtXwQywhSVvq0pF7WJ9Y5w1czl/g5lh1+lQiY8ZEUMV8PIC27wVjlOPK94XCFTFvJEjiH3fIXeYqJ2emOy2jAo94oqWTkczraE0WyNVVa1hYzAZWkVww8bwrBUipWBCG9xSvNKlcaVCTmj9zjiMyN6hFd5P0T6oVBtJHbjphLVu5opjvlAtbUmCMmbDEZkf1NFFljVBrntjvQCsua9kAtCI+LsYCDk7LOt+NRl1JF1VQUygkXSzO3BCsvpVlhNUTVYYU3Gq5Qeg/95KiBPKyj8EwsgYOurJhrjjFQAeZ4zZO+xZvXVz1MuOWZS/5ciqIgieSCSbfJNmpZcw+SWckVhOg1K7YzTpr+kv1dDPf4cDAZnl3rq3dveXjc4F/MMbAuOwTw/sLYzJvOASzKPo20keKcuDAdaHt8YOPZeUgAG73NeMjGrrS+QR4n8vEJwQ0EUpXTZQZwsNyRFRZPzIJyn9FDmOCmGhUp3FKtA1YvEjOeKjDrLxSKDwyoaOJFftShVmcBJHktgtsLFq6EhAPRFNzPpbj4O6c6U4Gw8ZFaKo/DQZRIg76IJkKPR0KkZkLE06xy3BPw0U4hm+wloqd5+SAve/As=
--------------------------------------------------------------------------------
/manuscript/images/ch07/vs-code-jx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch07/vs-code-jx.png
--------------------------------------------------------------------------------
/manuscript/images/ch08/issue-commit-msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch08/issue-commit-msg.png
--------------------------------------------------------------------------------
/manuscript/images/ch08/pr-all-checks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch08/pr-all-checks.png
--------------------------------------------------------------------------------
/manuscript/images/ch08/pr.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch08/pr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch08/pr.png
--------------------------------------------------------------------------------
/manuscript/images/ch10/versioning-github-releases.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch10/versioning-github-releases.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/prow-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/prow-ui.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-flow-pipeline-operator.drawio:
--------------------------------------------------------------------------------
1 | 5Vpbc+I2FP41PJbx3fBIgSYv2bKbzmzytKPYwlbXWFQWt/76Slg2lmSC8eLg7SYziXR0sTjfd24yA3u62j8QsI6fcAiTgWWE+4E9G1iWaXge+8clh1ziW04uiAgKxaST4Bn9C4uVQrpBIcykiRTjhKK1LAxwmsKASjJACN7J05Y4kZ+6BhHUBM8BSHTpVxTSOJeOXOMkf4Qoiosnm4YYWYFishBkMQjxriKy5wN7SjCmeWu1n8KEK6/QS77ujzOj5cEITGmTBd6n5Xj29bPxbT8PJo//vMwBWPzmCni2INmITzyDWyaYp1tEcLrim+fHp4dCJwRv0hDybY2B/fsuRhQ+r0HAR3eMBUwW01XCeiZrggRFKWsHbCdImGALCUVMwRMxQDFfsURJMsUJJsdH2EuX/zJ5Rgn+Disj3vGHr8AprcjzHybX9SJUxR8M9xWR0NMDxCtIyYFNEaPWWGAmSGvaor87UcAu5sQV+O2CtkDQLir3PiHDGgKcK4AaOxpQC8bue2ATAjhaBrXYBCP4trwVBr6MgadjYNqujoHpdoWBpUHwiPH3dyAwL0NwA03ZhitpqvQ4VU1ZNWy1ulKUrSnqAb3nRhro6SfwGubIH8pI1PmNUQ1lva6A0J2GhgJMwwmPk9wNJCDLUCArHu4RfRHuhLdfeXvoit5sXxmaHYpOyg5/XDT03aL/WmzIO6d1x16x8CwKGd6QAL7zSU2hVgpIBOllbsJQivs6qBXI3BrbKWQEJoCirZwt1OEonrDAiEfU0ssZcqSxRwoV8g8uVlWju7qRq2xkKxvlitE2OtKq/NjtmeZqTPsC15jQjGMSwyPnAN3wLl5yjNEaJijlA28blITZUGMmMzsqc1E26xSz5bIPEKIiriVwSWt8xwqFIX9Irc+RA+gt3IKvIFOkxFWnUMOwzpzCSINqBoP+hTFzfO8wZuqknhLEEqW+qao0/vupSidV60hjSpHGbxpqqnFGBKhOIo3dMNBY/Qo0juyFysBzdaBRayM13e440Fh6xbo4xZI/15AAiu9voo7fN29m+V2ZaN8s1GpqoV6vTNRULMtRLauxiSq27qi23nUuaGhM+wuF8O42qYXN0b1t0jU1TQ0sL+FJa4i2rBnx5hNIQQSzI8MozChKI36YNGR/V5BEeX/xhefQ+WJ2mMp6TfH/m8zalHnu2Bqefk25rZZGN4PTu2EWVMl8XitDF3ys+VE+1ulXeuN7istrW0ercdtVb3TP+E6GKThUpq35hOz8gT2j/jkn+uU73tQxjzpLAZpm6b8qPz1Thrt8e3AtPz1H3sjrip+KQdnCLs6eS5nvfQif7151/rJ8dlR6tPW3Km+cjvis3sJd4rNff65O+TzWL5w0PmcxWPMmCHiZ+xFpc5n+FmmzqafNTg3VOrvAHOtXAK3N3hi2q2WH1lUvNvguC0gQUwB/0fqDzmD8c77ssMfKnUjbOyhHLeQ+usC1riKgqJ1CkMVltVul4rm3ZUYDUlXJ2KhUaM+6ggUXWVdUtX2hnXOm7L/6XsVWYkjD3OtWtLvO7TVnXZ9J1/i9rtsrzqmvYy01rWnNuYb5UQvOTXdP6MmaLf6efMrA583bZEdear7K0T7UXpNh16L5I37rbt5HqfystpmySilTLSFbM4F1T19DzKefvsxpz/8D
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-flow-pipeline-operator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless-flow-pipeline-operator.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-flow-prow.drawio:
--------------------------------------------------------------------------------
1 | 3Vlbc6M2GP01fqyHi8H4Meu4yXSmXXfSmc0+7SjwGTQREhXyrb++EggbIWp7nbDxNplM0KebOedwdEhG/jzfPXBUZL+zBMjIc5LdyL8feZ7rBpH8pSr7uhLOJnUh5TjRg46FJ/wP6KKjq2ucQGkMFIwRgQuzGDNKIRZGDXHOtuawFSPmrgVKwSo8xYjY1S84EVldjQLnWH8EnGbNzq6je3LUDNaFMkMJ27ZK/mLkzzljor7Kd3MgCrwGl3rer//Re/hgHKi4ZEL4x2p2/+VP59tuEd89/v28QGj5SxDWy2wQWes7voeNLCzoBnNGc7V4/fHFvsGEszVNQC3rjPxP2wwLeCpQrHq3UgWylomcyJYrLxHBKZXXsVwJuCxsgAssAb7THYKpGStMyJwRxqst/FWgvmW9FJy9QqsnrL7UDEZFq15/ybqNi4ZKbQy7Vknj9AAsB8H3coju9WaaMy1a19ft7VECfjMma9HvN7JFWnbpYe0jM/JCk/MdRDWPTYuopVT3R3CTIIhWcS83cQQvq/fiYGpyENocuH5gc+AGQ3HgWRQ8MvZ6ggL3PAXvgJTvBAZSB8dpI+X1qNUbCijfAuoBn7KRC3D6CVzDjaZjk4k+34h6JBsORUTU4+7x7SnWnX20Yt3AQmrOsfTEW4PKCz4cKjsy1CeRU7uhQ3ApgJZV2pIAOtWz72zhJZP9qoxoohIhLgsk4gxUSWSQV9FO4UXWKa7mS3jjrApyoDo5TlPgmKay8RvQ13rQs/xZ4gIIpmrU5wI4EtXG9T44LwjUOUZ/lHmGxOeirFJjnstR8jIkErdPL3JamIoDdS3iJV/CZNc0Gcrk9qYj6VJzyhJYiR4ny3GSqE16xWQe5+9iUma0CSeWnLw+OQXBUHKaWnKysAea3Kksf8Q0QWV2eApbnMAOi2eF1jjQra+tnvudBrJq7JsGlffx3G58rVbwgqZ9nFe19ufoKNmax3DBMyQQT0GcGKixgMR4S7HZbdEX9LGnaxwIEnhjvtv0Uap3WDJcPTdaPJOOeFyvo4r6xvWs9rtIZyFvYi7kOR23qoGxFqoUdrjtN4jOPhhPiS4mqCxx3C81tyU0ZzwNrtLacFLzf0qlnRXIxUrrvsp13w4GVlqzXUtpf+EEbi9XRB+dK2Z2BLNQKjNUqEsUqxP+R+B0uN8GJ9fGadID02CRfmbHr6utyxmb5nWpd7WOxsPxesK81CpLGdwkAOqvDG80tEYnZx3NvylH82edd55rHW3SfXJ/8Nk5swPbgsrADsBVpC7WZVYla2VyOoLHjK5wupa5HLMqs1c5X4bxsSXd/0vMnp6316hHbNPBbOP7Es9VMdsZxj7eYBXTC62ieTZvxCs6Z054rVVMzXWCd8s+snn8x0U9/PjvH3/xLw==
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-flow-prow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless-flow-prow.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-flow-tekton.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-flow-tekton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless-flow-tekton.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-flow.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless-flow.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-static-agents.drawio:
--------------------------------------------------------------------------------
1 | 7VrRbpswFP2aPK4CHBLyuGVbp03TqvVh26OLL2CN2JExTbKvnw2GgE2WdEuJ1jaVGnxtX8y5x8e+JhO0XG2vBV5nnzmBfBJ4ZDtBbydB4PvTufrSll1tmQfT2pAKSkyjveGW/gJj9Iy1pASKXkPJeS7pum+MOWMQy54NC8E3/WYJz/t3XeMUHMNtjHPX+o0SmdXWKPT29g9A06y5s++ZmhVuGhtDkWHCNx0TejdBS8G5rK9W2yXkGrwGl7rf+wO17cAEMHlKB/nN+5R+vf+Rll9fwby4ya6/JK+Ml3ucl+aBr6k045W7BgTBS0ZA+/En6M0moxJu1zjWtRsVdmXL5Co31QnN8yXPuaj6IoIhSmJlL6TgP6FTM4sjuEtUjRkDCAnbgw/nt5AprgFfgRQ71aQlmkF519DHlDf7oPlNJLJOwGbGhg1P0tb1Hkp1YdB8ALJTB9llXhYSxB/Q9Y6jq1Giip6vc5oyZZN87WKehPpvEPPqo3twJjv2+nOeWARhPxYLNxQIDYQiQI8Vi9CJxUdgPykrzsv0ECIyHUI9Cu5Qhfo50J1bTEeXZvrMQdeBFRh5rcVYleIcFwWN+0jClsrvnesfejJchab0dmvmRlXYNQWmBv+9W+j00sV9t6rU9KsHB8TRfSsC6gF4KWI4rp4SixTkMf65Ee1ELBwIWGMTkGNJ7/vDHYqiucMNp+pB9tJoEab127ioH9P06i4glqN2JWsceZajGgfHUUWq9rH/nmcLh2dvSqqWczWAFKqB3nBSVOs+6B2BACxBV3OmNyCwwkyVlrqBvlAWPVF3VZNNBroR49oNA9AaUDWVWVlUMSBlTFlaWaAit4BC1/BE/TNycuUQX81z2ad6XxwYZ2ApiTFhI/A5JHJA91eUEH2TQY3qryhnEB3kH+BQh8ItHUYRnWZAJ6qOAZXgImvVfUB/vKsg7EiQf6IAXc3DngaNqEDzEyVocVEJWvTpg2xanCxBU8uRP64E+e5+2dKgf9lPNFM+Vp7UPtHd1iUwiwe30mS+uPPONNenlsz7U3euL4a2b4821YNnADqyQB8Q2HFBR88AdEtN/NmlQXeTxqcHupUdttvTi4HuZodPD/SZBXp0adDdpPHpgW5n6gMHIeOCPn8GoEd90IOBg8BxQY8c0B2cn+jxiBHWo7mJfyCk4yQnyNrvTu1jjVOTE2TNd2QftDx2cuIekLwwbSiVuBTTWmbZW5+HMm1mMW0xLtGaCTM20c5NmP+eB04CYzt6bCK4xyEPJsKpQb3Y8mCdXfl/e3blJD7RyMFyj1FegnUwWHbCNLbEuscvL8E6GCz7DdfIL6YC99jmZT18yHqIjsTvZCLYyd/ZXg+o4v6XOnXz/e+d0Lvf
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-static-agents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless-static-agents.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-static.drawio:
--------------------------------------------------------------------------------
1 | 3Vhbb9sgFP41eWzkS5zLY5d2mTZNq9qHro/EPrZRMViAm2S/fmCD71maKuuqpVIFH5wDfOecD5KJv872G47y9DuLgEw8J9pP/JuJ580CR/3XwKECFt6sAhKOowpyG+AB/wIDGrukwBGIzkTJGJE474IhoxRC2cEQ52zXnRYz0l01RwkMgIcQkSH6iCOZVujSHkvjXwAnqV3ZdcxIhuxkA4gURWzXgvzbib/mjMmqle3XQDR3lpfK7vOR0XpjHKh8jYF8dL4l9y9PSXF/BQtxl25+xFfGywsihTnwBkuzX3mwJHBW0Ai0H3fif9qlWMJDjkI9ulNRV1gqM2KGY0zImhHGS1s/QrCMQ4ULydkztEbm4RK2sRoZnsRuC7iEfQsyJ9sAy0Dyg5piRn1D8sFmj+nvmpi5NhBpK15zgyGTJkntuWFSNQyZZxA7GxC7JoWQwP9ArnOaXM0IVtl5TXBCFSZZPqQ8DvTfKOXlR1swKlt49blMKLygG4vVMBQ17e1Q1DG8eCyCQSy+An3GVFw20QNYRrMx1pfe1i9ZvwS7i16m+/860+cDdge0Ao2utRarXkiQEDjsMgl7LH+22k+6GKaB6d3sTW2UnYPtULX5n+1Oy0p3G7OyZ+2OxkCwgodwWisl4gnI0+kGUedmGUa0FbFgJGAW40CQxC/d+2gsimaFO4bVyeqEcXsJU/u1LqpzG6v2/dFzVF9k1pHTc1QRM3BUJlV97Lfn2WL8qnJ2sE0ZexY6NBwniZZYpy5wJ8c5EExBNbcFJpGYTrw5ynQt063I64xopasqRdlN0G5JU6bcdevfQMjIMoFYjqh1hqNILzKqLN174AJS4faEeD6iFLORxPtrOrw8SykMpRESaa3Ibc2o678p+af22Ln1f7KuFx+qruvyO/RCeXZdH3s7vVNdr47fzk5W0uY5FFQK6Je/5q2genNUU02LbFvWO4vb9e1ca2NUkiwKojys9S60JyxKqVebxhnoti46XgjtX09SlUm0ViA9mcm09G7nNh5KK7MGYdLuQOkECL2D/1NRZr0bYDbytHPe8+1hvyVeSFLMM8SZevbt8dQaOvUOmS46QuS8VYhOPkSCVwrW6kMJlrvqZo/fz4pXC1YvDX33UoKlus338Wp686OGf/sb
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-static.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless-static.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-teams-recovery.drawio:
--------------------------------------------------------------------------------
1 | 7VtNc6M4EP01Pk7KSGDjY8aZydZO7e5UcpjJEYMMqmDJBSK299evJAQYicTYwWAnmzkMtNDX66dWd0sewflqe5946+gvGqB4BMbBdgTvRgBYlj3l/wnJLpdMgZ0LwgQH6qNK8Ij/RUo4VtIMByitfcgojRle14U+JQT5rCbzkoRu6p8taVzvde2FyBA8+l5sSn/hgEW51HXGlfwPhMOo6Nkaq5KVV3ysBGnkBXSzJ4LfRnCeUMryp9V2jmIBXoFLXu/7K6XlwBJEWJsK7Nf4R/jw8hRmD1/QNP0Z3f+z/KJaefHiTE34HjM1XrYrQEhoRgIk2rFG8Osmwgw9rj1flG642rksYqtYFS9xHM9pTBNZFwYecpc+l6csoc9or2Tiu2ix5CUvKGGYQ34b45DwMkZFk2pkvAxtX52yVQLJGYjoCrFkxz8p6aew3xWkUu+bSpVWoZ9oX40zJfQUfcKy7Qph/qBAPgJw2wB8HmcpQ8kboI8Pg94MoaaKpSP+NapC/okalLA9ef7XjTKAU1fGzNQFhA26gONz6cIxdPEnIs+YpFx42+0icJAb2E3Iu2ABJfJdIDzV6A5b0n1yLoQnBsIGrIgEt8JO8zc/9tIU+3Uk+dyT3W+1CuTLk3i5AU7xfrfdL73bFW9bzH4XjfDnvJqj3qpK4qWok48OBcaeoKmAz4BmiY/emDpQc2deEiJ2iIWmTvd05jSorJAlKPYYfqmPt0mPqoefFPOZVJSZ1CnjaEzIp6kq7W8uejug3g7QF20Og9GQZFU569OJNjOI9t3DMV+tYFyt6QSlWczEEybCFyi+WGQ4DlKJOYtoJqZFKMNLblAZpiS9ye3BmKCNrJsyj3DdcxKsZUPZWjQilPYjW6CEIIbSfOpc/RGSPa9jbipWSGJGEJLdMbxC0p+RrWKGvZj7P7I3Wb8c8gjM86YS8T0uCtcowVRMYBMhIgdNRDldlv0WY5U1ZOUkIwSTMG/RI7I2WkSUPucASKgFMjfGSuWGidXXZt2aye7rpk+JPLUrxWjJGjarFQ4C0UmjUa1vg2dwCuDMNayk3bQR6WujMytZDKilmVSgBl4aldvRvsFUdq+ydU97Jc12rzKye3b1qWZWm41shwYTtjWYsyENZukZFuzR987WFtPWGrL6tZiW6fp/FXZQjCBE5J1BQLHifd4S921NV3SJJn5jVBBMZ4txR0vd1nYlyzYdolkDV8DZVjr4BKBDDXRnaNDhJwBdsybWZGjQzUD344GuRbTWdGjQzYj244GuRxqDmxczyP14oGs2HQxuXqafAHTNpoPBzYtrgG7gfDCdc0JW5rUU0KEM0Ki74EQZ1oOxifWKSvsJTqBmG209C9M2OIFaJhHqse+5gxMzn/M/05pCiaGYVjJLd32OZdpEY5p+8HJmohULpm+idU2Yq+eBEcDoDZ2bCGY65GgitFXqYNuDlruyTs1dGYGP27OyzDTK8av27Kb+sAkfdOnqbCgTkkezQTtDMg7Pz80GM7/zWZwF2Jpqk0ui2umGR/MW+j5mBGZWa1CqTS+Sa9MhuWakKk6NgWxXa6jnAxpg5pUe0FqcFRca6yq7ofp516EqcOorfOiTFmAmiBR65oq9PPSGzvQAM9Oj0ON77SQWh/iLhD+FrATgkvEEDff++sXTzGcoPO2rxLPhYlmveBb9m3g6V4De0MlzaMa6Dbel3slDPWXu+qg5Zb5wHRFPnuUGZLlnD3YDEnYRqg58k3FQfw7oe+PJF27027E9Z5jghYWpBy/Qdkkh5U8cjB3goAkyg2t6JqM117TYoe8EGbywOLVPqs2ukmrGbn8q1QB0+qWaeefk2ja43Ju8GCacfAdfd356PrSFZsLib3lj/oP5lA0/XOrZpzRzG28tudb3xcGVXRhvm5Ac9MI41O95n+q/Qli3E7a+Y5y8vPlr9TPU/PPqx7zw238=
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-teams-recovery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless-teams-recovery.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-teams.drawio:
--------------------------------------------------------------------------------
1 | 7VvbcuI4EP0aHidlSzaGxwyZydZuTc1U8jCTR2MLrIqxKFkksF+/EpZvaicQ4gskm1QlqGXJ9umjI3VLjPBstb3l/jr6wUISj5AVbkf4ZoSQbTue/Kcsu8ziISczLDkN9UWl4Z7+S7TR0tYNDUlau1AwFgu6rhsDliQkEDWbzzl7rl+2YHH9rmt/SYDhPvBjaP1NQxFl1olrlfa/CF1G+Z1tS9es/PxibUgjP2TPFRP+NsIzzpjIPq22MxIr8HJcsnbfX6gtHoyTRBzTQPy2/lnePT0sN3dfiJf+im5/Lr7oXp78eKNf+JYK/bxil4PA2SYJierHHuGvzxEV5H7tB6r2Wbpd2iKxinX1gsbxjMWM79vi0CeTRSDtqeDskVRqxsGEzBey5olwQSXk1zFdJrJOMNWlfjJZR7YvvrJdACkZSNiKCL6TlxT009jvclLp8nPpSjv3T1R141QbfU2fZdF3ibD8oEF+A+AOAHwWb1JB+CugW4dBb4bQcMXCVb+Nrtj/qBYsERV79tOOM5Bbd8YU+gLjBl8g3JUvXOCLv0nySJNUGq/bHQQumYROE/ITNMd75NtA2DPojo+k+7grhMcAYQArScJrpdOyFMR+mtKgjqR8d777o0fBvvCgClfIzcs322rtzS4vban4k3ciP2fNXF0qG6lC3iZ7OhKCOcFwgXwDtuEBeeXVkX534fMlEYdYCH1a8Znb4LLcxknsC/pUf94mP+o7/GJUvklJmXGdMq7BhOw1daPq5GL2g+r9IMvoKIMBdLRnVfHWpxNt2jyPSXjWLKWCcUrUqF5QThS2ZB4x9pjuFxNqcUJCKZ5CDm5klRIg/wo/CVTDmS4SP8zbiEj1tJboLxhf7Q2+umOq1g5Fz34QsNWKhbLzok1CSJhegYEgx72oU78uFglLiKEs2uRr0Y/JQjTMBSsahuomjZpVn2U6mHNxgwhhp4HRTlcilD/QkSqkQQ39NCrUvqpHWlasK8+tKIv9qq6UIlbRrYeabDWLWIuClK+eD+nRdEg9KhZeOXvMqeloQXKMjux+BcmGK+uvGxor+ZAhQ/LONXY+4gPZk1w6wpXegoyDxkV36E3nVktD3TFE33bgUJ82reg6G+noE4CODdDdoUHHnwB0Q03s8dCgwzjy44FuBIy2NzToMGD8eKCbC/nB5QXGkB8PdEPT0eDy4n0C0A1NR4PLywSADnA+mC05IenxUoblUIJl1F5sooX1YGxiv+DSfoITbGijYyY5jg1OsJGow2bapevgBKZL/mdaUygxFNMKZplLn7cybWwwzdzX6Jho+YDpm2htE+bieQACGLOjrokA0yFvJsKxTh1sejByV/apuSsQ+Ex6dhZMo7x91HYu9YclfNCha7IB5LePZoOxRQP2prtmA8zvfJbFAj6aauNzotrpwmOsFvrexUMwqzUo1byz5Jo3JNdAquLUGMiZGB31vEGDYF7pjqzVnm3usbayG/o+79pURW59hA+904JggkijB0fs+aE3dKYHwUyPRk/OteNYbeLPufy0FAUA54wnajhW1y+eMJ+h8XQuEs+GIxO94pnfH+LpXgB6QyfPMYx1y0NF76TfWZwrLKbqwc4V4jYi1IHPBw66jEPmlHjyORvzzGnPiSV8ZtHpwWOpbVJILyMOhgx40LwY4JqZwDiaa0bI0HdeDJ9ZeNon1aYXSTUwyZ9KNYTdfqkGj5pc2gSXLSLPhgknn2w3Fz+t7dXKYvntr+zy8jt0+Nt/
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless-teams.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless-teams.png
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless.drawio:
--------------------------------------------------------------------------------
1 | 7Vtbb6M4FP41eWwENtfH2cxsR1qtpmpX6vSRgBPYEhwZ57a/fk2wudhOmzAEOplppTY+NgZ/5/O54UzgbLW/J8E6/htHKJ0AI9pP4OcJAKZpuexfITmUEteFpWBJkogPqgVPyX+ICw0u3SQRylsDKcYpTdZtYYizDIW0JQsIwbv2sAVO23ddB0ukCJ7CIFWlz0lE41Lq2UYt/4qSZSzubBq8ZxWIwVyQx0GEdw0R/DKBM4IxLT+t9jOUFuAJXMrr/jzRWz0YQRk95wL6bPy1fNy+LDePd8jNH+L7b4s7Pss2SDd8wfcJ5c9LDwIEgjdZhIp5zAn8YxcnFD2tg7Do3TG1M1lMVynvXiRpOsMpJsdrYRQgbxEyeU4JfkWNHif00HzBeraI0IRB/ilNlhnro7iYkj8Z60P7k0s2KyAZAxFeIUoObEhFP449J5/p8PauVqUp9BM31WhxYcDps6zmrhFmHzjIFwBuKYDP0k1OEXkDdON90PUQSqpY2MWvVhXHn+IKnNGGvPzpRxnAbivDV3UBoUYX1cDedWEruvgHvVKcMdlDskZpkqF+t4KNvMjS4e+BOTzi3wPO0LPbpPft80gPr4Wzo+CswIqy6FNhrVkrTIM8T8I2kmzt5PC92AtTYIv2S7Pz857vlLJ1EK19Qr+Lcezzy3EOm7fqi4qGuKZ8OhQpnkFSAVsB3pAQvbF0wNdOA7JE9I2B0NMrtaE0W6MzISMoDWiybT+wTpH8Dg84YUup96bT3pu2RIVynfyipo+R5wHteYAhTVTioEx0pFW16u5M8xWmPaN5jPFrfgwHUKEydHxgitkfsd0lMrK9R9v0a2/YDDPD0N7dXBRw85uiBdVY5VUSRcVNtHajbe978X7WtG0KIDCmGmNgmhqr+waHfsgYANUaPKJ1oQ1TUcRFxlZgHzJ4mDvtB0LQBrDicwM+X+ezrmVKgXsKPdWmfjz04NjoeafQY0mJkxZbds4CMWdJKwA+NJ6acHZQPCHowbN3cNCNaOCiYKBPx+7+HI5dokyVAV3s2V0plXKH9ewQjk41dzSueT8n1+TE7WyueRLXvIG5prqJh4JW/ToEgilDGxcy39Ak6wvkhNq6SeT6c6OvGBFabZcipmhQBni6+NC7lk9RY3jhm6NkK5xznZ8b39aIBBQTMYrdtTFwaKUtwAmlOXPH7inDNz1whtLAgEoT5bI+rHNtkV+aBvmjBgLwbOPsj2mcq4qmSAW7BgKVVRcTmcMaZ0stWd9E1c6XM82xq3aWGtzfAtCWIQFtjg60GtreBNCmBDQYHWj15ctNAK2UWUYHWg2gBw4HmsFAIzYYIBzwzwwH7DGjAeD7bcpYdrdoAJrvTHTtaECXLVzKtI6s6cLQMZhmnTAfw1DNlQJP5ZXQ2VRz5VLWsFSz+8hxbp1qYFSqSW8xlcL3uVRzDakA5Q5MNTXH+U01bdQ8FtUcqRyuxFKdqeYNTDU1y/tNNW3eMBrVZKvW9XCG471jHq9Ntcte4fAjFVGQx1X6pc0P3FHYM2o1D0hWw+oaVAE5OpPf2VybE+oZvPJVi7HAZBeQqDi4g7ZMO8WH46EdbenfoHFwPNZDgixn0KJi+L8oe02y/G4/PayKJ1nXV7LlNA8ANSclqAQvnyrsvJGDQUC8vBYlXN1RzEELBvZlRwTPNg1gFNNgj5vby2f5uvoLKBkZIB+KvrZtuKyKdDYpfkFOQKkW29lfQDnu7Y0TrFl/F6IcXn+jBH75Hw==
--------------------------------------------------------------------------------
/manuscript/images/ch11/serverless.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch11/serverless.png
--------------------------------------------------------------------------------
/manuscript/images/ch12/prow-assign.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch12/prow-assign.png
--------------------------------------------------------------------------------
/manuscript/images/ch12/prow-collaborator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch12/prow-collaborator.png
--------------------------------------------------------------------------------
/manuscript/images/ch12/prow-lgtm-own-pr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch12/prow-lgtm-own-pr.png
--------------------------------------------------------------------------------
/manuscript/images/ch12/prow-pr-label-hold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch12/prow-pr-label-hold.png
--------------------------------------------------------------------------------
/manuscript/images/ch12/prow-pr-merged.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch12/prow-pr-merged.png
--------------------------------------------------------------------------------
/manuscript/images/ch12/prow-pr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch12/prow-pr.png
--------------------------------------------------------------------------------
/manuscript/images/ch13/prow-failed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch13/prow-failed.png
--------------------------------------------------------------------------------
/manuscript/images/ch14/jenkins-x-platform.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch14/jenkins-x-platform.png
--------------------------------------------------------------------------------
/manuscript/images/ch14/upgraded-webhook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch14/upgraded-webhook.png
--------------------------------------------------------------------------------
/manuscript/images/ch15/codecov-github-pr-checks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch15/codecov-github-pr-checks.png
--------------------------------------------------------------------------------
/manuscript/images/ch15/codecov-github-pr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch15/codecov-github-pr.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/blue-green.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch17/blue-green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/blue-green.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/canary-grafana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/canary-grafana.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/canary-rollback.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch17/canary-rollback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/canary-rollback.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/canary-rollout.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch17/canary-rollout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/canary-rollout.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/knative-request.drawio:
--------------------------------------------------------------------------------
1 | 5Vltc+I2EP41TD8l4xf8wscklyady81kmmmv91FYa+xUWK4sAvTXV7LlF1kOcIBzTO8LoJW0Rs/uPrtaT9y75eaBoTz5QjGQiWPhzcT9NHEc254G4ktKtpUkCNxKsGApVotawUv6LyihpaSrFEOhLeSUEp7mujCiWQYR12SIMbrWl8WU6E/N0QIMwUuEiCn9mmKeVNLQs1r5I6SLpH6ybamZJaoXK0GRIEzXHZF7P3HvGKW8+rXc3AGR4NW4VPt+fWe2+WMMMn7IBva0hj9X29d5/Jl+vX/6Ej8+vl55lZY3RFbqwJ9Xc2AZcAG6QJWsCg5MHYBva1QYXWUYpGJr4t6uk5TDS44iObsWfiBkCV8SMbLFzzdgPBWI3pB0kQkZp3JBTDOuzG17YmweR51QbodNR6SO9wB0CZxtxRI164QKauVr9kyN163lXF/Jkq7VAiVEylsWje4WUPFDYfod+NoGvjfPvwnBA+KwRtvTgI1TQu4ooazc62IPQjwV8oIz+jd0ZkJn7vr+mUCe6SA77gDI0wGQ3bEwdg2MDVhF7OXyJ4q4xGQfsGeAyfU8DabARGkIJH8skKb7QYIM30jGFKOIoKJIIx0V2KT8L+mZ154afevMfNoopy0H23qQiT9fbXK8evytO9nuK0f1xndNUNAVi2C/O3DEFsB3rPOrdYC1BGAatGMxb8BitYwBQTx909PGkBnVE55pKk7WhpX3TljVKqpzq11dmu8pcq0eCYY9RRUwhqLSq5pjH+9ovuFo9xuRQjIkdz5RhMXXLSIoi07NK336QxDG0RD9+VEI83gc+rO9H01/wTkj27no0PYPDG37okJ7GvRcxjkytA1F3seGdl2T73K1hQjh3AzOOAY/GgxOHMzm1k63MIKzqfbRvH6sNWzgmhMDPRmL+t0I2qYG/JB0HBpIojwnokrmKc3OSotxHDvvIO/PfW+4Ktxt/v1kudU5bx/Mo3HjzID5nxWs4CpndHPe4vsoBz8V5h+Gq23ea7476fQvgCeWlx+UguoexL4UNLusFOTrmcM9trr07F6Z+sHVpe0Yjmdfi/EfBTDZsCiE15VwiTgvuJRwKj8SkMZoC1FSFaLzphAVSxAvFbC3ShUqP0qfLvOM2J/hq1ye7NpwdhGpXHdvnQcymkGPNJQIqa4IgZgPNEuWKcbyIYN0pBPWCB2Vqaube6Ch0nTqhtz2/MRjNqx2EY/CGKMiKWGyD6SgDgFZ14G3k4NO4BLnokjC7hnbnh5JEm6/D9dXNDZJmHdQR5LE0+0vMqZpRiSor3QuFTUcEVO2RmyIPaQTic+4IZIEEOGJVJJRDD2WySnjJdnktICSZLbNXNX8W1TNv5+GRexwqvtDEBo0Mhvwazt0xqIRszAcgUZsjUac0WjkwjpZgW5tx57Jsx/HJL0br2N9LJPUN/X/RbpxLqst4vUaldP+ZfvgtkivuHX6b3PGdhLzMuTKdKPe8ZQ55/BkUyWKZ4rLAxQ0SoUaXFpFGKWqSDFdojSTz/i93S38QRWyUoHWThAyQfKLpJnVbsGWSApRUv+9VK6PEglZnfQiSghEPM0WUgEQKBH7adKX7+0tgpu3vt04MfzwgPQlhu0b4cpB2/fq7v1/
--------------------------------------------------------------------------------
/manuscript/images/ch17/knative-request.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/knative-request.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/knative-scale-to-three.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch17/knative-scale-to-three.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/knative-scale-to-three.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/knative-scale-to-zero.drawio:
--------------------------------------------------------------------------------
1 | 5VnbcqM4EP0aP46Lu/Fj4mSTrWSqUpXanZ1HAQ1oBiSvEDGer18JhA0I32I7k6r1g023WgKdPuoLntiLvHpgaJl+pRFkE8uIqol9N7Esx3LEt1SsG8VsZjeKhOGoUZlbxSv+BUppKG2JIyh6hpzSjONlXxlSQiDkPR1ijK76ZjHN+nddogQ0xWuIMl37DUc8bbS+a2z1j4CTtL2zaaiRHLXGSlGkKKKrjsq+n9gLRilvrvJqAZnErsWlmffHjtHNgzEg/JgJ7HkFf5frH0H8RL/dP3+NHx9/fHGbVd5QVqoNP5UBMAJcgC5QzcqCA1Mb4OsWFUZLEoFc2JjYt6sUc3hdolCOrgQNhC7leSYkU1y+AeNYIHqT4YQIHafSIKaEK3ebrpD17agdyulQdVRqew9Ac+BsLUzUqOUrqBXXzLmSV1vP2Z7SpV2vzZQSKbYkm7W3gIoLhekJ+JoavjcvfwrFA+KwQuvzgI1xli1oRlk9145c8CNH6AvO6E/ojPhWYHvehUCe90G27BGQnRGQ7Wth7GkY31eCtATJmc8UReLnFmWIhOcyeQg4Aj8OxwD3Qh+C+DqAm+7vBryNzR3ENVwTAexShyyOwQtHIYtm88AwToJsE/VR0N7W2Aul4w2467salJtY0IXSuxaUvoYkWi4zES05puSiZI3j2NqBvBd47nh02O/+wxRe95l4COarMXauwfxvCSV8WTJaXTYIv4vg58L823C19NiroTlSCTyjALIXWuCa5fZdQDmnuTDI5MAtCn8mtQ/69BWfndXEpriSAEeoSDfua/zQ1m5WY7uUz5ZXiSxZp5gWs2mOi3AqaldR+Iw51TAMY8ypm8caljNIPV4GMb+Kz6t+ZOpQYKzCuVoAM/UKR2MAkOhGluJCCjNUFDgcHKEBdlBh/o9039Rqxe/KVF7fVcq1tbBuBSK208xyW/F7d2w7rZbaeTvTTUFLFsK+rTd2HLEE9jm1RQSiXqux9xi7Iz5sdQwykR7e+g3KmGPVHV4oFlvbmQTtYXRoNq5mdRuKwUKuOcymg4UaZLSFap5ttn0G9SyNeuZUyH8VmCTSMeI0KywWUkxB9pNt4W2ICF+GENUjiDcGTJqsmh9Ca6xFoih4UbeOTO5NGqQ4kxaIyNkF1KAgIp+XiAhRhk3yFo2q+HoitbOm2qkQB5z3z0E/uhBKhqFIqQaxZRgRcxxF8iajmauf267QhJlHlKv+CLst52pJSueJcsplM78fwnjmD3zXcU8rbY9vv8ZKWPtDawC9hr1YBjA74V/F9SMSQC/8b7PBjgRQSy/AsIAD2NlZod394bTgfaq0YPvOdN75+H2aDd+QHJskbM/tLzR3PzRJWHrpv4+dKsJuKkjzAE9bzpmncW4nvQ6ypk16n4U1Wkf9Tp6YziBtzD+2mGjDY4cn1nSbviVh5EthmfBFo0E29QQp80C+VjJoXKNZN+9FKzc2vZa+qQp+AaP/m5Jg+F7Wnuklweh72auVBPZpXct7o8KlWpGDUaFl7yeJCs7gMNvmO6PCkDmWd6nsIcTtXy+N+fb/K/v+Pw==
--------------------------------------------------------------------------------
/manuscript/images/ch17/knative-scale-to-zero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/knative-scale-to-zero.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/recreate.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch17/recreate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/recreate.png
--------------------------------------------------------------------------------
/manuscript/images/ch17/rolling-update.drawio:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/manuscript/images/ch17/rolling-update.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch17/rolling-update.png
--------------------------------------------------------------------------------
/manuscript/images/ch18/jx-boot-github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch18/jx-boot-github.png
--------------------------------------------------------------------------------
/manuscript/images/ch19/app-dependencies-shared-env.drawio:
--------------------------------------------------------------------------------
1 | 5VrLdqM4EP0aLyeHt8kycTLpzkm/Jt0n00sZZNA0II6QYztfPxIIDBIExoNtkl4kQaUHUtXV5aqimbmIt3cEpOEn7MNoZmj+dmbezAxD1+cG+8Mtu8LizN3CEBDki0Z7wyN6gcKoCesa+TBrNKQYRxSlTaOHkwR6tGEDhOBNs9kKR823piCAiuHRA5FqfUI+DQura2t7+weIgrB8s66JmhiUjYUhC4GPNzWTeTszFwRjWjzF2wWMuPNKvxT9/uyorSZGYEKHdNgu7zPr6eP3++Dpm429Tz++3H/+QxfheQbRWqz4NnlGBCcxH9bQCExxhigmO7EKuitdQ/A68SEfXZuZ15sQUfiYAo/XbhgYmC2kccRKOn/EBL3ghILS8AwJRczPVxEKEmajmPdQFyXWyZvDbc0kFnkHcQwpn50maivoCMTpZQA2+/hZpS2sxc68FEYgMBNUY+/dyh6EZ/+LlxUnX6UpM+iv+FTv9+kKRdECR5jkfU0fQHflMXtGCf4FazWO58LlaiT3GpJ756p79Tb3Gsfyrgrhm+tW57IdmPJHbxch5mXS7+FlEY6HZWUA3q8gD9KXNWWjwI5Q2ND1rbZQuMbSdJyRQmE3Q8FwrYTCaYmEe6xIWEoklBjAxL/itMzDEIEsQwVgAaGquRYI5iSy+5tTzYVdFn/W6262goeK0q4sbRGtdWOln7WafSdeKPt0RibDa+LBfiSy1QSQ9vMB9BvfHjXOtTjaLXEsbQRGgKLn5herLbjiDV8xyrm9BJm0o01NwkexbtGr/oWRB5pLeLSlgQrHKAPlWKuWfTj87A6aVVE4fZo1nanRrNNOs6pz3xvNVrpgKjQ7/81p1hlIs/akaNZwRqJZUz8vzbodNGu+QZq1tanR7GU7zarOfW80a5sTo9lym/22PHs5kGfdSfGspY3Es5Z8vDoxz+pq2mAY/upAOwAwXeDUesB5ONDcgUCb1rnJkuChH4gzSV7qzjCYsbiDXa1Zyhtk3dO15ROFrb06rYpY29uzh2IGh2L+r+TBoXTpPiw3dJ7dPcT/vDgtuZxCW1jn0RbK16sF34MzZaZ9Qm3R6l01P1N4136D3pUPyOf3rnpALrzrvEHvyrr4/N5VD72PIVuOz2w314qHJyiO/x/apY+EpavxOJY4bg2Heggcpk1OoI3rQufCHKCNJT3Rq2Few2ddw3R/4c6W6pVSB9b8QM2iS+xryft+JNEiixDLtI4vQtQj+FSwrU8b285ZsS1DRf537lBsG1IiwrKOg21ZkJ8E2+8qqXFScFtnBbf0rzVLzkUMBrd0KLHk7Mh4SY12/KlJjY4LJwiyvcPv9VCAkrxiBVl0vdxMMZ9y/joaQv6cphHymItxwuvJOklQEvDZJPs2WYY9BGguGj+DGGZcDV6wwve8fhPiiP+FjQkhPh5gPxHKeBmv2C8fpmyXsNkUs2Ta0gv5bAF/2xK2TpdFSJnogjdf03wxGS5bZqWyrb/mQtmnTE7S5hZsatAEc9HaEKzCBMSlmwiu+AjyXZwY+T5/Satmbl77mY1wTpZESZUI7ruwI++B0cRty62o10hSONUHWVgd6o6Ug+vj0hF5sdyp/Vm5s0paQ+v5Wg9O90rM6Mhnp4OZkRX31/yK5vvLkubtvw==
--------------------------------------------------------------------------------
/manuscript/images/ch19/app-dependencies-shared-env.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch19/app-dependencies-shared-env.png
--------------------------------------------------------------------------------
/manuscript/images/ch19/app-dependencies-shared.drawio:
--------------------------------------------------------------------------------
1 | 5Vpdd5s4EP01ftwcQAKTx3x00+ak292me7J9lEEGbTHigBzb+fUrGWGDJBvWxYGkLwmMPpDuXF1mBk/AzWJ9l6Ms/kxDnEwcK1xPwO3EcWx76vB/wrIpLd7ULw1RTkLZaW94JC9YGi1pXZIQF42OjNKEkaxpDGia4oA1bCjP6arZbU6T5lMzFGHN8BigRLc+kZDFpdV3rb39IyZRXD3ZtmTLAlWdpaGIUUhXNRP4MAE3OaWsvFqsb3AiwKtwKcf9fqB1t7Acp6zLgPXsvoBPn77dR09/uTT4/PeX+z9+s2E5zTNKlnLHX3FGueUqy/hfINfONhUgOV2mIRZzWhNwvYoJw48ZCkTrilOA22K2SPidLS5pTl5oylBleMY5Ixzdq4REKbcxKkboW5G7E93xumaSW7vDdIFZvuFdZCu8lDBLntkV7Ku912wobXHNY07lMCSZEu3m3oPJLySe/wdbcBxb561gC9zxYescx9Z+K9juhG5E2GrQtmNqt2M6J0lyQxOab8eCEGF/HnB7wXL6A9davMDHs3lP8DoKvFMDvI4R3jOhqxP39toILn9fZOIy2CSEo5y3Izwr3fEw2xlQ8CPaOunLkvFZ8AFXuNgPockVvjMDnteTKxQV4ZqtucIzeMI/lyf0V5/mA5yGVyKIEG5IUFGQkrAoZ7q55ggOUr75R0jNhVvdfq+33a6lDpV3m+puTVhtGL/7XmvZDxI31ZiDninoMg9wOxP5biLM2vUAh41ISfdzzY+uwY+VLccJYuS5GV+ZnCuf8CclfGc7GtnKiQaqDpb7lqPq8ZA60VTho6tMVAKjTbTl2m7bp9PPPSCzx8KCscos8MYms55ZZnVw35vMgsuRyez0F5dZr6PMuqOSWcfrSWaBPazM+gdk9lhmO1aZda2xyeylWWZ1cN+bzLpgZDJbHbNfVmcvO+qsPyqdhVZPOgvV9OqVddbWywbd+Fcn2gmEOUROq4WcpxPN70i0ceVNUKGHfSLP1Dqr141m3O9oU+uWiQ7F4eW6akbhWkeXtRNWc39+Ua7gVM5/TR88xmb+w2zFpsXdw+LfF89QKWsUIeGREKPvIqT25jJwu3MREnQtQk57eJsZkdWrZO2QnjFq+zl01YqF+4pRmxHdlg8T7lvhrfphYnje6jXFdkjHylu1qDM8b/WSWYO33lvhrfqxcnje6uWydkjHyls1Sx6et3oJ7DHm2wm57fZaQ3iEqfLP6YjCdmjr/jhXqmx0h14S0nwwVKZcT3suQIdMWckuWjOaY/ysZzSHo7LBPvwoQSpUxbDzhx/lvQbVc99TCqOmJBBAhbpnSEn0gtxYuG2Pm9veoNxWqXJ5IrcdpSwJ4Xm4rabnr8Ltd1XifFVyw0HJrXxoh2plsjO5lUQaqrXS/kqcZv7p9Z5vMZ5sf9pZRnMhYmiGCmELKebnx0qp2MAMJzSNhNfXQbIsOJaJwJ+J3AWl4rIgaZSIcSjLEp50MELTLQPEosQUAUqrucTseM6jOvFIIrqx7TJyngwVhNGtb+l8P3eGAzLnlN/OfqGdGR7aseZxaMaDKRUBZCN4lCYkM6MEz5khYVqQMBQPMcavzdxs0kOdRQkQXEOcCU1xPzhXoGn4leIxwZKghqiIdwnWmarjbbrWo0ZVp6ZVpKZDipRjtbw4O4uUWpNSX+UnixS/3f9avOy+/809+PAf
--------------------------------------------------------------------------------
/manuscript/images/ch19/app-dependencies-shared.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch19/app-dependencies-shared.png
--------------------------------------------------------------------------------
/manuscript/images/ch19/app-dependencies.drawio:
--------------------------------------------------------------------------------
1 | 7Vpdd6M2EP01ftw9BoGNH7NOmiZturvJ7knzKINsdCIjjpBje399JUvYIMmfJS5J+mLDIAl053JnNKIDhtPFNYN5ekcTRDp+N1l0wGXH9z2v74s/aVkqS68fKcOE4UQ32hge8C+kjV1tneEEFbWGnFLCcV43xjTLUMxrNsgYndebjSmp3zWHE2QZHmJIbOsjTniqrFHY3dh/R3iSlnf2uvrKFJaNtaFIYULnFRO46oAho5Sro+liiIgEr8RF9ftty9X1gzGU8UM6LEa3RfB48+N28vg9pPHdz6+3f33yAjXMCyQzPeN7lFNhuchz8Qv0s/NlCQijsyxBcsxuB3yZp5ijhxzG8upcUEDYUj4l4syTh5ThXzTjsDS8IMaxQPeC4EkmbJzKHvZU9Oxkc7SomPTUrhGdIs6Woom+Ggw0zJpnXgn7fOM1L9C2tOIxv3QY1EyZrMfegCkONJ7HYAt2Y+u/FWxB2D5s/d3Yem8F27XQtQhbC9r9mHr7MR1jQoaUULbqCxKIonEs7AVn9BlVrvTiCI3GDcHrG/D2HfD6TnhfCV2buJdfnOCKeJHLw3hJsECZ7Ud4pNzx52htgPHzZOWkrzMuRkFbXBGiKAlcroj8Eej1GnKFoSJCsy1X9ByeiF7LE3bos3yAsuRCJhHSDQQWBVaEhYzb5oojBEhs+beUms9hefpUvXa50Dqkzpbl2QLzSjdx9lS5sukkT8o+Wz1T0BmL0X4mitlMEN+vByipZUq2nyt+DB1+LG0MEcjxSz2/cjlX3+EbxWJmaxp5xhsNTB1U89a9qvmQOVDf4GNoDKSAsQZacW097dPpF26R2V1pQVtlFvTaJrM9t8za4L43mQWDlsls/4PLbO9AmQ1bJbN+ryGZBd5/K7PRFpndtbJtq8yG3bbJ7MAtsza4701mQ9AymS1fsw+rs4MDdTZqlc4G3YZ0NjCXV2fWWc8uGxzGvyrRTiDMNnJ295DzdKJFBxKtXeumwKCHdyLPzDpr7zCaCb/DZaVZLhsU2x83NFcUYXfnY62F1d1eHKgnOJXz33/ckZfr4d394xzk90+TPwbPPx2VsgdFHrkfkcg/OpZMSeUhzHOCY+FCmhUKCOF6dZPVsWiFmfhPUC7eE5TFGEkzlj/PKJdzxVl9nE9FjmI8Fq+RpEdOC8wpE90+W2+eiGq8/q7Vo2NGZTithVJtgrriSdCYOwqhU5wk8ibOaF6vuTYQdc1qKQjsBChwJUCggbDrpIBdztulehrTBBbpOtFsc6Ddxfr9+ue3SgDNhUhgKtfBKxpDmgJTSpuLtE787W2l/ylnbLm1hHJmTnYy5cyoC0w9e2XKHVcqP5Fy+zI2N+W8f0+5nTvjVc7t4mZbKGesS4G5DHgrlLPL41cwTuv5T5keiZSJ0CUcEbRKksoMipNlmYJRkV0xmRd1b/gqO8s4xCoPU4/CCzv1EimNuiOT484KQWbh50VMZoVwECHLM+ZZasP5LEmWucPi2pKOHAxuZEfayQW7mN+E/Hg18dlo0T75qca7tRQ1Lj8Hqk+7qsaGZgSmZhy8N2esVoFZNntl8Tluz+JdEM5/k4TzjXDnDU4Nd+Y2xZnDnXObolov4CmUj5uhVRTi8lMnGMeoKKoxyY5hm+inQqewDY1hEroZnqcinEzsMHvx7ebjVBUiO96dt6hg76o0IT9HrvC2ArtXIlpWYd9SGTy+wm4EpebW/eJ08x2war75mhpc/QM=
--------------------------------------------------------------------------------
/manuscript/images/ch19/app-dependencies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vfarcic/devops26/c9738398b4a9e270817e3a8ca4333e27b166d851/manuscript/images/ch19/app-dependencies.png
--------------------------------------------------------------------------------
/manuscript/kaniko.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | name: kaniko
5 | spec:
6 | restartPolicy: Never
7 | containers:
8 | - name: kaniko
9 | image: gcr.io/kaniko-project/executor
10 | imagePullPolicy: Always
11 | args: ["--dockerfile=Dockerfile",
12 | "--context=git://github.com/carlossg/go-demo-6.git#refs/heads/kaniko",
13 | "--destination=csanchez/test"]
14 | volumeMounts:
15 | - name: docker-config
16 | mountPath: /kaniko/.docker
17 | resources:
18 | limits:
19 | cpu: 1
20 | memory: 200Mi
21 | volumes:
22 | - name: docker-config
23 | projected:
24 | sources:
25 | - secret:
26 | name: regcred
27 | items:
28 | - key: .dockerconfigjson
29 | path: config.json
30 |
--------------------------------------------------------------------------------
/manuscript/scripts/aks/aks-jx-gloo.sh:
--------------------------------------------------------------------------------
1 | ####################
2 | # Create a cluster #
3 | ####################
4 |
5 | # Install [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and make sure you have Azure admin permissions
6 |
7 | echo "nexus:
8 | enabled: false
9 | " | tee myvalues.yaml
10 |
11 | # Please replace [...] with a unique name (e.g., your GitHub user and a day and month).
12 | # Otherwise, it might fail to create a registry.
13 | # The name of the cluster must conform to the following pattern: '^[a-zA-Z0-9]*$'.
14 | CLUSTER_NAME=[...]
15 |
16 | # Replace `[...]` with your GitHub username
17 | export GH_USER=[...]
18 |
19 | jx create cluster aks \
20 | --cluster-name $CLUSTER_NAME \
21 | --resource-group-name jxrocks-group \
22 | --location eastus \
23 | --node-vm-size Standard_D4s_v3 \
24 | --nodes 3 \
25 | --default-admin-password=admin \
26 | --default-environment-prefix jx-rocks \
27 | --git-provider-kind github \
28 | --git-username $GH_USER
29 |
30 | #######################
31 | # Destroy the cluster #
32 | #######################
33 |
34 | az aks delete \
35 | -n $CLUSTER_NAME \
36 | -g jxrocks-group \
37 | --yes
38 |
39 | kubectl config delete-cluster $CLUSTER_NAME
40 |
41 | kubectl config delete-context $CLUSTER_NAME
42 |
43 | kubectl config unset \
44 | users.clusterUser_jxrocks-group_$CLUSTER_NAME
45 |
46 | az group delete \
47 | --name jxrocks-group \
48 | --yes
--------------------------------------------------------------------------------
/manuscript/scripts/aks/aks-jx-serverless-gloo.sh:
--------------------------------------------------------------------------------
1 | ####################
2 | # Create a cluster #
3 | ####################
4 |
5 | # Install [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and make sure you have Azure admin permissions
6 |
7 | echo "nexus:
8 | enabled: false
9 | " | tee myvalues.yaml
10 |
11 | # Please replace [...] with a unique name (e.g., your GitHub user and a day and month).
12 | # Otherwise, it might fail to create a registry.
13 | # The name of the cluster must conform to the following pattern: '^[a-zA-Z0-9]*$'.
14 | CLUSTER_NAME=[...]
15 |
16 | jx create cluster aks \
17 | --cluster-name $CLUSTER_NAME \
18 | --resource-group-name jxrocks-group \
19 | --location eastus \
20 | --node-vm-size Standard_D4s_v3 \
21 | --nodes 3 \
22 | --default-admin-password=admin \
23 | --default-environment-prefix tekton \
24 | --git-provider-kind github \
25 | --namespace cd \
26 | --prow \
27 | --tekton
28 |
29 | #######################
30 | # Destroy the cluster #
31 | #######################
32 |
33 | az aks delete \
34 | -n $CLUSTER_NAME \
35 | -g jxrocks-group \
36 | --yes
37 |
38 | kubectl config delete-cluster $CLUSTER_NAME
39 |
40 | kubectl config delete-context $CLUSTER_NAME
41 |
42 | kubectl config unset \
43 | users.clusterUser_jxrocks-group_$CLUSTER_NAME
44 |
45 | az group delete \
46 | --name jxrocks-group \
47 | --yes
--------------------------------------------------------------------------------
/manuscript/scripts/aks/aks-jx-serverless.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/b07f45f6907c2a1c71f45dbe0df8d410
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Install [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and make sure you have Azure admin permissions
8 |
9 | echo "nexus:
10 | enabled: false
11 | " | tee myvalues.yaml
12 |
13 | # Please replace [...] with a unique name (e.g., your GitHub user and a day and month).
14 | # The name of the cluster must conform to the following pattern: '^[a-zA-Z0-9]*$'.
15 | # Otherwise, it might fail to create a registry.
16 | CLUSTER_NAME=[...]
17 |
18 | jx create cluster aks \
19 | --cluster-name $CLUSTER_NAME \
20 | --resource-group-name jxrocks-group \
21 | --location eastus \
22 | --node-vm-size Standard_D4s_v3 \
23 | --nodes 3 \
24 | --default-admin-password=admin \
25 | --default-environment-prefix jx-rocks \
26 | --git-provider-kind github \
27 | --namespace jx \
28 | --prow \
29 | --tekton
30 |
31 | #######################
32 | # Destroy the cluster #
33 | #######################
34 |
35 | az aks delete \
36 | -n $CLUSTER_NAME \
37 | -g jxrocks-group \
38 | --yes
39 |
40 | kubectl config delete-cluster $CLUSTER_NAME
41 |
42 | kubectl config delete-context $CLUSTER_NAME
43 |
44 | kubectl config unset \
45 | users.clusterUser_jxrocks-group_$CLUSTER_NAME
46 |
47 | az group delete \
48 | --name jxrocks-group \
49 | --yes
50 |
--------------------------------------------------------------------------------
/manuscript/scripts/aks/aks-jx.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/6e01717c398a5d034ebe05b195514060
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Install [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) and make sure you have Azure admin permissions
8 |
9 | echo "nexus:
10 | enabled: false
11 | " | tee myvalues.yaml
12 |
13 | # Please replace [...] with a unique name (e.g., your GitHub user and a day and month).
14 | # Otherwise, it might fail to create a registry.
15 | # The name of the cluster must conform to the following pattern: '^[a-zA-Z0-9]*$'.
16 | CLUSTER_NAME=[...]
17 |
18 | jx create cluster aks \
19 | --cluster-name $CLUSTER_NAME \
20 | --resource-group-name jxrocks-group \
21 | --location eastus \
22 | --node-vm-size Standard_D2s_v3 \
23 | --nodes 3 \
24 | --default-admin-password=admin \
25 | --default-environment-prefix jx-rocks \
26 | --git-provider-kind github
27 |
28 | #######################
29 | # Destroy the cluster #
30 | #######################
31 |
32 | az aks delete \
33 | -n $CLUSTER_NAME \
34 | -g jxrocks-group \
35 | --yes
36 |
37 | kubectl config delete-cluster $CLUSTER_NAME
38 |
39 | kubectl config delete-context $CLUSTER_NAME
40 |
41 | kubectl config unset \
42 | users.clusterUser_jxrocks-group_$CLUSTER_NAME
43 |
44 | az group delete \
45 | --name jxrocks-group \
46 | --yes
--------------------------------------------------------------------------------
/manuscript/scripts/alibaba/alibaba-serverless.sh:
--------------------------------------------------------------------------------
1 | # https://jenkins-x.io/news/alibaba-container-service-jenkins-x/
2 |
3 | # Activate *Container Service*, *Resource Orchestration Service (ROS)*, *RAM*, and *Auto Scaling* services
4 |
5 | # Create the [Container Service roles](https://www.alibabacloud.com/help/doc-detail/86484.htm?spm=a2c63.p38356.b99.38.663a333eMXExon).
6 |
7 | # Download and install aliyun-cli (e.g., `brew install aliyun-cli`)
8 |
9 | aliyun configure
10 |
11 | REGION=ap-southeast-1
12 |
13 | aliyun vpc CreateVpc \
14 | --VpcName jx-rocks \
15 | --Description "Jenkins X" \
16 | --RegionId ${REGION} \
17 | --CidrBlock 172.16.0.0/12
18 |
19 | VPC_ID=[...]
20 |
21 | aliyun vpc CreateVSwitch \
22 | --VSwitchName jx-rocks \
23 | --VpcId ${VPC_ID} \
24 | --RegionId ${REGION} \
25 | --ZoneId ${REGION}a \
26 | --Description "Jenkins X" \
27 | --CidrBlock 172.16.0.0/24
28 |
29 | VSWITCH_ID=[...]
30 |
31 | aliyun ecs ImportKeyPair \
32 | --KeyPairName jx-rocks \
33 | --RegionId ${REGION} \
34 | --PublicKeyBody "$(cat ~/.ssh/id_rsa.pub)"
35 |
36 | VM_TYPE=ecs.n4.large
37 |
38 | mkdir -p cluster
39 |
40 | echo "{
41 | \"name\": \"jx-rocks\",
42 | \"cluster_type\": \"ManagedKubernetes\",
43 | \"disable_rollback\": true,
44 | \"timeout_mins\": 60,
45 | \"region_id\": \"${REGION}\",
46 | \"zoneid\": \"${REGION}b\",
47 | \"snat_entry\": true,
48 | \"cloud_monitor_flags\": false,
49 | \"public_slb\": true,
50 | \"worker_instance_type\": \"$VM_TYPE\",
51 | \"num_of_nodes\": 3,
52 | \"worker_system_disk_category\": \"cloud_efficiency\",
53 | \"worker_system_disk_size\": 120,
54 | \"worker_instance_charge_type\": \"PostPaid\",
55 | \"vpcid\": \"${VPC_ID}\",
56 | \"vswitchid\": \"${VSWITCH_ID}\",
57 | \"container_cidr\": \"192.168.0.0/16\",
58 | \"service_cidr\": \"10.0.0.0/20\",
59 | \"key_pair\": \"jx-rocks\"
60 | }" | tee cluster/alibaba-k8s.json
61 |
62 | aliyun cs POST /clusters \
63 | --header "Content-Type=application/json" \
64 | --body "$(cat cluster/alibaba-k8s.json)"
65 |
66 | CLUSTER_ID=[...]
67 |
68 | aliyun cs GET /k8s/${CLUSTER_ID}/user_config \
69 | | jq -r ".config" \
70 | | tee cluster/kubecfg-alibaba
71 |
72 | # Repeat if error
73 |
74 | export KUBECONFIG=$PWD/cluster/kubecfg-alibaba
75 |
76 | aliyun ecs CreateInstance \
77 | --RegionId ${REGION} \
78 | --ZoneId ${REGION}a \
79 | --InstanceType ecs.t5-lc2m1.nano \
80 | --ImageId \
81 | --help
82 |
83 |
84 | kubectl get nodes
85 |
86 | kubectl get storageclasses
87 |
88 | kubectl patch \
89 | storageclass alicloud-disk-ssd \
90 | -p '{"metadata": {"annotations": {"storageclass.kubernetes.io/is-default-class":"true"}}}'
91 |
92 | kubectl get storageclasses
93 |
94 | # open "https://cr.console.aliyun.com/"
95 |
96 | open "https://cr.console.aliyun.com/$REGION/instances/namespaces"
97 |
98 | # Create Namespace
99 |
100 | # Convert it to *Public*
101 |
102 | NAMESPACE=[...]
103 |
104 | cat << EOF > cluster/alibaba-namespace.json
105 | {
106 | "Namespace": {
107 | "Namespace": "${NAMESPACE}",
108 | }
109 | }
110 | EOF
111 |
112 | aliyun cr PUT /namespace/${NAMESPACE} \
113 | --header "Content-Type=application/json" \
114 | --body "$(cat cluster/alibaba-namespace.json)"
115 |
116 | aliyun cr POST /namespace/${NAMESPACE} \
117 | --header "Content-Type=application/json" \
118 | --body "$(cat cluster/alibaba-namespace.json)"
119 |
120 | jx install \
121 | --provider alibaba \
122 | --default-admin-password=admin \
123 | --default-environment-prefix=jx-rocks \
124 | --docker-registry=registry.${REGION}.aliyuncs.com \
125 | --docker-registry-org=${NAMESPACE} \
126 | --tekton
127 |
128 | # When in doubt, use the default answers, except in the case listed below
129 | # Answer with `n` to `Would you like to enable long term logs storage? A bucket for provider eks will be created`
130 |
131 | # Create docker login password from the console
132 |
133 | # This is not Docker Hub, but the user in Alibaba
134 | DOCKER_USERNAME=[...]
135 |
136 | # This is not Docker Hub, but the password in Alibaba
137 | DOCKER_PASSWORD=[...]
138 |
139 | AUTH=$(echo -n "${DOCKER_USERNAME}:${DOCKER_PASSWORD}" | base64)
140 |
141 | DATA=$(cat << EOF | base64
142 | {
143 | "auths": {
144 | "registry.${REGION}.aliyuncs.com": {
145 | "auth": "${AUTH}"
146 | }
147 | }
148 | }
149 | EOF
150 | )
151 |
152 | cat << EOF | kubectl apply -f -
153 | apiVersion: v1
154 | kind: Secret
155 | type: Opaque
156 | metadata:
157 | name: jenkins-docker-cfg
158 | namespace: jx
159 | data:
160 | config.json: ${DATA}
161 | EOF
162 |
--------------------------------------------------------------------------------
/manuscript/scripts/do/do-jx.sh:
--------------------------------------------------------------------------------
1 | ####################
2 | # Create a cluster #
3 | ####################
4 |
5 | # Install [doctl](https://github.com/digitalocean/doctl)
6 |
7 | doctl auth init
8 |
9 | doctl k8s cluster \
10 | create jx-rocks \
11 | --count 3 \
12 | --region nyc1 \
13 | --size s-2vcpu-4gb
14 |
15 | kubectl config use do-nyc1-jx-rocks
16 |
17 | # TODO: CA
18 |
19 | ####################################
20 | # Install NGINX Ingress controller #
21 | ####################################
22 |
23 | kubectl apply \
24 | -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/1cd17cd12c98563407ad03812aebac46ca4442f2/deploy/mandatory.yaml
25 |
26 | kubectl apply \
27 | -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/1cd17cd12c98563407ad03812aebac46ca4442f2/deploy/provider/cloud-generic.yaml
28 |
29 | export LB_IP=$(kubectl -n ingress-nginx \
30 | get svc -o jsonpath="{.items[0].status.loadBalancer.ingress[0].ip}")
31 |
32 | echo $LB_IP # It might take a while until LB is created. Repeat the `export` command if the output is empty.
33 |
34 | ##############
35 | # Install jx #
36 | ##############
37 |
38 | # Static
39 | jx install \
40 | --provider kubernetes \
41 | --external-ip $LB_IP \
42 | --domain jenkinx.$LB_IP.nip.io \
43 | --default-admin-password=admin \
44 | --ingress-namespace ingress-nginx \
45 | --ingress-deployment nginx-ingress-controller \
46 | --default-environment-prefix jx-rocks \
47 | --git-provider-kind github
48 |
49 | # Serverless
50 | jx install \
51 | --provider kubernetes \
52 | --external-ip $LB_IP \
53 | --domain $DOMAIN \
54 | --default-admin-password=admin \
55 | --ingress-namespace ingress-nginx \
56 | --ingress-deployment nginx-ingress-controller \
57 | --default-environment-prefix tekton \
58 | --git-provider-kind github \
59 | --namespace cd \
60 | --prow \
61 | --tekton
62 |
63 | #######################
64 | # Destroy the cluster #
65 | #######################
66 |
67 | doctl kubernetes cluster \
68 | delete jx-rocks \
69 | -f
70 |
71 | # TODO: Delete the volumes
72 |
73 | # TODO: Delete the LB
--------------------------------------------------------------------------------
/manuscript/scripts/eks/eks-jx-boot.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/cdc18fd7c439d4b39cd810e999dd8ce6
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Follow the instructions from https://github.com/weaveworks/eksctl to intall eksctl if you do not have it already.
8 |
9 | # If you already have eksctl, please make sure that you are running the latest version
10 |
11 | export AWS_ACCESS_KEY_ID=[...] # Replace [...] with the AWS Access Key ID
12 |
13 | export AWS_SECRET_ACCESS_KEY=[...] # Replace [...] with the AWS Secret Access Key
14 |
15 | export AWS_DEFAULT_REGION=us-east-1
16 |
17 | export CLUSTER_NAME=[...] # Replace `[...]` with the name of the cluster (e.g., jx-eks)
18 |
19 | eksctl create cluster \
20 | --name $CLUSTER_NAME \
21 | --region $AWS_DEFAULT_REGION \
22 | --node-type t2.large \
23 | --nodes 3 \
24 | --nodes-max 6 \
25 | --nodes-min 3 \
26 | --asg-access \
27 | --managed
28 |
29 | #######################
30 | # Add ECR Permissions #
31 | #######################
32 |
33 | IAM_ROLE=$(aws iam list-roles \
34 | | jq -r ".Roles[] \
35 | | select(.RoleName \
36 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
37 | .RoleName")
38 |
39 | echo $IAM_ROLE
40 |
41 | aws iam attach-role-policy \
42 | --role-name $IAM_ROLE \
43 | --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
44 |
45 | #############################
46 | # Create Cluster Autoscaler #
47 | #############################
48 |
49 | mkdir -p charts
50 |
51 | helm fetch stable/cluster-autoscaler \
52 | -d charts \
53 | --untar
54 |
55 | mkdir -p k8s-specs/aws
56 |
57 | helm template charts/cluster-autoscaler \
58 | --name aws-cluster-autoscaler \
59 | --output-dir k8s-specs/aws \
60 | --namespace kube-system \
61 | --set autoDiscovery.clusterName=$CLUSTER_NAME \
62 | --set awsRegion=$AWS_DEFAULT_REGION \
63 | --set sslCertPath=/etc/kubernetes/pki/ca.crt \
64 | --set rbac.create=true
65 |
66 | kubectl apply \
67 | -n kube-system \
68 | -f k8s-specs/aws/cluster-autoscaler/*
69 |
70 | #####################
71 | # Install Jenkins X #
72 | #####################
73 |
74 | git clone \
75 | https://github.com/jenkins-x/jenkins-x-boot-config.git \
76 | environment-$CLUSTER_NAME-dev
77 |
78 | cd environment-$CLUSTER_NAME-dev
79 |
80 | # Modify `jx-requirements.yaml`
81 |
82 | jx boot
83 |
84 | # Repeat the `jx boot` command if the process is aborted because of upgrading the `jx` CLI
85 |
86 | cd ..
87 |
88 | #######################
89 | # Destroy the cluster #
90 | #######################
91 |
92 | IAM_ROLE=$(aws iam list-roles \
93 | | jq -r ".Roles[] \
94 | | select(.RoleName \
95 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
96 | .RoleName")
97 |
98 | echo $IAM_ROLE
99 |
100 | aws iam detach-role-policy \
101 | --role-name $IAM_ROLE \
102 | --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
103 |
104 | eksctl delete cluster \
105 | --name $CLUSTER_NAME
106 |
107 | # Delete unused volumes
108 | for volume in `aws ec2 describe-volumes --output text| grep available | awk '{print $8}'`; do
109 | echo "Deleting volume $volume"
110 | aws ec2 delete-volume --volume-id $volume
111 | done
112 |
--------------------------------------------------------------------------------
/manuscript/scripts/eks/eks-jx-gloo.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/97184bedebfdc91628b87da7c0f07d43
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Install [AWS CLI](https://aws.amazon.com/cli/) and make sure you have AWS admin permissions
8 |
9 | # Install [eksctl](https://github.com/weaveworks/eksctl)
10 |
11 | export AWS_ACCESS_KEY_ID=[...] # Replace [...] with the AWS Access Key ID
12 |
13 | export AWS_SECRET_ACCESS_KEY=[...] # Replace [...] with the AWS Secret Access Key
14 |
15 | export AWS_DEFAULT_REGION=us-east-1
16 |
17 | echo "nexus:
18 | enabled: false
19 | " | tee myvalues.yaml
20 |
21 | CLUSTER_NAME=jx-rocks
22 |
23 | jx create cluster eks \
24 | --cluster-name $CLUSTER_NAME \
25 | --region $AWS_DEFAULT_REGION \
26 | --node-type t2.xlarge \
27 | --nodes 3 \
28 | --nodes-min 3 \
29 | --nodes-max 6 \
30 | --default-admin-password=admin \
31 | --default-environment-prefix jx-rocks \
32 | --git-provider-kind github \
33 | --static-jenkins
34 |
35 | # If you get stuck with the `waiting for external loadbalancer to be created and update the nginx-ingress-controller service in kube-system namespace`, you probably encountered a bug.
36 | # To fix it, open the AWS console and remove the `kubernetes.io/cluster/jx-rocks` tag from the security group `eks-cluster-sg-*`.
37 |
38 | # When in doubt, use the default answers, except in the cases listed below
39 | # Answer with `n` to `Would you like to register a wildcard DNS ALIAS to point at this ELB address?`
40 | # Answer with `n` to `Would you like to enable long term logs storage? A bucket for provider eks will be created`
41 |
42 | #############################
43 | # Create Cluster Autoscaler #
44 | #############################
45 |
46 | ASG_NAME=$(aws autoscaling \
47 | describe-auto-scaling-groups \
48 | | jq -r ".AutoScalingGroups[] \
49 | | select(.AutoScalingGroupName \
50 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
51 | .AutoScalingGroupName")
52 |
53 | echo $ASG_NAME
54 |
55 | aws autoscaling \
56 | create-or-update-tags \
57 | --tags \
58 | ResourceId=$ASG_NAME,ResourceType=auto-scaling-group,Key=k8s.io/cluster-autoscaler/enabled,Value=true,PropagateAtLaunch=true \
59 | ResourceId=$ASG_NAME,ResourceType=auto-scaling-group,Key=kubernetes.io/cluster/$CLUSTER_NAME,Value=true,PropagateAtLaunch=true
60 |
61 | IAM_ROLE=$(aws iam list-roles \
62 | | jq -r ".Roles[] \
63 | | select(.RoleName \
64 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
65 | .RoleName")
66 |
67 | echo $IAM_ROLE
68 |
69 | aws iam put-role-policy \
70 | --role-name $IAM_ROLE \
71 | --policy-name $CLUSTER_NAME-AutoScaling \
72 | --policy-document https://raw.githubusercontent.com/vfarcic/k8s-specs/master/scaling/eks-autoscaling-policy.json
73 |
74 | mkdir -p charts
75 |
76 | helm fetch stable/cluster-autoscaler \
77 | -d charts \
78 | --untar
79 |
80 | mkdir -p k8s-specs/aws
81 |
82 | helm template charts/cluster-autoscaler \
83 | --name aws-cluster-autoscaler \
84 | --output-dir k8s-specs/aws \
85 | --namespace kube-system \
86 | --set autoDiscovery.clusterName=$CLUSTER_NAME \
87 | --set awsRegion=$AWS_DEFAULT_REGION \
88 | --set sslCertPath=/etc/kubernetes/pki/ca.crt \
89 | --set rbac.create=true
90 |
91 | kubectl apply \
92 | -n kube-system \
93 | -f k8s-specs/aws/cluster-autoscaler/*
94 |
95 | #######################
96 | # Destroy the cluster #
97 | #######################
98 |
99 | IAM_ROLE=$(aws iam list-roles \
100 | | jq -r ".Roles[] \
101 | | select(.RoleName \
102 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
103 | .RoleName")
104 |
105 | echo $IAM_ROLE
106 |
107 | aws iam delete-role-policy \
108 | --role-name $IAM_ROLE \
109 | --policy-name $CLUSTER_NAME-AutoScaling
110 |
111 | eksctl delete cluster -n $CLUSTER_NAME
112 |
113 | # Delete unused volumes
114 | for volume in `aws ec2 describe-volumes --output text| grep available | awk '{print $8}'`; do
115 | echo "Deleting volume $volume"
116 | aws ec2 delete-volume --volume-id $volume
117 | done
118 |
--------------------------------------------------------------------------------
/manuscript/scripts/eks/eks-jx-serverless.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/f4a1df244d1852ee250e751c7191f5bd
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Install [AWS CLI](https://aws.amazon.com/cli/) and make sure you have AWS admin permissions
8 |
9 | # Install [eksctl](https://github.com/weaveworks/eksctl)
10 |
11 | export AWS_ACCESS_KEY_ID=[...] # Replace [...] with the AWS Access Key ID
12 |
13 | export AWS_SECRET_ACCESS_KEY=[...] # Replace [...] with the AWS Secret Access Key
14 |
15 | export AWS_DEFAULT_REGION=us-east-1
16 |
17 | echo "nexus:
18 | enabled: false
19 | " | tee myvalues.yaml
20 |
21 | CLUSTER_NAME=jx-rocks
22 |
23 | jx create cluster eks \
24 | --cluster-name $CLUSTER_NAME \
25 | --region $AWS_DEFAULT_REGION \
26 | --node-type t2.large \
27 | --nodes 3 \
28 | --nodes-min 3 \
29 | --nodes-max 6 \
30 | --default-admin-password=admin \
31 | --default-environment-prefix jx-rocks \
32 | --git-provider-kind github \
33 | --namespace jx \
34 | --prow \
35 | --tekton
36 |
37 | # If you get stuck with the `waiting for external loadbalancer to be created and update the nginx-ingress-controller service in kube-system namespace`, you probably encountered a bug.
38 | # To fix it, open the AWS console and remove the `kubernetes.io/cluster/jx-rocks` tag from the security group `eks-cluster-sg-*`.
39 |
40 | # When in doubt, use the default answers, except in the cases listed below
41 | # Answer with `n` to `Would you like to register a wildcard DNS ALIAS to point at this ELB address?`
42 | # Answer with `n` to `Would you like to enable long term logs storage? A bucket for provider eks will be created`
43 |
44 | #############################
45 | # Create Cluster Autoscaler #
46 | #############################
47 |
48 | ASG_NAME=$(aws autoscaling \
49 | describe-auto-scaling-groups \
50 | | jq -r ".AutoScalingGroups[] \
51 | | select(.AutoScalingGroupName \
52 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
53 | .AutoScalingGroupName")
54 |
55 | echo $ASG_NAME
56 |
57 | aws autoscaling \
58 | create-or-update-tags \
59 | --tags \
60 | ResourceId=$ASG_NAME,ResourceType=auto-scaling-group,Key=k8s.io/cluster-autoscaler/enabled,Value=true,PropagateAtLaunch=true \
61 | ResourceId=$ASG_NAME,ResourceType=auto-scaling-group,Key=kubernetes.io/cluster/$CLUSTER_NAME,Value=true,PropagateAtLaunch=true
62 |
63 | IAM_ROLE=$(aws iam list-roles \
64 | | jq -r ".Roles[] \
65 | | select(.RoleName \
66 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
67 | .RoleName")
68 |
69 | echo $IAM_ROLE
70 |
71 | aws iam put-role-policy \
72 | --role-name $IAM_ROLE \
73 | --policy-name $CLUSTER_NAME-AutoScaling \
74 | --policy-document https://raw.githubusercontent.com/vfarcic/k8s-specs/master/scaling/eks-autoscaling-policy.json
75 |
76 | mkdir -p charts
77 |
78 | helm fetch stable/cluster-autoscaler \
79 | -d charts \
80 | --untar
81 |
82 | rm -rf k8s-specs/aws/*
83 |
84 | mkdir -p k8s-specs/aws
85 |
86 | helm template charts/cluster-autoscaler \
87 | --name aws-cluster-autoscaler \
88 | --output-dir k8s-specs/aws \
89 | --namespace kube-system \
90 | --set autoDiscovery.clusterName=$CLUSTER_NAME \
91 | --set awsRegion=$AWS_DEFAULT_REGION \
92 | --set sslCertPath=/etc/kubernetes/pki/ca.crt \
93 | --set rbac.create=true
94 |
95 | kubectl apply \
96 | -n kube-system \
97 | -f k8s-specs/aws/cluster-autoscaler/*
98 |
99 | #######################
100 | # Destroy the cluster #
101 | #######################
102 |
103 | IAM_ROLE=$(aws iam list-roles \
104 | | jq -r ".Roles[] \
105 | | select(.RoleName \
106 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
107 | .RoleName")
108 |
109 | echo $IAM_ROLE
110 |
111 | aws iam delete-role-policy \
112 | --role-name $IAM_ROLE \
113 | --policy-name $CLUSTER_NAME-AutoScaling
114 |
115 | eksctl delete cluster -n $CLUSTER_NAME
116 |
117 | # Delete unused volumes
118 | for volume in `aws ec2 describe-volumes --output text| grep available | awk '{print $8}'`; do
119 | echo "Deleting volume $volume"
120 | aws ec2 delete-volume --volume-id $volume
121 | done
122 |
--------------------------------------------------------------------------------
/manuscript/scripts/eks/eks-jx.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/dfaf2b91819c0618faf030e6ac536eac
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Install [AWS CLI](https://aws.amazon.com/cli/) and make sure you have AWS admin permissions
8 |
9 | # Install [eksctl](https://github.com/weaveworks/eksctl)
10 |
11 | export AWS_ACCESS_KEY_ID=[...] # Replace [...] with the AWS Access Key ID
12 |
13 | export AWS_SECRET_ACCESS_KEY=[...] # Replace [...] with the AWS Secret Access Key
14 |
15 | export AWS_DEFAULT_REGION=us-east-1
16 |
17 | echo "nexus:
18 | enabled: false
19 | " | tee myvalues.yaml
20 |
21 | jx create cluster eks \
22 | --cluster-name jx-rocks \
23 | --region $AWS_DEFAULT_REGION \
24 | --node-type t2.large \
25 | --nodes 3 \
26 | --nodes-min 3 \
27 | --nodes-max 6 \
28 | --default-admin-password=admin \
29 | --default-environment-prefix jx-rocks \
30 | --git-provider-kind github \
31 | --static-jenkins
32 |
33 | # If you get stuck with the `waiting for external loadbalancer to be created and update the nginx-ingress-controller service in kube-system namespace`, you probably encountered a bug.
34 | # To fix it, open the AWS console and remove the `kubernetes.io/cluster/jx-rocks` tag from the security group `eks-cluster-sg-*`.
35 |
36 | # When in doubt, use the default answers, except in the cases listed below
37 | # Answer with `n` to `Would you like to register a wildcard DNS ALIAS to point at this ELB address?`
38 | # Answer with `n` to `Would you like to enable long term logs storage? A bucket for provider eks will be created`
39 |
40 | #############################
41 | # Create Cluster Autoscaler #
42 | #############################
43 |
44 | ASG_NAME=$(aws autoscaling \
45 | describe-auto-scaling-groups \
46 | | jq -r ".AutoScalingGroups[] \
47 | | select(.AutoScalingGroupName \
48 | | startswith(\"eksctl-jx-rocks-nodegroup\")) \
49 | .AutoScalingGroupName")
50 |
51 | echo $ASG_NAME
52 |
53 | aws autoscaling \
54 | create-or-update-tags \
55 | --tags \
56 | ResourceId=$ASG_NAME,ResourceType=auto-scaling-group,Key=k8s.io/cluster-autoscaler/enabled,Value=true,PropagateAtLaunch=true \
57 | ResourceId=$ASG_NAME,ResourceType=auto-scaling-group,Key=kubernetes.io/cluster/jx-rocks,Value=true,PropagateAtLaunch=true
58 |
59 | IAM_ROLE=$(aws iam list-roles \
60 | | jq -r ".Roles[] \
61 | | select(.RoleName \
62 | | startswith(\"eksctl-jx-rocks-nodegroup\")) \
63 | .RoleName")
64 |
65 | echo $IAM_ROLE
66 |
67 | aws iam put-role-policy \
68 | --role-name $IAM_ROLE \
69 | --policy-name jx-rocks-AutoScaling \
70 | --policy-document https://raw.githubusercontent.com/vfarcic/k8s-specs/master/scaling/eks-autoscaling-policy.json
71 |
72 | mkdir -p charts
73 |
74 | helm fetch stable/cluster-autoscaler \
75 | -d charts \
76 | --untar
77 |
78 | mkdir -p k8s-specs/aws
79 |
80 | helm template charts/cluster-autoscaler \
81 | --name aws-cluster-autoscaler \
82 | --output-dir k8s-specs/aws \
83 | --namespace kube-system \
84 | --set autoDiscovery.clusterName=jx-rocks \
85 | --set awsRegion=$AWS_DEFAULT_REGION \
86 | --set sslCertPath=/etc/kubernetes/pki/ca.crt \
87 | --set rbac.create=true
88 |
89 | kubectl apply \
90 | -n kube-system \
91 | -f k8s-specs/aws/cluster-autoscaler/*
92 |
93 | #######################
94 | # Destroy the cluster #
95 | #######################
96 |
97 | IAM_ROLE=$(aws iam list-roles \
98 | | jq -r ".Roles[] \
99 | | select(.RoleName \
100 | | startswith(\"eksctl-jx-rocks-nodegroup\")) \
101 | .RoleName")
102 |
103 | echo $IAM_ROLE
104 |
105 | aws iam delete-role-policy \
106 | --role-name $IAM_ROLE \
107 | --policy-name jx-rocks-AutoScaling
108 |
109 | eksctl delete cluster -n jx-rocks
110 |
111 | # Delete unused volumes
112 | for volume in `aws ec2 describe-volumes --output text| grep available | awk '{print $8}'`; do
113 | echo "Deleting volume $volume"
114 | aws ec2 delete-volume --volume-id $volume
115 | done
116 |
--------------------------------------------------------------------------------
/manuscript/scripts/eks/eks.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/3eaa9b10cb59424fc0447a563112f32e
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Follow the instructions from https://github.com/weaveworks/eksctl to intall eksctl if you do not have it already.
8 |
9 | # If you already have eksctl, please make sure that you are running the latest version
10 |
11 | export AWS_ACCESS_KEY_ID=[...] # Replace [...] with the AWS Access Key ID
12 |
13 | export AWS_SECRET_ACCESS_KEY=[...] # Replace [...] with the AWS Secret Access Key
14 |
15 | export AWS_DEFAULT_REGION=us-east-1
16 |
17 | export CLUSTER_NAME=[...] # Replace `[...]` with the name of the cluster (e.g., jx-eks)
18 |
19 | eksctl create cluster \
20 | --name $CLUSTER_NAME \
21 | --region $AWS_DEFAULT_REGION \
22 | --node-type t2.large \
23 | --nodes 3 \
24 | --nodes-max 6 \
25 | --nodes-min 3 \
26 | --asg-access \
27 | --managed
28 |
29 | #######################
30 | # Add ECR Permissions #
31 | #######################
32 |
33 | IAM_ROLE=$(aws iam list-roles \
34 | | jq -r ".Roles[] \
35 | | select(.RoleName \
36 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
37 | .RoleName")
38 |
39 | echo $IAM_ROLE
40 |
41 | aws iam attach-role-policy \
42 | --role-name $IAM_ROLE \
43 | --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
44 |
45 | #############################
46 | # Create Cluster Autoscaler #
47 | #############################
48 |
49 | mkdir -p charts
50 |
51 | helm fetch stable/cluster-autoscaler \
52 | -d charts \
53 | --untar
54 |
55 | mkdir -p k8s-specs/aws
56 |
57 | helm template charts/cluster-autoscaler \
58 | --name aws-cluster-autoscaler \
59 | --output-dir k8s-specs/aws \
60 | --namespace kube-system \
61 | --set autoDiscovery.clusterName=$CLUSTER_NAME \
62 | --set awsRegion=$AWS_DEFAULT_REGION \
63 | --set sslCertPath=/etc/kubernetes/pki/ca.crt \
64 | --set rbac.create=true
65 |
66 | kubectl apply \
67 | -n kube-system \
68 | -f k8s-specs/aws/cluster-autoscaler/*
69 |
70 | #######################
71 | # Destroy the cluster #
72 | #######################
73 |
74 | IAM_ROLE=$(aws iam list-roles \
75 | | jq -r ".Roles[] \
76 | | select(.RoleName \
77 | | startswith(\"eksctl-$CLUSTER_NAME-nodegroup\")) \
78 | .RoleName")
79 |
80 | echo $IAM_ROLE
81 |
82 | aws iam detach-role-policy \
83 | --role-name $IAM_ROLE \
84 | --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
85 |
86 | eksctl delete cluster \
87 | --name $CLUSTER_NAME
88 |
89 | # Delete unused volumes
90 | for volume in `aws ec2 describe-volumes --output text| grep available | awk '{print $8}'`; do
91 | echo "Deleting volume $volume"
92 | aws ec2 delete-volume --volume-id $volume
93 | done
94 |
--------------------------------------------------------------------------------
/manuscript/scripts/gke/gke-jx-boot.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/1eff2069aa68c4aee29c35b94dd9467f
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Use the same `PROJECT` as when you created the `dev` repository with `jx boot`
8 | export PROJECT=[...] # Replace `[...]` with the ID of the GCP project (e.g. jx).
9 |
10 | # Use the same `CLUSTER_NAME` as when you created the `dev` repository with `jx boot`
11 | export CLUSTER_NAME=[...] # Replace `[...]` with the name of the cluster (e.g., jx-gke)
12 |
13 | gcloud auth login
14 |
15 | gcloud container clusters \
16 | create $CLUSTER_NAME \
17 | --project $PROJECT \
18 | --region us-east1 \
19 | --machine-type n1-standard-2 \
20 | --enable-autoscaling \
21 | --num-nodes 1 \
22 | --max-nodes 2 \
23 | --min-nodes 1
24 |
25 | kubectl create clusterrolebinding \
26 | cluster-admin-binding \
27 | --clusterrole cluster-admin \
28 | --user $(gcloud config get-value account)
29 |
30 | #####################
31 | # Install Jenkins X #
32 | #####################
33 |
34 | git clone \
35 | https://github.com/jenkins-x/jenkins-x-boot-config.git \
36 | environment-$CLUSTER_NAME-dev
37 |
38 | cd environment-$CLUSTER_NAME-dev
39 |
40 | # Modify `jx-requirements.yaml`
41 |
42 | jx boot
43 |
44 | # Repeat the `jx boot` command if the process is aborted because of upgrading the `jx` CLI
45 |
46 | cd ..
47 |
48 | #######################
49 | # Destroy the cluster #
50 | #######################
51 |
52 | gcloud container clusters \
53 | delete $CLUSTER_NAME \
54 | --region us-east1 \
55 | --quiet
56 |
57 | # Remove unused disks to avoid reaching the quota (and save a bit of money)
58 | gcloud compute disks delete \
59 | --zone us-east1-b \
60 | $(gcloud compute disks list \
61 | --filter="zone:us-east1-b AND -users:*" \
62 | --format="value(id)") --quiet
63 | gcloud compute disks delete \
64 | --zone us-east1-c \
65 | $(gcloud compute disks list \
66 | --filter="zone:us-east1-c AND -users:*" \
67 | --format="value(id)") --quiet
68 | gcloud compute disks delete \
69 | --zone us-east1-d \
70 | $(gcloud compute disks list \
71 | --filter="zone:us-east1-d AND -users:*" \
72 | --format="value(id)") --quiet
73 |
--------------------------------------------------------------------------------
/manuscript/scripts/gke/gke-jx-gloo.sh:
--------------------------------------------------------------------------------
1 | ####################
2 | # Create a cluster #
3 | ####################
4 |
5 | # Install gcloud CLI (https://cloud.google.com/sdk/docs/quickstarts) and make sure that you have GCP admin permissions
6 |
7 | # Open https://console.cloud.google.com/cloud-resource-manager to create a new GCP project if you do not have one available already. Make sure to enable billing for that project.
8 |
9 | PROJECT=[...] # Replace `[...]` with the name of the GCP project (e.g. jx).
10 |
11 | echo "nexus:
12 | enabled: false
13 | " | tee myvalues.yaml
14 |
15 | jx create cluster gke \
16 | --cluster-name jx-rocks \
17 | --project-id $PROJECT \
18 | --region us-east1 \
19 | --machine-type n1-standard-4 \
20 | --min-num-nodes 1 \
21 | --max-num-nodes 2 \
22 | --default-admin-password=admin \
23 | --default-environment-prefix jx-rocks \
24 | --git-provider-kind github
25 |
26 | # If asked for input, use the default answers unless you're sure you want a non-standard setup.
27 |
28 | glooctl install knative \
29 | --install-knative-version=0.9.0
30 |
31 | #######################
32 | # Destroy the cluster #
33 | #######################
34 |
35 | gcloud container clusters \
36 | delete jx-rocks \
37 | --region us-east1 \
38 | --quiet
39 |
40 | # Remove unused disks to avoid reaching the quota (and save a bit of money)
41 | gcloud compute disks delete \
42 | --zone us-east1-b \
43 | $(gcloud compute disks list \
44 | --filter="zone:us-east1-b AND -users:*" \
45 | --format="value(id)") --quiet
46 | gcloud compute disks delete \
47 | --zone us-east1-c \
48 | $(gcloud compute disks list \
49 | --filter="zone:us-east1-c AND -users:*" \
50 | --format="value(id)") --quiet
51 | gcloud compute disks delete \
52 | --zone us-east1-d \
53 | $(gcloud compute disks list \
54 | --filter="zone:us-east1-d AND -users:*" \
55 | --format="value(id)") --quiet
56 |
57 | # Remove container images from GCR
58 | IMAGE=go-demo-6
59 | for TAG in $(gcloud container images \
60 | list-tags gcr.io/$PROJECT/$IMAGE \
61 | --format='get(tags)')
62 | do
63 | gcloud container images \
64 | delete gcr.io/$PROJECT/$IMAGE:$TAG \
65 | --quiet
66 | done
67 |
--------------------------------------------------------------------------------
/manuscript/scripts/gke/gke-jx-kaniko.sh:
--------------------------------------------------------------------------------
1 | ####################
2 | # Create a cluster #
3 | ####################
4 |
5 | # Install gcloud CLI (https://cloud.google.com/sdk/docs/quickstarts) and make sure that you have GCP admin permissions
6 |
7 | # Open https://console.cloud.google.com/cloud-resource-manager to create a new GCP project if you do not have one available already. Make sure to enable billing for that project.
8 |
9 | PROJECT=[...] # Replace `[...]` with the name of the GCP project (e.g. jx).
10 |
11 | echo "nexus:
12 | enabled: false
13 | " | tee myvalues.yaml
14 |
15 | jx create cluster gke \
16 | --cluster-name jx-rocks \
17 | --project-id $PROJECT \
18 | --region us-east1 \
19 | --machine-type n1-standard-2 \
20 | --min-num-nodes 1 \
21 | --max-num-nodes 2 \
22 | --default-admin-password=admin \
23 | --default-environment-prefix jx-rocks \
24 | --git-provider-kind github \
25 | --kaniko
26 |
27 | # If asked for input, use the default answers unless you're sure you want a non-standard setup.
28 |
29 | #######################
30 | # Destroy the cluster #
31 | #######################
32 |
33 | gcloud container clusters \
34 | delete jx-rocks \
35 | --region us-east1 \
36 | --quiet
37 |
38 | # Remove unused disks to avoid reaching the quota (and save a bit of money)
39 | # Remove unused disks to avoid reaching the quota (and save a bit of money)
40 | gcloud compute disks delete \
41 | --zone us-east1-b \
42 | $(gcloud compute disks list \
43 | --filter="zone:us-east1-b AND -users:*" \
44 | --format="value(id)")
45 | gcloud compute disks delete \
46 | --zone us-east1-c \
47 | $(gcloud compute disks list \
48 | --filter="zone:us-east1-c AND -users:*" \
49 | --format="value(id)")
50 | gcloud compute disks delete \
51 | --zone us-east1-d \
52 | $(gcloud compute disks list \
53 | --filter="zone:us-east1-d AND -users:*" \
54 | --format="value(id)")
--------------------------------------------------------------------------------
/manuscript/scripts/gke/gke-jx-serverless-gloo.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/cf939640f2af583c3a12d04affa67923
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Install gcloud CLI (https://cloud.google.com/sdk/docs/quickstarts) and make sure that you have GCP admin permissions
8 |
9 | # Open https://console.cloud.google.com/cloud-resource-manager to create a new GCP project if you do not have one available already. Make sure to enable billing for that project.
10 |
11 | export PROJECT=[...] # Replace `[...]` with the name of the GCP project (e.g. jx).
12 |
13 | echo "nexus:
14 | enabled: false
15 | " | tee myvalues.yaml
16 |
17 | jx create cluster gke \
18 | --cluster-name jx-rocks \
19 | --project-id $PROJECT \
20 | --region us-east1 \
21 | --machine-type n1-standard-2 \
22 | --min-num-nodes 1 \
23 | --max-num-nodes 2 \
24 | --default-admin-password=admin \
25 | --default-environment-prefix jx-rocks \
26 | --git-provider-kind github \
27 | --namespace jx \
28 | --prow \
29 | --tekton
30 |
31 | # If asked for input, use the default answers unless you're sure you want a non-standard setup.
32 |
33 | ############################
34 | # Install Gloo And Knative #
35 | ############################
36 |
37 | glooctl install knative \
38 | --install-knative-version=0.9.0
39 |
40 | jx edit deploy \
41 | --team \
42 | --kind knative \
43 | --batch-mode
44 |
45 | KNATIVE_IP=$(kubectl \
46 | --namespace gloo-system \
47 | get service knative-external-proxy \
48 | --output jsonpath="{.status.loadBalancer.ingress[0].ip}")
49 |
50 | echo $KNATIVE_IP
51 |
52 | # Confirm that the IP exists (that the LB was created)
53 |
54 | echo "apiVersion: v1
55 | kind: ConfigMap
56 | metadata:
57 | name: config-domain
58 | namespace: knative-serving
59 | data:
60 | $KNATIVE_IP.nip.io: \"\"" \
61 | | kubectl apply --filename -
62 |
63 | #######################
64 | # Destroy the cluster #
65 | #######################
66 |
67 | gcloud container clusters \
68 | delete jx-rocks \
69 | --region us-east1 \
70 | --quiet
71 |
72 | # Remove unused disks to avoid reaching the quota (and save a bit of money)
73 | gcloud compute disks delete \
74 | --zone us-east1-b \
75 | $(gcloud compute disks list \
76 | --filter="zone:us-east1-b AND -users:*" \
77 | --format="value(id)") --quiet
78 | gcloud compute disks delete \
79 | --zone us-east1-c \
80 | $(gcloud compute disks list \
81 | --filter="zone:us-east1-c AND -users:*" \
82 | --format="value(id)") --quiet
83 | gcloud compute disks delete \
84 | --zone us-east1-d \
85 | $(gcloud compute disks list \
86 | --filter="zone:us-east1-d AND -users:*" \
87 | --format="value(id)") --quiet
88 |
89 | # Remove container images from GCR
90 | IMAGE=go-demo-6
91 | for TAG in $(gcloud container images \
92 | list-tags gcr.io/$PROJECT/$IMAGE \
93 | --format='get(tags)')
94 | do
95 | gcloud container images \
96 | delete gcr.io/$PROJECT/$IMAGE:$TAG \
97 | --quiet
98 | done
99 |
--------------------------------------------------------------------------------
/manuscript/scripts/gke/gke-jx-serverless.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/fe18870a015f4acc34d91c106d0d43c8
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Install gcloud CLI (https://cloud.google.com/sdk/docs/quickstarts) and make sure that you have GCP admin permissions
8 |
9 | # Open https://console.cloud.google.com/cloud-resource-manager to create a new GCP project if you do not have one available already. Make sure to enable billing for that project.
10 |
11 | export PROJECT=[...] # Replace `[...]` with the name of the GCP project (e.g. jx).
12 |
13 | echo "nexus:
14 | enabled: false
15 | " | tee myvalues.yaml
16 |
17 | # Replace `[...]` with your GitHub username
18 | export GH_USER=[...]
19 |
20 | jx create cluster gke \
21 | --cluster-name jx-rocks \
22 | --project-id $PROJECT \
23 | --region us-east1 \
24 | --machine-type n1-standard-2 \
25 | --min-num-nodes 1 \
26 | --max-num-nodes 2 \
27 | --default-admin-password=admin \
28 | --default-environment-prefix jx-rocks \
29 | --git-provider-kind github \
30 | --namespace jx \
31 | --prow \
32 | --tekton
33 |
34 | # If asked for input, use the default answers unless you're sure you want a non-standard setup.
35 |
36 | #######################
37 | # Destroy the cluster #
38 | #######################
39 |
40 | gcloud container clusters \
41 | delete jx-rocks \
42 | --region us-east1 \
43 | --quiet
44 |
45 | # Remove unused disks to avoid reaching the quota (and save a bit of money)
46 | gcloud compute disks delete \
47 | --zone us-east1-b \
48 | $(gcloud compute disks list \
49 | --filter="zone:us-east1-b AND -users:*" \
50 | --format="value(id)") --quiet
51 | gcloud compute disks delete \
52 | --zone us-east1-c \
53 | $(gcloud compute disks list \
54 | --filter="zone:us-east1-c AND -users:*" \
55 | --format="value(id)") --quiet
56 | gcloud compute disks delete \
57 | --zone us-east1-d \
58 | $(gcloud compute disks list \
59 | --filter="zone:us-east1-d AND -users:*" \
60 | --format="value(id)") --quiet
61 |
62 | # Remove container images from GCR
63 | IMAGE=go-demo-6
64 | for TAG in $(gcloud container images \
65 | list-tags gcr.io/$PROJECT/$IMAGE \
66 | --format='get(tags)')
67 | do
68 | gcloud container images \
69 | delete gcr.io/$PROJECT/$IMAGE:$TAG \
70 | --quiet
71 | done
72 |
--------------------------------------------------------------------------------
/manuscript/scripts/gke/gke-jx.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/86e10c8771582c4b6a5249e9c513cd18
2 |
3 | ####################
4 | # Create a cluster #
5 | ####################
6 |
7 | # Install gcloud CLI (https://cloud.google.com/sdk/docs/quickstarts) and make sure that you have GCP admin permissions
8 |
9 | # Open https://console.cloud.google.com/cloud-resource-manager to create a new GCP project if you do not have one available already. Make sure to enable billing for that project.
10 |
11 | PROJECT=[...] # Replace `[...]` with the name of the GCP project (e.g. jx).
12 |
13 | echo "nexus:
14 | enabled: false
15 | " | tee myvalues.yaml
16 |
17 | # Replace `[...]` with your GitHub username
18 | export GH_USER=[...]
19 |
20 | jx create cluster gke \
21 | --cluster-name jx-rocks \
22 | --project-id $PROJECT \
23 | --region us-east1 \
24 | --machine-type n1-standard-2 \
25 | --min-num-nodes 1 \
26 | --max-num-nodes 2 \
27 | --default-admin-password=admin \
28 | --default-environment-prefix jx-rocks \
29 | --git-provider-kind github
30 |
31 | # If asked for input, use the default answers unless you're sure you want a non-standard setup.
32 |
33 | #######################
34 | # Destroy the cluster #
35 | #######################
36 |
37 | gcloud container clusters \
38 | delete jx-rocks \
39 | --region us-east1 \
40 | --quiet
41 |
42 | # Remove unused disks to avoid reaching the quota (and save a bit of money)
43 | gcloud compute disks delete \
44 | --zone us-east1-b \
45 | $(gcloud compute disks list \
46 | --filter="zone:us-east1-b AND -users:*" \
47 | --format="value(id)") --quiet
48 | gcloud compute disks delete \
49 | --zone us-east1-c \
50 | $(gcloud compute disks list \
51 | --filter="zone:us-east1-c AND -users:*" \
52 | --format="value(id)") --quiet
53 | gcloud compute disks delete \
54 | --zone us-east1-d \
55 | $(gcloud compute disks list \
56 | --filter="zone:us-east1-d AND -users:*" \
57 | --format="value(id)") --quiet
58 |
59 | # Remove container images from GCR
60 | IMAGE=go-demo-6
61 | for TAG in $(gcloud container images \
62 | list-tags gcr.io/$PROJECT/$IMAGE \
63 | --format='get(tags)')
64 | do
65 | gcloud container images \
66 | delete gcr.io/$PROJECT/$IMAGE:$TAG \
67 | --quiet
68 | done
69 |
--------------------------------------------------------------------------------
/manuscript/scripts/gke/gke.sh:
--------------------------------------------------------------------------------
1 | ####################
2 | # Create a cluster #
3 | ####################
4 |
5 | PROJECT=[...] # Replace `[...]` with the name of the GCP project (e.g. jx).
6 |
7 | CLUSTER_NAME=[...] # Replace `[...]` with the name of the cluster (e.g., jx-gke)
8 |
9 | gcloud auth login
10 |
11 | gcloud container clusters \
12 | create $CLUSTER_NAME \
13 | --project $PROJECT \
14 | --region us-east1 \
15 | --machine-type n1-standard-2 \
16 | --enable-autoscaling \
17 | --num-nodes 1 \
18 | --max-nodes 2 \
19 | --min-nodes 1
20 |
21 | kubectl create clusterrolebinding \
22 | cluster-admin-binding \
23 | --clusterrole cluster-admin \
24 | --user $(gcloud config get-value account)
25 |
26 | #######################
27 | # Destroy the cluster #
28 | #######################
29 |
30 | gcloud container clusters \
31 | delete $CLUSTER_NAME \
32 | --region us-east1 \
33 | --quiet
34 |
35 | # Remove unused disks to avoid reaching the quota (and save a bit of money)
36 | gcloud compute disks delete \
37 | --zone us-east1-b \
38 | $(gcloud compute disks list \
39 | --filter="zone:us-east1-b AND -users:*" \
40 | --format="value(id)") --quiet
41 | gcloud compute disks delete \
42 | --zone us-east1-c \
43 | $(gcloud compute disks list \
44 | --filter="zone:us-east1-c AND -users:*" \
45 | --format="value(id)") --quiet
46 | gcloud compute disks delete \
47 | --zone us-east1-d \
48 | $(gcloud compute disks list \
49 | --filter="zone:us-east1-d AND -users:*" \
50 | --format="value(id)") --quiet
51 |
--------------------------------------------------------------------------------
/manuscript/scripts/jx/install-gke.sh:
--------------------------------------------------------------------------------
1 | ######################
2 | # Create The Cluster #
3 | ######################
4 |
5 | gcloud auth login
6 |
7 | gcloud container clusters \
8 | create jx-rocks \
9 | --region us-east1 \
10 | --machine-type n1-standard-2 \
11 | --enable-autoscaling \
12 | --num-nodes 1 \
13 | --max-nodes 3 \
14 | --min-nodes 1
15 |
16 | kubectl create clusterrolebinding \
17 | cluster-admin-binding \
18 | --clusterrole cluster-admin \
19 | --user $(gcloud config get-value account)
20 |
21 | ###################
22 | # Install Ingress #
23 | ###################
24 |
25 | kubectl apply \
26 | -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/1cd17cd12c98563407ad03812aebac46ca4442f2/deploy/mandatory.yaml
27 |
28 | kubectl apply \
29 | -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/1cd17cd12c98563407ad03812aebac46ca4442f2/deploy/provider/cloud-generic.yaml
30 |
31 | #####################
32 | # Install Jenkins X #
33 | #####################
34 |
35 | export LB_IP=$(kubectl -n ingress-nginx \
36 | get svc ingress-nginx \
37 | -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
38 |
39 | echo $LB_IP
40 |
41 | DOMAIN=jenkinx.$LB_IP.nip.io
42 |
43 | PROVIDER=gke
44 |
45 | INGRESS_NS=ingress-nginx
46 |
47 | INGRESS_DEP=nginx-ingress-controller
48 |
49 | echo "nexus:
50 | enabled: false
51 | " | tee myvalues.yaml
52 |
53 | jx install \
54 | --provider $PROVIDER \
55 | --external-ip $LB_IP \
56 | --domain $DOMAIN \
57 | --default-admin-password=admin \
58 | --ingress-namespace $INGRESS_NS \
59 | --ingress-deployment $INGRESS_DEP \
60 | --default-environment-prefix jx-rocks \
61 | --git-provider-kind github
62 |
63 | #######################
64 | # Uninstall Jenkins X #
65 | #######################
66 |
67 | jx uninstall \
68 | --context $(kubectl config current-context) \
69 | -b
70 |
71 | #######################
72 | # Destroy the cluster #
73 | #######################
74 |
75 | gcloud container clusters \
76 | delete jx-rocks \
77 | --region us-east1 \
78 | --quiet
79 |
80 | gcloud compute disks delete \
81 | $(gcloud compute disks list \
82 | --filter="-users:*" \
83 | --format="value(id)")
84 |
--------------------------------------------------------------------------------
/manuscript/scripts/jx/install-serverless.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/7b3b3d90ecd7f343effe4fff5241d037
2 |
3 | #####################
4 | # Install Jenkins X #
5 | #####################
6 |
7 | # Replace `[...]` with the IP of the load balancer created when you installed the NGINX Ingress controller.
8 | # An example command that retrieves the IP is as follows.
9 | # kubectl get svc --all-namespaces -l app=nginx-ingress -l component=controller -o jsonpath="{.items[0].status.loadBalancer.ingress[0].ip}"
10 |
11 | LB_IP=[...]
12 |
13 | # Replace `[...]` with the domain that will be used to access Jenkins X and that is pointing to your LB.
14 | # If you don't have a domain, use `serverless.$LB_IP.nip.io` as the value.`
15 |
16 | DOMAIN=[...]
17 |
18 | # Replace `[...]` with your Kubernetes provider.
19 | # Execute `jx install --help | grep "provider="` to retrieve the list of the providers if you're unsure which one to set.
20 | # Use `kubernetes` as the provider if none from the list match yours.
21 |
22 | PROVIDER=[...]
23 |
24 | # Replace `ingress-nginx` with the Namespace where the NGINX Ingress controller is installed
25 |
26 | INGRESS_NS=ingress-nginx
27 |
28 | # Replace `nginx-ingress-controller` with the name of the NGINX Ingress controller deployment
29 |
30 | INGRESS_DEP=nginx-ingress-controller
31 |
32 | echo "nexus:
33 | enabled: false
34 | " | tee myvalues.yaml
35 |
36 | jx install \
37 | --provider $PROVIDER \
38 | --external-ip $LB_IP \
39 | --domain $DOMAIN \
40 | --default-admin-password=admin \
41 | --ingress-namespace $INGRESS_NS \
42 | --ingress-deployment $INGRESS_DEP \
43 | --default-environment-prefix jx-rocks \
44 | --git-provider-kind github \
45 | --namespace jx \
46 | --prow \
47 | --tekton
48 |
49 | #######################
50 | # Uninstall Jenkins X #
51 | #######################
52 |
53 | jx uninstall \
54 | --context $(kubectl config current-context) \
55 | --batch-mode
--------------------------------------------------------------------------------
/manuscript/scripts/jx/install.sh:
--------------------------------------------------------------------------------
1 | # Source: https://gist.github.com/3dd5592dc5d582ceeb68fb3c1cc59233
2 |
3 | #####################
4 | # Install Jenkins X #
5 | #####################
6 |
7 | # Replace `[...]` with the IP of the load balancer created when you installed the NGINX Ingress controller`
8 |
9 | LB_IP=[...]
10 |
11 | # Replace `[...]` with the domain that will be used to access Jenkins X and that is pointing to your LB.
12 | # If you don't have a domain, use `jenkinx.$LB_IP.nip.io` as the value.`
13 |
14 | DOMAIN=[...]
15 |
16 | # Replace `[...]` with your Kubernetes provider.
17 | # Execute `jx install --help | grep "provider="` to retrieve the list of the providers if you're unsure which one to set.
18 | # Use `kubernetes` as the provider if none from the list match yours.
19 |
20 | PROVIDER=[...]
21 |
22 | # Replace `ingress-nginx` with the Namespace where the NGINX Ingress controller is installed
23 |
24 | INGRESS_NS=ingress-nginx
25 |
26 | # Replace `nginx-ingress-controller` with the name of the NGINX Ingress controller deployment
27 |
28 | INGRESS_DEP=nginx-ingress-controller
29 |
30 | echo "nexus:
31 | enabled: false
32 | " | tee myvalues.yaml
33 |
34 | jx install \
35 | --provider $PROVIDER \
36 | --external-ip $LB_IP \
37 | --domain $DOMAIN \
38 | --default-admin-password=admin \
39 | --ingress-namespace $INGRESS_NS \
40 | --ingress-deployment $INGRESS_DEP \
41 | --default-environment-prefix jx-rocks \
42 | --git-provider-kind github
43 |
44 | #######################
45 | # Uninstall Jenkins X #
46 | #######################
47 |
48 | jx uninstall \
49 | --context $(kubectl config current-context) \
50 | -b
--------------------------------------------------------------------------------
/manuscript/scripts/minikube/minikube-istio.sh:
--------------------------------------------------------------------------------
1 | ###########
2 | # Cluster #
3 | ###########
4 |
5 | minikube start \
6 | --vm-driver virtualbox \
7 | --cpus 4 \
8 | --memory 8192
9 |
10 | minikube addons enable default-storageclass
11 |
12 | minikube addons disable ingress
13 |
14 | minikube addons enable storage-provisioner
15 |
16 | #########
17 | # Istio #
18 | #########
19 |
20 | helm upgrade -i istio \
21 | cluster/istio-*/install/kubernetes/helm/istio \
22 | --namespace istio-system \
23 | --set gateways.istio-ingressgateway.type=NodePort \
24 | --set gateways.istio-egressgateway.type=NodePort \
25 | --wait
26 |
--------------------------------------------------------------------------------
/manuscript/scripts/minikube/minikube-jx.sh:
--------------------------------------------------------------------------------
1 | ####################
2 | # Create a cluster #
3 | ####################
4 |
5 | # Install [Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/)
6 |
7 | jx create cluster minikube \
8 | -m 8192 \
9 | -c 8 \
10 | -s 150GB \
11 | -d virtualbox \
12 | --default-admin-password=admin \
13 | --default-environment-prefix jx-rocks \
14 | -b
15 |
16 | #######################
17 | # Destroy the cluster #
18 | #######################
19 |
20 | minikube delete
21 |
--------------------------------------------------------------------------------
/manuscript/scripts/minikube/minikube.sh:
--------------------------------------------------------------------------------
1 | ###########
2 | # Cluster #
3 | ###########
4 |
5 | minikube start \
6 | --vm-driver virtualbox \
7 | --cpus 4 \
8 | --memory 16384
9 |
10 | minikube addons enable default-storageclass
11 |
12 | minikube addons disable ingress
13 |
14 | minikube addons enable storage-provisioner
15 |
--------------------------------------------------------------------------------