diff --git a/readme.md b/readme.md index 6eaa841..5b7dc36 100644 --- a/readme.md +++ b/readme.md @@ -45,3 +45,4 @@ * [9.1. Жизненный цикл ПО](/src/homework/09-ci/9.1) * [9.3. CI\CD](/src/homework/09-ci/9.3) * [9.4 Jenkins](/src/homework/09-ci/9.4) +* [9.5. Teamcity](/src/homework/09-ci/9.5) diff --git a/src/homework/09-ci/9.4/readme.md b/src/homework/09-ci/9.4/readme.md index 25f334f..52b27f6 100644 --- a/src/homework/09-ci/9.4/readme.md +++ b/src/homework/09-ci/9.4/readme.md @@ -1,5 +1,5 @@ Выполнение [домашнего задания](https://github.com/netology-code/mnt-homeworks/blob/MNT-13/09-ci-04-jenkins/README.md) -по теме "9.3. Jenkins". +по теме "9.4. Jenkins". ## Q/A diff --git a/src/homework/09-ci/9.5/img/nexus_release.png b/src/homework/09-ci/9.5/img/nexus_release.png new file mode 100644 index 0000000..624c241 Binary files /dev/null and b/src/homework/09-ci/9.5/img/nexus_release.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_build_branch_success.png b/src/homework/09-ci/9.5/img/teamcity_build_branch_success.png new file mode 100644 index 0000000..5101c21 Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_build_branch_success.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_build_config.png b/src/homework/09-ci/9.5/img/teamcity_build_config.png new file mode 100644 index 0000000..d11e0e7 Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_build_config.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_build_config_sync.png b/src/homework/09-ci/9.5/img/teamcity_build_config_sync.png new file mode 100644 index 0000000..b0ffc56 Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_build_config_sync.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_build_success.png b/src/homework/09-ci/9.5/img/teamcity_build_success.png new file mode 100644 index 0000000..3d88574 Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_build_success.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_dashboard.png b/src/homework/09-ci/9.5/img/teamcity_dashboard.png new file mode 100644 index 0000000..9ab6e7e Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_dashboard.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_deploy_success.png b/src/homework/09-ci/9.5/img/teamcity_deploy_success.png new file mode 100644 index 0000000..81571b1 Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_deploy_success.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_maven_config.png b/src/homework/09-ci/9.5/img/teamcity_maven_config.png new file mode 100644 index 0000000..3ff7112 Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_maven_config.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_new_project.png b/src/homework/09-ci/9.5/img/teamcity_new_project.png new file mode 100644 index 0000000..071cc20 Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_new_project.png differ diff --git a/src/homework/09-ci/9.5/img/teamcity_project_build.png b/src/homework/09-ci/9.5/img/teamcity_project_build.png new file mode 100644 index 0000000..457c783 Binary files /dev/null and b/src/homework/09-ci/9.5/img/teamcity_project_build.png differ diff --git a/src/homework/09-ci/9.5/infrastructure/.gitignore b/src/homework/09-ci/9.5/infrastructure/.gitignore new file mode 100644 index 0000000..cc73027 --- /dev/null +++ b/src/homework/09-ci/9.5/infrastructure/.gitignore @@ -0,0 +1,3 @@ +files/*.pub +inventory/hosts.yml +roles/* diff --git a/src/homework/09-ci/9.5/infrastructure/inventory/group_vars/nexus.yml b/src/homework/09-ci/9.5/infrastructure/inventory/group_vars/nexus.yml new file mode 100644 index 0000000..aef5969 --- /dev/null +++ b/src/homework/09-ci/9.5/infrastructure/inventory/group_vars/nexus.yml @@ -0,0 +1,22 @@ +--- +nexus_user_group: nexus +nexus_user_name: nexus +nexus_directory_data: "/home/{{ nexus_user_name }}/sonatype-work/nexus3" +nexus_directory_home: "/home/{{ nexus_user_name }}/nexus" +nexus_directory_log: "/home/{{ nexus_user_name }}/log" +nexus_directory_package: "/home/{{ nexus_user_name }}/pkg" +nexus_directory_tmp: "/home/{{ nexus_user_name }}/tmp" +nexus_version: 3.14.0-04 +nexus_download_url: https://download.sonatype.com/nexus/3 +nexus_service_enabled: true +nexus_ulimit: 65536 +nexus_context_path: / +nexus_host: 0.0.0.0 +nexus_port: 8081 +nexus_port_check_timeout: 600 +nexus_edition: nexus-oss-edition +nexus_features: nexus-oss-feature +nexus_java_heap_size: 1200M +nexus_java_max_direct_memory: 2G +nexus_service_start_on_boot: true +nexus_configuration_disk_free_space_limit: ~ diff --git a/src/homework/09-ci/9.5/infrastructure/inventory/hosts.yml.example b/src/homework/09-ci/9.5/infrastructure/inventory/hosts.yml.example new file mode 100644 index 0000000..d084a7b --- /dev/null +++ b/src/homework/09-ci/9.5/infrastructure/inventory/hosts.yml.example @@ -0,0 +1,12 @@ +--- +all: + hosts: + nexus-01: + ansible_host: + children: + nexus: + hosts: + nexus-01: + vars: + ansible_connection_type: paramiko + ansible_user: diff --git a/src/homework/09-ci/9.5/infrastructure/site.yml b/src/homework/09-ci/9.5/infrastructure/site.yml new file mode 100644 index 0000000..4a7aab0 --- /dev/null +++ b/src/homework/09-ci/9.5/infrastructure/site.yml @@ -0,0 +1,158 @@ +--- +- name: Get Nexus installed + hosts: nexus + pre_tasks: + - name: Create Nexus group + become: true + group: + name: "{{ nexus_user_group }}" + state: present + - name: Create Nexus user + become: true + user: + name: "{{ nexus_user_name }}" + - name: Install JDK + become: true + package: + name: [java-1.8.0-openjdk, java-1.8.0-openjdk-devel] + state: present + tasks: + - name: Create Nexus directories + become: true + file: + group: "{{ nexus_user_group }}" + owner: "{{ nexus_user_name }}" + path: "{{ item }}" + state: directory + with_items: + - "{{ nexus_directory_log }}" + - "{{ nexus_directory_data }}" + - "{{ nexus_directory_data }}/etc" + - "{{ nexus_directory_package }}" + - "{{ nexus_directory_tmp }}" + + - name: Download Nexus + become: true + become_user: "{{ nexus_user_name }}" + get_url: + dest: "{{ nexus_directory_package }}/nexus-{{ nexus_version }}.tar.gz" + url: "{{ nexus_download_url }}/nexus-{{ nexus_version }}-unix.tar.gz" + + - name: Unpack Nexus + become: true + become_user: "{{ nexus_user_name }}" + unarchive: + copy: no + creates: "{{ nexus_directory_package }}/nexus-{{ nexus_version }}" + dest: "{{ nexus_directory_package }}" + src: "{{ nexus_directory_package }}/nexus-{{ nexus_version }}.tar.gz" + + - name: Link to Nexus Directory + become: true + become_user: "{{ nexus_user_name }}" + file: + dest: "{{ nexus_directory_home }}" + src: "{{ nexus_directory_package }}/nexus-{{ nexus_version }}" + state: link + + - name: Add NEXUS_HOME for Nexus user + become: true + become_user: "{{ nexus_user_name }}" + lineinfile: + create: yes + dest: "/home/{{ nexus_user_name }}/.bashrc" + insertafter: EOF + line: "export NEXUS_HOME={{ nexus_directory_home }}" + + - name: Add run_as_user to Nexus.rc + become: true + become_user: "{{ nexus_user_name }}" + lineinfile: + create: yes + dest: "{{ nexus_directory_home }}/bin/nexus.rc" + insertafter: EOF + line: "run_as_user=\"{{ nexus_user_name }}\"" + regexp: "^run_as_user" + + - name: Raise nofile limit for Nexus user + become: true + pam_limits: + domain: "{{ nexus_user_name }}" + limit_type: "-" + limit_item: nofile + value: "{{ nexus_ulimit }}" + + - name: Create Nexus service for SystemD + become: true + template: + dest: /lib/systemd/system/nexus.service + mode: 0644 + src: nexus.systemd.j2 + + - name: Ensure Nexus service is enabled for SystemD + become: true + systemd: + daemon_reload: yes + enabled: yes + name: nexus + when: + - nexus_service_enabled + + - name: Create Nexus vmoptions + become: true + become_user: "{{ nexus_user_name }}" + template: + dest: "{{ nexus_directory_home }}/bin/nexus.vmoptions" + src: nexus.vmoptions.j2 + register: nexus_config_changed + + - name: Create Nexus properties + become: true + become_user: "{{ nexus_user_name }}" + template: + dest: "{{ nexus_directory_data }}/etc/nexus.properties" + src: nexus.properties.j2 + register: nexus_config_changed + + - name: Lower Nexus disk space threshold + become: true + become_user: "{{ nexus_user_name }}" + lineinfile: + backrefs: yes + dest: "{{ nexus_directory_home }}/etc/karaf/system.properties" + insertafter: EOF + line: "storage.diskCache.diskFreeSpaceLimit={{ nexus_configuration_disk_free_space_limit }}" + regexp: ^storage\.diskCache\.diskFreeSpaceLimit + when: nexus_configuration_disk_free_space_limit is not none + register: nexus_config_changed + + - name: Start Nexus service if enabled + become: true + service: + enabled: yes + name: nexus + state: started + when: + - nexus_service_start_on_boot + - not nexus_config_changed.changed + tags: + - skip_ansible_lint + + - name: Ensure Nexus service is restarted + become: true + service: + name: nexus + state: restarted + when: + - nexus_service_start_on_boot + - nexus_config_changed.changed + tags: + - skip_ansible_lint + + - name: Wait for Nexus port if started + wait_for: + port: "{{ nexus_port }}" + state: started + timeout: "{{ nexus_port_check_timeout }}" + when: + - nexus_service_start_on_boot diff --git a/src/homework/09-ci/9.5/infrastructure/templates/nexus.properties.j2 b/src/homework/09-ci/9.5/infrastructure/templates/nexus.properties.j2 new file mode 100644 index 0000000..2b95258 --- /dev/null +++ b/src/homework/09-ci/9.5/infrastructure/templates/nexus.properties.j2 @@ -0,0 +1,12 @@ +# +# + +# Jetty section +application-host={{ nexus_host }} +application-port={{ nexus_port }} +nexus-context-path={{ nexus_context_path }} + +# Nexus section +nexus-edition={{ nexus_edition }} +nexus-features=\ + {{ nexus_features }} diff --git a/src/homework/09-ci/9.5/infrastructure/templates/nexus.systemd.j2 b/src/homework/09-ci/9.5/infrastructure/templates/nexus.systemd.j2 new file mode 100644 index 0000000..1483c14 --- /dev/null +++ b/src/homework/09-ci/9.5/infrastructure/templates/nexus.systemd.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=nexus service +After=network.target + +[Service] +Type=forking +User={{ nexus_user_name }} +Group={{ nexus_user_group }} +LimitNOFILE={{ nexus_ulimit }} +ExecStart={{ nexus_directory_home }}/bin/nexus start +ExecStop={{ nexus_directory_home }}/bin/nexus stop +Restart=on-abort + +[Install] +WantedBy=multi-user.target diff --git a/src/homework/09-ci/9.5/infrastructure/templates/nexus.vmoptions.j2 b/src/homework/09-ci/9.5/infrastructure/templates/nexus.vmoptions.j2 new file mode 100644 index 0000000..d3efba3 --- /dev/null +++ b/src/homework/09-ci/9.5/infrastructure/templates/nexus.vmoptions.j2 @@ -0,0 +1,16 @@ +-Xms{{ nexus_java_heap_size }} +-Xmx{{ nexus_java_heap_size }} +-XX:MaxDirectMemorySize={{ nexus_java_max_direct_memory }} +-XX:+UnlockDiagnosticVMOptions +-XX:+UnsyncloadClass +-XX:+LogVMOutput +-XX:LogFile={{ nexus_directory_log }}/jvm.log +-XX:-OmitStackTraceInFastThrow +-Djava.net.preferIPv4Stack=true +-Dkaraf.home=. +-Dkaraf.base=. +-Dkaraf.etc=etc/karaf +-Djava.util.logging.config.file=etc/karaf/java.util.logging.properties +-Dkaraf.data={{ nexus_directory_data }} +-Djava.io.tmpdir={{ nexus_directory_tmp }} +-Dkaraf.startLocalConsole=false diff --git a/src/homework/09-ci/9.5/readme.md b/src/homework/09-ci/9.5/readme.md new file mode 100644 index 0000000..c343810 --- /dev/null +++ b/src/homework/09-ci/9.5/readme.md @@ -0,0 +1,83 @@ +Выполнение [домашнего задания](https://github.com/netology-code/mnt-homeworks/blob/MNT-13/09-ci-05-teamcity/README.md) +по теме "9.5. Teamcity" + +## Q/A + +### Задание 1 + +> Подготовка к выполнению +> 1. В Ya.Cloud создайте новый инстанс (4CPU4RAM) на основе образа `jetbrains/teamcity-server` +> 2. Дождитесь запуска teamcity, выполните первоначальную настройку +> 3. Создайте ещё один инстанс(2CPU4RAM) на основе образа `jetbrains/teamcity-agent`. Пропишите к нему переменную окружения `SERVER_URL: "http://:8111"` +> 4. Авторизуйте агент +> 5. Сделайте fork [репозитория](https://github.com/aragastmatb/example-teamcity) +> 6. Создать VM (2CPU4RAM) и запустить [playbook](./infrastructure) + +Форк репозитория: [netology-devops-teamcity-example](https://github.com/Dannecron/netology-devops-teamcity-example). + +![teamcity_dashboard](./img/teamcity_dashboard.png) + +### Задание 2 + +> Основная часть +> 1. Создайте новый проект в teamcity на основе fork + +![teamcity_new_project](./img/teamcity_new_project.png) + +> 2. Сделайте autodetect конфигурации +> 3. Сохраните необходимые шаги, запустите первую сборку master'a + +![teamcity_project_build](./img/teamcity_project_build.png) + +![teamcity_build_success](./img/teamcity_build_success.png) + +> 4. Поменяйте условия сборки: если сборка по ветке `master`, то должен происходит `mvn clean deploy`, иначе `mvn clean test` + +![teamcity_build_config](./img/teamcity_build_config.png) + +> 5. Для deploy будет необходимо загрузить [settings.xml](./teamcity/settings.xml) в набор конфигураций maven у teamcity, предварительно записав туда креды для подключения к nexus +> 6. В pom.xml необходимо поменять ссылки на репозиторий и nexus + +![teamcity_maven_config](./img/teamcity_maven_config.png) + +> 7. Запустите сборку по master, убедитесь что всё прошло успешно, артефакт появился в nexus + +![teamcity_deploy_success](./img/teamcity_deploy_success.png) + +![nexus_release](./img/nexus_release.png) + +> 8. Мигрируйте `build configuration` в репозиторий + +![teamcity_build_config_sync](./img/teamcity_build_config_sync.png) + +> 9. Создайте отдельную ветку `feature/add_reply` в репозитории + +```shell +git branch -C feature/add_reply && git switch feature/add_reply +``` + +> 10. Напишите новый метод для класса Welcomer: метод должен возвращать произвольную реплику, содержащую слово `hunter` +> 11. Дополните тест для нового метода на поиск слова `hunter` в новой реплике +> 12. Сделайте push всех изменений в новую ветку в репозиторий + +Ветка с изменениями: [feature/add_reply](https://github.com/Dannecron/netology-devops-teamcity-example/tree/feature/add_reply) + +> 13. Убедитесь что сборка самостоятельно запустилась, тесты прошли успешно + +![teamcity_build_branch_success](./img/teamcity_build_branch_success.png) + +> 14. Внесите изменения из произвольной ветки `feature/add_reply` в `master` через `Merge` +> 15. Убедитесь, что нет собранного артефакта в сборке по ветке `master` +> 16. Настройте конфигурацию так, чтобы она собирала `.jar` в артефакты сборки + +Конфигурация уже настроена на сборку `jar`. При мерже в мастер сборка запустилась автоматически, +так как изначально кофигурация проверяет все изменения всех веток в репозитории. + +> 17. Проведите повторную сборку мастера, убедитесь, что сбора прошла успешно и артефакты собраны + +Поменяли `pom.xml`, вписав новую версию. Сборка запустилась автоматически и успешно опубликовала артефакты в `nexus`. + +> 18. Проверьте, что конфигурация в репозитории содержит все настройки конфигурации из teamcity +> 19. В ответ предоставьте ссылку на репозиторий + +[netology-devops-teamcity-example](https://github.com/Dannecron/netology-devops-teamcity-example) diff --git a/src/homework/09-ci/9.5/teamcity/settings.xml b/src/homework/09-ci/9.5/teamcity/settings.xml new file mode 100644 index 0000000..ac515eb --- /dev/null +++ b/src/homework/09-ci/9.5/teamcity/settings.xml @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + nexus + admin + admin123 + + + + + + + + + + + + + + + + + +