summaryrefslogtreecommitdiffstats
path: root/tozt
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2018-10-19 23:15:14 -0400
committerJesse Luehrs <doy@tozt.net>2018-10-19 23:15:14 -0400
commit8317b706d7a0a91c67c46950be07d40168705b6c (patch)
tree0dbba9df21c01deb1ed165fda1dce43dbdd8e2d5 /tozt
parentd0ef063b3d2cf7b4c2eba540a0773dae3afc26ef (diff)
downloadpuppet-tozt-8317b706d7a0a91c67c46950be07d40168705b6c.tar.gz
puppet-tozt-8317b706d7a0a91c67c46950be07d40168705b6c.zip
rename modules dir
Diffstat (limited to 'tozt')
-rw-r--r--tozt/c_toolchain/manifests/init.pp12
-rwxr-xr-xtozt/certbot/files/bootstrap-certbot69
-rw-r--r--tozt/certbot/files/reload-cert5
-rw-r--r--tozt/certbot/manifests/init.pp54
-rw-r--r--tozt/certbot/templates/certbot3
-rw-r--r--tozt/conf/manifests/init.pp15
-rw-r--r--tozt/conf/manifests/user.pp53
-rw-r--r--tozt/cron/manifests/init.pp11
-rw-r--r--tozt/duplicati/manifests/init.pp26
-rw-r--r--tozt/git/manifests/init.pp5
-rw-r--r--tozt/git/manifests/server.pp15
-rw-r--r--tozt/haveged/manifests/init.pp11
-rw-r--r--tozt/locate/files/updatedb5
-rw-r--r--tozt/locate/manifests/init.pp26
-rw-r--r--tozt/mail/manifests/sender.pp5
-rw-r--r--tozt/nginx/files/dhparam.pem13
-rw-r--r--tozt/nginx/files/mime.types.paste57
-rw-r--r--tozt/nginx/files/nginx.conf16
-rw-r--r--tozt/nginx/files/ssl12
-rw-r--r--tozt/nginx/manifests/config.pp18
-rw-r--r--tozt/nginx/manifests/init.pp11
-rw-r--r--tozt/nginx/manifests/install.pp5
-rw-r--r--tozt/nginx/manifests/service.pp6
-rw-r--r--tozt/nginx/manifests/site.pp20
-rw-r--r--tozt/ntp/manifests/init.pp11
-rw-r--r--tozt/package/manifests/cargo.pp39
-rw-r--r--tozt/package/manifests/makepkg.pp41
-rw-r--r--tozt/rust/manifests/init.pp5
-rw-r--r--tozt/rust/manifests/user.pp23
-rw-r--r--tozt/secret/manifests/init.pp9
-rw-r--r--tozt/ssh/manifests/user.pp20
-rw-r--r--tozt/sudo/manifests/init.pp10
-rw-r--r--tozt/sudo/manifests/user.pp7
-rw-r--r--tozt/tarsnap/files/acts5
-rw-r--r--tozt/tarsnap/files/acts.conf3
-rw-r--r--tozt/tarsnap/files/tarsnap.conf5
-rw-r--r--tozt/tarsnap/manifests/init.pp31
-rw-r--r--tozt/tozt/files/cgitrc32
-rwxr-xr-xtozt/tozt/files/hugo-tozt9
-rwxr-xr-xtozt/tozt/files/new-git-repo221
-rw-r--r--tozt/tozt/files/nginx/blog-tls.conf12
-rw-r--r--tozt/tozt/files/nginx/blog.conf10
-rw-r--r--tozt/tozt/files/nginx/doy-tls.conf15
-rw-r--r--tozt/tozt/files/nginx/doy.conf10
-rw-r--r--tozt/tozt/files/nginx/git-tls.conf22
-rw-r--r--tozt/tozt/files/nginx/git.conf10
-rw-r--r--tozt/tozt/files/nginx/paste-tls.conf18
-rw-r--r--tozt/tozt/files/nginx/paste.conf10
-rwxr-xr-xtozt/tozt/files/post-receive8
-rw-r--r--tozt/tozt/files/puppet-tozt6
-rw-r--r--tozt/tozt/manifests/backups.pp4
-rw-r--r--tozt/tozt/manifests/bootstrap.pp14
-rw-r--r--tozt/tozt/manifests/certbot.pp8
-rw-r--r--tozt/tozt/manifests/git.pp64
-rw-r--r--tozt/tozt/manifests/init.pp18
-rw-r--r--tozt/tozt/manifests/pass.pp36
-rw-r--r--tozt/tozt/manifests/paste.pp34
-rw-r--r--tozt/tozt/manifests/persistent.pp40
-rw-r--r--tozt/tozt/manifests/services.pp4
-rw-r--r--tozt/tozt/manifests/site.pp80
-rw-r--r--tozt/tozt/manifests/tools.pp20
-rw-r--r--tozt/tozt/manifests/user.pp113
-rw-r--r--tozt/tozt/manifests/users.pp11
-rw-r--r--tozt/tozt/manifests/vpn.pp3
-rw-r--r--tozt/wireguard/manifests/init.pp18
-rw-r--r--tozt/yaourt/manifests/init.pp20
-rw-r--r--tozt/zsh/manifests/init.pp5
67 files changed, 1557 insertions, 0 deletions
diff --git a/tozt/c_toolchain/manifests/init.pp b/tozt/c_toolchain/manifests/init.pp
new file mode 100644
index 0000000..2f9a364
--- /dev/null
+++ b/tozt/c_toolchain/manifests/init.pp
@@ -0,0 +1,12 @@
+class c_toolchain {
+ package {
+ [
+ "autoconf",
+ "automake",
+ "gcc",
+ "make",
+ "pkgconf",
+ ]:
+ ensure => installed,
+ }
+}
diff --git a/tozt/certbot/files/bootstrap-certbot b/tozt/certbot/files/bootstrap-certbot
new file mode 100755
index 0000000..4cf3ea5
--- /dev/null
+++ b/tozt/certbot/files/bootstrap-certbot
@@ -0,0 +1,69 @@
+#!/usr/bin/env bash
+set -eu
+set -o pipefail
+
+config_dir="$1"
+if systemctl is-active -q nginx; then
+ is_running=1
+else
+ is_running=
+fi
+
+cleanup() {
+ if [ -z "$is_running" ]; then
+ systemctl stop nginx
+ fi
+
+ if [ -e /etc/nginx/nginx.conf.backup ]; then
+ mv /etc/nginx/nginx.conf.backup /etc/nginx.conf
+ fi
+}
+trap cleanup EXIT
+
+mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
+cat > /etc/nginx/nginx.conf <<EOF
+worker_processes 1;
+events {
+ worker_connections 1024;
+}
+http {
+ server {
+ listen 80 default;
+ server_name tozt.net;
+ location / {
+ root /tmp;
+ }
+ }
+ server {
+ listen 80;
+ server_name blog.tozt.net;
+ location / {
+ root /tmp;
+ }
+ }
+ server {
+ listen 80;
+ server_name paste.tozt.net;
+ location / {
+ root /tmp;
+ }
+ }
+ server {
+ listen 80;
+ server_name git.tozt.net;
+ location / {
+ root /tmp;
+ }
+ }
+}
+EOF
+
+if [ -z "$is_running" ]; then
+ systemctl start nginx
+fi
+
+if [ -z "$config_dir" ]; then
+ /usr/bin/certbot -n --agree-tos -m doy@tozt.net --nginx -d tozt.net -d blog.tozt.net -d paste.tozt.net -d git.tozt.net
+else
+ /usr/bin/certbot -n --agree-tos -m doy@tozt.net --nginx -d tozt.net -d blog.tozt.net -d paste.tozt.net -d git.tozt.net --config-dir "$config_dir"
+fi
diff --git a/tozt/certbot/files/reload-cert b/tozt/certbot/files/reload-cert
new file mode 100644
index 0000000..9ca23e5
--- /dev/null
+++ b/tozt/certbot/files/reload-cert
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+set -eu
+set -o pipefail
+
+systemctl restart nginx
diff --git a/tozt/certbot/manifests/init.pp b/tozt/certbot/manifests/init.pp
new file mode 100644
index 0000000..27d59a6
--- /dev/null
+++ b/tozt/certbot/manifests/init.pp
@@ -0,0 +1,54 @@
+class certbot($config_dir=undef) {
+ if $config_dir {
+ $_config_dir = $config_dir
+ }
+ else {
+ $_config_dir = "/etc/letsencrypt"
+ }
+
+ include cron
+ include nginx
+
+ package {
+ [
+ 'certbot',
+ 'certbot-nginx',
+ ]:
+ ensure => installed;
+ }
+
+ file {
+ '/etc/cron.daily/certbot':
+ content => template('certbot/certbot'),
+ mode => '0755',
+ require => [
+ Package['certbot'],
+ Class['cron'],
+ ];
+ "${_config_dir}/renewal-hooks":
+ ensure => directory,
+ require => Package['certbot'];
+ "${_config_dir}/renewal-hooks/deploy":
+ ensure => directory,
+ require => File["${_config_dir}/renewal-hooks"];
+ "${_config_dir}/renewal-hooks/deploy/reload-cert":
+ source => 'puppet:///modules/certbot/reload-cert',
+ require => File["${_config_dir}/renewal-hooks/deploy"];
+ "/usr/local/bin/bootstrap-certbot":
+ source => 'puppet:///modules/certbot/bootstrap-certbot',
+ mode => '0755';
+ }
+
+ exec { "initial certbot run":
+ provider => shell,
+ command => "/usr/local/bin/bootstrap-certbot ${config_dir}",
+ creates => "${_config_dir}/live",
+ require => [
+ Package["certbot"],
+ # not Class["nginx"], because of circular dependencies with nginx::site
+ Package["nginx"],
+ Package["certbot-nginx"],
+ File['/usr/local/bin/bootstrap-certbot'],
+ ],
+ }
+}
diff --git a/tozt/certbot/templates/certbot b/tozt/certbot/templates/certbot
new file mode 100644
index 0000000..9568fe1
--- /dev/null
+++ b/tozt/certbot/templates/certbot
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+certbot renew -q<%= @config_dir_opts %>
diff --git a/tozt/conf/manifests/init.pp b/tozt/conf/manifests/init.pp
new file mode 100644
index 0000000..36e5f22
--- /dev/null
+++ b/tozt/conf/manifests/init.pp
@@ -0,0 +1,15 @@
+class conf {
+ include c_toolchain
+ include cron
+ include git
+
+ package {
+ [
+ "cmake",
+ "fortune-mod",
+ "less",
+ "vim",
+ ]:
+ ensure => installed,
+ }
+}
diff --git a/tozt/conf/manifests/user.pp b/tozt/conf/manifests/user.pp
new file mode 100644
index 0000000..b5af5b2
--- /dev/null
+++ b/tozt/conf/manifests/user.pp
@@ -0,0 +1,53 @@
+define conf::user($user=$name, $home=undef) {
+ $_home = $home ? {
+ undef => $user ? {
+ 'root' => '/root',
+ default => "/home/$user",
+ },
+ default => $home,
+ }
+
+ include conf
+
+ package::cargo { "fancy-prompt for $user":
+ package => 'fancy-prompt',
+ user => $user,
+ ensure => installed,
+ require => Package["cmake"],
+ }
+
+ exec { "git clone doy/conf for $user":
+ command => "/usr/bin/git clone git://github.com/doy/conf",
+ user => $user,
+ cwd => $_home,
+ creates => "$_home/conf",
+ require => [
+ User[$user],
+ File[$_home],
+ Class['git'],
+ ];
+ }
+
+ exec { "conf make install for $user":
+ command => "/usr/bin/make install",
+ user => $user,
+ cwd => "$_home/conf",
+ environment => [
+ "HOME=$_home",
+ "PWD=$_home/conf",
+ ],
+ creates => "$_home/.vimrc",
+ require => [
+ Class['cron'],
+ Class['c_toolchain'],
+ User[$user],
+ Exec["git clone doy/conf for $user"],
+ Package["vim"],
+ Package["fortune-mod"],
+ Package["less"],
+ Package::Cargo["fancy-prompt for $user"],
+ ];
+ }
+
+ # XXX use the right branch
+}
diff --git a/tozt/cron/manifests/init.pp b/tozt/cron/manifests/init.pp
new file mode 100644
index 0000000..9181c40
--- /dev/null
+++ b/tozt/cron/manifests/init.pp
@@ -0,0 +1,11 @@
+class cron {
+ package { "cronie":
+ ensure => installed,
+ }
+
+ service { 'cronie':
+ ensure => running,
+ enable => true,
+ require => Package['cronie'];
+ }
+}
diff --git a/tozt/duplicati/manifests/init.pp b/tozt/duplicati/manifests/init.pp
new file mode 100644
index 0000000..643dd43
--- /dev/null
+++ b/tozt/duplicati/manifests/init.pp
@@ -0,0 +1,26 @@
+class duplicati {
+ package {
+ [
+ "gtk-sharp-2",
+ "mono",
+ ]:
+ ensure => installed,
+ install_options => ["--asdeps"];
+ }
+
+ package::makepkg { 'duplicati-latest':
+ ensure => installed,
+ require => [
+ Package['gtk-sharp-2'],
+ Package['mono'],
+ ]
+ }
+
+ service { 'duplicati':
+ ensure => running,
+ enable => true,
+ require => Package::Makepkg['duplicati-latest'];
+ }
+
+ # XXX configure backups
+}
diff --git a/tozt/git/manifests/init.pp b/tozt/git/manifests/init.pp
new file mode 100644
index 0000000..bfb60ad
--- /dev/null
+++ b/tozt/git/manifests/init.pp
@@ -0,0 +1,5 @@
+class git {
+ package { "git":
+ ensure => installed,
+ }
+}
diff --git a/tozt/git/manifests/server.pp b/tozt/git/manifests/server.pp
new file mode 100644
index 0000000..93219a7
--- /dev/null
+++ b/tozt/git/manifests/server.pp
@@ -0,0 +1,15 @@
+class git::server {
+ package {
+ [
+ "cgit",
+ "fcgiwrap",
+ "python-markdown",
+ "python-pygments",
+ ]:
+ ensure => installed,
+ }
+
+ service { "fcgiwrap.socket":
+ ensure => running,
+ }
+}
diff --git a/tozt/haveged/manifests/init.pp b/tozt/haveged/manifests/init.pp
new file mode 100644
index 0000000..05ae5f8
--- /dev/null
+++ b/tozt/haveged/manifests/init.pp
@@ -0,0 +1,11 @@
+class haveged {
+ package { "haveged":
+ ensure => installed,
+ }
+
+ service { 'haveged':
+ ensure => running,
+ enable => true,
+ require => Package['haveged'],
+ }
+}
diff --git a/tozt/locate/files/updatedb b/tozt/locate/files/updatedb
new file mode 100644
index 0000000..21f2681
--- /dev/null
+++ b/tozt/locate/files/updatedb
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+set -eu
+set -o pipefail
+
+updatedb
diff --git a/tozt/locate/manifests/init.pp b/tozt/locate/manifests/init.pp
new file mode 100644
index 0000000..182e3b4
--- /dev/null
+++ b/tozt/locate/manifests/init.pp
@@ -0,0 +1,26 @@
+class locate {
+ include cron
+
+ package { "mlocate":
+ ensure => installed,
+ }
+
+ file {
+ '/etc/cron.daily/updatedb':
+ source => 'puppet:///modules/locate/updatedb',
+ mode => '0755',
+ require => [
+ Package['mlocate'],
+ Class['cron'],
+ ];
+ }
+
+ exec { "initial updatedb run":
+ command => "/etc/cron.daily/updatedb",
+ creates => "/var/lib/mlocate/mlocate.db",
+ require => [
+ File["/etc/cron.daily/updatedb"],
+ Package['mlocate'],
+ ]
+ }
+}
diff --git a/tozt/mail/manifests/sender.pp b/tozt/mail/manifests/sender.pp
new file mode 100644
index 0000000..ef30b2a
--- /dev/null
+++ b/tozt/mail/manifests/sender.pp
@@ -0,0 +1,5 @@
+class mail::sender {
+ package { "msmtp-mta":
+ ensure => installed,
+ }
+}
diff --git a/tozt/nginx/files/dhparam.pem b/tozt/nginx/files/dhparam.pem
new file mode 100644
index 0000000..4aa2270
--- /dev/null
+++ b/tozt/nginx/files/dhparam.pem
@@ -0,0 +1,13 @@
+-----BEGIN DH PARAMETERS-----
+MIICCAKCAgEA2Ch/tJWN/Hm/Go2T9Ok542zBAJJxmrIn8ghj/etM1uVQ8viqqDy/
+2RRswFeVJE8S5tf7W7+rPWVp1NzK7Fbxn1eb0r/MdnwgCkzBK2YcbQ6skZZz7lyd
+SXXac4YrdkaG60Bm2WtmHs73pptbxBTkt55yAdTyhm8fvVZewAn2a8GRgn/X9Nb6
+YcpbLa6yh0TA1YP/CckMN5yxI761IXpKXuDMMz/PjI9xK2NSXRCgknrHa71w7E9U
+x86EyeA8VB2baZ2ct0KlaK5MaFPLSSCPBQYxigCvH6apH+U9pho4YSdZL3wLjtzO
+mN7Z8FdhPr2P/Dk0HI4Y2LzJiAQoU2t7zMrGb4y/27zFrApUed6q1lbvJW46g+o0
+zy3fe1nwZ9Ibq0TA6FH0S+FRrSYrJEN1vqosoGJjLJteyddqLV8d6XRhrZaCJmWq
+itlqbYlnbK+rlxlJyuDC6wLMTxa/zYMvYSM0Ez8KKDLh3GNMqiEbccCuS77gvPKP
+hj4Gy0jslUSYSjJebot+wIQsGmAnL5CozEXdGMVahoqZWcqRRGsoVM/3vZ53uLgL
+Cs027wnvkeAnX1sxV/KnrovpVPISkQvG0awCZkjroKMRq33fgymvvvcHo7pGcef+
+7S0XsFBit8LrBT1XGx3VknC8XZ6hAACY1FDMth2J4dx8kqVnd2PH1dMCAQI=
+-----END DH PARAMETERS-----
diff --git a/tozt/nginx/files/mime.types.paste b/tozt/nginx/files/mime.types.paste
new file mode 100644
index 0000000..a32e153
--- /dev/null
+++ b/tozt/nginx/files/mime.types.paste
@@ -0,0 +1,57 @@
+types {
+ image/gif gif;
+ image/jpeg jpeg jpg;
+
+ image/png png;
+ image/tiff tif tiff;
+ image/x-icon ico;
+ image/x-jng jng;
+ image/x-ms-bmp bmp;
+
+ application/java-archive jar war ear;
+ application/mac-binhex40 hqx;
+ application/msword doc;
+ application/pdf pdf;
+ application/postscript ps eps ai;
+ application/rtf rtf;
+ application/vnd.ms-excel xls;
+ application/vnd.ms-powerpoint ppt;
+ application/vnd.wap.wmlc wmlc;
+ application/x-cocoa cco;
+ application/x-java-archive-diff jardiff;
+ application/x-java-jnlp-file jnlp;
+ application/x-makeself run;
+ application/x-pilot prc pdb;
+ application/x-rar-compressed rar;
+ application/x-redhat-package-manager rpm;
+ application/x-sea sea;
+ application/x-shockwave-flash swf;
+ application/x-stuffit sit;
+ application/x-xpinstall xpi;
+ application/zip zip;
+
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
+ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
+ application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
+
+ application/octet-stream bin exe dll;
+ application/octet-stream deb;
+ application/octet-stream dmg;
+ application/octet-stream eot;
+ application/octet-stream iso img;
+ application/octet-stream msi msp msm;
+
+ audio/midi mid midi kar;
+ audio/mpeg mp3;
+ audio/x-realaudio ra;
+
+ video/3gpp 3gpp 3gp;
+ video/mpeg mpeg mpg;
+ video/quicktime mov;
+ video/x-flv flv;
+ video/x-mng mng;
+ video/x-ms-asf asx asf;
+ video/x-ms-wmv wmv;
+ video/x-msvideo avi;
+}
+# vim:ft=nginx
diff --git a/tozt/nginx/files/nginx.conf b/tozt/nginx/files/nginx.conf
new file mode 100644
index 0000000..895330e
--- /dev/null
+++ b/tozt/nginx/files/nginx.conf
@@ -0,0 +1,16 @@
+worker_processes 1;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ sendfile on;
+ gzip on;
+ keepalive_timeout 65;
+
+ include /etc/nginx/sites-enabled/*;
+}
diff --git a/tozt/nginx/files/ssl b/tozt/nginx/files/ssl
new file mode 100644
index 0000000..6248ac8
--- /dev/null
+++ b/tozt/nginx/files/ssl
@@ -0,0 +1,12 @@
+ssl on;
+ssl_certificate /media/persistent/certbot/live/tozt.net/fullchain.pem;
+ssl_certificate_key /media/persistent/certbot/live/tozt.net/privkey.pem;
+ssl_protocols TLSv1.1 TLSv1.2;
+ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
+ssl_dhparam /etc/nginx/dhparam.pem;
+ssl_prefer_server_ciphers on;
+ssl_session_cache shared:SSL:10m;
+ssl_stapling on;
+ssl_stapling_verify on;
+
+# vim:ft=nginx
diff --git a/tozt/nginx/manifests/config.pp b/tozt/nginx/manifests/config.pp
new file mode 100644
index 0000000..8a95edd
--- /dev/null
+++ b/tozt/nginx/manifests/config.pp
@@ -0,0 +1,18 @@
+class nginx::config {
+ include haveged
+
+ file {
+ "/etc/nginx/sites-available":
+ ensure => directory;
+ "/etc/nginx/sites-enabled":
+ ensure => directory;
+ "/etc/nginx/ssl":
+ source => 'puppet:///modules/nginx/ssl';
+ "/etc/nginx/mime.types.paste":
+ source => 'puppet:///modules/nginx/mime.types.paste';
+ "/etc/nginx/nginx.conf":
+ source => 'puppet:///modules/nginx/nginx.conf';
+ "/etc/nginx/dhparam.pem":
+ source => 'puppet:///modules/nginx/dhparam.pem';
+ }
+}
diff --git a/tozt/nginx/manifests/init.pp b/tozt/nginx/manifests/init.pp
new file mode 100644
index 0000000..611be52
--- /dev/null
+++ b/tozt/nginx/manifests/init.pp
@@ -0,0 +1,11 @@
+class nginx {
+ contain nginx::install
+ contain nginx::config
+ contain nginx::service
+
+ Class['nginx::install'] -> Class['nginx::config']
+
+ Class['nginx::config'] ~> Class['nginx::service']
+ Class['nginx::install'] ~> Class['nginx::service']
+ Nginx::Site<| |> ~> Class['nginx::service']
+}
diff --git a/tozt/nginx/manifests/install.pp b/tozt/nginx/manifests/install.pp
new file mode 100644
index 0000000..680b0ab
--- /dev/null
+++ b/tozt/nginx/manifests/install.pp
@@ -0,0 +1,5 @@
+class nginx::install {
+ package { ['nginx', 'openssl']:
+ ensure => installed;
+ }
+}
diff --git a/tozt/nginx/manifests/service.pp b/tozt/nginx/manifests/service.pp
new file mode 100644
index 0000000..f03364f
--- /dev/null
+++ b/tozt/nginx/manifests/service.pp
@@ -0,0 +1,6 @@
+class nginx::service {
+ service { 'nginx':
+ ensure => running,
+ enable => true;
+ }
+}
diff --git a/tozt/nginx/manifests/site.pp b/tozt/nginx/manifests/site.pp
new file mode 100644
index 0000000..130a086
--- /dev/null
+++ b/tozt/nginx/manifests/site.pp
@@ -0,0 +1,20 @@
+define nginx::site($content=undef, $source=undef, $enabled=true) {
+ include nginx
+
+ file { "/etc/nginx/sites-available/$name":
+ source => $source,
+ content => $content;
+ }
+
+ if $enabled {
+ file { "/etc/nginx/sites-enabled/$name":
+ ensure => link,
+ target => "../sites-available/$name";
+ }
+ }
+ else {
+ file { "/etc/nginx/sites-enabled/$name":
+ ensure => absent;
+ }
+ }
+}
diff --git a/tozt/ntp/manifests/init.pp b/tozt/ntp/manifests/init.pp
new file mode 100644
index 0000000..89140c2
--- /dev/null
+++ b/tozt/ntp/manifests/init.pp
@@ -0,0 +1,11 @@
+class ntp {
+ package { "ntp":
+ ensure => installed,
+ }
+
+ service { 'ntpd':
+ ensure => running,
+ enable => true,
+ require => Package['ntp'],
+ }
+}
diff --git a/tozt/package/manifests/cargo.pp b/tozt/package/manifests/cargo.pp
new file mode 100644
index 0000000..2f599b9
--- /dev/null
+++ b/tozt/package/manifests/cargo.pp
@@ -0,0 +1,39 @@
+define package::cargo($package, $user, $ensure, $home=undef) {
+ $_home = $home ? {
+ undef => $user ? {
+ 'root' => '/root',
+ default => "/home/$user",
+ },
+ default => $home,
+ }
+
+ case $ensure {
+ 'installed': {
+ exec { "cargo install $package for $user":
+ provider => "shell",
+ command => "cargo install $package",
+ unless => "cargo install --list | grep -q '^$package'",
+ user => $user,
+ timeout => 3600,
+ require => [
+ User[$user],
+ Rust::User[$user],
+ File["${_home}/.cargo"],
+ ];
+ }
+ }
+ 'absent': {
+ exec { "cargo uninstall $package for $user":
+ provider => "shell",
+ command => "cargo uninstall $package",
+ onlyif => "cargo install --list | grep -q '^$package'",
+ user => $user,
+ require => [
+ User[$user],
+ Rust::User[$user],
+ File["${_home}/.cargo"],
+ ];
+ }
+ }
+ }
+}
diff --git a/tozt/package/manifests/makepkg.pp b/tozt/package/manifests/makepkg.pp
new file mode 100644
index 0000000..c9d0318
--- /dev/null
+++ b/tozt/package/manifests/makepkg.pp
@@ -0,0 +1,41 @@
+define package::makepkg($ensure, $build_user, $asdeps=false) {
+ if $asdeps {
+ $extra_cmdline = " --asdeps"
+ }
+ else {
+ $extra_cmdline = ""
+ }
+
+ include c_toolchain
+ include git
+
+ case $ensure {
+ 'installed': {
+ exec { "makepkg install $name":
+ provider => "shell",
+ command => "
+ cd /tmp
+ rm -rf 'makepkg-$name'
+ su $build_user -c 'git clone https://aur.archlinux.org/$name.git makepkg-$name'
+ cd 'makepkg-$name'
+ su $build_user -c makepkg
+ pacman -U --noconfirm --needed $extra_cmdline $name-*.pkg.tar.xz
+ ",
+ unless => "pacman -Q $name > /dev/null 2>&1",
+ path => "/usr/bin",
+ require => [
+ Class["git"],
+ Class["c_toolchain"],
+ ];
+ }
+ }
+ 'absent': {
+ exec { "makepkg uninstall $name":
+ provider => "shell",
+ command => "pacman --noconfirm -Rsn $name",
+ onlyif => "pacman -Q $name > /dev/null 2>&1",
+ path => "/usr/bin";
+ }
+ }
+ }
+}
diff --git a/tozt/rust/manifests/init.pp b/tozt/rust/manifests/init.pp
new file mode 100644
index 0000000..37f74ac
--- /dev/null
+++ b/tozt/rust/manifests/init.pp
@@ -0,0 +1,5 @@
+class rust {
+ package { "rustup":
+ ensure => installed,
+ }
+}
diff --git a/tozt/rust/manifests/user.pp b/tozt/rust/manifests/user.pp
new file mode 100644
index 0000000..1b16eeb
--- /dev/null
+++ b/tozt/rust/manifests/user.pp
@@ -0,0 +1,23 @@
+define rust::user($user=$name, $home=undef) {
+ $_home = $home ? {
+ undef => $user ? {
+ 'root' => '/root',
+ default => "/home/$user",
+ },
+ default => $home,
+ }
+
+ include rust
+
+ exec { "install and configure stable toolchain for $user":
+ provider => "shell",
+ command => "rustup default stable",
+ user => $user,
+ unless => "rustup show active-toolchain | grep -q stable",
+ require => [
+ Package["rustup"],
+ User[$user],
+ File["${_home}/.rustup"],
+ ],
+ }
+}
diff --git a/tozt/secret/manifests/init.pp b/tozt/secret/manifests/init.pp
new file mode 100644
index 0000000..054a71d
--- /dev/null
+++ b/tozt/secret/manifests/init.pp
@@ -0,0 +1,9 @@
+define secret($source, $path=$name, $owner=undef, $group=undef, $mode='0600') {
+ file { "$path":
+ source => "puppet:///modules/secret/$source",
+ owner => $owner,
+ group => $group,
+ mode => $mode,
+ show_diff => false,
+ }
+}
diff --git a/tozt/ssh/manifests/user.pp b/tozt/ssh/manifests/user.pp
new file mode 100644
index 0000000..9f976b2
--- /dev/null
+++ b/tozt/ssh/manifests/user.pp
@@ -0,0 +1,20 @@
+define ssh::user($user=$name, $group=$user, $home=undef) {
+ $_home = $home ? {
+ undef => $user ? {
+ 'root' => '/root',
+ default => "/home/$user",
+ },
+ default => $home,
+ }
+
+ secret { "${_home}/.ssh/id_rsa":
+ source => "ssh/${user}/privkey",
+ owner => $user,
+ group => $group,
+ }
+ secret { "${_home}/.ssh/id_rsa.pub":
+ source => "ssh/${user}/pubkey",
+ owner => $user,
+ group => $group,
+ }
+}
diff --git a/tozt/sudo/manifests/init.pp b/tozt/sudo/manifests/init.pp
new file mode 100644
index 0000000..8a38060
--- /dev/null
+++ b/tozt/sudo/manifests/init.pp
@@ -0,0 +1,10 @@
+class sudo {
+ package { "sudo":
+ ensure => 'installed';
+ }
+
+ file { "/etc/sudoers.d/wheel":
+ ensure => present,
+ content => '%wheel ALL=(ALL) ALL';
+ }
+}
diff --git a/tozt/sudo/manifests/user.pp b/tozt/sudo/manifests/user.pp
new file mode 100644
index 0000000..81fde70
--- /dev/null
+++ b/tozt/sudo/manifests/user.pp
@@ -0,0 +1,7 @@
+define sudo::user($user=$name) {
+ include sudo
+
+ file { "/var/db/sudo/lectured/$user":
+ ensure => 'present';
+ }
+}
diff --git a/tozt/tarsnap/files/acts b/tozt/tarsnap/files/acts
new file mode 100644
index 0000000..7c2c3bd
--- /dev/null
+++ b/tozt/tarsnap/files/acts
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+set -eu
+set -o pipefail
+
+acts
diff --git a/tozt/tarsnap/files/acts.conf b/tozt/tarsnap/files/acts.conf
new file mode 100644
index 0000000..5228f54
--- /dev/null
+++ b/tozt/tarsnap/files/acts.conf
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+backuptargets="home/doy/pass home/doy/paste home/doy/public_html home/doy/irclogs"
diff --git a/tozt/tarsnap/files/tarsnap.conf b/tozt/tarsnap/files/tarsnap.conf
new file mode 100644
index 0000000..42e2fb9
--- /dev/null
+++ b/tozt/tarsnap/files/tarsnap.conf
@@ -0,0 +1,5 @@
+cachedir /var/lib/tarsnap/cache
+keyfile /etc/tarsnap/machine-key
+nodump
+print-stats
+checkpoint-bytes 1G
diff --git a/tozt/tarsnap/manifests/init.pp b/tozt/tarsnap/manifests/init.pp
new file mode 100644
index 0000000..c397164
--- /dev/null
+++ b/tozt/tarsnap/manifests/init.pp
@@ -0,0 +1,31 @@
+class tarsnap {
+ include cron
+
+ package { 'tarsnap':
+ ensure => installed;
+ }
+
+ package::makepkg { 'acts':
+ ensure => installed,
+ require => Package['tarsnap'];
+ }
+
+ file {
+ '/etc/tarsnap/tarsnap.conf':
+ source => 'puppet:///modules/tarsnap/tarsnap.conf';
+ '/etc/acts.conf':
+ source => 'puppet:///modules/tarsnap/acts.conf';
+ '/etc/cron.daily/acts':
+ source => 'puppet:///modules/tarsnap/acts',
+ mode => '0755',
+ require => [
+ File['/etc/acts.conf'],
+ Package::Makepkg['acts'],
+ Class['cron'],
+ ];
+ }
+
+ secret { "/etc/tarsnap/machine-key":
+ source => 'tarsnap',
+ }
+}
diff --git a/tozt/tozt/files/cgitrc b/tozt/tozt/files/cgitrc
new file mode 100644
index 0000000..e52e13b
--- /dev/null
+++ b/tozt/tozt/files/cgitrc
@@ -0,0 +1,32 @@
+root-title=git.tozt.net
+root-desc=
+logo=https://tozt.net/sphtkr.jpg
+
+enable-index-owner=0
+enable-index-links=1
+enable-blame=1
+enable-commit-graph=1
+enable-log-filecount=1
+enable-log-linecount=1
+branch-sort=age
+repository-sort=age
+max-stats=year
+max-repo-count=500
+
+clone-url=doy@tozt.net:git/$CGIT_REPO_URL git://git.tozt.net/$CGIT_REPO_URL git@github.com:doy/$CGIT_REPO_URL git://github.com/doy/$CGIT_REPO_URL https://github.com/doy/$CGIT_REPO_URL
+snapshots=tar.gz zip
+
+readme=:README.md
+readme=:README.txt
+readme=:README
+
+about-filter=/usr/lib/cgit/filters/about-formatting.sh
+source-filter=/usr/lib/cgit/filters/syntax-highlighting.py
+module-link=/%s/tree/?id=%s
+
+mimetype-file=/etc/mime.types
+
+virtual-root=/
+
+remove-suffix=1
+scan-path=/media/persistent/git/doy/
diff --git a/tozt/tozt/files/hugo-tozt b/tozt/tozt/files/hugo-tozt
new file mode 100755
index 0000000..859656b
--- /dev/null
+++ b/tozt/tozt/files/hugo-tozt
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+set -eu
+set -o pipefail
+
+cd ~/coding/tozt-hugo
+git pull
+git clean -dffx
+hugo
+rsync -av public/. ~/site
diff --git a/tozt/tozt/files/new-git-repo b/tozt/tozt/files/new-git-repo
new file mode 100755
index 0000000..138fadb
--- /dev/null
+++ b/tozt/tozt/files/new-git-repo
@@ -0,0 +1,221 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+no warnings "experimental::signatures";
+use 5.020;
+use feature 'signatures';
+
+use Getopt::Long;
+
+package NewGitRepo {
+ use Cwd;
+ use HTTP::Tiny;
+ use JSON::PP;
+
+ sub new($class, %opts) {
+ bless {
+ user => $opts{user},
+ root => $opts{root},
+ }, $class;
+ }
+
+ sub init($self, %opts) {
+ my $new_dir = "${\$self->{root}}/$opts{name}";
+ my $user = $self->{user};
+ my $token = $self->github_token;
+
+ local $ENV{GIT_DIR} = $new_dir;
+
+ if ($opts{from_github}) {
+ git(
+ 'clone',
+ '--bare',
+ "git://github.com/$user/$opts{name}",
+ $new_dir
+ );
+ git(qw(remote rm origin));
+
+ if (defined($opts{description})) {
+ $self->set_github_description($opts{name}, $opts{description});
+ }
+ }
+ else {
+ mkdir($new_dir);
+ git(qw(init --bare));
+ $self->create_github_repository($opts{name}, $opts{description});
+ }
+
+ git(
+ 'remote',
+ 'add', 'github',
+ "https://$user:$token\@github.com/$user/$opts{name}",
+ );
+
+ my $cgitrc = $self->generate_cgitrc(%opts);
+ spew("$new_dir/cgitrc", $cgitrc);
+
+ my $hook_file = "$new_dir/hooks/post-receive";
+ spew($hook_file, slurp("/usr/local/share/git/post-receive"));
+ chmod 0755, $hook_file or die "couldn't chmod $hook_file: $!";
+
+ if ($opts{from_github}) {
+ my $old_dir = getcwd;
+ chdir $new_dir || die "couldn't chdir to $new_dir: $!";
+ eval {
+ system('./hooks/post-receive');
+ };
+ my $err = $@;
+ chdir $old_dir;
+ if ($err) {
+ $@ = $err;
+ die;
+ }
+ }
+ }
+
+ sub generate_cgitrc($self, %opts) {
+ my $desc = defined($opts{description})
+ ? $opts{description}
+ : $self->repo_metadata($opts{name})->{description};
+ my %cgit_opts = (
+ (defined($desc)
+ ? (desc => $desc)
+ : ()),
+ section => $opts{unmaintained} ? "unmaintained" : "maintained",
+ );
+ join("\n", map { "$_=$cgit_opts{$_}" } sort keys %cgit_opts) . "\n";
+ }
+
+ sub repo_metadata($self, $name) {
+ my $query = <<EOF;
+ query {
+ repository(owner: "${\$self->{user}}", name: "$name") {
+ description
+ }
+ }
+EOF
+ $self->github_v4($query)->{data}{repository};
+ }
+
+ sub set_github_description($self, $name, $description) {
+ $self->github_v3(
+ 'PATCH',
+ "/repos/${\$self->{user}}/$name",
+ {
+ description => $description,
+ }
+ );
+ }
+
+ sub create_github_repository($self, $name, $description) {
+ $self->github_v3(
+ 'POST',
+ '/user/repos',
+ {
+ name => $name,
+ (defined($description)
+ ? (description => $description)
+ : ()),
+ }
+ );
+ }
+
+ sub github_v3($self, $method, $path, $data=undef) {
+ my $res = $self->ua->request(
+ $method,
+ "https://api.github.com$path",
+ {
+ (defined($data)
+ ? (content => encode_json($data))
+ : ()),
+ }
+ );
+ if (!$res->{success}) {
+ die "query failed ($res->{status}): $res->{content}";
+ }
+ decode_json($res->{content})
+ }
+
+ sub github_v4($self, $query) {
+ my $res = $self->ua->post(
+ "https://api.github.com/graphql",
+ {
+ content => encode_json({query => $query}),
+ }
+ );
+ if (!$res->{success}) {
+ die "query failed ($res->{status}): $res->{content}";
+ }
+ decode_json($res->{content})
+ }
+
+ sub ua($self) {
+ $self->{ua} ||= HTTP::Tiny->new(
+ default_headers => {
+ 'Authorization' => "bearer ${\$self->github_token}",
+ 'Content-Type' => "application/json",
+ 'Accept' => "application/json",
+ },
+ verify_SSL => 1,
+ );
+ }
+
+ sub github_token($self) {
+ $self->{github_token} ||= do {
+ chomp(my $token = slurp("$ENV{HOME}/.github"));
+ $token
+ }
+ }
+
+ sub git(@args) {
+ system('git', @args) and die "couldn't run git: $!";
+ }
+
+ sub slurp($filename) {
+ open my $fh, '<', $filename or die "couldn't open $filename: $!";
+ do { local $/; <$fh> };
+ }
+
+ sub spew($filename, $contents) {
+ open my $fh, '>', $filename or die "couldn't open $filename: $!";
+ print $fh $contents or die "couldn't write to $filename: $!";
+ close $fh or die "couldn't close $filename: $!";
+ }
+}
+
+
+sub main(@argv) {
+ my %opts = parse_args(\@argv);
+ my $user = delete $opts{user};
+ my $root = delete $opts{root};
+ NewGitRepo->new(
+ user => $user,
+ root => $root,
+ )->init(%opts);
+}
+
+sub parse_args($argv) {
+ my %opts = (
+ from_github => undef,
+ user => $ENV{USER},
+ root => "$ENV{HOME}/git",
+ unmaintained => undef,
+ description => undef,
+ );
+
+ Getopt::Long::GetOptionsFromArray(
+ $argv,
+ 'from-github' => \$opts{from_github},
+ 'user=s' => \$opts{user},
+ 'root=s' => \$opts{root},
+ 'unmaintained' => \$opts{unmaintained},
+ 'description=s' => \$opts{description},
+ );
+ $opts{name} = shift @$argv;
+
+ die "extra args found: " . join(' ', @$argv) if @$argv;
+
+ %opts
+}
+
+main(@ARGV);
diff --git a/tozt/tozt/files/nginx/blog-tls.conf b/tozt/tozt/files/nginx/blog-tls.conf
new file mode 100644
index 0000000..094d5b7
--- /dev/null
+++ b/tozt/tozt/files/nginx/blog-tls.conf
@@ -0,0 +1,12 @@
+server {
+ listen 443;
+ server_name blog.tozt.net;
+
+ access_log /var/log/nginx/blog.access.log;
+ error_log /var/log/nginx/blog.error.log;
+
+ include ssl;
+
+ rewrite ^(.*) https://tozt.net/blog$1 permanent;
+}
+# vim:ft=nginx
diff --git a/tozt/tozt/files/nginx/blog.conf b/tozt/tozt/files/nginx/blog.conf
new file mode 100644
index 0000000..cbb72df
--- /dev/null
+++ b/tozt/tozt/files/nginx/blog.conf
@@ -0,0 +1,10 @@
+server {
+ listen 80;
+ server_name blog.tozt.net;
+
+ access_log /var/log/nginx/blog.access.log;
+ error_log /var/log/nginx/blog.error.log;
+
+ rewrite ^(.*) https://tozt.net/blog$1 permanent;
+}
+# vim:ft=nginx
diff --git a/tozt/tozt/files/nginx/doy-tls.conf b/tozt/tozt/files/nginx/doy-tls.conf
new file mode 100644
index 0000000..e869a5c
--- /dev/null
+++ b/tozt/tozt/files/nginx/doy-tls.conf
@@ -0,0 +1,15 @@
+server {
+ listen 443 default;
+ server_name tozt.net;
+
+ access_log /var/log/nginx/doy.access.log;
+ error_log /var/log/nginx/doy.error.log;
+
+ include ssl;
+
+ location / {
+ root /home/doy;
+ try_files /site$uri /site$uri/index.html /public_html$uri =404;
+ }
+}
+# vim:ft=nginx
diff --git a/tozt/tozt/files/nginx/doy.conf b/tozt/tozt/files/nginx/doy.conf
new file mode 100644
index 0000000..15c3932
--- /dev/null
+++ b/tozt/tozt/files/nginx/doy.conf
@@ -0,0 +1,10 @@
+server {
+ listen 80 default;
+ server_name tozt.net;
+
+ access_log /var/log/nginx/doy.access.log;
+ error_log /var/log/nginx/doy.error.log;
+
+ rewrite ^(.*) https://$host$1 permanent;
+}
+# vim:ft=nginx
diff --git a/tozt/tozt/files/nginx/git-tls.conf b/tozt/tozt/files/nginx/git-tls.conf
new file mode 100644
index 0000000..6e0dfbb
--- /dev/null
+++ b/tozt/tozt/files/nginx/git-tls.conf
@@ -0,0 +1,22 @@
+server {
+ listen 443;
+ server_name git.tozt.net;
+
+ access_log /var/log/nginx/git.access.log;
+ error_log /var/log/nginx/git.error.log;
+
+ include ssl;
+
+ root /usr/share/webapps/cgit;
+ try_files $uri @cgit;
+
+ location @cgit {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi;
+ fastcgi_param PATH_INFO $uri;
+ fastcgi_param QUERY_STRING $args;
+ fastcgi_param HTTP_HOST $server_name;
+ fastcgi_pass unix:/run/fcgiwrap.sock;
+ }
+}
+# vim:ft=nginx
diff --git a/tozt/tozt/files/nginx/git.conf b/tozt/tozt/files/nginx/git.conf
new file mode 100644
index 0000000..cafdcc8
--- /dev/null
+++ b/tozt/tozt/files/nginx/git.conf
@@ -0,0 +1,10 @@
+server {
+ listen 80;
+ server_name git.tozt.net;
+
+ access_log /var/log/nginx/git.access.log;
+ error_log /var/log/nginx/git.error.log;
+
+ rewrite ^(.*) https://$host$1 permanent;
+}
+# vim:ft=nginx
diff --git a/tozt/tozt/files/nginx/paste-tls.conf b/tozt/tozt/files/nginx/paste-tls.conf
new file mode 100644
index 0000000..b73d7a8
--- /dev/null
+++ b/tozt/tozt/files/nginx/paste-tls.conf
@@ -0,0 +1,18 @@
+server {
+ listen 443;
+ server_name paste.tozt.net;
+
+ access_log /var/log/nginx/paste.access.log;
+ error_log /var/log/nginx/paste.error.log;
+
+ include ssl;
+
+ include /etc/nginx/mime.types.paste;
+
+ root /home/doy/paste;
+ default_type text/plain;
+ gzip_types text/plain;
+
+ location / { }
+}
+# vim:ft=nginx
diff --git a/tozt/tozt/files/nginx/paste.conf b/tozt/tozt/files/nginx/paste.conf
new file mode 100644
index 0000000..839fe78
--- /dev/null
+++ b/tozt/tozt/files/nginx/paste.conf
@@ -0,0 +1,10 @@
+server {
+ listen 80;
+ server_name paste.tozt.net;
+
+ access_log /var/log/nginx/paste.access.log;
+ error_log /var/log/nginx/paste.error.log;
+
+ rewrite ^(.*) https://$host$1 permanent;
+}
+# vim:ft=nginx
diff --git a/tozt/tozt/files/post-receive b/tozt/tozt/files/post-receive
new file mode 100755
index 0000000..2f26f7c
--- /dev/null
+++ b/tozt/tozt/files/post-receive
@@ -0,0 +1,8 @@
+#!/bin/sh
+set -eu
+set -o pipefail
+
+mkdir -p info/web
+git for-each-ref --sort=committerdate --format='%(committerdate)' refs/heads | tail -n1 > info/web/last-modified
+
+git push --mirror github
diff --git a/tozt/tozt/files/puppet-tozt b/tozt/tozt/files/puppet-tozt
new file mode 100644
index 0000000..4ea27ef
--- /dev/null
+++ b/tozt/tozt/files/puppet-tozt
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+set -eu
+set -o pipefail
+
+(cd /usr/local/share/puppet-tozt && sudo git pull)
+sudo puppet apply --show_diff --modulepath=/usr/local/share/puppet-tozt/modules -e 'include tozt'
diff --git a/tozt/tozt/manifests/backups.pp b/tozt/tozt/manifests/backups.pp
new file mode 100644
index 0000000..2036777
--- /dev/null
+++ b/tozt/tozt/manifests/backups.pp
@@ -0,0 +1,4 @@
+class tozt::backups {
+ include duplicati
+ include tarsnap
+}
diff --git a/tozt/tozt/manifests/bootstrap.pp b/tozt/tozt/manifests/bootstrap.pp
new file mode 100644
index 0000000..7d18444
--- /dev/null
+++ b/tozt/tozt/manifests/bootstrap.pp
@@ -0,0 +1,14 @@
+class tozt::bootstrap {
+ package {
+ [
+ "puppet",
+ "rsync",
+ ]:
+ ensure => installed,
+ }
+
+ file { '/usr/local/bin/puppet-tozt':
+ source => 'puppet:///modules/tozt/puppet-tozt',
+ mode => '0755';
+ }
+}
diff --git a/tozt/tozt/manifests/certbot.pp b/tozt/tozt/manifests/certbot.pp
new file mode 100644
index 0000000..cad7d1a
--- /dev/null
+++ b/tozt/tozt/manifests/certbot.pp
@@ -0,0 +1,8 @@
+class tozt::certbot {
+ include tozt::persistent
+
+ class { "certbot":
+ config_dir => "/media/persistent/certbot",
+ require => Class["tozt::persistent"],
+ }
+}
diff --git a/tozt/tozt/manifests/git.pp b/tozt/tozt/manifests/git.pp
new file mode 100644
index 0000000..03204dc
--- /dev/null
+++ b/tozt/tozt/manifests/git.pp
@@ -0,0 +1,64 @@
+class tozt::git {
+ include git::server
+ include tozt::certbot
+ include tozt::persistent
+
+ package { "perl-io-socket-ssl":
+ ensure => installed,
+ }
+
+ file {
+ "/media/persistent/git/doy":
+ ensure => directory,
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ Class['tozt::persistent'],
+ User['doy'],
+ Group['doy'],
+ ];
+ "/home/doy/git":
+ ensure => link,
+ target => "/media/persistent/git/doy",
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ User['doy'],
+ Group['doy'],
+ File["/home/doy"],
+ ];
+ "/etc/cgitrc":
+ source => "puppet:///modules/tozt/cgitrc";
+ "/usr/local/share/git":
+ ensure => directory;
+ "/usr/local/share/git/post-receive":
+ source => "puppet:///modules/tozt/post-receive",
+ require => File['/usr/local/share/git'];
+ "/usr/local/bin/new-git-repo":
+ source => "puppet:///modules/tozt/new-git-repo",
+ mode => '0755',
+ require => [
+ Package['perl-io-socket-ssl'],
+ File['/usr/local/share/git/post-receive'],
+ ];
+ }
+
+ secret { "/home/doy/.github":
+ source => 'github',
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ User['doy'],
+ Group['doy'],
+ File["/home/doy"],
+ ];
+ }
+
+ nginx::site {
+ "git-tls":
+ source => 'puppet:///modules/tozt/nginx/git-tls.conf',
+ require => Class['certbot'];
+ "git":
+ source => 'puppet:///modules/tozt/nginx/git.conf';
+ }
+}
diff --git a/tozt/tozt/manifests/init.pp b/tozt/tozt/manifests/init.pp
new file mode 100644
index 0000000..b13c4cd
--- /dev/null
+++ b/tozt/tozt/manifests/init.pp
@@ -0,0 +1,18 @@
+class tozt {
+ include tozt::users
+
+ Package::Makepkg {
+ build_user => 'doy',
+ }
+
+ Tozt::User['doy'] -> Package::Makepkg<| build_user == 'doy' |>
+
+ include tozt::bootstrap
+ include tozt::backups
+ include tozt::git
+ include tozt::pass
+ include tozt::site
+ include tozt::services
+ include tozt::tools
+ include tozt::vpn
+}
diff --git a/tozt/tozt/manifests/pass.pp b/tozt/tozt/manifests/pass.pp
new file mode 100644
index 0000000..b1241c1
--- /dev/null
+++ b/tozt/tozt/manifests/pass.pp
@@ -0,0 +1,36 @@
+class tozt::pass {
+ include tozt::persistent
+
+ file {
+ "/media/persistent/pass":
+ ensure => directory,
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ Class['tozt::persistent'],
+ User['doy'],
+ Group['doy'],
+ ];
+ "/home/doy/pass":
+ ensure => link,
+ target => "/media/persistent/pass",
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ File['/home/doy'],
+ User['doy'],
+ Group['doy'],
+ ];
+ }
+
+ exec { "pass git init":
+ command => "/usr/bin/git init --bare",
+ user => "doy",
+ cwd => "/media/persistent/pass",
+ creates => "/media/persistent/pass/HEAD",
+ require => [
+ Class["git"],
+ File["/media/persistent/pass"],
+ ],
+ }
+}
diff --git a/tozt/tozt/manifests/paste.pp b/tozt/tozt/manifests/paste.pp
new file mode 100644
index 0000000..93d7939
--- /dev/null
+++ b/tozt/tozt/manifests/paste.pp
@@ -0,0 +1,34 @@
+class tozt::paste {
+ include tozt::certbot
+ include tozt::persistent
+
+ file {
+ "/media/persistent/paste/doy":
+ ensure => directory,
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ Class['tozt::persistent'],
+ User['doy'],
+ Group['doy'],
+ ];
+ "/home/doy/paste":
+ ensure => link,
+ target => "/media/persistent/paste/doy",
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ User['doy'],
+ Group['doy'],
+ File["/home/doy"],
+ ];
+ }
+
+ nginx::site {
+ "paste-tls":
+ source => 'puppet:///modules/tozt/nginx/paste-tls.conf',
+ require => Class['certbot'];
+ "paste":
+ source => 'puppet:///modules/tozt/nginx/paste.conf';
+ }
+}
diff --git a/tozt/tozt/manifests/persistent.pp b/tozt/tozt/manifests/persistent.pp
new file mode 100644
index 0000000..0726455
--- /dev/null
+++ b/tozt/tozt/manifests/persistent.pp
@@ -0,0 +1,40 @@
+class tozt::persistent {
+ file {
+ "/media":
+ ensure => directory;
+ "/media/persistent":
+ ensure => directory,
+ require => File["/media"],
+ }
+
+ $fstab_line = "/dev/disk/by-id/scsi-0DO_Volume_tozt-persistent /media/persistent ext4 rw,relatime 0 2"
+ exec { "populate fstab":
+ provider => shell,
+ command => "echo '${fstab_line}' >> /etc/fstab",
+ unless => "/usr/bin/grep -qF '${fstab_line}' /etc/fstab",
+ require => File["/media/persistent"],
+ }
+
+ exec { "mount /media/persistent":
+ provider => shell,
+ command => "/usr/bin/mount /media/persistent",
+ unless => "grep ' /media/persistent ' /proc/mounts",
+ require => [
+ File["/media/persistent"],
+ Exec["populate fstab"],
+ ]
+ }
+
+ file {
+ [
+ "/media/persistent/public_html",
+ "/media/persistent/paste",
+ "/media/persistent/git",
+ "/media/persistent/certbot",
+ "/media/persistent/cargo",
+ "/media/persistent/rustup",
+ ]:
+ ensure => directory,
+ require => Exec["mount /media/persistent"];
+ }
+}
diff --git a/tozt/tozt/manifests/services.pp b/tozt/tozt/manifests/services.pp
new file mode 100644
index 0000000..8dfbe5b
--- /dev/null
+++ b/tozt/tozt/manifests/services.pp
@@ -0,0 +1,4 @@
+class tozt::services {
+ include locate
+ include ntp
+}
diff --git a/tozt/tozt/manifests/site.pp b/tozt/tozt/manifests/site.pp
new file mode 100644
index 0000000..f28619a
--- /dev/null
+++ b/tozt/tozt/manifests/site.pp
@@ -0,0 +1,80 @@
+class tozt::site {
+ include git
+ include tozt::certbot
+ include tozt::persistent
+
+ package { "hugo":
+ ensure => installed,
+ }
+
+ exec { "clone tozt.net":
+ command => "/usr/bin/git clone git://github.com/doy/tozt-hugo",
+ user => "doy",
+ cwd => "/home/doy/coding",
+ creates => "/home/doy/coding/tozt-hugo",
+ require => [
+ Class["git"],
+ File["/home/doy/coding"],
+ ],
+ }
+
+ exec { "generate tozt.net":
+ provider => shell,
+ command => "
+ rm -rf public
+ hugo
+ mv public /home/doy/site
+ ",
+ user => "doy",
+ cwd => "/home/doy/coding/tozt-hugo",
+ creates => "/home/doy/site",
+ require => [
+ Exec["clone tozt.net"],
+ User['doy'],
+ File['/home/doy'],
+ Package["hugo"],
+ Class["git"],
+ ],
+ }
+
+ file {
+ "/media/persistent/public_html/doy":
+ ensure => directory,
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ Class['tozt::persistent'],
+ User['doy'],
+ Group['doy'],
+ ];
+ "/home/doy/public_html":
+ ensure => link,
+ target => "/media/persistent/public_html/doy",
+ owner => 'doy',
+ group => 'doy',
+ require => [
+ User['doy'],
+ Group['doy'],
+ File["/home/doy"],
+ ];
+ }
+
+ nginx::site {
+ "doy-tls":
+ source => 'puppet:///modules/tozt/nginx/doy-tls.conf',
+ require => Class['certbot'];
+ "doy":
+ source => 'puppet:///modules/tozt/nginx/doy.conf';
+ "blog-tls":
+ source => 'puppet:///modules/tozt/nginx/blog-tls.conf',
+ require => Class['certbot'];
+ "blog":
+ source => 'puppet:///modules/tozt/nginx/blog.conf';
+ }
+
+ file {
+ '/usr/local/bin/hugo-tozt':
+ source => 'puppet:///modules/tozt/hugo-tozt',
+ mode => '0755';
+ }
+}
diff --git a/tozt/tozt/manifests/tools.pp b/tozt/tozt/manifests/tools.pp
new file mode 100644
index 0000000..5531460
--- /dev/null
+++ b/tozt/tozt/manifests/tools.pp
@@ -0,0 +1,20 @@
+class tozt::tools {
+ include mail::sender
+ include yaourt
+
+ package {
+ [
+ "bc",
+ "exa",
+ "fzf",
+ "htop",
+ "lsof",
+ "mutt",
+ "ncdu",
+ "strace",
+ "the_silver_searcher",
+ "tmux",
+ ]:
+ ensure => 'installed';
+ }
+}
diff --git a/tozt/tozt/manifests/user.pp b/tozt/tozt/manifests/user.pp
new file mode 100644
index 0000000..99c52ed
--- /dev/null
+++ b/tozt/tozt/manifests/user.pp
@@ -0,0 +1,113 @@
+define tozt::user(
+ $pwhash,
+ $user=$name,
+ $group=$user,
+ $home=undef,
+ $extra_groups=[],
+ $homedir_mode='0700',
+ $shell='/usr/bin/zsh',
+) {
+ $_home = $home ? {
+ undef => $user ? {
+ 'root' => '/root',
+ default => "/home/$user",
+ },
+ default => $home,
+ }
+
+ include tozt::persistent
+
+ group { $group:
+ ensure => present;
+ }
+
+ user { $user:
+ ensure => 'present',
+ gid => $group,
+ groups => $extra_groups,
+ home => $_home,
+ shell => $shell,
+ password => $pwhash,
+ require => Group[$group];
+ }
+
+ file {
+ $_home:
+ ensure => 'directory',
+ owner => $user,
+ group => $group,
+ mode => $homedir_mode,
+ require => [
+ User[$user],
+ Group[$group],
+ ];
+ "${_home}/coding":
+ ensure => 'directory',
+ owner => $user,
+ group => $group,
+ mode => $homedir_mode,
+ require => [
+ User[$user],
+ Group[$group],
+ File[$_home],
+ ];
+ "/media/persistent/cargo/${user}":
+ ensure => 'directory',
+ owner => $user,
+ group => $group,
+ mode => $homedir_mode,
+ require => [
+ User[$user],
+ Group[$group],
+ Class["tozt::persistent"],
+ ];
+ "/media/persistent/rustup/${user}":
+ ensure => 'directory',
+ owner => $user,
+ group => $group,
+ mode => $homedir_mode,
+ require => [
+ User[$user],
+ Group[$group],
+ Class["tozt::persistent"],
+ ];
+ "${_home}/.cargo":
+ ensure => link,
+ target => "/media/persistent/cargo/${user}",
+ owner => $user,
+ group => $group,
+ require => [
+ User[$user],
+ Group[$group],
+ File["${_home}"],
+ ];
+ "${_home}/.rustup":
+ ensure => link,
+ target => "/media/persistent/rustup/${user}",
+ owner => $user,
+ group => $group,
+ require => [
+ User[$user],
+ Group[$group],
+ File["${_home}"],
+ ];
+ }
+
+ rust::user { $user:
+ }
+ conf::user { $user:
+ }
+ ssh::user { $user:
+ group => $group,
+ }
+
+ if $user != 'root' {
+ sudo::user { $user:
+ }
+ }
+
+ if $shell == '/usr/bin/zsh' {
+ include zsh
+ Class['zsh'] -> User[$user]
+ }
+}
diff --git a/tozt/tozt/manifests/users.pp b/tozt/tozt/manifests/users.pp
new file mode 100644
index 0000000..b07373b
--- /dev/null
+++ b/tozt/tozt/manifests/users.pp
@@ -0,0 +1,11 @@
+class tozt::users {
+ tozt::user { 'root':
+ pwhash => '$6$cqlzoze/Mq3$bHGFqjPF6wBRLcI0VWuQa9cg8c1DfGWL21QdA9KUuDqhtnCfjyaKryu.ACxP9umzuYsWpikegZN6wbTU2JX6V1';
+ }
+
+ tozt::user { 'doy':
+ pwhash => '$6$Q6Y/nmt/QZbU$6D692oUPiFvnQEwoPtL7l83l/KaY/czy9/KI9.GnEEOslQumU39qteDDp.0i9E7nSDodWGOmPgfAsoYJBYrta1',
+ extra_groups => ['wheel'],
+ homedir_mode => '0701';
+ }
+}
diff --git a/tozt/tozt/manifests/vpn.pp b/tozt/tozt/manifests/vpn.pp
new file mode 100644
index 0000000..aa84f53
--- /dev/null
+++ b/tozt/tozt/manifests/vpn.pp
@@ -0,0 +1,3 @@
+class tozt::vpn {
+ include wireguard
+}
diff --git a/tozt/wireguard/manifests/init.pp b/tozt/wireguard/manifests/init.pp
new file mode 100644
index 0000000..236a269
--- /dev/null
+++ b/tozt/wireguard/manifests/init.pp
@@ -0,0 +1,18 @@
+class wireguard {
+ package { ["linux-headers", "wireguard-tools"]:
+ ensure => installed,
+ }
+
+ secret { "/etc/wireguard/algo.conf":
+ source => "wireguard",
+ }
+
+ service { "wg-quick@algo":
+ ensure => running,
+ enable => true,
+ require => [
+ Package["wireguard-tools"],
+ Secret["/etc/wireguard/algo.conf"],
+ ],
+ }
+}
diff --git a/tozt/yaourt/manifests/init.pp b/tozt/yaourt/manifests/init.pp
new file mode 100644
index 0000000..871cac8
--- /dev/null
+++ b/tozt/yaourt/manifests/init.pp
@@ -0,0 +1,20 @@
+class yaourt {
+ package {
+ [
+ "yajl"
+ ]:
+ ensure => 'installed',
+ install_options => ["--asdeps"];
+ }
+
+ package::makepkg { 'package-query':
+ ensure => installed,
+ asdeps => true,
+ require => Package['yajl'];
+ }
+
+ package::makepkg { 'yaourt':
+ ensure => installed,
+ require => Package::Makepkg['package-query'];
+ }
+}
diff --git a/tozt/zsh/manifests/init.pp b/tozt/zsh/manifests/init.pp
new file mode 100644
index 0000000..e6f97aa
--- /dev/null
+++ b/tozt/zsh/manifests/init.pp
@@ -0,0 +1,5 @@
+class zsh {
+ package { "zsh":
+ ensure => installed,
+ }
+}