Initial main commit

This commit is contained in:
Dak Thompson 2024-07-11 16:03:33 -05:00
commit 1e1929c3fd
19 changed files with 548 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/host_vars/server2.yml

View File

@ -0,0 +1,7 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<ScalaCodeStyleSettings>
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
</ScalaCodeStyleSettings>
</code_scheme>
</component>

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="userId" value="-247ead6e:190a3356b8f:-7f5f" />
</MTProjectMetadataState>
</option>
</component>
</project>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

97
.idea/workspace.xml Normal file
View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="2ce79a1a-9d85-45af-a67e-4994beebf389" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/codeStyles/Project.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/codeStyles/codeStyleConfig.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/material_theme_project_new.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/group_vars/all/vault.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/hosts.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/roles/java/tasks/main.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/roles/teamcity/files/buildAgent.properties" afterDir="false" />
<change afterPath="$PROJECT_DIR$/roles/teamcity/files/server.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/roles/teamcity/tasks/build_deps.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/roles/teamcity/tasks/main.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/roles/teamcity/tasks/postgres.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/roles/teamcity/tasks/teamcity.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/roles/teamcity/templates/teamcity.service" afterDir="false" />
<change afterPath="$PROJECT_DIR$/run.sh" afterDir="false" />
<change afterPath="$PROJECT_DIR$/site.yml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ComposerSettings">
<execution />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectCodeStyleSettingsMigration">
<option name="version" value="2" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 3
}]]></component>
<component name="ProjectId" id="2j76bDvNmCfbo2eRSTY5ridKTUq" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.ShowReadmeOnStart": "true",
"git-widget-placeholder": "main",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "/home/dagmatto/homelab_teamcity",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" />
<recent name="$PROJECT_DIR$/roles" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" />
</key>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-jdk-9823dce3aa75-b114ca120d71-intellij.indexing.shared.core-IU-242.19890.14" />
<option value="bundled-js-predefined-d6986cc7102b-eef0733dfcaf-JavaScript-IU-242.19890.14" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="2ce79a1a-9d85-45af-a67e-4994beebf389" name="Changes" comment="" />
<created>1720725841180</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1720725841180</updated>
<workItem from="1720725843691" duration="4120000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>

13
group_vars/all/vault.yml Normal file
View File

@ -0,0 +1,13 @@
$ANSIBLE_VAULT;1.1;AES256
61383464396566303430643432623037336434356366383864336564613038353130646134653766
3863636265343162636362663066373937356263653131320a626236653636313733656337383061
64393736626434363033613332626162633633663435346432373965333937353564333131313364
6639643934343036340a643163663431366430323563356131386436313861386634343462343132
36393765356463373138323139323230396134323239626137656231396362636338326435376636
32343136313535616537363831353735386264653331313738333161383133366266323938323239
32303464333839343863633038343739323334313033373761303232383130306163323639326537
38666336616531643338396662393533636561646534316566623366666366396139306266316139
32346239323636613761343638623338346361653338363065383466306166373034323436643432
61393034366665663633663862653333356536636237383964636463336363616530653333333363
34613633313332356166366331363738373338363361366439313233653038383837323262316333
35633462376563353232

9
hosts.yml Normal file
View File

@ -0,0 +1,9 @@
---
all:
hosts:
server1:
ansible_become_pass: "{{ server1_become_pass }}"
server2:
ansible_become_pass: "{{ server2_become_pass }}"
vars:
ansible_user: zoe

25
roles/java/tasks/main.yml Normal file
View File

@ -0,0 +1,25 @@
---
- name: Install zip
become: yes
package:
name: zip
state: latest
- name: Install unzip
become: yes
package:
name: unzip
state: latest
- name: Install SDKMan
become: yes
become_user: "{{ sdkman_user }}"
shell:
chdir: "{{ ansible_env.HOME }}"
cmd: |
curl -s "https://get.sdkman.io" | bash
- name: Install Java
become: yes
become_user: "{{ sdkman_user }}"
shell:
chdir: "{{ ansible_env.HOME }}"
cmd: |
/bin/bash -lc "sdk install java {{ java_version }}-tem"

View File

@ -0,0 +1,52 @@
## TeamCity build agent configuration file
######################################
# Required Agent Properties #
######################################
## The address of the TeamCity server. The same as is used to open TeamCity web interface in the browser.
## Example: serverUrl=https://buildserver.mydomain.com:8111
serverUrl=http://192.168.3.7:8111/
## The unique name of the agent used to identify this agent on the TeamCity server
## Use blank name to let server generate it.
## By default, this name would be created from the build agent's host name
name=Default Agent
## Container directory to create default checkout directories for the build configurations.
## TeamCity agent assumes ownership of the directory and will delete unknown directories inside.
workDir=../work
## Container directory for the temporary directories.
## TeamCity agent assumes ownership of the directory. The directory may be cleaned between the builds.
tempDir=../temp
## Container directory for agent state files and caches.
## TeamCity agent assumes ownership of the directory and can delete content inside.
systemDir=../system
######################################
# Optional Agent Properties #
######################################
## A token which is used to identify this agent on the TeamCity server for agent authorization purposes.
## It is automatically generated and saved back on the first agent connection to the server.
authorizationToken=
######################################
# Default Build Properties #
######################################
## All properties starting with "system.name" will be passed to the build script as "name"
## All properties starting with "env.name" will be set as environment variable "name" for the build process
## Note that value should be properly escaped. (use "\\" to represent single backslash ("\"))
## More on file structure: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html#load(java.io.InputStream)
# Build Script Properties
#system.exampleProperty=example Value
# Environment Variables
#env.exampleEnvVar=example Env Value

View File

@ -0,0 +1,167 @@
<?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8105" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8111
-->
<Connector port="8111" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="60000"
redirectPort="8543"
useBodyEncodingForURI="true"
tcpNoDelay="1"
/>
<!-- Uncomment if connector with Http11NioProtocol does not work reliably -->
<!--
<Connector port="8111" protocol="HTTP/1.1"
connectionTimeout="60000"
redirectPort="8543"
useBodyEncodingForURI="true"
/>
-->
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8111" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8543" />
-->
<!-- Define a SSL HTTP/1.1 Connector on port 8543
This connector uses the JSSE configuration, when using APR, the
connector should be using the OpenSSL style configuration
described in the APR documentation -->
<!--
<Connector port="8543" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="60000"
useBodyEncodingForURI="true"
socket.txBufSize="64000"
socket.rxBufSize="64000"
SSLEnabled="true"
scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"/>
-->
<!-- Define an AJP 1.3 Connector on port 8109 -->
<!--
<Connector port="8109" protocol="AJP/1.3" redirectPort="8543" />
-->
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="192.168.3.7" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="192.168.3.7">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="192.168.3.7" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.ErrorReportValve"
showReport="false"
showServerInfo="false" />
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<!--
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="192.168.3.7_access_log." suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
-->
</Host>
</Engine>
</Service>
</Server>

View File

@ -0,0 +1,6 @@
---
- name: Install Git
become: yes
package:
name: git
state: latest

View File

@ -0,0 +1,8 @@
---
- name: Install Postgres
import_tasks: postgres.yml
- name: Install build deps
import_tasks: build_deps.yml
- name: Install TeamCity
import_tasks: teamcity.yml

View File

@ -0,0 +1,50 @@
---
- name: Update sudoers
become: yes
community.general.sudoers:
name: zoe-do-as-postgres
state: present
user: zoe
runas: postgres
commands: ALL
- name: Create teamcity PostgreSQL user
become: yes
become_user: postgres
postgresql_user:
name: teamcity
state: present
password: "{{ teamcity_psql_password }}"
role_attr_flags: CREATEDB
environment:
PGOPTIONS: "-c password_encryption=scram-sha-256"
- name: Update pg_hba conf
become: yes
postgresql_pg_hba:
contype: host
dest: /var/lib/pgsql/data/pg_hba.conf
method: scram-sha-256
address: localhost
users: teamcity
state: present
- name: Reload PostgreSQL
become: yes
systemd:
name: postgresql
state: reloaded
- name: Create teamcity PostgreSQL DB
become: yes
become_user: postgres
postgresql_db:
name: teamcity
owner: teamcity
state: present
template: template0
encoding: UTF8
lc_collate: en_US.UTF-8
lc_ctype: en_US.UTF-8
- name: Create teamcity schema
become: yes
become_user: postgres
postgresql_schema:
name: teamcity
owner: teamcity

View File

@ -0,0 +1,41 @@
---
- name: Download TeamCity
become: yes
unarchive:
src: https://download.jetbrains.com/teamcity/TeamCity-{{ teamcity_version }}.tar.gz
dest: /opt/teamcity
remote_src: yes
owner: teamcity
group: teamcity
mode: 0750
- name: Upload TeamCity server configuration
become: yes
copy:
src: server.xml
dest: "/opt/teamcity/TeamCity/conf/server.xml"
owner: teamcity
group: teamcity
mode: 0750
- name: Upload TeamCity buildAgent properties
become: yes
copy:
src: buildAgent.properties
dest: "/opt/teamcity/TeamCity/buildAgent/conf/buildAgent.properties"
owner: teamcity
group: teamcity
mode: 0750
- name: Upload teamcity.service
become: yes
template:
src: teamcity.service
dest: /etc/systemd/system/teamcity.service
owner: root
group: root
mode: 0755
- name: Restart TeamCity
become: yes
systemd:
enabled: yes
name: teamcity.service
state: restarted
daemon_reload: yes

View File

@ -0,0 +1,19 @@
[Unit]
Description=TeamCity: A Build Server
After=syslog.target
After=network.target
Wants=postgresql.service
After=postgresql.service
[Service]
User=teamcity
Group=teamcity
ExecStart=/opt/teamcity/TeamCity/bin/runAll.sh start
ExecStop=/opt/teamcity/TeamCity/bin/runAll.sh stop
Environment=TEAMCITY_DATA_PATH={{ teamcity_data_path }} JAVA_HOME=/opt/teamcity/.sdkman/candidates/java/current
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

3
run.sh Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env sh
ansible-playbook -i hosts.yml site.yml --vault-password-file ~/.vault_pass.txt

23
site.yml Normal file
View File

@ -0,0 +1,23 @@
---
- name: Setup TeamCity
hosts: server2
vars:
teamcity_data_path: /opt/teamcity/data
pre_tasks:
- name: Create TeamCity Data dir
become: yes
file:
path: "{{ teamcity_data_path }}"
state: directory
recurse: yes
owner: teamcity
group: teamcity
mode: '750'
roles:
- role: java
vars:
sdkman_user: teamcity
java_version: 17.0.8.1
- role: teamcity
vars:
teamcity_version: 2023.05.3