├── .gitignore
├── LICENSE
├── README.md
├── section-1
├── video-1.2
│ ├── README.md
│ └── spring-boot-http-gradle
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .helmignore
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── build.gradle
│ │ ├── charts
│ │ ├── preview
│ │ │ ├── Chart.yaml
│ │ │ ├── Makefile
│ │ │ ├── requirements.yaml
│ │ │ └── values.yaml
│ │ └── spring-boot-http-gradle
│ │ │ ├── .helmignore
│ │ │ ├── Chart.yaml
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── templates
│ │ │ ├── NOTES.txt
│ │ │ ├── _helpers.tpl
│ │ │ ├── canary.yaml
│ │ │ ├── deployment.yaml
│ │ │ ├── hpa.yaml
│ │ │ ├── ksvc.yaml
│ │ │ └── service.yaml
│ │ │ └── values.yaml
│ │ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ ├── jenkins-x.yml
│ │ ├── skaffold.yaml
│ │ ├── src
│ │ ├── main
│ │ │ └── java
│ │ │ │ └── hello
│ │ │ │ ├── Application.java
│ │ │ │ ├── Greeting.java
│ │ │ │ └── GreetingController.java
│ │ └── test
│ │ │ └── java
│ │ │ └── hello
│ │ │ └── GreetingControllerTests.java
│ │ └── watch.sh
├── video-1.3
│ └── README.md
├── video-1.4
│ └── README.md
├── video-1.5
│ └── README.md
└── video-1.6
│ ├── README.md
│ └── jx-requirements.yml
├── section-2
├── video-2.1
│ └── README.md
├── video-2.2
│ ├── README.md
│ └── express-hello
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
├── video-2.3
│ └── README.md
├── video-2.4
│ └── README.md
├── video-2.5
│ └── README.md
└── video-2.6
│ └── README.md
├── section-3
├── video-3.1
│ ├── README.md
│ └── hello-video-3-1
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
├── video-3.2
│ ├── README.md
│ ├── hello-3-2-auto
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
│ └── hello-3-2-specify
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
├── video-3.3
│ └── README.md
├── video-3.4
│ └── README.md
└── video-3.5
│ ├── README.md
│ ├── hello-3-5-audit
│ ├── .gitignore
│ ├── index.js
│ ├── jenkins-x.yml
│ ├── package-lock.json
│ └── package.json
│ └── hello-3-5-replace
│ ├── .gitignore
│ ├── index.js
│ ├── jenkins-x.yml
│ ├── package-lock.json
│ └── package.json
├── section-4
├── video-4.1
│ ├── README.md
│ └── hello-4-1
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── jenkins-x.yml
│ │ ├── package-lock.json
│ │ └── package.json
├── video-4.2
│ ├── README.md
│ └── hello-4-2
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── jenkins-x.yml
│ │ ├── package-lock.json
│ │ └── package.json
├── video-4.3
│ ├── README.md
│ └── hello-4-3
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── jenkins-x.yml
│ │ ├── package-lock.json
│ │ └── package.json
├── video-4.4
│ ├── README.md
│ └── hello-4-4
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── jenkins-x.yml
│ │ ├── package-lock.json
│ │ └── package.json
└── video-4.5
│ └── README.md
├── section-5
├── video-5.1
│ ├── README.md
│ └── plone.yaml
├── video-5.2
│ ├── README.md
│ └── deployment.yaml
├── video-5.3
│ ├── README.md
│ └── service.yaml
├── video-5.4
│ ├── README.md
│ └── plone.yaml
├── video-5.5
│ ├── README.md
│ └── values.yaml
└── video-5.6
│ ├── README.md
│ ├── bad-command
│ └── deployment.yaml
│ ├── bad-image-name
│ └── deployment.yaml
│ └── good-deployment
│ └── deployment.yaml
└── section-6
├── video-6.1
└── README.md
├── video-6.2
└── README.md
├── video-6.3
└── README.md
└── video-6.4
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | jenkins-x-boot-config
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # Hands-On Continuous Integration and Delivery with Jenkins X and Kubernetes [Video]
5 | This is the code repository for [Hands-On Continuous Integration and Delivery with Jenkins X and Kubernetes [Video]]( https://www.packtpub.com/cloud-networking/hands-on-continuous-integration-and-delivery-with-jenkins-x-and-kubernetes-video), published by [Packt](https://www.packtpub.com/?utm_source=github ). It contains all the supporting project files necessary to work through the video course from start to finish.
6 |
7 | ## About the Video Course
8 | Jenkins X is an exciting and fast way to build applications on Kubernetes. Jenkins X handles the job of configuring Kubernetes to build, test, and deploy your applications, so you can focus on fast delivery and make your applications great!
9 | Kubernetes is powerful but complicated; using it not only to run your application but also to build and test it requires a lot of configuration. Jenkins X provides automation for Kubernetes so you can use it to its full potential without spending all of your time configuring and debugging.
10 | This course adopts a step-by-step approach to show you how to use Jenkins X, with plenty of hands-on examples that you can use for your own applications. You'll start with a simple example application deployed to Kubernetes using Jenkins X, then build up to awesome features such as preview environments, promotion, and monitoring. With this course, you can learn Jenkins X fast, and immediately apply what you've learned.
11 |
12 |
What You Will Learn
13 |
14 |
15 |
16 | • Install and configure Jenkins X in a cloud environment with Google Cloud Platform
17 | • Build an application with Jenkins X, or import an existing application so you can get started quickly
18 | • Control how Jenkins X builds and deploys your applications so you can create the build and test pipeline that works for you
19 | • Build preview environments so you can test the latest software changes in your application before you promote it to production
20 | • Managing application updates (including manual promotion, rolling updates, and pull requests) so you can accelerate the delivery of your application
21 |
22 |
23 | ## Instructions and Navigation
24 | ### Assumed Knowledge
25 | This course is for developers, IT/DevOps professionals, or system admins keen to take advantage of Jenkins X and Kubernetes to enhance their Continuous Delivery processes. A basic knowledge of developing and building software is assumed.
26 | This course requires use of a text editor (e.g. Atom); Git client (graphical or command line); and access to Google Cloud Engine and GitHub.
27 |
28 | ## Technical Requirements
29 | #### Minimum Hardware Requirements
30 | For successful completion of this course, students will require a computer system with at least the following:
31 |
32 | OS: Linux (recommended), Windows, or macOS
33 | Processor: Dual-core processor
34 | Memory: 4 GB
35 | Storage: 120 GB
36 |
37 | The course examples demonstrate the installation and use on Linux. To run with the minimum hardware requirements, students will also need the ability to create Kubernetes clusters in a cloud environment.
38 |
39 | #### Recommended Hardware Requirements
40 | For an optimal experience with hands-on labs and other practical activities, students require access to sufficient hardware to run a virtual machine:
41 |
42 | OS: Linux (recommended), Windows, or macOS
43 | Processor: Quad-core processor
44 | Memory: 8 GB
45 | Storage: 120 GB
46 |
47 | This will permit using Jenkins X and Kubernetes via Minikube. Access to a cloud environment is also strongly recommended.
48 |
49 | #### Software Requirements
50 | The following requirements are recommended to view and edit the example files.
51 |
52 | Operating system: Windows, Linux, or macOS
53 | Hypervisor: VirtualBox or Hyper-V
54 | Browser: Chrome or Firefox (latest version)
55 | IDE (Visual Studio Code or IntelliJ recommended)
56 |
57 |
58 | ## Important Note
59 |
60 | We will be using cloud resources, with the possibility that this will cost
61 | money. Google Cloud Platform has a limited-time free tier, and our
62 | setup will stay within the free tier, but once your free period expires
63 | there will be a cost, which is greater as long as you have nodes in your
64 | cluster's node pool.
65 |
66 | To reduce costs while keeping your cluster configuration, you can resize the
67 | cluster's node pool to 0, and then size it back up when you're ready to use
68 | it. Remember to also turn off autoscaling so it doesn't scale back up again,
69 | and revisit the cluster page to make sure the nodes were deleted properly.
70 |
71 | Of course, you can also delete your cluster entirely and re-create it using
72 | the instructions in Section 1.
73 |
74 | ## Application Cleanup
75 |
76 | Throughout these videos, we will be creating applications in our Jenkins X
77 | cluster. These applications will continue to run unless deleted or the cluster
78 | is deleted from Google Kubernetes Engine.
79 |
80 | To delete applications from Jenkins X, use the `jx delete application`
81 | command. This will prompt you for one or more applications to delete. You will
82 | have to manually remove the Git repository in GitHub.
83 |
84 | One note of caution: as of when these videos were recorded, deleting the
85 | application does not completely remove it from Jenkins X. There will still be
86 | files in the boot configuration repository and Helm charts in chartmuseum. For
87 | this reason, it is not safe to delete an application and add a new application
88 | with the same name.
89 |
90 | ## Related Products
91 | * [Adobe After Effects CC: Tips, Tricks, and Techniques [Video]](https://www.packtpub.com/business-other/adobe-after-effects-cc-tips-tricks-and-techniques-video)
92 |
93 | * [Mastering Palo Alto Networks [Video]](https://www.packtpub.com/networking-and-servers/mastering-palo-alto-networks-video)
94 |
95 | * [Azure Cognitive Services for Developers [Video]](https://www.packtpub.com/application-development/azure-cognitive-services-developers-video)
96 |
--------------------------------------------------------------------------------
/section-1/video-1.2/README.md:
--------------------------------------------------------------------------------
1 | # Video 1.2
2 |
3 | This video demonstrates Jenkins X.
4 |
5 | ## Prerequisites
6 |
7 | To try out this example for yourself, you will need a Jenkins X cluster up
8 | and running. You can accomplish this by following the instructions in the
9 | rest of Section 1.
10 |
11 | ## Import
12 |
13 | This directory contains source code from a Jenkins X quickstart example. Once
14 | you have a Jenkins X cluster, you can add this software to your Jenkins X
15 | cluster using the `jx import` command:
16 |
17 | ```
18 | jx import spring-boot-http-gradle
19 | ```
20 |
21 | Or, even easier, you can follow the instructions in Video 2.1 to create
22 | this application from the original quickstart.
23 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/.dockerignore:
--------------------------------------------------------------------------------
1 | draft.toml
2 | charts/
3 | NOTICE
4 | LICENSE
5 | README.md
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/.gitignore:
--------------------------------------------------------------------------------
1 | *.sw?
2 | .#*
3 | *#
4 | *~
5 | .classpath
6 | .project
7 | .settings
8 | bin
9 | build
10 | target
11 | dependency-reduced-pom.xml
12 | *.sublime-*
13 | /scratch
14 | .gradle
15 | README.html
16 | *.iml
17 | .idea
18 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/.helmignore:
--------------------------------------------------------------------------------
1 | # Patterns to ignore when building packages.
2 | # This supports shell glob matching, relative path matching, and
3 | # negation (prefixed with !). Only one pattern per line.
4 | .DS_Store
5 | # Common VCS dirs
6 | .git/
7 | .gitignore
8 | .bzr/
9 | .bzrignore
10 | .hg/
11 | .hgignore
12 | .svn/
13 | # Common backup files
14 | *.swp
15 | *.bak
16 | *.tmp
17 | *~
18 | # Various IDEs
19 | .project
20 | .idea/
21 | *.tmproj
22 | *.png
23 |
24 | # known compile time folders
25 | target/
26 | node_modules/
27 | vendor/
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM openjdk:8-jdk-slim
2 | ENV PORT 8080
3 | EXPOSE 8080
4 | COPY build/libs/*.jar /opt/app.jar
5 | WORKDIR /opt
6 | CMD ["java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-jar", "app.jar"]
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/README.md:
--------------------------------------------------------------------------------
1 | Minimal Jenkins X demo repo based on https://spring.io/guides/gs/consuming-rest/ with the [Spring Actuator](https://spring.io/guides/gs/actuator-service) added in
2 |
3 | While the original example offers both Maven and Gradle the idea with this demo was to focus purely on Gradle, exercising a new Jenkins X Gradle build pack.
4 |
5 | Run locally with `gradlew bootRun`
6 |
7 | Test via http://localhost:8080/greeting
8 |
9 | Health check at http://localhost:8080/actuator/health
10 |
11 | Credit: thanks to https://github.com/Cervator for the contribution of this quickstart
12 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenCentral()
4 | }
5 | dependencies {
6 | classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.2.RELEASE")
7 | }
8 | }
9 |
10 | apply plugin: 'java'
11 | apply plugin: 'eclipse'
12 | apply plugin: 'idea'
13 | apply plugin: 'org.springframework.boot'
14 | apply plugin: 'io.spring.dependency-management'
15 |
16 | bootJar {
17 | baseName = 'restyserv'
18 | version = '0.3.0'
19 | }
20 |
21 | repositories {
22 | mavenCentral()
23 | }
24 |
25 | sourceCompatibility = 1.8
26 | targetCompatibility = 1.8
27 |
28 | dependencies {
29 | compile("org.springframework.boot:spring-boot-starter-web")
30 | compile("org.springframework.boot:spring-boot-starter-actuator")
31 | testCompile('org.springframework.boot:spring-boot-starter-test')
32 | testCompile('com.jayway.jsonpath:json-path')
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/preview/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | description: A Helm chart for Kubernetes
3 | icon: https://raw.githubusercontent.com/jenkins-x/jenkins-x-platform/master/images/java.png
4 | name: preview
5 | version: 0.1.0-SNAPSHOT
6 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/preview/Makefile:
--------------------------------------------------------------------------------
1 | OS := $(shell uname)
2 |
3 | preview:
4 | ifeq ($(OS),Darwin)
5 | sed -i "" -e "s/version:.*/version: $(PREVIEW_VERSION)/" Chart.yaml
6 | sed -i "" -e "s/version:.*/version: $(PREVIEW_VERSION)/" ../*/Chart.yaml
7 | sed -i "" -e "s/tag:.*/tag: $(PREVIEW_VERSION)/" values.yaml
8 | else ifeq ($(OS),Linux)
9 | sed -i -e "s/version:.*/version: $(PREVIEW_VERSION)/" Chart.yaml
10 | sed -i -e "s/version:.*/version: $(PREVIEW_VERSION)/" ../*/Chart.yaml
11 | sed -i -e "s|repository:.*|repository: $(DOCKER_REGISTRY)\/jenkins-x-263922\/spring-boot-http-gradle|" values.yaml
12 | sed -i -e "s/tag:.*/tag: $(PREVIEW_VERSION)/" values.yaml
13 | else
14 | echo "platfrom $(OS) not supported to release from"
15 | exit -1
16 | endif
17 | echo " version: $(PREVIEW_VERSION)" >> requirements.yaml
18 | jx step helm build
19 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/preview/requirements.yaml:
--------------------------------------------------------------------------------
1 | # !! File must end with empty line !!
2 | dependencies:
3 | - alias: expose
4 | name: exposecontroller
5 | repository: http://chartmuseum.jenkins-x.io
6 | version: 2.3.92
7 | - alias: cleanup
8 | name: exposecontroller
9 | repository: http://chartmuseum.jenkins-x.io
10 | version: 2.3.92
11 |
12 | # !! "alias: preview" must be last entry in dependencies array !!
13 | # !! Place custom dependencies above !!
14 | - alias: preview
15 | name: spring-boot-http-gradle
16 | repository: file://../spring-boot-http-gradle
17 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/preview/values.yaml:
--------------------------------------------------------------------------------
1 |
2 | expose:
3 | Annotations:
4 | helm.sh/hook: post-install,post-upgrade
5 | helm.sh/hook-delete-policy: hook-succeeded
6 | config:
7 | exposer: Ingress
8 | http: true
9 | tlsacme: false
10 |
11 | cleanup:
12 | Args:
13 | - --cleanup
14 | Annotations:
15 | helm.sh/hook: pre-delete
16 | helm.sh/hook-delete-policy: hook-succeeded
17 |
18 | preview:
19 | image:
20 | repository:
21 | tag:
22 | pullPolicy: IfNotPresent
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/.helmignore:
--------------------------------------------------------------------------------
1 | # Patterns to ignore when building packages.
2 | # This supports shell glob matching, relative path matching, and
3 | # negation (prefixed with !). Only one pattern per line.
4 | .DS_Store
5 | # Common VCS dirs
6 | .git/
7 | .gitignore
8 | .bzr/
9 | .bzrignore
10 | .hg/
11 | .hgignore
12 | .svn/
13 | # Common backup files
14 | *.swp
15 | *.bak
16 | *.tmp
17 | *~
18 | # Various IDEs
19 | .project
20 | .idea/
21 | *.tmproj
22 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | description: A Helm chart for Kubernetes
3 | icon: https://raw.githubusercontent.com/jenkins-x/jenkins-x-platform/master/images/java.png
4 | name: spring-boot-http-gradle
5 | version: 0.1.0-SNAPSHOT
6 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/Makefile:
--------------------------------------------------------------------------------
1 | CHART_REPO := http://jenkins-x-chartmuseum:8080
2 | CURRENT=$(pwd)
3 | NAME := spring-boot-http-gradle
4 | OS := $(shell uname)
5 | RELEASE_VERSION := $(shell cat ../../VERSION)
6 |
7 | build: clean
8 | rm -rf requirements.lock
9 | helm dependency build
10 | helm lint
11 |
12 | install: clean build
13 | helm install . --name ${NAME}
14 |
15 | upgrade: clean build
16 | helm upgrade ${NAME} .
17 |
18 | delete:
19 | helm delete --purge ${NAME}
20 |
21 | clean:
22 | rm -rf charts
23 | rm -rf ${NAME}*.tgz
24 |
25 | release: clean
26 | helm dependency build
27 | helm lint
28 | helm init --client-only
29 | helm package .
30 | curl --fail -u $(CHARTMUSEUM_CREDS_USR):$(CHARTMUSEUM_CREDS_PSW) --data-binary "@$(NAME)-$(shell sed -n 's/^version: //p' Chart.yaml).tgz" $(CHART_REPO)/api/charts
31 | rm -rf ${NAME}*.tgz%
32 |
33 | tag:
34 | ifeq ($(OS),Darwin)
35 | sed -i "" -e "s/version:.*/version: $(RELEASE_VERSION)/" Chart.yaml
36 | sed -i "" -e "s/tag:.*/tag: $(RELEASE_VERSION)/" values.yaml
37 | else ifeq ($(OS),Linux)
38 | sed -i -e "s/version:.*/version: $(RELEASE_VERSION)/" Chart.yaml
39 | sed -i -e "s|repository:.*|repository: $(DOCKER_REGISTRY)\/jenkins-x-263922\/spring-boot-http-gradle|" values.yaml
40 | sed -i -e "s/tag:.*/tag: $(RELEASE_VERSION)/" values.yaml
41 | else
42 | echo "platfrom $(OS) not supported to release from"
43 | exit -1
44 | endif
45 | git add --all
46 | git commit -m "release $(RELEASE_VERSION)" --allow-empty # if first release then no verion update is performed
47 | git tag -fa v$(RELEASE_VERSION) -m "Release version $(RELEASE_VERSION)"
48 | git push origin v$(RELEASE_VERSION)
49 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/README.md:
--------------------------------------------------------------------------------
1 | # Java application
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/templates/NOTES.txt:
--------------------------------------------------------------------------------
1 |
2 | Get the application URL by running these commands:
3 |
4 | kubectl get ingress {{ template "fullname" . }}
5 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/templates/_helpers.tpl:
--------------------------------------------------------------------------------
1 | {{/* vim: set filetype=mustache: */}}
2 | {{/*
3 | Expand the name of the chart.
4 | */}}
5 | {{- define "name" -}}
6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
7 | {{- end -}}
8 |
9 | {{/*
10 | Create a default fully qualified app name.
11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12 | */}}
13 | {{- define "fullname" -}}
14 | {{- $name := default .Chart.Name .Values.nameOverride -}}
15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
16 | {{- end -}}
17 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/templates/canary.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.canary.enabled }}
2 | apiVersion: flagger.app/v1alpha3
3 | kind: Canary
4 | metadata:
5 | name: {{ template "fullname" . }}
6 | labels:
7 | draft: {{ default "draft-app" .Values.draft }}
8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
9 | spec:
10 | provider: istio
11 | targetRef:
12 | apiVersion: apps/v1
13 | kind: Deployment
14 | name: {{ template "fullname" . }}
15 | progressDeadlineSeconds: {{ .Values.canary.progressDeadlineSeconds }}
16 | {{- if .Values.hpa.enabled }}
17 | autoscalerRef:
18 | apiVersion: autoscaling/v2beta1
19 | kind: HorizontalPodAutoscaler
20 | name: {{ template "fullname" . }}
21 | {{- end }}
22 | service:
23 | port: {{ .Values.service.externalPort }}
24 | targetPort: {{ .Values.service.internalPort }}
25 | gateways:
26 | - {{ template "fullname" . }}
27 | hosts:
28 | - {{ .Values.canary.host }}
29 | canaryAnalysis:
30 | interval: {{ .Values.canary.canaryAnalysis.interval }}
31 | threshold: {{ .Values.canary.canaryAnalysis.threshold }}
32 | maxWeight: {{ .Values.canary.canaryAnalysis.maxWeight }}
33 | stepWeight: {{ .Values.canary.canaryAnalysis.stepWeight }}
34 | metrics:
35 | - name: request-success-rate
36 | threshold: {{ .Values.canary.canaryAnalysis.metrics.requestSuccessRate.threshold }}
37 | interval: {{ .Values.canary.canaryAnalysis.metrics.requestSuccessRate.interval }}
38 | - name: request-duration
39 | threshold: {{ .Values.canary.canaryAnalysis.metrics.requestDuration.threshold }}
40 | interval: {{ .Values.canary.canaryAnalysis.metrics.requestDuration.interval }}
41 |
42 | ---
43 |
44 | apiVersion: networking.istio.io/v1alpha3
45 | kind: Gateway
46 | metadata:
47 | name: {{ template "fullname" . }}
48 | spec:
49 | selector:
50 | istio: ingressgateway
51 | servers:
52 | - port:
53 | number: {{ .Values.service.externalPort }}
54 | name: http
55 | protocol: HTTP
56 | hosts:
57 | - {{ .Values.canary.host }}
58 | {{- end }}
59 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/templates/deployment.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.knativeDeploy }}
2 | {{- else }}
3 | apiVersion: extensions/v1beta1
4 | kind: Deployment
5 | metadata:
6 | name: {{ template "fullname" . }}
7 | labels:
8 | draft: {{ default "draft-app" .Values.draft }}
9 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
10 | spec:
11 | {{- if .Values.hpa.enabled }}
12 | {{- else }}
13 | replicas: {{ .Values.replicaCount }}
14 | {{- end }}
15 | template:
16 | metadata:
17 | labels:
18 | draft: {{ default "draft-app" .Values.draft }}
19 | app: {{ template "fullname" . }}
20 | {{- if .Values.podAnnotations }}
21 | annotations:
22 | {{ toYaml .Values.podAnnotations | indent 8 }}
23 | {{- end }}
24 | spec:
25 | containers:
26 | - name: {{ .Chart.Name }}
27 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
28 | imagePullPolicy: {{ .Values.image.pullPolicy }}
29 | env:
30 | {{- range $pkey, $pval := .Values.env }}
31 | - name: {{ $pkey }}
32 | value: {{ quote $pval }}
33 | {{- end }}
34 | envFrom:
35 | {{ toYaml .Values.envFrom | indent 10 }}
36 | ports:
37 | - containerPort: {{ .Values.service.internalPort }}
38 | livenessProbe:
39 | httpGet:
40 | path: {{ .Values.probePath }}
41 | port: {{ .Values.service.internalPort }}
42 | initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
43 | periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
44 | successThreshold: {{ .Values.livenessProbe.successThreshold }}
45 | timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
46 | readinessProbe:
47 | httpGet:
48 | path: {{ .Values.probePath }}
49 | port: {{ .Values.service.internalPort }}
50 | periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
51 | successThreshold: {{ .Values.readinessProbe.successThreshold }}
52 | timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
53 | resources:
54 | {{ toYaml .Values.resources | indent 12 }}
55 | terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
56 | {{- end }}
57 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/templates/hpa.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.hpa.enabled }}
2 | apiVersion: autoscaling/v2beta1
3 | kind: HorizontalPodAutoscaler
4 | metadata:
5 | name: {{ template "fullname" . }}
6 | labels:
7 | draft: {{ default "draft-app" .Values.draft }}
8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
9 | spec:
10 | scaleTargetRef:
11 | apiVersion: apps/v1
12 | kind: Deployment
13 | name: {{ template "fullname" . }}
14 | minReplicas: {{ .Values.hpa.minReplicas }}
15 | maxReplicas: {{ .Values.hpa.maxReplicas }}
16 | metrics:
17 | - type: Resource
18 | resource:
19 | name: cpu
20 | targetAverageUtilization: {{ .Values.hpa.cpuTargetAverageUtilization }}
21 | - type: Resource
22 | resource:
23 | name: memory
24 | targetAverageUtilization: {{ .Values.hpa.memoryTargetAverageUtilization }}
25 | {{- end }}
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/templates/ksvc.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.knativeDeploy }}
2 | apiVersion: serving.knative.dev/v1alpha1
3 | kind: Service
4 | metadata:
5 | {{- if .Values.service.name }}
6 | name: {{ .Values.service.name }}
7 | {{- else }}
8 | name: {{ template "fullname" . }}
9 | {{- end }}
10 | labels:
11 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
12 | spec:
13 | runLatest:
14 | configuration:
15 | revisionTemplate:
16 | spec:
17 | container:
18 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
19 | imagePullPolicy: {{ .Values.image.pullPolicy }}
20 | env:
21 | {{- range $pkey, $pval := .Values.env }}
22 | - name: {{ $pkey }}
23 | value: {{ quote $pval }}
24 | {{- end }}
25 | livenessProbe:
26 | httpGet:
27 | path: {{ .Values.probePath }}
28 | initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
29 | periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
30 | successThreshold: {{ .Values.livenessProbe.successThreshold }}
31 | timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
32 | readinessProbe:
33 | failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
34 | httpGet:
35 | path: {{ .Values.probePath }}
36 | periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
37 | successThreshold: {{ .Values.readinessProbe.successThreshold }}
38 | timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
39 | resources:
40 | {{ toYaml .Values.resources | indent 14 }}
41 | {{- end }}
42 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/templates/service.yaml:
--------------------------------------------------------------------------------
1 | {{- if or .Values.knativeDeploy .Values.canary.enabled }}
2 | {{- else }}
3 | apiVersion: v1
4 | kind: Service
5 | metadata:
6 | {{- if .Values.service.name }}
7 | name: {{ .Values.service.name }}
8 | {{- else }}
9 | name: {{ template "fullname" . }}
10 | {{- end }}
11 | labels:
12 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
13 | {{- if .Values.service.annotations }}
14 | annotations:
15 | {{ toYaml .Values.service.annotations | indent 4 }}
16 | {{- end }}
17 | spec:
18 | type: {{ .Values.service.type }}
19 | ports:
20 | - port: {{ .Values.service.externalPort }}
21 | targetPort: {{ .Values.service.internalPort }}
22 | protocol: TCP
23 | name: http
24 | selector:
25 | app: {{ template "fullname" . }}
26 | {{- end }}
27 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/charts/spring-boot-http-gradle/values.yaml:
--------------------------------------------------------------------------------
1 | # Default values for Gradle projects.
2 | # This is a YAML-formatted file.
3 | # Declare variables to be passed into your templates.
4 | replicaCount: 1
5 | image:
6 | repository: draft
7 | tag: dev
8 | pullPolicy: IfNotPresent
9 |
10 | # define environment variables here as a map of key: value
11 | env:
12 |
13 | # enable this flag to use knative serve to deploy the app
14 | knativeDeploy: false
15 |
16 | # HorizontalPodAutoscaler
17 | hpa:
18 | enabled: false
19 | minReplicas: 2
20 | maxReplicas: 6
21 | cpuTargetAverageUtilization: 80
22 | memoryTargetAverageUtilization: 80
23 |
24 | # Canary deployments
25 | # If enabled, Istio and Flagger need to be installed in the cluster
26 | canary:
27 | enabled: false
28 | progressDeadlineSeconds: 60
29 | canaryAnalysis:
30 | interval: "1m"
31 | threshold: 5
32 | maxWeight: 60
33 | stepWeight: 20
34 | # WARNING: Canary deployments will fail and rollback if there is no traffic that will generate the below specified metrics.
35 | metrics:
36 | requestSuccessRate:
37 | threshold: 99
38 | interval: "1m"
39 | requestDuration:
40 | threshold: 1000
41 | interval: "1m"
42 | # The host is using Istio Gateway and is currently not auto-generated
43 | # Please overwrite the `canary.host` in `values.yaml` in each environment repository (e.g., staging, production)
44 | host: acme.com
45 |
46 | service:
47 | name: spring-boot-http-gradle
48 | type: ClusterIP
49 | externalPort: 80
50 | internalPort: 8080
51 | annotations:
52 | fabric8.io/expose: "true"
53 | fabric8.io/ingress.annotations: "kubernetes.io/ingress.class: nginx"
54 | resources:
55 | limits:
56 | cpu: 500m
57 | memory: 512Mi
58 | requests:
59 | cpu: 400m
60 | memory: 512Mi
61 | probePath: /actuator/health
62 | livenessProbe:
63 | initialDelaySeconds: 60
64 | periodSeconds: 10
65 | successThreshold: 1
66 | timeoutSeconds: 1
67 | readinessProbe:
68 | failureThreshold: 1
69 | periodSeconds: 10
70 | successThreshold: 1
71 | timeoutSeconds: 1
72 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Hands-On-Continuous-Integration-and-Delivery-with-Jenkins-X-and-Kubernetes/b0d9e86698f3506540e3e360fce1d695ded447e0/section-1/video-1.2/spring-boot-http-gradle/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon May 28 22:31:05 EDT 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
7 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/jenkins-x.yml:
--------------------------------------------------------------------------------
1 | buildPack: gradle
2 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/skaffold.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: skaffold/v1beta2
2 | kind: Config
3 | build:
4 | artifacts:
5 | - image: jenkins-x-263922/spring-boot-http-gradle
6 | context: .
7 | docker: {}
8 | tagPolicy:
9 | envTemplate:
10 | template: '{{.DOCKER_REGISTRY}}/{{.IMAGE_NAME}}:{{.VERSION}}'
11 | local: {}
12 | deploy:
13 | kubectl: {}
14 | profiles:
15 | - name: dev
16 | build:
17 | tagPolicy:
18 | envTemplate:
19 | template: '{{.DOCKER_REGISTRY}}/{{.IMAGE_NAME}}:{{.DIGEST_HEX}}'
20 | local: {}
21 | deploy:
22 | helm:
23 | releases:
24 | - name: spring-boot-http-gradle
25 | chartPath: charts/spring-boot-http-gradle
26 | setValueTemplates:
27 | image.repository: '{{.DOCKER_REGISTRY}}/{{.IMAGE_NAME}}'
28 | image.tag: '{{.DIGEST_HEX}}'
29 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/src/main/java/hello/Application.java:
--------------------------------------------------------------------------------
1 | package hello;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Application.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/src/main/java/hello/Greeting.java:
--------------------------------------------------------------------------------
1 | package hello;
2 |
3 | public class Greeting {
4 |
5 | private final long id;
6 | private final String content;
7 |
8 | public Greeting(long id, String content) {
9 | this.id = id;
10 | this.content = content;
11 | }
12 |
13 | public long getId() {
14 | return id;
15 | }
16 |
17 | public String getContent() {
18 | return content;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/src/main/java/hello/GreetingController.java:
--------------------------------------------------------------------------------
1 | package hello;
2 |
3 | import java.util.concurrent.atomic.AtomicLong;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | @RestController
9 | public class GreetingController {
10 |
11 | private static final String template = "Hello there, %s!";
12 | private final AtomicLong counter = new AtomicLong();
13 |
14 | @RequestMapping("/universe")
15 | public Greeting universe(@RequestParam(value="name", defaultValue="Universe") String name) {
16 | return new Greeting(counter.incrementAndGet(),
17 | String.format(template, name));
18 | }
19 |
20 | @RequestMapping("/greeting")
21 | public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
22 | return new Greeting(counter.incrementAndGet(),
23 | String.format(template, name));
24 | }
25 |
26 | @RequestMapping("/")
27 | public String defaultEndpoint(@RequestParam(value="name", defaultValue="World") String name) {
28 | return String.format(template, name);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/src/test/java/hello/GreetingControllerTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package hello;
17 |
18 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
19 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
20 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
21 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
22 |
23 | import org.junit.Test;
24 | import org.junit.runner.RunWith;
25 | import org.springframework.beans.factory.annotation.Autowired;
26 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
27 | import org.springframework.boot.test.context.SpringBootTest;
28 | import org.springframework.test.context.junit4.SpringRunner;
29 | import org.springframework.test.web.servlet.MockMvc;
30 |
31 | @RunWith(SpringRunner.class)
32 | @SpringBootTest
33 | @AutoConfigureMockMvc
34 | public class GreetingControllerTests {
35 |
36 | @Autowired
37 | private MockMvc mockMvc;
38 |
39 | @Test
40 | public void noParamGreetingShouldReturnDefaultMessage() throws Exception {
41 |
42 | this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk())
43 | .andExpect(jsonPath("$.content").value("Hello there, World!"));
44 | }
45 |
46 | @Test
47 | public void noParamDefaultEndpointShouldReturnDefaultMessage() throws Exception {
48 | this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk());
49 | }
50 |
51 | @Test
52 | public void paramGreetingShouldReturnTailoredMessage() throws Exception {
53 |
54 | this.mockMvc.perform(get("/greeting").param("name", "Spring Community"))
55 | .andDo(print()).andExpect(status().isOk())
56 | .andExpect(jsonPath("$.content").value("Hello there, Spring Community!"));
57 | }
58 |
59 | @Test
60 | public void paramDefaultEndpointShouldReturnTailoredMessage() throws Exception {
61 | this.mockMvc.perform(get("/").param("name", "Spring Community"))
62 | .andDo(print()).andExpect(status().isOk());
63 | }
64 |
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/section-1/video-1.2/spring-boot-http-gradle/watch.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # watch the java files and continously deploy the service
4 | gradle build
5 | skaffold run -p dev
6 | reflex -r "\.java$" -- bash -c 'gradle build && skaffold run -p dev'
7 |
--------------------------------------------------------------------------------
/section-1/video-1.3/README.md:
--------------------------------------------------------------------------------
1 | # Video 1.3
2 |
3 | In this video we will install `jx`, the Jenkins X command line tool.
4 |
5 | ## Installing
6 |
7 | Start by visiting this link:
8 |
9 | https://jenkins-x.io/docs/getting-started/setup/install/
10 |
11 | There are download instructions for macOS, Linux, and Windows.
12 |
13 | ## Linux PATH
14 |
15 | For the Linux installation, we need to make sure that `jx` is on the PATH.
16 | I recommend creating a directory `$HOME/bin` as this will allow updating
17 | `jx` as a normal user.
18 |
19 | To create the directory and move `jx` there:
20 |
21 | ```
22 | mkdir -p $HOME/bin
23 | mv jx $HOME/bin
24 | ```
25 |
26 | In many cases, the `$HOME/bin` directory will already be on the PATH. If not,
27 | add this line to `$HOME/.bashrc` or `$HOME/.bash_profile`, as applicable:
28 |
29 | ```
30 | export PATH="$HOME/bin:${PATH}"
31 | ```
32 |
33 | ## Verifying Install
34 |
35 | To verify that `jx` is installed correctly and check the version, run:
36 |
37 | ```
38 | jx --version
39 | ```
40 |
--------------------------------------------------------------------------------
/section-1/video-1.4/README.md:
--------------------------------------------------------------------------------
1 | # Video 1.4
2 |
3 | To create a Kubernetes cluster for Jenkins X, we will use Google Kubernetes
4 | Engine.
5 |
6 | ## Prerequisites
7 |
8 | In order to complete this lesson, you will need to create an account with
9 | Google Cloud Platform:
10 |
11 | https://cloud.google.com/
12 |
13 | You will also need a Google Cloud Platform project. Follow the instructions
14 | here:
15 |
16 | https://cloud.google.com/resource-manager/docs/creating-managing-projects
17 |
18 | Finally, you will need the `jx` command line tool as installed in the previous
19 | video.
20 |
21 | ## Creating a Cluster
22 |
23 | We will use the `jx create cluster gke` command to create the cluster.
24 |
25 | Run:
26 |
27 | ```
28 | jx create cluster gke --cluster-name=jenkinsx --skip-installation
29 | ```
30 |
31 | Follow the prompts as described in the video.
32 |
--------------------------------------------------------------------------------
/section-1/video-1.5/README.md:
--------------------------------------------------------------------------------
1 | # Video 1.5
2 |
3 | ## GitOps
4 |
5 | Jenkins X uses GitOps to manage the Jenkins X installation. This means
6 | that the Jenkins X configuration is stored in a Git repository, and any
7 | changes we make, whether directly or with the `jx` command line tool, are
8 | reflected in the Git repository for the installation.
9 |
10 | ## GitHub Setup
11 |
12 | In order for Jenkins X to perform GitOps, it needs access to a Git repository
13 | server. For this course, we are using GitHub. You can choose to either use
14 | your personal GitHub account for everything, or create a separate "bot" account
15 | and a GitHub organization. Just be sure to follow the GitHub terms of service
16 | for any accounts created for machine purposes.
17 |
18 | For this video, we'll demonstrate a GitHub organization that includes a
19 | personal account and a separate bot account. This will allow us to use the
20 | bot account for Jenkins X changes so we can see automated changes more easily.
21 |
22 | ## GitHub Access Token
23 |
24 | To get started, we need to give Jenkins X rights to make changes in our Git
25 | repositories. For GitHub, we can do this by creating a personal access token.
26 |
27 | To configure a personal access token, go here:
28 |
29 | https://github.com/settings/tokens
30 |
31 | Be sure that you're logged in with the account you want Jenkins X to use.
32 |
33 | Jenkins X requires the following permissions:
34 |
35 | * repo (all)
36 | * read:org
37 | * write:repo_hook
38 | * read:repo_hook
39 | * read:user
40 | * user:email
41 | * delete_repo
42 |
43 | Once you have created a token with these permissions, be sure to keep the
44 | token in a safe place so we can use it for `jx boot`.
45 |
--------------------------------------------------------------------------------
/section-1/video-1.6/README.md:
--------------------------------------------------------------------------------
1 | # Video 1.6
2 |
3 | We're now ready to install Jenkins X using the `jx boot` command.
4 | We'll be using our Kubernetes cluster configuration and our GitHub token.
5 |
6 | ## Prerequisites
7 |
8 | * Create a Kubernetes cluster and GitHub token per the instructions.
9 | * Have your Git command line client installed and configured with your
10 | name and email.
11 |
12 | ## Jenkins X Boot
13 |
14 | The `jx boot` command uses the cluster's Git repository to configure the
15 | running installation of Jenkins X. This includes installing or modifying
16 | any pieces as necessary.
17 |
18 | When we first run `jx boot`, we will not have a Git repository, so `jx boot`
19 | will clone it for us. It will then push this repository to the GitHub
20 | account or organization we specify. From that point forward, we should make
21 | configuration changes to our cluster only from within the Git repository.
22 |
23 | To get the Jenkins X Boot process started, we can supply a
24 | `jx-requirements.yml` file. There is a sample one in this directory.
25 |
26 | To run using the provided configuration:
27 |
28 | ```
29 | jx boot -r jx-requirements.yml
30 | ```
31 |
32 | Once you've successfully booted Jenkins X, you can either re-clone the Git
33 | repository it created for you, or just move the `jenkins-x-boot-config`
34 | directory somewhere else on your system. Be sure to use this directory to
35 | configure your cluster!
36 |
37 | ## Public vs. Private Environments
38 |
39 | Most of `jx-requirements.yml` matches the default, but there is one change.
40 |
41 | Because we install into a GitHub organization that is running under the free
42 | tier, we are only allowed to create public repositories. Jenkins X defaults
43 | to using private repositories for cluster configuration, so we need to tell
44 | Jenkins X to make the repositories public. We do this by setting
45 | `environmentGitPublic` to `true` in `jx-requirements.yml`.
46 |
47 | If you are installing into a paid organization or a personal account, you
48 | can choose to remove this configuration entry to use private repositories.
49 |
50 | ## Configuring TLS
51 |
52 | This Jenkins X setup is designed for you to learn how to use Jenkins X.
53 | Once you have your Jenkins X cluster up and running, you will want to
54 | configure Transport Layer Security (TLS). To enable TLS, you will need a custom
55 | domain that you own in order to issue the certificates. For this reason,
56 | enabling TLS is not shown as part of the course.
57 |
58 | It's important to enable TLS, because our Jenkins X server will be creating
59 | webhooks to GitHub that include tokens that Jenkins X uses to ensure that the
60 | webhook comes from the right source. We want to secure the communication from
61 | GitHub to Jenkins X to ensure that token is not sent in the clear. To do this we
62 | need to enable TLS in `jx-requirements.yml`.
63 |
--------------------------------------------------------------------------------
/section-1/video-1.6/jx-requirements.yml:
--------------------------------------------------------------------------------
1 | autoUpdate:
2 | enabled: false
3 | schedule: ""
4 | bootConfigURL: https://github.com/jenkins-x/jenkins-x-boot-config.git
5 | cluster:
6 | gitKind: github
7 | gitName: github
8 | gitServer: https://github.com
9 | environmentGitPublic: true
10 | namespace: jx
11 | provider: gke
12 | environments:
13 | - ingress:
14 | domain: ""
15 | externalDNS: false
16 | namespaceSubDomain: ""
17 | tls:
18 | email: ""
19 | enabled: false
20 | production: false
21 | key: dev
22 | - ingress:
23 | domain: ""
24 | externalDNS: false
25 | namespaceSubDomain: ""
26 | tls:
27 | email: ""
28 | enabled: false
29 | production: false
30 | key: staging
31 | - ingress:
32 | domain: ""
33 | externalDNS: false
34 | namespaceSubDomain: ""
35 | tls:
36 | email: ""
37 | enabled: false
38 | production: false
39 | key: production
40 | gitops: true
41 | ingress:
42 | domain: ""
43 | externalDNS: false
44 | namespaceSubDomain: -jx.
45 | tls:
46 | email: ""
47 | enabled: false
48 | production: false
49 | kaniko: true
50 | repository: nexus
51 | secretStorage: local
52 | storage:
53 | backup:
54 | enabled: false
55 | url: ""
56 | logs:
57 | enabled: false
58 | url: ""
59 | reports:
60 | enabled: false
61 | url: ""
62 | repository:
63 | enabled: false
64 | url: ""
65 | vault: {}
66 | velero:
67 | schedule: ""
68 | ttl: ""
69 | versionStream:
70 | ref: master
71 | url: https://github.com/jenkins-x/jenkins-x-versions.git
72 | webhook: prow
73 |
--------------------------------------------------------------------------------
/section-2/video-2.1/README.md:
--------------------------------------------------------------------------------
1 | # Video 2.1
2 |
3 | This video demonstrates adding an application to Jenkins X from a quickstart.
4 |
5 | ## Prerequisites
6 |
7 | To try out this example for yourself, you will need a Jenkins X cluster up
8 | and running. You can accomplish this by following the instructions in the
9 | rest of Section 1.
10 |
11 | ## Quickstart
12 |
13 | Jenkins X includes "quickstarts", which are repositories that already have
14 | some code available. You can use these to quickly add a new application to
15 | Jenkins X, allowing you to place your own code into a repository that is
16 | already configured for Jenkins X.
17 |
18 | To create a new Jenkins X quickstart, run:
19 |
20 | ```
21 | jx create quickstart
22 | ```
23 |
24 | Once the process is complete, you will have a new Git repository published to
25 | GitHub and configured to build and deploy using Jenkins X and Kubernetes.
26 |
27 | ## Inspection
28 |
29 | You can inspect your new application using a variety of Jenkins X commands,
30 | as documented here:
31 |
32 | https://jenkins-x.io/docs/using-jx/developing/browsing/
33 |
--------------------------------------------------------------------------------
/section-2/video-2.2/README.md:
--------------------------------------------------------------------------------
1 | # Video 2.2
2 |
3 | This video demonstrates importing existing code as an application in Jenkins X.
4 |
5 | ## Prerequisites
6 |
7 | To try out this example for yourself, you will need a Jenkins X cluster up
8 | and running. You can accomplish this by following the instructions in the
9 | rest of Section 1.
10 |
11 | ## Import
12 |
13 | The `jx import` command will import existing code into Jenkins X. It will
14 | create the necessary Docker build and Helm chart to deploy the application
15 | to Kubernetes.
16 |
17 | This folder contains a "Hello World" Node application using Express. To import
18 | it to Jenkins X, run:
19 |
20 | ```
21 | jx import express-hello
22 | ```
23 |
24 | Once the process is complete, you will have a new Git repository published to
25 | GitHub and configured to build and deploy using Jenkins X and Kubernetes.
26 |
27 | ## Inspection
28 |
29 | You can inspect your new application using a variety of Jenkins X commands,
30 | as documented here:
31 |
32 | https://jenkins-x.io/docs/using-jx/developing/browsing/
33 |
--------------------------------------------------------------------------------
/section-2/video-2.2/express-hello/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-2/video-2.2/express-hello/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-2/video-2.2/express-hello/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "array-flatten": {
17 | "version": "1.1.1",
18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
20 | },
21 | "body-parser": {
22 | "version": "1.19.0",
23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
24 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
25 | "requires": {
26 | "bytes": "3.1.0",
27 | "content-type": "~1.0.4",
28 | "debug": "2.6.9",
29 | "depd": "~1.1.2",
30 | "http-errors": "1.7.2",
31 | "iconv-lite": "0.4.24",
32 | "on-finished": "~2.3.0",
33 | "qs": "6.7.0",
34 | "raw-body": "2.4.0",
35 | "type-is": "~1.6.17"
36 | }
37 | },
38 | "bytes": {
39 | "version": "3.1.0",
40 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
41 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
42 | },
43 | "content-disposition": {
44 | "version": "0.5.3",
45 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
46 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
47 | "requires": {
48 | "safe-buffer": "5.1.2"
49 | }
50 | },
51 | "content-type": {
52 | "version": "1.0.4",
53 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
54 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
55 | },
56 | "cookie": {
57 | "version": "0.4.0",
58 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
59 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
60 | },
61 | "cookie-signature": {
62 | "version": "1.0.6",
63 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
64 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
65 | },
66 | "debug": {
67 | "version": "2.6.9",
68 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
69 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
70 | "requires": {
71 | "ms": "2.0.0"
72 | }
73 | },
74 | "depd": {
75 | "version": "1.1.2",
76 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
77 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
78 | },
79 | "destroy": {
80 | "version": "1.0.4",
81 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
82 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
83 | },
84 | "ee-first": {
85 | "version": "1.1.1",
86 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
87 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
88 | },
89 | "encodeurl": {
90 | "version": "1.0.2",
91 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
92 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
93 | },
94 | "escape-html": {
95 | "version": "1.0.3",
96 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
97 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
98 | },
99 | "etag": {
100 | "version": "1.8.1",
101 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
102 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
103 | },
104 | "express": {
105 | "version": "4.17.1",
106 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
107 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
108 | "requires": {
109 | "accepts": "~1.3.7",
110 | "array-flatten": "1.1.1",
111 | "body-parser": "1.19.0",
112 | "content-disposition": "0.5.3",
113 | "content-type": "~1.0.4",
114 | "cookie": "0.4.0",
115 | "cookie-signature": "1.0.6",
116 | "debug": "2.6.9",
117 | "depd": "~1.1.2",
118 | "encodeurl": "~1.0.2",
119 | "escape-html": "~1.0.3",
120 | "etag": "~1.8.1",
121 | "finalhandler": "~1.1.2",
122 | "fresh": "0.5.2",
123 | "merge-descriptors": "1.0.1",
124 | "methods": "~1.1.2",
125 | "on-finished": "~2.3.0",
126 | "parseurl": "~1.3.3",
127 | "path-to-regexp": "0.1.7",
128 | "proxy-addr": "~2.0.5",
129 | "qs": "6.7.0",
130 | "range-parser": "~1.2.1",
131 | "safe-buffer": "5.1.2",
132 | "send": "0.17.1",
133 | "serve-static": "1.14.1",
134 | "setprototypeof": "1.1.1",
135 | "statuses": "~1.5.0",
136 | "type-is": "~1.6.18",
137 | "utils-merge": "1.0.1",
138 | "vary": "~1.1.2"
139 | }
140 | },
141 | "finalhandler": {
142 | "version": "1.1.2",
143 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
144 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
145 | "requires": {
146 | "debug": "2.6.9",
147 | "encodeurl": "~1.0.2",
148 | "escape-html": "~1.0.3",
149 | "on-finished": "~2.3.0",
150 | "parseurl": "~1.3.3",
151 | "statuses": "~1.5.0",
152 | "unpipe": "~1.0.0"
153 | }
154 | },
155 | "forwarded": {
156 | "version": "0.1.2",
157 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
158 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
159 | },
160 | "fresh": {
161 | "version": "0.5.2",
162 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
163 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
164 | },
165 | "http-errors": {
166 | "version": "1.7.2",
167 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
168 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
169 | "requires": {
170 | "depd": "~1.1.2",
171 | "inherits": "2.0.3",
172 | "setprototypeof": "1.1.1",
173 | "statuses": ">= 1.5.0 < 2",
174 | "toidentifier": "1.0.0"
175 | }
176 | },
177 | "iconv-lite": {
178 | "version": "0.4.24",
179 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
180 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
181 | "requires": {
182 | "safer-buffer": ">= 2.1.2 < 3"
183 | }
184 | },
185 | "inherits": {
186 | "version": "2.0.3",
187 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
188 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
189 | },
190 | "ipaddr.js": {
191 | "version": "1.9.0",
192 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
193 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
194 | },
195 | "media-typer": {
196 | "version": "0.3.0",
197 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
198 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
199 | },
200 | "merge-descriptors": {
201 | "version": "1.0.1",
202 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
203 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
204 | },
205 | "methods": {
206 | "version": "1.1.2",
207 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
208 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
209 | },
210 | "mime": {
211 | "version": "1.6.0",
212 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
213 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
214 | },
215 | "mime-db": {
216 | "version": "1.43.0",
217 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
218 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
219 | },
220 | "mime-types": {
221 | "version": "2.1.26",
222 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
223 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
224 | "requires": {
225 | "mime-db": "1.43.0"
226 | }
227 | },
228 | "ms": {
229 | "version": "2.0.0",
230 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
231 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
232 | },
233 | "negotiator": {
234 | "version": "0.6.2",
235 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
236 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
237 | },
238 | "on-finished": {
239 | "version": "2.3.0",
240 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
241 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
242 | "requires": {
243 | "ee-first": "1.1.1"
244 | }
245 | },
246 | "parseurl": {
247 | "version": "1.3.3",
248 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
249 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
250 | },
251 | "path-to-regexp": {
252 | "version": "0.1.7",
253 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
254 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
255 | },
256 | "proxy-addr": {
257 | "version": "2.0.5",
258 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
259 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
260 | "requires": {
261 | "forwarded": "~0.1.2",
262 | "ipaddr.js": "1.9.0"
263 | }
264 | },
265 | "qs": {
266 | "version": "6.7.0",
267 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
268 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
269 | },
270 | "range-parser": {
271 | "version": "1.2.1",
272 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
273 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
274 | },
275 | "raw-body": {
276 | "version": "2.4.0",
277 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
278 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
279 | "requires": {
280 | "bytes": "3.1.0",
281 | "http-errors": "1.7.2",
282 | "iconv-lite": "0.4.24",
283 | "unpipe": "1.0.0"
284 | }
285 | },
286 | "safe-buffer": {
287 | "version": "5.1.2",
288 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
289 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
290 | },
291 | "safer-buffer": {
292 | "version": "2.1.2",
293 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
294 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
295 | },
296 | "send": {
297 | "version": "0.17.1",
298 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
299 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
300 | "requires": {
301 | "debug": "2.6.9",
302 | "depd": "~1.1.2",
303 | "destroy": "~1.0.4",
304 | "encodeurl": "~1.0.2",
305 | "escape-html": "~1.0.3",
306 | "etag": "~1.8.1",
307 | "fresh": "0.5.2",
308 | "http-errors": "~1.7.2",
309 | "mime": "1.6.0",
310 | "ms": "2.1.1",
311 | "on-finished": "~2.3.0",
312 | "range-parser": "~1.2.1",
313 | "statuses": "~1.5.0"
314 | },
315 | "dependencies": {
316 | "ms": {
317 | "version": "2.1.1",
318 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
319 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
320 | }
321 | }
322 | },
323 | "serve-static": {
324 | "version": "1.14.1",
325 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
326 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
327 | "requires": {
328 | "encodeurl": "~1.0.2",
329 | "escape-html": "~1.0.3",
330 | "parseurl": "~1.3.3",
331 | "send": "0.17.1"
332 | }
333 | },
334 | "setprototypeof": {
335 | "version": "1.1.1",
336 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
337 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
338 | },
339 | "statuses": {
340 | "version": "1.5.0",
341 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
342 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
343 | },
344 | "toidentifier": {
345 | "version": "1.0.0",
346 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
347 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
348 | },
349 | "type-is": {
350 | "version": "1.6.18",
351 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
352 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
353 | "requires": {
354 | "media-typer": "0.3.0",
355 | "mime-types": "~2.1.24"
356 | }
357 | },
358 | "unpipe": {
359 | "version": "1.0.0",
360 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
361 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
362 | },
363 | "utils-merge": {
364 | "version": "1.0.1",
365 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
366 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
367 | },
368 | "vary": {
369 | "version": "1.1.2",
370 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
371 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
372 | }
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/section-2/video-2.2/express-hello/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-2/video-2.3/README.md:
--------------------------------------------------------------------------------
1 | # Video 2.3
2 |
3 | This video demonstrates what happens behind the scenes when we add an
4 | application to Jenkins X.
5 |
6 | ## Prerequisites
7 |
8 | To see similar pull requests in your own Jenkins configuration repository,
9 | create your Jenkins X installation as described in Section 1, then add at
10 | least one application as described in Video 2.1 or 2.2.
11 |
12 | ## GitOps
13 |
14 | Every command we run that modifies the Jenkins X installation, such as adding
15 | an application with `jx create quickstart` or `jx import`, also results in a
16 | Git commit to our configuration repository. This configuration repository
17 | tells Jenkins X what applications are configured and how to obtain the source
18 | code. As we will see in the future, it also identifies what version of an
19 | application is running in each environment.
20 |
21 | See the video for details on how Jenkins X uses GitOps.
22 |
--------------------------------------------------------------------------------
/section-2/video-2.4/README.md:
--------------------------------------------------------------------------------
1 | # Video 2.4
2 |
3 | This video demonstrates the Prow web interface that shows a build status
4 | screen.
5 |
6 | ## Prerequisites
7 |
8 | To see the Prow status screen and build status for jobs in your own cluster,
9 | create your Jenkins X installation as described in Section 1, then add at
10 | least one application as described in Video 2.1 or 2.2.
11 |
12 | ## Prow
13 |
14 | Prow is a Kubernetes native CI/CD server. It is triggered by webhooks from
15 | the Git repository and runs builds in Docker containers in Kubernetes. It
16 | provides a basic status page and also reports build results back to GitHub
17 | as updates to pull requests.
18 |
19 | See the video for details on Prow.
20 |
--------------------------------------------------------------------------------
/section-2/video-2.5/README.md:
--------------------------------------------------------------------------------
1 | # Video 2.5
2 |
3 | This video demonstrates viewing pipeline logs for Jenkins X builds.
4 |
5 | ## Prerequisites
6 |
7 | To see pipeline logs for jobs in your own cluster, create your Jenkins X
8 | installation as described in Section 1, then add at least one application as
9 | described in Video 2.1 or 2.2.
10 |
11 | ## Applications, Activities and Logs
12 |
13 | As we saw before, you can get a list of applications using:
14 |
15 | ```
16 | jx get applications
17 | ```
18 |
19 | You can also get a list of build activities:
20 |
21 | ```
22 | jx get activities
23 | ```
24 |
25 | Finally, you can see specific build logs:
26 |
27 | ```
28 | jx get build logs
29 | ```
30 |
31 | See the video for examples.
32 |
--------------------------------------------------------------------------------
/section-2/video-2.6/README.md:
--------------------------------------------------------------------------------
1 | # Video 2.6
2 |
3 | This video demonstrates the underlying Kubernetes resources that Jenkins X
4 | creates when it deploys an application.
5 |
6 | ## Prerequisites
7 |
8 | To see the Kubernetes resources for applications in your own cluster, create
9 | your Jenkins X installation as described in Section 1, then add at least one
10 | application as described in Video 2.1 or 2.2.
11 |
12 | ## Kubernetes
13 |
14 | Kubernetes is a container orchestration platform. Jenkins X uses Kubernetes to
15 | run its own components, run builds, and deploy applications. We can use the
16 | `kubectl` command to inspect Kubernetes resources.
17 |
18 | Kubernetes organizes containers and other resources into namespaces. We can
19 | see the list of namespaces using:
20 |
21 | ```
22 | kubectl get ns
23 | ```
24 |
25 | Kubernetes organizes running containers into "pods". To see the pods in the
26 | `jx-staging` namespace, we can run:
27 |
28 | ```
29 | kubectl -n jx-staging get pods
30 | ```
31 |
32 | Finally, we can see the log for a given pod using:
33 |
34 | ```
35 | kubectl -n jx-staging logs
36 | ```
37 |
38 | See the video for examples.
39 |
--------------------------------------------------------------------------------
/section-3/video-3.1/README.md:
--------------------------------------------------------------------------------
1 | # Video 3.1
2 |
3 | This video demonstrates how Jenkins X uses build packs to tell it what
4 | steps to take to build, test, and deploy software.
5 |
6 | ## Prerequisites
7 |
8 | To see the Jenkins X build packs, configuration file, and resulting build
9 | steps in your own cluster, first install your cluster per the instructions
10 | in section 1.
11 |
12 | ## Build Packs
13 |
14 | Jenkins X includes "build packs", which contain instructions for how to build
15 | and deploy code in various programming languages (Java, Python, JavaScript,
16 | etc.).
17 |
18 | Default Jenkins X build packs are in Git repositories on GitHub. Jenkins X
19 | downloads build packs to our `$HOME/.jx` directory so it can choose the right
20 | build pack for our code.
21 |
22 | To get started, import the JavaScript project in this folder:
23 |
24 | ```
25 | jx import hello-video-3-1
26 | ```
27 |
28 | Once the project is imported, you can see a new file `jenkins-x.yml` with
29 | the content:
30 |
31 | ```
32 | buildPack: javascript
33 | ```
34 |
35 | This tells Jenkins X what build pack to use to build the project.
36 |
--------------------------------------------------------------------------------
/section-3/video-3.1/hello-video-3-1/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-3/video-3.1/hello-video-3-1/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-3/video-3.1/hello-video-3-1/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "array-flatten": {
17 | "version": "1.1.1",
18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
20 | },
21 | "body-parser": {
22 | "version": "1.19.0",
23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
24 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
25 | "requires": {
26 | "bytes": "3.1.0",
27 | "content-type": "~1.0.4",
28 | "debug": "2.6.9",
29 | "depd": "~1.1.2",
30 | "http-errors": "1.7.2",
31 | "iconv-lite": "0.4.24",
32 | "on-finished": "~2.3.0",
33 | "qs": "6.7.0",
34 | "raw-body": "2.4.0",
35 | "type-is": "~1.6.17"
36 | }
37 | },
38 | "bytes": {
39 | "version": "3.1.0",
40 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
41 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
42 | },
43 | "content-disposition": {
44 | "version": "0.5.3",
45 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
46 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
47 | "requires": {
48 | "safe-buffer": "5.1.2"
49 | }
50 | },
51 | "content-type": {
52 | "version": "1.0.4",
53 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
54 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
55 | },
56 | "cookie": {
57 | "version": "0.4.0",
58 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
59 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
60 | },
61 | "cookie-signature": {
62 | "version": "1.0.6",
63 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
64 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
65 | },
66 | "debug": {
67 | "version": "2.6.9",
68 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
69 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
70 | "requires": {
71 | "ms": "2.0.0"
72 | }
73 | },
74 | "depd": {
75 | "version": "1.1.2",
76 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
77 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
78 | },
79 | "destroy": {
80 | "version": "1.0.4",
81 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
82 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
83 | },
84 | "ee-first": {
85 | "version": "1.1.1",
86 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
87 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
88 | },
89 | "encodeurl": {
90 | "version": "1.0.2",
91 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
92 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
93 | },
94 | "escape-html": {
95 | "version": "1.0.3",
96 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
97 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
98 | },
99 | "etag": {
100 | "version": "1.8.1",
101 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
102 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
103 | },
104 | "express": {
105 | "version": "4.17.1",
106 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
107 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
108 | "requires": {
109 | "accepts": "~1.3.7",
110 | "array-flatten": "1.1.1",
111 | "body-parser": "1.19.0",
112 | "content-disposition": "0.5.3",
113 | "content-type": "~1.0.4",
114 | "cookie": "0.4.0",
115 | "cookie-signature": "1.0.6",
116 | "debug": "2.6.9",
117 | "depd": "~1.1.2",
118 | "encodeurl": "~1.0.2",
119 | "escape-html": "~1.0.3",
120 | "etag": "~1.8.1",
121 | "finalhandler": "~1.1.2",
122 | "fresh": "0.5.2",
123 | "merge-descriptors": "1.0.1",
124 | "methods": "~1.1.2",
125 | "on-finished": "~2.3.0",
126 | "parseurl": "~1.3.3",
127 | "path-to-regexp": "0.1.7",
128 | "proxy-addr": "~2.0.5",
129 | "qs": "6.7.0",
130 | "range-parser": "~1.2.1",
131 | "safe-buffer": "5.1.2",
132 | "send": "0.17.1",
133 | "serve-static": "1.14.1",
134 | "setprototypeof": "1.1.1",
135 | "statuses": "~1.5.0",
136 | "type-is": "~1.6.18",
137 | "utils-merge": "1.0.1",
138 | "vary": "~1.1.2"
139 | }
140 | },
141 | "finalhandler": {
142 | "version": "1.1.2",
143 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
144 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
145 | "requires": {
146 | "debug": "2.6.9",
147 | "encodeurl": "~1.0.2",
148 | "escape-html": "~1.0.3",
149 | "on-finished": "~2.3.0",
150 | "parseurl": "~1.3.3",
151 | "statuses": "~1.5.0",
152 | "unpipe": "~1.0.0"
153 | }
154 | },
155 | "forwarded": {
156 | "version": "0.1.2",
157 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
158 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
159 | },
160 | "fresh": {
161 | "version": "0.5.2",
162 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
163 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
164 | },
165 | "http-errors": {
166 | "version": "1.7.2",
167 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
168 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
169 | "requires": {
170 | "depd": "~1.1.2",
171 | "inherits": "2.0.3",
172 | "setprototypeof": "1.1.1",
173 | "statuses": ">= 1.5.0 < 2",
174 | "toidentifier": "1.0.0"
175 | }
176 | },
177 | "iconv-lite": {
178 | "version": "0.4.24",
179 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
180 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
181 | "requires": {
182 | "safer-buffer": ">= 2.1.2 < 3"
183 | }
184 | },
185 | "inherits": {
186 | "version": "2.0.3",
187 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
188 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
189 | },
190 | "ipaddr.js": {
191 | "version": "1.9.0",
192 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
193 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
194 | },
195 | "media-typer": {
196 | "version": "0.3.0",
197 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
198 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
199 | },
200 | "merge-descriptors": {
201 | "version": "1.0.1",
202 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
203 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
204 | },
205 | "methods": {
206 | "version": "1.1.2",
207 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
208 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
209 | },
210 | "mime": {
211 | "version": "1.6.0",
212 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
213 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
214 | },
215 | "mime-db": {
216 | "version": "1.43.0",
217 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
218 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
219 | },
220 | "mime-types": {
221 | "version": "2.1.26",
222 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
223 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
224 | "requires": {
225 | "mime-db": "1.43.0"
226 | }
227 | },
228 | "ms": {
229 | "version": "2.0.0",
230 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
231 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
232 | },
233 | "negotiator": {
234 | "version": "0.6.2",
235 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
236 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
237 | },
238 | "on-finished": {
239 | "version": "2.3.0",
240 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
241 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
242 | "requires": {
243 | "ee-first": "1.1.1"
244 | }
245 | },
246 | "parseurl": {
247 | "version": "1.3.3",
248 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
249 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
250 | },
251 | "path-to-regexp": {
252 | "version": "0.1.7",
253 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
254 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
255 | },
256 | "proxy-addr": {
257 | "version": "2.0.5",
258 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
259 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
260 | "requires": {
261 | "forwarded": "~0.1.2",
262 | "ipaddr.js": "1.9.0"
263 | }
264 | },
265 | "qs": {
266 | "version": "6.7.0",
267 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
268 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
269 | },
270 | "range-parser": {
271 | "version": "1.2.1",
272 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
273 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
274 | },
275 | "raw-body": {
276 | "version": "2.4.0",
277 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
278 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
279 | "requires": {
280 | "bytes": "3.1.0",
281 | "http-errors": "1.7.2",
282 | "iconv-lite": "0.4.24",
283 | "unpipe": "1.0.0"
284 | }
285 | },
286 | "safe-buffer": {
287 | "version": "5.1.2",
288 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
289 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
290 | },
291 | "safer-buffer": {
292 | "version": "2.1.2",
293 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
294 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
295 | },
296 | "send": {
297 | "version": "0.17.1",
298 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
299 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
300 | "requires": {
301 | "debug": "2.6.9",
302 | "depd": "~1.1.2",
303 | "destroy": "~1.0.4",
304 | "encodeurl": "~1.0.2",
305 | "escape-html": "~1.0.3",
306 | "etag": "~1.8.1",
307 | "fresh": "0.5.2",
308 | "http-errors": "~1.7.2",
309 | "mime": "1.6.0",
310 | "ms": "2.1.1",
311 | "on-finished": "~2.3.0",
312 | "range-parser": "~1.2.1",
313 | "statuses": "~1.5.0"
314 | },
315 | "dependencies": {
316 | "ms": {
317 | "version": "2.1.1",
318 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
319 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
320 | }
321 | }
322 | },
323 | "serve-static": {
324 | "version": "1.14.1",
325 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
326 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
327 | "requires": {
328 | "encodeurl": "~1.0.2",
329 | "escape-html": "~1.0.3",
330 | "parseurl": "~1.3.3",
331 | "send": "0.17.1"
332 | }
333 | },
334 | "setprototypeof": {
335 | "version": "1.1.1",
336 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
337 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
338 | },
339 | "statuses": {
340 | "version": "1.5.0",
341 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
342 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
343 | },
344 | "toidentifier": {
345 | "version": "1.0.0",
346 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
347 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
348 | },
349 | "type-is": {
350 | "version": "1.6.18",
351 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
352 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
353 | "requires": {
354 | "media-typer": "0.3.0",
355 | "mime-types": "~2.1.24"
356 | }
357 | },
358 | "unpipe": {
359 | "version": "1.0.0",
360 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
361 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
362 | },
363 | "utils-merge": {
364 | "version": "1.0.1",
365 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
366 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
367 | },
368 | "vary": {
369 | "version": "1.1.2",
370 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
371 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
372 | }
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/section-3/video-3.1/hello-video-3-1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-3/video-3.2/README.md:
--------------------------------------------------------------------------------
1 | # Video 3.2
2 |
3 | This video demonstrates how Jenkins X can auto-detect the build pack and how
4 | it can be specified on the command line.
5 |
6 | ## Prerequisites
7 |
8 | First install your cluster per the instruction in section 1.
9 |
10 | ## Build Pack Auto-detection
11 |
12 | When we run `jx import`, Jenkins X looks for a `jenkins-x.yml` file. If it
13 | is not present, it will attempt to auto-detect the build pack to use based
14 | on what type of code it finds in the directory.
15 |
16 | To see an example of auto-detection, import the `hello-3-2-auto` folder.
17 |
18 | ```
19 | jx import hello-3-2-auto
20 | ```
21 |
22 | Once the project is imported, you can see a new file `jenkins-x.yml` with
23 | the content:
24 |
25 | ```
26 | buildPack: javascript
27 | ```
28 |
29 | ## Specify Build Pack
30 |
31 | We can specify the build pack either by creating the `jenkins-x.yml` file or
32 | by specifying on the command line.
33 |
34 | To see the list of available build packs:
35 |
36 | ```
37 | jx import --list-packs
38 | ```
39 |
40 | To specify a build pack (using `hello-3-2-specify` as an example):
41 |
42 | ```
43 | jx import hello-3-2-specify --pack=javascript
44 | ```
45 |
--------------------------------------------------------------------------------
/section-3/video-3.2/hello-3-2-auto/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-3/video-3.2/hello-3-2-auto/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-3/video-3.2/hello-3-2-auto/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "array-flatten": {
17 | "version": "1.1.1",
18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
20 | },
21 | "body-parser": {
22 | "version": "1.19.0",
23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
24 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
25 | "requires": {
26 | "bytes": "3.1.0",
27 | "content-type": "~1.0.4",
28 | "debug": "2.6.9",
29 | "depd": "~1.1.2",
30 | "http-errors": "1.7.2",
31 | "iconv-lite": "0.4.24",
32 | "on-finished": "~2.3.0",
33 | "qs": "6.7.0",
34 | "raw-body": "2.4.0",
35 | "type-is": "~1.6.17"
36 | }
37 | },
38 | "bytes": {
39 | "version": "3.1.0",
40 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
41 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
42 | },
43 | "content-disposition": {
44 | "version": "0.5.3",
45 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
46 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
47 | "requires": {
48 | "safe-buffer": "5.1.2"
49 | }
50 | },
51 | "content-type": {
52 | "version": "1.0.4",
53 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
54 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
55 | },
56 | "cookie": {
57 | "version": "0.4.0",
58 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
59 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
60 | },
61 | "cookie-signature": {
62 | "version": "1.0.6",
63 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
64 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
65 | },
66 | "debug": {
67 | "version": "2.6.9",
68 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
69 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
70 | "requires": {
71 | "ms": "2.0.0"
72 | }
73 | },
74 | "depd": {
75 | "version": "1.1.2",
76 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
77 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
78 | },
79 | "destroy": {
80 | "version": "1.0.4",
81 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
82 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
83 | },
84 | "ee-first": {
85 | "version": "1.1.1",
86 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
87 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
88 | },
89 | "encodeurl": {
90 | "version": "1.0.2",
91 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
92 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
93 | },
94 | "escape-html": {
95 | "version": "1.0.3",
96 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
97 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
98 | },
99 | "etag": {
100 | "version": "1.8.1",
101 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
102 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
103 | },
104 | "express": {
105 | "version": "4.17.1",
106 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
107 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
108 | "requires": {
109 | "accepts": "~1.3.7",
110 | "array-flatten": "1.1.1",
111 | "body-parser": "1.19.0",
112 | "content-disposition": "0.5.3",
113 | "content-type": "~1.0.4",
114 | "cookie": "0.4.0",
115 | "cookie-signature": "1.0.6",
116 | "debug": "2.6.9",
117 | "depd": "~1.1.2",
118 | "encodeurl": "~1.0.2",
119 | "escape-html": "~1.0.3",
120 | "etag": "~1.8.1",
121 | "finalhandler": "~1.1.2",
122 | "fresh": "0.5.2",
123 | "merge-descriptors": "1.0.1",
124 | "methods": "~1.1.2",
125 | "on-finished": "~2.3.0",
126 | "parseurl": "~1.3.3",
127 | "path-to-regexp": "0.1.7",
128 | "proxy-addr": "~2.0.5",
129 | "qs": "6.7.0",
130 | "range-parser": "~1.2.1",
131 | "safe-buffer": "5.1.2",
132 | "send": "0.17.1",
133 | "serve-static": "1.14.1",
134 | "setprototypeof": "1.1.1",
135 | "statuses": "~1.5.0",
136 | "type-is": "~1.6.18",
137 | "utils-merge": "1.0.1",
138 | "vary": "~1.1.2"
139 | }
140 | },
141 | "finalhandler": {
142 | "version": "1.1.2",
143 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
144 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
145 | "requires": {
146 | "debug": "2.6.9",
147 | "encodeurl": "~1.0.2",
148 | "escape-html": "~1.0.3",
149 | "on-finished": "~2.3.0",
150 | "parseurl": "~1.3.3",
151 | "statuses": "~1.5.0",
152 | "unpipe": "~1.0.0"
153 | }
154 | },
155 | "forwarded": {
156 | "version": "0.1.2",
157 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
158 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
159 | },
160 | "fresh": {
161 | "version": "0.5.2",
162 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
163 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
164 | },
165 | "http-errors": {
166 | "version": "1.7.2",
167 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
168 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
169 | "requires": {
170 | "depd": "~1.1.2",
171 | "inherits": "2.0.3",
172 | "setprototypeof": "1.1.1",
173 | "statuses": ">= 1.5.0 < 2",
174 | "toidentifier": "1.0.0"
175 | }
176 | },
177 | "iconv-lite": {
178 | "version": "0.4.24",
179 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
180 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
181 | "requires": {
182 | "safer-buffer": ">= 2.1.2 < 3"
183 | }
184 | },
185 | "inherits": {
186 | "version": "2.0.3",
187 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
188 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
189 | },
190 | "ipaddr.js": {
191 | "version": "1.9.0",
192 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
193 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
194 | },
195 | "media-typer": {
196 | "version": "0.3.0",
197 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
198 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
199 | },
200 | "merge-descriptors": {
201 | "version": "1.0.1",
202 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
203 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
204 | },
205 | "methods": {
206 | "version": "1.1.2",
207 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
208 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
209 | },
210 | "mime": {
211 | "version": "1.6.0",
212 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
213 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
214 | },
215 | "mime-db": {
216 | "version": "1.43.0",
217 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
218 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
219 | },
220 | "mime-types": {
221 | "version": "2.1.26",
222 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
223 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
224 | "requires": {
225 | "mime-db": "1.43.0"
226 | }
227 | },
228 | "ms": {
229 | "version": "2.0.0",
230 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
231 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
232 | },
233 | "negotiator": {
234 | "version": "0.6.2",
235 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
236 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
237 | },
238 | "on-finished": {
239 | "version": "2.3.0",
240 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
241 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
242 | "requires": {
243 | "ee-first": "1.1.1"
244 | }
245 | },
246 | "parseurl": {
247 | "version": "1.3.3",
248 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
249 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
250 | },
251 | "path-to-regexp": {
252 | "version": "0.1.7",
253 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
254 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
255 | },
256 | "proxy-addr": {
257 | "version": "2.0.5",
258 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
259 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
260 | "requires": {
261 | "forwarded": "~0.1.2",
262 | "ipaddr.js": "1.9.0"
263 | }
264 | },
265 | "qs": {
266 | "version": "6.7.0",
267 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
268 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
269 | },
270 | "range-parser": {
271 | "version": "1.2.1",
272 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
273 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
274 | },
275 | "raw-body": {
276 | "version": "2.4.0",
277 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
278 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
279 | "requires": {
280 | "bytes": "3.1.0",
281 | "http-errors": "1.7.2",
282 | "iconv-lite": "0.4.24",
283 | "unpipe": "1.0.0"
284 | }
285 | },
286 | "safe-buffer": {
287 | "version": "5.1.2",
288 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
289 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
290 | },
291 | "safer-buffer": {
292 | "version": "2.1.2",
293 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
294 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
295 | },
296 | "send": {
297 | "version": "0.17.1",
298 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
299 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
300 | "requires": {
301 | "debug": "2.6.9",
302 | "depd": "~1.1.2",
303 | "destroy": "~1.0.4",
304 | "encodeurl": "~1.0.2",
305 | "escape-html": "~1.0.3",
306 | "etag": "~1.8.1",
307 | "fresh": "0.5.2",
308 | "http-errors": "~1.7.2",
309 | "mime": "1.6.0",
310 | "ms": "2.1.1",
311 | "on-finished": "~2.3.0",
312 | "range-parser": "~1.2.1",
313 | "statuses": "~1.5.0"
314 | },
315 | "dependencies": {
316 | "ms": {
317 | "version": "2.1.1",
318 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
319 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
320 | }
321 | }
322 | },
323 | "serve-static": {
324 | "version": "1.14.1",
325 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
326 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
327 | "requires": {
328 | "encodeurl": "~1.0.2",
329 | "escape-html": "~1.0.3",
330 | "parseurl": "~1.3.3",
331 | "send": "0.17.1"
332 | }
333 | },
334 | "setprototypeof": {
335 | "version": "1.1.1",
336 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
337 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
338 | },
339 | "statuses": {
340 | "version": "1.5.0",
341 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
342 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
343 | },
344 | "toidentifier": {
345 | "version": "1.0.0",
346 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
347 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
348 | },
349 | "type-is": {
350 | "version": "1.6.18",
351 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
352 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
353 | "requires": {
354 | "media-typer": "0.3.0",
355 | "mime-types": "~2.1.24"
356 | }
357 | },
358 | "unpipe": {
359 | "version": "1.0.0",
360 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
361 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
362 | },
363 | "utils-merge": {
364 | "version": "1.0.1",
365 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
366 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
367 | },
368 | "vary": {
369 | "version": "1.1.2",
370 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
371 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
372 | }
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/section-3/video-3.2/hello-3-2-auto/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-3/video-3.2/hello-3-2-specify/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-3/video-3.2/hello-3-2-specify/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-3/video-3.2/hello-3-2-specify/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-3/video-3.3/README.md:
--------------------------------------------------------------------------------
1 | # Video 3.3
2 |
3 | This video discusses how build packs use YAML to define the build steps.
4 |
5 | ## Prerequisites
6 |
7 | None
8 |
9 | ## Build Pack YAML
10 |
11 | See the video for information on build packs and YAML. You can use
12 | these links for more information.
13 |
14 | * About YAML: https://yaml.org/
15 | * Jenkins X Build Pack Documentation: https://jenkins-x.io/docs/reference/components/build-packs/
16 | * Jenkins X Classic Build Packs: https://github.com/jenkins-x-buildpacks/jenkins-x-classic
17 | * Jenkins X Kubernetes Build Packs: https://github.com/jenkins-x-buildpacks/jenkins-x-kubernetes
18 |
--------------------------------------------------------------------------------
/section-3/video-3.4/README.md:
--------------------------------------------------------------------------------
1 | # Video 3.4
2 |
3 | This video discusses how Jenkins X build packs use inheritance to avoid
4 | duplication in defining build steps.
5 |
6 | ## Prerequisites
7 |
8 | None
9 |
10 | ## Build Pack Inheritance
11 |
12 | See the video for information on build packs and YAML. You can use
13 | these links for more information.
14 |
15 | * Jenkins X Build Pack Inheritance Documentation: https://jenkins-x.io/docs/reference/components/build-packs/#extending
16 | * Jenkins X Classic Build Packs: https://github.com/jenkins-x-buildpacks/jenkins-x-classic
17 | * Jenkins X Kubernetes Build Packs: https://github.com/jenkins-x-buildpacks/jenkins-x-kubernetes
18 |
--------------------------------------------------------------------------------
/section-3/video-3.5/README.md:
--------------------------------------------------------------------------------
1 | # Video 3.5
2 |
3 | This video demonstrates how to add or replace build steps in a Jenkins X
4 | build pack.
5 |
6 | ## Prerequisites
7 |
8 | First install your cluster per the instruction in section 1.
9 |
10 | ## Build Pack Overrides
11 |
12 | We can add or replace build steps in a pipeline through the `jenkins-x.yml`
13 | file.
14 |
15 | For example, to add `npm audit` to our JavaScript build, we just need this
16 | content in `jenkins-x.yml`:
17 |
18 | ```
19 | buildPack: javascript
20 | pipelineConfig:
21 | pipelines:
22 | release:
23 | build:
24 | steps:
25 | - sh: npm audit
26 | name: npm-audit
27 | ```
28 |
29 | This will result in `npm audit` being run after all of the build steps that
30 | are defined in the build pack (including any build steps in inherited
31 | pipelines).
32 |
33 | If we instead want to completely replace the build steps, we can use the
34 | `replace` field. For example, to change the JavaScript build to remove the
35 | `npm test` step:
36 |
37 | ```
38 | buildPack: javascript
39 | pipelineConfig:
40 | pipelines:
41 | release:
42 | build:
43 | replace: true
44 | steps:
45 | - sh: jx step credential -s npm-token -k file -f /builder/home/.npmrc --optional=true
46 | name: npmrc
47 | - sh: npm install
48 | name: npm-install
49 | - sh: export VERSION=$PREVIEW_VERSION && skaffold build -f skaffold.yaml
50 | name: container-build
51 | ```
52 |
53 | Note that we needed to bring in the build steps from all of the inherited
54 | pipeline files because they are all replaced.
55 |
--------------------------------------------------------------------------------
/section-3/video-3.5/hello-3-5-audit/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-3/video-3.5/hello-3-5-audit/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-3/video-3.5/hello-3-5-audit/jenkins-x.yml:
--------------------------------------------------------------------------------
1 | buildPack: javascript
2 | pipelineConfig:
3 | pipelines:
4 | release:
5 | build:
6 | steps:
7 | - sh: npm audit
8 | name: npm-audit
9 |
--------------------------------------------------------------------------------
/section-3/video-3.5/hello-3-5-audit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-3/video-3.5/hello-3-5-replace/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-3/video-3.5/hello-3-5-replace/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-3/video-3.5/hello-3-5-replace/jenkins-x.yml:
--------------------------------------------------------------------------------
1 | buildPack: javascript
2 | pipelineConfig:
3 | pipelines:
4 | release:
5 | build:
6 | replace: true
7 | steps:
8 | - sh: jx step credential -s npm-token -k file -f /builder/home/.npmrc --optional=true
9 | name: npmrc
10 | - sh: npm install
11 | name: npm-install
12 | - sh: export VERSION=$PREVIEW_VERSION && skaffold build -f skaffold.yaml
13 | name: container-build
14 |
--------------------------------------------------------------------------------
/section-3/video-3.5/hello-3-5-replace/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-4/video-4.1/README.md:
--------------------------------------------------------------------------------
1 | # Video 4.1
2 |
3 | This video demonstrates promoting an application to the production environment.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | ## Environments and Promotion
10 |
11 | Jenkins X uses environments to take an application through a typical
12 | continuous delivery workflow. By default, any pull requests are deployed to
13 | a "development" environment. Any changes to master (from a pull request or a
14 | direct push to master) are deployed automatically to a "staging" environment.
15 | This allows us to test the latest version before manually deploying to
16 | "production".
17 |
18 | To try this out, first import the application in `hello-4-1` using `jx import`.
19 | Then, once it has finished deploying to "staging", you can test it. When you
20 | are ready to deploy to production, run:
21 |
22 | ```
23 | jx promote hello-4-1 --version 0.0.1 --env production
24 | ```
25 |
26 | If you specified a different application name, or if you pushed changes to
27 | `master`, you may need to use a different application name or version number.
28 | You can always use `jx get applications` to see your application and figure
29 | out what parameters to use to promote to production.
30 |
31 | Once the promotion has succeeded, `jx get applications` will show your new
32 | application promoted to production and let you keep track of what version has
33 | been promoted there.
34 |
--------------------------------------------------------------------------------
/section-4/video-4.1/hello-4-1/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-4/video-4.1/hello-4-1/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-4/video-4.1/hello-4-1/jenkins-x.yml:
--------------------------------------------------------------------------------
1 | buildPack: javascript
2 |
--------------------------------------------------------------------------------
/section-4/video-4.1/hello-4-1/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "array-flatten": {
17 | "version": "1.1.1",
18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
20 | },
21 | "body-parser": {
22 | "version": "1.19.0",
23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
24 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
25 | "requires": {
26 | "bytes": "3.1.0",
27 | "content-type": "~1.0.4",
28 | "debug": "2.6.9",
29 | "depd": "~1.1.2",
30 | "http-errors": "1.7.2",
31 | "iconv-lite": "0.4.24",
32 | "on-finished": "~2.3.0",
33 | "qs": "6.7.0",
34 | "raw-body": "2.4.0",
35 | "type-is": "~1.6.17"
36 | }
37 | },
38 | "bytes": {
39 | "version": "3.1.0",
40 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
41 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
42 | },
43 | "content-disposition": {
44 | "version": "0.5.3",
45 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
46 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
47 | "requires": {
48 | "safe-buffer": "5.1.2"
49 | }
50 | },
51 | "content-type": {
52 | "version": "1.0.4",
53 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
54 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
55 | },
56 | "cookie": {
57 | "version": "0.4.0",
58 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
59 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
60 | },
61 | "cookie-signature": {
62 | "version": "1.0.6",
63 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
64 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
65 | },
66 | "debug": {
67 | "version": "2.6.9",
68 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
69 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
70 | "requires": {
71 | "ms": "2.0.0"
72 | }
73 | },
74 | "depd": {
75 | "version": "1.1.2",
76 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
77 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
78 | },
79 | "destroy": {
80 | "version": "1.0.4",
81 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
82 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
83 | },
84 | "ee-first": {
85 | "version": "1.1.1",
86 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
87 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
88 | },
89 | "encodeurl": {
90 | "version": "1.0.2",
91 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
92 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
93 | },
94 | "escape-html": {
95 | "version": "1.0.3",
96 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
97 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
98 | },
99 | "etag": {
100 | "version": "1.8.1",
101 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
102 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
103 | },
104 | "express": {
105 | "version": "4.17.1",
106 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
107 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
108 | "requires": {
109 | "accepts": "~1.3.7",
110 | "array-flatten": "1.1.1",
111 | "body-parser": "1.19.0",
112 | "content-disposition": "0.5.3",
113 | "content-type": "~1.0.4",
114 | "cookie": "0.4.0",
115 | "cookie-signature": "1.0.6",
116 | "debug": "2.6.9",
117 | "depd": "~1.1.2",
118 | "encodeurl": "~1.0.2",
119 | "escape-html": "~1.0.3",
120 | "etag": "~1.8.1",
121 | "finalhandler": "~1.1.2",
122 | "fresh": "0.5.2",
123 | "merge-descriptors": "1.0.1",
124 | "methods": "~1.1.2",
125 | "on-finished": "~2.3.0",
126 | "parseurl": "~1.3.3",
127 | "path-to-regexp": "0.1.7",
128 | "proxy-addr": "~2.0.5",
129 | "qs": "6.7.0",
130 | "range-parser": "~1.2.1",
131 | "safe-buffer": "5.1.2",
132 | "send": "0.17.1",
133 | "serve-static": "1.14.1",
134 | "setprototypeof": "1.1.1",
135 | "statuses": "~1.5.0",
136 | "type-is": "~1.6.18",
137 | "utils-merge": "1.0.1",
138 | "vary": "~1.1.2"
139 | }
140 | },
141 | "finalhandler": {
142 | "version": "1.1.2",
143 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
144 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
145 | "requires": {
146 | "debug": "2.6.9",
147 | "encodeurl": "~1.0.2",
148 | "escape-html": "~1.0.3",
149 | "on-finished": "~2.3.0",
150 | "parseurl": "~1.3.3",
151 | "statuses": "~1.5.0",
152 | "unpipe": "~1.0.0"
153 | }
154 | },
155 | "forwarded": {
156 | "version": "0.1.2",
157 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
158 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
159 | },
160 | "fresh": {
161 | "version": "0.5.2",
162 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
163 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
164 | },
165 | "http-errors": {
166 | "version": "1.7.2",
167 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
168 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
169 | "requires": {
170 | "depd": "~1.1.2",
171 | "inherits": "2.0.3",
172 | "setprototypeof": "1.1.1",
173 | "statuses": ">= 1.5.0 < 2",
174 | "toidentifier": "1.0.0"
175 | }
176 | },
177 | "iconv-lite": {
178 | "version": "0.4.24",
179 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
180 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
181 | "requires": {
182 | "safer-buffer": ">= 2.1.2 < 3"
183 | }
184 | },
185 | "inherits": {
186 | "version": "2.0.3",
187 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
188 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
189 | },
190 | "ipaddr.js": {
191 | "version": "1.9.0",
192 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
193 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
194 | },
195 | "media-typer": {
196 | "version": "0.3.0",
197 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
198 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
199 | },
200 | "merge-descriptors": {
201 | "version": "1.0.1",
202 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
203 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
204 | },
205 | "methods": {
206 | "version": "1.1.2",
207 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
208 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
209 | },
210 | "mime": {
211 | "version": "1.6.0",
212 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
213 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
214 | },
215 | "mime-db": {
216 | "version": "1.43.0",
217 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
218 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
219 | },
220 | "mime-types": {
221 | "version": "2.1.26",
222 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
223 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
224 | "requires": {
225 | "mime-db": "1.43.0"
226 | }
227 | },
228 | "ms": {
229 | "version": "2.0.0",
230 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
231 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
232 | },
233 | "negotiator": {
234 | "version": "0.6.2",
235 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
236 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
237 | },
238 | "on-finished": {
239 | "version": "2.3.0",
240 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
241 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
242 | "requires": {
243 | "ee-first": "1.1.1"
244 | }
245 | },
246 | "parseurl": {
247 | "version": "1.3.3",
248 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
249 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
250 | },
251 | "path-to-regexp": {
252 | "version": "0.1.7",
253 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
254 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
255 | },
256 | "proxy-addr": {
257 | "version": "2.0.5",
258 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
259 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
260 | "requires": {
261 | "forwarded": "~0.1.2",
262 | "ipaddr.js": "1.9.0"
263 | }
264 | },
265 | "qs": {
266 | "version": "6.7.0",
267 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
268 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
269 | },
270 | "range-parser": {
271 | "version": "1.2.1",
272 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
273 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
274 | },
275 | "raw-body": {
276 | "version": "2.4.0",
277 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
278 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
279 | "requires": {
280 | "bytes": "3.1.0",
281 | "http-errors": "1.7.2",
282 | "iconv-lite": "0.4.24",
283 | "unpipe": "1.0.0"
284 | }
285 | },
286 | "safe-buffer": {
287 | "version": "5.1.2",
288 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
289 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
290 | },
291 | "safer-buffer": {
292 | "version": "2.1.2",
293 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
294 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
295 | },
296 | "send": {
297 | "version": "0.17.1",
298 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
299 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
300 | "requires": {
301 | "debug": "2.6.9",
302 | "depd": "~1.1.2",
303 | "destroy": "~1.0.4",
304 | "encodeurl": "~1.0.2",
305 | "escape-html": "~1.0.3",
306 | "etag": "~1.8.1",
307 | "fresh": "0.5.2",
308 | "http-errors": "~1.7.2",
309 | "mime": "1.6.0",
310 | "ms": "2.1.1",
311 | "on-finished": "~2.3.0",
312 | "range-parser": "~1.2.1",
313 | "statuses": "~1.5.0"
314 | },
315 | "dependencies": {
316 | "ms": {
317 | "version": "2.1.1",
318 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
319 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
320 | }
321 | }
322 | },
323 | "serve-static": {
324 | "version": "1.14.1",
325 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
326 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
327 | "requires": {
328 | "encodeurl": "~1.0.2",
329 | "escape-html": "~1.0.3",
330 | "parseurl": "~1.3.3",
331 | "send": "0.17.1"
332 | }
333 | },
334 | "setprototypeof": {
335 | "version": "1.1.1",
336 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
337 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
338 | },
339 | "statuses": {
340 | "version": "1.5.0",
341 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
342 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
343 | },
344 | "toidentifier": {
345 | "version": "1.0.0",
346 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
347 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
348 | },
349 | "type-is": {
350 | "version": "1.6.18",
351 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
352 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
353 | "requires": {
354 | "media-typer": "0.3.0",
355 | "mime-types": "~2.1.24"
356 | }
357 | },
358 | "unpipe": {
359 | "version": "1.0.0",
360 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
361 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
362 | },
363 | "utils-merge": {
364 | "version": "1.0.1",
365 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
366 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
367 | },
368 | "vary": {
369 | "version": "1.1.2",
370 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
371 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
372 | }
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/section-4/video-4.1/hello-4-1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-4/video-4.2/README.md:
--------------------------------------------------------------------------------
1 | # Video 4.2
2 |
3 | This video demonstrates how Jenkins X uses preview environments to deploy a
4 | temporary version of an application during a pull request.
5 |
6 | ## Prerequisites
7 |
8 | First install your cluster per the instruction in section 1.
9 |
10 | ## Preview Environments
11 |
12 | It is common when making changes to an application to create a "feature branch"
13 | and make the changes in that separate branch. Once we are ready to merge the
14 | changes into the master branch, we create a "pull request" in GitHub. This is
15 | an opportunity for others on the team to review the changes before they are
16 | merged into master.
17 |
18 | Jenkins X provides additional functionality for pull requests, including running
19 | a build of the application with the changes merged in, reporting the build
20 | results back to the pull request review page, and deploying the application to
21 | a temporary preview environment that reviewers can use to test the changes.
22 |
23 | To try this out, first import the application in `hello-4-2` using `jx import`.
24 | Then, once it has finished deploying to "staging", create a feature branch:
25 |
26 | ```
27 | cd hello-4-2
28 | git checkout -b trial-change
29 | ```
30 |
31 | At this point you can edit one or more of the files. Then, commit and push the
32 | change:
33 |
34 | ```
35 | git add .
36 | git commit -m 'trial change'
37 | git push -u origin trial-change
38 | ```
39 |
40 | If you visit the application's Git repository in GitHub, you will see Jenkins X
41 | start building the application and report back the results. If the build is
42 | successful, you will see it deploy to a preview environment.
43 |
44 | ## Cleanup
45 |
46 | You can see the list of preview environments using `jx get preview` and delete
47 | preview requirements when they are no longer needed using `jx delete preview`.
48 |
--------------------------------------------------------------------------------
/section-4/video-4.2/hello-4-2/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-4/video-4.2/hello-4-2/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-4/video-4.2/hello-4-2/jenkins-x.yml:
--------------------------------------------------------------------------------
1 | buildPack: javascript
2 |
--------------------------------------------------------------------------------
/section-4/video-4.2/hello-4-2/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "array-flatten": {
17 | "version": "1.1.1",
18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
20 | },
21 | "body-parser": {
22 | "version": "1.19.0",
23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
24 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
25 | "requires": {
26 | "bytes": "3.1.0",
27 | "content-type": "~1.0.4",
28 | "debug": "2.6.9",
29 | "depd": "~1.1.2",
30 | "http-errors": "1.7.2",
31 | "iconv-lite": "0.4.24",
32 | "on-finished": "~2.3.0",
33 | "qs": "6.7.0",
34 | "raw-body": "2.4.0",
35 | "type-is": "~1.6.17"
36 | }
37 | },
38 | "bytes": {
39 | "version": "3.1.0",
40 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
41 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
42 | },
43 | "content-disposition": {
44 | "version": "0.5.3",
45 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
46 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
47 | "requires": {
48 | "safe-buffer": "5.1.2"
49 | }
50 | },
51 | "content-type": {
52 | "version": "1.0.4",
53 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
54 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
55 | },
56 | "cookie": {
57 | "version": "0.4.0",
58 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
59 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
60 | },
61 | "cookie-signature": {
62 | "version": "1.0.6",
63 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
64 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
65 | },
66 | "debug": {
67 | "version": "2.6.9",
68 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
69 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
70 | "requires": {
71 | "ms": "2.0.0"
72 | }
73 | },
74 | "depd": {
75 | "version": "1.1.2",
76 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
77 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
78 | },
79 | "destroy": {
80 | "version": "1.0.4",
81 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
82 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
83 | },
84 | "ee-first": {
85 | "version": "1.1.1",
86 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
87 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
88 | },
89 | "encodeurl": {
90 | "version": "1.0.2",
91 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
92 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
93 | },
94 | "escape-html": {
95 | "version": "1.0.3",
96 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
97 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
98 | },
99 | "etag": {
100 | "version": "1.8.1",
101 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
102 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
103 | },
104 | "express": {
105 | "version": "4.17.1",
106 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
107 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
108 | "requires": {
109 | "accepts": "~1.3.7",
110 | "array-flatten": "1.1.1",
111 | "body-parser": "1.19.0",
112 | "content-disposition": "0.5.3",
113 | "content-type": "~1.0.4",
114 | "cookie": "0.4.0",
115 | "cookie-signature": "1.0.6",
116 | "debug": "2.6.9",
117 | "depd": "~1.1.2",
118 | "encodeurl": "~1.0.2",
119 | "escape-html": "~1.0.3",
120 | "etag": "~1.8.1",
121 | "finalhandler": "~1.1.2",
122 | "fresh": "0.5.2",
123 | "merge-descriptors": "1.0.1",
124 | "methods": "~1.1.2",
125 | "on-finished": "~2.3.0",
126 | "parseurl": "~1.3.3",
127 | "path-to-regexp": "0.1.7",
128 | "proxy-addr": "~2.0.5",
129 | "qs": "6.7.0",
130 | "range-parser": "~1.2.1",
131 | "safe-buffer": "5.1.2",
132 | "send": "0.17.1",
133 | "serve-static": "1.14.1",
134 | "setprototypeof": "1.1.1",
135 | "statuses": "~1.5.0",
136 | "type-is": "~1.6.18",
137 | "utils-merge": "1.0.1",
138 | "vary": "~1.1.2"
139 | }
140 | },
141 | "finalhandler": {
142 | "version": "1.1.2",
143 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
144 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
145 | "requires": {
146 | "debug": "2.6.9",
147 | "encodeurl": "~1.0.2",
148 | "escape-html": "~1.0.3",
149 | "on-finished": "~2.3.0",
150 | "parseurl": "~1.3.3",
151 | "statuses": "~1.5.0",
152 | "unpipe": "~1.0.0"
153 | }
154 | },
155 | "forwarded": {
156 | "version": "0.1.2",
157 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
158 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
159 | },
160 | "fresh": {
161 | "version": "0.5.2",
162 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
163 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
164 | },
165 | "http-errors": {
166 | "version": "1.7.2",
167 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
168 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
169 | "requires": {
170 | "depd": "~1.1.2",
171 | "inherits": "2.0.3",
172 | "setprototypeof": "1.1.1",
173 | "statuses": ">= 1.5.0 < 2",
174 | "toidentifier": "1.0.0"
175 | }
176 | },
177 | "iconv-lite": {
178 | "version": "0.4.24",
179 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
180 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
181 | "requires": {
182 | "safer-buffer": ">= 2.1.2 < 3"
183 | }
184 | },
185 | "inherits": {
186 | "version": "2.0.3",
187 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
188 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
189 | },
190 | "ipaddr.js": {
191 | "version": "1.9.0",
192 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
193 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
194 | },
195 | "media-typer": {
196 | "version": "0.3.0",
197 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
198 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
199 | },
200 | "merge-descriptors": {
201 | "version": "1.0.1",
202 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
203 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
204 | },
205 | "methods": {
206 | "version": "1.1.2",
207 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
208 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
209 | },
210 | "mime": {
211 | "version": "1.6.0",
212 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
213 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
214 | },
215 | "mime-db": {
216 | "version": "1.43.0",
217 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
218 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
219 | },
220 | "mime-types": {
221 | "version": "2.1.26",
222 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
223 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
224 | "requires": {
225 | "mime-db": "1.43.0"
226 | }
227 | },
228 | "ms": {
229 | "version": "2.0.0",
230 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
231 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
232 | },
233 | "negotiator": {
234 | "version": "0.6.2",
235 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
236 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
237 | },
238 | "on-finished": {
239 | "version": "2.3.0",
240 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
241 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
242 | "requires": {
243 | "ee-first": "1.1.1"
244 | }
245 | },
246 | "parseurl": {
247 | "version": "1.3.3",
248 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
249 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
250 | },
251 | "path-to-regexp": {
252 | "version": "0.1.7",
253 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
254 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
255 | },
256 | "proxy-addr": {
257 | "version": "2.0.5",
258 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
259 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
260 | "requires": {
261 | "forwarded": "~0.1.2",
262 | "ipaddr.js": "1.9.0"
263 | }
264 | },
265 | "qs": {
266 | "version": "6.7.0",
267 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
268 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
269 | },
270 | "range-parser": {
271 | "version": "1.2.1",
272 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
273 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
274 | },
275 | "raw-body": {
276 | "version": "2.4.0",
277 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
278 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
279 | "requires": {
280 | "bytes": "3.1.0",
281 | "http-errors": "1.7.2",
282 | "iconv-lite": "0.4.24",
283 | "unpipe": "1.0.0"
284 | }
285 | },
286 | "safe-buffer": {
287 | "version": "5.1.2",
288 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
289 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
290 | },
291 | "safer-buffer": {
292 | "version": "2.1.2",
293 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
294 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
295 | },
296 | "send": {
297 | "version": "0.17.1",
298 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
299 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
300 | "requires": {
301 | "debug": "2.6.9",
302 | "depd": "~1.1.2",
303 | "destroy": "~1.0.4",
304 | "encodeurl": "~1.0.2",
305 | "escape-html": "~1.0.3",
306 | "etag": "~1.8.1",
307 | "fresh": "0.5.2",
308 | "http-errors": "~1.7.2",
309 | "mime": "1.6.0",
310 | "ms": "2.1.1",
311 | "on-finished": "~2.3.0",
312 | "range-parser": "~1.2.1",
313 | "statuses": "~1.5.0"
314 | },
315 | "dependencies": {
316 | "ms": {
317 | "version": "2.1.1",
318 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
319 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
320 | }
321 | }
322 | },
323 | "serve-static": {
324 | "version": "1.14.1",
325 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
326 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
327 | "requires": {
328 | "encodeurl": "~1.0.2",
329 | "escape-html": "~1.0.3",
330 | "parseurl": "~1.3.3",
331 | "send": "0.17.1"
332 | }
333 | },
334 | "setprototypeof": {
335 | "version": "1.1.1",
336 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
337 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
338 | },
339 | "statuses": {
340 | "version": "1.5.0",
341 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
342 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
343 | },
344 | "toidentifier": {
345 | "version": "1.0.0",
346 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
347 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
348 | },
349 | "type-is": {
350 | "version": "1.6.18",
351 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
352 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
353 | "requires": {
354 | "media-typer": "0.3.0",
355 | "mime-types": "~2.1.24"
356 | }
357 | },
358 | "unpipe": {
359 | "version": "1.0.0",
360 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
361 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
362 | },
363 | "utils-merge": {
364 | "version": "1.0.1",
365 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
366 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
367 | },
368 | "vary": {
369 | "version": "1.1.2",
370 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
371 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
372 | }
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/section-4/video-4.2/hello-4-2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-4/video-4.3/README.md:
--------------------------------------------------------------------------------
1 | # Video 4.3
2 |
3 | This video demonstrates how to use a Jenkins X DevPod to run an application
4 | within the Kubernetes cluster, allowing us to see changes immediately.
5 |
6 | ## Prerequisites
7 |
8 | First install your cluster per the instruction in section 1.
9 |
10 | ## DevPod
11 |
12 | A Jenkins X DevPod is a version of our application that is based on our local
13 | code directories rather than what is in Git. Using a Jenkins X DevPod allows
14 | us to test our code in a more realistic environment running in Kubernetes
15 | itself rather than just on the local computer.
16 |
17 | To create a DevPod, run this command from inside the code directory for an
18 | application:
19 |
20 | ```
21 | jx create devpod
22 | ```
23 |
24 | This will create the DevPod and open a shell. You can then start the
25 | application as normal (e.g. `npm start` for our example JavaScript application).
26 |
27 | You can open an additional shell in the DevPod from another terminal window
28 | by running:
29 |
30 | ```
31 | jx create devpod --reuse
32 | ```
33 |
34 | When finished, just run `jx delete devpod` to clean up.
35 |
--------------------------------------------------------------------------------
/section-4/video-4.3/hello-4-3/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-4/video-4.3/hello-4-3/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-4/video-4.3/hello-4-3/jenkins-x.yml:
--------------------------------------------------------------------------------
1 | buildPack: javascript
2 |
--------------------------------------------------------------------------------
/section-4/video-4.3/hello-4-3/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "array-flatten": {
17 | "version": "1.1.1",
18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
20 | },
21 | "body-parser": {
22 | "version": "1.19.0",
23 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
24 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
25 | "requires": {
26 | "bytes": "3.1.0",
27 | "content-type": "~1.0.4",
28 | "debug": "2.6.9",
29 | "depd": "~1.1.2",
30 | "http-errors": "1.7.2",
31 | "iconv-lite": "0.4.24",
32 | "on-finished": "~2.3.0",
33 | "qs": "6.7.0",
34 | "raw-body": "2.4.0",
35 | "type-is": "~1.6.17"
36 | }
37 | },
38 | "bytes": {
39 | "version": "3.1.0",
40 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
41 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
42 | },
43 | "content-disposition": {
44 | "version": "0.5.3",
45 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
46 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
47 | "requires": {
48 | "safe-buffer": "5.1.2"
49 | }
50 | },
51 | "content-type": {
52 | "version": "1.0.4",
53 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
54 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
55 | },
56 | "cookie": {
57 | "version": "0.4.0",
58 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
59 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
60 | },
61 | "cookie-signature": {
62 | "version": "1.0.6",
63 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
64 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
65 | },
66 | "debug": {
67 | "version": "2.6.9",
68 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
69 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
70 | "requires": {
71 | "ms": "2.0.0"
72 | }
73 | },
74 | "depd": {
75 | "version": "1.1.2",
76 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
77 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
78 | },
79 | "destroy": {
80 | "version": "1.0.4",
81 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
82 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
83 | },
84 | "ee-first": {
85 | "version": "1.1.1",
86 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
87 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
88 | },
89 | "encodeurl": {
90 | "version": "1.0.2",
91 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
92 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
93 | },
94 | "escape-html": {
95 | "version": "1.0.3",
96 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
97 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
98 | },
99 | "etag": {
100 | "version": "1.8.1",
101 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
102 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
103 | },
104 | "express": {
105 | "version": "4.17.1",
106 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
107 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
108 | "requires": {
109 | "accepts": "~1.3.7",
110 | "array-flatten": "1.1.1",
111 | "body-parser": "1.19.0",
112 | "content-disposition": "0.5.3",
113 | "content-type": "~1.0.4",
114 | "cookie": "0.4.0",
115 | "cookie-signature": "1.0.6",
116 | "debug": "2.6.9",
117 | "depd": "~1.1.2",
118 | "encodeurl": "~1.0.2",
119 | "escape-html": "~1.0.3",
120 | "etag": "~1.8.1",
121 | "finalhandler": "~1.1.2",
122 | "fresh": "0.5.2",
123 | "merge-descriptors": "1.0.1",
124 | "methods": "~1.1.2",
125 | "on-finished": "~2.3.0",
126 | "parseurl": "~1.3.3",
127 | "path-to-regexp": "0.1.7",
128 | "proxy-addr": "~2.0.5",
129 | "qs": "6.7.0",
130 | "range-parser": "~1.2.1",
131 | "safe-buffer": "5.1.2",
132 | "send": "0.17.1",
133 | "serve-static": "1.14.1",
134 | "setprototypeof": "1.1.1",
135 | "statuses": "~1.5.0",
136 | "type-is": "~1.6.18",
137 | "utils-merge": "1.0.1",
138 | "vary": "~1.1.2"
139 | }
140 | },
141 | "finalhandler": {
142 | "version": "1.1.2",
143 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
144 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
145 | "requires": {
146 | "debug": "2.6.9",
147 | "encodeurl": "~1.0.2",
148 | "escape-html": "~1.0.3",
149 | "on-finished": "~2.3.0",
150 | "parseurl": "~1.3.3",
151 | "statuses": "~1.5.0",
152 | "unpipe": "~1.0.0"
153 | }
154 | },
155 | "forwarded": {
156 | "version": "0.1.2",
157 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
158 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
159 | },
160 | "fresh": {
161 | "version": "0.5.2",
162 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
163 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
164 | },
165 | "http-errors": {
166 | "version": "1.7.2",
167 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
168 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
169 | "requires": {
170 | "depd": "~1.1.2",
171 | "inherits": "2.0.3",
172 | "setprototypeof": "1.1.1",
173 | "statuses": ">= 1.5.0 < 2",
174 | "toidentifier": "1.0.0"
175 | }
176 | },
177 | "iconv-lite": {
178 | "version": "0.4.24",
179 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
180 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
181 | "requires": {
182 | "safer-buffer": ">= 2.1.2 < 3"
183 | }
184 | },
185 | "inherits": {
186 | "version": "2.0.3",
187 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
188 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
189 | },
190 | "ipaddr.js": {
191 | "version": "1.9.0",
192 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
193 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
194 | },
195 | "media-typer": {
196 | "version": "0.3.0",
197 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
198 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
199 | },
200 | "merge-descriptors": {
201 | "version": "1.0.1",
202 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
203 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
204 | },
205 | "methods": {
206 | "version": "1.1.2",
207 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
208 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
209 | },
210 | "mime": {
211 | "version": "1.6.0",
212 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
213 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
214 | },
215 | "mime-db": {
216 | "version": "1.43.0",
217 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
218 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
219 | },
220 | "mime-types": {
221 | "version": "2.1.26",
222 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
223 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
224 | "requires": {
225 | "mime-db": "1.43.0"
226 | }
227 | },
228 | "ms": {
229 | "version": "2.0.0",
230 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
231 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
232 | },
233 | "negotiator": {
234 | "version": "0.6.2",
235 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
236 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
237 | },
238 | "on-finished": {
239 | "version": "2.3.0",
240 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
241 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
242 | "requires": {
243 | "ee-first": "1.1.1"
244 | }
245 | },
246 | "parseurl": {
247 | "version": "1.3.3",
248 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
249 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
250 | },
251 | "path-to-regexp": {
252 | "version": "0.1.7",
253 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
254 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
255 | },
256 | "proxy-addr": {
257 | "version": "2.0.5",
258 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
259 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
260 | "requires": {
261 | "forwarded": "~0.1.2",
262 | "ipaddr.js": "1.9.0"
263 | }
264 | },
265 | "qs": {
266 | "version": "6.7.0",
267 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
268 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
269 | },
270 | "range-parser": {
271 | "version": "1.2.1",
272 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
273 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
274 | },
275 | "raw-body": {
276 | "version": "2.4.0",
277 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
278 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
279 | "requires": {
280 | "bytes": "3.1.0",
281 | "http-errors": "1.7.2",
282 | "iconv-lite": "0.4.24",
283 | "unpipe": "1.0.0"
284 | }
285 | },
286 | "safe-buffer": {
287 | "version": "5.1.2",
288 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
289 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
290 | },
291 | "safer-buffer": {
292 | "version": "2.1.2",
293 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
294 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
295 | },
296 | "send": {
297 | "version": "0.17.1",
298 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
299 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
300 | "requires": {
301 | "debug": "2.6.9",
302 | "depd": "~1.1.2",
303 | "destroy": "~1.0.4",
304 | "encodeurl": "~1.0.2",
305 | "escape-html": "~1.0.3",
306 | "etag": "~1.8.1",
307 | "fresh": "0.5.2",
308 | "http-errors": "~1.7.2",
309 | "mime": "1.6.0",
310 | "ms": "2.1.1",
311 | "on-finished": "~2.3.0",
312 | "range-parser": "~1.2.1",
313 | "statuses": "~1.5.0"
314 | },
315 | "dependencies": {
316 | "ms": {
317 | "version": "2.1.1",
318 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
319 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
320 | }
321 | }
322 | },
323 | "serve-static": {
324 | "version": "1.14.1",
325 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
326 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
327 | "requires": {
328 | "encodeurl": "~1.0.2",
329 | "escape-html": "~1.0.3",
330 | "parseurl": "~1.3.3",
331 | "send": "0.17.1"
332 | }
333 | },
334 | "setprototypeof": {
335 | "version": "1.1.1",
336 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
337 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
338 | },
339 | "statuses": {
340 | "version": "1.5.0",
341 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
342 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
343 | },
344 | "toidentifier": {
345 | "version": "1.0.0",
346 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
347 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
348 | },
349 | "type-is": {
350 | "version": "1.6.18",
351 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
352 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
353 | "requires": {
354 | "media-typer": "0.3.0",
355 | "mime-types": "~2.1.24"
356 | }
357 | },
358 | "unpipe": {
359 | "version": "1.0.0",
360 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
361 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
362 | },
363 | "utils-merge": {
364 | "version": "1.0.1",
365 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
366 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
367 | },
368 | "vary": {
369 | "version": "1.1.2",
370 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
371 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
372 | }
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/section-4/video-4.3/hello-4-3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index.js",
8 | "test": "exit 0"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "express": "^4.17.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/section-4/video-4.4/README.md:
--------------------------------------------------------------------------------
1 | # Video 4.4
2 |
3 | This video demonstrates editing an application in a DevPod using the editor
4 | built into the DevPod.
5 |
6 | ## Prerequisites
7 |
8 | First install your cluster per the instruction in section 1.
9 |
10 | ## DevPod
11 |
12 | Jenkins X can provide an editor running within the DevPod; by default this is
13 | Visual Studio Code. We can use this to edit our application source code from
14 | a web browser to rapidly see changes.
15 |
16 | Start by creating a DevPod:
17 |
18 | ```
19 | jx create devpod
20 | ```
21 |
22 | From the DevPod shell, note the URL for the IDE. Also start the application.
23 |
24 | At this point you can visit the IDE in the browser to edit your code.
25 |
--------------------------------------------------------------------------------
/section-4/video-4.4/hello-4-4/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/section-4/video-4.4/hello-4-4/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const app = express()
3 | const port = 8080
4 |
5 | app.get('/', (req, res) => res.send('Hello World!\n'))
6 |
7 | app.listen(port, () => console.log(`Example app listening on port ${port}!`))
8 |
--------------------------------------------------------------------------------
/section-4/video-4.4/hello-4-4/jenkins-x.yml:
--------------------------------------------------------------------------------
1 | buildPack: javascript
2 |
--------------------------------------------------------------------------------
/section-4/video-4.4/hello-4-4/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "express-hello",
3 | "version": "1.0.0",
4 | "description": "Express Hello World",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon index.js",
8 | "start": "node index.js",
9 | "test": "exit 0"
10 | },
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "express": "^4.17.1"
15 | },
16 | "devDependencies": {
17 | "nodemon": "^2.0.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/section-4/video-4.5/README.md:
--------------------------------------------------------------------------------
1 | # Video 4.5
2 |
3 | This video shows how Jenkins X uses Skaffold to build the Docker images used
4 | to run applications.
5 |
6 | ## Prerequisites
7 |
8 | None
9 |
10 | ## Skaffold
11 |
12 | Skaffold is a tool to help with the building of Docker images. It allows us
13 | to configure the Docker build using a YAML file rather than passing all of
14 | the parameters on the command line to `docker build`. It also supports
15 | incremental re-build, so it can be used for rapid development.
16 |
17 | When we import a project, Jenkins X creates a `Dockerfile` and `skaffold.yaml`
18 | file if they don't already exist. The `Dockerfile` consists of instructions to
19 | Docker as to how to build the image. The `skaffold.yaml` configures the name of
20 | the image, what registry to push to after completion, and other parameters.
21 |
22 | The `Dockerfile` and `skaffold.yaml` come from the build pack so they can be
23 | specific to the language and runtime we're using (e.g. `javascript` with Node).
24 | The build pack also contains the command to run `skaffold` to build and push
25 | the image.
26 |
--------------------------------------------------------------------------------
/section-5/video-5.1/README.md:
--------------------------------------------------------------------------------
1 | # Video 5.1
2 |
3 | This video demonstrates an application deployed to Kubernetes.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | Second, you need to know the domain name that your cluster is using for
10 | ingress. Because of the way we create the cluster using Google Kubernetes
11 | Engine in section 1, it gets a single IP address. We can use `nip.io` to
12 | treat that IP address as a domain, but first we need to know what it is.
13 |
14 | To find out, run:
15 |
16 | ```
17 | kubectl get ingress
18 | ```
19 |
20 | You will see a list of Kubernetes Ingress resources (more on those later)
21 | that all share the same IP address. Copy that IP address to the clipboard and
22 | paste it into the `plone.yaml` file where it says `REPLACE_ME_INGRESS_IP`.
23 |
24 | When finished, you should have a line in your `plone.yaml` that looks like
25 | this (but with a different IP address; don't use this one!):
26 |
27 | ```
28 | - host: plone.10.11.12.13.nip.io
29 | ```
30 |
31 | ## Kubernetes
32 |
33 | Jenkins X uses Kubernetes as the platform on which it runs its own components,
34 | runs builds, and deploys applications. Kubernetes is a "container orchestration"
35 | platform. This means that it runs containerized applications (such as Docker
36 | images), providing them with configuration, storage, networking, and fault
37 | tolerance (including health checks, load balancing, and failover).
38 |
39 | When we deployed our cluster in Section 1, before we could run `jx boot`, we
40 | first had to create a Kubernetes cluster on which to deploy Jenkins X. In
41 | addition to using this cluster with Jenkins X, we can also configure it directly
42 | using the `kubectl` command (which we saw in Section 2).
43 |
44 | ## Deploying to Kubernetes
45 |
46 | To deploy an application to Kubernetes, we create "resources" in the cluster.
47 | The Kubernetes control plane (the set of services that manage the cluster)
48 | does the necessary work to start containers, configure networking, etc.
49 |
50 | We specify the necessary resources using YAML configuration files. We can
51 | then apply these resources to the cluster (create or update, as needed)
52 | using the `kubectl apply` command. For example:
53 |
54 | ```
55 | kubectl apply -f plone.yaml
56 | ```
57 |
58 | You can now visit your Plone instance in a browser using the host name you
59 | configured in the ingress above.
60 |
61 | ## Cleaning Up
62 |
63 | To clean up the resources in a file, we can just run `kubectl delete`:
64 |
65 | ```
66 | kubectl delete -f plone.yaml
67 | ```
68 |
--------------------------------------------------------------------------------
/section-5/video-5.1/plone.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: Deployment
3 | apiVersion: apps/v1
4 | metadata:
5 | name: plone
6 | labels:
7 | app: plone
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: plone
13 | template:
14 | metadata:
15 | labels:
16 | app: plone
17 | spec:
18 | containers:
19 | - name: plone
20 | image: plone:5.2.1-alpine
21 | ports:
22 | - containerPort: 8080
23 | ---
24 | kind: Service
25 | apiVersion: v1
26 | metadata:
27 | name: plone
28 | spec:
29 | selector:
30 | app: plone
31 | type: ClusterIP
32 | ports:
33 | - protocol: TCP
34 | port: 8080
35 | targetPort: 8080
36 | ---
37 | kind: Ingress
38 | apiVersion: extensions/v1beta1
39 | metadata:
40 | name: plone
41 | spec:
42 | rules:
43 | - host: plone.REPLACE_ME_INGRESS_IP.nip.io
44 | http:
45 | paths:
46 | - backend:
47 | serviceName: plone
48 | servicePort: 8080
49 |
--------------------------------------------------------------------------------
/section-5/video-5.2/README.md:
--------------------------------------------------------------------------------
1 | # Video 5.2
2 |
3 | This video shows Kubernetes deployments and pods.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | ## Deployments and Pods
10 |
11 | A pod is a logical group of containers that all run on the same Kubernetes node
12 | and share a Pod IP address. Kubernetes uses deployments to manage pods,
13 | including creating pods, creating multiple replicas of pods, performing a
14 | rolling update to allow for upgrading an application with zero downtime, and
15 | replacing pods when there is a failure in a container or in a Kubernetes node.
16 |
17 | When we create a deployment, we give it a template for the pods it creates.
18 | This includes information on what containers to create. It also includes a
19 | set of labels that are used by the deployment to find and manage its pods.
20 | This means we have to configure a "selector" in the deployment that matches
21 | the "labels" that we give in the pod template.
22 |
23 | ## Creating a Deployment
24 |
25 | As before, we use `kubectl apply`:
26 |
27 | ```
28 | kubectl apply -f deployment.yaml
29 | ```
30 |
31 | We can verify that the deployment exists and that the matching pods were
32 | created:
33 |
34 | ```
35 | kubectl get deployment plone
36 | kubectl get pods -l app=plone
37 | ```
38 |
39 | ## Cleaning Up
40 |
41 | To clean up the resources in a file, we can just run `kubectl delete`:
42 |
43 | ```
44 | kubectl delete -f deployment.yaml
45 | ```
46 |
47 | We can also delete individual resources directly:
48 |
49 | ```
50 | kubectl delete deployment plone
51 | ```
52 |
53 | However, note that if you only delete a pod, the deployment will automatically
54 | create a replacement.
55 |
--------------------------------------------------------------------------------
/section-5/video-5.2/deployment.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: Deployment
3 | apiVersion: apps/v1
4 | metadata:
5 | name: plone
6 | labels:
7 | app: plone
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: plone
13 | template:
14 | metadata:
15 | labels:
16 | app: plone
17 | spec:
18 | containers:
19 | - name: plone
20 | image: plone:5.2.1-alpine
21 | ports:
22 | - containerPort: 8080
23 |
--------------------------------------------------------------------------------
/section-5/video-5.3/README.md:
--------------------------------------------------------------------------------
1 | # Video 5.3
2 |
3 | This video shows Kubernetes services.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | ## Services
10 |
11 | Pods may come and go in a cluster, either because of failure or because we
12 | are upgrading our application. In addition, we may have multiple pod replicas
13 | to providing horizontal scaling. Therefore, while each pod has its own IP
14 | address, we can't use the pod IP address to reliably communicate with our
15 | application.
16 |
17 | A Kubernetes service provides a well-known name and a long-lasting IP address
18 | for our application. The service receives a cluster IP address, and any traffic
19 | to the cluster IP address is automatically load balanced across all pods that
20 | match the service's selector. Even as pods come and go, clients can still use
21 | the service and will be routed to a healthy pod.
22 |
23 | ## Creating a Service
24 |
25 | As before, we use `kubectl apply`:
26 |
27 | ```
28 | kubectl apply -f service.yaml
29 | ```
30 |
31 | We can verify that the service exists and matches the pods in the deployment:
32 |
33 | ```
34 | kubectl get service plone
35 | kubectl describe service plone
36 | ```
37 |
38 | ## Cleaning Up
39 |
40 | To clean up the resources in a file, we can just run `kubectl delete`:
41 |
42 | ```
43 | kubectl delete -f service.yaml
44 | ```
45 |
46 | We can also delete individual resources directly:
47 |
48 | ```
49 | kubectl delete service plone
50 | kubectl delete deployment plone
51 | ```
52 |
--------------------------------------------------------------------------------
/section-5/video-5.3/service.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: Service
3 | apiVersion: v1
4 | metadata:
5 | name: plone
6 | spec:
7 | selector:
8 | app: plone
9 | type: ClusterIP
10 | ports:
11 | - protocol: TCP
12 | port: 8080
13 | targetPort: 8080
14 | ---
15 | kind: Deployment
16 | apiVersion: apps/v1
17 | metadata:
18 | name: plone
19 | labels:
20 | app: plone
21 | spec:
22 | replicas: 3
23 | selector:
24 | matchLabels:
25 | app: plone
26 | template:
27 | metadata:
28 | labels:
29 | app: plone
30 | spec:
31 | containers:
32 | - name: plone
33 | image: plone:5.2.1-alpine
34 | ports:
35 | - containerPort: 8080
36 |
--------------------------------------------------------------------------------
/section-5/video-5.4/README.md:
--------------------------------------------------------------------------------
1 | # Video 5.4
2 |
3 | This video shows Kubernetes ingress resources.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | Second, you need to know the domain name that your cluster is using for
10 | ingress. Because of the way we create the cluster using Google Kubernetes
11 | Engine in section 1, it gets a single IP address. We can use `nip.io` to
12 | treat that IP address as a domain, but first we need to know what it is.
13 |
14 | To find out, run:
15 |
16 | ```
17 | kubectl get ingress
18 | ```
19 |
20 | You will see a list of Kubernetes Ingress resources (as described in this video)
21 | that all share the same IP address. Copy that IP address to the clipboard and
22 | paste it into the `plone.yaml` file where it says `REPLACE_ME_INGRESS_IP`.
23 |
24 | When finished, you should have a line in your `plone.yaml` that looks like
25 | this (but with a different IP address; don't use this one!):
26 |
27 | ```
28 | - host: plone.10.11.12.13.nip.io
29 | ```
30 |
31 | ## Ingress
32 |
33 | The cluster IP we created for our service is only accessible from inside the
34 | cluster. While there are other types of services that we can use to get
35 | external IP addresses (IP addresses that we can access from outside the cluster)
36 | it is usually easier and more efficient to just use an ingress.
37 |
38 | An ingress is a special kind of Kubernetes service that has an external IP
39 | address and routes traffic to services. The ingress has an ingress controller
40 | that is configured with rules telling it how to route traffic. This typically
41 | means HTTP traffic, and the rules are based on the `Host` header in the request
42 | or matching the path of the URL.
43 |
44 | The ingress uses these rules to route traffic to a service; the service then
45 | routes traffic to a specific pod instance.
46 |
47 | ## Creating an Ingress
48 |
49 | As before, we use `kubectl apply`:
50 |
51 | ```
52 | kubectl apply -f plone.yaml
53 | ```
54 |
55 | We can verify that the ingress exists and has the right routing rules:
56 |
57 | ```
58 | kubectl get ingress plone
59 | kubectl describe ingress plone
60 | ```
61 |
62 | ## Cleaning Up
63 |
64 | To clean up the resources in a file, we can just run `kubectl delete`:
65 |
66 | ```
67 | kubectl delete -f plone.yaml
68 | ```
69 |
70 | We can also delete individual resources directly:
71 |
72 | ```
73 | kubectl delete ingress plone
74 | kubectl delete service plone
75 | kubectl delete deployment plone
76 | ```
77 |
--------------------------------------------------------------------------------
/section-5/video-5.4/plone.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: Ingress
3 | apiVersion: extensions/v1beta1
4 | metadata:
5 | name: plone
6 | spec:
7 | rules:
8 | - host: plone.REPLACE_ME_INGRESS_IP.nip.io
9 | http:
10 | paths:
11 | - backend:
12 | serviceName: plone
13 | servicePort: 8080
14 | ---
15 | kind: Service
16 | apiVersion: v1
17 | metadata:
18 | name: plone
19 | spec:
20 | selector:
21 | app: plone
22 | type: ClusterIP
23 | ports:
24 | - protocol: TCP
25 | port: 8080
26 | targetPort: 8080
27 | ---
28 | kind: Deployment
29 | apiVersion: apps/v1
30 | metadata:
31 | name: plone
32 | labels:
33 | app: plone
34 | spec:
35 | replicas: 1
36 | selector:
37 | matchLabels:
38 | app: plone
39 | template:
40 | metadata:
41 | labels:
42 | app: plone
43 | spec:
44 | containers:
45 | - name: plone
46 | image: plone:5.2.1-alpine
47 | ports:
48 | - containerPort: 8080
49 |
--------------------------------------------------------------------------------
/section-5/video-5.5/README.md:
--------------------------------------------------------------------------------
1 | # Video 5.5
2 |
3 | This video demonstrates Helm, the Kubernetes package manager.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | Second, you need to know the domain name that your cluster is using for
10 | ingress. Because of the way we create the cluster using Google Kubernetes
11 | Engine in section 1, it gets a single IP address. We can use `nip.io` to
12 | treat that IP address as a domain, but first we need to know what it is.
13 |
14 | To find out, run:
15 |
16 | ```
17 | kubectl get ingress
18 | ```
19 |
20 | You will see a list of Kubernetes Ingress resources (as described previously)
21 | that all share the same IP address. Copy that IP address to the clipboard and
22 | paste it into the `values.yaml` file where it says `REPLACE_ME_INGRESS_IP`.
23 |
24 | When finished, you should have a section in your `values.yaml` that looks like
25 | this (but with a different IP address; don't use this one!):
26 |
27 | ```
28 | hosts:
29 | - bookstack.10.11.12.13.nip.io
30 | ```
31 |
32 | Finally, you need to install the Helm client and add the stable repo as
33 | described [in the documentation][helm].
34 |
35 | [helm]:https://helm.sh/docs/intro/quickstart/
36 |
37 | ## Helm
38 |
39 | To deploy an application to Kubernetes, we need to know not just about
40 | Kubernetes but also about how to configure the application we're deploying.
41 | Additionally, Kubernetes YAML files quickly get long and hard to maintain.
42 |
43 | Helm is designed to address this by offering "charts", which are collections
44 | of Kubernetes resources designed to make it easy to deploy an application.
45 | Helm supports downloading and installing charts from repositories, overriding
46 | configuration for a chart, upgrading a chart to a new version, and deleting
47 | a chart.
48 |
49 | Once Helm is configured, you can install an application from a chart using:
50 |
51 | ```
52 | helm install bookstack stable/bookstack -f values.yaml
53 | ```
54 |
55 | The application will take a few minutes to install and be available. You can
56 | verify it by visiting the URL in the browser.
57 |
58 | ## Cleaning Up
59 |
60 | To delete the application:
61 |
62 | ```
63 | helm delete bookstack
64 | ```
65 |
--------------------------------------------------------------------------------
/section-5/video-5.5/values.yaml:
--------------------------------------------------------------------------------
1 | ingress:
2 | enabled: true
3 | hosts:
4 | - bookstack.REPLACE_ME_INGRESS_IP.nip.io
5 |
--------------------------------------------------------------------------------
/section-5/video-5.6/README.md:
--------------------------------------------------------------------------------
1 | # Video 5.6
2 |
3 | This video demonstrates debugging applications within Kubernetes.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | ## Debugging Kubernetes
10 |
11 | Once an application is up and running, Kubernetes will do its best to keep
12 | it running with the number of specified replicas, and will route traffic
13 | to it. However, sometimes it can be challenging to get an application up
14 | as it can be challenging to figure out what is going wrong.
15 |
16 | There are a few key commands for debugging an application in Kubernetes:
17 |
18 | * `kubectl get []`: List all resources of `type`, or just the
19 | resource with the provided `name`. Use an output format such as `-o wide`
20 | to get more information, or `-o yaml` to see the complete configuration.
21 | * `kubectl describe `: Show the current status of the resource,
22 | together with recent events.
23 | * `kubectl logs `: See the logs for an individual pod.
24 | * `kubectl exec -ti [-c ] `: Run a command
25 | inside a pod. If there are multiple containers in the pod you must provide
26 | a container name.
27 |
28 | Generally, the first two commands are used prior to getting the pod to the
29 | `Running` state, and the last two commands are used after the pod runs the
30 | first time.
31 |
32 | There are multiple different error states for a pod, but two are the most
33 | commonly seen:
34 |
35 | * `ImagePullBackOff`: This means that Kubernetes has tried multiple times to
36 | pull the Docker image and has been unsuccessful. This may indicate that the
37 | image name is incorrect, that the registry is down, or that there is an
38 | issue with authentication or authorization to pull the image.
39 | * `CrashLoopBackOff`: This means that Kubernetes was able to pull the image,
40 | but the command to start the container keeps failing. This may indicate a
41 | bad command, a bad configuration of the pod, or an error in the application
42 | that causes it to exit. If the pod is configured with health checks, it may
43 | also mean that the pod is failing health checks.
44 |
45 | To help illustrate these errors, this folder has three deployments:
46 |
47 | * `bad-image-name`: The name of the Plone image is misspelled to cause an
48 | `ImagePullBackOff`.
49 | * `bad-command`: The command `/bin/false` is specified to cause a container
50 | that will fail repeatedly and cause `CrashLoopBackOff`.
51 | * `good-deployment`: Both of these errors are fixed to allow creation of a
52 | `Running` container to test `log` and `exec`.
53 |
--------------------------------------------------------------------------------
/section-5/video-5.6/bad-command/deployment.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: Deployment
3 | apiVersion: apps/v1
4 | metadata:
5 | name: plone
6 | labels:
7 | app: plone
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: plone
13 | template:
14 | metadata:
15 | labels:
16 | app: plone
17 | spec:
18 | containers:
19 | - name: plone
20 | image: plone:5.2.1-alpine
21 | command: ["/bin/false"] # Causes the container to fail on startup
22 | ports:
23 | - containerPort: 8080
24 |
--------------------------------------------------------------------------------
/section-5/video-5.6/bad-image-name/deployment.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: Deployment
3 | apiVersion: apps/v1
4 | metadata:
5 | name: plone
6 | labels:
7 | app: plone
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: plone
13 | template:
14 | metadata:
15 | labels:
16 | app: plone
17 | spec:
18 | containers:
19 | - name: plone
20 | image: plone:5.2.1-alpne # Should be 5.2.1-alpine
21 | ports:
22 | - containerPort: 8080
23 |
--------------------------------------------------------------------------------
/section-5/video-5.6/good-deployment/deployment.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | kind: Deployment
3 | apiVersion: apps/v1
4 | metadata:
5 | name: plone
6 | labels:
7 | app: plone
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: plone
13 | template:
14 | metadata:
15 | labels:
16 | app: plone
17 | spec:
18 | containers:
19 | - name: plone
20 | image: plone:5.2.1-alpine
21 | ports:
22 | - containerPort: 8080
23 |
--------------------------------------------------------------------------------
/section-6/video-6.1/README.md:
--------------------------------------------------------------------------------
1 | # Video 6.1
2 |
3 | This video demonstrates adding "apps" to Jenkins X.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | Second, if you installed Helm 3 in your PATH as part of Video 5.5, you may
10 | need to make sure it is no longer in your PATH, as of this writing (March 2020)
11 | Jenkins X does not yet support Helm 3.
12 |
13 | ## Jenkins X Apps
14 |
15 | Jenkins X has the concept of an "app" that we can add to the cluster. This is
16 | different from an application that Jenkins X builds and deploys; Jenkins X
17 | only manages deployement for an app.
18 |
19 | We can deploy an app using a Helm chart; the only difference with using Helm
20 | directly is that Jenkins X will manage the deployment for us using GitOps
21 | so we can more easily rebuild the cluster if needed.
22 |
23 | ## Adding an App to Jenkins X
24 |
25 | We can add an app to Jenkins X by referencing the name and repository for the
26 | Helm chart. For example:
27 |
28 | ```
29 | jx add app mongodb --repository https://charts.bitnami.com/bitnami
30 | ```
31 |
32 | This will create a pull request that will eventually end up adding MongoDB
33 | to our Kubernetes cluster.
34 |
35 | ## Cleaning Up
36 |
37 | To delete the MongoDB Jenkins X app, run:
38 |
39 | ```
40 | jx delete app mongodb
41 | ```
42 |
--------------------------------------------------------------------------------
/section-6/video-6.2/README.md:
--------------------------------------------------------------------------------
1 | # Video 6.2
2 |
3 | This video demonstrates Jenkins X addons.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | ## Jenkins X Addons
10 |
11 | Jenkins X Addons are, confusingly, different from Jenkins X Apps. There is a
12 | proposal to merge the two concepts but for now they are separate.
13 |
14 | A Jenkins X Addon allows us to add optional core functionality to Jenkins X.
15 | There are a number of addons; you can run `jx create addon --help` to see a
16 | list.
17 |
18 | Unlike apps, addons are not tracked using GitOps.
19 |
20 | ## Installing an Addon
21 |
22 | Run the `jx create addon` command. For example:
23 |
24 | ```
25 | jx create addon anchore
26 | ```
27 |
28 | ## Cleaning Up
29 |
30 | To delete the addon, run:
31 |
32 | ```
33 | jx delete addon anchore
34 | ```
35 |
--------------------------------------------------------------------------------
/section-6/video-6.3/README.md:
--------------------------------------------------------------------------------
1 | # Video 6.3
2 |
3 | This video demonstrates installing Prometheus as a Jenkins X addon.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | ## Prometheus
10 |
11 | Prometheus is a monitoring service. It is configured with a list of endpoints
12 | that it "scrapes" periodically to collect data. This data can include health
13 | information or metrics such as number of requests. Prometheus provides a
14 | database of all of the data it scrapes for use in visualizations.
15 |
16 | Many of the Kubernetes and Jenkins X services are already configured with
17 | endpoints to provide data to Prometheus, and when we install Prometheus in
18 | Kubernetes, it can automatically detect where to scrape metrics data. This
19 | makes it very easy to add monitoring for Kubernetes components and our own
20 | applications.
21 |
22 | ## Installing Prometheus
23 |
24 | Install Prometheus as a Jenkins X addon:
25 |
26 | ```
27 | jx create addon prometheus
28 | ```
29 |
30 | Then visit the Prometheus server in the browser. You can get the URL by
31 | running `kubectl get ingress`. Use `admin` as the username and password.
32 |
33 | ## Cleaning Up
34 |
35 | To delete the addon, run:
36 |
37 | ```
38 | jx delete addon prometheus
39 | ```
40 |
--------------------------------------------------------------------------------
/section-6/video-6.4/README.md:
--------------------------------------------------------------------------------
1 | # Video 6.4
2 |
3 | This video demonstrates installing Grafana as a Jenkins X addon.
4 |
5 | ## Prerequisites
6 |
7 | First install your cluster per the instruction in section 1.
8 |
9 | ## Grafana
10 |
11 | Grafana is a visualization tool. It can pull data from sources such as
12 | Prometheus and present them in a variety of ways.
13 |
14 | ## Installing Grafana
15 |
16 | Install Grafana as a Jenkins X addon:
17 |
18 | ```
19 | jx create addon grafana
20 | ```
21 |
22 | Next, we need to retrieve the password. First get the name of the running
23 | pod:
24 |
25 | ```
26 | kubectl get pods -l app=grafana
27 | ```
28 |
29 | Now use that pod name to get the password:
30 |
31 | ```
32 | kubectl exec -ti env | grep PASS
33 | ```
34 |
35 | ## Cleaning Up
36 |
37 | To delete the addon, run:
38 |
39 | ```
40 | jx delete addon grafana
41 | ```
42 |
--------------------------------------------------------------------------------