Initial commit
commit
c3200c91db
@ -0,0 +1,6 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = hosts
|
||||||
|
transport = ssh
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
pipelining = true
|
@ -0,0 +1,14 @@
|
|||||||
|
[dav]
|
||||||
|
kodos-cdddav.codesignd.net
|
||||||
|
|
||||||
|
[git]
|
||||||
|
kodos-cddgit.codesignd.net
|
||||||
|
|
||||||
|
[mail]
|
||||||
|
kodos-cddmail[1:2].codesignd.net
|
||||||
|
|
||||||
|
[misc]
|
||||||
|
kodos-cddmisc1.codesignd.net
|
||||||
|
|
||||||
|
[web]
|
||||||
|
kodos-cddweb[1:2].codesignd.net
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- src: snapstromegon.uberspace_mail_catchall
|
||||||
|
- src: snapstromegon.uberspace_mail_user
|
||||||
|
- src: snapstromegon.uberspace_web_backend
|
||||||
|
- src: snapstromegon.uberspace_web_domain
|
@ -0,0 +1,3 @@
|
|||||||
|
function radicale
|
||||||
|
~/.local/bin/radicale --config ~/radicale/config $argv
|
||||||
|
end
|
@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
########################################################################
|
||||||
|
# 2018-11-25 Lukas Bestle <project-shell@lukasbestle.com>
|
||||||
|
########################################################################
|
||||||
|
# Concats a directory of ICS files to a single ICS file for sharing
|
||||||
|
#
|
||||||
|
# Usage: radicale_to_ics <directory> <output.ics> [<calname>]
|
||||||
|
#
|
||||||
|
# <directory> Directory with ICS files (e.g. from Radicale)
|
||||||
|
# <output.ics> Output path for the concatenated ICS file
|
||||||
|
# <calname> Optional name of the ICS file
|
||||||
|
# (displayed in clients)
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
directory="$1"
|
||||||
|
output="$2"
|
||||||
|
calname="$3"
|
||||||
|
|
||||||
|
if [[ -z "$output" ]]; then
|
||||||
|
# Print help
|
||||||
|
echo -e "\033[1mUsage:\033[0m \033[34mradicale_to_ics\033[0m <directory> <output.ics> [<calname>]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Place temporary file right next to the output file
|
||||||
|
# Will be moved when done with processing
|
||||||
|
tmp="$output.tmp"
|
||||||
|
|
||||||
|
# iCalendar header
|
||||||
|
echo "BEGIN:VCALENDAR" > "$tmp"
|
||||||
|
echo "VERSION:2.0" >> "$tmp"
|
||||||
|
echo "X-WR-TIMEZONE:Europe/Berlin" >> "$tmp"
|
||||||
|
echo "CALSCALE:GREGORIAN" >> "$tmp"
|
||||||
|
echo "METHOD:PUBLISH" >> "$tmp"
|
||||||
|
|
||||||
|
# Add calendar name if given
|
||||||
|
if [[ -n "$calname" ]]; then
|
||||||
|
echo "X-WR-CALNAME:$calname" >> "$tmp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Concat all event files in the given directory
|
||||||
|
# unless the directory is empty
|
||||||
|
if [[ "$(ls "$directory")" ]]; then
|
||||||
|
for file in "$directory"/*; do
|
||||||
|
# Extract all VEVENT elements (supports multiple per input file)
|
||||||
|
sed '/^BEGIN:VEVENT/, /^END:VEVENT/!d' "$file" >> "$tmp"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add iCalendar footer
|
||||||
|
echo "END:VCALENDAR" >> "$tmp"
|
||||||
|
|
||||||
|
# Move to final destination
|
||||||
|
mv "$tmp" "$output"
|
@ -0,0 +1,24 @@
|
|||||||
|
# The user "lukas" can read and write any collection
|
||||||
|
[admin]
|
||||||
|
user: lukas
|
||||||
|
collection: .*
|
||||||
|
permissions: RrWw
|
||||||
|
|
||||||
|
# Allow reading root collection for authenticated users (required for the web interface)
|
||||||
|
[root]
|
||||||
|
user: .+
|
||||||
|
collection:
|
||||||
|
permissions: R
|
||||||
|
|
||||||
|
# Allow reading and writing principal collection (same as user name)
|
||||||
|
[principal]
|
||||||
|
user: .+
|
||||||
|
collection: {user}
|
||||||
|
permissions: RW
|
||||||
|
|
||||||
|
# Allow reading and writing calendars and address books that are direct
|
||||||
|
# children of the principal collection
|
||||||
|
[calendars]
|
||||||
|
user: .+
|
||||||
|
collection: {user}/[^/]+
|
||||||
|
permissions: rw
|
@ -0,0 +1,3 @@
|
|||||||
|
.Radicale.cache
|
||||||
|
.Radicale.lock
|
||||||
|
.Radicale.tmp-*
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
- name: Reread service config
|
||||||
|
command: supervisorctl reread
|
||||||
|
|
||||||
|
- name: Restart Radicale
|
||||||
|
supervisorctl:
|
||||||
|
name: radicale
|
||||||
|
state: restarted
|
@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
- name: Add DAV domain to Uberspace config
|
||||||
|
import_role:
|
||||||
|
name: snapstromegon.uberspace_web_domain
|
||||||
|
vars:
|
||||||
|
domain: dav.bstl.xyz
|
||||||
|
|
||||||
|
- name: Copy config to home directory
|
||||||
|
copy:
|
||||||
|
src: home/
|
||||||
|
dest: "{{ ansible_env.HOME }}/"
|
||||||
|
mode: preserve
|
||||||
|
tags: radicale-update
|
||||||
|
notify: Restart Radicale
|
||||||
|
|
||||||
|
- name: Copy service config
|
||||||
|
template:
|
||||||
|
src: service.ini.j2
|
||||||
|
dest: "{{ ansible_env.HOME }}/etc/services.d/radicale.ini"
|
||||||
|
notify: Reread service config
|
||||||
|
|
||||||
|
- name: Copy app config
|
||||||
|
template:
|
||||||
|
src: config.j2
|
||||||
|
dest: "{{ ansible_env.HOME }}/radicale/config"
|
||||||
|
tags: radicale-update
|
||||||
|
notify: Restart Radicale
|
||||||
|
|
||||||
|
- name: Set up Radicale users
|
||||||
|
template:
|
||||||
|
src: users.j2
|
||||||
|
dest: "{{ ansible_facts.env.HOME }}/radicale/users"
|
||||||
|
tags: radicale-update
|
||||||
|
notify: Restart Radicale
|
||||||
|
|
||||||
|
- name: Configure web backend
|
||||||
|
import_role:
|
||||||
|
name: snapstromegon.uberspace_web_backend
|
||||||
|
vars:
|
||||||
|
route: dav.bstl.xyz
|
||||||
|
http:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
- name: Install and update Radicale
|
||||||
|
pip:
|
||||||
|
name: radicale[bcrypt]
|
||||||
|
state: latest
|
||||||
|
extra_args: --user
|
||||||
|
executable: pip3.8
|
||||||
|
tags: radicale-update
|
||||||
|
notify: Restart Radicale
|
||||||
|
|
||||||
|
- name: Initialize storage repository
|
||||||
|
command:
|
||||||
|
chdir: "{{ ansible_env.HOME }}/radicale/storage"
|
||||||
|
cmd: git init
|
||||||
|
creates: "{{ ansible_env.HOME }}/radicale/storage/.git"
|
||||||
|
|
||||||
|
- name: Set up garbage collection cronjob
|
||||||
|
cron:
|
||||||
|
name: "Garbage-collection"
|
||||||
|
special_time: weekly
|
||||||
|
job: git --git-dir {{ ansible_env.HOME }}/radicale/storage/.git gc
|
@ -0,0 +1,16 @@
|
|||||||
|
[server]
|
||||||
|
hosts = 0.0.0.0:8080
|
||||||
|
|
||||||
|
[auth]
|
||||||
|
type = htpasswd
|
||||||
|
htpasswd_filename = {{ ansible_env.HOME }}/radicale/users
|
||||||
|
htpasswd_encryption = bcrypt
|
||||||
|
realm = bstl DAV - Password Required
|
||||||
|
|
||||||
|
[rights]
|
||||||
|
type = from_file
|
||||||
|
file = {{ ansible_env.HOME }}/radicale/rights
|
||||||
|
|
||||||
|
[storage]
|
||||||
|
filesystem_folder = {{ ansible_env.HOME }}/radicale/storage
|
||||||
|
hook = git add -A && (git diff --cached --quiet || git commit -m "Changes by "%(user)s)
|
@ -0,0 +1,4 @@
|
|||||||
|
[program:radicale]
|
||||||
|
command={{ ansible_env.HOME }}/.local/bin/radicale --config {{ ansible_env.HOME }}/radicale/config
|
||||||
|
autostart=yes
|
||||||
|
autorestart=yes
|
@ -0,0 +1,3 @@
|
|||||||
|
{% for username, password in dav_users.items() %}
|
||||||
|
{{ username }}:{{ password }}
|
||||||
|
{% endfor %}
|
@ -0,0 +1,3 @@
|
|||||||
|
function gitea
|
||||||
|
env GITEA_WORK_DIR=$HOME/gitea ~/.linuxbrew/bin/gitea $argv
|
||||||
|
end
|
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -0,0 +1 @@
|
|||||||
|
<svg width="1000" height="1000" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="M591.655 0a504.542 504.542 0 0178.979 21.11l-12.775 135.521a377.428 377.428 0 0160.526 35.013l110.923-78.783a511.365 511.365 0 0157.832 57.832l-78.783 110.922a377.428 377.428 0 0135.012 60.526l135.52-12.775A504.542 504.542 0 011000 408.345l-123.768 56.707A382.582 382.582 0 01877.827 500c0 11.784-.54 23.441-1.595 34.95L1000 591.654a504.542 504.542 0 01-21.11 78.979l-135.52-12.775a377.428 377.428 0 01-35.013 60.526l78.783 110.922a511.365 511.365 0 01-57.833 57.833l-110.922-78.784a377.428 377.428 0 01-60.526 35.013l12.775 135.52A504.542 504.542 0 01591.655 1000l-56.707-123.77a382.582 382.582 0 01-34.947 1.596c-11.783 0-23.44-.54-34.948-1.595L408.345 1000a504.542 504.542 0 01-78.979-21.11l12.775-135.522a377.428 377.428 0 01-60.525-35.012L170.693 887.14a511.365 511.365 0 01-57.832-57.832l78.783-110.925a377.428 377.428 0 01-35.011-60.524L21.11 670.634A504.542 504.542 0 010 591.655l123.77-56.707A382.582 382.582 0 01122.175 500c0-11.783.54-23.44 1.595-34.947L0 408.345a504.542 504.542 0 0121.11-78.979l135.523 12.775a377.428 377.428 0 0135.011-60.524L112.86 170.693a511.365 511.365 0 0157.833-57.833l110.923 78.784a377.428 377.428 0 0160.525-35.012L329.366 21.11A504.542 504.542 0 01408.345 0l56.708 123.77A382.582 382.582 0 01500 122.173c11.783 0 23.44.54 34.947 1.595L591.655 0zm-91.654 241.084c-142.995 0-258.916 115.92-258.916 258.916 0 142.995 115.92 258.916 258.916 258.916 142.995 0 258.916-115.92 258.916-258.916 0-142.995-115.92-258.916-258.916-258.916z" fill="#000"/><path stroke="#000" stroke-width="57.537" d="M500.5 347l132.935 76.75v153.5L500.5 654l-132.935-76.75v-153.5z"/></g></svg>
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
@ -0,0 +1,24 @@
|
|||||||
|
<footer>
|
||||||
|
<div class="ui container">
|
||||||
|
<div class="ui left">
|
||||||
|
© Lukas Bestle
|
||||||
|
</div>
|
||||||
|
<div class="ui right links">
|
||||||
|
{{if .ShowFooterBranding}}
|
||||||
|
<a target="_blank" rel="noopener noreferrer" href="https://github.com/go-gitea/gitea"><i class="fa fa-github-square"></i><span class="sr-only">GitHub</span></a>
|
||||||
|
{{end}}
|
||||||
|
<div class="ui language bottom floating slide up dropdown link item">
|
||||||
|
<i class="world icon"></i>
|
||||||
|
<div class="text">{{.LangName}}</div>
|
||||||
|
<div class="menu">
|
||||||
|
{{range .AllLangs}}
|
||||||
|
<a class="item {{if eq $.Lang .Lang}}active selected{{end}}" href="{{if eq $.Lang .Lang}}#{{else}}{{$.Link}}?lang={{.Lang}}{{end}}">{{.Name}}</a>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a target="_blank" href="https://codesignd.com">{{.i18n.Tr "website"}}</a>
|
||||||
|
<a target="_blank" href="https://codesignd.com/legal">Imprint</a>
|
||||||
|
{{if (or .ShowFooterVersion .PageIsAdmin)}}<span class="version">{{GoVer}}</span>{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
@ -0,0 +1,133 @@
|
|||||||
|
<div class="ui container" id="navbar">
|
||||||
|
<div class="item brand" style="justify-content: space-between;">
|
||||||
|
<a href="{{AppSubUrl}}/">
|
||||||
|
<img class="ui mini image" src="{{AppSubUrl}}/img/gitea-sm.png">
|
||||||
|
</a>
|
||||||
|
<div class="ui basic icon button mobile-only" id="navbar-expand-toggle">
|
||||||
|
<i class="sidebar icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{if .IsSigned}}
|
||||||
|
<a class="item {{if .PageIsDashboard}}active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "dashboard"}}</a>
|
||||||
|
<a class="item {{if .PageIsIssues}}active{{end}}" href="{{AppSubUrl}}/issues">{{.i18n.Tr "issues"}}</a>
|
||||||
|
<a class="item {{if .PageIsPulls}}active{{end}}" href="{{AppSubUrl}}/pulls">{{.i18n.Tr "pull_requests"}}</a>
|
||||||
|
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "explore"}}</a>
|
||||||
|
{{else if .IsLandingPageHome}}
|
||||||
|
<a class="item {{if .PageIsHome}}active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "home"}}</a>
|
||||||
|
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "explore"}}</a>
|
||||||
|
{{else if .IsLandingPageExplore}}
|
||||||
|
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "home"}}</a>
|
||||||
|
{{else if .IsLandingPageOrganizations}}
|
||||||
|
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "home"}}</a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{template "custom/extra_links" .}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
<div class="item">
|
||||||
|
<div class="ui icon input">
|
||||||
|
<input class="searchbox" type="text" placeholder="{{.i18n.Tr "search_project"}}">
|
||||||
|
<i class="search icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{if .IsSigned}}
|
||||||
|
<div class="right stackable menu">
|
||||||
|
<a href="{{AppSubUrl}}/notifications" class="item poping up" data-content='{{.i18n.Tr "notifications"}}' data-variation="tiny inverted">
|
||||||
|
<span class="text">
|
||||||
|
<i class="fitted octicon octicon-bell"></i>
|
||||||
|
<span class="sr-mobile-only">{{.i18n.Tr "notifications"}}</span>
|
||||||
|
|
||||||
|
{{if .NotificationUnreadCount}}
|
||||||
|
<span class="ui red label">
|
||||||
|
{{.NotificationUnreadCount}}
|
||||||
|
</span>
|
||||||
|
{{end}}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="ui dropdown jump item poping up" data-content="{{.i18n.Tr "create_new"}}" data-variation="tiny inverted">
|
||||||
|
<span class="text">
|
||||||
|
<i class="fitted octicon octicon-plus"></i>
|
||||||
|
<span class="sr-mobile-only">{{.i18n.Tr "create_new"}}</span>
|
||||||
|
<i class="fitted octicon octicon-triangle-down not-mobile"></i>
|
||||||
|
</span>
|
||||||
|
<div class="menu">
|
||||||
|
<a class="item" href="{{AppSubUrl}}/repo/create">
|
||||||
|
<i class="fitted octicon octicon-plus"></i> {{.i18n.Tr "new_repo"}}
|
||||||
|
</a>
|
||||||
|
<a class="item" href="{{AppSubUrl}}/repo/migrate">
|
||||||
|
<i class="fitted octicon octicon-repo-clone"></i> {{.i18n.Tr "new_migrate"}}
|
||||||
|
</a>
|
||||||
|
{{if .SignedUser.CanCreateOrganization}}
|
||||||
|
<a class="item" href="{{AppSubUrl}}/org/create">
|
||||||
|
<i class="fitted octicon octicon-organization"></i> {{.i18n.Tr "new_org"}}
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
</div><!-- end content create new menu -->
|
||||||
|
</div><!-- end dropdown menu create new -->
|
||||||
|
|
||||||
|
<div class="ui dropdown jump item poping up" tabindex="-1" data-content="{{.i18n.Tr "user_profile_and_more"}}" data-variation="tiny inverted">
|
||||||
|
<span class="text">
|
||||||
|
<img class="ui tiny avatar image" src="{{.SignedUser.RelAvatarLink}}">
|
||||||
|
<span class="sr-only">{{.i18n.Tr "user_profile_and_more"}}</span>
|
||||||
|
<span class="mobile-only">{{.SignedUser.Name}}</span>
|
||||||
|
<i class="fitted octicon octicon-triangle-down not-mobile" tabindex="-1"></i>
|
||||||
|
</span>
|
||||||
|
<div class="menu user-menu" tabindex="-1">
|
||||||
|
<div class="ui header">
|
||||||
|
{{.i18n.Tr "signed_in_as"}} <strong>{{.SignedUser.Name}}</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="divider"></div>
|
||||||
|
<a class="item" href="{{AppSubUrl}}/{{.SignedUser.Name}}">
|
||||||
|
<i class="octicon octicon-person"></i>
|
||||||
|
{{.i18n.Tr "your_profile"}}<!-- Your profile -->
|
||||||
|
</a>
|
||||||
|
<a class="item" href="{{AppSubUrl}}/{{.SignedUser.Name}}?tab=stars">
|
||||||
|
<i class="octicon octicon-star"></i>
|
||||||
|
{{.i18n.Tr "your_starred"}}
|
||||||
|
</a>
|
||||||
|
<a class="{{if .PageIsUserSettings}}active{{end}} item" href="{{AppSubUrl}}/user/settings">
|
||||||
|
<i class="octicon octicon-settings"></i>
|
||||||
|
{{.i18n.Tr "your_settings"}}<!-- Your settings -->
|
||||||
|
</a>
|
||||||
|
<a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">
|
||||||
|
<i class="octicon octicon-question"></i>
|
||||||
|
{{.i18n.Tr "help"}}<!-- Help -->
|
||||||
|
</a>
|
||||||
|
{{if .IsAdmin}}
|
||||||
|
<div class="divider"></div>
|
||||||
|
|
||||||
|
<a class="{{if .PageIsAdmin}}active{{end}} item" href="{{AppSubUrl}}/admin">
|
||||||
|
<i class="icon settings"></i>
|
||||||
|
{{.i18n.Tr "admin_panel"}}<!-- Admin Panel -->
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
<div class="divider"></div>
|
||||||
|
<a class="item" href="{{AppSubUrl}}/user/logout">
|
||||||
|
<i class="octicon octicon-sign-out"></i>
|
||||||
|
{{.i18n.Tr "sign_out"}}<!-- Sign Out -->
|
||||||
|
</a>
|
||||||
|
</div><!-- end content avatar menu -->
|
||||||
|
</div><!-- end dropdown avatar menu -->
|
||||||
|
</div><!-- end signed user right menu -->
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
|
||||||
|
<div class="right stackable menu">
|
||||||
|
{{if .ShowRegistrationButton}}
|
||||||
|
<a class="item{{if .PageIsSignUp}} active{{end}}" href="{{AppSubUrl}}/user/sign_up">
|
||||||
|
<i class="octicon octicon-person"></i> {{.i18n.Tr "register"}}
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
|
<a class="item{{if .PageIsSignIn}} active{{end}}" href="{{AppSubUrl}}/user/login?redirect_to={{.Link}}">
|
||||||
|
<i class="octicon octicon-sign-in"></i> {{.i18n.Tr "sign_in"}}
|
||||||
|
</a>
|
||||||
|
</div><!-- end anonymous right menu -->
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
</div>
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
- name: Reread service config
|
||||||
|
command: supervisorctl reread
|
||||||
|
|
||||||
|
- name: Restart Gitea
|
||||||
|
supervisorctl:
|
||||||
|
name: gitea
|
||||||
|
state: restarted
|
@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
- name: Add Git domain to Uberspace config
|
||||||
|
import_role:
|
||||||
|
name: snapstromegon.uberspace_web_domain
|
||||||
|
vars:
|
||||||
|
domain: git.codesignd.com
|
||||||
|
|
||||||
|
- name: Copy config to home directory
|
||||||
|
copy:
|
||||||
|
src: home/
|
||||||
|
dest: "{{ ansible_env.HOME }}/"
|
||||||
|
mode: preserve
|
||||||
|
tags: gitea-update
|
||||||
|
notify: Restart Gitea
|
||||||
|
|
||||||
|
- name: Copy service config
|
||||||
|
template:
|
||||||
|
src: service.ini.j2
|
||||||
|
dest: "{{ ansible_env.HOME }}/etc/services.d/gitea.ini"
|
||||||
|
notify: Reread service config
|
||||||
|
|
||||||
|
- name: Copy app config
|
||||||
|
template:
|
||||||
|
src: app.ini.j2
|
||||||
|
dest: "{{ ansible_env.HOME }}/gitea/custom/conf/app.ini"
|
||||||
|
tags: gitea-update
|
||||||
|
notify: Restart Gitea
|
||||||
|
|
||||||
|
- name: Configure web backend
|
||||||
|
import_role:
|
||||||
|
name: snapstromegon.uberspace_web_backend
|
||||||
|
vars:
|
||||||
|
route: git.codesignd.com
|
||||||
|
http:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
- name: Set up Gitea Homebrew tap
|
||||||
|
homebrew_tap:
|
||||||
|
name: gitea/tap
|
||||||
|
url: https://gitea.com/gitea/homebrew-gitea.git
|
||||||
|
|
||||||
|
- name: Install and update Gitea
|
||||||
|
homebrew:
|
||||||
|
name: gitea
|
||||||
|
state: latest
|
||||||
|
notify: Restart Gitea
|
||||||
|
tags: gitea-update
|
@ -0,0 +1,73 @@
|
|||||||
|
; Config last updated based on:
|
||||||
|
; commit: bcb722daec4bdd45303da97173a2b8a3c4c95dcd
|
||||||
|
; date: 2020-01-19
|
||||||
|
|
||||||
|
APP_NAME = codesignd Git
|
||||||
|
RUN_USER = {{ ansible_user_id }}
|
||||||
|
RUN_MODE = prod
|
||||||
|
|
||||||
|
; Server settings
|
||||||
|
; ===============
|
||||||
|
|
||||||
|
[server]
|
||||||
|
PROTOCOL = http
|
||||||
|
DOMAIN = git.codesignd.com
|
||||||
|
HTTP_PORT = 8080
|
||||||
|
ROOT_URL = https://%(DOMAIN)s/
|
||||||
|
SSH_PORT = 22
|
||||||
|
OFFLINE_MODE = true
|
||||||
|
ENABLE_GZIP = true
|
||||||
|
LANDING_PAGE = explore
|
||||||
|
|
||||||
|
[security]
|
||||||
|
INSTALL_LOCK = true
|
||||||
|
SECRET_KEY = {{ git_secret_key }}
|
||||||
|
INTERNAL_TOKEN = {{ git_internal_token }}
|
||||||
|
PASSWORD_COMPLEXITY = off
|
||||||
|
|
||||||
|
[oauth2]
|
||||||
|
JWT_SECRET = {{ git_jwt_secret }}
|
||||||
|
|
||||||
|
; Paths
|
||||||
|
; =====
|
||||||
|
|
||||||
|
[database]
|
||||||
|
DB_TYPE = sqlite3
|
||||||
|
PATH = /home/%(RUN_USER)s/gitea/data/gitea.db
|
||||||
|
|
||||||
|
[repository]
|
||||||
|
ROOT = /home/%(RUN_USER)s/gitea/repos
|
||||||
|
|
||||||
|
; Functionality settings
|
||||||
|
; ======================
|
||||||
|
|
||||||
|
[admin]
|
||||||
|
DISABLE_REGULAR_ORG_CREATION = true
|
||||||
|
|
||||||
|
[log]
|
||||||
|
MODE = file
|
||||||
|
LEVEL = Info
|
||||||
|
|
||||||
|
[mailer]
|
||||||
|
ENABLED = true
|
||||||
|
FROM = %(APP_NAME)s <git@codesignd.com>
|
||||||
|
MAILER_TYPE = sendmail
|
||||||
|
|
||||||
|
[service]
|
||||||
|
DISABLE_REGISTRATION = true
|
||||||
|
ENABLE_NOTIFY_MAIL = true
|
||||||
|
NO_REPLY_ADDRESS = noreply.codesignd.com
|
||||||
|
|
||||||
|
[session]
|
||||||
|
COOKIE_SECURE = true
|
||||||
|
|
||||||
|
; Branding
|
||||||
|
; ========
|
||||||
|
|
||||||
|
[ui]
|
||||||
|
THEME_COLOR_META_TAG = `#eb8e2e`
|
||||||
|
|
||||||
|
[other]
|
||||||
|
SHOW_FOOTER_BRANDING = false
|
||||||
|
SHOW_FOOTER_VERSION = false
|
||||||
|
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
|
@ -0,0 +1,5 @@
|
|||||||
|
[program:gitea]
|
||||||
|
command={{ ansible_env.HOME }}/.linuxbrew/bin/gitea web
|
||||||
|
environment=GITEA_WORK_DIR={{ ansible_env.HOME }}/gitea
|
||||||
|
autostart=yes
|
||||||
|
autorestart=yes
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
- name: Opt out from Homebrew analytics
|
||||||
|
command: ~/.linuxbrew/bin/brew analytics off
|
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Install Homebrew
|
||||||
|
git:
|
||||||
|
repo: "https://github.com/Homebrew/brew.git"
|
||||||
|
version: master
|
||||||
|
dest: "{{ ansible_env.HOME }}/.linuxbrew"
|
||||||
|
notify: Opt out from Homebrew analytics
|
||||||
|
|
||||||
|
- name: Install Homebrew formulae
|
||||||
|
homebrew:
|
||||||
|
name: "{{ homebrew_formulae }}"
|
||||||
|
state: latest
|
||||||
|
path: "{{ ansible_env.HOME}}/.linuxbrew/bin"
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: Add host domain to Uberspace config
|
||||||
|
import_role:
|
||||||
|
name: snapstromegon.uberspace_web_domain
|
||||||
|
vars:
|
||||||
|
domain: kodos-{{ ansible_user_id }}.codesignd.net
|
||||||
|
|
||||||
|
- name: Set up host site
|
||||||
|
template:
|
||||||
|
src: index.html.j2
|
||||||
|
dest: /var/www/virtual/{{ ansible_user_id }}/html/index.html
|
@ -0,0 +1,127 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<title>kodos-{{ ansible_user_id }}.codesignd.net</title>
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Reset */
|
||||||
|
html {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
*, *::before, *::after {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
box-sizing: inherit;
|
||||||
|
|
||||||
|
text-decoration: none;
|
||||||
|
list-style: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Container styling */
|
||||||
|
html {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
|
background: #efefef;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-width: 20rem;
|
||||||
|
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 0 10px #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 25rem) {
|
||||||
|
html {
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
|
background: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-width: initial;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 1rem;
|
||||||
|
|
||||||
|
box-shadow: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
border-top: 2px dotted #efefef;
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* General Typography */
|
||||||
|
:root {
|
||||||
|
font-family: system-ui, sans-serif;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.2;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 span {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 8rem;
|
||||||
|
height: 8rem;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cog {
|
||||||
|
animation: rotate 30s linear infinite;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
}
|
||||||
|
@keyframes rotate {
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #ed8f1b;
|
||||||
|
}
|
||||||
|
footer a:not(:last-child) {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<svg viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg"><g fill="none"><path class="cog" d="M475.28 853.557L408.45 999.43a503.966 503.966 0 0 1-78.883-21.084l15.057-159.725a354.034 354.034 0 0 1-42.828-24.777l-130.73 92.853a510.782 510.782 0 0 1-57.761-57.762l92.853-130.729a354.034 354.034 0 0 1-24.777-42.828L21.655 670.434A503.967 503.967 0 0 1 .57 591.55l145.872-66.831a359.603 359.603 0 0 1-.85-24.72c0-8.31.287-16.553.85-24.72L.57 408.45a503.966 503.966 0 0 1 21.084-78.883l159.725 15.057a354.034 354.034 0 0 1 24.777-42.828l-92.853-130.73a510.782 510.782 0 0 1 57.762-57.761l130.729 92.853a354.034 354.034 0 0 1 42.828-24.777L329.566 21.655A503.967 503.967 0 0 1 408.45.57l66.831 145.872a359.404 359.404 0 0 1 49.44 0L591.55.57a503.966 503.966 0 0 1 78.883 21.084L655.377 181.38a354.034 354.034 0 0 1 42.828 24.777l130.73-92.853a510.782 510.782 0 0 1 57.761 57.762l-92.853 130.729a354.034 354.034 0 0 1 24.777 42.828l159.725-15.057a503.967 503.967 0 0 1 21.084 78.883L853.557 475.28a359.404 359.404 0 0 1 0 49.44l145.873 66.83a503.966 503.966 0 0 1-21.084 78.883L818.62 655.377a354.034 354.034 0 0 1-24.777 42.828l92.853 130.73a510.782 510.782 0 0 1-57.762 57.761l-130.729-92.853a354.034 354.034 0 0 1-42.828 24.777l15.057 159.725a503.967 503.967 0 0 1-78.883 21.084L524.72 853.557a359.404 359.404 0 0 1-49.44 0zM787.356 500c0-158.703-128.653-287.356-287.356-287.356S212.644 341.297 212.644 500 341.297 787.356 500 787.356 787.356 658.703 787.356 500z" fill="#F4B971"/><path stroke="#0BB888" stroke-width="57.471" d="M500 346.743l132.724 76.629v153.256L500 653.257l-132.724-76.629V423.372z"/><circle stroke="#ED8F1B" stroke-width="118.774" cx="500.001" cy="500" r="318.008"/></g></svg>
|
||||||
|
<h1><span>kodos-{{ ansible_user_id }}</span>.codesignd.net</h1>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<a href="https://codesignd.com/contact">Contact</a>
|
||||||
|
<a href="https://codesignd.com/legal">Imprint</a>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- name: Set up email redirect
|
||||||
|
copy:
|
||||||
|
content: "{{ mail_redirect_to }}"
|
||||||
|
dest: "{{ ansible_env.HOME }}/.qmail"
|
||||||
|
|
||||||
|
- name: Delete catch-all address and local Maildirs
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- "{{ ansible_env.HOME }}/.spamfolder"
|
||||||
|
- "{{ ansible_env.HOME }}/.qmail-default"
|
||||||
|
- "{{ ansible_env.HOME }}/Maildir"
|
||||||
|
- "{{ ansible_env.HOME }}/users"
|
@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
- name: Read existing Uberspace domains
|
||||||
|
command: uberspace mail domain list
|
||||||
|
register: uberspace_mail_domain_result
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Add configured domains to Uberspace config
|
||||||
|
shell: "uberspace mail domain add $(idn {{ item }})"
|
||||||
|
when: item not in uberspace_mail_domain_result.stdout_lines
|
||||||
|
loop: "{{ mail_domains.get(ansible_user_id, []) }}"
|
||||||
|
|
||||||
|
- name: Delete system Maildir
|
||||||
|
file:
|
||||||
|
path: "{{ ansible_env.HOME }}/Maildir"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Set up local mail user
|
||||||
|
import_role:
|
||||||
|
name: snapstromegon.uberspace_mail_user
|
||||||
|
vars:
|
||||||
|
user: lukas
|
||||||
|
password: "{{ mail_password }}"
|
||||||
|
|
||||||
|
- name: Enable catchall mode
|
||||||
|
import_role:
|
||||||
|
name: snapstromegon.uberspace_mail_catchall
|
||||||
|
vars:
|
||||||
|
user: lukas
|
||||||
|
|
||||||
|
- name: Create qdated key
|
||||||
|
command:
|
||||||
|
cmd: qdated-makekey
|
||||||
|
creates: "{{ ansible_env.HOME }}/.qdated-key"
|
||||||
|
|
||||||
|
- name: Read qdated key
|
||||||
|
slurp:
|
||||||
|
src: "{{ ansible_env.HOME }}/.qdated-key"
|
||||||
|
register: qdated_key
|
||||||
|
no_log: yes
|
||||||
|
|
||||||
|
- name: Register qdated key as fact
|
||||||
|
set_fact:
|
||||||
|
qdated_key: "{{ qdated_key.content | b64decode }}"
|
||||||
|
no_log: yes
|
||||||
|
|
||||||
|
- name: Set up .qmail-dated-default file
|
||||||
|
template:
|
||||||
|
src: qmail-dated.j2
|
||||||
|
dest: "{{ ansible_env.HOME }}/.qmail-dated-default"
|
||||||
|
|
||||||
|
- name: Create mutt config directory
|
||||||
|
file:
|
||||||
|
path: "{{ ansible_env.HOME }}/.mutt"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Set up mutt config
|
||||||
|
template:
|
||||||
|
src: muttrc.j2
|
||||||
|
dest: "{{ ansible_env.HOME }}/.mutt/muttrc"
|
@ -0,0 +1,32 @@
|
|||||||
|
# We use Maildirs, not Mailboxes
|
||||||
|
set mbox_type=Maildir
|
||||||
|
|
||||||
|
# Cache headers
|
||||||
|
set header_cache=~/.cache/mutt_header_cache
|
||||||
|
|
||||||
|
# Directory setup
|
||||||
|
set folder="~/users/lukas"
|
||||||
|
set spoolfile="+/"
|
||||||
|
set record="+.Sent"
|
||||||
|
set postponed="+.Drafts"
|
||||||
|
|
||||||
|
# Load IMAP folders as mailboxes
|
||||||
|
mailboxes `echo -n "+ "; find ${maildir:-~/users/lukas} -maxdepth 1 -type d -name ".*" -printf "+'%f' "`
|
||||||
|
macro index c "<change-folder>?<toggle-mailboxes>" "open a different folder"
|
||||||
|
macro pager c "<change-folder>?<toggle-mailboxes>" "open a different folder"
|
||||||
|
|
||||||
|
# Sender
|
||||||
|
set from="Lukas Bestle <{{ mail_default_address[ansible_user_id] }}>"
|
||||||
|
|
||||||
|
# Sorting
|
||||||
|
set sort=threads
|
||||||
|
set sort_aux=date-sent
|
||||||
|
|
||||||
|
# Better Umlaut support
|
||||||
|
unset allow_8bit
|
||||||
|
|
||||||
|
# Display formats
|
||||||
|
set mask="!^\\.[^.]"
|
||||||
|
set date_format="%a, %d. %b %H:%M"
|
||||||
|
set index_format="%3C %Z %D %-25.25F (%?l?%4l&%4c?) %s"
|
||||||
|
set folder_format="%2C %t %d %t %f"
|
@ -0,0 +1,3 @@
|
|||||||
|
# Email address is valid for 7 days
|
||||||
|
|~/.linuxbrew/bin/qdated-check 604800
|
||||||
|
{{ ansible_user_id }}-lukas
|
@ -0,0 +1,4 @@
|
|||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFi5drlM5Uli7GbTZFiKPKnG8RmOyS2eu3c6XkwwJiSk luX@smithers.codesignd.net
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOBEksH8LMO5jf1QsMH3yRdxSmY2XPk8CH9HNsWfsXVt luX@bart.codesignd.net
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIETsPbHqAta4E6j9pm/9E4lLurlPoh+p5zOWiZ9GS5ml luX@maggie.codesignd.net
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG9J5FMq9ttUcnuqWhYsiKVuols5uD2Ddv7L3Z93nD2W luX@homer.codesignd.net
|
@ -0,0 +1,60 @@
|
|||||||
|
###
|
||||||
|
# Loader for Oh My Fish! packages
|
||||||
|
# Loads all packages stored in ~/.config/fish/pkgs/
|
||||||
|
#
|
||||||
|
# Inspired by https://github.com/jorgebucaran/fisher
|
||||||
|
###
|
||||||
|
|
||||||
|
set -q pkgs_path; or set -g pkgs_path ~/.config/fish/pkgs
|
||||||
|
|
||||||
|
# also search for functions/completions/binaries/manpages within packages
|
||||||
|
set fish_function_path $fish_function_path[1] $pkgs_path/.functions $pkgs_path/*/functions $fish_function_path[2..-1]
|
||||||
|
set fish_complete_path $fish_complete_path[1] $pkgs_path/*/completions $fish_complete_path[2..-1]
|
||||||
|
set -x PATH $pkgs_path/*/bin $PATH
|
||||||
|
set -x MANPATH $pkgs_path/*/man $MANPATH
|
||||||
|
|
||||||
|
# load package key bindings when needed
|
||||||
|
if functions -q fish_user_key_bindings
|
||||||
|
functions -c fish_user_key_bindings fish_user_key_bindings_copy
|
||||||
|
end
|
||||||
|
function fish_user_key_bindings
|
||||||
|
for file in $pkgs_path/*/key_bindings.fish
|
||||||
|
builtin source $file 2>&1 > /dev/null
|
||||||
|
end
|
||||||
|
if functions -q fish_user_key_bindings_copy
|
||||||
|
fish_user_key_bindings_copy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# load custom config from packages
|
||||||
|
for file in $pkgs_path/*/conf.d/*.fish $pkgs_path/*/init.fish
|
||||||
|
builtin source $file 2> /dev/null
|
||||||
|
end
|
||||||
|
|
||||||
|
# ensure that the prompt is loaded (doesn't autoload for some reason)
|
||||||
|
if test -f $pkgs_path/.functions/fish_prompt.fish
|
||||||
|
builtin source $pkgs_path/.functions/fish_prompt.fish 2> /dev/null
|
||||||
|
end
|
||||||
|
|
||||||
|
# collect all functions on the top-level of packages into $pkgs_path/.functions
|
||||||
|
# (run by Ansible after packages have been updated)
|
||||||
|
function _pkgs_collect_functions
|
||||||
|
# clear the functions directory as we rebuild it from scratch
|
||||||
|
if test -d $pkgs_path/.functions
|
||||||
|
command rm -rf $pkgs_path/.functions
|
||||||
|
end
|
||||||
|
command mkdir -p $pkgs_path/.functions
|
||||||
|
|
||||||
|
# consider all fish files in the top-level of each package
|
||||||
|
for src in $pkgs_path/*/*.fish
|
||||||
|
set -l package (command basename (command dirname $src))
|
||||||
|
set -l filename (command basename $src)
|
||||||
|
|
||||||
|
# we don't care about uninstall.fish;
|
||||||
|
# init.fish and key_bindings.fish are dynamically handled on runtime above
|
||||||
|
if not contains $filename {init,key_bindings,uninstall}.fish
|
||||||
|
# create a relative symlink
|
||||||
|
command ln -sf ../$package/$filename $pkgs_path/.functions/$filename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,46 @@
|
|||||||
|
# Environment variables
|
||||||
|
# ---------------------
|
||||||
|
|
||||||
|
set -x PATH $HOME/bin \
|
||||||
|
$HOME/.composer/vendor/bin \
|
||||||
|
$HOME/.local/bin \
|
||||||
|
$HOME/.linuxbrew/bin \
|
||||||
|
$PATH
|
||||||
|
|
||||||
|
set -x MANPATH $HOME/.linuxbrew/share/man \
|
||||||
|
$MANPATH
|
||||||
|
|
||||||
|
# language
|
||||||
|
set -x LANG de_DE.UTF-8
|
||||||
|
|
||||||
|
# editor
|
||||||
|
set -x VISUAL "$HOME/.config/fish/pkgs/rmate/rmate -p 64364 -w" # Visual Studio Code (wait mode)
|
||||||
|
set -x EDITOR 'nano -w' # nano as fallback editor
|
||||||
|
|
||||||
|
set -x XDG_CONFIG_HOME $HOME/.config
|
||||||
|
|
||||||
|
# Aliases
|
||||||
|
# -------
|
||||||
|
|
||||||
|
# Edit file remotely with VS Code
|
||||||
|
alias code="$HOME/.config/fish/pkgs/rmate/rmate -p 64364"
|
||||||
|
|
||||||
|
# Short ls command
|
||||||
|
alias l='ls -la'
|
||||||
|
|
||||||
|
# General Settings
|
||||||
|
# ----------------
|
||||||
|
|
||||||
|
# enforce 24-bit color mode
|
||||||
|
# (the requried env var is not transmitted via SSH)
|
||||||
|
set -x COLORTERM truecolor
|
||||||
|
set -g fish_term24bit 1
|
||||||
|
|
||||||
|
# settings for the bobthefish theme
|
||||||
|
set -g fish_prompt_pwd_dir_length 0
|
||||||
|
set -g theme_color_scheme solarized-dark
|
||||||
|
set -g theme_date_format '+%a %d.%m.%y %H:%M:%S'
|
||||||
|
set -g theme_display_git_master_branch yes
|
||||||
|
set -g theme_show_exit_status yes
|
||||||
|
set -g theme_title_use_abbreviated_path no
|
||||||
|
set -x VIRTUAL_ENV_DISABLE_PROMPT 1
|
@ -0,0 +1,3 @@
|
|||||||
|
function fish_greeting
|
||||||
|
welcome
|
||||||
|
end
|
@ -0,0 +1,21 @@
|
|||||||
|
###
|
||||||
|
# Looks up the IPv4 address of the given hostname and tries to find the reverse record of that IP
|
||||||
|
#
|
||||||
|
# Globals:
|
||||||
|
# None
|
||||||
|
# Arguments:
|
||||||
|
# $domain string Hostname to look up
|
||||||
|
# Returns:
|
||||||
|
# None
|
||||||
|
###
|
||||||
|
function nsreverse
|
||||||
|
# lookup IP
|
||||||
|
set ip (dig "$argv[1]" A +short); or return 1
|
||||||
|
|
||||||
|
# lookup reverse record
|
||||||
|
set reverse (dig -x "$ip" +short); or return 1
|
||||||
|
|
||||||
|
# output
|
||||||
|
echo -e "\033[1mIPv4: \033[0;34m $ip\033[0m"
|
||||||
|
echo -e "\033[1mReverse lookup:\033[0;34m $reverse\033[0m"
|
||||||
|
end
|
@ -0,0 +1,21 @@
|
|||||||
|
###
|
||||||
|
# Looks up the IPv6 address of the given hostname and tries to find the reverse record of that IP
|
||||||
|
#
|
||||||
|
# Globals:
|
||||||
|
# None
|
||||||
|
# Arguments:
|
||||||
|
# $domain string Hostname to look up
|
||||||
|
# Returns:
|
||||||
|
# None
|
||||||
|
###
|
||||||
|
function nsreverse6
|
||||||
|
# lookup IP
|
||||||
|
set ip (dig "$argv[1]" AAAA +short); or return 1
|
||||||
|
|
||||||
|
# lookup reverse record
|
||||||
|
set reverse (dig -x "$ip" +short); or return 1
|
||||||
|
|
||||||
|
# output
|
||||||
|
echo -e "\033[1mIPv6: \033[0;34m $ip\033[0m"
|
||||||
|
echo -e "\033[1mReverse lookup:\033[0;34m $reverse\033[0m"
|
||||||
|
end
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,6 @@
|
|||||||
|
function dateSummarizer() {
|
||||||
|
echo -n "\033[34m"
|
||||||
|
date
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSummarizer "Date" dateSummarizer
|
@ -0,0 +1,111 @@
|
|||||||
|
function uptimeSummarizer() {
|
||||||
|
# Get the uptime in seconds depending on the kernel
|
||||||
|
if [[ "$(uname -s)" == 'Darwin' ]]; then
|
||||||
|
# OS X
|
||||||
|
# kern.boottime is an absolute timestamp
|
||||||
|
bootTime="$(sysctl -n kern.boottime | awk '{print $4}' | sed 's/,//g')"
|
||||||
|
currentTime="$(date +%s)"
|
||||||
|
uptime="$(($currentTime - $bootTime))"
|
||||||
|
elif [[ -f /proc/uptime ]]; then
|
||||||
|
# Linux
|
||||||
|
uptime="$(cat /proc/uptime)"
|
||||||
|
uptime="${uptime%%.*}"
|
||||||
|
else
|
||||||
|
# We don't have a handler for that
|
||||||
|
# If you need one, please create an issue at
|
||||||
|
# https://github.com/lukasbestle/my-welcome/issues
|
||||||
|
echo "\033[31mUnsupported environment, can't get uptime. :(\033[0m"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse into units
|
||||||
|
seconds="$((uptime % 60))"
|
||||||
|
minutes="$((uptime / 60 % 60))"
|
||||||
|
hours="$(( uptime / 60 / 60 % 24))"
|
||||||
|
days="$(( uptime / 60 / 60 / 24 % 30))"
|
||||||
|
months="$(( uptime / 60 / 60 / 24 / 30 % 12))"
|
||||||
|
years="$(( uptime / 60 / 60 / 24 / 30 / 12))"
|
||||||
|
|
||||||
|
# Output depending on the scale of the uptime
|
||||||
|
if [[ years -ge 1 ]]; then
|
||||||
|
outputYears=true
|
||||||
|
outputMonths=true
|
||||||
|
outputDays=true
|
||||||
|
elif [[ months -ge 1 ]]; then
|
||||||
|
outputMonths=true
|
||||||
|
outputDays=true
|
||||||
|
elif [[ days -ge 1 ]]; then
|
||||||
|
outputDays=true
|
||||||
|
outputHours=true
|
||||||
|
outputMinutes=true
|
||||||
|
elif [[ hours -ge 1 ]]; then
|
||||||
|
outputHours=true
|
||||||
|
outputMinutes=true
|
||||||
|
elif [[ minutes -ge 1 ]]; then
|
||||||
|
outputMinutes=true
|
||||||
|
outputSeconds=true
|
||||||
|
else
|
||||||
|
outputSeconds=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Output each element
|
||||||
|
output=''
|
||||||
|
if [[ "$outputYears" == true ]]; then
|
||||||
|
output+="\033[34m$years"
|
||||||
|
if [[ "$years" == 1 ]]; then
|
||||||
|
output+=' year\033[0m\n'
|
||||||
|
else
|
||||||
|
output+=' years\033[0m\n'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$outputMonths" == true ]]; then
|
||||||
|
output+="\033[34m$months"
|
||||||
|
if [[ "$months" == 1 ]]; then
|
||||||
|
output+=' month\033[0m\n'
|
||||||
|
else
|
||||||
|
output+=' months\033[0m\n'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$outputDays" == true ]]; then
|
||||||
|
output+="\033[34m$days"
|
||||||
|
if [[ "$days" == 1 ]]; then
|
||||||
|
output+=' day\033[0m\n'
|
||||||
|
else
|
||||||
|
output+=' days\033[0m\n'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$outputHours" == true ]]; then
|
||||||
|
output+="\033[34m$hours"
|
||||||
|
if [[ "$hours" == 1 ]]; then
|
||||||
|
output+=' hour\033[0m\n'
|
||||||
|
else
|
||||||
|
output+=' hours\033[0m\n'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$outputMinutes" == true ]]; then
|
||||||
|
output+="\033[34m$minutes"
|
||||||
|
if [[ "$minutes" == 1 ]]; then
|
||||||
|
output+=' minute\033[0m\n'
|
||||||
|
else
|
||||||
|
output+=' minutes\033[0m\n'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$outputSeconds" == true ]]; then
|
||||||
|
output+="\033[34m$seconds"
|
||||||
|
if [[ "$seconds" == 1 ]]; then
|
||||||
|
output+=' second\033[0m\n'
|
||||||
|
else
|
||||||
|
output+=' seconds\033[0m\n'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Replace newlines with a comma
|
||||||
|
echo "Host up for $(echo -ne "$output" | paste -s -d ';' - | sed "s/\;/\, /g")"
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSummarizer "Uptime" uptimeSummarizer
|
@ -0,0 +1,12 @@
|
|||||||
|
function quotaSummarizer() {
|
||||||
|
# Get current quota information in MB (integers) and % of total
|
||||||
|
quota_used=$(quota -lgs | grep '/dev/' | sed 's/ \/dev\/[a-z]\+[0-9] \+\([0-9]\+\?\)M.*/\1/')
|
||||||
|
quota_total=$(quota -lgs | grep '/dev/' | sed 's/ \/dev\/[a-z]\+[0-9] \+[0-9]\+\?M \+\([0-9]\+\?\)M.*/\1/')
|
||||||
|
quota_free=$(( $quota_total - $quota_used ))
|
||||||
|
quota_percentage=$(( $quota_used * 100 / $quota_total ))
|
||||||
|
|
||||||
|
echo "Used \033[34m$quota_used MB\033[0m of \033[34m$quota_total MB\033[0m (\033[34m$quota_percentage %\033[0m)"
|
||||||
|
echo -n "\033[34m$quota_free MB\033[0m available"
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSummarizer "Quota" quotaSummarizer
|
@ -0,0 +1,8 @@
|
|||||||
|
function ramSummarizer() {
|
||||||
|
# Get current RAM usage in MB (integer)
|
||||||
|
ram_used=$(ps -u $USER -o rss= | awk '{rss += $1} END {printf("%0.f", rss / 1000)}')
|
||||||
|
|
||||||
|
echo -n "Used \033[34m$ram_used MB\033[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
registerSummarizer "RAM" ramSummarizer
|
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
- name: Collect fish functions from packages
|
||||||
|
command: fish -c _pkgs_collect_functions
|
@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
- name: Set authorized SSH keys
|
||||||
|
authorized_key:
|
||||||
|
user: "{{ ansible_user_id }}"
|
||||||
|
state: present
|
||||||
|
key: "{{ item }}"
|
||||||
|
with_file: authorized_keys
|
||||||
|
|
||||||
|
- name: Get current shell
|
||||||
|
shell: "getent passwd {{ ansible_user_id }} | cut -d: -f7"
|
||||||
|
register: current_shell
|
||||||
|
changed_when: no
|
||||||
|
|
||||||
|
- name: Change shell to fish
|
||||||
|
command: chsh --shell /usr/bin/fish
|
||||||
|
when: "current_shell.stdout != '/usr/bin/fish'"
|
||||||
|
|
||||||
|
- name: Copy dotfiles to home directory
|
||||||
|
copy:
|
||||||
|
src: dotfiles/
|
||||||
|
dest: "{{ ansible_env.HOME }}/"
|
||||||
|
mode: preserve
|
||||||
|
|
||||||
|
- name: Copy Git config to home directory
|
||||||
|
template:
|
||||||
|
src: gitconfig.j2
|
||||||
|
dest: "{{ ansible_env.HOME }}/.config/git/config"
|
||||||
|
|
||||||
|
- name: Remove unneeded files
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- "{{ ansible_env.HOME }}/.bash_history"
|
||||||
|
- "{{ ansible_env.HOME }}/.bash_logout"
|
||||||
|
- "{{ ansible_env.HOME }}/.bash_profile"
|
||||||
|
- "{{ ansible_env.HOME }}/.bashrc"
|
||||||
|
- "{{ ansible_env.HOME }}/.emacs"
|
||||||
|
- "{{ ansible_env.HOME }}/.zcompdump"
|
||||||
|
- "{{ ansible_env.HOME }}/.zshrc"
|
||||||
|
|
||||||
|
- name: Download and update iTerm2 shell integration
|
||||||
|
get_url:
|
||||||
|
url: https://iterm2.com/shell_integration/fish
|
||||||
|
dest: "{{ ansible_env.HOME }}/.config/fish/conf.d/iterm2_integration.fish"
|
||||||
|
force: yes
|
||||||
|
|
||||||
|
- name: Download and update Oh My Fish! packages
|
||||||
|
git:
|
||||||
|
repo: "{{ item.value }}"
|
||||||
|
dest: "{{ ansible_env.HOME }}/.config/fish/pkgs/{{ item.key }}"
|
||||||
|
loop: "{{ omf_pkgs | dict2items }}"
|
||||||
|
notify: Collect fish functions from packages
|
||||||
|
|
||||||
|
- name: Disable Cron MAILTO
|
||||||
|
cronvar:
|
||||||
|
name: MAILTO
|
||||||
|
value: ""
|
@ -0,0 +1,17 @@
|
|||||||
|
; user settings
|
||||||
|
[user]
|
||||||
|
name = kodos-{{ ansible_user_id }}.codesignd.net
|
||||||
|
email = hostmaster@codesignd.net
|
||||||
|
|
||||||
|
; core settings
|
||||||
|
[advice]
|
||||||
|
detachedHead = false
|
||||||
|
[branch]
|
||||||
|
autoSetupRebase = always
|
||||||
|
[core]
|
||||||
|
editor = code -w
|
||||||
|
quotepath = false
|
||||||
|
[help]
|
||||||
|
autocorrect = 10
|
||||||
|
[push]
|
||||||
|
default = upstream
|
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
for host in ~/.config/qdated/*; do
|
||||||
|
HOME="$host" qdated-now > "$host/current"
|
||||||
|
done
|
@ -0,0 +1,102 @@
|
|||||||
|
---
|
||||||
|
- name: Copy config to home directory
|
||||||
|
copy:
|
||||||
|
src: home/
|
||||||
|
dest: "{{ ansible_env.HOME }}/"
|
||||||
|
mode: preserve
|
||||||
|
|
||||||
|
- name: Create link at ~/web
|
||||||
|
file:
|
||||||
|
src: /var/www/virtual/{{ ansible_user_id }}
|
||||||
|
dest: "{{ ansible_env.HOME }}/web"
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Initialize ~/web/sites
|
||||||
|
file:
|
||||||
|
path: /var/www/virtual/{{ ansible_user_id }}/sites
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Download and update projectr
|
||||||
|
git:
|
||||||
|
repo: https://github.com/lukasbestle/projectr.git
|
||||||
|
dest: "{{ ansible_env.HOME }}/.config/fish/pkgs/projectr"
|
||||||
|
|
||||||
|
- name: Set up deploy script
|
||||||
|
template:
|
||||||
|
src: deploy.php.j2
|
||||||
|
dest: /var/www/virtual/{{ ansible_user_id }}/html/deploy.php
|
||||||
|
|
||||||
|
- name: Read existing Uberspace domains
|
||||||
|
command: uberspace web domain list
|
||||||
|
register: uberspace_web_domain_result
|
||||||
|
changed_when: no
|
||||||
|
|
||||||
|
- name: Add configured domains to Uberspace config
|
||||||
|
shell: "uberspace web domain add $(idn {{ item.key }})"
|
||||||
|
when: item.key not in uberspace_web_domain_result.stdout_lines
|
||||||
|
loop: "{{ web_links.get(ansible_user_id, {}) | dict2items }}"
|
||||||
|
|
||||||
|
- name: Set up sites using projectr
|
||||||
|
command:
|
||||||
|
argv:
|
||||||
|
- site_add
|
||||||
|
- "{{ item.key }}"
|
||||||
|
creates: /var/www/virtual/{{ ansible_user_id }}/sites/{{ item.key }}
|
||||||
|
loop: "{{ web_sites.get(ansible_user_id, {}) | dict2items }}"
|
||||||
|
|
||||||
|
- name: Set up site origins using projectr (sites with origin)
|
||||||
|
command:
|
||||||
|
argv:
|
||||||
|
- site_origin
|
||||||
|
- "{{ item.key }}"
|
||||||
|
- "{{ item.value }}"
|
||||||
|
creates: /var/www/virtual/{{ ansible_user_id }}/sites/{{ item.key }}/.origin
|
||||||
|
loop: "{{ web_sites.get(ansible_user_id, {}) | dict2items }}"
|
||||||
|
when: item.value != None
|
||||||
|
|
||||||
|
- name: Set up site origins using projectr (sites without origin)
|
||||||
|
command:
|
||||||
|
argv:
|
||||||
|
- site_origin
|
||||||
|
- "{{ item.key }}"
|
||||||
|
removes: /var/www/virtual/{{ ansible_user_id }}/sites/{{ item.key }}/.origin
|
||||||
|
loop: "{{ web_sites.get(ansible_user_id, {}) | dict2items }}"
|
||||||
|
when: item.value == None
|
||||||
|
|
||||||
|
- name: Deploy sites using projectr (sites with origin)
|
||||||
|
command:
|
||||||
|
argv:
|
||||||
|
- site_deploy
|
||||||
|
- "{{ item.key }}"
|
||||||
|
creates: /var/www/virtual/{{ ansible_user_id }}/sites/{{ item.key }}/current
|
||||||
|
loop: "{{ web_sites.get(ansible_user_id, {}) | dict2items }}"
|
||||||
|
when: item.value != None
|
||||||
|
|
||||||
|
- name: Link sites to domains
|
||||||
|
command:
|
||||||
|
argv:
|
||||||
|
- site_link
|
||||||
|
- "{{ item.value.site }}"
|
||||||
|
- "{{ item.key }}"
|
||||||
|
- "{{ item.value.get('path', '') }}"
|
||||||
|
creates: /var/www/virtual/{{ ansible_user_id }}/{{ item.key }}
|
||||||
|
loop: "{{ web_links.get(ansible_user_id, {}) | dict2items }}"
|
||||||
|
|
||||||
|
- name: Ensure that qdated directories for all Mail Uberspaces exist
|
||||||
|
file:
|
||||||
|
path: "{{ ansible_env.HOME }}/.config/qdated/{{ hostvars[item].ansible_user_id }}"
|
||||||
|
state: directory
|
||||||
|
loop: "{{ groups.mail }}"
|
||||||
|
|
||||||
|
- name: Copy qdated keys from all Mail Uberspaces
|
||||||
|
copy:
|
||||||
|
content: "{{ hostvars[item].qdated_key }}"
|
||||||
|
dest: "{{ ansible_env.HOME }}/.config/qdated/{{ hostvars[item].ansible_user_id }}/.qdated-key"
|
||||||
|
loop: "{{ groups.mail }}"
|
||||||
|
|
||||||
|
- name: Set up qdated address generation cronjob
|
||||||
|
cron:
|
||||||
|
name: "qdated generation"
|
||||||
|
hour: "2"
|
||||||
|
minute: "3"
|
||||||
|
job: "{{ ansible_env.HOME }}/bin/qdated-generate"
|
@ -0,0 +1,172 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* projectr
|
||||||
|
* Tools for deployments and project management
|
||||||
|
*
|
||||||
|
* Gitea frontend for deployments
|
||||||
|
*
|
||||||
|
* @author Lukas Bestle <project-projectr@lukasbestle.com>
|
||||||
|
* @copyright Copyright 2014 Lukas Bestle
|
||||||
|
* @license MIT
|
||||||
|
* @file webhook.gitea.php
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 1. Configuration
|
||||||
|
// ====================
|
||||||
|
|
||||||
|
// Secret used as authentication (you have to set this in the Gitea project settings as well)
|
||||||
|
// ATTENTION: Make sure this is long and secure, as anyone could checkout any commit of your projects otherwise
|
||||||
|
define('SECRET', '{{ projectr_deploy_secret }}');
|
||||||
|
|
||||||
|
// Path where you installed the scripts from the "bin" directory of this repository
|
||||||
|
// This is required, as PHP doesn't automatically use the environment and therefore your $PATH from your shell
|
||||||
|
define('TOOLKIT_PATH', '/home/{{ ansible_user_id }}/.config/fish/pkgs/projectr/bin');
|
||||||
|
|
||||||
|
// 2. Setup
|
||||||
|
// ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an example webhook for Gitea projects.
|
||||||
|
* It's fairly simple to set this script up on your server/Uberspace, here's how:
|
||||||
|
*
|
||||||
|
* 1. Setup the toolkit, so you can access the tools from your SSH shell (more about that in README.md)
|
||||||
|
* 2. Take a look at the settings above.
|
||||||
|
* 2.1. Seriously, have you set a secret? Yes? Alright.
|
||||||
|
* 3. Place this script in a directory in ~/web/ (something like "~/web/hooks.example.com")
|
||||||
|
* 4. You should now be able to access https://hooks.example.com/webhook.gitea.php
|
||||||
|
* This should output "Web hook event (X-Gitea-Event header) is missing from request.".
|
||||||
|
*
|
||||||
|
* Now you can create projects and let this script deploy them for you:
|
||||||
|
*
|
||||||
|
* 5. If your project is a private repository:
|
||||||
|
* 5.1. Generate an SSH key by using `ssh-keygen`. The default values are alright for this purpose.
|
||||||
|
* 5.2. Copy the contents of `~/.ssh/id_rsa.pub` to your clipboard and add it as "Deploy Key" in your project's Gitea settings interface.
|
||||||
|
* 6. Create the project on the server by running either `project_add <path> <exact HTTPS clone url from Gitea>#<branch to deploy>` or
|
||||||
|
* `site_add <name> <exact HTTPS clone url from Gitea>#<branch to deploy>`.
|
||||||
|
* It's important to use the exact HTTPS url (not the SSH one) so this script can find the project!
|
||||||
|
* 7. Add the URL (the one you tested in 4.) of the script to your project's web hooks (choose the type "Gitea").
|
||||||
|
* Make sure to add the secret configured above and select the "POST" method, the "application/json" type and the "Push Events" trigger.
|
||||||
|
* 8. To test if it everything works, push some code to your Gitea repository.
|
||||||
|
*
|
||||||
|
* Troubleshooting:
|
||||||
|
* - Use `tail -f <path to project>/logs/*.log`. This should tell you what went wrong.
|
||||||
|
* - Check if the TOOLKIT_PATH you set above is correct.
|
||||||
|
* - Check if you set the origin of your project to the correct URL.
|
||||||
|
* - Open the web hook URL you entered in Gitea in your browser and check if the output is "Web hook event (X-Gitea-Event header) is missing from request.".
|
||||||
|
* - Click on the pen icon next to your web hook in Gitea's settings interface. You should see a list of "recent deliveries".
|
||||||
|
* You can find the exact error message from this script in the "Response" tab of the delivery.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 3. Done
|
||||||
|
// The code starts here
|
||||||
|
// ====================
|
||||||
|
|
||||||
|
// We are always returning plain text
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
|
||||||
|
// Check if a secret has been set
|
||||||
|
if (SECRET === '{{ '{{' }} projectr_deploy_secret }}') {
|
||||||
|
http_response_code(500);
|
||||||
|
die('No secret has been set in ' . basename(__FILE__) . ". This script won't work without one.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check which event this is
|
||||||
|
if (isset($_SERVER['HTTP_X_GITEA_EVENT']) !== true) {
|
||||||
|
http_response_code(400);
|
||||||
|
die('Web hook event (X-Gitea-Event header) is missing from request.');
|
||||||
|
}
|
||||||
|
$event = $_SERVER['HTTP_X_GITEA_EVENT'];
|
||||||
|
switch ($event) {
|
||||||
|
case 'push':
|
||||||
|
echo "Received push event.\n";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
http_response_code(400);
|
||||||
|
die("Received $event event, ignoring.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the request body
|
||||||
|
$input = false;
|
||||||
|
switch ($_SERVER['CONTENT_TYPE']) {
|
||||||
|
case 'application/json':
|
||||||
|
echo "Received JSON data in body.\n";
|
||||||
|
$input = file_get_contents('php://input');
|
||||||
|
break;
|
||||||
|
case 'application/x-www-form-urlencoded':
|
||||||
|
echo "Received URL-encoded form data in body.\n";
|
||||||
|
$input = (isset($_POST['payload']) === true)? $_POST['payload'] : '';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
http_response_code(400);
|
||||||
|
die("Don't know what to do with {$_SERVER['CONTENT_TYPE']} content type.");
|
||||||
|
}
|
||||||
|
if (!$input) {
|
||||||
|
http_response_code(400);
|
||||||
|
die('No POST body sent.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the authentication is valid
|
||||||
|
if (isset($_SERVER['HTTP_X_GITEA_SIGNATURE']) !== true) {
|
||||||
|
http_response_code(401);
|
||||||
|
die("Secret (X-Gitea-Signature header) is missing from request. Have you set a secret in Gitea's project settings?");
|
||||||
|
}
|
||||||
|
if (hash_equals(hash_hmac('sha256', $input, SECRET, false), $_SERVER['HTTP_X_GITEA_SIGNATURE']) !== true) {
|
||||||
|
http_response_code(403);
|
||||||
|
die('Secret (X-Gitea-Signature header) is wrong or does not match request body.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse payload
|
||||||
|
$payload = json_decode($input, true);
|
||||||
|
if (is_array($payload) !== true) {
|
||||||
|
http_response_code(400);
|
||||||
|
die('Invalid payload (no JSON?).');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get some interesting information from the payload
|
||||||
|
$url = $payload['repository']['clone_url'];
|
||||||
|
$commit = $payload['after'];
|
||||||
|
$ref = $payload['ref'];
|
||||||
|
if (preg_match('{(?:.*/){2}(.*)}', $ref, $matches) !== 1) {
|
||||||
|
http_response_code(400);
|
||||||
|
die('Invalid ref field (does not match regular expression "(?:.*/){2}(.*)").');
|
||||||
|
}
|
||||||
|
$branch = $matches[1];
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
echo "Received commit hash \"$commit\" for repository URL \"$url\" (branch \"$branch\").\n";
|
||||||
|
|
||||||
|
// Determine the path to the projects file
|
||||||
|
$xdgProjectsFile = ($_ENV['XDG_CONFIG_HOME'] ?? ($_SERVER['HOME'] . '/.config')) . '/projectr/projects';
|
||||||
|
$projectsFile = is_file($xdgProjectsFile) === true ? $xdgProjectsFile : $_SERVER['HOME'] . '/.projects';
|
||||||
|
|
||||||
|
// Open the projects file and iterate through every project
|
||||||
|
$listPointer = fopen($projectsFile, 'r');
|
||||||
|
$exitCode = 0;
|
||||||
|
while (($project = fgets($listPointer)) !== false) {
|
||||||
|
// Trim whitespace
|
||||||
|
$project = trim($project);
|
||||||
|
|
||||||
|
// Only deployable projects are interesting for us
|
||||||
|
if (is_file($project . '/.origin') !== true || is_file($project . '/.branch') !== true) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a .origin and .branch file, check if they match
|
||||||
|
if (trim(file_get_contents($project . '/.origin')) === $url && trim(file_get_contents($project . '/.branch')) === $branch) {
|
||||||
|
// Found the right project
|
||||||
|
echo "Found project at $project, running deploy script.\n";
|
||||||
|
|
||||||
|
// Run deploy script (in the background, because Gitea doesn't like responses > 5sec by default)
|
||||||
|
passthru('export PATH=' . escapeshellarg(TOOLKIT_PATH) . ':$PATH; project_deploy ' . escapeshellarg($project) . ' ' . escapeshellarg($commit) . ' &> /dev/null &', $exitCode);
|
||||||
|
|
||||||
|
// If it didn't work, add debug statement
|
||||||
|
if ($exitCode !== 0) {
|
||||||
|
echo "Something didn't work.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterated through every project, exit
|
||||||
|
http_response_code(($exitCode === 0)? 200 : 500);
|
||||||
|
die('All done.');
|
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
if [[ -n "$1" ]]; then
|
||||||
|
ansible-playbook -v --ask-vault-pass site.yml --tags "$1"
|
||||||
|
else
|
||||||
|
ansible-playbook -v --ask-vault-pass site.yml
|
||||||
|
fi
|
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
- name: General tasks for all Uberspaces
|
||||||
|
hosts: all
|
||||||
|
vars_files:
|
||||||
|
- vars/installs.yml
|
||||||
|
roles:
|
||||||
|
- homebrew
|
||||||
|
- host-site
|
||||||
|
- terminal
|
||||||
|
|
||||||
|
- name: Redirect mail from non-mail Uberspaces
|
||||||
|
hosts: "!mail"
|
||||||
|
vars_files:
|
||||||
|
- vars/config.yml
|
||||||
|
roles:
|
||||||
|
- mail-redirect
|
||||||
|
|
||||||
|
- name: DAV Uberspaces
|
||||||
|
hosts: dav
|
||||||
|
vars_files:
|
||||||
|
- vars/vault.yml
|
||||||
|
roles:
|
||||||
|
- dav
|
||||||
|
|
||||||
|
- name: Git Uberspaces
|
||||||
|
hosts: git
|
||||||
|
vars_files:
|
||||||
|
- vars/vault.yml
|
||||||
|
roles:
|
||||||
|
- git
|
||||||
|
|
||||||
|
- name: Mail Uberspaces
|
||||||
|
hosts: mail
|
||||||
|
vars_files:
|
||||||
|
- vars/config.yml
|
||||||
|
- vars/vault.yml
|
||||||
|
roles:
|
||||||
|
- mail
|
||||||
|
|
||||||
|
- name: Web Uberspaces
|
||||||
|
hosts: web
|
||||||
|
vars_files:
|
||||||
|
- vars/config.yml
|
||||||
|
- vars/vault.yml
|
||||||
|
roles:
|
||||||
|
- web
|
@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
# Email domains to set up per host
|
||||||
|
mail_domains:
|
||||||
|
cddmail1:
|
||||||
|
- lukasbestle.com
|
||||||
|
- lukasbestle.de
|
||||||
|
- bstl.xyz
|
||||||
|
cddmail2:
|
||||||
|
- codesignd.com
|
||||||
|
- codesignd.de
|
||||||
|
- codesignd.net
|
||||||
|
- codesigned.de
|
||||||
|
|
||||||
|
# Default sender address per host
|
||||||
|
mail_default_address:
|
||||||
|
cddmail1: mail@lukasbestle.com
|
||||||
|
cddmail2: lukas@codesignd.de
|
||||||
|
|
||||||
|
# Destination for email redirects from non-mail Uberspaces
|
||||||
|
mail_redirect_to: hostmaster@codesignd.net
|
||||||
|
|
||||||
|
# Web sites to set up per host (name: origin)
|
||||||
|
web_sites:
|
||||||
|
cddweb1:
|
||||||
|
bachelor: null
|
||||||
|
lukasbestle: https://git.codesignd.com/sites/lukasbestle.com.git
|
||||||
|
codesignd: null
|
||||||
|
cddweb2:
|
||||||
|
shareable: null
|
||||||
|
cdn: null
|
||||||
|
|
||||||
|
# Domain links to set up per host
|
||||||
|
web_links:
|
||||||
|
cddweb1:
|
||||||
|
bachelor.lukasbestle.com:
|
||||||
|
site: bachelor
|
||||||
|
lukasbestle.com:
|
||||||
|
site: lukasbestle
|
||||||
|
path: current/public
|
||||||
|
codesignd.com:
|
||||||
|
site: codesignd
|
||||||
|
codesignd.de:
|
||||||
|
site: codesignd
|
||||||
|
cddweb2:
|
||||||
|
bstl.xyz:
|
||||||
|
site: shareable
|
||||||
|
f.bstl.xyz:
|
||||||
|
site: shareable
|
||||||
|
path: data/files
|
||||||
|
cdn.codesignd.net:
|
||||||
|
site: cdn
|
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
# Homebrew formulae to install on all Uberspaces
|
||||||
|
homebrew_formulae:
|
||||||
|
# Helpers
|
||||||
|
- lukasbestle/tap/qdated # Timestamped email addresses for qmail
|
||||||
|
|
||||||
|
# Shell tools
|
||||||
|
- fasd # Directory jump tool
|
||||||
|
- figlet # ASCII fonts
|
||||||
|
|
||||||
|
# Package managers
|
||||||
|
- composer
|
||||||
|
|
||||||
|
# Oh My Fish! packages to install and keep updated
|
||||||
|
# Key: Short package name; Value: URL to a Git repo
|
||||||
|
omf_pkgs:
|
||||||
|
theme-bobthefish: https://github.com/oh-my-fish/theme-bobthefish.git
|
||||||
|
rmate: https://github.com/aurora/rmate.git
|
||||||
|
welcome: https://github.com/lukasbestle/welcome.git
|
||||||
|
z: https://github.com/jethrokuan/z.git
|
@ -0,0 +1,30 @@
|
|||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
66326137613864613264363534623131343633613662326230346136623738633030336166343231
|
||||||
|
6363393961646635336163386530393630333337383432330a316634623932626163313866393861
|
||||||
|
33366438346438366639623666643661373365666430393862333839393133363063653637343863
|
||||||
|
6464663264393931360a363433333139376264613333333130343136366437643162666132373233
|
||||||
|
63383136303230643432633165383939653836313338333766626263643232626539383965363163
|
||||||
|
65356336656264333037626366663864663137336661346230306661633430616166383063356539
|
||||||
|
35396634326331343935366565386436343866643635356337366631313038306462306137623939
|
||||||
|
64306266646638313638313766323336353261366166366433336165383230303866633137653264
|
||||||
|
32346131343062396533343238343366643963323131356130643737626464323863323437393262
|
||||||
|
36346533623137353234393738643266386165666662346636666436336432656439336430653734
|
||||||
|
38326162666630633464376464323130633832626665386464306231653161326135323764366435
|
||||||
|
63613637376331346265653738373539316531316539646538356463383832323034333963666261
|
||||||
|
37373934333139393662353835316438323839316232666263383661313232613839656236623338
|
||||||
|
39333261663936626564383665623933353862323932353734393962646636616235626637373062
|
||||||
|
38656136323739353935613634653331663137613761373266633332383534333039646162623437
|
||||||
|
36333839373066333263643234633462323635643738643731333139633263643335396636396239
|
||||||
|
30343964633964353264373437353463613766343033386362663130633030303362646139393563
|
||||||
|
36363635343861636564646266626631313262623664363063393231343838306538393263326633
|
||||||
|
66343831346438616665666165353661663131373935353438653061373463623266313832656132
|
||||||
|
65653561383732653638373638363036626166633838313736313133656438353334396364333964
|
||||||
|
62346265636266663239316432313463346536633762343135366233396331313662653263643036
|
||||||
|
30353761656662633862346464353631323465613037623332326664343533656439623236343535
|
||||||
|
62323831323139653039353237653832646336363832383139393137386531336230383837343038
|
||||||
|
38643761643833643231643731323239643734653532626366313033633563383966376537313735
|
||||||
|
62653231343830386430653461366437646261623331313734623036353839306539633364613264
|
||||||
|
62636637363363393166313035333835353962303263386633316231353362343665303566326332
|
||||||
|
62386339646532343766373537623435653462323566386262393832616563333638353933376364
|
||||||
|
31653034373964366134356536393935613931326663323335336437386132613733643964643434
|
||||||
|
62643265663632663261393836336561623561333333303161646466346332313239
|
Loading…
Reference in New Issue