everything as a code
TRANSCRIPT
![Page 1: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/1.jpg)
Everything as a CodeНепривычно о привычном
![Page 2: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/2.jpg)
@aatarasoff
@aatarasoff
@aatarasoff
![Page 3: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/3.jpg)
No warranty guarantee
![Page 4: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/4.jpg)
Matrix has you
4
![Page 5: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/5.jpg)
5
![Page 6: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/6.jpg)
6
![Page 7: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/7.jpg)
Выйти за пределы...
7
![Page 8: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/8.jpg)
...поняв, что всё есть код
8
![Page 9: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/9.jpg)
Как вы представляете себе код?
9
![Page 10: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/10.jpg)
@Configuration@EnableConfigurationProperties(OneServerProperties.class)public class OneServerConfiguration implements ApplicationContextAware { ApplicationContext applicationContext;
@Autowired OneServerProperties properties;
@Bean public HttpServer httpServer() throws IOException { HttpServer httpServer = new RelativePathHttpServer();
for (String beanName : context.getBeans(HttpController.class)) { httpServer.addRequestHandlers(context.getBean(beanName)); }
return httpServer; }}
10
Наверное как-то так
![Page 11: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/11.jpg)
Что такое код?
● Коллекция инструкций
● Человекочитаемый формат
○ plain text
● Может быть понят и “проигран”
○ после компиляции
○ интерпретатором
11
![Page 12: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/12.jpg)
Да я тоже пишу код!
12
![Page 13: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/13.jpg)
Вооружи себя
13
![Page 14: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/14.jpg)
Настройка рабочего окружения
14
![Page 15: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/15.jpg)
Install apps Code Checkout Configure workspace First Blood
15
![Page 16: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/16.jpg)
Install apps Code Checkout Configure workspace First Blood
brew install
16
![Page 17: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/17.jpg)
Install apps Code Checkout Configure workspace First Blood
brew installpip install
17
![Page 18: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/18.jpg)
Install apps Code Checkout Configure workspace First Blood
git
18
![Page 19: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/19.jpg)
Install apps Code Checkout Configure workspace First Blood
customize*.properties
19
![Page 20: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/20.jpg)
Install apps Code Checkout Configure workspace First Blood
customize*.propertiestemplate
.gradle
20
![Page 21: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/21.jpg)
Install apps Code Checkout Configure workspace First Blood
customize*.propertiesinstall
certificates
21
![Page 22: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/22.jpg)
Install apps Code Checkout Configure workspace First Blood
first build
22
![Page 23: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/23.jpg)
Install apps Code Checkout Configure workspace First Blood
mass buildfirst deploy
23
![Page 24: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/24.jpg)
ansible-playbook -i local-inv setup.yml --tags configure
24
Интерпретатор
![Page 25: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/25.jpg)
ansible-playbook -i local-inv setup.yml --tags configure
25
Конфигурация
![Page 26: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/26.jpg)
ansible-playbook -i local-inv setup.yml --tags configure
26
Алгоритм
![Page 27: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/27.jpg)
#checkout repositories from git- include: checkout.yml
#configure your local environment- include: configure.yml
#add useful mappings to your hosts file- include: hosts.yml
#add gradle support- include: gradle.yml
#clean and build all projects- include: build.yml
#delpoy all services to dev- include: build.yml
27
Алгоритм
![Page 28: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/28.jpg)
ansible-playbook -i local-inv setup.yml --tags configure
28
Входные параметры
![Page 29: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/29.jpg)
- name: checkout services git: repo: "{{ git.root }}/{{ item.name }}.git" dest: "{{ work_dir }}/{{ item.name }}" update: yes with_items: - "{{ services }}" tags: - services
29
Массовый checkout/pull
![Page 30: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/30.jpg)
- name: checkout services git: repo: "{{ git.root }}/{{ item.name }}.git" dest: "{{ work_dir }}/{{ item.name }}" update: yes with_items: - "{{ services }}" tags: - services
Переменные
30
![Page 31: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/31.jpg)
- name: checkout services git: // with_items: - "{{ services }}"
services: - { name: one-instant-messenger , sourceDir: src } - { name: one-discussions, sourceDir: src } - { name: one-attachment, sourceDir: src, testDir: test, local: true }
Циклы
31
![Page 32: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/32.jpg)
services: - { name: one-instant-messenger, sourceDir: src } - { name: one-discussions, sourceDir: src } - { name: one-attachment, sourceDir: src, testDir: test }
Коллекции и структуры данных
32
![Page 33: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/33.jpg)
- name: create gradle build file template: src: build.gradle.j2 dest: "{{ work_dir }}/build.gradle" mode: 0644
- name: create gradle settings file template: src: settings.gradle.j2 dest: "{{ work_dir }}/settings.gradle" mode: 0644
Шаблоны
33
![Page 34: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/34.jpg)
{% if services is not none %}{% for service in services %} if (project.name == '{{ service.name }}') {{% if 'sourceDir' in service %} main.java.srcDir '{{ service.sourceDir }}'{% endif %}{% if 'testDir' in service %} test.java.srcDir '{{ service.testDir }}'{% endif %} }
Условные операторы
34
![Page 35: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/35.jpg)
{% if services is not none %}{% for service in services %} if (project.name == '{{ service.name }}') {{% if 'sourceDir' in service %} main.java.srcDir '{{ service.sourceDir }}'{% endif %}{% if 'testDir' in service %} test.java.srcDir '{{ service.testDir }}'{% endif %} }
Опять циклы
35
![Page 36: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/36.jpg)
- stat: path={{ username }}.key register: certkey
- name: generate private key shell: openssl genrsa -out {{ username }}.key -aes256 4096 when: not certkey.stat.exists
Идемпотентность
36
![Page 37: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/37.jpg)
Install apps Code Checkout Configure workspace Multiplie Use
37
Петля обратной связи
git
![Page 38: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/38.jpg)
Что получили
● Автоконфигурация рабочего
пространства
○ повторяемая
○ немутабельная
● Можно дать скрипт новичку
● Можно и нужно пользоваться этим
каждый день
38
![Page 39: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/39.jpg)
Код есть код
39
![Page 40: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/40.jpg)
Искусство сборки
40
![Page 41: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/41.jpg)
Compile code Unit tests Package Publishing
41
![Page 42: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/42.jpg)
Compile code Unit tests Package
compiler
Publishing
42
![Page 43: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/43.jpg)
Compile code Unit tests Package
javacresourceprocessing
Publishing
43
![Page 44: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/44.jpg)
Compile code Unit tests Package
javacresources copyingdependency resolving
Publishing
44
![Page 45: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/45.jpg)
Compile code Unit tests Package
junit
Publishing
45
![Page 46: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/46.jpg)
Compile code Unit tests Package
jar
Publishing
46
![Page 47: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/47.jpg)
Compile code Unit tests Package
jarnpm, deb, ...
Publishing
47
![Page 48: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/48.jpg)
Compile code Unit tests Package
jarnpm, so, ...docker image
Publishing
48
![Page 49: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/49.jpg)
Compile code Unit tests Package
ivy
Publishing
49
![Page 50: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/50.jpg)
Compile code Unit tests Package
maven, ivymaven
Publishing
50
![Page 51: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/51.jpg)
Compile code Unit tests Package Publishing
maven, ivylocal or dev deploydocker registry
51
![Page 52: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/52.jpg)
Системы сборки
● Ant + Ivy
● Maven
● Gradle
● Docker
● npm
● ...
52
![Page 53: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/53.jpg)
FROM golang:1.7-alpineMAINTAINER [email protected]
VOLUME /dataWORKDIR /data
RUN apk update && \ apk upgrade && \ apk add git bash
RUN go get github.com/aatarasoff/apistress && \ go install github.com/aatarasoff/apistress
CMD [ "apistress" ]
Dockerfile. Наследование
53
![Page 54: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/54.jpg)
FROM golang:1.7-alpineMAINTAINER [email protected]
VOLUME /dataWORKDIR /data
RUN apk update && \ apk upgrade && \ apk add git bash
RUN go get github.com/aatarasoff/apistress && \ go install github.com/aatarasoff/apistress
CMD [ "apistress" ]
Dockerfile. Инструкции
54
![Page 55: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/55.jpg)
FROM golang:1.7-alpineMAINTAINER [email protected]
ARG maindir=/data
VOLUME $maindirWORKDIR $maindir
RUN apk update && apk upgrade && apk add git bash
RUN go get github.com/aatarasoff/apistress && \ go install github.com/aatarasoff/apistress
CMD [ "apistress" ]
Dockerfile. Переменные
55
![Page 56: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/56.jpg)
docker build … && docker push …
56
![Page 57: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/57.jpg)
publishing { publications { mavenJava(MavenPublication) { artifactId 'spring-one-nio-autoconfigure'
from components.java
artifact sourceJar { classifier "sources" } } }}
Gradle. DSL
57
![Page 58: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/58.jpg)
compile(ivyDependencies(projectDir, 'runtime'))
def ivyDependencies(ivyPath, conf) { def dep = [] def ivyModule = new XmlParser().parse(file("${ivyPath}/ivy.xml"))
ivyModule.dependencies.dependency.each dep.add([group: (null == it.@org ? 'ru.odnoklassniki' : it.@org), name: it.@name, version: it.@rev, configuration: (it.@conf =~ /->(\w+)/)[0][1]]) }
return dep}
Gradle. Ну просто код
58
![Page 59: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/59.jpg)
<macrodef name="docker-build-image" description="Build docker image"> <attribute name=" buildcommand"
default="build -t @{repo}/@{image}:@{tag} ."/>
<sequential> <exec executable="docker"> <arg line=" @{buildcommand}"/> </exec> </sequential></macrodef>
И даже в Ant-е есть жизнь
59
![Page 60: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/60.jpg)
./gradlew build test ant-docker-build-image publish
60
![Page 61: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/61.jpg)
Фреймворки для автоматизации
● Ant + Ivy
● Maven
● Gradle
● Docker
● npm
● ...
61
![Page 62: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/62.jpg)
Что получили
● Сборка это код
○ XML
○ DSL
○ Groovy
○ etc
● Системы сборки не только для
сборки
62
![Page 63: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/63.jpg)
Ликвидация багов
63
![Page 64: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/64.jpg)
Unit tests API tests Stress tests UI tests
64
![Page 65: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/65.jpg)
Unit tests API tests Stress tests UI tests
TDD
65
![Page 66: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/66.jpg)
Unit tests API tests Stress tests UI tests
BDD Specs
66
![Page 67: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/67.jpg)
def "Return error code 400, if User-ID header is not presented"() { given: def request = post("/rent")
when: def result = this.mvc.perform(request)
then: result.andExpect(status().isBadRequest()) .andDo(document("rent-user-id-is-absent"))}
Дружелюбный BDD
67
![Page 68: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/68.jpg)
def "Return error code 400, if User-ID header is not presented"() { given: def request = post("/rent")
when: def result = this.mvc.perform(request)
then: result.andExpect( status().isBadRequest()) .andDo(document("rent-user-id-is-absent"))}
Простые проверки
68
![Page 69: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/69.jpg)
Unit tests API tests Stress tests UI tests
JMeter, wrk, vegeta
69
![Page 70: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/70.jpg)
Unit tests API tests Stress tests UI tests
JMeterproduction
70
![Page 71: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/71.jpg)
{ "baseUrl": "http://host:9000/rent-service", "tests": [ { "rps": 10, "duration": 5, "target": { "method": "GET", "path": "/rent", "headers": [ ... ] }, "sla": { "latency": 1000, "successRate": 99.999 } }, ... ]}
config.json
71
![Page 72: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/72.jpg)
{ "baseUrl": "http://host:9000/rent-service", "tests": [ { "rps": 10, "duration": 5, "target": { "method": "GET", "path": "/rent", "headers": [ ... ] }, "sla": { "latency": 1000, "successRate": 99.999 } }, ... ]}
config.json
72
![Page 73: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/73.jpg)
{ "baseUrl": "http://host:9000/rent-service", "tests": [ { "rps": 10, "duration": 5, "target": { "method": "GET", "path": "/rent", "headers": [ ... ] }, "sla": { "latency": 1000, "successRate": 99.999 } }, ... ]}
config.json
73
![Page 74: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/74.jpg)
cat config.json | docker run -i apistress -config=stdin
74
Где-то мы такое видели
![Page 75: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/75.jpg)
Requests [total, rate] 50, 10.20Duration [total, attack, wait] 5.022872793s, 4.899943287s, 122.929506msLatencies [mean, 50, 95, 99, max] 143.772484ms, ..., 290.101831msBytes In [total, mean] 4842, 96.84Bytes Out [total, mean] 950, 19.00Success [ratio] 100.00%Status Codes [code:count] 200:50Error Set:
Test#1
75
![Page 76: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/76.jpg)
> cat config.json | docker run -i apistress -config=stdin> echo $?0
76
Код возврата
![Page 77: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/77.jpg)
Requests [total, rate] 200, 10.05Duration [total, attack, wait] 23.04784s, 19.899754743s, 3.148093811sLatencies [mean, 50, 95, 99, max] 3.023677499s, ..., 11.832287083sBytes In [total, mean] 6874, 34.37Bytes Out [total, mean] 1349, 6.75Success [ratio] 35.50%Status Codes [code:count] 0:129 200:71Error Set:Get http://host:9000/rent-service/rent: EOFGet http://host:9000/rent-service/rent: http: server closed idle connection...
Test#2
77
![Page 78: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/78.jpg)
> cat config.json | docker run -i apistress -config=stdin> echo $?1
78
Код возврата
![Page 79: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/79.jpg)
Unit tests API tests Stress tests UI tests
Selenium, Selenide
79
![Page 80: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/80.jpg)
Что получили
● Все тестовые сценарии в коде
● Можно встроить в процесс сборки
или доставки ПО
● Если хотите, то можно
генерировать отчёты для разбора
полётов
80
![Page 81: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/81.jpg)
Кододокументация
81
![Page 82: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/82.jpg)
Analyst, PM Developer Tester Docs
Word, PDF...
82
![Page 83: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/83.jpg)
Analyst, PM Developer Tester Docs
Word, PDF... Code + Tests
83
![Page 84: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/84.jpg)
Analyst, PM Developer Tester Docs
Word, PDF... Code + Tests Test cases
84
![Page 85: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/85.jpg)
Analyst, PM Developer Tester Docs :(
Word, PDF... Code + Tests Test cases
85
![Page 86: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/86.jpg)
Analyst, PM Developer Tester Docs :)
Markdown/Asciidoctor
Docs :)
86
![Page 87: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/87.jpg)
= Hippo Rent ServiceThis is documentation for Open API of our hippo renting service
== Methods
=== Rent
==== Request specification===== Headers//тут опишем http-заголовки===== Example//а здесь будут примеры вызова
==== Response specification===== Response fields//здесь описание полей ответа===== Example//ну и пример того, что вообще ожидать в ответе
Вот такой документ
87
![Page 88: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/88.jpg)
./gradlew ... asciidoc publishDocs
88
Ну, вы поняли да? :)
![Page 89: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/89.jpg)
def "Rent a hippo"() { given: def request = post("/rent").header("User-ID", "aatarasoff")
when: def result = this.mvc.perform(request)
then: result.andExpect(status().isOk()) .andDo(document( "rent-hippo", preprocessResponse(prettyPrint()), requestHeaders( headerWithName("User-ID").description("User unique identifier")), responseFields( fieldWithPath("hippoRemain").description("Hippo remain count"), fieldWithPath("parrot_fee").description("Fee in virtual parrots"), fieldWithPath("ins").description("Insurance number. Yeah, we sell it"), fieldWithPath("hash").description("Blockchain block hash")) ))}
…и снова тесты
89
![Page 90: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/90.jpg)
def "Rent a hippo"() { given: def request = post("/rent").header("User-ID", "aatarasoff")
when: def result = this.mvc.perform(request)
then: result.andExpect(status().isOk()) .andDo(document( "rent-hippo", preprocessResponse(prettyPrint()), requestHeaders( headerWithName("User-ID").description("User unique identifier")), responseFields( fieldWithPath("hippoRemain").description("Hippo remain count"), fieldWithPath("parrot_fee").description("Fee in virtual parrots"), fieldWithPath("ins").description("Insurance number. Yeah, we sell it"), fieldWithPath("hash").description("Blockchain block hash")) ))}
А не документация ли это?
90
![Page 91: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/91.jpg)
document( "rent-hippo", preprocessResponse(prettyPrint()), requestHeaders( headerWithName("User-ID").description("User unique identifier")), responseFields( fieldWithPath("hippoRemain").description("Hippo remain count"), fieldWithPath("parrot_fee").description("Fee in virtual parrots"), fieldWithPath("ins").description("Insurance number. Yeah, we sell it"), fieldWithPath("hash").description("Blockchain block hash")))
Имя сниппета
91
![Page 92: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/92.jpg)
document( "rent-hippo", preprocessResponse(prettyPrint()), requestHeaders( headerWithName("User-ID").description("User unique identifier")), responseFields( fieldWithPath("hippoRemain").description("Hippo remain count"), fieldWithPath("parrot_fee").description("Fee in virtual parrots"), fieldWithPath("ins").description("Insurance number. Yeah, we sell it"), fieldWithPath("hash").description("Blockchain block hash")))
Тестируем заголовки
92
![Page 93: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/93.jpg)
document( "rent-hippo", preprocessResponse(prettyPrint()), requestHeaders( headerWithName("User-ID").description("User unique identifier")), responseFields( fieldWithPath("hippoRemain").description("Hippo remain count"), fieldWithPath("parrot_fee").description("Fee in virtual parrots"), fieldWithPath("ins").description("Insurance number. Yeah, we sell it"), fieldWithPath("hash").description("Blockchain block hash")))
Тестируем поля ответа
93
![Page 94: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/94.jpg)
generated-snippetsrent-hippo
curl-request.adochttp-request.adochttp-response.adochttpie-request.adocrequest-headers.adocresponse-fields.adoc
Получаем сниппеты
94
![Page 95: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/95.jpg)
= Hippo Rent ServiceThis is documentation for Open API of our hippo renting service
== Methods
=== Rent
==== Request specification===== Headersinclude::{snippets}/rent-hippo/request-headers.adoc[]===== Exampleinclude::{snippets}/rent-hippo/http-request.adoc[]
==== Response specification===== Response fieldsinclude::{snippets}/rent-hippo/response-fields.adoc[]===== Exampleinclude::{snippets}/rent-hippo/http-response.adoc[]
Вставляем их в документ
95
![Page 96: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/96.jpg)
= Hippo Rent ServiceThis is documentation for Open API of our hippo renting service
== Methods
=== Rent
==== Request specification===== Headersinclude::{snippets}/rent-hippo/request-headers.adoc[]===== Exampleinclude::{snippets}/rent-hippo/http-request.adoc[]
==== Response specification===== Response fieldsinclude::{snippets}/rent-hippo/response-fields.adoc[]===== Exampleinclude::{snippets}/rent-hippo/http-response.adoc[]
96
![Page 97: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/97.jpg)
97
![Page 98: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/98.jpg)
Что получили?
● Документация как код
○ лежит в репозитории с кодом
○ встроена в цикл сборки
○ рендерится в html, pdf и т.д.
○ почти всегда актуальна
● Синергия с тестами
98
![Page 99: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/99.jpg)
Инфракод
99
![Page 100: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/100.jpg)
Hardware
Containers
Application
PaaS
Mesos/Kubernetes/Private cloud
100
![Page 101: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/101.jpg)
Hardware + OS System Libs PaaS Application
101
![Page 102: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/102.jpg)
Hardware + OS System Libs PaaS Application
Ansible
102
![Page 103: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/103.jpg)
Hardware + OS System Libs PaaS Application
AnsiblePuppet/Chef
103
![Page 104: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/104.jpg)
Ansible. Inventory
[datacenter]api-server-1api-server-2api-server-3
[datacenter:vars]magicvar = 42
104
![Page 105: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/105.jpg)
Ansible. Playbook
- hosts: datacenter roles: - role: docker - role: rsyslog
105
![Page 106: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/106.jpg)
ansible-playbook -i datacenter1 bootstrap.yml
106
Без комментариев
![Page 107: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/107.jpg)
Hardware + OS System Libs PaaS Application
Ansible
107
![Page 108: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/108.jpg)
Hardware + OS System Libs PaaS Application
AnsiblePuppet/Chef
108
![Page 109: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/109.jpg)
Hardware + OS System Libs PaaS Application
Manifest
109
![Page 110: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/110.jpg)
Docker compose
services: zk: image: zookeeper network_mode: bridge ports: - 2181:2181 environment: ZK_CONFIG: tickTime=2000,initLimit=10,clientPort=2181 ZK_ID: 1
110
![Page 111: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/111.jpg)
Docker compose
services: zk: image: zookeeper network_mode: bridge ports: - 2181:2181 environment: ZK_CONFIG: tickTime=2000,initLimit=10,clientPort=2181 ZK_ID: 1
111
![Page 112: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/112.jpg)
Конфигурация сервиса
services: zk: image: zookeeper network_mode: bridge ports: - 2181:2181 environment: ZK_CONFIG: tickTime=2000,initLimit=10,clientPort=2181 ZK_ID: 1
112
![Page 113: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/113.jpg)
Mesos/Marathon{ "id": "/api/rent-service", "cpus": 1, "mem": 1024, "instances": 3, "container": { "docker": { "image": "rent-service:0.0.1", "portMappings": [ { "containerPort": 8080 } ] } }}
113
![Page 114: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/114.jpg)
curl -X POST ... http://marathon/v2/apps?force=true
114
Вот и весь деплоймент
![Page 115: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/115.jpg)
Конфигурация приложений
https://your_repo/rent-service-config/routes.yml
routes: payment: path: /payment-service/** serviceId: payment-service
115
![Page 116: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/116.jpg)
Ещё конфигурация
● Zookeeper
● Consul
● Vault
● configo by Zeroturnaround
● ...
116
![Page 117: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/117.jpg)
configo
117
docker run \ -e CONFIGO_SOURCE_0='{"type": "http", "format": "yaml", "url":
"https://my.server.com/common.yaml"}' \ rent-service
//внутри приложенияgetEnvironmentVariable("MY_ENV_VAR")
https://github.com/zeroturnaround/configo
![Page 118: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/118.jpg)
Что получили?
● Инфрастуктура может быть легко
описана в виде кода
● Деплоймент и конфигурация
приложений в виде конфигов и
манифестов
118
![Page 119: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/119.jpg)
Неубиваемый CI
119
![Page 120: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/120.jpg)
120
Install Master Configure Slaves
![Page 121: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/121.jpg)
121
Install Master Configure Slaves
Ansible
![Page 122: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/122.jpg)
122
Install Master Configure Slaves
Ansible
![Page 123: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/123.jpg)
Jenkins Docker Cloud plugin
<——— Хост с докером
<——— Сколько контейнеров можно запустить
123
![Page 124: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/124.jpg)
Автоконфигурация
<clouds> {% for group in ['build', 'test', 'production'] %} {% for node in groups[group + '-slaves'] %} <com.github.kostyasha.yad.DockerCloud plugin="[email protected]"> <name>{{ node }}</name>
... <templates> <com.github.kostyasha.yad.DockerSlaveTemplate> <id>mycloud-template</id> <dockerContainerLifecycle> <image>{{ group }}-jenkins-slave</image> ...
</templates> <connector> <serverUrl>tcp://{{ node.hostname }}:2375</serverUrl> <apiVersion>1.20</apiVersion> </connector> </com.github.kostyasha.yad.DockerCloud> {% endfor %} {% endfor %} </clouds>
124
![Page 125: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/125.jpg)
Код доставки
125
![Page 126: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/126.jpg)
126
![Page 127: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/127.jpg)
pipeline-template.groovy
127
![Page 128: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/128.jpg)
//checkout and definition stagenode('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"
// Mark build 'stage' stage 'Build'
sh ('./gradlew clean build final')}
//next steps128
![Page 129: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/129.jpg)
//checkout and definition stagenode('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"
// Mark build 'stage' stage 'Build'
sh ('./gradlew clean build final')}
//next steps129
![Page 130: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/130.jpg)
//checkout and definition stagenode('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"
// Mark build 'stage' stage 'Build'
sh ('./gradlew clean build final')}
//next steps130
![Page 131: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/131.jpg)
//checkout and definition stagenode('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"
// Mark build 'stage' stage 'Build'
sh ('./gradlew clean build final')}
//next steps131
![Page 132: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/132.jpg)
//checkout and definition stagenode('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"
// Mark build 'stage' stage 'Build'
sh ('./gradlew clean build final')}
//next steps132
![Page 133: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/133.jpg)
//checkout and definition stagenode('build') { // Mark the code checkout 'stage' stage 'Checkout' git credentialsId: 'jenkins-git', url: "${git_url}/${repo}.git"
// Mark build 'stage' stage 'Build'
sh ('./gradlew clean build final')}
//next steps133
![Page 134: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/134.jpg)
//deploy artifact to testnode('test') { sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook( credentialsId: 'ansible', installation: 'ansible', playbook: 'deploy.yml', inventory: 'test' )}
134
![Page 135: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/135.jpg)
//deploy artifact to testnode('test') { sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook( credentialsId: 'ansible', installation: 'ansible', playbook: 'deploy.yml', inventory: 'test' )}
135
![Page 136: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/136.jpg)
//deploy artifact to testnode('test') { sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook( credentialsId: 'ansible', installation: 'ansible', playbook: 'deploy.yml', inventory: 'test' )}
136
![Page 137: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/137.jpg)
//deploy artifact to testnode('test') { sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook( credentialsId: 'ansible', installation: 'ansible', playbook: 'deploy.yml', inventory: 'test' )}
137
![Page 138: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/138.jpg)
//deploy artifact to testnode('test') { sh('ansible-galaxy install -r requirements.yml')
ansiblePlaybook( credentialsId: 'ansible', installation: 'ansible', playbook: 'deploy.yml', inventory: 'test' )}
jiraComment ( issueKey: issue_id, body: "Artifact has been deployed")
138
![Page 139: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/139.jpg)
node('build') { def repos = fetchRepos(project) for (repo in repos) { build(repo) }}
def fetchRepos(String project) { def url = new URL("https://repo/projects/${project}/repos?limit=1000")
def conn = url.openConnection() conn.setRequestMethod("GET") def responseCode = conn.getResponseCode()
final slurper = new groovy.json.JsonSlurper()
def repos = slurper.parse(conn.getInputStream()).values
for (repo in repos) { if (repo.slug.contains('one-')) result << repo.slug }
return result}
139
![Page 140: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/140.jpg)
node('build') { def repos = fetchRepos(project) for (repo in repos) { build(repo) }}
def fetchRepos(String project) { def url = new URL("https://repo/projects/${project}/repos?limit=1000")
def conn = url.openConnection() conn.setRequestMethod("GET") def responseCode = conn.getResponseCode()
final slurper = new groovy.json.JsonSlurper()
def repos = slurper.parse(conn.getInputStream()).values
for (repo in repos) { if (repo.slug.contains('one-')) result << repo.slug }
return result}
140
![Page 141: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/141.jpg)
node('build') { def repos = fetchRepos(project) for (repo in repos) { build(repo) }}
def fetchRepos(String project) { def url = new URL("https://repo/projects/${project}/repos?limit=1000")
def conn = url.openConnection() conn.setRequestMethod("GET") def responseCode = conn.getResponseCode()
final slurper = new groovy.json.JsonSlurper()
def repos = slurper.parse(conn.getInputStream()).values
for (repo in repos) { if (repo.slug.contains('one-')) result << repo.slug }
return result}
141
![Page 142: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/142.jpg)
Микросервисы
142
![Page 143: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/143.jpg)
143
Install Master Configure Slaves
Create meta job
Ansible
![Page 144: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/144.jpg)
144
Install Master Configure Slaves
Create meta job
AnsiblecURL
![Page 145: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/145.jpg)
145
Install Master Configure Slaves
Create meta job
Create pipelines
![Page 146: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/146.jpg)
jobs.each { job -> pipelineJob("${basePath}/${job}") { //define SCM
definition { cps { script(readFileFromWorkspace('pipeline-template.groovy')) sandbox() } } }}
JobDSL plugin
146
![Page 147: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/147.jpg)
jobs.each { job -> pipelineJob("${basePath}/${job}") { //define SCM
definition { cps { script(readFileFromWorkspace('pipeline-template.groovy')) sandbox() } } }}
JobDSL plugin
147
![Page 148: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/148.jpg)
jobs.each { job -> pipelineJob("${basePath}/${job}") { //define SCM
definition { cps { script(readFileFromWorkspace('pipeline-template.groovy')) sandbox() } } }}
JobDSL plugin
148
![Page 149: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/149.jpg)
149
Install Master Configure Slaves
Create meta job
Create pipelines
git
![Page 150: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/150.jpg)
ansible-playbook -i jenkins-for-my-team jenkins.yml
150
Это последний раз
![Page 151: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/151.jpg)
Что получили?
● Пайплайн как код
● Неубиваемый CI
○ без бэкапов
○ всё хранится как код
○ разворачивается за X минут
151
![Page 152: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/152.jpg)
Выводы
● Почти любой процесс можно
формализовать, представить в
виде кода и автоматизировать
● Мы все пишем код, хотя можем
думать, что это не так
152
![Page 153: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/153.jpg)
Спасибо, что выбрали красную
![Page 154: Everything as a code](https://reader031.vdocument.in/reader031/viewer/2022030313/58e4a73f1a28abbb038b4a83/html5/thumbnails/154.jpg)
@aatarasoff
@aatarasoff
@aatarasoff
QA