From 874adce8f4efdda653c1e60d5b353a3bc816af93 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 27 Mar 2019 18:28:57 +0900 Subject: gerboweb: Initial commit The functionality is there, no design yet --- gerboweb/deploy/mirrorlist | 474 ++++++++++++++++++++++++++++++++++++++++++ gerboweb/deploy/playbook.yml | 100 +++++++++ gerboweb/deploy/render.sh | 20 ++ gerboweb/deploy/vector.sh | 18 ++ gerboweb/gerboweb.cfg | 4 + gerboweb/gerboweb.py | 147 +++++++++++++ gerboweb/job_processor.py | 40 ++++ gerboweb/job_queue.py | 88 ++++++++ gerboweb/templates/index.html | 86 ++++++++ 9 files changed, 977 insertions(+) create mode 100644 gerboweb/deploy/mirrorlist create mode 100644 gerboweb/deploy/playbook.yml create mode 100755 gerboweb/deploy/render.sh create mode 100755 gerboweb/deploy/vector.sh create mode 100644 gerboweb/gerboweb.cfg create mode 100644 gerboweb/gerboweb.py create mode 100644 gerboweb/job_processor.py create mode 100644 gerboweb/job_queue.py create mode 100644 gerboweb/templates/index.html (limited to 'gerboweb') diff --git a/gerboweb/deploy/mirrorlist b/gerboweb/deploy/mirrorlist new file mode 100644 index 0000000..a2fd58c --- /dev/null +++ b/gerboweb/deploy/mirrorlist @@ -0,0 +1,474 @@ +## +## Arch Linux repository mirrorlist +## Generated on 2017-06-06 +## + +## Worldwide +#Server = https://archlinux.surlyjake.com/archlinux/$repo/os/$arch +#Server = http://mirrors.evowise.com/archlinux/$repo/os/$arch +Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch + +## Australia +#Server = https://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch +#Server = http://archlinux.mirror.digitalpacific.com.au/$repo/os/$arch +#Server = http://ftp.iinet.net.au/pub/archlinux/$repo/os/$arch +#Server = http://mirror.internode.on.net/pub/archlinux/$repo/os/$arch +#Server = http://ftp.swin.edu.au/archlinux/$repo/os/$arch +#Server = http://archlinux.uberglobalmirror.com/$repo/os/$arch + +## Austria +#Server = http://mirror.digitalnova.at/archlinux/$repo/os/$arch +#Server = http://mirror.easyname.at/archlinux/$repo/os/$arch +#Server = http://mirror1.htu.tugraz.at/archlinux/$repo/os/$arch + +## Belarus +#Server = http://ftp.byfly.by/pub/archlinux/$repo/os/$arch +#Server = http://mirror.datacenter.by/pub/archlinux/$repo/os/$arch + +## Belgium +#Server = http://archlinux.cu.be/$repo/os/$arch +#Server = http://archlinux.mirror.kangaroot.net/$repo/os/$arch + +## Bosnia and Herzegovina +#Server = http://burek.archlinux.ba/$repo/os/$arch +#Server = http://archlinux.mirror.ba/$repo/os/$arch + +## Brazil +#Server = http://br.mirror.archlinux-br.org/$repo/os/$arch +#Server = http://archlinux.c3sl.ufpr.br/$repo/os/$arch +#Server = http://linorg.usp.br/archlinux/$repo/os/$arch +#Server = http://pet.inf.ufsc.br/mirrors/archlinux/$repo/os/$arch +#Server = http://archlinux.pop-es.rnp.br/$repo/os/$arch + +## Bulgaria +#Server = http://mirror.host.ag/archlinux/$repo/os/$arch +#Server = http://mirrors.netix.net/archlinux/$repo/os/$arch +#Server = http://mirror.telepoint.bg/archlinux/$repo/os/$arch +#Server = http://mirrors.uni-plovdiv.net/archlinux/$repo/os/$arch +#Server = https://mirrors.uni-plovdiv.net/archlinux/$repo/os/$arch + +## Canada +#Server = http://mirror.cedille.club/archlinux/$repo/os/$arch +#Server = http://archlinux.mirror.colo-serv.net/$repo/os/$arch +#Server = http://mirror.csclub.uwaterloo.ca/archlinux/$repo/os/$arch +#Server = https://mirror.csclub.uwaterloo.ca/archlinux/$repo/os/$arch +#Server = http://mirror.frgl.pw/archlinux/$repo/os/$arch +#Server = https://mirror.frgl.pw/archlinux/$repo/os/$arch +#Server = http://mirror.its.dal.ca/archlinux/$repo/os/$arch +#Server = http://muug.ca/mirror/archlinux/$repo/os/$arch +#Server = https://muug.ca/mirror/archlinux/$repo/os/$arch +#Server = http://archlinux.mirror.rafal.ca/$repo/os/$arch + +## Chile +#Server = http://mirror.archlinux.cl/$repo/os/$arch + +## China +#Server = http://mirrors.163.com/archlinux/$repo/os/$arch +#Server = http://mirror.lzu.edu.cn/archlinux/$repo/os/$arch +#Server = http://mirrors.neusoft.edu.cn/archlinux/$repo/os/$arch +#Server = https://mirrors.skyshe.cn/archlinux/$repo/os/$arch +#Server = http://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch +#Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch +#Server = http://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch +#Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch +#Server = http://mirrors.xjtu.edu.cn/archlinux/$repo/os/$arch +#Server = https://mirrors.xjtu.edu.cn/archlinux/$repo/os/$arch +#Server = http://mirrors.zju.edu.cn/archlinux/$repo/os/$arch + +## Colombia +#Server = http://mirror.edatel.net.co/archlinux/$repo/os/$arch +#Server = http://mirror.upb.edu.co/archlinux/$repo/os/$arch + +## Croatia +#Server = http://archlinux.iskon.hr/$repo/os/$arch + +## Czech Republic +#Server = http://mirror.dkm.cz/archlinux/$repo/os/$arch +#Server = https://mirror.dkm.cz/archlinux/$repo/os/$arch +#Server = http://ftp.fi.muni.cz/pub/linux/arch/$repo/os/$arch +#Server = http://ftp.linux.cz/pub/linux/arch/$repo/os/$arch +#Server = http://gluttony.sin.cvut.cz/arch/$repo/os/$arch +#Server = https://gluttony.sin.cvut.cz/arch/$repo/os/$arch +#Server = http://mirrors.nic.cz/archlinux/$repo/os/$arch +#Server = http://ftp.sh.cvut.cz/arch/$repo/os/$arch +#Server = https://ftp.sh.cvut.cz/arch/$repo/os/$arch +#Server = http://mirror.vpsfree.cz/archlinux/$repo/os/$arch + +## Denmark +#Server = http://mirrors.dotsrc.org/archlinux/$repo/os/$arch +#Server = https://mirrors.dotsrc.org/archlinux/$repo/os/$arch +#Server = http://ftp.klid.dk/ftp/archlinux/$repo/os/$arch +#Server = http://mirror.one.com/archlinux/$repo/os/$arch +#Server = https://mirror.one.com/archlinux/$repo/os/$arch + +## Ecuador +#Server = http://mirror.cedia.org.ec/archlinux/$repo/os/$arch +#Server = http://mirror.espoch.edu.ec/archlinux/$repo/os/$arch +#Server = http://mirror.uta.edu.ec/archlinux/$repo/os/$arch + +## Finland +#Server = http://arch.mirror.far.fi/$repo/os/$arch + +## France +#Server = http://archlinux.de-labrusse.fr/$repo/os/$arch +#Server = http://mirror.archlinux.ikoula.com/archlinux/$repo/os/$arch +#Server = http://archlinux.vi-di.fr/$repo/os/$arch +#Server = https://archlinux.vi-di.fr/$repo/os/$arch +#Server = http://mirror.armbrust.me/archlinux/$repo/os/$arch +#Server = https://mirror.armbrust.me/archlinux/$repo/os/$arch +#Server = https://archlinux.ec-tech.fr/$repo/os/$arch +#Server = http://fooo.biz/archlinux/$repo/os/$arch +#Server = https://fooo.biz/archlinux/$repo/os/$arch +#Server = http://mirror.gerhard.re/archlinux/$repo/os/$arch +#Server = http://mirror.ibcp.fr/pub/archlinux/$repo/os/$arch +#Server = http://mirror.lastmikoi.net/archlinux/$repo/os/$arch +#Server = http://archlinux.mailtunnel.eu/$repo/os/$arch +#Server = https://www.mailtunnel.eu/archlinux/$repo/os/$arch +#Server = http://mir.archlinux.fr/$repo/os/$arch +#Server = http://archlinux.mirrors.ovh.net/archlinux/$repo/os/$arch +#Server = http://archlinux.mirror.pkern.at/$repo/os/$arch +#Server = https://archlinux.mirror.pkern.at/$repo/os/$arch +#Server = http://archlinux.polymorf.fr/$repo/os/$arch +#Server = http://mirrors.standaloneinstaller.com/archlinux/$repo/os/$arch +#Server = http://arch.tamcore.eu/$repo/os/$arch +#Server = http://mirror.tyborek.pl/arch/$repo/os/$arch +#Server = https://mirror.tyborek.pl/arch/$repo/os/$arch +#Server = http://ftp.u-strasbg.fr/linux/distributions/archlinux/$repo/os/$arch +#Server = https://mirror.wormhole.eu/archlinux/$repo/os/$arch +#Server = http://arch.yourlabs.org/$repo/os/$arch + +## Germany +#Server = http://mirror.23media.de/archlinux/$repo/os/$arch +#Server = https://arch.32g.eu/$repo/os/$arch +#Server = http://artfiles.org/archlinux.org/$repo/os/$arch +#Server = https://fabric-mirror.vps.hosteurope.de/archlinux/$repo/os/$arch +#Server = https://mirror.bethselamin.de/$repo/os/$arch +#Server = http://mirror.euserv.net/linux/archlinux/$repo/os/$arch +#Server = http://mirror.f4st.host/archlinux/$repo/os/$arch +#Server = https://mirror.f4st.host/archlinux/$repo/os/$arch +#Server = http://ftp.fau.de/archlinux/$repo/os/$arch +#Server = https://ftp.fau.de/archlinux/$repo/os/$arch +#Server = http://mirror.fluxent.de/archlinux/$repo/os/$arch +#Server = https://mirror.fluxent.de/archlinux/$repo/os/$arch +#Server = http://mirror.gnomus.de/$repo/os/$arch +#Server = http://www.gutscheindrache.com/mirror/archlinux/$repo/os/$arch +#Server = http://ftp.gwdg.de/pub/linux/archlinux/$repo/os/$arch +#Server = http://mirror.hactar.xyz/$repo/os/$arch +#Server = https://mirror.hactar.xyz/$repo/os/$arch +#Server = http://archlinux.honkgong.info/$repo/os/$arch +#Server = http://ftp.hosteurope.de/mirror/ftp.archlinux.org/$repo/os/$arch +#Server = http://ftp-stud.hs-esslingen.de/pub/Mirrors/archlinux/$repo/os/$arch +#Server = http://archlinux.mirror.iphh.net/$repo/os/$arch +#Server = http://repo.itmettke.de/archlinux/$repo/os/$arch +#Server = https://repo.itmettke.de/archlinux/$repo/os/$arch +#Server = https://mirror.jankoppe.de/archlinux/$repo/os/$arch +#Server = http://arch.jensgutermuth.de/$repo/os/$arch +#Server = https://arch.jensgutermuth.de/$repo/os/$arch +#Server = http://mirror.js-webcoding.de/pub/archlinux/$repo/os/$arch +#Server = https://mirror.js-webcoding.de/pub/archlinux/$repo/os/$arch +#Server = http://k42.ch/mirror/archlinux/$repo/os/$arch +#Server = https://k42.ch/mirror/archlinux/$repo/os/$arch +#Server = http://mirror.de.leaseweb.net/archlinux/$repo/os/$arch +Server = https://mirror.de.leaseweb.net/archlinux/$repo/os/$arch +#Server = http://mirror.loli.forsale/arch/$repo/os/$arch +#Server = https://mirror.loli.forsale/arch/$repo/os/$arch +#Server = http://mirror.metalgamer.eu/archlinux/$repo/os/$arch +#Server = https://mirror.metalgamer.eu/archlinux/$repo/os/$arch +#Server = http://mirror.michael-eckert.net/archlinux/$repo/os/$arch +#Server = https://mirror.michael-eckert.net/archlinux/$repo/os/$arch +#Server = http://mirrors.n-ix.net/archlinux/$repo/os/$arch +#Server = https://mirrors.n-ix.net/archlinux/$repo/os/$arch +#Server = http://mirror.netcologne.de/archlinux/$repo/os/$arch +Server = https://mirror.netcologne.de/archlinux/$repo/os/$arch +#Server = http://mirrors.niyawe.de/archlinux/$repo/os/$arch +#Server = https://mirrors.niyawe.de/archlinux/$repo/os/$arch +#Server = http://archlinux.nullpointer.io/$repo/os/$arch +#Server = https://archlinux.nullpointer.io/$repo/os/$arch +#Server = http://mirror.pseudoform.org/$repo/os/$arch +#Server = https://mirror.pseudoform.org/$repo/os/$arch +#Server = https://www.ratenzahlung.de/mirror/archlinux/$repo/os/$arch +#Server = http://ftp.halifax.rwth-aachen.de/archlinux/$repo/os/$arch +#Server = http://linux.rz.rub.de/archlinux/$repo/os/$arch +#Server = http://mirror.selfnet.de/archlinux/$repo/os/$arch +#Server = http://ftp.spline.inf.fu-berlin.de/mirrors/archlinux/$repo/os/$arch +#Server = https://ftp.spline.inf.fu-berlin.de/mirrors/archlinux/$repo/os/$arch +#Server = http://archlinux.thaller.ws/$repo/os/$arch +#Server = https://archlinux.thaller.ws/$repo/os/$arch +#Server = http://archlinux.thelinuxnetworx.rocks/$repo/os/$arch +#Server = https://archlinux.thelinuxnetworx.rocks/$repo/os/$arch +#Server = http://archmirror.tomforb.es/$repo/os/$arch +#Server = https://archmirror.tomforb.es/$repo/os/$arch +#Server = http://ftp.tu-chemnitz.de/pub/linux/archlinux/$repo/os/$arch +#Server = http://mirror.ubrco.de/archlinux/$repo/os/$arch +#Server = https://mirror.ubrco.de/archlinux/$repo/os/$arch +#Server = http://ftp.uni-bayreuth.de/linux/archlinux/$repo/os/$arch +#Server = http://ftp.uni-hannover.de/archlinux/$repo/os/$arch +#Server = http://ftp.uni-kl.de/pub/linux/archlinux/$repo/os/$arch +#Server = http://mirror.united-gameserver.de/archlinux/$repo/os/$arch +#Server = http://mirror.vfn-nrw.de/archlinux/$repo/os/$arch +#Server = https://mirror.vfn-nrw.de/archlinux/$repo/os/$arch + +## Greece +#Server = http://ftp.cc.uoc.gr/mirrors/linux/archlinux/$repo/os/$arch +#Server = http://foss.aueb.gr/mirrors/linux/archlinux/$repo/os/$arch +#Server = https://foss.aueb.gr/mirrors/linux/archlinux/$repo/os/$arch +#Server = http://mirrors.myaegean.gr/linux/archlinux/$repo/os/$arch +#Server = http://ftp.ntua.gr/pub/linux/archlinux/$repo/os/$arch +#Server = http://ftp.otenet.gr/linux/archlinux/$repo/os/$arch + +## Hong Kong +#Server = http://arch-mirror.wtako.net/$repo/os/$arch +#Server = https://arch-mirror.wtako.net/$repo/os/$arch + +## Hungary +#Server = http://ftp.energia.mta.hu/pub/mirrors/ftp.archlinux.org/$repo/os/$arch +#Server = http://archmirror.hbit.sztaki.hu/archlinux/$repo/os/$arch + +## Iceland +#Server = http://mirror.system.is/arch/$repo/os/$arch +#Server = https://mirror.system.is/arch/$repo/os/$arch + +## India +#Server = http://mirror.cse.iitk.ac.in/archlinux/$repo/os/$arch +#Server = http://ftp.iitm.ac.in/archlinux/$repo/os/$arch + +## Indonesia +#Server = http://mirror.devilzc0de.org/archlinux/$repo/os/$arch +#Server = http://mirror.poliwangi.ac.id/archlinux/$repo/os/$arch +#Server = http://suro.ubaya.ac.id/archlinux/$repo/os/$arch + +## Iran +#Server = http://repo.sadjad.ac.ir/arch/$repo/os/$arch +#Server = https://repo.sadjad.ac.ir/arch/$repo/os/$arch + +## Ireland +#Server = http://ftp.heanet.ie/mirrors/ftp.archlinux.org/$repo/os/$arch +#Server = https://ftp.heanet.ie/mirrors/ftp.archlinux.org/$repo/os/$arch + +## Israel +#Server = http://mirror.isoc.org.il/pub/archlinux/$repo/os/$arch + +## Italy +#Server = http://archlinux.prometeolibero.eu/archlinux/$repo/os/$arch +#Server = https://archlinux.prometeolibero.eu/archlinux/$repo/os/$arch +#Server = https://archlinux.beccacervello.it/archlinux/$repo/os/$arch +#Server = http://mi.mirror.garr.it/mirrors/archlinux/$repo/os/$arch +#Server = http://mirrors.prometeus.net/archlinux/$repo/os/$arch +#Server = http://archlinux.students.cs.unibo.it/$repo/os/$arch + +## Japan +#Server = http://ftp.tsukuba.wide.ad.jp/Linux/archlinux/$repo/os/$arch +Server = http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/$repo/os/$arch + +## Kazakhstan +#Server = http://mirror.neolabs.kz/archlinux/$repo/os/$arch + +## Latvia +#Server = http://archlinux.koyanet.lv/archlinux/$repo/os/$arch + +## Lithuania +#Server = http://mirrors.atviras.lt/archlinux/$repo/os/$arch +#Server = https://mirrors.atviras.lt/archlinux/$repo/os/$arch + +## Luxembourg +#Server = http://archlinux.mirror.root.lu/$repo/os/$arch + +## Macedonia +#Server = http://arch.softver.org.mk/archlinux/$repo/os/$arch +#Server = http://mirror.t-home.mk/archlinux/$repo/os/$arch +#Server = https://mirror.t-home.mk/archlinux/$repo/os/$arch + +## Netherlands +#Server = http://arch.apt-get.eu/$repo/os/$arch +#Server = http://mirror.i3d.net/pub/archlinux/$repo/os/$arch +#Server = https://mirror.i3d.net/pub/archlinux/$repo/os/$arch +#Server = http://mirror.nl.leaseweb.net/archlinux/$repo/os/$arch +#Server = https://mirror.nl.leaseweb.net/archlinux/$repo/os/$arch +#Server = http://mirror.netrouting.net/archlinux/$repo/os/$arch +#Server = http://ftp.nluug.nl/os/Linux/distr/archlinux/$repo/os/$arch +#Server = http://ftp.snt.utwente.nl/pub/os/linux/archlinux/$repo/os/$arch +#Server = http://archlinux.mirror.wearetriple.com/$repo/os/$arch +#Server = https://archlinux.mirror.wearetriple.com/$repo/os/$arch + +## New Caledonia +#Server = http://mirror.lagoon.nc/pub/archlinux/$repo/os/$arch +#Server = http://archlinux.nautile.nc/archlinux/$repo/os/$arch + +## New Zealand +#Server = https://mirror.smith.geek.nz/archlinux/$repo/os/$arch + +## Norway +#Server = http://mirror.archlinux.no/$repo/os/$arch +#Server = http://archlinux.uib.no/$repo/os/$arch +#Server = http://mirror.neuf.no/archlinux/$repo/os/$arch +#Server = https://mirror.neuf.no/archlinux/$repo/os/$arch + +## Philippines +#Server = http://mirror.rise.ph/archlinux/$repo/os/$arch + +## Poland +#Server = http://mirror.chmuri.net/archmirror/$repo/os/$arch +#Server = http://arch.midov.pl/arch/$repo/os/$arch +#Server = http://mirror.onet.pl/pub/mirrors/archlinux/$repo/os/$arch +#Server = http://piotrkosoft.net/pub/mirrors/ftp.archlinux.org/$repo/os/$arch +#Server = http://ftp.vectranet.pl/archlinux/$repo/os/$arch + +## Portugal +#Server = http://glua.ua.pt/pub/archlinux/$repo/os/$arch +#Server = https://glua.ua.pt/pub/archlinux/$repo/os/$arch +#Server = http://ftp.rnl.tecnico.ulisboa.pt/pub/archlinux/$repo/os/$arch + +## Qatar +#Server = http://mirror.qnren.qa/archlinux/$repo/os/$arch + +## Romania +#Server = http://mirror.archlinux.ro/archlinux/$repo/os/$arch +#Server = http://archlinux.mirrors.linux.ro/$repo/os/$arch +#Server = http://mirrors.m247.ro/archlinux/$repo/os/$arch +#Server = http://mirrors.pidginhost.com/arch/$repo/os/$arch + +## Russia +#Server = http://mirror.aur.rocks/$repo/os/$arch +#Server = https://mirror.aur.rocks/$repo/os/$arch +#Server = http://mirror.rol.ru/archlinux/$repo/os/$arch +#Server = https://mirror.rol.ru/archlinux/$repo/os/$arch +#Server = http://mirror.yandex.ru/archlinux/$repo/os/$arch +#Server = https://mirror.yandex.ru/archlinux/$repo/os/$arch + +## Serbia +#Server = http://mirror.pmf.kg.ac.rs/archlinux/$repo/os/$arch + +## Singapore +#Server = http://mirror.0x.sg/archlinux/$repo/os/$arch +#Server = http://download.nus.edu.sg/mirror/arch/$repo/os/$arch + +## Slovakia +#Server = http://mirror.lnx.sk/pub/linux/archlinux/$repo/os/$arch +#Server = https://mirror.lnx.sk/pub/linux/archlinux/$repo/os/$arch +#Server = http://tux.rainside.sk/archlinux/$repo/os/$arch + +## Slovenia +#Server = http://archimonde.ts.si/archlinux/$repo/os/$arch +#Server = https://archimonde.ts.si/archlinux/$repo/os/$arch + +## South Africa +#Server = http://za.mirror.archlinux-br.org/$repo/os/$arch +#Server = http://ftp.wa.co.za/pub/archlinux/$repo/os/$arch +#Server = http://mirror.is.co.za/mirror/archlinux.org/$repo/os/$arch +#Server = http://mirror.wbs.co.za/archlinux/$repo/os/$arch + +## South Korea +#Server = http://ftp.kaist.ac.kr/ArchLinux/$repo/os/$arch +#Server = http://mirror.premi.st/archlinux/$repo/os/$arch + +## Spain +#Server = http://osl.ugr.es/archlinux/$repo/os/$arch +#Server = http://sunsite.rediris.es/mirror/archlinux/$repo/os/$arch + +## Sweden +#Server = http://ftp.acc.umu.se/mirror/archlinux/$repo/os/$arch +#Server = https://ftp.acc.umu.se/mirror/archlinux/$repo/os/$arch +#Server = http://archlinux.dynamict.se/$repo/os/$arch +#Server = https://archlinux.dynamict.se/$repo/os/$arch +#Server = http://ftp.lysator.liu.se/pub/archlinux/$repo/os/$arch +#Server = https://ftp.lysator.liu.se/pub/archlinux/$repo/os/$arch +#Server = http://ftp.myrveln.se/pub/linux/archlinux/$repo/os/$arch +#Server = https://ftp.myrveln.se/pub/linux/archlinux/$repo/os/$arch +#Server = https://mirror.osbeck.com/archlinux/$repo/os/$arch +#Server = http://ftp.portlane.com/pub/os/linux/archlinux/$repo/os/$arch + +## Switzerland +#Server = http://pkg.adfinis-sygroup.ch/archlinux/$repo/os/$arch +#Server = https://pkg.adfinis-sygroup.ch/archlinux/$repo/os/$arch +#Server = http://archlinux.puzzle.ch/$repo/os/$arch + +## Taiwan +#Server = http://archlinux.cs.nctu.edu.tw/$repo/os/$arch +#Server = http://shadow.ind.ntou.edu.tw/archlinux/$repo/os/$arch +#Server = http://ftp.tku.edu.tw/Linux/ArchLinux/$repo/os/$arch +#Server = http://ftp.yzu.edu.tw/Linux/archlinux/$repo/os/$arch + +## Thailand +#Server = http://mirror.adminbannok.com/archlinux/$repo/os/$arch +#Server = http://mirror.kku.ac.th/archlinux/$repo/os/$arch +#Server = https://mirror.kku.ac.th/archlinux/$repo/os/$arch + +## Turkey +#Server = http://ftp.linux.org.tr/archlinux/$repo/os/$arch + +## Ukraine +#Server = http://archlinux.ip-connect.vn.ua/$repo/os/$arch +#Server = https://archlinux.ip-connect.vn.ua/$repo/os/$arch +#Server = http://mirrors.nix.org.ua/linux/archlinux/$repo/os/$arch +#Server = https://mirrors.nix.org.ua/linux/archlinux/$repo/os/$arch + +## United Kingdom +#Server = http://mirror.bytemark.co.uk/archlinux/$repo/os/$arch +#Server = http://mirrors.manchester.m247.com/arch-linux/$repo/os/$arch +#Server = http://www.mirrorservice.org/sites/ftp.archlinux.org/$repo/os/$arch +#Server = http://arch.serverspace.co.uk/arch/$repo/os/$arch +#Server = http://archlinux.mirrors.uk2.net/$repo/os/$arch + +## United States +#Server = http://mirrors.acm.wpi.edu/archlinux/$repo/os/$arch +#Server = http://mirrors.advancedhosters.com/archlinux/$repo/os/$arch +#Server = http://mirrors.aggregate.org/archlinux/$repo/os/$arch +#Server = http://ca.us.mirror.archlinux-br.org/$repo/os/$arch +#Server = http://il.us.mirror.archlinux-br.org/$repo/os/$arch +#Server = http://archlinux.surlyjake.com/archlinux/$repo/os/$arch +#Server = http://arlm.tyzoid.com/$repo/os/$arch +#Server = http://mirror.as65535.net/archlinux/$repo/os/$arch +#Server = http://mirrors.cat.pdx.edu/archlinux/$repo/os/$arch +#Server = http://mirror.cc.columbia.edu/pub/linux/archlinux/$repo/os/$arch +#Server = http://arch.mirror.constant.com/$repo/os/$arch +#Server = https://arch.mirror.constant.com/$repo/os/$arch +#Server = http://cosmos.cites.illinois.edu/pub/archlinux/$repo/os/$arch +#Server = http://mirror.cs.pitt.edu/archlinux/$repo/os/$arch +#Server = http://mirror.cs.vt.edu/pub/ArchLinux/$repo/os/$arch +#Server = http://mirror.epiphyte.network/archlinux/$repo/os/$arch +#Server = https://mirror.epiphyte.network/archlinux/$repo/os/$arch +#Server = http://mirror.es.its.nyu.edu/archlinux/$repo/os/$arch +#Server = http://mirrors.gigenet.com/archlinux/$repo/os/$arch +#Server = http://mirror.grig.io/archlinux/$repo/os/$arch +#Server = https://mirror.grig.io/archlinux/$repo/os/$arch +#Server = http://www.gtlib.gatech.edu/pub/archlinux/$repo/os/$arch +#Server = http://mirror1.hackingand.coffee/arch/$repo/os/$arch +#Server = http://mirror2.hackingand.coffee/arch/$repo/os/$arch +#Server = http://mirror3.hackingand.coffee/arch/$repo/os/$arch +#Server = http://mirror.htnshost.com/archlinux/$repo/os/$arch +#Server = http://mirror.jmu.edu/pub/archlinux/$repo/os/$arch +#Server = http://mirrors.kernel.org/archlinux/$repo/os/$arch +#Server = https://mirrors.kernel.org/archlinux/$repo/os/$arch +#Server = http://mirror.us.leaseweb.net/archlinux/$repo/os/$arch +#Server = https://mirror.us.leaseweb.net/archlinux/$repo/os/$arch +#Server = http://il.mirrors.linaxe.net/archlinux/$repo/os/$arch +#Server = http://mirrors.liquidweb.com/archlinux/$repo/os/$arch +#Server = http://arch.localmsp.org/arch/$repo/os/$arch +#Server = https://arch.localmsp.org/arch/$repo/os/$arch +#Server = http://mirror.lty.me/archlinux/$repo/os/$arch +#Server = https://mirror.lty.me/archlinux/$repo/os/$arch +#Server = http://mirrors.lug.mtu.edu/archlinux/$repo/os/$arch +#Server = https://mirrors.lug.mtu.edu/archlinux/$repo/os/$arch +#Server = http://mirror.math.princeton.edu/pub/archlinux/$repo/os/$arch +#Server = http://mirror.metrocast.net/archlinux/$repo/os/$arch +#Server = http://mirror.kaminski.io/archlinux/$repo/os/$arch +#Server = https://mirror.kaminski.io/archlinux/$repo/os/$arch +#Server = http://mirror.nexcess.net/archlinux/$repo/os/$arch +#Server = http://mirrors.ocf.berkeley.edu/archlinux/$repo/os/$arch +#Server = https://mirrors.ocf.berkeley.edu/archlinux/$repo/os/$arch +#Server = http://ftp.osuosl.org/pub/archlinux/$repo/os/$arch +#Server = http://arch.mirrors.pair.com/$repo/os/$arch +#Server = http://mirrors.rit.edu/archlinux/$repo/os/$arch +#Server = https://mirrors.rit.edu/archlinux/$repo/os/$arch +#Server = http://mirrors.rutgers.edu/archlinux/$repo/os/$arch +#Server = https://mirrors.rutgers.edu/archlinux/$repo/os/$arch +#Server = https://mirrors.tuxns.net/archlinux/$repo/os/$arch +#Server = http://mirror.umd.edu/archlinux/$repo/os/$arch +#Server = http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch +#Server = http://mirrors.xmission.com/archlinux/$repo/os/$arch +#Server = http://mirror.yellowfiber.net/archlinux/$repo/os/$arch + +## Vietnam +#Server = http://f.archlinuxvn.org/archlinux/$repo/os/$arch +#Server = http://mirror-fpt-telecom.fpt.net/archlinux/$repo/os/$arch + diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml new file mode 100644 index 0000000..a510772 --- /dev/null +++ b/gerboweb/deploy/playbook.yml @@ -0,0 +1,100 @@ +- name: Gerbolyze container setup playbook + hosts: localhost + connection: local + tasks: + - name: Download arch bootstrap image + get_url: + url: http://mirror.rackspace.com/archlinux/iso/2019.03.01/archlinux-bootstrap-2019.03.01-x86_64.tar.gz + dest: /tmp/arch-bootstrap.tar.xz + checksum: sha256:865c8a25312b663e724923eecf0dfc626f4cd621e2cfcb19eafc69a4fc666756 + + - name: Install host requisites + become: yes + dnf: + name: btrfs-progs,arch-install-scripts + state: latest + + - name: Create container image file + become: yes + shell: truncate -s 4G /var/cache/gerbolyze_container.img + args: + creates: /var/cache/gerbolyze_container.img + + - name: Create container image filesystem + become: yes + filesystem: + dev: /var/cache/gerbolyze_container.img + fstype: btrfs + + - name: Create container image fstab entry + become: yes + mount: + src: /var/cache/gerbolyze_container.img + path: /var/cache/gerbolyze_container + state: mounted + fstype: btrfs + opts: loop + + - name: Unpack bootstrap image + become: yes + unarchive: + remote_src: yes + src: /tmp/arch-bootstrap.tar.xz + dest: /var/cache/gerbolyze_container + extra_opts: --strip-components=1 + creates: /var/cache/gerbolyze_container/etc + + - name: Copy mirrorlist into container + become: yes + copy: + src: mirrorlist + dest: /var/cache/gerbolyze_container/etc/pacman.d/mirrorlist + + - name: Copy render script + become: yes + copy: + src: render.sh + dest: /usr/local/sbin/gerbolyze_render.sh + mode: ug+x + + - name: Copy vector script + become: yes + copy: + src: vector.sh + dest: /usr/local/sbin/gerbolyze_vector.sh + mode: ug+x + + - name: Initialize container pacman keyring + become: yes + shell: arch-chroot /var/cache/gerbolyze_container pacman-key --init && arch-chroot /var/cache/gerbolyze_container pacman-key --populate archlinux + args: + creates: /var/cache/gerbolyze_container/etc/pacman.d/gnupg + + - name: Fixup pacman.conf for pacman to work in chroot without its own root fs + become: yes + lineinfile: + path: /var/cache/gerbolyze_container/etc/pacman.conf + regexp: '^CheckSpace' + line: '#CheckSpace' + + - name: Update container and install software + become: yes + shell: arch-chroot /var/cache/gerbolyze_container pacman -Syu --noconfirm python3 opencv hdf5 gtk3 python-numpy python-pip imagemagick unzip zip + + # TODO maybe install directly from local git checkout? + - name: Install gerbolyze + become: yes + shell: arch-chroot /var/cache/gerbolyze_container pip install -U --upgrade-strategy=eager gerbolyze + + # - name: Cleanup bootstrap image + # file: + # path: /tmp/arch-bootstrap.tar.xz + # state: absent + + - name: Create app cache directory + file: + path: /var/cache/gerboweb + owner: user # FIXME debug + group: user # FIXME debug + mode: 0770 + diff --git a/gerboweb/deploy/render.sh b/gerboweb/deploy/render.sh new file mode 100755 index 0000000..c3920de --- /dev/null +++ b/gerboweb/deploy/render.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +[ $# != 1 ] && exit 1 +ID=$1 +egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 + +systemd-nspawn \ + -D /var/cache/gerbolyze_container \ + -x --bind=/var/cache/gerboweb/upload/$ID:/mnt \ + /bin/sh -c "set -euo pipefail +unzip -j -d /tmp/gerber /mnt/gerber.zip +rm -f /mnt/render_top.png /mnt/render_bottom.png /mnt/render_top.small.png /mnt/render_bottom.small.png +date; echo 'Rendering bottom layer' +gerbolyze render top /tmp/gerber /mnt/render_top.png +date; echo 'Scaling down' +convert /mnt/render_top.png -resize 500x500 /mnt/render_top.small.png +date; echo 'Rendering top layer' +gerbolyze render bottom /tmp/gerber /mnt/render_bottom.png +date; echo 'Scaling down' +convert /mnt/render_bottom.png -resize 500x500 /mnt/render_bottom.small.png" diff --git a/gerboweb/deploy/vector.sh b/gerboweb/deploy/vector.sh new file mode 100755 index 0000000..5d239d5 --- /dev/null +++ b/gerboweb/deploy/vector.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +[ $# != 2 ] && exit 1 +ID=$1 +egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 +LAYER=$2 +egrep -x -q '^(top|bottom)$'<<<"$LAYER" || exit 2 + +systemd-nspawn \ + -D /var/cache/gerbolyze_container \ + -x --bind=/var/cache/gerboweb/upload/$ID:/mnt \ + /bin/sh -c "set -euo pipefail +cd /tmp +unzip -j -d gerber_in /mnt/gerber.zip +gerbolyze vectorize $LAYER gerber_in gerber /mnt/overlay.png +rm -f /mnt/gerber_out.zip +zip -r /mnt/gerber_out.zip gerber" + diff --git a/gerboweb/gerboweb.cfg b/gerboweb/gerboweb.cfg new file mode 100644 index 0000000..02ea211 --- /dev/null +++ b/gerboweb/gerboweb.cfg @@ -0,0 +1,4 @@ +MAX_CONTENT_LENGTH=10000000 +SECRET_KEY="FIXME: CHANGE THIS KEY" +UPLOAD_PATH="/var/cache/gerboweb/upload" +JOB_QUEUE_DB="/var/cache/gerboweb/job_queue.sqlite3" diff --git a/gerboweb/gerboweb.py b/gerboweb/gerboweb.py new file mode 100644 index 0000000..bf2921a --- /dev/null +++ b/gerboweb/gerboweb.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 + +# TODO create systemd unit file +# TODO create systemd tmpfiles.d config +# TODO setup ansible deployment +# TODO setup webserver user disk quota + +import tempfile +import uuid +from functools import wraps +from os import path +import os +import sqlite3 + +from flask import Flask, url_for, redirect, session, make_response, render_template, request, send_file, abort +from flask_wtf import FlaskForm +from flask_wtf.file import FileField +from wtforms.fields import RadioField +from wtforms.validators import DataRequired +from werkzeug.utils import secure_filename + +from job_queue import JobQueue + +app = Flask(__name__, static_url_path='/static') +app.config.from_envvar('GERBOWEB_SETTINGS') + +class UploadForm(FlaskForm): + upload_file = FileField(validators=[DataRequired()]) + +class OverlayForm(UploadForm): + upload_file = FileField(validators=[DataRequired()]) + side = RadioField('Side', choices=[('top', 'Top'), ('bottom', 'Bottom')]) + +class ResetForm(FlaskForm): + pass + +job_queue = JobQueue(app.config['JOB_QUEUE_DB']) + +def tempfile_path(namespace): + """ Return a path for a per-session temporary file identified by the given namespace. Create the session tempfile + dir if necessary. The application tempfile dir is controlled via the upload_path config value and not managed by + this function. """ + if not path.isdir(app.config['UPLOAD_PATH']): + os.mkdir(app.config['UPLOAD_PATH']) + sess_tmp = path.join(app.config['UPLOAD_PATH'], session['session_id']) + if not path.isdir(sess_tmp): + os.mkdir(sess_tmp) + + return path.join(sess_tmp, namespace) + +def require_session_id(fun): + @wraps(fun) + def wrapper(*args, **kwargs): + if 'session_id' not in session: + session['session_id'] = str(uuid.uuid4()) + return fun(*args, **kwargs) + return wrapper + +@app.route('/') +@require_session_id +def index(): + forms = { + 'gerber_form': UploadForm(), + 'overlay_form': OverlayForm(), + 'reset_form': ResetForm() } + + for job in ('vector_job', 'render_job'): + if job in session and job_queue[session[job]].finished: + del session[job] + + r = make_response(render_template('index.html', + has_renders = path.isfile(tempfile_path('gerber.zip')), + has_output = path.isfile(tempfile_path('overlay.png')), + **forms)) + if 'vector_job' in session or 'render_job' in session: + r.headers.set('refresh', '10') + return r + +# NOTES about the gerber and overlay file upload routines +# * The maximum upload size is limited by the MAX_CONTENT_LENGTH config setting. +# * The uploaded files are deleted after a while by systemd tmpfiles.d +# TODO: validate this setting applies *after* gzip transport compression + +@app.route('/upload/', methods=['POST']) +@require_session_id +def upload(namespace): + if namespace not in ('gerber', 'overlay'): + return abort(400, 'Invalid upload type') + + upload_form = UploadForm() if namespace == 'gerber' else OverlayForm() + if upload_form.validate_on_submit(): + f = upload_form.upload_file.data + + if namespace == 'gerber': + f.save(tempfile_path('gerber.zip')) + session['filename'] = secure_filename(f.filename) # Cache filename for later download + if 'render_job' in session: + job_queue.drop(session['render_job']) + session['render_job'] = job_queue.enqueue('render', + session_id=session['session_id'], + client=request.remote_addr) + else: # namespace == 'vector' + f.save(tempfile_path('overlay.png')) + + # Re-vectorize if either file has changed + if path.isfile(tempfile_path('gerber.zip')) and path.isfile(tempfile_path('overlay.png')): + if 'vector_job' in session: + job_queue.drop(session['vector_job']) + session['vector_job'] = job_queue.enqueue('vector', + client=request.remote_addr, + session_id=session['session_id'], + side=upload_form.side.data) + + return redirect(url_for('index')) + +@app.route('/render/preview/') +def render_preview(side): + if not side in ('top', 'bottom'): + return abort(400, 'side must be either "top" or "bottom"') + return send_file(tempfile_path(f'render_{side}.small.png')) + +@app.route('/render/download/') +def render_download(side): + if not side in ('top', 'bottom'): + return abort(400, 'side must be either "top" or "bottom"') + return send_file(tempfile_path(f'render_{side}.png'), + mimetype='image/png', + as_attachment=True, + attachment_filename=f'{path.splitext(session["filename"])[0]}_render.png') + +@app.route('/output/download') +def output_download(): + return send_file(tempfile_path('gerber_out.zip'), + mimetype='application/zip', + as_attachment=True, + attachment_filename=f'{path.splitext(session["filename"])[0]}_with_artwork.zip') + +@app.route('/session_reset', methods=['POST']) +@require_session_id +def session_reset(): + if 'render_job' in session: + session['render_job'].abort() + if 'vector_job' in session: + session['vector_job'].abort() + session.clear() + return redirect(url_for('index')) + diff --git a/gerboweb/job_processor.py b/gerboweb/job_processor.py new file mode 100644 index 0000000..c138bf4 --- /dev/null +++ b/gerboweb/job_processor.py @@ -0,0 +1,40 @@ + +import signal +import subprocess +import logging +import itertools + +from job_queue import JobQueue + + +if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('queue', help='job queue sqlite3 database file') + parser.add_argument('--loglevel', '-l', default='info') + args = parser.parse_args() + + numeric_level = getattr(logging, args.loglevel.upper(), None) + if not isinstance(numeric_level, int): + raise ValueError('Invalid log level: %s' % loglevel) + logging.basicConfig(level=numeric_level) + + job_queue = JobQueue(args.queue) + + signal.signal(signal.SIGALRM, lambda *args: None) # Ignore incoming alarm signals while processing jobs + signal.setitimer(signal.ITIMER_REAL, 0.001, 1) + while signal.sigwait([signal.SIGALRM, signal.SIGINT]) == signal.SIGALRM: + logging.debug('Checking for jobs') + for job in job_queue.job_iter('render'): + logging.info(f'Processing {job.type} job {job.id} session {job["session_id"]} from {job.client} submitted {job.created}') + with job: + job.result = subprocess.call(['sudo', '/usr/local/sbin/gerbolyze_render.sh', job['session_id']]) + logging.info(f'Finishied processing {job.type} job {job.id}') + + for job in job_queue.job_iter('vector'): + logging.info(f'Processing {job.type} job {job.id} session {job["session_id"]} from {job.client} submitted {job.created}') + with job: + job.result = subprocess.call(['sudo', '/usr/local/sbin/gerbolyze_vector.sh', job['session_id'], job['side']]) + logging.info(f'Finishied processing {job.type} job {job.id}') + logging.info('Caught SIGINT. Exiting.') + diff --git a/gerboweb/job_queue.py b/gerboweb/job_queue.py new file mode 100644 index 0000000..e48379d --- /dev/null +++ b/gerboweb/job_queue.py @@ -0,0 +1,88 @@ + +import json +import sqlite3 + +class JobQueue: + def __init__(self, dbfile): + self.dbfile = dbfile + self.db = sqlite3.connect(dbfile, check_same_thread=False) + self.db.row_factory = sqlite3.Row + with self.db as conn: + conn.execute('''CREATE TABLE IF NOT EXISTS jobs + (id INTEGER PRIMARY KEY, + type TEXT, + params TEXT, + client TEXT, + result TEXT DEFAULT NULL, + created DATETIME DEFAULT CURRENT_TIMESTAMP, + consumed DATETIME DEFAULT NULL, + aborted DATETIME DEFAULT NULL, + finished DATETIME DEFAULT NULL);''') + + def enqueue(self, task_type:str, client, **params): + """ Enqueue a job of the given type with the given params. Returns the new job ID. """ + with self.db as conn: + return conn.execute('INSERT INTO jobs(type, client, params) VALUES (?, ?, ?)', + (task_type, client, json.dumps(params))).lastrowid + + def check_result(slef, job_id): + with self.db as conn: + job = conn.execute('SELECT * FROM jobs WHERE id=?', (job_id,)).fetchone() + if job is None: + raise IndexError('Job id not found') + return job.result + + def drop(self, job_id): + with self.db as conn: + return conn.execute('DELETE FROM jobs WHERE id=?', (job_id,)).rowcount > 0 + + def pop(self, task_type): + """ Fetch the next job of the given type. Returns a sqlite3.Row object of the job or None if no jobs of the given + type are queued. """ + with self.db as conn: + job = conn.execute('SELECT * FROM jobs WHERE type=? AND consumed IS NULL ORDER BY created ASC LIMIT 1', + (task_type,)).fetchone() + if job is None: + return None + + # Atomically commit to this job + conn.execute('UPDATE jobs SET consumed=datetime("now") WHERE id=?', (job['id'],)) + + return Job(self.db, job) + + def job_iter(self, task_type): + return iter(lambda: self.pop(task_type), None) + + def __getitem__(self, key): + """ Return the job with the given ID, or raise a KeyError if the key cannot be found. """ + with self.db as conn: + job = conn.execute('SELECT * FROM jobs WHERE id=?', (key,)).fetchone() + if job is None: + raise KeyError(f'Unknown job ID "{key}"') + + return Job(self.db, job) + +class Job(dict): + def __init__(self, db, row): + super().__init__(json.loads(row['params'])) + self._db = db + self._row = row + self.id = row['id'] + self.type = row['type'] + self.client = row['client'] + self.created = row['created'] + self.consumed = row['consumed'] + self.finished = row['finished'] + self.result = None + + def __enter__(self): + return self + + def __exit__(self, _exc_type, _exc_val, _exc_tb): + with self._db as conn: + conn.execute('UPDATE jobs SET finished=datetime("now"), result=? WHERE id=?', (self.result, self.id,)) + + def abort(self): + with self._db as conn: + conn.execute('UPDATE jobs SET aborted=datetime("now") WHERE id=?', (self.id,)) + diff --git a/gerboweb/templates/index.html b/gerboweb/templates/index.html new file mode 100644 index 0000000..c5c8503 --- /dev/null +++ b/gerboweb/templates/index.html @@ -0,0 +1,86 @@ + + + + Gerbolyze Raster image to PCB renderer + + +
+

Raster image to PCB converter

+

+ Gerbolyze is a tool for rendering black and white raster (PNG) images directly onto gerber layers. You can + use this to put art on a PCB's silkscreen, solder mask or copper layers. The input is a black-and-white PNG + image that is vectorized and rendered into an existing gerber file. Gerbolyze works with gerber files + produced with any EDA toolchain and has been tested to work with both Altium and KiCAD. +

+
+ +
+

Step 1: Upload zipped gerber files

+

+ First, upload a zip file containing all your gerber files. The default file names used by KiCAD, Eagle + and Altium are supported. +

+ +
+ {{gerber_form.csrf_token}} + {{gerber_form.upload_file.label}} {{gerber_form.upload_file(size=20)}} + +
+
+ + {% if 'render_job' in session or has_renders %} +
+

Step 2: Download the target side's preview image

+

+ Second, download either the top or bottom preview image and use it to align and scale your own artwork + in an image editing program such as Gimp. Then upload your overlay image below. + + Note that you will have to convert grayscale images into binary images yourself. Gerbolyze can't do this + for you since there are lots of variables involved. Our Guideline on image processing gives an overview on + one way to produce agreeable binary images from grayscale source material. +

+ {% if 'render_job' in session %} + Processing... (this may take several minutes!) + {% else %} + Download + Download + {% endif %} +
+ {{reset_form.csrf_token}} + +
+
+ +
+

Step 3: Upload overlay image

+

+ Now, upload your binary overlay image as a PNG and let gerbolyze render it onto the target layer. The PNG + file should be a black and white binary file with details generally above about 10px size. Antialiased + edges are supported. +

+
+ {{overlay_form.csrf_token}} + {{overlay_form.upload_file.label}} {{overlay_form.upload_file(size=20)}} + {{overlay_form.side.label}} {{overlay_form.side()}} + +
+
+ + {% if 'vector_job' in session or has_output %} +
+

Step 4: Download the processed gerber files

+ {% if 'vector_job' in session %} + Processing... (this may take several minutes!) + {% else %} + Download + {% endif %} +
+ {{reset_form.csrf_token}} + +
+
+ {% endif %} {# vector job #} + {% endif %} {# render job #} + + -- cgit From dabe1d8809348cf82c82b9a871f0509e1403a8cd Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 27 Mar 2019 23:08:20 +0900 Subject: Deployment to digitalocean works --- gerboweb/deploy/gerboweb-job-processor.service | 9 ++ gerboweb/deploy/inventory.yml | 7 ++ gerboweb/deploy/nginx.conf | 98 +++++++++++++++++++ gerboweb/deploy/playbook.yml | 125 +++++++++++++++++++------ gerboweb/deploy/tmpfiles-gerboweb.conf | 1 + gerboweb/deploy/uwsgi-app@.service | 15 +++ gerboweb/deploy/uwsgi-app@.socket | 11 +++ gerboweb/deploy/uwsgi-gerboweb.ini | 14 +++ gerboweb/gerboweb.py | 4 +- 9 files changed, 252 insertions(+), 32 deletions(-) create mode 100644 gerboweb/deploy/gerboweb-job-processor.service create mode 100644 gerboweb/deploy/inventory.yml create mode 100644 gerboweb/deploy/nginx.conf create mode 100644 gerboweb/deploy/tmpfiles-gerboweb.conf create mode 100644 gerboweb/deploy/uwsgi-app@.service create mode 100644 gerboweb/deploy/uwsgi-app@.socket create mode 100644 gerboweb/deploy/uwsgi-gerboweb.ini (limited to 'gerboweb') diff --git a/gerboweb/deploy/gerboweb-job-processor.service b/gerboweb/deploy/gerboweb-job-processor.service new file mode 100644 index 0000000..8569317 --- /dev/null +++ b/gerboweb/deploy/gerboweb-job-processor.service @@ -0,0 +1,9 @@ +[Unit] +Description=Gerboweb gerber job processor + +[Service] +WorkingDirectory=/var/lib/gerboweb +ExecStart=/usr/bin/python3 job_processor.py /var/cache/gerboweb/job_queue.sqlite3 + +[Install] +WantedBy=uwsgi-app@gerboweb.service diff --git a/gerboweb/deploy/inventory.yml b/gerboweb/deploy/inventory.yml new file mode 100644 index 0000000..34e2e99 --- /dev/null +++ b/gerboweb/deploy/inventory.yml @@ -0,0 +1,7 @@ +--- +all: + hosts: + wendelstein: + ansible_host: wendelstein.jaseg.net + ansible_ssh_identity_file: ~/.ssh/id_ed25519 + ansible_user: root diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf new file mode 100644 index 0000000..22b3be2 --- /dev/null +++ b/gerboweb/deploy/nginx.conf @@ -0,0 +1,98 @@ +# For more information on configuration, see: +# * Official English Documentation: http://nginx.org/en/docs/ +# * Official Russian Documentation: http://nginx.org/ru/docs/ + +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 4096; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; + + server { + listen 80 default_server; + listen [::]:80 default_server; + server_name gerbolyze.jaseg.net; + root /usr/share/nginx/html; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location ^~ /static/ { + root /var/lib/gerboweb/static; + } + + location / { + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/gerboweb.socket; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } + +# Settings for a TLS enabled server. +# +# server { +# listen 443 ssl http2 default_server; +# listen [::]:443 ssl http2 default_server; +# server_name _; +# root /usr/share/nginx/html; +# +# ssl_certificate "/etc/pki/nginx/server.crt"; +# ssl_certificate_key "/etc/pki/nginx/private/server.key"; +# ssl_session_cache shared:SSL:1m; +# ssl_session_timeout 10m; +# ssl_ciphers PROFILE=SYSTEM; +# ssl_prefer_server_ciphers on; +# +# # Load configuration files for the default server block. +# include /etc/nginx/default.d/*.conf; +# +# location / { +# } +# +# error_page 404 /404.html; +# location = /40x.html { +# } +# +# error_page 500 502 503 504 /50x.html; +# location = /50x.html { +# } +# } + +} + diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index a510772..eb4f367 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -1,33 +1,30 @@ - name: Gerbolyze container setup playbook - hosts: localhost - connection: local + hosts: all tasks: + - name: Create container image file + command: truncate -s 4G /var/cache/gerbolyze_container.img + args: + creates: /var/cache/gerbolyze_container.img + register: create_container + - name: Download arch bootstrap image get_url: url: http://mirror.rackspace.com/archlinux/iso/2019.03.01/archlinux-bootstrap-2019.03.01-x86_64.tar.gz dest: /tmp/arch-bootstrap.tar.xz checksum: sha256:865c8a25312b663e724923eecf0dfc626f4cd621e2cfcb19eafc69a4fc666756 + when: create_container is changed - name: Install host requisites - become: yes dnf: - name: btrfs-progs,arch-install-scripts + name: btrfs-progs,arch-install-scripts,nginx,uwsgi,python3-flask,python3-flask-wtf,systemd-container,uwsgi-plugin-python3 state: latest - - name: Create container image file - become: yes - shell: truncate -s 4G /var/cache/gerbolyze_container.img - args: - creates: /var/cache/gerbolyze_container.img - - name: Create container image filesystem - become: yes filesystem: dev: /var/cache/gerbolyze_container.img fstype: btrfs - name: Create container image fstab entry - become: yes mount: src: /var/cache/gerbolyze_container.img path: /var/cache/gerbolyze_container @@ -36,7 +33,6 @@ opts: loop - name: Unpack bootstrap image - become: yes unarchive: remote_src: yes src: /tmp/arch-bootstrap.tar.xz @@ -45,56 +41,125 @@ creates: /var/cache/gerbolyze_container/etc - name: Copy mirrorlist into container - become: yes copy: src: mirrorlist dest: /var/cache/gerbolyze_container/etc/pacman.d/mirrorlist - name: Copy render script - become: yes copy: src: render.sh dest: /usr/local/sbin/gerbolyze_render.sh mode: ug+x - name: Copy vector script - become: yes copy: src: vector.sh dest: /usr/local/sbin/gerbolyze_vector.sh mode: ug+x - name: Initialize container pacman keyring - become: yes shell: arch-chroot /var/cache/gerbolyze_container pacman-key --init && arch-chroot /var/cache/gerbolyze_container pacman-key --populate archlinux args: creates: /var/cache/gerbolyze_container/etc/pacman.d/gnupg - name: Fixup pacman.conf for pacman to work in chroot without its own root fs - become: yes lineinfile: path: /var/cache/gerbolyze_container/etc/pacman.conf regexp: '^CheckSpace' line: '#CheckSpace' - name: Update container and install software - become: yes shell: arch-chroot /var/cache/gerbolyze_container pacman -Syu --noconfirm python3 opencv hdf5 gtk3 python-numpy python-pip imagemagick unzip zip # TODO maybe install directly from local git checkout? - name: Install gerbolyze - become: yes shell: arch-chroot /var/cache/gerbolyze_container pip install -U --upgrade-strategy=eager gerbolyze - # - name: Cleanup bootstrap image - # file: - # path: /tmp/arch-bootstrap.tar.xz - # state: absent - - - name: Create app cache directory + - name: Cleanup bootstrap image file: - path: /var/cache/gerboweb - owner: user # FIXME debug - group: user # FIXME debug - mode: 0770 + path: /tmp/arch-bootstrap.tar.xz + state: absent + + - name: Copy webapp sources + synchronize: + # FIXME: make this path configurable + src: ~/gerbolyze/gerboweb/ + dest: /var/lib/gerboweb/ + group: no + owner: no + + - name: Copy nginx config + copy: + src: nginx.conf + dest: /etc/nginx/nginx.conf + + - name: Create uwsgi worker user and group + user: + name: uwsgi-gerboweb + create_home: no + group: uwsgi + password: '!' + shell: /sbin/nologin + system: yes + + - name: Add nginx user to uwsgi group for access to uwsgi socket + user: + name: nginx + groups: uwsgi + append: yes + + - name: Copy uwsgi config + copy: + src: uwsgi-gerboweb.ini + dest: /etc/uwsgi.d/gerboweb.ini + owner: uwsgi-gerboweb + group: uwsgi + mode: 440 + + - name: Copy uwsgi systemd socket config + copy: + src: uwsgi-app@.socket + dest: /etc/systemd/system/ + + - name: Copy uwsgi systemd service config + copy: + src: uwsgi-app@.service + dest: /etc/systemd/system/ + + - name: Copy job processor systemd service config + copy: + src: gerboweb-job-processor.service + dest: /etc/systemd/system/ + + - name: Enable uwsgi systemd socket + systemd: + daemon-reload: yes + name: uwsgi-app@gerboweb.socket + enabled: yes + + - name: Enable and launch uwsgi systemd service + systemd: + name: uwsgi-app@gerboweb.service + enabled: yes + state: restarted + + - name: Enable and launch job processor + systemd: + name: gerboweb-job-processor.service + enabled: yes + state: restarted + + - name: Enable and launch nginx systemd service + systemd: + name: nginx.service + enabled: yes + state: restarted + + - name: Copy gerboweb cache dir tmpfiles.d config + copy: + src: tmpfiles-gerboweb.conf + dest: /etc/tmpfiles.d/gerboweb.conf + owner: root + group: root + mode: 0644 diff --git a/gerboweb/deploy/tmpfiles-gerboweb.conf b/gerboweb/deploy/tmpfiles-gerboweb.conf new file mode 100644 index 0000000..33264cf --- /dev/null +++ b/gerboweb/deploy/tmpfiles-gerboweb.conf @@ -0,0 +1 @@ +d /var/cache/gerboweb 760 uwsgi-gerboweb uwsgi 2d diff --git a/gerboweb/deploy/uwsgi-app@.service b/gerboweb/deploy/uwsgi-app@.service new file mode 100644 index 0000000..61bf1e4 --- /dev/null +++ b/gerboweb/deploy/uwsgi-app@.service @@ -0,0 +1,15 @@ +[Unit] +Description=%i uWSGI app +After=syslog.target + +[Service] +ExecStart=/usr/sbin/uwsgi \ + --ini /etc/uwsgi.d/%i.ini \ + --socket /run/uwsgi/%i.socket +User=uwsgi-%i +Group=uwsgi +Restart=on-failure +KillSignal=SIGQUIT +Type=notify +StandardError=syslog +NotifyAccess=all diff --git a/gerboweb/deploy/uwsgi-app@.socket b/gerboweb/deploy/uwsgi-app@.socket new file mode 100644 index 0000000..ae06d71 --- /dev/null +++ b/gerboweb/deploy/uwsgi-app@.socket @@ -0,0 +1,11 @@ +[Unit] +Description=Socket for uWSGI app %i + +[Socket] +ListenStream=/run/uwsgi/%i.socket +SocketUser=uwsgi-%i +SocketGroup=nginx +SocketMode=0660 + +[Install] +WantedBy=sockets.target diff --git a/gerboweb/deploy/uwsgi-gerboweb.ini b/gerboweb/deploy/uwsgi-gerboweb.ini new file mode 100644 index 0000000..748af71 --- /dev/null +++ b/gerboweb/deploy/uwsgi-gerboweb.ini @@ -0,0 +1,14 @@ +[uwsgi] +chmod-socket = 660 +master = True +cheap = True +idle = 600 +die-on-idle = True # If app is not used often, it will exit and be launched + # again by systemd requested by users. + +manage-script-name = True +plugins = python3 +chdir = /var/lib/gerboweb +mount = /=gerboweb:app +env = GERBOWEB_SETTINGS=gerboweb.cfg + diff --git a/gerboweb/gerboweb.py b/gerboweb/gerboweb.py index bf2921a..6b579f0 100644 --- a/gerboweb/gerboweb.py +++ b/gerboweb/gerboweb.py @@ -14,7 +14,7 @@ import sqlite3 from flask import Flask, url_for, redirect, session, make_response, render_template, request, send_file, abort from flask_wtf import FlaskForm -from flask_wtf.file import FileField +from flask_wtf.file import FileField, FileRequired from wtforms.fields import RadioField from wtforms.validators import DataRequired from werkzeug.utils import secure_filename @@ -28,7 +28,7 @@ class UploadForm(FlaskForm): upload_file = FileField(validators=[DataRequired()]) class OverlayForm(UploadForm): - upload_file = FileField(validators=[DataRequired()]) + upload_file = FileField(validators=[FileRequired()]) side = RadioField('Side', choices=[('top', 'Top'), ('bottom', 'Bottom')]) class ResetForm(FlaskForm): -- cgit From 84148e368d3804c841d566cd0a8f28263445ef97 Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 28 Mar 2019 01:50:07 +0900 Subject: gerboweb: Add HTTPS via letsencrypt --- gerboweb/deploy/nginx.conf | 50 ++++++++++++++++++-------------------------- gerboweb/deploy/playbook.yml | 17 ++++++++++++++- gerboweb/gerboweb.py | 3 --- 3 files changed, 36 insertions(+), 34 deletions(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index 22b3be2..c76a3db 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -39,8 +39,28 @@ http { listen 80 default_server; listen [::]:80 default_server; server_name gerbolyze.jaseg.net; + return 301 https://$host$request_uri; + } + + server { + listen 443 ssl http2 default_server; + listen [::]:443 ssl http2 default_server; + server_name gerbolyze.jaseg.net; root /usr/share/nginx/html; + ssl_certificate "/etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/gerbolyze.jaseg.net/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; @@ -64,35 +84,5 @@ http { } } -# Settings for a TLS enabled server. -# -# server { -# listen 443 ssl http2 default_server; -# listen [::]:443 ssl http2 default_server; -# server_name _; -# root /usr/share/nginx/html; -# -# ssl_certificate "/etc/pki/nginx/server.crt"; -# ssl_certificate_key "/etc/pki/nginx/private/server.key"; -# ssl_session_cache shared:SSL:1m; -# ssl_session_timeout 10m; -# ssl_ciphers PROFILE=SYSTEM; -# ssl_prefer_server_ciphers on; -# -# # Load configuration files for the default server block. -# include /etc/nginx/default.d/*.conf; -# -# location / { -# } -# -# error_page 404 /404.html; -# location = /40x.html { -# } -# -# error_page 500 502 503 504 /50x.html; -# location = /50x.html { -# } -# } - } diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index eb4f367..3789c21 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -16,7 +16,7 @@ - name: Install host requisites dnf: - name: btrfs-progs,arch-install-scripts,nginx,uwsgi,python3-flask,python3-flask-wtf,systemd-container,uwsgi-plugin-python3 + name: btrfs-progs,arch-install-scripts,nginx,uwsgi,python3-flask,python3-flask-wtf,systemd-container,uwsgi-plugin-python3,certbot,python3-certbot-nginx state: latest - name: Create container image filesystem @@ -131,6 +131,21 @@ src: gerboweb-job-processor.service dest: /etc/systemd/system/ + - name: Set SELinux to permissive mode # FIXME + selinux: + state: permissive + policy: targeted + + - name: Create letsencrypt certificate + command: certbot --nginx certonly -d gerbolyze.jaseg.net -n --agree-tos --email gerboweb@jaseg.net + args: + creates: /etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem + + - name: Enable certbot renewal timer + systemd: + name: certbot-renew.timer + enabled: yes + - name: Enable uwsgi systemd socket systemd: daemon-reload: yes diff --git a/gerboweb/gerboweb.py b/gerboweb/gerboweb.py index 6b579f0..17e03e2 100644 --- a/gerboweb/gerboweb.py +++ b/gerboweb/gerboweb.py @@ -1,8 +1,5 @@ #!/usr/bin/env python3 -# TODO create systemd unit file -# TODO create systemd tmpfiles.d config -# TODO setup ansible deployment # TODO setup webserver user disk quota import tempfile -- cgit From 23d392c2f7a744d38a369f8bc91cfd0f215f82b0 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 29 Mar 2019 22:09:16 +0900 Subject: Working on the design --- gerboweb/deploy/nginx.conf | 2 +- gerboweb/deploy/playbook.yml | 6 - gerboweb/deploy/uwsgi-gerboweb.ini | 1 - gerboweb/gerboweb.py | 10 +- gerboweb/static/style.css | 241 +++++++++++++++++++++++++++++++++++++ gerboweb/templates/index.html | 217 +++++++++++++++++++++------------ 6 files changed, 388 insertions(+), 89 deletions(-) create mode 100644 gerboweb/static/style.css (limited to 'gerboweb') diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index c76a3db..6344904 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -65,7 +65,7 @@ http { include /etc/nginx/default.d/*.conf; location ^~ /static/ { - root /var/lib/gerboweb/static; + root /var/lib/gerboweb; } location / { diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 3789c21..9753df6 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -152,12 +152,6 @@ name: uwsgi-app@gerboweb.socket enabled: yes - - name: Enable and launch uwsgi systemd service - systemd: - name: uwsgi-app@gerboweb.service - enabled: yes - state: restarted - - name: Enable and launch job processor systemd: name: gerboweb-job-processor.service diff --git a/gerboweb/deploy/uwsgi-gerboweb.ini b/gerboweb/deploy/uwsgi-gerboweb.ini index 748af71..3c8addd 100644 --- a/gerboweb/deploy/uwsgi-gerboweb.ini +++ b/gerboweb/deploy/uwsgi-gerboweb.ini @@ -1,5 +1,4 @@ [uwsgi] -chmod-socket = 660 master = True cheap = True idle = 600 diff --git a/gerboweb/gerboweb.py b/gerboweb/gerboweb.py index 17e03e2..1f8d884 100644 --- a/gerboweb/gerboweb.py +++ b/gerboweb/gerboweb.py @@ -9,7 +9,7 @@ from os import path import os import sqlite3 -from flask import Flask, url_for, redirect, session, make_response, render_template, request, send_file, abort +from flask import Flask, url_for, redirect, session, make_response, render_template, request, send_file, abort, flash from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileRequired from wtforms.fields import RadioField @@ -26,7 +26,7 @@ class UploadForm(FlaskForm): class OverlayForm(UploadForm): upload_file = FileField(validators=[FileRequired()]) - side = RadioField('Side', choices=[('top', 'Top'), ('bottom', 'Bottom')]) + side = RadioField('Side', choices=[('top', 'Top'), ('bottom', 'Bottom')], default=lambda: session.get('last_download')) class ResetForm(FlaskForm): pass @@ -56,6 +56,7 @@ def require_session_id(fun): @app.route('/') @require_session_id def index(): + flash(f'Gerber file successfully uploaded.', 'success') forms = { 'gerber_form': UploadForm(), 'overlay_form': OverlayForm(), @@ -108,6 +109,7 @@ def upload(namespace): session_id=session['session_id'], side=upload_form.side.data) + flash(f'{"Gerber" if namespace == "gerber" else "Overlay"} file successfully uploaded.', 'success') return redirect(url_for('index')) @app.route('/render/preview/') @@ -120,10 +122,12 @@ def render_preview(side): def render_download(side): if not side in ('top', 'bottom'): return abort(400, 'side must be either "top" or "bottom"') + + session['last_download'] = side return send_file(tempfile_path(f'render_{side}.png'), mimetype='image/png', as_attachment=True, - attachment_filename=f'{path.splitext(session["filename"])[0]}_render.png') + attachment_filename=f'{path.splitext(session["filename"])[0]}_render_{side}.png') @app.route('/output/download') def output_download(): diff --git a/gerboweb/static/style.css b/gerboweb/static/style.css new file mode 100644 index 0000000..975c7f2 --- /dev/null +++ b/gerboweb/static/style.css @@ -0,0 +1,241 @@ + +:root { + --c-blue1: #19aeff; + --c-blue2: #0084c8; + --c-blue3: #005c94; + --c-red1: #ff4141; + --c-red2: #dc0000; + --c-red3: #b50000; + --c-orange1: #ffff3e; + --c-orange2: #ff9900; + --c-orange3: #ff6600; + --c-brown1: #ffc022; + --c-brown2: #b88100; + --c-brown3: #804d00; + --c-green1: #ccff42; + --c-green2: #9ade00; + --c-green3: #009100; + --c-purple1: #f1caff; + --c-purple2: #d76cff; + --c-purple3: #ba00ff; + --c-metallic1: #bdcdd4; + --c-metallic2: #9eabb0; + --c-metallic3: #364e59; + --c-metallic4: #0e232e; + --c-grey1: #ffffff; + --c-grey2: #cccccc; + --c-grey3: #999999; + --c-grey4: #666666; + --c-grey5: #2d2d2d; + + --cg1: #003018; + --cg2: #006130; + --cg3: #00964a; + --cg4: #00d167; + --cg5: #4cffa4; + --cg6: #b7ffda; + --cg7: #e1fff0; +} + +body { + font-family: 'Helvetica', 'Arial', sans-serif; + color: var(--c-metallic4); + display: flex; + flex-direction: row; + justify-content: center; + margin: 0; + background-color: hsl(10 10% 97%); +} + +.layout-container { + flex-basis: 55em; + flex-shrink: 1; + flex-grow: 0; + padding: 3em; + background-color: white; +} + +div.flash-success { + background-color: var(--c-green1); + color: hsl(80 20% 20%); + text-shadow: 0 0 2px var(--c-green1); + border-radius: 5px; + margin: 1em; + padding-left: 3em; + padding-right: 3em; + padding-top: 2em; + padding-bottom: 2em; +} + +div.flash-success::before { + content: "Success!"; + display: block; + font-weight: bold; + font-size: 16pt; + margin-right: 1em; + margin-bottom: 0.5em; +} + +div.desc { + margin-top: 5em; + margin-bottom: 7em; +} + +div.loading-message { + text-align: center; + margin-top: 2em; +} + +.steps { + display: flex; + flex-direction: column; +} + +.step { + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: center; + flex-wrap: wrap; + width: 100%; + padding-top: 20px; +} + +.step > .description { + flex-basis: 20em; + flex-shrink: 0; + flex-grow: 0; + margin-left: 20px; + + overflow-wrap: break-word; + word-wrap: break-word; + hyphens: auto; + text-align: justify; +} + +.step > .description > h2 { + text-align: right; + margin-top: 0 +} + +.step > .controls { + flex-grow: 1; + flex-shrink: 1; + display: flex; + flex-direction: column; + align-items: stretch; + margin-right: 20px; + margin-left: 20px; + + padding: 1em; + + background-color: hsl(210 40% 97%); + border-radius: 5px; +} + +input.reset-button { + background-color: var(--c-red1); + color: var(--c-grey1); + text-shadow: 0 0 2px var(--c-red3); + border: 0; + border-radius: 5px; + padding: 0.5em 1em 0.5em 1em; +} + +input.submit-button { + background-color: var(--c-green2); + color: hsl(80 20% 20%); + text-shadow: 0 0 2px var(--c-green1); + font-weight: bold; + margin-left: 1em; + border: 0; + border-radius: 5px; + padding: 0.5em 1em 0.5em 1em; +} + +.controls > .form-controls { + margin-bottom: 1em; +} + +.controls > .submit-buttons { + margin-top: 1em; + text-align: right; +} + +.controls > .download-controls { + padding: 1em; + margin-bottom: 1em; + display: flex; + flex-direction: column; + align-items: center; +} + +a.output-download:link, a.output-download:hover, a.output-download:visited, a.output-download:active { + font-size: 30pt; + font-weight: bold; + color: var(--c-metallic4); + text-shadow: 0.5px 0.5px 0.5px var(--c-metallic2); +} + +.preview-images { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: flex-start; + justify-content: space-around; +} + +.preview { + width: 200px; + height: 200px; + border-radius: 5px; + display: flex; + justify-content: center; + align-items: center; +} + +a.overlay:link, a.overlay:hover, a.overlay:visited, a.overlay:active { + text-align: center; + font-size: 30pt; + font-weight: bold; + color: var(--c-metallic4); + text-shadow: 0.5px 0.5px 0.5px var(--c-metallic2); +} + +/* Spinner from https://loading.io/css/ */ +.lds-ring { + display: inline-block; + position: relative; + width: 64px; + height: 64px; +} +.lds-ring div { + box-sizing: border-box; + display: block; + position: absolute; + width: 51px; + height: 51px; + margin: 6px; + border: 6px solid var(--c-metallic4); + border-radius: 50%; + animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; + border-color: var(--c-metallic4) transparent transparent transparent; +} +.lds-ring div:nth-child(1) { + animation-delay: -0.45s; +} +.lds-ring div:nth-child(2) { + animation-delay: -0.3s; +} +.lds-ring div:nth-child(3) { + animation-delay: -0.15s; +} +@keyframes lds-ring { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + diff --git a/gerboweb/templates/index.html b/gerboweb/templates/index.html index c5c8503..3e4c255 100644 --- a/gerboweb/templates/index.html +++ b/gerboweb/templates/index.html @@ -1,86 +1,147 @@ - - - Gerbolyze Raster image to PCB renderer - - -
-

Raster image to PCB converter

-

- Gerbolyze is a tool for rendering black and white raster (PNG) images directly onto gerber layers. You can - use this to put art on a PCB's silkscreen, solder mask or copper layers. The input is a black-and-white PNG - image that is vectorized and rendered into an existing gerber file. Gerbolyze works with gerber files - produced with any EDA toolchain and has been tested to work with both Altium and KiCAD. -

-
+ + + Gerbolyze Raster image to PCB renderer + + + +
+
+

Raster image to PCB converter

+

+ Gerbolyze is a tool for rendering black and white raster (PNG) images directly onto gerber layers. You can + use this to put art on a PCB's silkscreen, solder mask or copper layers. The input is a black-and-white PNG + image that is vectorized and rendered into an existing gerber file. Gerbolyze works with gerber files + produced with any EDA toolchain and has been tested to work with both Altium and KiCAD. +

+
-
-

Step 1: Upload zipped gerber files

-

- First, upload a zip file containing all your gerber files. The default file names used by KiCAD, Eagle - and Altium are supported. -

+ {% with messages = get_flashed_messages(with_categories=True) %} + {% if messages %} +
+ {% for category, message in messages %} +
{{ message }}
+ {% endfor %} +
+ {% endif %} + {% endwith %} -
- {{gerber_form.csrf_token}} - {{gerber_form.upload_file.label}} {{gerber_form.upload_file(size=20)}} - -
-
+
{{reset_form.csrf_token}}
- {% if 'render_job' in session or has_renders %} -
-

Step 2: Download the target side's preview image

-

- Second, download either the top or bottom preview image and use it to align and scale your own artwork - in an image editing program such as Gimp. Then upload your overlay image below. +

+
+
+

Step 1: Upload zipped gerber files

+

+ First, upload a zip file containing all your gerber files. The default file names used by KiCAD, Eagle + and Altium are supported. +

+
- Note that you will have to convert grayscale images into binary images yourself. Gerbolyze can't do this - for you since there are lots of variables involved. Our Guideline on image processing gives an overview on - one way to produce agreeable binary images from grayscale source material. -

- {% if 'render_job' in session %} - Processing... (this may take several minutes!) - {% else %} - Download - Download - {% endif %} -
- {{reset_form.csrf_token}} - -
-
+
+
+ {{gerber_form.csrf_token}} +
+
+
Upload Gerber file:
+ +
+
+ + +
+
+
-
-

Step 3: Upload overlay image

-

- Now, upload your binary overlay image as a PNG and let gerbolyze render it onto the target layer. The PNG - file should be a black and white binary file with details generally above about 10px size. Antialiased - edges are supported. -

-
- {{overlay_form.csrf_token}} - {{overlay_form.upload_file.label}} {{overlay_form.upload_file(size=20)}} - {{overlay_form.side.label}} {{overlay_form.side()}} - -
-
+ {% if 'render_job' in session or has_renders %} +
+
+

Step 2: Download the target side's preview image

+

+ Second, download either the top or bottom preview image and use it to align and scale your own artwork + in an image editing program such as Gimp. Then upload your overlay image below. - {% if 'vector_job' in session or has_output %} -

-

Step 4: Download the processed gerber files

- {% if 'vector_job' in session %} - Processing... (this may take several minutes!) - {% else %} - Download - {% endif %} -
- {{reset_form.csrf_token}} - -
-
- {% endif %} {# vector job #} - {% endif %} {# render job #} - + Note that you will have to convert grayscale images into binary images yourself. Gerbolyze can't do this + for you since there are lots of variables involved. Our Guideline on image processing gives an overview on + one way to produce agreeable binary images from grayscale source material. +

+
+
+ {% if 'render_job' in session %} + Processing... (this may take several minutes!) + {% else %} + + {% endif %} +
+ +
+
+
+ +
+
+

Step 3: Upload overlay image

+

+ Now, upload your binary overlay image as a PNG and let gerbolyze render it onto the target layer. The PNG + file should be a black and white binary file with details generally above about 10px size. Antialiased + edges are supported. +

+
+
+
+ {{overlay_form.csrf_token}} +
+
+
Upload Overlay PNG file:
+ +
+
+
Target layer:
+ + + + +
+
+ + +
+
+
+ + {% if 'vector_job' in session or has_output %} +
+
+

Step 4: Download the processed gerber files

+
+
+ {# if 'vector_job' in session FIXME #} + {% if True %} +
+
+
Processing...
+
(this may take several minutes!)
+
+ {% else %} + + {% endif %} +
+ +
+
+
+ {% endif %} {# vector job #} + {% endif %} {# render job #} +
+
+ -- cgit From 6b4eac36d6ff46881b26a36556a07280ccd69783 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sat, 30 Mar 2019 04:01:03 +0900 Subject: gerboweb: Initial design revision --- gerboweb/deploy/render.sh | 4 +- gerboweb/gerboweb.py | 69 +++++++++++-------- gerboweb/static/bg.jpg | Bin 0 -> 331765 bytes gerboweb/static/bg10.jpg | Bin 0 -> 177533 bytes gerboweb/static/sample1.jpg | Bin 0 -> 299841 bytes gerboweb/static/sample2.jpg | Bin 0 -> 251440 bytes gerboweb/static/sample3.jpg | Bin 0 -> 171160 bytes gerboweb/static/style.css | 149 +++++++++++++++++++++++++++++++++++------- gerboweb/templates/index.html | 63 +++++++++++------- 9 files changed, 207 insertions(+), 78 deletions(-) create mode 100644 gerboweb/static/bg.jpg create mode 100644 gerboweb/static/bg10.jpg create mode 100644 gerboweb/static/sample1.jpg create mode 100644 gerboweb/static/sample2.jpg create mode 100644 gerboweb/static/sample3.jpg (limited to 'gerboweb') diff --git a/gerboweb/deploy/render.sh b/gerboweb/deploy/render.sh index c3920de..eefe7f0 100755 --- a/gerboweb/deploy/render.sh +++ b/gerboweb/deploy/render.sh @@ -13,8 +13,8 @@ rm -f /mnt/render_top.png /mnt/render_bottom.png /mnt/render_top.small.png /mnt/ date; echo 'Rendering bottom layer' gerbolyze render top /tmp/gerber /mnt/render_top.png date; echo 'Scaling down' -convert /mnt/render_top.png -resize 500x500 /mnt/render_top.small.png +convert /mnt/render_top.png -resize 500x500 -negate -brightness-contrast 30x30 -colorspace gray /mnt/render_top.small.png date; echo 'Rendering top layer' gerbolyze render bottom /tmp/gerber /mnt/render_bottom.png date; echo 'Scaling down' -convert /mnt/render_bottom.png -resize 500x500 /mnt/render_bottom.small.png" +convert /mnt/render_bottom.png -resize 500x500 -negate -brightness-contrast 30x30 -colorspace gray /mnt/render_bottom.small.png" diff --git a/gerboweb/gerboweb.py b/gerboweb/gerboweb.py index 1f8d884..a276d74 100644 --- a/gerboweb/gerboweb.py +++ b/gerboweb/gerboweb.py @@ -26,7 +26,8 @@ class UploadForm(FlaskForm): class OverlayForm(UploadForm): upload_file = FileField(validators=[FileRequired()]) - side = RadioField('Side', choices=[('top', 'Top'), ('bottom', 'Bottom')], default=lambda: session.get('last_download')) + side = RadioField('Side', choices=[('top', 'Top'), ('bottom', 'Bottom')], + default=lambda: session.get('side_selected', session.get('last_download'))) class ResetForm(FlaskForm): pass @@ -56,7 +57,6 @@ def require_session_id(fun): @app.route('/') @require_session_id def index(): - flash(f'Gerber file successfully uploaded.', 'success') forms = { 'gerber_form': UploadForm(), 'overlay_form': OverlayForm(), @@ -79,37 +79,49 @@ def index(): # * The uploaded files are deleted after a while by systemd tmpfiles.d # TODO: validate this setting applies *after* gzip transport compression -@app.route('/upload/', methods=['POST']) +def vectorize(): + if 'vector_job' in session: + job_queue.drop(session['vector_job']) + session['vector_job'] = job_queue.enqueue('vector', + client=request.remote_addr, + session_id=session['session_id'], + side=session['side_selected']) + +def render(): + if 'render_job' in session: + job_queue.drop(session['render_job']) + session['render_job'] = job_queue.enqueue('render', + session_id=session['session_id'], + client=request.remote_addr) + +@app.route('/upload/gerber', methods=['POST']) @require_session_id -def upload(namespace): - if namespace not in ('gerber', 'overlay'): - return abort(400, 'Invalid upload type') +def upload_gerber(): + upload_form = UploadForm() + if upload_form.validate_on_submit(): + f = upload_form.upload_file.data + f.save(tempfile_path('gerber.zip')) + session['filename'] = secure_filename(f.filename) # Cache filename for later download - upload_form = UploadForm() if namespace == 'gerber' else OverlayForm() + render() + if path.isfile(tempfile_path('overlay.png')): # Re-vectorize when gerbers change + vectorize() + + flash(f'Gerber file successfully uploaded.', 'success') + return redirect(url_for('index')) + +@app.route('/upload/overlay', methods=['POST']) +@require_session_id +def upload_overlay(): + upload_form = OverlayForm() if upload_form.validate_on_submit(): f = upload_form.upload_file.data + f.save(tempfile_path('overlay.png')) + session['side_selected'] = upload_form.side.data + + vectorize() - if namespace == 'gerber': - f.save(tempfile_path('gerber.zip')) - session['filename'] = secure_filename(f.filename) # Cache filename for later download - if 'render_job' in session: - job_queue.drop(session['render_job']) - session['render_job'] = job_queue.enqueue('render', - session_id=session['session_id'], - client=request.remote_addr) - else: # namespace == 'vector' - f.save(tempfile_path('overlay.png')) - - # Re-vectorize if either file has changed - if path.isfile(tempfile_path('gerber.zip')) and path.isfile(tempfile_path('overlay.png')): - if 'vector_job' in session: - job_queue.drop(session['vector_job']) - session['vector_job'] = job_queue.enqueue('vector', - client=request.remote_addr, - session_id=session['session_id'], - side=upload_form.side.data) - - flash(f'{"Gerber" if namespace == "gerber" else "Overlay"} file successfully uploaded.', 'success') + flash(f'Overlay file successfully uploaded.', 'success') return redirect(url_for('index')) @app.route('/render/preview/') @@ -144,5 +156,6 @@ def session_reset(): if 'vector_job' in session: session['vector_job'].abort() session.clear() + flash('Session reset', 'success'); return redirect(url_for('index')) diff --git a/gerboweb/static/bg.jpg b/gerboweb/static/bg.jpg new file mode 100644 index 0000000..94856fc Binary files /dev/null and b/gerboweb/static/bg.jpg differ diff --git a/gerboweb/static/bg10.jpg b/gerboweb/static/bg10.jpg new file mode 100644 index 0000000..9d14fd3 Binary files /dev/null and b/gerboweb/static/bg10.jpg differ diff --git a/gerboweb/static/sample1.jpg b/gerboweb/static/sample1.jpg new file mode 100644 index 0000000..948da6f Binary files /dev/null and b/gerboweb/static/sample1.jpg differ diff --git a/gerboweb/static/sample2.jpg b/gerboweb/static/sample2.jpg new file mode 100644 index 0000000..ef47bd4 Binary files /dev/null and b/gerboweb/static/sample2.jpg differ diff --git a/gerboweb/static/sample3.jpg b/gerboweb/static/sample3.jpg new file mode 100644 index 0000000..780c080 Binary files /dev/null and b/gerboweb/static/sample3.jpg differ diff --git a/gerboweb/static/style.css b/gerboweb/static/style.css index 975c7f2..ede89d4 100644 --- a/gerboweb/static/style.css +++ b/gerboweb/static/style.css @@ -35,30 +35,61 @@ --cg5: #4cffa4; --cg6: #b7ffda; --cg7: #e1fff0; + + --cr1: #300900; + --cr2: #611200; + --cr3: #961c00; + --cr4: #d12700; + --cr5: #ff6e4c; + --cr6: #ffc5b7; + --cr7: #ffe7e1; + + --cb1: #001b30; + --cb2: #003761; + --cb3: #005596; + --cb4: #0076d1; + --cb5: #4cb1ff; + --cb6: #b7e0ff; + --cb7: #e1f2ff; + --cb8: #f5fbff; } body { font-family: 'Helvetica', 'Arial', sans-serif; - color: var(--c-metallic4); + color: var(--cb1); display: flex; flex-direction: row; justify-content: center; margin: 0; - background-color: hsl(10 10% 97%); + background-color: var(--cb8); } .layout-container { flex-basis: 55em; flex-shrink: 1; flex-grow: 0; - padding: 3em; + padding: 45px; background-color: white; } +div.header { + background-image: url("/static/bg10.jpg"); + background-position: center; + background-size: cover; + background-repeat: no-repeat; + display: flex; + margin-left: -45px; + margin-right: -45px; + margin-bottom: 3em; + padding-left: 3em; + padding-right: 3em; + text-shadow: 1px 1px 1px black; +} + div.flash-success { - background-color: var(--c-green1); - color: hsl(80 20% 20%); - text-shadow: 0 0 2px var(--c-green1); + background-color: var(--cg6); + color: var(--cg1); + text-shadow: 0 0 2px var(--cg7); border-radius: 5px; margin: 1em; padding-left: 3em; @@ -79,6 +110,13 @@ div.flash-success::before { div.desc { margin-top: 5em; margin-bottom: 7em; + + overflow-wrap: break-word; + word-wrap: break-word; + hyphens: auto; + text-align: justify; + + color: white; } div.loading-message { @@ -89,6 +127,7 @@ div.loading-message { .steps { display: flex; flex-direction: column; + counter-reset: step; } .step { @@ -99,6 +138,29 @@ div.loading-message { flex-wrap: wrap; width: 100%; padding-top: 20px; + position: relative; + margin-bottom: 1em; + margin-top: 2em; +} + +.step > .description::before { + counter-increment: step; + content: counter(step); + + font-weight: 700; + font-size: 30px; + text-align: center; + border-radius: 50%; + background-color: var(--cg5); + + display: block; + position: absolute; + top: 15px; + left: 0; + width: 60px; + + line-height: 50px; + padding-top: 10px; } .step > .description { @@ -115,7 +177,9 @@ div.loading-message { .step > .description > h2 { text-align: right; - margin-top: 0 + margin-top: 0; + padding-left: 60px; + height: 60px; } .step > .controls { @@ -124,28 +188,28 @@ div.loading-message { display: flex; flex-direction: column; align-items: stretch; - margin-right: 20px; - margin-left: 20px; + margin-right: 1em; + margin-left: 1em; padding: 1em; - background-color: hsl(210 40% 97%); + background-color: var(--cb8); border-radius: 5px; } input.reset-button { - background-color: var(--c-red1); - color: var(--c-grey1); - text-shadow: 0 0 2px var(--c-red3); + background-color: var(--cr4); + color: white; + text-shadow: 0 0 2px var(--cr1); border: 0; border-radius: 5px; padding: 0.5em 1em 0.5em 1em; } input.submit-button { - background-color: var(--c-green2); - color: hsl(80 20% 20%); - text-shadow: 0 0 2px var(--c-green1); + background-color: var(--cg4); + color: var(--cg1); + text-shadow: 0 0 2px var(--cg7); font-weight: bold; margin-left: 1em; border: 0; @@ -173,8 +237,8 @@ input.submit-button { a.output-download:link, a.output-download:hover, a.output-download:visited, a.output-download:active { font-size: 30pt; font-weight: bold; - color: var(--c-metallic4); - text-shadow: 0.5px 0.5px 0.5px var(--c-metallic2); + color: var(--cb1); + text-shadow: 0.5px 0.5px 0.5px var(--cb6); } .preview-images { @@ -185,21 +249,56 @@ a.output-download:link, a.output-download:hover, a.output-download:visited, a.ou justify-content: space-around; } -.preview { +a.preview:link, a.preview:hover, a.preview:visited, a.preview:active { + text-decoration: none; width: 200px; height: 200px; border-radius: 5px; + margin: 1em; display: flex; justify-content: center; align-items: center; + background-color: var(--cb3); + background-blend-mode: multiply; + background-size: contain; + background-repeat: no-repeat; + background-position: 50% 50%; + box-shadow: 1px 1px 5px 1px #001b304d; } -a.overlay:link, a.overlay:hover, a.overlay:visited, a.overlay:active { +.overlay { text-align: center; - font-size: 30pt; + font-size: 50pt; font-weight: bold; - color: var(--c-metallic4); - text-shadow: 0.5px 0.5px 0.5px var(--c-metallic2); + color: var(--cg4); + mix-blend-mode: screen; +} + +.sample-images { + text-align: center; +} + +.sample-images > h1 { + color: white; + padding-top: 5px; + line-height: 70px; + /* background-image: linear-gradient(to top right, var(--cg5), var(--cg6)); */ + + background-image: url("/static/bg10.jpg"); + background-position: center; + background-size: cover; + background-repeat: no-repeat; + + margin-left: -45px; + margin-right: -45px; + margin-top: 3em; + text-shadow: 1px 1px 1px black; +} + +.sample-images > img { + width: 300px; + height: 300px; + margin: 1em; } /* Spinner from https://loading.io/css/ */ @@ -216,10 +315,10 @@ a.overlay:link, a.overlay:hover, a.overlay:visited, a.overlay:active { width: 51px; height: 51px; margin: 6px; - border: 6px solid var(--c-metallic4); + border: 6px solid var(--cb1); border-radius: 50%; animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - border-color: var(--c-metallic4) transparent transparent transparent; + border-color: var(--cb1) transparent transparent transparent; } .lds-ring div:nth-child(1) { animation-delay: -0.45s; diff --git a/gerboweb/templates/index.html b/gerboweb/templates/index.html index 3e4c255..eeece65 100644 --- a/gerboweb/templates/index.html +++ b/gerboweb/templates/index.html @@ -6,14 +6,16 @@
-
-

Raster image to PCB converter

-

- Gerbolyze is a tool for rendering black and white raster (PNG) images directly onto gerber layers. You can - use this to put art on a PCB's silkscreen, solder mask or copper layers. The input is a black-and-white PNG - image that is vectorized and rendered into an existing gerber file. Gerbolyze works with gerber files - produced with any EDA toolchain and has been tested to work with both Altium and KiCAD. -

+
+
+

Raster image to PCB converter

+

+ Gerbolyze is a tool for rendering black and white raster (PNG) images directly onto gerber layers. You can + use this to put art on a PCB's silkscreen, solder mask or copper layers. The input is a black-and-white PNG + image that is vectorized and rendered into an existing gerber file. Gerbolyze works with gerber files + produced with any EDA toolchain and has been tested to work with both Altium and KiCAD. +

+
{% with messages = get_flashed_messages(with_categories=True) %} @@ -31,7 +33,7 @@
-

Step 1: Upload zipped gerber files

+

Upload zipped gerber files

First, upload a zip file containing all your gerber files. The default file names used by KiCAD, Eagle and Altium are supported. @@ -39,7 +41,7 @@

-
+ {{gerber_form.csrf_token}}
@@ -56,7 +58,7 @@ {% if 'render_job' in session or has_renders %}
-

Step 2: Download the target side's preview image

+

Download the target side's preview image

Second, download either the top or bottom preview image and use it to align and scale your own artwork in an image editing program such as Gimp. Then upload your overlay image below. @@ -68,15 +70,19 @@

{% if 'render_job' in session %} - Processing... (this may take several minutes!) +
+
+
Processing...
+
(this may take several minutes!)
+
{% else %} {% endif %}
@@ -87,7 +93,7 @@
-

Step 3: Upload overlay image

+

Upload overlay image

Now, upload your binary overlay image as a PNG and let gerbolyze render it onto the target layer. The PNG file should be a black and white binary file with details generally above about 10px size. Antialiased @@ -95,7 +101,7 @@

-
+ {{overlay_form.csrf_token}}
@@ -119,11 +125,10 @@ {% if 'vector_job' in session or has_output %}
-

Step 4: Download the processed gerber files

+

Download the processed gerber files

- {# if 'vector_job' in session FIXME #} - {% if True %} + {% if 'vector_job' in session %}
Processing...
@@ -137,11 +142,23 @@
+
{% endif %} {# vector job #} {% endif %} {# render job #}
+
+

Sample images

+ + + +
-- cgit From 9f20d47c1f5a1d83c6a5dd9dc4ea57dad53c64d9 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sat, 30 Mar 2019 04:20:14 +0900 Subject: gerbolyze: Add color scheme svg --- gerboweb/colors.svg | 357 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 gerboweb/colors.svg (limited to 'gerboweb') diff --git a/gerboweb/colors.svg b/gerboweb/colors.svg new file mode 100644 index 0000000..d7b2eee --- /dev/null +++ b/gerboweb/colors.svg @@ -0,0 +1,357 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 2 3 4 5 6 7 + + + + + + + + 8 + -- cgit From 6ece0619029687f0c63f4d1423e64733ba7d93aa Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 31 Mar 2019 04:08:39 +0900 Subject: gerboweb: Fixup playbook to run from fresh install --- gerboweb/deploy/nginx_nossl.conf | 45 ++++++++++++++++ gerboweb/deploy/playbook.yml | 93 +++++++++++++++++++++++++--------- gerboweb/deploy/tmpfiles-gerboweb.conf | 2 +- gerboweb/static/style.css | 3 +- 4 files changed, 116 insertions(+), 27 deletions(-) create mode 100644 gerboweb/deploy/nginx_nossl.conf (limited to 'gerboweb') diff --git a/gerboweb/deploy/nginx_nossl.conf b/gerboweb/deploy/nginx_nossl.conf new file mode 100644 index 0000000..0ecd1cb --- /dev/null +++ b/gerboweb/deploy/nginx_nossl.conf @@ -0,0 +1,45 @@ +# For more information on configuration, see: +# * Official English Documentation: http://nginx.org/en/docs/ +# * Official Russian Documentation: http://nginx.org/ru/docs/ + +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 4096; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; + + server { + listen 80 default_server; + listen [::]:80 default_server; + server_name gerbolyze.jaseg.net; + return 301 https://$host$request_uri; + } +} + diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 9753df6..a0ff505 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -1,6 +1,33 @@ - name: Gerbolyze container setup playbook - hosts: all + hosts: wendelstein tasks: + - name: Set hostname + hostname: + name: wendelstein.jaseg.net + + - name: Install common admin tools + dnf: + name: htop,tmux,fish,mosh,neovim + state: latest + + - name: Install host requisites + dnf: + name: btrfs-progs,arch-install-scripts,nginx,uwsgi,python3-flask,python3-flask-wtf,systemd-container,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python + state: latest + + - name: Disable password-based root login + lineinfile: + path: /etc/ssh/sshd_config + regexp: '^PermitRootLogin' + line: 'PermitRootLogin without-password' + register: disable_root_pw_ssh + + - name: Restart sshd + systemd: + name: sshd + state: restarted + when: disable_root_pw_ssh is changed + - name: Create container image file command: truncate -s 4G /var/cache/gerbolyze_container.img args: @@ -14,11 +41,6 @@ checksum: sha256:865c8a25312b663e724923eecf0dfc626f4cd621e2cfcb19eafc69a4fc666756 when: create_container is changed - - name: Install host requisites - dnf: - name: btrfs-progs,arch-install-scripts,nginx,uwsgi,python3-flask,python3-flask-wtf,systemd-container,uwsgi-plugin-python3,certbot,python3-certbot-nginx - state: latest - - name: Create container image filesystem filesystem: dev: /var/cache/gerbolyze_container.img @@ -88,9 +110,9 @@ group: no owner: no - - name: Copy nginx config + - name: Copy first stage nginx config copy: - src: nginx.conf + src: nginx_nossl.conf dest: /etc/nginx/nginx.conf - name: Create uwsgi worker user and group @@ -136,22 +158,33 @@ state: permissive policy: targeted - - name: Create letsencrypt certificate - command: certbot --nginx certonly -d gerbolyze.jaseg.net -n --agree-tos --email gerboweb@jaseg.net - args: - creates: /etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem - - - name: Enable certbot renewal timer - systemd: - name: certbot-renew.timer - enabled: yes - - name: Enable uwsgi systemd socket systemd: daemon-reload: yes name: uwsgi-app@gerboweb.socket enabled: yes + - name: Copy gerboweb cache dir tmpfiles.d config + copy: + src: tmpfiles-gerboweb.conf + dest: /etc/tmpfiles.d/gerboweb.conf + owner: root + group: root + mode: 0644 + register: tmpfiles_config + + - name: Kick systemd tmpfiles service to create cache dir + command: systemd-tmpfiles --create + when: tmpfiles_config is changed + + - name: Create job queue db + file: + path: /var/cache/gerboweb/job_queue.sqlite3 + owner: root + group: uwsgi + mode: 0660 + state: touch + - name: Enable and launch job processor systemd: name: gerboweb-job-processor.service @@ -164,11 +197,23 @@ enabled: yes state: restarted - - name: Copy gerboweb cache dir tmpfiles.d config + - name: Create letsencrypt certificate + command: certbot --nginx certonly -d gerbolyze.jaseg.net -n --agree-tos --email gerboweb@jaseg.net + args: + creates: /etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem + + - name: Copy final nginx config copy: - src: tmpfiles-gerboweb.conf - dest: /etc/tmpfiles.d/gerboweb.conf - owner: root - group: root - mode: 0644 + src: nginx.conf + dest: /etc/nginx/nginx.conf + + - name: Restart nginx to load new cert + systemd: + name: nginx.service + state: restarted + + - name: Enable certbot renewal timer + systemd: + name: certbot-renew.timer + enabled: yes diff --git a/gerboweb/deploy/tmpfiles-gerboweb.conf b/gerboweb/deploy/tmpfiles-gerboweb.conf index 33264cf..1f11122 100644 --- a/gerboweb/deploy/tmpfiles-gerboweb.conf +++ b/gerboweb/deploy/tmpfiles-gerboweb.conf @@ -1 +1 @@ -d /var/cache/gerboweb 760 uwsgi-gerboweb uwsgi 2d +d /var/cache/gerboweb 770 uwsgi-gerboweb uwsgi 2d diff --git a/gerboweb/static/style.css b/gerboweb/static/style.css index ede89d4..eb926dc 100644 --- a/gerboweb/static/style.css +++ b/gerboweb/static/style.css @@ -159,8 +159,7 @@ div.loading-message { left: 0; width: 60px; - line-height: 50px; - padding-top: 10px; + line-height: 60px; } .step > .description { -- cgit From bd146dd1636116680f7d9a4e1a85adc3d803a7c5 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 31 Mar 2019 21:52:12 +0900 Subject: gerboweb: Add favicon --- gerboweb/static/favicon-1024.png | Bin 0 -> 555502 bytes gerboweb/static/favicon-128.png | Bin 0 -> 30221 bytes gerboweb/static/favicon-16.png | Bin 0 -> 1040 bytes gerboweb/static/favicon-256.png | Bin 0 -> 87765 bytes gerboweb/static/favicon-32.png | Bin 0 -> 2945 bytes gerboweb/static/favicon-48.png | Bin 0 -> 5850 bytes gerboweb/static/favicon-512.png | Bin 0 -> 243219 bytes gerboweb/static/favicon-64.png | Bin 0 -> 9566 bytes gerboweb/static/favicon.png | Bin 0 -> 549230 bytes gerboweb/templates/index.html | 2 ++ 10 files changed, 2 insertions(+) create mode 100644 gerboweb/static/favicon-1024.png create mode 100644 gerboweb/static/favicon-128.png create mode 100644 gerboweb/static/favicon-16.png create mode 100644 gerboweb/static/favicon-256.png create mode 100644 gerboweb/static/favicon-32.png create mode 100644 gerboweb/static/favicon-48.png create mode 100644 gerboweb/static/favicon-512.png create mode 100644 gerboweb/static/favicon-64.png create mode 100644 gerboweb/static/favicon.png (limited to 'gerboweb') diff --git a/gerboweb/static/favicon-1024.png b/gerboweb/static/favicon-1024.png new file mode 100644 index 0000000..ed33689 Binary files /dev/null and b/gerboweb/static/favicon-1024.png differ diff --git a/gerboweb/static/favicon-128.png b/gerboweb/static/favicon-128.png new file mode 100644 index 0000000..8bdefac Binary files /dev/null and b/gerboweb/static/favicon-128.png differ diff --git a/gerboweb/static/favicon-16.png b/gerboweb/static/favicon-16.png new file mode 100644 index 0000000..4164370 Binary files /dev/null and b/gerboweb/static/favicon-16.png differ diff --git a/gerboweb/static/favicon-256.png b/gerboweb/static/favicon-256.png new file mode 100644 index 0000000..364a3bb Binary files /dev/null and b/gerboweb/static/favicon-256.png differ diff --git a/gerboweb/static/favicon-32.png b/gerboweb/static/favicon-32.png new file mode 100644 index 0000000..f46cf2b Binary files /dev/null and b/gerboweb/static/favicon-32.png differ diff --git a/gerboweb/static/favicon-48.png b/gerboweb/static/favicon-48.png new file mode 100644 index 0000000..c9a8c19 Binary files /dev/null and b/gerboweb/static/favicon-48.png differ diff --git a/gerboweb/static/favicon-512.png b/gerboweb/static/favicon-512.png new file mode 100644 index 0000000..10b2234 Binary files /dev/null and b/gerboweb/static/favicon-512.png differ diff --git a/gerboweb/static/favicon-64.png b/gerboweb/static/favicon-64.png new file mode 100644 index 0000000..76279e2 Binary files /dev/null and b/gerboweb/static/favicon-64.png differ diff --git a/gerboweb/static/favicon.png b/gerboweb/static/favicon.png new file mode 100644 index 0000000..a22a3a7 Binary files /dev/null and b/gerboweb/static/favicon.png differ diff --git a/gerboweb/templates/index.html b/gerboweb/templates/index.html index eeece65..4dca6dc 100644 --- a/gerboweb/templates/index.html +++ b/gerboweb/templates/index.html @@ -3,6 +3,8 @@ Gerbolyze Raster image to PCB renderer + +
-- cgit From a846d39bc88e0c03402b20790b04762666bc055f Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 2 Apr 2019 04:34:57 +0900 Subject: gerboweb: Fix job queue handling --- gerboweb/gerboweb.py | 17 +++++++++++------ gerboweb/job_queue.py | 19 ++++--------------- 2 files changed, 15 insertions(+), 21 deletions(-) (limited to 'gerboweb') diff --git a/gerboweb/gerboweb.py b/gerboweb/gerboweb.py index a276d74..7e952a4 100644 --- a/gerboweb/gerboweb.py +++ b/gerboweb/gerboweb.py @@ -63,8 +63,12 @@ def index(): 'reset_form': ResetForm() } for job in ('vector_job', 'render_job'): - if job in session and job_queue[session[job]].finished: - del session[job] + if job in session: + job = job_queue[session[job]] + if job.finished: + if job.result != 0: + flash(f'Error processing gerber files', 'success') # FIXME make this an error, add CSS + del session[job] r = make_response(render_template('index.html', has_renders = path.isfile(tempfile_path('gerber.zip')), @@ -81,7 +85,7 @@ def index(): def vectorize(): if 'vector_job' in session: - job_queue.drop(session['vector_job']) + job_queue[session['vector_job']].abort() session['vector_job'] = job_queue.enqueue('vector', client=request.remote_addr, session_id=session['session_id'], @@ -89,7 +93,7 @@ def vectorize(): def render(): if 'render_job' in session: - job_queue.drop(session['render_job']) + job_queue[session['render_job']].abort() session['render_job'] = job_queue.enqueue('render', session_id=session['session_id'], client=request.remote_addr) @@ -115,6 +119,7 @@ def upload_gerber(): def upload_overlay(): upload_form = OverlayForm() if upload_form.validate_on_submit(): + # FIXME raise error when no side selected f = upload_form.upload_file.data f.save(tempfile_path('overlay.png')) session['side_selected'] = upload_form.side.data @@ -152,9 +157,9 @@ def output_download(): @require_session_id def session_reset(): if 'render_job' in session: - session['render_job'].abort() + job_queue[session['render_job']].abort() if 'vector_job' in session: - session['vector_job'].abort() + job_queue[session['vector_job']].abort() session.clear() flash('Session reset', 'success'); return redirect(url_for('index')) diff --git a/gerboweb/job_queue.py b/gerboweb/job_queue.py index e48379d..76f17dc 100644 --- a/gerboweb/job_queue.py +++ b/gerboweb/job_queue.py @@ -25,22 +25,11 @@ class JobQueue: return conn.execute('INSERT INTO jobs(type, client, params) VALUES (?, ?, ?)', (task_type, client, json.dumps(params))).lastrowid - def check_result(slef, job_id): - with self.db as conn: - job = conn.execute('SELECT * FROM jobs WHERE id=?', (job_id,)).fetchone() - if job is None: - raise IndexError('Job id not found') - return job.result - - def drop(self, job_id): - with self.db as conn: - return conn.execute('DELETE FROM jobs WHERE id=?', (job_id,)).rowcount > 0 - def pop(self, task_type): """ Fetch the next job of the given type. Returns a sqlite3.Row object of the job or None if no jobs of the given type are queued. """ with self.db as conn: - job = conn.execute('SELECT * FROM jobs WHERE type=? AND consumed IS NULL ORDER BY created ASC LIMIT 1', + job = conn.execute('SELECT * FROM jobs WHERE type=? AND consumed IS NULL AND aborted IS NULL ORDER BY created ASC LIMIT 1', (task_type,)).fetchone() if job is None: return None @@ -73,7 +62,7 @@ class Job(dict): self.created = row['created'] self.consumed = row['consumed'] self.finished = row['finished'] - self.result = None + self.result = row['result'] def __enter__(self): return self @@ -82,7 +71,7 @@ class Job(dict): with self._db as conn: conn.execute('UPDATE jobs SET finished=datetime("now"), result=? WHERE id=?', (self.result, self.id,)) - def abort(self): - with self._db as conn: + def abort(self, job_id): + with self.db as conn: conn.execute('UPDATE jobs SET aborted=datetime("now") WHERE id=?', (self.id,)) -- cgit From cbb98bcf0ee0e9e123f054377ff68b513efe6bf6 Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 2 Apr 2019 04:36:10 +0900 Subject: gerboweb: Modularize deployment playbooks a bit --- gerboweb/deploy/.gitignore | 2 + gerboweb/deploy/bootstrap_arch_container.yml | 60 +++++++ gerboweb/deploy/gerboweb-job-processor.service | 9 - gerboweb/deploy/gerboweb-job-processor.service.j2 | 9 + gerboweb/deploy/gerboweb.cfg.j2 | 4 + gerboweb/deploy/playbook.yml | 201 ++-------------------- gerboweb/deploy/render.sh | 20 --- gerboweb/deploy/render.sh.j2 | 20 +++ gerboweb/deploy/setup_containers.yml | 25 +++ gerboweb/deploy/setup_gerboweb.yml | 95 ++++++++++ gerboweb/deploy/setup_webserver.yml | 52 ++++++ gerboweb/deploy/tmpfiles-gerboweb.conf | 1 - gerboweb/deploy/tmpfiles-gerboweb.conf.j2 | 1 + gerboweb/deploy/uwsgi-gerboweb.ini | 2 +- gerboweb/deploy/vector.sh | 18 -- gerboweb/deploy/vector.sh.j2 | 18 ++ 16 files changed, 299 insertions(+), 238 deletions(-) create mode 100644 gerboweb/deploy/.gitignore create mode 100644 gerboweb/deploy/bootstrap_arch_container.yml delete mode 100644 gerboweb/deploy/gerboweb-job-processor.service create mode 100644 gerboweb/deploy/gerboweb-job-processor.service.j2 create mode 100644 gerboweb/deploy/gerboweb.cfg.j2 delete mode 100755 gerboweb/deploy/render.sh create mode 100755 gerboweb/deploy/render.sh.j2 create mode 100644 gerboweb/deploy/setup_containers.yml create mode 100644 gerboweb/deploy/setup_gerboweb.yml create mode 100644 gerboweb/deploy/setup_webserver.yml delete mode 100644 gerboweb/deploy/tmpfiles-gerboweb.conf create mode 100644 gerboweb/deploy/tmpfiles-gerboweb.conf.j2 delete mode 100755 gerboweb/deploy/vector.sh create mode 100755 gerboweb/deploy/vector.sh.j2 (limited to 'gerboweb') diff --git a/gerboweb/deploy/.gitignore b/gerboweb/deploy/.gitignore new file mode 100644 index 0000000..97b80a1 --- /dev/null +++ b/gerboweb/deploy/.gitignore @@ -0,0 +1,2 @@ +gerboweb_flask_secret.txt +playbook.retry diff --git a/gerboweb/deploy/bootstrap_arch_container.yml b/gerboweb/deploy/bootstrap_arch_container.yml new file mode 100644 index 0000000..bd534e8 --- /dev/null +++ b/gerboweb/deploy/bootstrap_arch_container.yml @@ -0,0 +1,60 @@ +--- +- name: Set local path facts + set_fact: + image: "/var/cache/containers/{{ container }}.img" + root: "/var/cache/containers/{{ container }}_root" + "{{container}}_root": "/var/cache/containers/{{ container }}_root" + +- name: Create container image file + command: truncate -s 4G "{{image}}" + args: + creates: "{{image}}" + register: create_container + +- name: Download arch bootstrap image + get_url: + url: http://mirror.rackspace.com/archlinux/iso/2019.03.01/archlinux-bootstrap-2019.03.01-x86_64.tar.gz + dest: /tmp/arch-bootstrap.tar.xz + checksum: sha256:865c8a25312b663e724923eecf0dfc626f4cd621e2cfcb19eafc69a4fc666756 + when: create_container is changed + +- name: Create container image filesystem + filesystem: + dev: "{{image}}" + fstype: btrfs + +- name: Create container image fstab entry + mount: + src: "{{image}}" + path: "{{root}}" + state: mounted + fstype: btrfs + opts: loop + +- name: Unpack bootstrap image + unarchive: + remote_src: yes + src: /tmp/arch-bootstrap.tar.xz + dest: "{{root}}" + extra_opts: --strip-components=1 + creates: "{{root}}/etc" + +- name: Copy mirrorlist into container + copy: + src: mirrorlist + dest: "{{root}}/etc/pacman.d/mirrorlist" + +- name: Initialize container pacman keyring + shell: arch-chroot "{{root}}" pacman-key --init && arch-chroot "{{root}}" pacman-key --populate archlinux + args: + creates: "{{root}}/etc/pacman.d/gnupg" + +- name: Fixup pacman.conf for pacman to work in chroot without its own root fs + lineinfile: + path: "{{root}}/etc/pacman.conf" + regexp: '^CheckSpace' + line: '#CheckSpace' + +- name: Update container and install software + shell: arch-chroot "{{root}}" pacman -Syu --noconfirm + diff --git a/gerboweb/deploy/gerboweb-job-processor.service b/gerboweb/deploy/gerboweb-job-processor.service deleted file mode 100644 index 8569317..0000000 --- a/gerboweb/deploy/gerboweb-job-processor.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Gerboweb gerber job processor - -[Service] -WorkingDirectory=/var/lib/gerboweb -ExecStart=/usr/bin/python3 job_processor.py /var/cache/gerboweb/job_queue.sqlite3 - -[Install] -WantedBy=uwsgi-app@gerboweb.service diff --git a/gerboweb/deploy/gerboweb-job-processor.service.j2 b/gerboweb/deploy/gerboweb-job-processor.service.j2 new file mode 100644 index 0000000..517d8b8 --- /dev/null +++ b/gerboweb/deploy/gerboweb-job-processor.service.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=Gerboweb gerber job processor + +[Service] +WorkingDirectory=/var/lib/gerboweb +ExecStart=/usr/bin/python3 job_processor.py {{gerboweb_cache}}/job_queue.sqlite3 + +[Install] +WantedBy=uwsgi-app@gerboweb.service diff --git a/gerboweb/deploy/gerboweb.cfg.j2 b/gerboweb/deploy/gerboweb.cfg.j2 new file mode 100644 index 0000000..994cd08 --- /dev/null +++ b/gerboweb/deploy/gerboweb.cfg.j2 @@ -0,0 +1,4 @@ +MAX_CONTENT_LENGTH=10000000 +SECRET_KEY="{{lookup('password', 'gerboweb_flask_secret.txt length=32')}}" +UPLOAD_PATH="{{gerboweb_cache}}/upload" +JOB_QUEUE_DB="{{gerboweb_cache}}/job_queue.sqlite3" diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index a0ff505..23544c4 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -7,12 +7,12 @@ - name: Install common admin tools dnf: - name: htop,tmux,fish,mosh,neovim + name: htop,tmux,fish,mosh,neovim,sqlite state: latest - name: Install host requisites dnf: - name: btrfs-progs,arch-install-scripts,nginx,uwsgi,python3-flask,python3-flask-wtf,systemd-container,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python + name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python state: latest - name: Disable password-based root login @@ -28,192 +28,15 @@ state: restarted when: disable_root_pw_ssh is changed - - name: Create container image file - command: truncate -s 4G /var/cache/gerbolyze_container.img - args: - creates: /var/cache/gerbolyze_container.img - register: create_container + - name: Create containers + include_tasks: setup_containers.yml + vars: + containers: + - gerboweb + - clippy - - name: Download arch bootstrap image - get_url: - url: http://mirror.rackspace.com/archlinux/iso/2019.03.01/archlinux-bootstrap-2019.03.01-x86_64.tar.gz - dest: /tmp/arch-bootstrap.tar.xz - checksum: sha256:865c8a25312b663e724923eecf0dfc626f4cd621e2cfcb19eafc69a4fc666756 - when: create_container is changed - - - name: Create container image filesystem - filesystem: - dev: /var/cache/gerbolyze_container.img - fstype: btrfs - - - name: Create container image fstab entry - mount: - src: /var/cache/gerbolyze_container.img - path: /var/cache/gerbolyze_container - state: mounted - fstype: btrfs - opts: loop - - - name: Unpack bootstrap image - unarchive: - remote_src: yes - src: /tmp/arch-bootstrap.tar.xz - dest: /var/cache/gerbolyze_container - extra_opts: --strip-components=1 - creates: /var/cache/gerbolyze_container/etc - - - name: Copy mirrorlist into container - copy: - src: mirrorlist - dest: /var/cache/gerbolyze_container/etc/pacman.d/mirrorlist - - - name: Copy render script - copy: - src: render.sh - dest: /usr/local/sbin/gerbolyze_render.sh - mode: ug+x - - - name: Copy vector script - copy: - src: vector.sh - dest: /usr/local/sbin/gerbolyze_vector.sh - mode: ug+x - - - name: Initialize container pacman keyring - shell: arch-chroot /var/cache/gerbolyze_container pacman-key --init && arch-chroot /var/cache/gerbolyze_container pacman-key --populate archlinux - args: - creates: /var/cache/gerbolyze_container/etc/pacman.d/gnupg - - - name: Fixup pacman.conf for pacman to work in chroot without its own root fs - lineinfile: - path: /var/cache/gerbolyze_container/etc/pacman.conf - regexp: '^CheckSpace' - line: '#CheckSpace' - - - name: Update container and install software - shell: arch-chroot /var/cache/gerbolyze_container pacman -Syu --noconfirm python3 opencv hdf5 gtk3 python-numpy python-pip imagemagick unzip zip - - # TODO maybe install directly from local git checkout? - - name: Install gerbolyze - shell: arch-chroot /var/cache/gerbolyze_container pip install -U --upgrade-strategy=eager gerbolyze - - - name: Cleanup bootstrap image - file: - path: /tmp/arch-bootstrap.tar.xz - state: absent - - - name: Copy webapp sources - synchronize: - # FIXME: make this path configurable - src: ~/gerbolyze/gerboweb/ - dest: /var/lib/gerboweb/ - group: no - owner: no - - - name: Copy first stage nginx config - copy: - src: nginx_nossl.conf - dest: /etc/nginx/nginx.conf - - - name: Create uwsgi worker user and group - user: - name: uwsgi-gerboweb - create_home: no - group: uwsgi - password: '!' - shell: /sbin/nologin - system: yes - - - name: Add nginx user to uwsgi group for access to uwsgi socket - user: - name: nginx - groups: uwsgi - append: yes - - - name: Copy uwsgi config - copy: - src: uwsgi-gerboweb.ini - dest: /etc/uwsgi.d/gerboweb.ini - owner: uwsgi-gerboweb - group: uwsgi - mode: 440 - - - name: Copy uwsgi systemd socket config - copy: - src: uwsgi-app@.socket - dest: /etc/systemd/system/ - - - name: Copy uwsgi systemd service config - copy: - src: uwsgi-app@.service - dest: /etc/systemd/system/ - - - name: Copy job processor systemd service config - copy: - src: gerboweb-job-processor.service - dest: /etc/systemd/system/ - - - name: Set SELinux to permissive mode # FIXME - selinux: - state: permissive - policy: targeted - - - name: Enable uwsgi systemd socket - systemd: - daemon-reload: yes - name: uwsgi-app@gerboweb.socket - enabled: yes - - - name: Copy gerboweb cache dir tmpfiles.d config - copy: - src: tmpfiles-gerboweb.conf - dest: /etc/tmpfiles.d/gerboweb.conf - owner: root - group: root - mode: 0644 - register: tmpfiles_config - - - name: Kick systemd tmpfiles service to create cache dir - command: systemd-tmpfiles --create - when: tmpfiles_config is changed - - - name: Create job queue db - file: - path: /var/cache/gerboweb/job_queue.sqlite3 - owner: root - group: uwsgi - mode: 0660 - state: touch - - - name: Enable and launch job processor - systemd: - name: gerboweb-job-processor.service - enabled: yes - state: restarted - - - name: Enable and launch nginx systemd service - systemd: - name: nginx.service - enabled: yes - state: restarted - - - name: Create letsencrypt certificate - command: certbot --nginx certonly -d gerbolyze.jaseg.net -n --agree-tos --email gerboweb@jaseg.net - args: - creates: /etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem - - - name: Copy final nginx config - copy: - src: nginx.conf - dest: /etc/nginx/nginx.conf - - - name: Restart nginx to load new cert - systemd: - name: nginx.service - state: restarted - - - name: Enable certbot renewal timer - systemd: - name: certbot-renew.timer - enabled: yes + - name: Setup web server + include_tasks: setup_webserver.yml + - name: Setup gerboweb + include_tasks: setup_gerboweb.yml diff --git a/gerboweb/deploy/render.sh b/gerboweb/deploy/render.sh deleted file mode 100755 index eefe7f0..0000000 --- a/gerboweb/deploy/render.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -[ $# != 1 ] && exit 1 -ID=$1 -egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 - -systemd-nspawn \ - -D /var/cache/gerbolyze_container \ - -x --bind=/var/cache/gerboweb/upload/$ID:/mnt \ - /bin/sh -c "set -euo pipefail -unzip -j -d /tmp/gerber /mnt/gerber.zip -rm -f /mnt/render_top.png /mnt/render_bottom.png /mnt/render_top.small.png /mnt/render_bottom.small.png -date; echo 'Rendering bottom layer' -gerbolyze render top /tmp/gerber /mnt/render_top.png -date; echo 'Scaling down' -convert /mnt/render_top.png -resize 500x500 -negate -brightness-contrast 30x30 -colorspace gray /mnt/render_top.small.png -date; echo 'Rendering top layer' -gerbolyze render bottom /tmp/gerber /mnt/render_bottom.png -date; echo 'Scaling down' -convert /mnt/render_bottom.png -resize 500x500 -negate -brightness-contrast 30x30 -colorspace gray /mnt/render_bottom.small.png" diff --git a/gerboweb/deploy/render.sh.j2 b/gerboweb/deploy/render.sh.j2 new file mode 100755 index 0000000..ceb837d --- /dev/null +++ b/gerboweb/deploy/render.sh.j2 @@ -0,0 +1,20 @@ +#!/bin/sh + +[ $# != 1 ] && exit 1 +ID=$1 +egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 + +systemd-nspawn \ + -D {{gerboweb_root}} \ + -x --bind={{gerboweb_cache}}/upload/$ID:/mnt \ + /bin/sh -c "set -euo pipefail +unzip -j -d /tmp/gerber /mnt/gerber.zip +rm -f /mnt/render_top.png /mnt/render_bottom.png /mnt/render_top.small.png /mnt/render_bottom.small.png +date; echo 'Rendering bottom layer' +gerbolyze render top /tmp/gerber /mnt/render_top.png +date; echo 'Scaling down' +convert /mnt/render_top.png -resize 500x500 -negate -brightness-contrast 30x30 -colorspace gray /mnt/render_top.small.png +date; echo 'Rendering top layer' +gerbolyze render bottom /tmp/gerber /mnt/render_bottom.png +date; echo 'Scaling down' +convert /mnt/render_bottom.png -resize 500x500 -negate -brightness-contrast 30x30 -colorspace gray /mnt/render_bottom.small.png" diff --git a/gerboweb/deploy/setup_containers.yml b/gerboweb/deploy/setup_containers.yml new file mode 100644 index 0000000..dd0a5ca --- /dev/null +++ b/gerboweb/deploy/setup_containers.yml @@ -0,0 +1,25 @@ +--- +- name: Install host requisites + dnf: + name: btrfs-progs,arch-install-scripts,systemd-container,libselinux-python + state: latest + +- name: Create container dir + file: + path: /var/cache/containers + owner: root + group: root + mode: 0775 + state: directory + +- name: Create individual containers + include_tasks: bootstrap_arch_container.yml + with_items: "{{ containers }}" + loop_control: + loop_var: container + +- name: Cleanup bootstrap image + file: + path: /tmp/arch-bootstrap.tar.xz + state: absent + diff --git a/gerboweb/deploy/setup_gerboweb.yml b/gerboweb/deploy/setup_gerboweb.yml new file mode 100644 index 0000000..e1a49fb --- /dev/null +++ b/gerboweb/deploy/setup_gerboweb.yml @@ -0,0 +1,95 @@ +--- +- name: Set local facts + set_fact: + gerboweb_cache: /var/cache/gerboweb + +- name: Copy render script + template: + src: render.sh.j2 + dest: /usr/local/sbin/gerbolyze_render.sh + mode: ug+x + +- name: Copy vector script + template: + src: vector.sh.j2 + dest: /usr/local/sbin/gerbolyze_vector.sh + mode: ug+x + +- name: Install packages into gerbolyze container + shell: arch-chroot "{{gerboweb_root}}" pacman -Syu --noconfirm python3 opencv hdf5 gtk3 python-numpy python-pip imagemagick unzip zip + + # TODO maybe install directly from local git checkout? +- name: Install gerbolyze + shell: arch-chroot "{{gerboweb_root}}" pip install -U --upgrade-strategy=eager gerbolyze + +- name: Copy webapp sources + synchronize: + # FIXME: make this path configurable + src: ~/gerbolyze/gerboweb/ + dest: /var/lib/gerboweb/ + group: no + owner: no + +- name: Create uwsgi worker user and group + user: + name: uwsgi-gerboweb + create_home: no + group: uwsgi + password: '!' + shell: /sbin/nologin + system: yes + +- name: Template webapp config + template: + src: gerboweb.cfg.j2 + dest: /var/lib/gerboweb/gerboweb_prod.cfg + owner: uwsgi-gerboweb + group: root + mode: 0660 + +- name: Copy uwsgi config + copy: + src: uwsgi-gerboweb.ini + dest: /etc/uwsgi.d/gerboweb.ini + owner: uwsgi-gerboweb + group: uwsgi + mode: 440 + +- name: Copy job processor systemd service config + template: + src: gerboweb-job-processor.service.j2 + dest: /etc/systemd/system/gerboweb-job-processor.service + +- name: Enable uwsgi systemd socket + systemd: + daemon-reload: yes + name: uwsgi-app@gerboweb.socket + enabled: yes + +- name: Copy gerboweb cache dir tmpfiles.d config + template: + src: tmpfiles-gerboweb.conf.j2 + dest: /etc/tmpfiles.d/gerboweb.conf + owner: root + group: root + mode: 0644 + register: tmpfiles_config + +- name: Kick systemd tmpfiles service to create cache dir + command: systemd-tmpfiles --create + when: tmpfiles_config is changed + +- name: Create job queue db + file: + path: "{{gerboweb_cache}}/job_queue.sqlite3" + owner: root + group: uwsgi + mode: 0660 + state: touch + +- name: Enable and launch job processor + systemd: + name: gerboweb-job-processor.service + enabled: yes + state: restarted + diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml new file mode 100644 index 0000000..7dc65c5 --- /dev/null +++ b/gerboweb/deploy/setup_webserver.yml @@ -0,0 +1,52 @@ +- name: Copy first stage nginx config + copy: + src: nginx_nossl.conf + dest: /etc/nginx/nginx.conf + +- name: Add nginx user to uwsgi group for access to uwsgi socket + user: + name: nginx + groups: uwsgi + append: yes + +- name: Copy uwsgi systemd socket config + copy: + src: uwsgi-app@.socket + dest: /etc/systemd/system/ + +- name: Copy uwsgi systemd service config + copy: + src: uwsgi-app@.service + dest: /etc/systemd/system/ + +- name: Set SELinux to permissive mode # FIXME this is to let nginx talk to uwsgi + selinux: + state: permissive + policy: targeted + +- name: Enable and launch nginx systemd service + systemd: + name: nginx.service + enabled: yes + state: restarted + +- name: Create letsencrypt certificate + command: certbot --nginx certonly -d gerbolyze.jaseg.net -n --agree-tos --email gerboweb@jaseg.net + args: + creates: /etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem + +- name: Copy final nginx config + copy: + src: nginx.conf + dest: /etc/nginx/nginx.conf + +- name: Restart nginx to load new cert + systemd: + name: nginx.service + state: restarted + +- name: Enable certbot renewal timer + systemd: + name: certbot-renew.timer + enabled: yes + diff --git a/gerboweb/deploy/tmpfiles-gerboweb.conf b/gerboweb/deploy/tmpfiles-gerboweb.conf deleted file mode 100644 index 1f11122..0000000 --- a/gerboweb/deploy/tmpfiles-gerboweb.conf +++ /dev/null @@ -1 +0,0 @@ -d /var/cache/gerboweb 770 uwsgi-gerboweb uwsgi 2d diff --git a/gerboweb/deploy/tmpfiles-gerboweb.conf.j2 b/gerboweb/deploy/tmpfiles-gerboweb.conf.j2 new file mode 100644 index 0000000..18469b7 --- /dev/null +++ b/gerboweb/deploy/tmpfiles-gerboweb.conf.j2 @@ -0,0 +1 @@ +d {{gerboweb_cache}} 770 uwsgi-gerboweb uwsgi 2d diff --git a/gerboweb/deploy/uwsgi-gerboweb.ini b/gerboweb/deploy/uwsgi-gerboweb.ini index 3c8addd..ec52f90 100644 --- a/gerboweb/deploy/uwsgi-gerboweb.ini +++ b/gerboweb/deploy/uwsgi-gerboweb.ini @@ -9,5 +9,5 @@ manage-script-name = True plugins = python3 chdir = /var/lib/gerboweb mount = /=gerboweb:app -env = GERBOWEB_SETTINGS=gerboweb.cfg +env = GERBOWEB_SETTINGS=gerboweb_prod.cfg diff --git a/gerboweb/deploy/vector.sh b/gerboweb/deploy/vector.sh deleted file mode 100755 index 5d239d5..0000000 --- a/gerboweb/deploy/vector.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -[ $# != 2 ] && exit 1 -ID=$1 -egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 -LAYER=$2 -egrep -x -q '^(top|bottom)$'<<<"$LAYER" || exit 2 - -systemd-nspawn \ - -D /var/cache/gerbolyze_container \ - -x --bind=/var/cache/gerboweb/upload/$ID:/mnt \ - /bin/sh -c "set -euo pipefail -cd /tmp -unzip -j -d gerber_in /mnt/gerber.zip -gerbolyze vectorize $LAYER gerber_in gerber /mnt/overlay.png -rm -f /mnt/gerber_out.zip -zip -r /mnt/gerber_out.zip gerber" - diff --git a/gerboweb/deploy/vector.sh.j2 b/gerboweb/deploy/vector.sh.j2 new file mode 100755 index 0000000..b17116e --- /dev/null +++ b/gerboweb/deploy/vector.sh.j2 @@ -0,0 +1,18 @@ +#!/bin/sh + +[ $# != 2 ] && exit 1 +ID=$1 +egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 +LAYER=$2 +egrep -x -q '^(top|bottom)$'<<<"$LAYER" || exit 2 + +systemd-nspawn \ + -D {{gerboweb_root}} \ + -x --bind={{gerboweb_cache}}/upload/$ID:/mnt \ + /bin/sh -c "set -euo pipefail +cd /tmp +unzip -j -d gerber_in /mnt/gerber.zip +gerbolyze vectorize $LAYER gerber_in gerber /mnt/overlay.png +rm -f /mnt/gerber_out.zip +zip -r /mnt/gerber_out.zip gerber" + -- cgit From a54abadf01e9e543b416ed09e8500ed71170342c Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 3 Apr 2019 23:53:04 +0900 Subject: gerbolyze fixes, clippy experiments --- gerboweb/deploy/bootstrap_arch_container.yml | 6 +-- gerboweb/deploy/clippy-nspawn.service | 36 +++++++++++++++ gerboweb/deploy/clippy.service.j2 | 9 ++++ gerboweb/deploy/playbook.yml | 5 +- gerboweb/deploy/setup_clippy.yml | 69 ++++++++++++++++++++++++++++ gerboweb/deploy/setup_containers.yml | 8 ---- gerboweb/deploy/uwsgi-app@.service | 3 +- gerboweb/deploy/uwsgi-gerboweb.ini | 5 +- gerboweb/gerboweb.py | 8 ++-- gerboweb/job_queue.py | 2 +- 10 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 gerboweb/deploy/clippy-nspawn.service create mode 100644 gerboweb/deploy/clippy.service.j2 create mode 100644 gerboweb/deploy/setup_clippy.yml (limited to 'gerboweb') diff --git a/gerboweb/deploy/bootstrap_arch_container.yml b/gerboweb/deploy/bootstrap_arch_container.yml index bd534e8..4126bbd 100644 --- a/gerboweb/deploy/bootstrap_arch_container.yml +++ b/gerboweb/deploy/bootstrap_arch_container.yml @@ -1,9 +1,9 @@ --- - name: Set local path facts set_fact: - image: "/var/cache/containers/{{ container }}.img" - root: "/var/cache/containers/{{ container }}_root" - "{{container}}_root": "/var/cache/containers/{{ container }}_root" + image: "/var/lib/machines/{{ container }}.img" + root: "/var/lib/machines/{{ container }}" + "{{container}}_root": "/var/lib/machines/{{ container }}" - name: Create container image file command: truncate -s 4G "{{image}}" diff --git a/gerboweb/deploy/clippy-nspawn.service b/gerboweb/deploy/clippy-nspawn.service new file mode 100644 index 0000000..66b8e85 --- /dev/null +++ b/gerboweb/deploy/clippy-nspawn.service @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Clippy container +PartOf=machines.target +Before=machines.target +After=network.target systemd-resolved.service +RequiresMountsFor=/var/lib/machines + +[Service] +ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --ephemeral --boot --network-veth --port=23:2342 -U --settings=override --machine=clippy +KillMode=mixed +Type=notify +RestartForceExitStatus=133 +SuccessExitStatus=133 +WatchdogSec=3min +Slice=machine.slice +Delegate=yes +TasksMax=512 + +# Enforce a strict device policy, similar to the one nspawn configures when it +# allocates its own scope unit. Make sure to keep these policies in sync if you +# change them! +DevicePolicy=closed +DeviceAllow=/dev/net/tun rwm +DeviceAllow=char-pts rw + +[Install] +WantedBy=machines.target diff --git a/gerboweb/deploy/clippy.service.j2 b/gerboweb/deploy/clippy.service.j2 new file mode 100644 index 0000000..22b3d7d --- /dev/null +++ b/gerboweb/deploy/clippy.service.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=Clippy listener daemon + +[Service] +WorkingDirectory=/var/lib/clippy.git +ExecStart=/usr/bin/python3 clippy.py -s -x 60x30 -e + +[Install] +WantedBy=multi-user.target diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 23544c4..60fe499 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -12,7 +12,7 @@ - name: Install host requisites dnf: - name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python + name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git state: latest - name: Disable password-based root login @@ -40,3 +40,6 @@ - name: Setup gerboweb include_tasks: setup_gerboweb.yml + + - name: Setup clippy + include_tasks: setup_clippy.yml diff --git a/gerboweb/deploy/setup_clippy.yml b/gerboweb/deploy/setup_clippy.yml new file mode 100644 index 0000000..e4416e0 --- /dev/null +++ b/gerboweb/deploy/setup_clippy.yml @@ -0,0 +1,69 @@ +--- +- name: Clone pixelterm git + git: + repo: https://github.com/jaseg/pixelterm + dest: "{{clippy_root}}/var/lib/pixelterm.git" + +- name: Clone clippy git + git: + repo: https://github.com/jaseg/clippy + dest: "{{clippy_root}}/var/lib/clippy.git" + +- name: Setup required packages for clippy + command: arch-chroot "{{clippy_root}}" pacman -Syu --noconfirm python3 python-pip python-numpy python-pillow + +- name: Setup pixelterm + command: arch-chroot "{{clippy_root}}" sh -c "cd /var/lib/pixelterm.git && python3 setup.py install" + +- name: Setup container clippy systemd service file + template: + src: clippy.service.j2 + dest: "{{clippy_root}}/etc/systemd/system/clippy.service" + owner: root + group: root + mode: 0664 + +- name: Enable systemd machines target + systemd: + name: machines.target + enabled: yes + +- name: Copy over clippy container auto boot service file + copy: + src: clippy-nspawn.service + dest: /etc/systemd/system/clippy-nspawn.service + owner: root + group: root + mode: 0664 + +- name: Enable clippy container auto boot + systemd: + daemon-reload: yes + name: clippy-nspawn.service + enabled: yes + +- name: Restart clippy container + shell: | + systemctl stop clippy-nspawn + sleep 1 + systemctl start clippy-nspawn + for x in $(seq 0 30); do + systemctl -M clippy is-system-running && exit + sleep 1 + done + +- name: Enable clippy systemd service in container + command: systemctl enable -M clippy clippy.service + +- name: Restart clippy systemd service in container + command: systemctl restart -M clippy clippy.service + +#- name: Enable host networkd +# systemd: +# name: systemd-networkd +# enabled: yes +# state: started + +- name: Enable clippy container networkd + command: systemctl enable -M clippy systemd-networkd + diff --git a/gerboweb/deploy/setup_containers.yml b/gerboweb/deploy/setup_containers.yml index dd0a5ca..4738f1e 100644 --- a/gerboweb/deploy/setup_containers.yml +++ b/gerboweb/deploy/setup_containers.yml @@ -4,14 +4,6 @@ name: btrfs-progs,arch-install-scripts,systemd-container,libselinux-python state: latest -- name: Create container dir - file: - path: /var/cache/containers - owner: root - group: root - mode: 0775 - state: directory - - name: Create individual containers include_tasks: bootstrap_arch_container.yml with_items: "{{ containers }}" diff --git a/gerboweb/deploy/uwsgi-app@.service b/gerboweb/deploy/uwsgi-app@.service index 61bf1e4..8398456 100644 --- a/gerboweb/deploy/uwsgi-app@.service +++ b/gerboweb/deploy/uwsgi-app@.service @@ -5,7 +5,8 @@ After=syslog.target [Service] ExecStart=/usr/sbin/uwsgi \ --ini /etc/uwsgi.d/%i.ini \ - --socket /run/uwsgi/%i.socket + --chmod-socket=660 \ + --socket=/run/uwsgi/%i.socket User=uwsgi-%i Group=uwsgi Restart=on-failure diff --git a/gerboweb/deploy/uwsgi-gerboweb.ini b/gerboweb/deploy/uwsgi-gerboweb.ini index ec52f90..155d01a 100644 --- a/gerboweb/deploy/uwsgi-gerboweb.ini +++ b/gerboweb/deploy/uwsgi-gerboweb.ini @@ -1,10 +1,7 @@ [uwsgi] master = True cheap = True -idle = 600 -die-on-idle = True # If app is not used often, it will exit and be launched - # again by systemd requested by users. - +die-on-idle = False manage-script-name = True plugins = python3 chdir = /var/lib/gerboweb diff --git a/gerboweb/gerboweb.py b/gerboweb/gerboweb.py index 7e952a4..2633e7b 100644 --- a/gerboweb/gerboweb.py +++ b/gerboweb/gerboweb.py @@ -62,13 +62,13 @@ def index(): 'overlay_form': OverlayForm(), 'reset_form': ResetForm() } - for job in ('vector_job', 'render_job'): - if job in session: - job = job_queue[session[job]] + for job_type in ('vector_job', 'render_job'): + if job_type in session: + job = job_queue[session[job_type]] if job.finished: if job.result != 0: flash(f'Error processing gerber files', 'success') # FIXME make this an error, add CSS - del session[job] + del session[job_type] r = make_response(render_template('index.html', has_renders = path.isfile(tempfile_path('gerber.zip')), diff --git a/gerboweb/job_queue.py b/gerboweb/job_queue.py index 76f17dc..62ba398 100644 --- a/gerboweb/job_queue.py +++ b/gerboweb/job_queue.py @@ -13,7 +13,7 @@ class JobQueue: type TEXT, params TEXT, client TEXT, - result TEXT DEFAULT NULL, + result INTEGER DEFAULT NULL, created DATETIME DEFAULT CURRENT_TIMESTAMP, consumed DATETIME DEFAULT NULL, aborted DATETIME DEFAULT NULL, -- cgit From 143419bb5aafd7a671b3c532d7fad9c050e45741 Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 4 Apr 2019 20:08:46 +0900 Subject: Fix up clippy networking --- gerboweb/deploy/clippy-nspawn.service | 2 +- gerboweb/deploy/clippy.nspawn | 2 ++ gerboweb/deploy/iptables.rules | 24 ++++++++++++++++++++++++ gerboweb/deploy/playbook.yml | 24 +++++++++++++++++++++++- gerboweb/deploy/setup_clippy.yml | 20 ++++++++++++++++++-- 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 gerboweb/deploy/clippy.nspawn create mode 100644 gerboweb/deploy/iptables.rules (limited to 'gerboweb') diff --git a/gerboweb/deploy/clippy-nspawn.service b/gerboweb/deploy/clippy-nspawn.service index 66b8e85..8dbedbd 100644 --- a/gerboweb/deploy/clippy-nspawn.service +++ b/gerboweb/deploy/clippy-nspawn.service @@ -15,7 +15,7 @@ After=network.target systemd-resolved.service RequiresMountsFor=/var/lib/machines [Service] -ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --ephemeral --boot --network-veth --port=23:2342 -U --settings=override --machine=clippy +ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --ephemeral --boot -U --settings=override --machine=clippy KillMode=mixed Type=notify RestartForceExitStatus=133 diff --git a/gerboweb/deploy/clippy.nspawn b/gerboweb/deploy/clippy.nspawn new file mode 100644 index 0000000..dfe2935 --- /dev/null +++ b/gerboweb/deploy/clippy.nspawn @@ -0,0 +1,2 @@ +[Network] +VirtualEthernet=no diff --git a/gerboweb/deploy/iptables.rules b/gerboweb/deploy/iptables.rules new file mode 100644 index 0000000..0f6f366 --- /dev/null +++ b/gerboweb/deploy/iptables.rules @@ -0,0 +1,24 @@ +# Generated by iptables-save v1.8.0 on Thu Apr 4 11:06:33 2019 +*nat +:PREROUTING ACCEPT [13:648] +:INPUT ACCEPT [8:440] +:OUTPUT ACCEPT [18:1260] +:POSTROUTING ACCEPT [18:1260] +-A PREROUTING -i eth0 -p tcp -m tcp --dport 23 -j REDIRECT --to-ports 2342 +COMMIT +# Completed on Thu Apr 4 11:06:33 2019 +# Generated by iptables-save v1.8.0 on Thu Apr 4 11:06:33 2019 +*filter +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [360:761646] +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 2342 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 23 -j ACCEPT +-A INPUT -j REJECT --reject-with icmp-host-prohibited +-A FORWARD -j REJECT --reject-with icmp-host-prohibited +COMMIT +# Completed on Thu Apr 4 11:06:33 2019 diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 60fe499..1c694d5 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -12,7 +12,7 @@ - name: Install host requisites dnf: - name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git + name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services state: latest - name: Disable password-based root login @@ -28,6 +28,28 @@ state: restarted when: disable_root_pw_ssh is changed + - name: Create iptables firewall config dir + file: + path: /etc/iptables + state: directory + owner: root + group: root + mode: 0775 + + - name: Configure iptables firewall service + copy: + src: iptables.rules + dest: /etc/iptables/iptables.rules + owner: root + group: root + mode: 0664 + + - name: Enable iptables firewall service + systemd: + name: iptables + enabled: yes + state: started + - name: Create containers include_tasks: setup_containers.yml vars: diff --git a/gerboweb/deploy/setup_clippy.yml b/gerboweb/deploy/setup_clippy.yml index e4416e0..26142b6 100644 --- a/gerboweb/deploy/setup_clippy.yml +++ b/gerboweb/deploy/setup_clippy.yml @@ -36,6 +36,22 @@ group: root mode: 0664 +- name: Create systemd-nspawn config dir + file: + path: /etc/systemd/nspawn + state: directory + owner: root + group: root + mode: 0775 + +- name: Copy over clippy container config + copy: + src: clippy.nspawn + dest: /etc/systemd/nspawn/clippy.nspawn + owner: root + group: root + mode: 0664 + - name: Enable clippy container auto boot systemd: daemon-reload: yes @@ -64,6 +80,6 @@ # enabled: yes # state: started -- name: Enable clippy container networkd - command: systemctl enable -M clippy systemd-networkd +#- name: Enable clippy container networkd +# command: systemctl enable -M clippy systemd-networkd -- cgit From 1bdfa0925e857cee67d896c13a505fe18c1044e2 Mon Sep 17 00:00:00 2001 From: jaseg Date: Mon, 15 Apr 2019 10:31:58 +0900 Subject: deploy: Fix up iptables to allow http(s) --- gerboweb/deploy/iptables.rules | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gerboweb') diff --git a/gerboweb/deploy/iptables.rules b/gerboweb/deploy/iptables.rules index 0f6f366..db68eb5 100644 --- a/gerboweb/deploy/iptables.rules +++ b/gerboweb/deploy/iptables.rules @@ -18,6 +18,8 @@ COMMIT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 2342 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 23 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT -- cgit From bf4620e3bf83cc332eace157ee73924b134ee5a3 Mon Sep 17 00:00:00 2001 From: jaseg Date: Mon, 15 Apr 2019 10:32:34 +0900 Subject: gerboweb: Add viewport meta --- gerboweb/templates/index.html | 1 + 1 file changed, 1 insertion(+) (limited to 'gerboweb') diff --git a/gerboweb/templates/index.html b/gerboweb/templates/index.html index 4dca6dc..a19fc88 100644 --- a/gerboweb/templates/index.html +++ b/gerboweb/templates/index.html @@ -5,6 +5,7 @@ +
-- cgit From 8cb082a42d71a1e86a138eb58106d636e7c6d191 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 26 Jun 2019 16:41:45 +0900 Subject: Misc changes. Move up to fedora 30, add gerbolyze, secure download --- gerboweb/deploy/inventory.yml | 1 + gerboweb/deploy/nginx.conf | 80 +++++++++++++++++++----- gerboweb/deploy/nginx_nossl.conf | 7 +++ gerboweb/deploy/playbook.yml | 15 ++--- gerboweb/deploy/secure_download.cfg.j2 | 1 + gerboweb/deploy/setup_secure_download.yml | 57 +++++++++++++++++ gerboweb/deploy/setup_webserver.yml | 15 ++++- gerboweb/deploy/tmpfiles-secure-download.conf.j2 | 1 + gerboweb/deploy/uwsgi-secure-download.ini | 10 +++ 9 files changed, 161 insertions(+), 26 deletions(-) create mode 100644 gerboweb/deploy/secure_download.cfg.j2 create mode 100644 gerboweb/deploy/setup_secure_download.yml create mode 100644 gerboweb/deploy/tmpfiles-secure-download.conf.j2 create mode 100644 gerboweb/deploy/uwsgi-secure-download.ini (limited to 'gerboweb') diff --git a/gerboweb/deploy/inventory.yml b/gerboweb/deploy/inventory.yml index 34e2e99..ea577e3 100644 --- a/gerboweb/deploy/inventory.yml +++ b/gerboweb/deploy/inventory.yml @@ -5,3 +5,4 @@ all: ansible_host: wendelstein.jaseg.net ansible_ssh_identity_file: ~/.ssh/id_ed25519 ansible_user: root + ansible_python_interpreter: /usr/bin/python3 diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index 6344904..1f44981 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -51,36 +51,86 @@ http { ssl_certificate "/etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/gerbolyze.jaseg.net/privkey.pem"; ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; + include /etc/letsencrypt/options-ssl-nginx.conf; - ssl_stapling on; - ssl_stapling_verify on; + ssl_stapling on; + ssl_stapling_verify on; - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; - add_header Strict-Transport-Security "max-age=86400"; + add_header Strict-Transport-Security "max-age=86400"; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; - location ^~ /static/ { - root /var/lib/gerboweb; - } + location ^~ /static/ { + root /var/lib/gerboweb; + } + + location / { + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/gerboweb.socket; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } + + server { + listen 80; + listen [::]:80; + server_name blog.jaseg.net blog.jaseg.net; + return 301 https://$host$request_uri; + } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name blog.jaseg.net blog.jaseg.net; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/blog.jaseg.net/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/blog.jaseg.net/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; location / { - include uwsgi_params; - uwsgi_pass unix:/run/uwsgi/gerboweb.socket; + root /var/www/blog.jaseg.net; + } + + location /d/ { + rewrite ^/d/(.*)$ /$1 break; + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/secure-download.socket; } error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; + location = /40x.html { + root /usr/share/nginx/html; } error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; + location = /50x.html { + root /usr/share/nginx/html; } } diff --git a/gerboweb/deploy/nginx_nossl.conf b/gerboweb/deploy/nginx_nossl.conf index 0ecd1cb..8d5a5a5 100644 --- a/gerboweb/deploy/nginx_nossl.conf +++ b/gerboweb/deploy/nginx_nossl.conf @@ -41,5 +41,12 @@ http { server_name gerbolyze.jaseg.net; return 301 https://$host$request_uri; } + + server { + listen 80; + listen [::]:80; + server_name blog.jaseg.net; + return 301 https://$host$request_uri; + } } diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 1c694d5..afea884 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -12,7 +12,7 @@ - name: Install host requisites dnf: - name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services + name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services,python3-pycryptodomex state: latest - name: Disable password-based root login @@ -28,18 +28,10 @@ state: restarted when: disable_root_pw_ssh is changed - - name: Create iptables firewall config dir - file: - path: /etc/iptables - state: directory - owner: root - group: root - mode: 0775 - - name: Configure iptables firewall service copy: src: iptables.rules - dest: /etc/iptables/iptables.rules + dest: /etc/sysconfig/iptables owner: root group: root mode: 0664 @@ -65,3 +57,6 @@ - name: Setup clippy include_tasks: setup_clippy.yml + + - name: Setup secure download + include_tasks: setup_secure_download.yml diff --git a/gerboweb/deploy/secure_download.cfg.j2 b/gerboweb/deploy/secure_download.cfg.j2 new file mode 100644 index 0000000..36d86c1 --- /dev/null +++ b/gerboweb/deploy/secure_download.cfg.j2 @@ -0,0 +1 @@ +SERVE_PATH="{{secure_download_dir}}" diff --git a/gerboweb/deploy/setup_secure_download.yml b/gerboweb/deploy/setup_secure_download.yml new file mode 100644 index 0000000..aa94a53 --- /dev/null +++ b/gerboweb/deploy/setup_secure_download.yml @@ -0,0 +1,57 @@ +--- +- name: Set local facts + set_fact: + secure_download_dir: /var/cache/secure_download + +- name: Copy webapp sources + synchronize: + # FIXME: make this path configurable + src: ~/secure_download/ + dest: /var/lib/secure_download/ + group: no + owner: no + +- name: Create secure download worker user and group + user: + name: uwsgi-secure-download + create_home: no + group: uwsgi + password: '!' + shell: /sbin/nologin + system: yes + +- name: Template webapp config + template: + src: secure_download.cfg.j2 + dest: /var/lib/secure_download/secure_download_prod.cfg + owner: uwsgi-secure-download + group: root + mode: 0660 + +- name: Copy uwsgi config + copy: + src: uwsgi-secure-download.ini + dest: /etc/uwsgi.d/secure-download.ini + owner: uwsgi-secure-download + group: uwsgi + mode: 440 + +- name: Enable uwsgi systemd socket + systemd: + daemon-reload: yes + name: uwsgi-app@secure-download.socket + enabled: yes + +- name: Copy server dir tmpfiles.d config + template: + src: tmpfiles-secure-download.conf.j2 + dest: /etc/tmpfiles.d/secure-download.conf + owner: root + group: root + mode: 0644 + register: sec_dl_tmpfiles_config + +- name: Kick systemd tmpfiles service to create serve dir + command: systemd-tmpfiles --create + when: sec_dl_tmpfiles_config is changed + diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml index 7dc65c5..ea821d8 100644 --- a/gerboweb/deploy/setup_webserver.yml +++ b/gerboweb/deploy/setup_webserver.yml @@ -9,6 +9,14 @@ groups: uwsgi append: yes +- name: Create blog.jaseg.net content dir + file: + path: /var/www/blog.jaseg.net + state: directory + owner: nginx + group: nginx + mode: 0550 + - name: Copy uwsgi systemd socket config copy: src: uwsgi-app@.socket @@ -30,11 +38,16 @@ enabled: yes state: restarted -- name: Create letsencrypt certificate +- name: Create letsencrypt certificate for gerbolyze.jaseg.net command: certbot --nginx certonly -d gerbolyze.jaseg.net -n --agree-tos --email gerboweb@jaseg.net args: creates: /etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem +- name: Create letsencrypt certificate for blog.jaseg.net + command: certbot --nginx certonly -d blog.jaseg.net -n --agree-tos --email blog@jaseg.net + args: + creates: /etc/letsencrypt/live/blog.jaseg.net/fullchain.pem + - name: Copy final nginx config copy: src: nginx.conf diff --git a/gerboweb/deploy/tmpfiles-secure-download.conf.j2 b/gerboweb/deploy/tmpfiles-secure-download.conf.j2 new file mode 100644 index 0000000..84d7add --- /dev/null +++ b/gerboweb/deploy/tmpfiles-secure-download.conf.j2 @@ -0,0 +1 @@ +d {{secure_download_dir}} 770 uwsgi-download uwsgi 45d diff --git a/gerboweb/deploy/uwsgi-secure-download.ini b/gerboweb/deploy/uwsgi-secure-download.ini new file mode 100644 index 0000000..5f999fc --- /dev/null +++ b/gerboweb/deploy/uwsgi-secure-download.ini @@ -0,0 +1,10 @@ +[uwsgi] +master = True +cheap = True +die-on-idle = False +manage-script-name = True +plugins = python3 +chdir = /var/lib/secure_download +mount = /=server:app +env = SECURE_DOWNLOAD_SETTINGS=secure_download_prod.cfg + -- cgit From 0ada527f0b0e8400253407b78a25d8fbadbe726b Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 27 Jun 2019 11:57:45 +0900 Subject: Limit logging of secure download requests --- gerboweb/deploy/nginx.conf | 2 ++ gerboweb/deploy/uwsgi-secure-download.ini | 1 + 2 files changed, 3 insertions(+) (limited to 'gerboweb') diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index 1f44981..b6f13c0 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -118,6 +118,8 @@ http { } location /d/ { + access_log off; + log_not_found off; rewrite ^/d/(.*)$ /$1 break; include uwsgi_params; uwsgi_pass unix:/run/uwsgi/secure-download.socket; diff --git a/gerboweb/deploy/uwsgi-secure-download.ini b/gerboweb/deploy/uwsgi-secure-download.ini index 5f999fc..4a4aa65 100644 --- a/gerboweb/deploy/uwsgi-secure-download.ini +++ b/gerboweb/deploy/uwsgi-secure-download.ini @@ -3,6 +3,7 @@ master = True cheap = True die-on-idle = False manage-script-name = True +log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) [URI hidden] => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core)) plugins = python3 chdir = /var/lib/secure_download mount = /=server:app -- cgit From aaacaed22082df3ec338b1bc795ebe3013c450c8 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 29 Sep 2019 16:28:11 +0200 Subject: deploy: add pogojig --- gerboweb/deploy/bootstrap_arch_container.yml | 4 +- gerboweb/deploy/checkouts/pogojig | 1 + gerboweb/deploy/nginx.conf | 128 +++++++++++++++++++++-- gerboweb/deploy/playbook.yml | 11 ++ gerboweb/deploy/pogojig-job-processor.service.j2 | 9 ++ gerboweb/deploy/pogojig.cfg.j2 | 4 + gerboweb/deploy/pogojig_flask_secret.txt | 1 + gerboweb/deploy/pogojig_generate.sh.j2 | 25 +++++ gerboweb/deploy/setup_openjscad.yml | 9 ++ gerboweb/deploy/setup_pogojig.yml | 118 +++++++++++++++++++++ gerboweb/deploy/setup_tracespace.yml | 9 ++ gerboweb/deploy/setup_webserver.yml | 25 +++-- gerboweb/deploy/tmpfiles-pogojig.conf.j2 | 1 + gerboweb/deploy/uwsgi-pogojig.ini | 10 ++ 14 files changed, 333 insertions(+), 22 deletions(-) create mode 160000 gerboweb/deploy/checkouts/pogojig create mode 100644 gerboweb/deploy/pogojig-job-processor.service.j2 create mode 100644 gerboweb/deploy/pogojig.cfg.j2 create mode 100644 gerboweb/deploy/pogojig_flask_secret.txt create mode 100755 gerboweb/deploy/pogojig_generate.sh.j2 create mode 100644 gerboweb/deploy/setup_openjscad.yml create mode 100644 gerboweb/deploy/setup_pogojig.yml create mode 100644 gerboweb/deploy/setup_tracespace.yml create mode 100644 gerboweb/deploy/tmpfiles-pogojig.conf.j2 create mode 100644 gerboweb/deploy/uwsgi-pogojig.ini (limited to 'gerboweb') diff --git a/gerboweb/deploy/bootstrap_arch_container.yml b/gerboweb/deploy/bootstrap_arch_container.yml index 4126bbd..11bbf3d 100644 --- a/gerboweb/deploy/bootstrap_arch_container.yml +++ b/gerboweb/deploy/bootstrap_arch_container.yml @@ -13,9 +13,9 @@ - name: Download arch bootstrap image get_url: - url: http://mirror.rackspace.com/archlinux/iso/2019.03.01/archlinux-bootstrap-2019.03.01-x86_64.tar.gz + url: http://mirror.rackspace.com/archlinux/iso/2019.09.01/archlinux-bootstrap-2019.09.01-x86_64.tar.gz dest: /tmp/arch-bootstrap.tar.xz - checksum: sha256:865c8a25312b663e724923eecf0dfc626f4cd621e2cfcb19eafc69a4fc666756 + checksum: sha256:9fc9f178db6f5c188be8884c0abf10c69418e7cd38a4389e866fac5d9961297d when: create_container is changed - name: Create container image filesystem diff --git a/gerboweb/deploy/checkouts/pogojig b/gerboweb/deploy/checkouts/pogojig new file mode 160000 index 0000000..04b34f7 --- /dev/null +++ b/gerboweb/deploy/checkouts/pogojig @@ -0,0 +1 @@ +Subproject commit 04b34f73c1e0023ce4abdb9f1c9f0d9175247624 diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index b6f13c0..6cf28cf 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -36,9 +36,9 @@ http { include /etc/nginx/conf.d/*.conf; server { - listen 80 default_server; - listen [::]:80 default_server; - server_name gerbolyze.jaseg.net; + listen 80; + listen [::]:80; + server_name .jaseg.net; return 301 https://$host$request_uri; } @@ -84,13 +84,6 @@ http { } } - server { - listen 80; - listen [::]:80; - server_name blog.jaseg.net blog.jaseg.net; - return 301 https://$host$request_uri; - } - server { listen 443 ssl http2; listen [::]:443 ssl http2; @@ -136,5 +129,120 @@ http { } } + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name pogojig.jaseg.net; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/pogojig.jaseg.net/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/pogojig.jaseg.net/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location ^~ /pogospace/ { + root /var/lib/pogojig/pogospace; + } + + location / { + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/pogojig.socket; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name tracespace.jaseg.net; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/tracespace.jaseg.net/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/tracespace.jaseg.net/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location / { + root /var/www/tracespace.jaseg.net; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name openjscad.jaseg.net; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/openjscad.jaseg.net/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/openjscad.jaseg.net/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location / { + root /var/www/openjscad.jaseg.net; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } } diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index afea884..6d558d3 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -48,6 +48,7 @@ containers: - gerboweb - clippy + - pogojig - name: Setup web server include_tasks: setup_webserver.yml @@ -60,3 +61,13 @@ - name: Setup secure download include_tasks: setup_secure_download.yml + + - name: Setup tracespace + include_tasks: setup_tracespace.yml + + - name: Setup openjscad + include_tasks: setup_openjscad.yml + + - name: Setup pogojig + include_tasks: setup_pogojig.yml + diff --git a/gerboweb/deploy/pogojig-job-processor.service.j2 b/gerboweb/deploy/pogojig-job-processor.service.j2 new file mode 100644 index 0000000..5ca9a8b --- /dev/null +++ b/gerboweb/deploy/pogojig-job-processor.service.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=Pogojig render job processor + +[Service] +WorkingDirectory=/var/lib/pogojig +ExecStart=/usr/bin/python3 job_processor.py {{pogojig_cache}}/job_queue.sqlite3 + +[Install] +WantedBy=uwsgi-app@pogojig.service diff --git a/gerboweb/deploy/pogojig.cfg.j2 b/gerboweb/deploy/pogojig.cfg.j2 new file mode 100644 index 0000000..3dd7160 --- /dev/null +++ b/gerboweb/deploy/pogojig.cfg.j2 @@ -0,0 +1,4 @@ +MAX_CONTENT_LENGTH=10000000 +SECRET_KEY="{{lookup('password', 'pogojig_flask_secret.txt length=32')}}" +UPLOAD_PATH="{{pogojig_cache}}/upload" +JOB_QUEUE_DB="{{pogojig_cache}}/job_queue.sqlite3" diff --git a/gerboweb/deploy/pogojig_flask_secret.txt b/gerboweb/deploy/pogojig_flask_secret.txt new file mode 100644 index 0000000..fc1e245 --- /dev/null +++ b/gerboweb/deploy/pogojig_flask_secret.txt @@ -0,0 +1 @@ +RhshDKyRVcg.5r4ulH:0f8Vhut0HoFS3 diff --git a/gerboweb/deploy/pogojig_generate.sh.j2 b/gerboweb/deploy/pogojig_generate.sh.j2 new file mode 100755 index 0000000..c1cc023 --- /dev/null +++ b/gerboweb/deploy/pogojig_generate.sh.j2 @@ -0,0 +1,25 @@ +#!/bin/sh + +[ $# != 1 ] && exit 1 +ID=$1 +egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 + +systemd-nspawn \ + -D {{pogojig_root}} \ + -x --bind={{pogojig_cache}}/upload/$ID:/mnt \ + /bin/sh -c "set -euo pipefail +cd /mnt + +date; echo 'Cleaning up previous output' +rm -rf pcb_shape.dxf jig.stl kicad kicad.zip sources.zip + +date; echo 'Rendering' +cp -r /var/lib/pogojig_renderer sources +cp input.svg sources/ +make -C sources + +date; echo 'Packing source bundle' +cp -r sources/out/pcb_shape.dxf sources/out/jig.stl sources/out/kicad ./ +zip -r sources.zip sources +zip -r kicad.zip kicad +rm -rf sources" diff --git a/gerboweb/deploy/setup_openjscad.yml b/gerboweb/deploy/setup_openjscad.yml new file mode 100644 index 0000000..dea4ad2 --- /dev/null +++ b/gerboweb/deploy/setup_openjscad.yml @@ -0,0 +1,9 @@ +--- +- name: Copy openjscad webapp sources + synchronize: + # FIXME: make this path configurable + src: ~/openjscad_dist/ + dest: /var/www/openjscad.jaseg.net/ + group: no + owner: no + diff --git a/gerboweb/deploy/setup_pogojig.yml b/gerboweb/deploy/setup_pogojig.yml new file mode 100644 index 0000000..8a4c827 --- /dev/null +++ b/gerboweb/deploy/setup_pogojig.yml @@ -0,0 +1,118 @@ +--- +- name: Set local facts + set_fact: + pogojig_cache: /var/cache/pogojig + +- name: Copy render script + template: + src: pogojig_generate.sh.j2 + dest: /usr/local/sbin/pogojig_generate.sh + mode: ug+x + +- name: Install packages into pogojig container + shell: arch-chroot "{{pogojig_root}}" pacman -Syu --noconfirm python3 python-pip imagemagick unzip zip openscad inkscape make python-lxml xorg-server-xvfb + +- name: Install python dependencies into pogojig container + shell: arch-chroot "{{pogojig_root}}" pip install -U --upgrade-strategy=eager ezdxf xvfbwrapper + +- name: Install pogojig + synchronize: + # FIXME: make this path configurable + src: checkouts/pogojig/renderer/ + dest: "{{pogojig_root}}/var/lib/pogojig_renderer" + group: no + +- name: Copy webapp sources + synchronize: + # FIXME: make this path configurable + src: checkouts/pogojig/webapp/ + dest: /var/lib/pogojig + group: no + owner: no + +- name: Create web home for modified tracespace + file: + path: /var/lib/pogojig/pogospace + state: directory + owner: nginx + group: nginx + mode: 0550 + +- name: Unpack modified tracespace sources + unarchive: + src: resource/pogojig-tracespace.tar.gz + dest: /var/lib/pogojig/pogospace + extra_opts: [--strip-components=1] + owner: nginx + group: nginx + +- name: Create uwsgi worker user and group + user: + name: uwsgi-pogojig + create_home: no + group: uwsgi + password: '!' + shell: /sbin/nologin + system: yes + +- name: Template webapp config + template: + src: pogojig.cfg.j2 + dest: /var/lib/pogojig/pogojig_prod.cfg + owner: uwsgi-pogojig + group: root + mode: 0660 + +- name: Copy uwsgi config + copy: + src: uwsgi-pogojig.ini + dest: /etc/uwsgi.d/pogojig.ini + owner: uwsgi-pogojig + group: uwsgi + mode: 440 + +- name: Copy job processor systemd service config + template: + src: pogojig-job-processor.service.j2 + dest: /etc/systemd/system/pogojig-job-processor.service + +- name: Enable uwsgi systemd socket + systemd: + daemon-reload: yes + name: uwsgi-app@pogojig.socket + enabled: yes + +# FIXME the socket doesn't seem to work properly +- name: Enable uwsgi systemd service + systemd: + daemon-reload: yes + name: uwsgi-app@pogojig.service + enabled: yes + +- name: Copy pogojig cache dir tmpfiles.d config + template: + src: tmpfiles-pogojig.conf.j2 + dest: /etc/tmpfiles.d/pogojig.conf + owner: root + group: root + mode: 0644 + register: pogojig_tmpfiles_config + +- name: Kick systemd tmpfiles service to create cache dir + command: systemd-tmpfiles --create + when: pogojig_tmpfiles_config is changed + +- name: Create job queue db + file: + path: "{{pogojig_cache}}/job_queue.sqlite3" + owner: root + group: uwsgi + mode: 0660 + state: touch + +- name: Enable and launch job processor + systemd: + name: pogojig-job-processor.service + enabled: yes + state: restarted + diff --git a/gerboweb/deploy/setup_tracespace.yml b/gerboweb/deploy/setup_tracespace.yml new file mode 100644 index 0000000..2975967 --- /dev/null +++ b/gerboweb/deploy/setup_tracespace.yml @@ -0,0 +1,9 @@ +--- +- name: Copy tracespace webapp sources + synchronize: + # FIXME: make this path configurable + src: ~/tracespace_dist/ + dest: /var/www/tracespace.jaseg.net/ + group: no + owner: no + diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml index ea821d8..671a699 100644 --- a/gerboweb/deploy/setup_webserver.yml +++ b/gerboweb/deploy/setup_webserver.yml @@ -9,13 +9,17 @@ groups: uwsgi append: yes -- name: Create blog.jaseg.net content dir +- name: Create subdomain content dirs file: - path: /var/www/blog.jaseg.net + path: /var/www/{{item}} state: directory owner: nginx group: nginx mode: 0550 + loop: + - blog.jaseg.net + - tracespace.jaseg.net + - openjscad.jaseg.net - name: Copy uwsgi systemd socket config copy: @@ -38,15 +42,16 @@ enabled: yes state: restarted -- name: Create letsencrypt certificate for gerbolyze.jaseg.net - command: certbot --nginx certonly -d gerbolyze.jaseg.net -n --agree-tos --email gerboweb@jaseg.net +- name: Create subdomain letsencrypt certificates + command: certbot --nginx certonly -d {{item}} -n --agree-tos --email {{item}}-letsencrypt@jaseg.net args: - creates: /etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem - -- name: Create letsencrypt certificate for blog.jaseg.net - command: certbot --nginx certonly -d blog.jaseg.net -n --agree-tos --email blog@jaseg.net - args: - creates: /etc/letsencrypt/live/blog.jaseg.net/fullchain.pem + creates: /etc/letsencrypt/live/{{item}}/fullchain.pem + loop: + - blog.jaseg.net + - gerbolyze.jaseg.net + - tracespace.jaseg.net + - openjscad.jaseg.net + - pogojig.jaseg.net - name: Copy final nginx config copy: diff --git a/gerboweb/deploy/tmpfiles-pogojig.conf.j2 b/gerboweb/deploy/tmpfiles-pogojig.conf.j2 new file mode 100644 index 0000000..4e9fef1 --- /dev/null +++ b/gerboweb/deploy/tmpfiles-pogojig.conf.j2 @@ -0,0 +1 @@ +d {{pogojig_cache}} 770 uwsgi-pogojig uwsgi 2d diff --git a/gerboweb/deploy/uwsgi-pogojig.ini b/gerboweb/deploy/uwsgi-pogojig.ini new file mode 100644 index 0000000..003702d --- /dev/null +++ b/gerboweb/deploy/uwsgi-pogojig.ini @@ -0,0 +1,10 @@ +[uwsgi] +master = True +cheap = True +die-on-idle = False +manage-script-name = True +plugins = python3 +chdir = /var/lib/pogojig +mount = /=pogojig:app +env = POGOJIG_SETTINGS=pogojig_prod.cfg + -- cgit From cbbdba053e9eca935ad80eb35e0ede4bb84776df Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 29 Sep 2019 17:11:10 +0200 Subject: Add pogojig template zip packing --- gerboweb/deploy/checkouts/pogojig | 2 +- gerboweb/deploy/playbook.yml | 2 +- gerboweb/deploy/setup_gerboweb.yml | 2 ++ gerboweb/deploy/setup_pogojig.yml | 7 +++++++ 4 files changed, 11 insertions(+), 2 deletions(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/checkouts/pogojig b/gerboweb/deploy/checkouts/pogojig index 04b34f7..75dd7db 160000 --- a/gerboweb/deploy/checkouts/pogojig +++ b/gerboweb/deploy/checkouts/pogojig @@ -1 +1 @@ -Subproject commit 04b34f73c1e0023ce4abdb9f1c9f0d9175247624 +Subproject commit 75dd7db73fe87d57f5965d0c689257a56296201c diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 6d558d3..0d16d7f 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -12,7 +12,7 @@ - name: Install host requisites dnf: - name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services,python3-pycryptodomex + name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services,python3-pycryptodomex,zip state: latest - name: Disable password-based root login diff --git a/gerboweb/deploy/setup_gerboweb.yml b/gerboweb/deploy/setup_gerboweb.yml index e1a49fb..c06444c 100644 --- a/gerboweb/deploy/setup_gerboweb.yml +++ b/gerboweb/deploy/setup_gerboweb.yml @@ -27,6 +27,8 @@ # FIXME: make this path configurable src: ~/gerbolyze/gerboweb/ dest: /var/lib/gerboweb/ + rsync_opts: + - "--exclude=/deploy" group: no owner: no diff --git a/gerboweb/deploy/setup_pogojig.yml b/gerboweb/deploy/setup_pogojig.yml index 8a4c827..cf49fbe 100644 --- a/gerboweb/deploy/setup_pogojig.yml +++ b/gerboweb/deploy/setup_pogojig.yml @@ -27,9 +27,16 @@ # FIXME: make this path configurable src: checkouts/pogojig/webapp/ dest: /var/lib/pogojig + delete: true group: no owner: no +- name: Pack makefile template zip + archive: + path: "{{pogojig_root}}/var/lib/pogojig_renderer" + dest: /var/lib/pogojig/static/pogojig_makefile_template.zip + format: zip + - name: Create web home for modified tracespace file: path: /var/lib/pogojig/pogospace -- cgit From 841364c500d79fb2749df8a08e85ed26d49bf893 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 17 Jan 2020 00:51:09 +0100 Subject: m( --- gerboweb/deploy/.gitignore | 2 +- gerboweb/deploy/pogojig_flask_secret.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 gerboweb/deploy/pogojig_flask_secret.txt (limited to 'gerboweb') diff --git a/gerboweb/deploy/.gitignore b/gerboweb/deploy/.gitignore index 97b80a1..c3129a6 100644 --- a/gerboweb/deploy/.gitignore +++ b/gerboweb/deploy/.gitignore @@ -1,2 +1,2 @@ -gerboweb_flask_secret.txt +*_secret.txt playbook.retry diff --git a/gerboweb/deploy/pogojig_flask_secret.txt b/gerboweb/deploy/pogojig_flask_secret.txt deleted file mode 100644 index fc1e245..0000000 --- a/gerboweb/deploy/pogojig_flask_secret.txt +++ /dev/null @@ -1 +0,0 @@ -RhshDKyRVcg.5r4ulH:0f8Vhut0HoFS3 -- cgit From 996d47f17580cd6b9efcbd78b97aba13f8e487e3 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 17 Jan 2020 00:51:31 +0100 Subject: Add kochbuch --- gerboweb/deploy/nginx.conf | 40 +++++++++++++++++++++++++++++++++++++ gerboweb/deploy/setup_webserver.yml | 2 ++ 2 files changed, 42 insertions(+) (limited to 'gerboweb') diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index 6cf28cf..8d21357 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -129,6 +129,45 @@ http { } } + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name kochbuch.jaseg.net kochbuch.jaseg.net; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/kochbuch.jaseg.net/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/kochbuch.jaseg.net/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location / { + auth_basic "blubb"; + auth_basic_user_file /etc/nginx/kochbuch.htpasswd; + root /var/www/kochbuch.jaseg.net; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } + server { listen 443 ssl http2; listen [::]:443 ssl http2; @@ -145,6 +184,7 @@ http { resolver 67.207.67.2 67.207.67.3 valid=300s; resolver_timeout 10s; + client_max_body_size 10M; add_header Strict-Transport-Security "max-age=86400"; diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml index 671a699..1405bed 100644 --- a/gerboweb/deploy/setup_webserver.yml +++ b/gerboweb/deploy/setup_webserver.yml @@ -18,6 +18,7 @@ mode: 0550 loop: - blog.jaseg.net + - kochbuch.jaseg.net - tracespace.jaseg.net - openjscad.jaseg.net @@ -48,6 +49,7 @@ creates: /etc/letsencrypt/live/{{item}}/fullchain.pem loop: - blog.jaseg.net + - kochbuch.jaseg.net - gerbolyze.jaseg.net - tracespace.jaseg.net - openjscad.jaseg.net -- cgit From 40ae8e829c5eedf56fc4a3183c40bf10a65b8797 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 17 Jan 2020 11:10:51 +0100 Subject: deploy: gerbowebg/cairoffi issue workaround --- gerboweb/deploy/setup_gerboweb.yml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gerboweb') diff --git a/gerboweb/deploy/setup_gerboweb.yml b/gerboweb/deploy/setup_gerboweb.yml index c06444c..29e83d3 100644 --- a/gerboweb/deploy/setup_gerboweb.yml +++ b/gerboweb/deploy/setup_gerboweb.yml @@ -18,6 +18,9 @@ - name: Install packages into gerbolyze container shell: arch-chroot "{{gerboweb_root}}" pacman -Syu --noconfirm python3 opencv hdf5 gtk3 python-numpy python-pip imagemagick unzip zip +- name: Workaround for cairoffi problem + shell: arch-chroot "{{gerboweb_root}}" pip install -U --upgrade-strategy=eager wheel + # TODO maybe install directly from local git checkout? - name: Install gerbolyze shell: arch-chroot "{{gerboweb_root}}" pip install -U --upgrade-strategy=eager gerbolyze -- cgit From 314d03748e938f62796313386bad52818e89a793 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 17 Jan 2020 11:11:52 +0100 Subject: deploy: add notification proxy --- gerboweb/deploy/.gitignore | 1 + gerboweb/deploy/nginx.conf | 38 +++++++++++ gerboweb/deploy/notification_proxy.py | 89 +++++++++++++++++++++++++ gerboweb/deploy/notification_proxy_config.py.j2 | 5 ++ gerboweb/deploy/playbook.yml | 3 + gerboweb/deploy/setup_notification_proxy.yml | 48 +++++++++++++ gerboweb/deploy/setup_webserver.yml | 2 + gerboweb/deploy/uwsgi-notification-proxy.ini | 10 +++ 8 files changed, 196 insertions(+) create mode 100644 gerboweb/deploy/notification_proxy.py create mode 100644 gerboweb/deploy/notification_proxy_config.py.j2 create mode 100644 gerboweb/deploy/setup_notification_proxy.yml create mode 100644 gerboweb/deploy/uwsgi-notification-proxy.ini (limited to 'gerboweb') diff --git a/gerboweb/deploy/.gitignore b/gerboweb/deploy/.gitignore index c3129a6..e681fba 100644 --- a/gerboweb/deploy/.gitignore +++ b/gerboweb/deploy/.gitignore @@ -1,2 +1,3 @@ *_secret.txt +*_apikey.txt playbook.retry diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index 8d21357..fb88cbd 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -129,6 +129,44 @@ http { } } + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name automation.jaseg.de; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/automation.jaseg.de/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/automation.jaseg.de/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location / { + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/notification-proxy.socket; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } + server { listen 443 ssl http2; listen [::]:443 ssl http2; diff --git a/gerboweb/deploy/notification_proxy.py b/gerboweb/deploy/notification_proxy.py new file mode 100644 index 0000000..ae4d73e --- /dev/null +++ b/gerboweb/deploy/notification_proxy.py @@ -0,0 +1,89 @@ +import smtplib +import ssl +import email.utils +import hmac +from email.mime.text import MIMEText +from datetime import datetime +import functools +import json +import binascii + +from flask import Flask, request, abort + +app = Flask(__name__) +app.config.from_pyfile('config.py') + +smtp_server = "smtp.sendgrid.net" +port = 465 + +mail_routes = {} +def mail_route(name, receiver, subject): + def wrap(func): + global routes + mail_routes[name] = (receiver, subject, func) + return func + return wrap + + +def authenticate(secret): + def wrap(func): + func.last_seqnum = 0 + @functools.wraps(func) + def wrapper(*args, **kwargs): + if not request.is_json: + abort(400) + + if not 'auth' in request.json and 'payload' in request.json: + abort(400) + + if not isinstance(request.json['auth'], str): + abort(400) + their_digest = binascii.unhexlify(request.json['auth']) + + our_digest = hmac.digest(secret.encode('utf-8'), request.json['payload'].encode('utf-8'), 'sha256') + if not hmac.compare_digest(their_digest, our_digest): + abort(403) + + try: + payload = json.loads(request.json['payload']) + except: + abort(400) + + if not isinstance(payload['seq'], int) or payload['seq'] <= func.last_seqnum: + abort(400) + + func.last_seqnum = payload['seq'] + del payload['seq'] + return func(payload) + return wrapper + return wrap + +@mail_route('klingel', 'computerstuff@jaseg.de', 'It rang!') +@authenticate(app.config['SECRET_KLINGEL']) +def klingel(_): + return f'Date: {datetime.utcnow().isoformat()}' + + +@app.route('/notify/', methods=['POST']) +def notify(route_name): + try: + context = ssl.create_default_context() + smtp = smtplib.SMTP_SSL(smtp_server, port) + smtp.login('apikey', app.config['SENDGRID_APIKEY']) + + sender = f'{route_name}@{app.config["DOMAIN"]}' + + receiver, subject, func = mail_routes[route_name] + + msg = MIMEText(func() or subject) + msg['Subject'] = subject + msg['From'] = sender + msg['To'] = receiver + msg['Date'] = email.utils.formatdate() + smtp.sendmail(sender, receiver, msg.as_string()) + finally: + smtp.quit() + return 'success' + +if __name__ == '__main__': + app.run() diff --git a/gerboweb/deploy/notification_proxy_config.py.j2 b/gerboweb/deploy/notification_proxy_config.py.j2 new file mode 100644 index 0000000..ea53e34 --- /dev/null +++ b/gerboweb/deploy/notification_proxy_config.py.j2 @@ -0,0 +1,5 @@ + +SENDGRID_APIKEY = '{{lookup('file', 'notification_proxy_sendgrid_apikey.txt')}}' +DOMAIN = 'automation.jaseg.de' + +SECRET_KLINGEL = '{{lookup('password', 'notification_proxy_klingel_secret.txt length=32')}}' diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 0d16d7f..2db45bc 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -71,3 +71,6 @@ - name: Setup pogojig include_tasks: setup_pogojig.yml + - name: Setup notification proxy + include_tasks: setup_notification_proxy.yml + diff --git a/gerboweb/deploy/setup_notification_proxy.yml b/gerboweb/deploy/setup_notification_proxy.yml new file mode 100644 index 0000000..3f86412 --- /dev/null +++ b/gerboweb/deploy/setup_notification_proxy.yml @@ -0,0 +1,48 @@ +--- +- name: Create notification proxy worker user and group + user: + name: uwsgi-notification-proxy + create_home: no + group: uwsgi + password: '!' + shell: /sbin/nologin + system: yes + +- name: Create webapp dir + file: + path: /var/lib/notification-proxy + state: directory + owner: uwsgi-notification-proxy + group: uwsgi + mode: 0550 + +- name: Copy webapp sources + copy: + src: notification_proxy.py + dest: /var/lib/notification-proxy/ + owner: uwsgi-notification-proxy + group: uwsgi + mode: 0440 + +- name: Template webapp config + template: + src: notification_proxy_config.py.j2 + dest: /var/lib/notification-proxy/config.py + owner: uwsgi-notification-proxy + group: root + mode: 0660 + +- name: Copy uwsgi config + copy: + src: uwsgi-notification-proxy.ini + dest: /etc/uwsgi.d/notification-proxy.ini + owner: uwsgi-notification-proxy + group: uwsgi + mode: 0440 + +- name: Enable uwsgi systemd socket + systemd: + daemon-reload: yes + name: uwsgi-app@notification-proxy.socket + enabled: yes + diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml index 1405bed..8f1f429 100644 --- a/gerboweb/deploy/setup_webserver.yml +++ b/gerboweb/deploy/setup_webserver.yml @@ -21,6 +21,7 @@ - kochbuch.jaseg.net - tracespace.jaseg.net - openjscad.jaseg.net + - automation.jaseg.de - name: Copy uwsgi systemd socket config copy: @@ -54,6 +55,7 @@ - tracespace.jaseg.net - openjscad.jaseg.net - pogojig.jaseg.net + - automation.jaseg.de - name: Copy final nginx config copy: diff --git a/gerboweb/deploy/uwsgi-notification-proxy.ini b/gerboweb/deploy/uwsgi-notification-proxy.ini new file mode 100644 index 0000000..aab2b5a --- /dev/null +++ b/gerboweb/deploy/uwsgi-notification-proxy.ini @@ -0,0 +1,10 @@ +[uwsgi] +master = True +cheap = True +die-on-idle = False +manage-script-name = True +log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) [URI hidden] => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core)) +plugins = python3 +chdir = /var/lib/notification-proxy +mount = /=notification_proxy:app + -- cgit From e2865d243b360a462b3dae5157fd78fd26be1371 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 22 Jan 2020 15:54:35 +0100 Subject: nginx.conf: fix typo --- gerboweb/deploy/nginx.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index fb88cbd..f3400cc 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -87,7 +87,7 @@ http { server { listen 443 ssl http2; listen [::]:443 ssl http2; - server_name blog.jaseg.net blog.jaseg.net; + server_name blog.jaseg.net; root /usr/share/nginx/html; ssl_certificate "/etc/letsencrypt/live/blog.jaseg.net/fullchain.pem"; @@ -170,7 +170,7 @@ http { server { listen 443 ssl http2; listen [::]:443 ssl http2; - server_name kochbuch.jaseg.net kochbuch.jaseg.net; + server_name kochbuch.jaseg.net; root /usr/share/nginx/html; ssl_certificate "/etc/letsencrypt/live/kochbuch.jaseg.net/fullchain.pem"; -- cgit From a4eba0f69960fc40325c087dc03b9513f657b1e6 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 22 Jan 2020 15:54:59 +0100 Subject: notification_proxy: Add heartbeat and startup monitoring --- gerboweb/deploy/notification_proxy.py | 155 ++++++++++++++++++------ gerboweb/deploy/notification_proxy_config.py.j2 | 4 + gerboweb/deploy/playbook.yml | 2 +- gerboweb/deploy/setup_notification_proxy.yml | 15 ++- 4 files changed, 138 insertions(+), 38 deletions(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/notification_proxy.py b/gerboweb/deploy/notification_proxy.py index ae4d73e..d30a23d 100644 --- a/gerboweb/deploy/notification_proxy.py +++ b/gerboweb/deploy/notification_proxy.py @@ -4,86 +4,169 @@ import email.utils import hmac from email.mime.text import MIMEText from datetime import datetime +import time import functools import json import binascii +import uwsgidecorators + +import sqlite3 from flask import Flask, request, abort app = Flask(__name__) app.config.from_pyfile('config.py') -smtp_server = "smtp.sendgrid.net" -port = 465 +db = sqlite3.connect(app.config['SQLITE_DB'], check_same_thread=False) +with db as conn: + conn.execute('''CREATE TABLE IF NOT EXISTS seqs_seen + (route_name TEXT PRIMARY KEY, + seq INTEGER)''') + conn.execute('''CREATE TABLE IF NOT EXISTS time_seen + (route_name TEXT PRIMARY KEY)''') + + conn.execute('''CREATE TABLE IF NOT EXISTS heartbeats_seen + (route_name TEXT PRIMARY KEY, + timestamp INTEGER, + notified INTEGER)''') + # Clear table on startup to avoid spurious notifications + conn.execute('''DELETE FROM heartbeats_seen''') mail_routes = {} -def mail_route(name, receiver, subject): + +def mail_route(name, receiver, subject, secret): def wrap(func): global routes - mail_routes[name] = (receiver, subject, func) + mail_routes[name] = (receiver, subject, func, secret) return func return wrap -def authenticate(secret): - def wrap(func): - func.last_seqnum = 0 - @functools.wraps(func) - def wrapper(*args, **kwargs): - if not request.is_json: +def authenticate(route_name, secret, clock_delta_tolerance:'s'=120): + with db as conn: + if not request.is_json: + print('Rejecting notification: Incorrect content type') + abort(400) + + if not 'auth' in request.json and 'payload' in request.json: + print('Rejecting notification: signature or payload not found') + abort(400) + + if not isinstance(request.json['auth'], str): + print('Rejecting notification: signature is of incorrect type') + abort(400) + their_digest = binascii.unhexlify(request.json['auth']) + + our_digest = hmac.digest(secret.encode('utf-8'), request.json['payload'].encode('utf-8'), 'sha256') + if not hmac.compare_digest(their_digest, our_digest): + print('Rejecting notification: Incorrect signature') + abort(403) + + try: + payload = json.loads(request.json['payload']) + except: + print('Rejecting notification: Payload is not JSON') + abort(400) + + last_seqnum = conn.execute('SELECT seq FROM seqs_seen WHERE route_name = ?', (route_name,)).fetchone() or 0 + # We can check for seq here: Only an attacker with knowledge of the secret would be able to remove + # seq from a message. This means for a single key, only messages with or without seq may ever be used. + if 'seq' in payload: + seq = payload['seq'] + if not isinstance(seq, int): + print('Rejecting notification: seq of wrong type') abort(400) - if not 'auth' in request.json and 'payload' in request.json: + if seq <= last_seqnum: + print('Rejecting notification: seq out of order') abort(400) - if not isinstance(request.json['auth'], str): - abort(400) - their_digest = binascii.unhexlify(request.json['auth']) + conn.execute('INSERT OR REPLACE INTO seqs_seen VALUES (?, ?)', (route_name, seq)) - our_digest = hmac.digest(secret.encode('utf-8'), request.json['payload'].encode('utf-8'), 'sha256') - if not hmac.compare_digest(their_digest, our_digest): - abort(403) + elif last_seqnum: + print('Rejecting notification: seq not included but past messages included seq') + abort(400) - try: - payload = json.loads(request.json['payload']) - except: + msg_time = None + if 'time' in payload: + msg_time = payload['time'] + if not isinstance(msg_time, int): + print('Rejecting notification: time of wrong type') abort(400) - if not isinstance(payload['seq'], int) or payload['seq'] <= func.last_seqnum: + if abs(msg_time - int(time.time())) > clock_delta_tolerance: + print('Rejecting notification: timestamp too far in the future or past') abort(400) - func.last_seqnum = payload['seq'] - del payload['seq'] - return func(payload) - return wrapper - return wrap + conn.execute('INSERT OR REPLACE INTO time_seen VALUES (?)', (route_name,)) -@mail_route('klingel', 'computerstuff@jaseg.de', 'It rang!') -@authenticate(app.config['SECRET_KLINGEL']) -def klingel(_): - return f'Date: {datetime.utcnow().isoformat()}' + elif conn.execute('SELECT * FROM time_seen WHERE route_name = ?', (route_name,)).fetchone(): + print('Rejecting notification: time not included but past messages included time') + abort(400) + if msg_time is None: + msg_time = int(time.time()) -@app.route('/notify/', methods=['POST']) -def notify(route_name): + return msg_time, payload['scope'], payload['d'] + +@mail_route('klingel', 'computerstuff@jaseg.de', 'It rang!', app.config['SECRET_KLINGEL']) +def klingel(rms=None, capture=None, **kwargs): + return f'rms={rms}\ncapture={capture}\nextra_args={kwargs}' + + +def send_mail(route_name, receiver, subject, body): try: context = ssl.create_default_context() - smtp = smtplib.SMTP_SSL(smtp_server, port) + smtp = smtplib.SMTP_SSL(app.config['SMTP_HOST'], app.config['SMTP_PORT']) smtp.login('apikey', app.config['SENDGRID_APIKEY']) sender = f'{route_name}@{app.config["DOMAIN"]}' - receiver, subject, func = mail_routes[route_name] - - msg = MIMEText(func() or subject) + msg = MIMEText(body) msg['Subject'] = subject msg['From'] = sender msg['To'] = receiver msg['Date'] = email.utils.formatdate() + smtp.sendmail(sender, receiver, msg.as_string()) finally: smtp.quit() + +@app.route('/v1/notify/', methods=['POST']) +def notify(route_name): + receiver, notify_subject, func, secret = mail_routes[route_name] + msg_time, scope, kwargs = authenticate(route_name, secret) + + if scope == 'default': + # Exceptions will yield a 500 error + body = func(**kwargs) + send_mail(route_name, receiver, notify_subject, body or 'empty message') + + elif scope == 'boot': + formatted = datetime.utcfromtimestamp(msg_time).isoformat() + send_mail(route_name, receiver, 'System startup', f'System powered up at {formatted}') + + elif scope == 'heartbeat': + with db as conn: + conn.execute('INSERT OR REPLACE INTO heartbeats_seen VALUES (?, ?, 0)', (route_name, int(time.time()))) + return 'success' +@uwsgidecorators.timer(60) +def heartbeat_timer(_uwsgi_signum): + threshold = int(time.time()) - app.config['HEARTBEAT_TIMEOUT'] + with db as conn: + for route, ts in db.execute( + 'SELECT route_name, timestamp FROM heartbeats_seen WHERE timestamp <= ? AND notified == 0', + (threshold,)).fetchall(): + print(f'Heartbeat expired for {route}: {ts} < {threshold}') + + receiver, *_ = mail_routes[route] + last = datetime.utcfromtimestamp(ts).isoformat() + + send_mail(route, receiver, 'Heartbeat timeout', f'Last heartbeat at {last}') + db.execute('UPDATE heartbeats_seen SET notified = ? WHERE route_name = ?', (int(time.time()), route)) + if __name__ == '__main__': app.run() + diff --git a/gerboweb/deploy/notification_proxy_config.py.j2 b/gerboweb/deploy/notification_proxy_config.py.j2 index ea53e34..2ecf571 100644 --- a/gerboweb/deploy/notification_proxy_config.py.j2 +++ b/gerboweb/deploy/notification_proxy_config.py.j2 @@ -1,5 +1,9 @@ SENDGRID_APIKEY = '{{lookup('file', 'notification_proxy_sendgrid_apikey.txt')}}' DOMAIN = 'automation.jaseg.de' +SMTP_HOST = "smtp.sendgrid.net" +SMTP_PORT = 465 +HEARTBEAT_TIMEOUT = 300 +SQLITE_DB = '{{notification_proxy_sqlite_dbfile}}' SECRET_KLINGEL = '{{lookup('password', 'notification_proxy_klingel_secret.txt length=32')}}' diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 2db45bc..7c7c95d 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -12,7 +12,7 @@ - name: Install host requisites dnf: - name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services,python3-pycryptodomex,zip + name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services,python3-pycryptodomex,zip,python3-uwsgidecorators state: latest - name: Disable password-based root login diff --git a/gerboweb/deploy/setup_notification_proxy.yml b/gerboweb/deploy/setup_notification_proxy.yml index 3f86412..b47af05 100644 --- a/gerboweb/deploy/setup_notification_proxy.yml +++ b/gerboweb/deploy/setup_notification_proxy.yml @@ -1,4 +1,8 @@ --- +- name: Set local facts + set_fact: + notification_proxy_sqlite_dbfile: /var/lib/notification-proxy/db.sqlite3 + - name: Create notification proxy worker user and group user: name: uwsgi-notification-proxy @@ -14,7 +18,7 @@ state: directory owner: uwsgi-notification-proxy group: uwsgi - mode: 0550 + mode: 0750 - name: Copy webapp sources copy: @@ -46,3 +50,12 @@ name: uwsgi-app@notification-proxy.socket enabled: yes +- name: Create sqlite db file + file: + path: "{{notification_proxy_sqlite_dbfile}}" + owner: uwsgi-notification-proxy + group: uwsgi + mode: 0660 + state: touch + + -- cgit From d11c4bd67534e61a0479c9179a4ea98b83be58ea Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 23 Jan 2020 11:48:45 +0100 Subject: notify: add some more monitoring --- gerboweb/deploy/notification_proxy.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gerboweb') diff --git a/gerboweb/deploy/notification_proxy.py b/gerboweb/deploy/notification_proxy.py index d30a23d..fcef50f 100644 --- a/gerboweb/deploy/notification_proxy.py +++ b/gerboweb/deploy/notification_proxy.py @@ -150,6 +150,9 @@ def notify(route_name): with db as conn: conn.execute('INSERT OR REPLACE INTO heartbeats_seen VALUES (?, ?, 0)', (route_name, int(time.time()))) + elif scope == 'error': + print(f'Device error: {kwargs}') + return 'success' @uwsgidecorators.timer(60) -- cgit From 0614974bedf0f44845e7a4062881284bd6fe6c0f Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 23 Jan 2020 11:49:01 +0100 Subject: pogojig: some updates? --- gerboweb/deploy/checkouts/pogojig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/checkouts/pogojig b/gerboweb/deploy/checkouts/pogojig index 75dd7db..13a5721 160000 --- a/gerboweb/deploy/checkouts/pogojig +++ b/gerboweb/deploy/checkouts/pogojig @@ -1 +1 @@ -Subproject commit 75dd7db73fe87d57f5965d0c689257a56296201c +Subproject commit 13a57211f0d0feb34b452b3e19be83a095707ed6 -- cgit From 0e9d0e8efab79f527507f8c161daaad44cfd1b56 Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 26 Jan 2020 22:38:02 +0100 Subject: deploy/klingel: Add classification support --- gerboweb/deploy/notification_proxy.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/notification_proxy.py b/gerboweb/deploy/notification_proxy.py index fcef50f..117f8e1 100644 --- a/gerboweb/deploy/notification_proxy.py +++ b/gerboweb/deploy/notification_proxy.py @@ -34,10 +34,10 @@ with db as conn: mail_routes = {} -def mail_route(name, receiver, subject, secret): +def mail_route(name, receiver, secret): def wrap(func): global routes - mail_routes[name] = (receiver, subject, func, secret) + mail_routes[name] = (receiver, func, secret) return func return wrap @@ -109,9 +109,10 @@ def authenticate(route_name, secret, clock_delta_tolerance:'s'=120): return msg_time, payload['scope'], payload['d'] -@mail_route('klingel', 'computerstuff@jaseg.de', 'It rang!', app.config['SECRET_KLINGEL']) -def klingel(rms=None, capture=None, **kwargs): - return f'rms={rms}\ncapture={capture}\nextra_args={kwargs}' +@mail_route('klingel', 'computerstuff@jaseg.de', app.config['SECRET_KLINGEL']) +def klingel(classification='somewhere', rms=None, capture=None, **kwargs): + return (f'It rang {classification}!', + f'rms={rms}\ncapture={capture}\nextra_args={kwargs}') def send_mail(route_name, receiver, subject, body): @@ -134,13 +135,16 @@ def send_mail(route_name, receiver, subject, body): @app.route('/v1/notify/', methods=['POST']) def notify(route_name): - receiver, notify_subject, func, secret = mail_routes[route_name] + receiver, func, secret = mail_routes[route_name] msg_time, scope, kwargs = authenticate(route_name, secret) if scope == 'default': # Exceptions will yield a 500 error - body = func(**kwargs) - send_mail(route_name, receiver, notify_subject, body or 'empty message') + subject, body = func(**kwargs) + send_mail(route_name, receiver, subject, body or 'empty message') + + elif scope == 'info': + send_mail(route_name, receiver, f'System info: {kwargs["info_msg"]}', f'Logged data: {kwargs}') elif scope == 'boot': formatted = datetime.utcfromtimestamp(msg_time).isoformat() -- cgit From 0dcc11ebd03a6b80e9d930ab9edf5fe74291f95b Mon Sep 17 00:00:00 2001 From: jaseg Date: Mon, 30 Mar 2020 00:55:33 +0200 Subject: Add gitolite/cgit git hosting --- gerboweb/deploy/bootstrap_arch_container.yml | 4 +- gerboweb/deploy/cgit-logo.png | Bin 0 -> 104376 bytes gerboweb/deploy/cgitrc | 20 +++ gerboweb/deploy/gitolite.rc | 202 +++++++++++++++++++++++++++ gerboweb/deploy/nginx.conf | 48 +++++++ gerboweb/deploy/playbook.yml | 3 + gerboweb/deploy/setup_gerboweb.yml | 2 +- gerboweb/deploy/setup_git.yml | 115 +++++++++++++++ gerboweb/deploy/setup_webserver.yml | 2 + gerboweb/deploy/uwsgi-app@.service | 2 +- gerboweb/deploy/uwsgi-cgit.ini | 8 ++ 11 files changed, 402 insertions(+), 4 deletions(-) create mode 100644 gerboweb/deploy/cgit-logo.png create mode 100644 gerboweb/deploy/cgitrc create mode 100644 gerboweb/deploy/gitolite.rc create mode 100644 gerboweb/deploy/setup_git.yml create mode 100644 gerboweb/deploy/uwsgi-cgit.ini (limited to 'gerboweb') diff --git a/gerboweb/deploy/bootstrap_arch_container.yml b/gerboweb/deploy/bootstrap_arch_container.yml index 11bbf3d..e983f5c 100644 --- a/gerboweb/deploy/bootstrap_arch_container.yml +++ b/gerboweb/deploy/bootstrap_arch_container.yml @@ -13,9 +13,9 @@ - name: Download arch bootstrap image get_url: - url: http://mirror.rackspace.com/archlinux/iso/2019.09.01/archlinux-bootstrap-2019.09.01-x86_64.tar.gz + url: http://mirror.rackspace.com/archlinux/iso/2020.03.01/archlinux-bootstrap-2020.03.01-x86_64.tar.gz dest: /tmp/arch-bootstrap.tar.xz - checksum: sha256:9fc9f178db6f5c188be8884c0abf10c69418e7cd38a4389e866fac5d9961297d + checksum: sha256:49c7aa8718e48f5a4ec570624520fa50616ed3e044af101ec3aa16c155136f82 when: create_container is changed - name: Create container image filesystem diff --git a/gerboweb/deploy/cgit-logo.png b/gerboweb/deploy/cgit-logo.png new file mode 100644 index 0000000..f781fdd Binary files /dev/null and b/gerboweb/deploy/cgit-logo.png differ diff --git a/gerboweb/deploy/cgitrc b/gerboweb/deploy/cgitrc new file mode 100644 index 0000000..d77778b --- /dev/null +++ b/gerboweb/deploy/cgitrc @@ -0,0 +1,20 @@ +css=/cgit.css +logo= /cgit.png + +enable-http-clone=1 +robots=noindex, nofollow +virtual-root=/ + +readme=:README.rst +about-filter=/usr/libexec/cgit/filters/about-formatting.sh + +enable-index-links=1 +enable-commit-grpah=1 +enable-log-filecount=1 +enable-log-linecount=1 +enable-git-config=1 + +source-filter=/usr/libexec/cgit/filters/syntax-highlighting.py + +project-list=/var/lib/gitolite3/projects.list +scan-path=/var/lib/gitolite3/repositories diff --git a/gerboweb/deploy/gitolite.rc b/gerboweb/deploy/gitolite.rc new file mode 100644 index 0000000..33ecfb2 --- /dev/null +++ b/gerboweb/deploy/gitolite.rc @@ -0,0 +1,202 @@ +# configuration variables for gitolite + +# This file is in perl syntax. But you do NOT need to know perl to edit it -- +# just mind the commas, use single quotes unless you know what you're doing, +# and make sure the brackets and braces stay matched up! + +# (Tip: perl allows a comma after the last item in a list also!) + +# HELP for commands can be had by running the command with "-h". + +# HELP for all the other FEATURES can be found in the documentation (look for +# "list of non-core programs shipped with gitolite" in the master index) or +# directly in the corresponding source file. + +%RC = ( + + # ------------------------------------------------------------------ + + # default umask gives you perms of '0700'; see the rc file docs for + # how/why you might change this + UMASK => 0027, + + # look for "git-config" in the documentation + GIT_CONFIG_KEYS => 'core\.sharedRepository', + + # comment out if you don't need all the extra detail in the logfile + LOG_EXTRA => 1, + # logging options + # 1. leave this section as is for 'normal' gitolite logging (default) + # 2. uncomment this line to log ONLY to syslog: + # LOG_DEST => 'syslog', + # 3. uncomment this line to log to syslog and the normal gitolite log: + # LOG_DEST => 'syslog,normal', + # 4. prefixing "repo-log," to any of the above will **also** log just the + # update records to "gl-log" in the bare repo directory: + # LOG_DEST => 'repo-log,normal', + # LOG_DEST => 'repo-log,syslog', + # LOG_DEST => 'repo-log,syslog,normal', + # syslog 'facility': defaults to 'local0', uncomment if needed. For example: + # LOG_FACILITY => 'local4', + + # roles. add more roles (like MANAGER, TESTER, ...) here. + # WARNING: if you make changes to this hash, you MUST run 'gitolite + # compile' afterward, and possibly also 'gitolite trigger POST_COMPILE' + ROLES => { + READERS => 1, + WRITERS => 1, + }, + + # enable caching (currently only Redis). PLEASE RTFM BEFORE USING!!! + # CACHE => 'Redis', + + # ------------------------------------------------------------------ + + # rc variables used by various features + + # the 'info' command prints this as additional info, if it is set + # SITE_INFO => 'Please see http://blahblah/gitolite for more help', + + # the CpuTime feature uses these + # display user, system, and elapsed times to user after each git operation + # DISPLAY_CPU_TIME => 1, + # display a warning if total CPU times (u, s, cu, cs) crosses this limit + # CPU_TIME_WARN_LIMIT => 0.1, + + # the Mirroring feature needs this + # HOSTNAME => "foo", + + # TTL for redis cache; PLEASE SEE DOCUMENTATION BEFORE UNCOMMENTING! + # CACHE_TTL => 600, + + # ------------------------------------------------------------------ + + # suggested locations for site-local gitolite code (see cust.html) + + # this one is managed directly on the server + # LOCAL_CODE => "$ENV{HOME}/local", + + # or you can use this, which lets you put everything in a subdirectory + # called "local" in your gitolite-admin repo. For a SECURITY WARNING + # on this, see http://gitolite.com/gitolite/non-core.html#pushcode + # LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local", + + # ------------------------------------------------------------------ + + # List of commands and features to enable + + ENABLE => [ + + # COMMANDS + + # These are the commands enabled by default + 'help', + 'desc', + 'info', + 'perms', + 'writable', + + # Uncomment or add new commands here. + # 'create', + # 'fork', + # 'mirror', + # 'readme', + # 'sskm', + # 'D', + + # These FEATURES are enabled by default. + + # essential (unless you're using smart-http mode) + 'ssh-authkeys', + + # creates git-config entries from gitolite.conf file entries like 'config foo.bar = baz' + 'git-config', + + # creates git-daemon-export-ok files; if you don't use git-daemon, comment this out + 'daemon', + + # creates projects.list file; if you don't use gitweb, comment this out + 'gitweb', + + # These FEATURES are disabled by default; uncomment to enable. If you + # need to add new ones, ask on the mailing list :-) + + # user-visible behaviour + + # prevent wild repos auto-create on fetch/clone + # 'no-create-on-read', + # no auto-create at all (don't forget to enable the 'create' command!) + # 'no-auto-create', + + # access a repo by another (possibly legacy) name + # 'Alias', + + # give some users direct shell access. See documentation in + # sts.html for details on the following two choices. + # "Shell $ENV{HOME}/.gitolite.shell-users", + # 'Shell alice bob', + + # set default roles from lines like 'option default.roles-1 = ...', etc. + # 'set-default-roles', + + # show more detailed messages on deny + # 'expand-deny-messages', + + # show a message of the day + # 'Motd', + + # system admin stuff + + # enable mirroring (don't forget to set the HOSTNAME too!) + # 'Mirroring', + + # allow people to submit pub files with more than one key in them + # 'ssh-authkeys-split', + + # selective read control hack + # 'partial-copy', + + # manage local, gitolite-controlled, copies of read-only upstream repos + # 'upstream', + + # updates 'description' file instead of 'gitweb.description' config item + # 'cgit', + + # allow repo-specific hooks to be added + # 'repo-specific-hooks', + + # performance, logging, monitoring... + + # be nice + # 'renice 10', + + # log CPU times (user, system, cumulative user, cumulative system) + # 'CpuTime', + + # syntactic_sugar for gitolite.conf and included files + + # allow backslash-escaped continuation lines in gitolite.conf + # 'continuation-lines', + + # create implicit user groups from directory names in keydir/ + # 'keysubdirs-as-groups', + + # allow simple line-oriented macros + # 'macros', + + # Kindergarten mode + + # disallow various things that sensible people shouldn't be doing anyway + # 'Kindergarten', + ], + +); + +# ------------------------------------------------------------------------------ +# per perl rules, this should be the last line in such a file: +1; + +# Local variables: +# mode: perl +# End: +# vim: set syn=perl: diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index f3400cc..b4245fa 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -322,5 +322,53 @@ http { root /usr/share/nginx/html; } } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name git.jaseg.net; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/git.jaseg.net/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/git.jaseg.net/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location ~ ^/(cgit.css|robots.txt) { + root /usr/share/cgit; + expires 30d; + } + + location ~ ^/(cgit.png|favicon.png) { + alias /var/www/git.jaseg.net/cgit.png; + } + + location / { + include uwsgi_params; + uwsgi_modifier1 9; + uwsgi_pass unix:/run/uwsgi/cgit.socket; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } } diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 7c7c95d..777d079 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -74,3 +74,6 @@ - name: Setup notification proxy include_tasks: setup_notification_proxy.yml + - name: Setup semi-public git server + include_tasks: setup_git.yml + diff --git a/gerboweb/deploy/setup_gerboweb.yml b/gerboweb/deploy/setup_gerboweb.yml index 29e83d3..6a20eed 100644 --- a/gerboweb/deploy/setup_gerboweb.yml +++ b/gerboweb/deploy/setup_gerboweb.yml @@ -58,7 +58,7 @@ dest: /etc/uwsgi.d/gerboweb.ini owner: uwsgi-gerboweb group: uwsgi - mode: 440 + mode: 0440 - name: Copy job processor systemd service config template: diff --git a/gerboweb/deploy/setup_git.yml b/gerboweb/deploy/setup_git.yml new file mode 100644 index 0000000..9d351e5 --- /dev/null +++ b/gerboweb/deploy/setup_git.yml @@ -0,0 +1,115 @@ +- name: Install host requisites + dnf: + name: cgit,gitolite3,python3-pygments,python3-docutils,nodejs-markdown + state: latest + +- name: Copy cgit favicon + copy: + src: cgit-logo.png + dest: /var/www/git.jaseg.net/cgit.png + +- name: Create cgit instance config dir + file: + path: /var/lib/cgit + state: directory + mode: 0755 + +- name: Copy cgit rc + copy: + src: cgitrc + dest: /var/lib/cgit/cgitrc-gitolite-public + mode: 0644 + +- name: Create uwsgi worker user and group + user: + name: uwsgi-cgit + create_home: no + group: uwsgi + password: '!' + shell: /sbin/nologin + system: yes + +- name: Copy uwsgi config + copy: + src: uwsgi-cgit.ini + dest: /etc/uwsgi.d/cgit.ini + owner: uwsgi-cgit + group: uwsgi + mode: 0440 + +- name: Enable uwsgi systemd socket + systemd: + daemon-reload: yes + name: uwsgi-app@cgit.socket + enabled: yes + +- name: Copy gitolite admin pubkey + copy: + src: ~/.ssh/id_ed25519.gitolite.pub + dest: /tmp/jaseg-gitolite.pub + owner: gitolite3 + group: gitolite3 + +- name: Run gitolite initialization + command: gitolite setup -pk /tmp/jaseg-gitolite.pub + become: true + become_method: su + become_user: gitolite3 + become_flags: '-s /bin/sh' + args: + creates: /var/lib/gitolite3/projects.list + +- name: Remove leftover admin pubkey + file: + state: absent + path: /tmp/jaseg-gitolite.pub + +- name: Allow uwsgi group to access gitolite repo dir + file: + path: /var/lib/gitolite3 + state: directory + owner: gitolite3 + group: uwsgi + +- name: Add cgit uwsgi user to gitolite group + user: + name: uwsgi-cgit + groups: gitolite3 + append: yes + +- name: Allow cgit uwsgi user to access gitolite repos + file: + path: /var/lib/gitolite3/repositories + mode: 0750 + +- name: Allow cgit uwsgi user to gitolite repo list + file: + path: /var/lib/gitolite3/projects.list + mode: 0640 + +- name: Copy gitolite rc + copy: + src: gitolite.rc + dest: /var/lib/gitolite3/.gitolite.rc + owner: gitolite3 + group: gitolite3 + mode: 0600 + +- name: Query system user account info + getent: + database: passwd + key: gitolite3 + +- name: Create git alias user + user: + name: git + create_home: no + group: gitolite3 + password: '!' + comment: Alias for gitolite3 user + shell: "{{ getent_passwd['gitolite3'][5] }}" + system: yes + non_unique: yes + home: "{{ getent_passwd['gitolite3'][4] }}" + uid: "{{ getent_passwd['gitolite3'][1] }}" + diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml index 8f1f429..748bef8 100644 --- a/gerboweb/deploy/setup_webserver.yml +++ b/gerboweb/deploy/setup_webserver.yml @@ -17,6 +17,7 @@ group: nginx mode: 0550 loop: + - git.jaseg.net - blog.jaseg.net - kochbuch.jaseg.net - tracespace.jaseg.net @@ -49,6 +50,7 @@ args: creates: /etc/letsencrypt/live/{{item}}/fullchain.pem loop: + - git.jaseg.net - blog.jaseg.net - kochbuch.jaseg.net - gerbolyze.jaseg.net diff --git a/gerboweb/deploy/uwsgi-app@.service b/gerboweb/deploy/uwsgi-app@.service index 8398456..bdae8fd 100644 --- a/gerboweb/deploy/uwsgi-app@.service +++ b/gerboweb/deploy/uwsgi-app@.service @@ -5,7 +5,7 @@ After=syslog.target [Service] ExecStart=/usr/sbin/uwsgi \ --ini /etc/uwsgi.d/%i.ini \ - --chmod-socket=660 \ + --chmod-socket=660 \ --socket=/run/uwsgi/%i.socket User=uwsgi-%i Group=uwsgi diff --git a/gerboweb/deploy/uwsgi-cgit.ini b/gerboweb/deploy/uwsgi-cgit.ini new file mode 100644 index 0000000..9a10350 --- /dev/null +++ b/gerboweb/deploy/uwsgi-cgit.ini @@ -0,0 +1,8 @@ +[uwsgi] +master = True +plugins = cgi +chdir = /var/lib/gitolite3 +processes = 1 +threads = 2 +cgi = /var/www/cgi-bin/cgit +env = CGIT_CONFIG=/var/lib/cgit/cgitrc-gitolite-public -- cgit From 24f1e420ff74ad503cb20e28901834882c266b94 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 5 Jun 2020 16:28:39 +0200 Subject: deploy: Add dyndns service --- gerboweb/deploy/.gitignore | 1 + gerboweb/deploy/credentials.ini.example | 3 +++ gerboweb/deploy/inventory.yml | 3 +++ gerboweb/deploy/iptables.rules | 1 + gerboweb/deploy/library/inwx-collection | 1 + gerboweb/deploy/nginx.conf | 38 +++++++++++++++++++++++++++++++++ gerboweb/deploy/playbook.yml | 36 +++++++++++++++++++++++++++++-- gerboweb/deploy/setup_webserver.yml | 1 + 8 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 gerboweb/deploy/credentials.ini.example create mode 160000 gerboweb/deploy/library/inwx-collection (limited to 'gerboweb') diff --git a/gerboweb/deploy/.gitignore b/gerboweb/deploy/.gitignore index e681fba..136f960 100644 --- a/gerboweb/deploy/.gitignore +++ b/gerboweb/deploy/.gitignore @@ -1,3 +1,4 @@ *_secret.txt *_apikey.txt playbook.retry +credentials.ini diff --git a/gerboweb/deploy/credentials.ini.example b/gerboweb/deploy/credentials.ini.example new file mode 100644 index 0000000..9b87321 --- /dev/null +++ b/gerboweb/deploy/credentials.ini.example @@ -0,0 +1,3 @@ +[inwx] +user=... +pass=... diff --git a/gerboweb/deploy/inventory.yml b/gerboweb/deploy/inventory.yml index ea577e3..913ea5f 100644 --- a/gerboweb/deploy/inventory.yml +++ b/gerboweb/deploy/inventory.yml @@ -6,3 +6,6 @@ all: ansible_ssh_identity_file: ~/.ssh/id_ed25519 ansible_user: root ansible_python_interpreter: /usr/bin/python3 + localhost: + ansible_connection: local + ansible_python_interpreter: "{{ansible_playbook_python}}" diff --git a/gerboweb/deploy/iptables.rules b/gerboweb/deploy/iptables.rules index db68eb5..620c4d3 100644 --- a/gerboweb/deploy/iptables.rules +++ b/gerboweb/deploy/iptables.rules @@ -20,6 +20,7 @@ COMMIT -A INPUT -p tcp -m state --state NEW -m tcp --dport 23 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT +-A INPUT -p udp --dport 53 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT diff --git a/gerboweb/deploy/library/inwx-collection b/gerboweb/deploy/library/inwx-collection new file mode 160000 index 0000000..0ac040d --- /dev/null +++ b/gerboweb/deploy/library/inwx-collection @@ -0,0 +1 @@ +Subproject commit 0ac040da14cc9d834098addc03cd8d4d26647df0 diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index b4245fa..744bd01 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -370,5 +370,43 @@ http { root /usr/share/nginx/html; } } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name dyndns.jaseg.de; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/dyndns.jaseg.de/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/dyndns.jaseg.de/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + location / { + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/dyndns.socket; + } + + error_page 404 /404.html; + location = /40x.html { + root /usr/share/nginx/html; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } } diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 777d079..6b1f46f 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -1,4 +1,34 @@ -- name: Gerbolyze container setup playbook +- name: DNS setup + hosts: localhost + module_defaults: + inwx: + username: "{{lookup('ini', 'user section=inwx file=credentials.ini')}}" + password: "{{lookup('ini', 'pass section=inwx file=credentials.ini')}}" + vars: + subdomains: + - git.jaseg.net + - blog.jaseg.net + - kochbuch.jaseg.net + - gerbolyze.jaseg.net + - tracespace.jaseg.net + - openjscad.jaseg.net + - pogojig.jaseg.net + - automation.jaseg.de + - dyndns.jaseg.de + fastmail_domains: + - jaseg.net + - jaseg.de + tasks: + - name: Gather wendelstein facts + setup: + delegate_to: wendelstein + delegate_facts: True + + - name: Setup DNS + include_tasks: dns.yml + + +- name: Wendelstein setup hosts: wendelstein tasks: - name: Set hostname @@ -12,7 +42,7 @@ - name: Install host requisites dnf: - name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services,python3-pycryptodomex,zip,python3-uwsgidecorators + name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services,python3-pycryptodomex,zip,python3-uwsgidecorators,nsd state: latest - name: Disable password-based root login @@ -77,3 +107,5 @@ - name: Setup semi-public git server include_tasks: setup_git.yml + - name: Setup private DynDNS service + include_tasks: setup_dyndns.yml diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml index 748bef8..eb34a5b 100644 --- a/gerboweb/deploy/setup_webserver.yml +++ b/gerboweb/deploy/setup_webserver.yml @@ -58,6 +58,7 @@ - openjscad.jaseg.net - pogojig.jaseg.net - automation.jaseg.de + - dyndns.jaseg.de - name: Copy final nginx config copy: -- cgit From 73a2d0b0fbcb20c6c0c79aa5491db0bf5329f713 Mon Sep 17 00:00:00 2001 From: jaseg Date: Fri, 5 Jun 2020 16:28:52 +0200 Subject: deploy: Enable gitolite 'D' repo deletion command --- gerboweb/deploy/gitolite.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/gitolite.rc b/gerboweb/deploy/gitolite.rc index 33ecfb2..2c8435a 100644 --- a/gerboweb/deploy/gitolite.rc +++ b/gerboweb/deploy/gitolite.rc @@ -102,7 +102,7 @@ # 'mirror', # 'readme', # 'sskm', - # 'D', + 'D', # These FEATURES are enabled by default. -- cgit From 6635bc6d464cd09d81fbaa3ded345a08dc840447 Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 29 Dec 2020 13:06:44 +0100 Subject: Update arch container keyrings before sysupdate --- gerboweb/deploy/bootstrap_arch_container.yml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gerboweb') diff --git a/gerboweb/deploy/bootstrap_arch_container.yml b/gerboweb/deploy/bootstrap_arch_container.yml index e983f5c..dfe677b 100644 --- a/gerboweb/deploy/bootstrap_arch_container.yml +++ b/gerboweb/deploy/bootstrap_arch_container.yml @@ -55,6 +55,9 @@ regexp: '^CheckSpace' line: '#CheckSpace' +- name: Update container keyring + shell: arch-chroot "{{root}}" pacman -Sy --noconfirm archlinux-keyring + - name: Update container and install software shell: arch-chroot "{{root}}" pacman -Syu --noconfirm -- cgit From 9510936fd9c9bb6c354b66da8f85e1ca728c2a60 Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 29 Dec 2020 13:06:57 +0100 Subject: gitolite.rc: Enable cgit metadata config keys --- gerboweb/deploy/gitolite.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/gitolite.rc b/gerboweb/deploy/gitolite.rc index 2c8435a..ad1d2bb 100644 --- a/gerboweb/deploy/gitolite.rc +++ b/gerboweb/deploy/gitolite.rc @@ -21,7 +21,7 @@ UMASK => 0027, # look for "git-config" in the documentation - GIT_CONFIG_KEYS => 'core\.sharedRepository', + GIT_CONFIG_KEYS => 'core\.sharedRepository gitweb.owner gitweb.description gitweb.category', # comment out if you don't need all the extra detail in the logfile LOG_EXTRA => 1, -- cgit From 659290677b4ab53bca1fd92fd01c90aee09c2fa7 Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 29 Dec 2020 13:07:30 +0100 Subject: Move most domains from jaseg.net to jaseg.de --- gerboweb/deploy/library/inwx-collection | 2 +- gerboweb/deploy/nginx.conf | 50 ++++++++++++++++++++++++++++++--- gerboweb/deploy/nginx_nossl.conf | 7 +++++ gerboweb/deploy/playbook.yml | 5 +++- gerboweb/deploy/setup_containers.yml | 2 +- gerboweb/deploy/setup_git.yml | 2 +- gerboweb/deploy/setup_webserver.yml | 8 ++++-- 7 files changed, 65 insertions(+), 11 deletions(-) (limited to 'gerboweb') diff --git a/gerboweb/deploy/library/inwx-collection b/gerboweb/deploy/library/inwx-collection index 0ac040d..2928298 160000 --- a/gerboweb/deploy/library/inwx-collection +++ b/gerboweb/deploy/library/inwx-collection @@ -1 +1 @@ -Subproject commit 0ac040da14cc9d834098addc03cd8d4d26647df0 +Subproject commit 2928298f35d66d265679e8188029ce5834b28983 diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index 744bd01..d46c394 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -88,7 +88,6 @@ http { listen 443 ssl http2; listen [::]:443 ssl http2; server_name blog.jaseg.net; - root /usr/share/nginx/html; ssl_certificate "/etc/letsencrypt/live/blog.jaseg.net/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/blog.jaseg.net/privkey.pem"; @@ -103,11 +102,33 @@ http { add_header Strict-Transport-Security "max-age=86400"; + return 301 https://blog.jaseg.de$request_uri; + } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name blog.jaseg.de; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/blog.jaseg.de/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/blog.jaseg.de/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { - root /var/www/blog.jaseg.net; + root /var/www/blog.jaseg.de; } location /d/ { @@ -327,7 +348,6 @@ http { listen 443 ssl http2; listen [::]:443 ssl http2; server_name git.jaseg.net; - root /usr/share/nginx/html; ssl_certificate "/etc/letsencrypt/live/git.jaseg.net/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/git.jaseg.net/privkey.pem"; @@ -342,6 +362,28 @@ http { add_header Strict-Transport-Security "max-age=86400"; + return 301 https://git.jaseg.de$request_uri; + } + + server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name git.jaseg.de; + root /usr/share/nginx/html; + + ssl_certificate "/etc/letsencrypt/live/git.jaseg.de/fullchain.pem"; + ssl_certificate_key "/etc/letsencrypt/live/git.jaseg.de/privkey.pem"; + ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; + include /etc/letsencrypt/options-ssl-nginx.conf; + + ssl_stapling on; + ssl_stapling_verify on; + + resolver 67.207.67.2 67.207.67.3 valid=300s; + resolver_timeout 10s; + + add_header Strict-Transport-Security "max-age=86400"; + # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; @@ -351,7 +393,7 @@ http { } location ~ ^/(cgit.png|favicon.png) { - alias /var/www/git.jaseg.net/cgit.png; + alias /var/www/git.jaseg.de/cgit.png; } location / { diff --git a/gerboweb/deploy/nginx_nossl.conf b/gerboweb/deploy/nginx_nossl.conf index 8d5a5a5..87de478 100644 --- a/gerboweb/deploy/nginx_nossl.conf +++ b/gerboweb/deploy/nginx_nossl.conf @@ -48,5 +48,12 @@ http { server_name blog.jaseg.net; return 301 https://$host$request_uri; } + + server { + listen 80; + listen [::]:80; + server_name blog.jaseg.de; + return 301 https://$host$request_uri; + } } diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 6b1f46f..72beb91 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -1,5 +1,6 @@ - name: DNS setup hosts: localhost + tags: dns module_defaults: inwx: username: "{{lookup('ini', 'user section=inwx file=credentials.ini')}}" @@ -7,7 +8,9 @@ vars: subdomains: - git.jaseg.net + - git.jaseg.de - blog.jaseg.net + - blog.jaseg.de - kochbuch.jaseg.net - gerbolyze.jaseg.net - tracespace.jaseg.net @@ -42,7 +45,7 @@ - name: Install host requisites dnf: - name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,libselinux-python,git,iptables-services,python3-pycryptodomex,zip,python3-uwsgidecorators,nsd + name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,python3-libselinux,git,iptables-services,python3-pycryptodomex,zip,python3-uwsgidecorators,nsd state: latest - name: Disable password-based root login diff --git a/gerboweb/deploy/setup_containers.yml b/gerboweb/deploy/setup_containers.yml index 4738f1e..8adb9da 100644 --- a/gerboweb/deploy/setup_containers.yml +++ b/gerboweb/deploy/setup_containers.yml @@ -1,7 +1,7 @@ --- - name: Install host requisites dnf: - name: btrfs-progs,arch-install-scripts,systemd-container,libselinux-python + name: btrfs-progs,arch-install-scripts,systemd-container,python3-libselinux state: latest - name: Create individual containers diff --git a/gerboweb/deploy/setup_git.yml b/gerboweb/deploy/setup_git.yml index 9d351e5..6e7d621 100644 --- a/gerboweb/deploy/setup_git.yml +++ b/gerboweb/deploy/setup_git.yml @@ -6,7 +6,7 @@ - name: Copy cgit favicon copy: src: cgit-logo.png - dest: /var/www/git.jaseg.net/cgit.png + dest: /var/www/git.jaseg.de/cgit.png - name: Create cgit instance config dir file: diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml index eb34a5b..4711ad0 100644 --- a/gerboweb/deploy/setup_webserver.yml +++ b/gerboweb/deploy/setup_webserver.yml @@ -17,8 +17,8 @@ group: nginx mode: 0550 loop: - - git.jaseg.net - - blog.jaseg.net + - git.jaseg.de + - blog.jaseg.de - kochbuch.jaseg.net - tracespace.jaseg.net - openjscad.jaseg.net @@ -46,12 +46,14 @@ state: restarted - name: Create subdomain letsencrypt certificates - command: certbot --nginx certonly -d {{item}} -n --agree-tos --email {{item}}-letsencrypt@jaseg.net + command: certbot --nginx certonly -d {{item}} -n --agree-tos --email {{item}}-letsencrypt@jaseg.de args: creates: /etc/letsencrypt/live/{{item}}/fullchain.pem loop: - git.jaseg.net + - git.jaseg.de - blog.jaseg.net + - blog.jaseg.de - kochbuch.jaseg.net - gerbolyze.jaseg.net - tracespace.jaseg.net -- cgit From e63a7e557da86afc69f987df416b9932d0822d31 Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 29 Dec 2020 13:08:13 +0100 Subject: Add dns, dyndns services --- gerboweb/deploy/dns.yml | 91 +++++++++ gerboweb/deploy/dyndns.py | 149 +++++++++++++++ gerboweb/deploy/dyndns_config.py.j2 | 14 ++ gerboweb/deploy/nsd.conf | 372 ++++++++++++++++++++++++++++++++++++ gerboweb/deploy/setup_dyndns.yml | 80 ++++++++ gerboweb/deploy/uwsgi-dyndns.ini | 10 + 6 files changed, 716 insertions(+) create mode 100644 gerboweb/deploy/dns.yml create mode 100644 gerboweb/deploy/dyndns.py create mode 100644 gerboweb/deploy/dyndns_config.py.j2 create mode 100644 gerboweb/deploy/nsd.conf create mode 100644 gerboweb/deploy/setup_dyndns.yml create mode 100644 gerboweb/deploy/uwsgi-dyndns.ini (limited to 'gerboweb') diff --git a/gerboweb/deploy/dns.yml b/gerboweb/deploy/dns.yml new file mode 100644 index 0000000..0fd753a --- /dev/null +++ b/gerboweb/deploy/dns.yml @@ -0,0 +1,91 @@ +- name: Setup subdomain A records pointing to wendelstein + inwx: + domain: "{{item.partition('.')[2]}}" + record: "{{item.partition('.')[0]}}" + type: A + value: "{{ hostvars['wendelstein']['ansible_default_ipv4']['address'] }}" + loop: "{{subdomains}}" + +- name: Setup dyndns A record + inwx: + domain: jaseg.de + record: ns + type: A + value: "{{ hostvars['wendelstein']['ansible_default_ipv4']['address'] }}" + +- name: Setup dyndns NS record + inwx: + domain: jaseg.de + record: dyn + type: NS + value: 'ns.jaseg.de' + +- name: Setup subdomain AAAA records pointing to wendelstein + inwx: + domain: "{{item.partition('.')[2]}}" + record: "{{item.partition('.')[0]}}" + type: AAAA + value: "{{ hostvars['wendelstein']['ansible_default_ipv6']['address'] }}" + loop: "{{subdomains}}" + +- name: Setup jaseg.net subdomain MX records pointing to fastmail + inwx: + domain: "{{item.partition('.')[2]}}" + record: "{{item.partition('.')[0]}}" + type: MX + priority: 10 + value: in1-smtp.messagingengine.com + loop: "{{subdomains}}" + +- name: Setup jaseg.net subdomain MX records pointing to fastmail + inwx: + domain: "{{item.partition('.')[2]}}" + record: "{{item.partition('.')[0]}}" + type: MX + priority: 20 + value: in2-smtp.messagingengine.com + loop: "{{subdomains}}" + +- name: Setup sendgrid gateway + inwx: + domain: jaseg.de + type: CNAME + record: "{{item.split(' ')[0]}}" + value: "{{item.split(' ')[1]}}" + loop: + - em6100.automation u14518136.wl137.sendgrid.net + - s1._domainkey.automation s1.domainkey.u14518136.wl137.sendgrid.net + - s2._domainkey.automation s2.domainkey.u14518136.wl137.sendgrid.net + +- name: Set fastmail DNS entry template + set_fact: + fastmail_dns_entries: + - {rtype: MX, record: ".", prio: 10, value: in1-smtp.messagingengine.com} + - {rtype: MX, record: ".", prio: 20, value: in2-smtp.messagingengine.com} + - {rtype: MX, record: "*", prio: 10, value: in1-smtp.messagingengine.com} + - {rtype: MX, record: "*", prio: 20, value: in2-smtp.messagingengine.com} + - {rtype: TXT, record: ".", value: "v=spf1 include:spf.messagingengine.com ?all"} + - {rtype: CNAME, record: mesmtp._domainkey, value: mesmtp.jaseg.de.dkim.fmhosted.com} + - {rtype: CNAME, record: fm1._domainkey, value: fm1.jaseg.de.dkim.fmhosted.com} + - {rtype: CNAME, record: fm2._domainkey, value: fm2.jaseg.de.dkim.fmhosted.com} + - {rtype: CNAME, record: fm3._domainkey, value: fm3.jaseg.de.dkim.fmhosted.com} + - {rtype: SRV, record: _submission._tcp, prio: 0, weight: 1, port: 587, value: smtp.fastmail.com} + - {rtype: SRV, record: _imap._tcp, prio: 0, weight: 0, port: 0, value: "."} + - {rtype: SRV, record: _imaps._tcp, prio: 0, weight: 1, port: 993, value: imap.fastmail.com} + - {rtype: SRV, record: _pop3._tcp, prio: 0, weight: 0, port: 0, value: "."} + - {rtype: SRV, record: _pop3s._tcp, prio: 10, weight: 1, port: 995, value: pop.fastmail.com} + - {rtype: SRV, record: _jmap._tcp, prio: 0, weight: 1, port: 443, value: jmap.fastmail.com} + - {rtype: SRV, record: _carddav._tcp, prio: 0, weight: 0, port: 0, value: "."} + - {rtype: SRV, record: _carddavs._tcp, prio: 0, weight: 1, port: 443, value: carddav.fastmail.com} + +- name: Setup fastmail DNS entries + inwx: + domain: "{{ item[1] }}" + type: "{{ item[0]['rtype'] }}" + record: "{{ item[0]['record'] | regex_replace('\\.*$', '') }}" + priority: "{{ item[0].get('prio') | int }}" + port: "{{ item[0].get('port') | int}}" + weight: "{{ item[0].get('weight') | int }}" + value: "{{ item[0]['value'] }}" + loop: "{{ fastmail_dns_entries | product(fastmail_domains) | list }}" + diff --git a/gerboweb/deploy/dyndns.py b/gerboweb/deploy/dyndns.py new file mode 100644 index 0000000..2546dce --- /dev/null +++ b/gerboweb/deploy/dyndns.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 + +import time +from contextlib import contextmanager +import re +import os +import os.path +import random +import string +import subprocess +import sqlite3 +import hmac +from ipaddress import IPv4Address, IPv6Address + +from flask import Flask, request, abort +import uwsgidecorators + +app = Flask(__name__) +app.config.update(dict( + RECORD_EXPIRY_S = 86400, + NSD_CONTROL = 'nsd-control' + )) +app.config.from_pyfile('config.py') + + +ZONEFILE_TEMPLATE = '''\ +; #################################################### ; +; THIS FILE IS AUTOMATICALLY GENERATED! DO NOT MODIFY! ; +; #################################################### ; + +$ORIGIN {zone}. +$TTL 1800 +@ IN SOA {ns}. {mail}. ( + {serial} ; serial number + 60 ; refresh + 60 ; retry + {expire} ; expire + 60 ; ttl + ) +; Name servers + IN NS {ns}. + +; Additional A records from template +; @ IN A 192.0.2.3 +; www IN A 192.0.2.3 + +; Dynamically generated records +{dynamic_records} +''' + +db = sqlite3.connect(app.config['SQLITE_DB'], check_same_thread=False) +with db as conn: + conn.execute('''CREATE TABLE IF NOT EXISTS zone_versions (date TEXT)''') + conn.execute('''CREATE TABLE IF NOT EXISTS records + (name TEXT PRIMARY KEY, ipv4 TEXT, ipv6 TEXT, last_update INTEGER)''') + +def purge_expired_records(): + with db as conn: + conn.execute('DELETE FROM records WHERE last_update < ?', + (int(time.time()) - app.config['RECORD_EXPIRY_S'],)) + +def update_record(record, ipv4=None, ipv6=None): + with db as conn: + old_v4, old_v6 = conn.execute('SELECT ipv4, ipv6 FROM records WHERE name=?', (record,)).fetchone() or (None, None) + conn.execute('INSERT OR REPLACE INTO records VALUES (?, ?, ?, ?)', (record, ipv4, ipv6, int(time.time()))) + return ipv4 != old_v4 or ipv6 != old_v6 + +@contextmanager +def inplace_rewrite(filename, cleanup=True): + print('Writing', filename) + filename = os.path.abspath(filename) + if cleanup: + basename = os.path.basename(filename) + for entry in os.scandir(os.path.dirname(filename)): + if entry.name.startswith(basename) and re.match(r'\.tmp-[a-zA-Z0-9]{8}', entry.name[len(basename):]): + os.remove(entry.path) + + tmp_fn = filename + f'.tmp-' + ''.join(random.choices(string.ascii_letters + string.digits, k=8)) + with open(tmp_fn, 'w') as tmp_f: + yield tmp_f + tmp_f.flush() + os.fsync(tmp_f.fileno()) + os.rename(tmp_fn, filename) + +def write_zonefile(): + # Find the next free zonefile version number + with db as conn: + conn.execute('INSERT INTO zone_versions VALUES (DATE())') + date, version_num, = conn.execute('SELECT zone_versions.date, COUNT(*) FROM zone_versions WHERE zone_versions.date = DATE()').fetchone() + zone_version = f'{date.replace("-", "")}{version_num:02d}' + + # Generate dynamic record block + with db as conn: + records = db.execute('SELECT name, "A", ipv4 FROM records UNION SELECT name, "AAAA", ipv6 FROM records') + dynamic_records = '\n'.join(f'{name:<20} IN {rtype:<4} {value}' for name, rtype, value in records if value is not None) + + # Template zone file content + content = ZONEFILE_TEMPLATE.format( + zone = app.config['ZONE'], + ns = app.config['NAMESERVER'], + mail = app.config['NAMESERVER_MAIL'].replace('@', '.'), + serial = zone_version, + dynamic_records = dynamic_records, + expire = app.config['RECORD_EXPIRY_S'] + ) + + with inplace_rewrite(app.config['ZONEFILE'], cleanup=True) as f: + f.write(content) + +def kick_nsd(): + prog = app.config['NSD_CONTROL'] + if isinstance(prog, str): + prog = [prog] + subprocess.run([*prog, 'reload', app.config['ZONE']], check=True) + +@app.before_first_request +@uwsgidecorators.timer(300) +def update_zonefile(): + purge_expired_records() + write_zonefile() + kick_nsd() + +@app.route('/update', methods=['POST']) +def route_update(): + if request.authorization is None: + abort(403) + + record = request.authorization['username'] + record_config = app.config['DYNAMIC_RECORDS'].get(record) + if record_config is None: + abort(403) + + *supported_formats, password = record_config + if not hmac.compare_digest(request.authorization['password'], password): + abort(403) + + ipv4 = request.args.get('ipv4', '127.0.0.1') + ipv6 = request.args.get('ipv6', '::1') + ipv4 = str(IPv4Address(ipv4)) if 'v4' in supported_formats else None + ipv6 = str(IPv6Address(ipv6)) if 'v6' in supported_formats else None + if update_record(record, ipv4=ipv4, ipv6=ipv6): + update_zonefile() + + return 'success' + + +if __name__ == '__main__': + app.run() + diff --git a/gerboweb/deploy/dyndns_config.py.j2 b/gerboweb/deploy/dyndns_config.py.j2 new file mode 100644 index 0000000..3212a1e --- /dev/null +++ b/gerboweb/deploy/dyndns_config.py.j2 @@ -0,0 +1,14 @@ + +SQLITE_DB = '{{dyndns_sqlite_dbfile}}' + +NAMESERVER = 'ns.jaseg.de' +NAMESERVER_MAIL = 'dns@jaseg.de' +ZONEFILE = 'dyn.jaseg.de.zone' +ZONE = 'dyn.jaseg.de' +NSD_CONTROL = 'sudo -u nsd nsd-control'.split() + +DYNAMIC_RECORDS = { + 'bigdata': ('v6', '{{ lookup('password', 'dyndns_secret_bigdata.txt length=32') }}'), + 'raspi': ('v6', '{{ lookup('password', 'dyndns_secret_raspi.txt length=32') }}'), +} + diff --git a/gerboweb/deploy/nsd.conf b/gerboweb/deploy/nsd.conf new file mode 100644 index 0000000..d4b577f --- /dev/null +++ b/gerboweb/deploy/nsd.conf @@ -0,0 +1,372 @@ +# +# nsd.conf -- the NSD(8) configuration file, nsd.conf(5). +# +# Copyright (c) 2001-2011, NLnet Labs. All rights reserved. +# +# See LICENSE for the license. +# + +# This is a comment. +# Sample configuration file +# include: "file" # include that file's text over here. Globbed, "*.conf" + +# options for the nsd server +server: + # Number of NSD servers to fork. Put the number of CPUs to use here. + server-count: 1 + + # uncomment to specify specific interfaces to bind (default are the + # wildcard interfaces 0.0.0.0 and ::0). + # For servers with multiple IP addresses, list them one by one, + # or the source address of replies could be wrong. + # Use ip-transparent to be able to list addresses that turn on later. + # ip-address: 1.2.3.4 + # ip-address: 1.2.3.4@5678 + # ip-address: 12fe::8ef0 + + # Allow binding to non local addresses. Default no. + # ip-transparent: no + + # Allow binding to addresses that are down. Default no. + # ip-freebind: no + + # use the reuseport socket option for performance. Default no. + reuseport: yes + + # override maximum socket send buffer size. Default of 0 results in + # send buffer size being set to 1048576 (bytes). + # send-buffer-size: 1048576 + + # override maximum socket receive buffer size. Default of 0 results in + # receive buffer size being set to 1048576 (bytes). + # receive-buffer-size: 1048576 + + # enable debug mode, does not fork daemon process into the background. + # debug-mode: no + + # listen on IPv4 connections + # do-ip4: yes + + # listen on IPv6 connections + # do-ip6: yes + + # port to answer queries on. default is 53. + # port: 53 + + # Verbosity level. + # verbosity: 0 + + # After binding socket, drop user privileges. + # can be a username, id or id.gid. + # username: nsd + + # Run NSD in a chroot-jail. + # make sure to have pidfile and database reachable from there. + # by default, no chroot-jail is used. + # chroot: "/etc/nsd" + + # The directory for zonefile: files. The daemon chdirs here. + zonesdir: "/etc/nsd" + + # the list of dynamically added zones. + # zonelistfile: "/var/lib/nsd/zone.list" + + # the database to use + # if set to "" then no disk-database is used, less memory usage. + database: "" + + # log messages to file. Default to stderr and syslog (with + # facility LOG_DAEMON). stderr disappears when daemon goes to bg. + # logfile: "/var/log/nsd.log" + + # File to store pid for nsd in. + # pidfile: "/run/nsd/nsd.pid" + + # The file where secondary zone refresh and expire timeouts are kept. + # If you delete this file, all secondary zones are forced to be + # 'refreshing' (as if nsd got a notify). Set to "" to disable. + # xfrdfile: "/var/lib/nsd/ixfr.state" + + # The directory where zone transfers are stored, in a subdir of it. + # xfrdir: "/tmp" + + # don't answer VERSION.BIND and VERSION.SERVER CHAOS class queries + hide-version: yes + + # don't answer HOSTNAME.BIND and ID.SERVER CHAOS class queries + hide-identity: yes + + # version string the server responds with for chaos queries. + # default is 'NSD x.y.z' with the server's version number. + # version: "NSD" + + # identify the server (CH TXT ID.SERVER entry). + # identity: "unidentified server" + + # NSID identity (hex string, or "ascii_somestring"). default disabled. + # nsid: "aabbccdd" + + # Maximum number of concurrent TCP connections per server. + # tcp-count: 100 + + # Accept (and immediately close) TCP connections after maximum number + # of connections is reached to prevent kernel connection queue from + # growing. + # tcp-reject-overflow: no + + # Maximum number of queries served on a single TCP connection. + # By default 0, which means no maximum. + # tcp-query-count: 0 + + # Override the default (120 seconds) TCP timeout. + # tcp-timeout: 120 + + # Maximum segment size (MSS) of TCP socket on which the server + # responds to queries. Default is 0, system default MSS. + # tcp-mss: 0 + + # Maximum segment size (MSS) of TCP socket for outgoing AXFR request. + # Default is 0, system default MSS. + # outgoing-tcp-mss: 0 + + # Preferred EDNS buffer size for IPv4. + # ipv4-edns-size: 4096 + + # Preferred EDNS buffer size for IPv6. + # ipv6-edns-size: 4096 + + # statistics are produced every number of seconds. Prints to log. + # Default is 0, meaning no statistics are produced. + # statistics: 3600 + + # Number of seconds between reloads triggered by xfrd. + # xfrd-reload-timeout: 1 + + # log timestamp in ascii (y-m-d h:m:s.msec), yes is default. + # log-time-ascii: yes + + # round robin rotation of records in the answer. + round-robin: yes + + # minimal-responses only emits extra data for referrals. + minimal-responses: yes + + # Do not return additional information if the apex zone of the + # additional information is configured but does not match the apex zone + # of the initial query. + # confine-to-zone: no + + # refuse queries of type ANY. For stopping floods. + refuse-any: yes + + # check mtime of all zone files on start and sighup + # zonefiles-check: yes + + # write changed zonefiles to disk, every N seconds. + # default is 0(disabled) or 3600(if database is ""). + # zonefiles-write: 3600 + + # RRLconfig + # Response Rate Limiting, size of the hashtable. Default 1000000. + # rrl-size: 1000000 + + # Response Rate Limiting, maximum QPS allowed (from one query source). + # If set to 0, ratelimiting is disabled. Also set + # rrl-whitelist-ratelimit to 0 to disable ratelimit processing. + # Default is on. + # rrl-ratelimit: 200 + + # Response Rate Limiting, number of packets to discard before + # sending a SLIP response (a truncated one, allowing an honest + # resolver to retry with TCP). Default is 2 (one half of the + # queries will receive a SLIP response, 0 disables SLIP (all + # packets are discarded), 1 means every request will get a + # SLIP response. When the ratelimit is hit the traffic is + # divided by the rrl-slip value. + # rrl-slip: 2 + + # Response Rate Limiting, IPv4 prefix length. Addresses are + # grouped by netblock. + # rrl-ipv4-prefix-length: 24 + + # Response Rate Limiting, IPv6 prefix length. Addresses are + # grouped by netblock. + # rrl-ipv6-prefix-length: 64 + + # Response Rate Limiting, maximum QPS allowed (from one query source) + # for whitelisted types. Default is on. + # rrl-whitelist-ratelimit: 2000 + # RRLend + + # Optional local server config + include: "/etc/nsd/server.d/*.conf" + +# Include optional local configs. +include: "/etc/nsd/conf.d/*.conf" + +# Fedora: DNSTAP not yet enabled +# dnstap: + # set this to yes and set one or more of dnstap-log-..-messages to yes. + # dnstap-enable: no + # dnstap-socket-path: "/var/run/dnstap.sock" + # dnstap-send-identity: no + # dnstap-send-version: no + # dnstap-identity: "" + # dnstap-version: "" + # dnstap-log-auth-query-messages: no + # dnstap-log-auth-response-messages: no + + # Service clients over TLS (on the TCP sockets), with plain DNS inside + # the TLS stream. Give the certificate to use and private key. + # Default is "" (disabled). Requires restart to take effect. + # tls-service-key: "path/to/privatekeyfile.key" + # tls-service-pem: "path/to/publiccertfile.pem" + # tls-service-ocsp: "path/to/ocsp.pem" + # tls-port: 853 + +# Remote control config section. +remote-control: + # Enable remote control with nsd-control(8) here. + # set up the keys and certificates with nsd-control-setup. + control-enable: yes + + # what interfaces are listened to for control, default is on localhost. + # with an absolute path, a unix local named pipe is used for control + # (and key and cert files are not needed, use directory permissions). + # control-interface: 127.0.0.1 + # control-interface: ::1 + control-interface: /run/nsd/nsd.ctl + + # port number for remote control operations (uses TLS over TCP). + # control-port: 8952 + + # nsd server key file for remote control. + # server-key-file: "/etc/nsd/nsd_server.key" + + # nsd server certificate file for remote control. + # server-cert-file: "/etc/nsd/nsd_server.pem" + + # nsd-control key file. + # control-key-file: "/etc/nsd/nsd_control.key" + + # nsd-control certificate file. + # control-cert-file: "/etc/nsd/nsd_control.pem" + + +# Secret keys for TSIGs that secure zone transfers. +# You could include: "secret.keys" and put the 'key:' statements in there, +# and give that file special access control permissions. +# +# key: + # The key name is sent to the other party, it must be the same + #name: "keyname" + # algorithm hmac-md5, or sha1, sha256, sha224, sha384, sha512 + #algorithm: sha256 + # secret material, must be the same as the other party uses. + # base64 encoded random number. + # e.g. from dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64 + #secret: "K2tf3TRjvQkVCmJF3/Z9vA==" + + +# Patterns have zone configuration and they are shared by one or more zones. +# +# pattern: + # name by which the pattern is referred to + #name: "myzones" + # the zonefile for the zones that use this pattern. + # if relative then from the zonesdir (inside the chroot). + # the name is processed: %s - zone name (as appears in zone:name). + # %1 - first character of zone name, %2 second, %3 third. + # %z - topleveldomain label of zone, %y, %x next labels in name. + # if label or character does not exist you get a dot '.'. + # for example "%s.zone" or "zones/%1/%2/%3/%s" or "secondary/%z/%s" + #zonefile: "%s.zone" + + # If no master and slave access control elements are provided, + # this zone will not be served to/from other servers. + + # A master zone needs notify: and provide-xfr: lists. A slave + # may also allow zone transfer (for debug or other secondaries). + # notify these slaves when the master zone changes, address TSIG|NOKEY + # IP can be ipv4 and ipv6, with @port for a nondefault port number. + #notify: 192.0.2.1 NOKEY + # allow these IPs and TSIG to transfer zones, addr TSIG|NOKEY|BLOCKED + # address range 192.0.2.0/24, 1.2.3.4&255.255.0.0, 3.0.2.20-3.0.2.40 + #provide-xfr: 192.0.2.0/24 my_tsig_key_name + # set the number of retries for notify. + #notify-retry: 5 + + # uncomment to provide AXFR to all the world + # provide-xfr: 0.0.0.0/0 NOKEY + # provide-xfr: ::0/0 NOKEY + + # A slave zone needs allow-notify: and request-xfr: lists. + #allow-notify: 2001:db8::0/64 my_tsig_key_name + # By default, a slave will request a zone transfer with IXFR/TCP. + # If you want to make use of IXFR/UDP use: UDP addr tsigkey + # for a master that only speaks AXFR (like NSD) use AXFR addr tsigkey + #request-xfr: 192.0.2.2 the_tsig_key_name + # Attention: You cannot use UDP and AXFR together. AXFR is always over + # TCP. If you use UDP, we higly recommend you to deploy TSIG. + # Allow AXFR fallback if the master does not support IXFR. Default + # is yes. + #allow-axfr-fallback: yes + # set local interface for sending zone transfer requests. + # default is let the OS choose. + #outgoing-interface: 10.0.0.10 + # limit the refresh and retry interval in seconds. + #max-refresh-time: 2419200 + #min-refresh-time: 0 + #max-retry-time: 1209600 + #min-retry-time: 0 + + # Slave server tries zone transfer to all masters and picks highest + # zone version available, for when masters have different versions. + #multi-master-check: no + + # limit the zone transfer size (in bytes), stops very large transfers + # 0 is no limits enforced. + # size-limit-xfr: 0 + + # if compiled with --enable-zone-stats, give name of stat block for + # this zone (or group of zones). Output from nsd-control stats. + # zonestats: "%s" + + # if you give another pattern name here, at this point the settings + # from that pattern are inserted into this one (as if it were a + # macro). The statement can be given in between other statements, + # because the order of access control elements can make a difference + # (which master to request from first, which slave to notify first). + #include-pattern: "common-masters" + + +# Fixed zone entries. Here you can config zones that cannot be deleted. +# Zones that are dynamically added and deleted are put in the zonelist file. +# +# zone: + # name: "example.com" + # you can give a pattern here, all the settings from that pattern + # are then inserted at this point + # include-pattern: "master" + # You can also specify (additional) options directly for this zone. + # zonefile: "example.com.zone" + # request-xfr: 192.0.2.1 example.com.key + + # RRLconfig + # Response Rate Limiting, whitelist types + # rrl-whitelist: nxdomain + # rrl-whitelist: error + # rrl-whitelist: referral + # rrl-whitelist: any + # rrl-whitelist: rrsig + # rrl-whitelist: wildcard + # rrl-whitelist: nodata + # rrl-whitelist: dnskey + # rrl-whitelist: positive + # rrl-whitelist: all + # RRLend + +zone: + name: "dyn.jaseg.de" + zonefile: "/var/lib/dyndns/dyn.jaseg.de.zone" + diff --git a/gerboweb/deploy/setup_dyndns.yml b/gerboweb/deploy/setup_dyndns.yml new file mode 100644 index 0000000..d9735c7 --- /dev/null +++ b/gerboweb/deploy/setup_dyndns.yml @@ -0,0 +1,80 @@ +--- +- name: Set local facts + set_fact: + dyndns_sqlite_dbfile: /var/lib/dyndns/db.sqlite3 + +- name: Copy nsd config + copy: + src: nsd.conf + dest: /etc/nsd/nsd.conf + owner: root + group: root + mode: 0644 + +- name: Enable and launch nsd systemd service + systemd: + name: nsd.service + enabled: yes + state: restarted + +- name: Create dyndns worker user and group + user: + name: uwsgi-dyndns + create_home: no + group: uwsgi + password: '!' + shell: /sbin/nologin + system: yes + +- name: Allow dyndns app to kick nsd + lineinfile: + path: /etc/sudoers + line: 'uwsgi-dyndns ALL=(nsd) NOPASSWD: /usr/sbin/nsd-control reload dyn.jaseg.de' + +- name: Create webapp dir + file: + path: /var/lib/dyndns + state: directory + owner: uwsgi-dyndns + group: nsd + mode: 0750 + +- name: Copy webapp sources + copy: + src: dyndns.py + dest: /var/lib/dyndns/ + owner: uwsgi-dyndns + group: uwsgi + mode: 0440 + +- name: Template webapp config + template: + src: dyndns_config.py.j2 + dest: /var/lib/dyndns/config.py + owner: uwsgi-dyndns + group: root + mode: 0660 + +- name: Copy uwsgi config + copy: + src: uwsgi-dyndns.ini + dest: /etc/uwsgi.d/dyndns.ini + owner: uwsgi-dyndns + group: uwsgi + mode: 0440 + +- name: Enable uwsgi systemd socket + systemd: + daemon-reload: yes + name: uwsgi-app@dyndns.socket + enabled: yes + +- name: Create sqlite db file + file: + path: "{{dyndns_sqlite_dbfile}}" + owner: uwsgi-dyndns + group: uwsgi + mode: 0660 + state: touch + + diff --git a/gerboweb/deploy/uwsgi-dyndns.ini b/gerboweb/deploy/uwsgi-dyndns.ini new file mode 100644 index 0000000..b62e2af --- /dev/null +++ b/gerboweb/deploy/uwsgi-dyndns.ini @@ -0,0 +1,10 @@ +[uwsgi] +master = True +cheap = True +die-on-idle = False +manage-script-name = True +log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) [URI hidden] => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core)) +plugins = python3 +chdir = /var/lib/dyndns +mount = /=dyndns:app + -- cgit From b47ca7bbdc725d27f9f2875c11026b80e4affa4e Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 29 Dec 2020 13:08:39 +0100 Subject: Add dyndns secrets to gitignore --- gerboweb/deploy/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'gerboweb') diff --git a/gerboweb/deploy/.gitignore b/gerboweb/deploy/.gitignore index 136f960..2d2e2fc 100644 --- a/gerboweb/deploy/.gitignore +++ b/gerboweb/deploy/.gitignore @@ -1,4 +1,5 @@ *_secret.txt +dyndns_secret_*.txt *_apikey.txt playbook.retry credentials.ini -- cgit From 6fbea50682a52b9210b06f73d36c5f575d16362c Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 30 Dec 2020 11:38:27 +0100 Subject: Tag git setup foo --- gerboweb/deploy/cgit-logo-orig.png | Bin 0 -> 104376 bytes gerboweb/deploy/cgit-logo.png | Bin 104376 -> 42197 bytes gerboweb/deploy/cgitrc | 23 +++++++++++- gerboweb/deploy/playbook.yml | 74 +++++++++++++++++++++++++++++++------ gerboweb/deploy/setup_git.yml | 54 +++++++++++++++++---------- 5 files changed, 119 insertions(+), 32 deletions(-) create mode 100644 gerboweb/deploy/cgit-logo-orig.png (limited to 'gerboweb') diff --git a/gerboweb/deploy/cgit-logo-orig.png b/gerboweb/deploy/cgit-logo-orig.png new file mode 100644 index 0000000..f781fdd Binary files /dev/null and b/gerboweb/deploy/cgit-logo-orig.png differ diff --git a/gerboweb/deploy/cgit-logo.png b/gerboweb/deploy/cgit-logo.png index f781fdd..b1c0322 100644 Binary files a/gerboweb/deploy/cgit-logo.png and b/gerboweb/deploy/cgit-logo.png differ diff --git a/gerboweb/deploy/cgitrc b/gerboweb/deploy/cgitrc index d77778b..9b5a651 100644 --- a/gerboweb/deploy/cgitrc +++ b/gerboweb/deploy/cgitrc @@ -1,11 +1,24 @@ css=/cgit.css -logo= /cgit.png +logo=/cgit.png enable-http-clone=1 robots=noindex, nofollow virtual-root=/ readme=:README.rst +readme=:readme.rst +readme=:README.md +readme=:readme.md +readme=:README.txt +readme=:readme.txt +readme=:README.mkd +readme=:readme.mkd +readme=:README.htm +readme=:readme.htm +readme=:README.html +readme=:readme.html +readme=:README +readme=:readme about-filter=/usr/libexec/cgit/filters/about-formatting.sh enable-index-links=1 @@ -18,3 +31,11 @@ source-filter=/usr/libexec/cgit/filters/syntax-highlighting.py project-list=/var/lib/gitolite3/projects.list scan-path=/var/lib/gitolite3/repositories + +mimetype.gif=image/gif +mimetype.html=text/html +mimetype.jpg=image/jpeg +mimetype.jpeg=image/jpeg +mimetype.pdf=application/pdf +mimetype.png=image/png +mimetype.svg=image/svg+xml diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml index 72beb91..a34e8fe 100644 --- a/gerboweb/deploy/playbook.yml +++ b/gerboweb/deploy/playbook.yml @@ -35,20 +35,24 @@ hosts: wendelstein tasks: - name: Set hostname + tags: setup hostname: name: wendelstein.jaseg.net - name: Install common admin tools + tags: setup dnf: name: htop,tmux,fish,mosh,neovim,sqlite state: latest - name: Install host requisites + tags: setup dnf: name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,python3-libselinux,git,iptables-services,python3-pycryptodomex,zip,python3-uwsgidecorators,nsd state: latest - name: Disable password-based root login + tags: setup lineinfile: path: /etc/ssh/sshd_config regexp: '^PermitRootLogin' @@ -56,12 +60,14 @@ register: disable_root_pw_ssh - name: Restart sshd + tags: setup systemd: name: sshd state: restarted when: disable_root_pw_ssh is changed - name: Configure iptables firewall service + tags: setup copy: src: iptables.rules dest: /etc/sysconfig/iptables @@ -70,13 +76,18 @@ mode: 0664 - name: Enable iptables firewall service + tags: setup systemd: name: iptables enabled: yes state: started - name: Create containers - include_tasks: setup_containers.yml + tags: setup + include_tasks: + file: setup_containers.yml + apply: + tags: setup vars: containers: - gerboweb @@ -84,31 +95,72 @@ - pogojig - name: Setup web server - include_tasks: setup_webserver.yml + tags: www + include_tasks: + file: setup_webserver.yml + apply: + tags: www - name: Setup gerboweb - include_tasks: setup_gerboweb.yml + tags: gerboweb + include_tasks: + file: setup_gerboweb.yml + apply: + tags: gerboweb - name: Setup clippy - include_tasks: setup_clippy.yml + tags: clippy + include_tasks: + file: setup_clippy.yml + apply: + tags: clippy - name: Setup secure download - include_tasks: setup_secure_download.yml + tags: secure-download + include_tasks: + file: setup_secure_download.yml + apply: + tags: secure-download - name: Setup tracespace - include_tasks: setup_tracespace.yml + tags: pogojig + include_tasks: + file: setup_tracespace.yml + apply: + tags: pogojig - name: Setup openjscad - include_tasks: setup_openjscad.yml + tags: pogojig + include_tasks: + file: setup_openjscad.yml + apply: + tags: pogojig - name: Setup pogojig - include_tasks: setup_pogojig.yml + tags: pogojig + include_tasks: + file: setup_pogojig.yml + apply: + tags: pogojig - name: Setup notification proxy - include_tasks: setup_notification_proxy.yml + tags: notification-proxy + include_tasks: + file: setup_notification_proxy.yml + apply: + tags: + notification-proxy - name: Setup semi-public git server - include_tasks: setup_git.yml + tags: git + include_tasks: + file: setup_git.yml + apply: + tags: git - name: Setup private DynDNS service - include_tasks: setup_dyndns.yml + tags: dyndns + include_tasks: + file: setup_dyndns.yml + apply: + tags: dyndns diff --git a/gerboweb/deploy/setup_git.yml b/gerboweb/deploy/setup_git.yml index 6e7d621..d1789bd 100644 --- a/gerboweb/deploy/setup_git.yml +++ b/gerboweb/deploy/setup_git.yml @@ -43,26 +43,34 @@ name: uwsgi-app@cgit.socket enabled: yes -- name: Copy gitolite admin pubkey - copy: - src: ~/.ssh/id_ed25519.gitolite.pub - dest: /tmp/jaseg-gitolite.pub - owner: gitolite3 - group: gitolite3 - -- name: Run gitolite initialization - command: gitolite setup -pk /tmp/jaseg-gitolite.pub - become: true - become_method: su - become_user: gitolite3 - become_flags: '-s /bin/sh' - args: - creates: /var/lib/gitolite3/projects.list - -- name: Remove leftover admin pubkey - file: - state: absent - path: /tmp/jaseg-gitolite.pub +- name: Check if gitolite ssh config exists + stat: + path: /var/lib/gitolite3/.ssh/authorized_keys + register: gitolite_ssh_keys_stat + +- name: Gitolite admin key setup + block: + - name: Copy gitolite admin pubkey + copy: + src: ~/.ssh/id_ed25519.gitolite.pub + dest: /tmp/jaseg-gitolite.pub + owner: gitolite3 + group: gitolite3 + + - name: Run gitolite initialization + command: gitolite setup -pk /tmp/jaseg-gitolite.pub + become: true + become_method: su + become_user: gitolite3 + become_flags: '-s /bin/sh' + args: + creates: /var/lib/gitolite3/projects.list + + - name: Remove leftover admin pubkey + file: + state: absent + path: /tmp/jaseg-gitolite.pub + when: not gitolite_ssh_keys_stat.stat.exists - name: Allow uwsgi group to access gitolite repo dir file: @@ -113,3 +121,9 @@ home: "{{ getent_passwd['gitolite3'][4] }}" uid: "{{ getent_passwd['gitolite3'][1] }}" +- name: Hack to fix cgit handling for restructuredtext readmes + file: + src: /usr/bin/rst2html + dest: /usr/bin/rst2html.py + state: link + -- cgit From ee35c061194ade1274e4d01b3ad799258618a199 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 30 Dec 2020 11:52:05 +0100 Subject: Update cgit config with cosmetic changes --- gerboweb/deploy/cgit-favicon.ico | Bin 0 -> 5430 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 gerboweb/deploy/cgit-favicon.ico (limited to 'gerboweb') diff --git a/gerboweb/deploy/cgit-favicon.ico b/gerboweb/deploy/cgit-favicon.ico new file mode 100644 index 0000000..c4ad2ef Binary files /dev/null and b/gerboweb/deploy/cgit-favicon.ico differ -- cgit From e290ac758b02a9d03bacd511c87fc997db41d0a8 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 30 Dec 2020 12:11:11 +0100 Subject: Add README --- gerboweb/deploy/README.rst | 33 +++++++++++++++++++++++++++++++++ gerboweb/deploy/cgitrc | 7 +++++++ gerboweb/deploy/nginx.conf | 4 ++++ gerboweb/deploy/setup_git.yml | 9 +++++++-- 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 gerboweb/deploy/README.rst (limited to 'gerboweb') diff --git a/gerboweb/deploy/README.rst b/gerboweb/deploy/README.rst new file mode 100644 index 0000000..d74418d --- /dev/null +++ b/gerboweb/deploy/README.rst @@ -0,0 +1,33 @@ +Admin foo howto +=============== + +Ansible +------- + +Selectively run ansible playbooks for the git service and webserver setup: + +.. code-block:: + + ansible-playbook -i inventory.yml -t git,www playbook.yml + +Gitolite/CGIT +------------- + +Remove ad-hoc repo from command line: + +.. code-block:: + + ssh git@git.jaseg.de unlock sjandrakei/pub/usb-remote + ssh git@git.jaseg.de D unlock sjandrakei/pub/usb-remote + +Set ad-hoc repo description from command line: + +.. code-block:: + + ssh git@git.jaseg.de desc sjandrakei/pub/kochbuch Bringing analog recipe books into the interwebs + +Create ad-hoc repo from command line: + +.. code-block:: + + git clone git@git.jaseg.de:sjandrakei/pub/repo-to-be-created.git diff --git a/gerboweb/deploy/cgitrc b/gerboweb/deploy/cgitrc index 9b5a651..eebcc09 100644 --- a/gerboweb/deploy/cgitrc +++ b/gerboweb/deploy/cgitrc @@ -1,5 +1,12 @@ css=/cgit.css logo=/cgit.png +favicon=/favicon.png + +root-title=git.jaseg.de +root-desc=jaseg's git repositories +snapshots=tar.gz tar.bz2 zip + +clone-url=git@git.jaseg.de:$CGIT_REPO_URL https://git.jaseg.de/$CGIT_REPO_URL enable-http-clone=1 robots=noindex, nofollow diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf index d46c394..f14f370 100644 --- a/gerboweb/deploy/nginx.conf +++ b/gerboweb/deploy/nginx.conf @@ -396,6 +396,10 @@ http { alias /var/www/git.jaseg.de/cgit.png; } + location ~ ^/favicon.ico { + alias /var/www/git.jaseg.de/favicon.ico; + } + location / { include uwsgi_params; uwsgi_modifier1 9; diff --git a/gerboweb/deploy/setup_git.yml b/gerboweb/deploy/setup_git.yml index d1789bd..2f4c59f 100644 --- a/gerboweb/deploy/setup_git.yml +++ b/gerboweb/deploy/setup_git.yml @@ -1,13 +1,18 @@ - name: Install host requisites dnf: - name: cgit,gitolite3,python3-pygments,python3-docutils,nodejs-markdown + name: cgit,gitolite3,python3-pygments,python3-docutils,nodejs-markdown,python3-markdown state: latest -- name: Copy cgit favicon +- name: Copy cgit logo copy: src: cgit-logo.png dest: /var/www/git.jaseg.de/cgit.png +- name: Copy cgit favicon + copy: + src: cgit-favicon.ico + dest: /var/www/git.jaseg.de/favicon.ico + - name: Create cgit instance config dir file: path: /var/lib/cgit -- cgit From c6b1c2225d1ac4ac647950be8667b5709b0033a1 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 30 Dec 2020 13:12:06 +0100 Subject: remove ansible scripts, they are now in their own "infra" repo --- gerboweb/deploy/.gitignore | 5 - gerboweb/deploy/README.rst | 33 -- gerboweb/deploy/bootstrap_arch_container.yml | 63 --- gerboweb/deploy/cgit-favicon.ico | Bin 5430 -> 0 bytes gerboweb/deploy/cgit-logo-orig.png | Bin 104376 -> 0 bytes gerboweb/deploy/cgit-logo.png | Bin 42197 -> 0 bytes gerboweb/deploy/cgitrc | 48 --- gerboweb/deploy/checkouts/pogojig | 1 - gerboweb/deploy/clippy-nspawn.service | 36 -- gerboweb/deploy/clippy.nspawn | 2 - gerboweb/deploy/clippy.service.j2 | 9 - gerboweb/deploy/credentials.ini.example | 3 - gerboweb/deploy/dns.yml | 91 ----- gerboweb/deploy/dyndns.py | 149 ------- gerboweb/deploy/dyndns_config.py.j2 | 14 - gerboweb/deploy/gerboweb-job-processor.service.j2 | 9 - gerboweb/deploy/gerboweb.cfg.j2 | 4 - gerboweb/deploy/gitolite.rc | 202 --------- gerboweb/deploy/inventory.yml | 11 - gerboweb/deploy/iptables.rules | 27 -- gerboweb/deploy/library/inwx-collection | 1 - gerboweb/deploy/mirrorlist | 474 ---------------------- gerboweb/deploy/nginx.conf | 458 --------------------- gerboweb/deploy/nginx_nossl.conf | 59 --- gerboweb/deploy/notification_proxy.py | 179 -------- gerboweb/deploy/notification_proxy_config.py.j2 | 9 - gerboweb/deploy/nsd.conf | 372 ----------------- gerboweb/deploy/playbook.yml | 166 -------- gerboweb/deploy/pogojig-job-processor.service.j2 | 9 - gerboweb/deploy/pogojig.cfg.j2 | 4 - gerboweb/deploy/pogojig_generate.sh.j2 | 25 -- gerboweb/deploy/render.sh.j2 | 20 - gerboweb/deploy/secure_download.cfg.j2 | 1 - gerboweb/deploy/setup_clippy.yml | 85 ---- gerboweb/deploy/setup_containers.yml | 17 - gerboweb/deploy/setup_dyndns.yml | 80 ---- gerboweb/deploy/setup_gerboweb.yml | 100 ----- gerboweb/deploy/setup_git.yml | 134 ------ gerboweb/deploy/setup_notification_proxy.yml | 61 --- gerboweb/deploy/setup_openjscad.yml | 9 - gerboweb/deploy/setup_pogojig.yml | 125 ------ gerboweb/deploy/setup_secure_download.yml | 57 --- gerboweb/deploy/setup_tracespace.yml | 9 - gerboweb/deploy/setup_webserver.yml | 79 ---- gerboweb/deploy/tmpfiles-gerboweb.conf.j2 | 1 - gerboweb/deploy/tmpfiles-pogojig.conf.j2 | 1 - gerboweb/deploy/tmpfiles-secure-download.conf.j2 | 1 - gerboweb/deploy/uwsgi-app@.service | 16 - gerboweb/deploy/uwsgi-app@.socket | 11 - gerboweb/deploy/uwsgi-cgit.ini | 8 - gerboweb/deploy/uwsgi-dyndns.ini | 10 - gerboweb/deploy/uwsgi-gerboweb.ini | 10 - gerboweb/deploy/uwsgi-notification-proxy.ini | 10 - gerboweb/deploy/uwsgi-pogojig.ini | 10 - gerboweb/deploy/uwsgi-secure-download.ini | 11 - gerboweb/deploy/vector.sh.j2 | 18 - 56 files changed, 3347 deletions(-) delete mode 100644 gerboweb/deploy/.gitignore delete mode 100644 gerboweb/deploy/README.rst delete mode 100644 gerboweb/deploy/bootstrap_arch_container.yml delete mode 100644 gerboweb/deploy/cgit-favicon.ico delete mode 100644 gerboweb/deploy/cgit-logo-orig.png delete mode 100644 gerboweb/deploy/cgit-logo.png delete mode 100644 gerboweb/deploy/cgitrc delete mode 160000 gerboweb/deploy/checkouts/pogojig delete mode 100644 gerboweb/deploy/clippy-nspawn.service delete mode 100644 gerboweb/deploy/clippy.nspawn delete mode 100644 gerboweb/deploy/clippy.service.j2 delete mode 100644 gerboweb/deploy/credentials.ini.example delete mode 100644 gerboweb/deploy/dns.yml delete mode 100644 gerboweb/deploy/dyndns.py delete mode 100644 gerboweb/deploy/dyndns_config.py.j2 delete mode 100644 gerboweb/deploy/gerboweb-job-processor.service.j2 delete mode 100644 gerboweb/deploy/gerboweb.cfg.j2 delete mode 100644 gerboweb/deploy/gitolite.rc delete mode 100644 gerboweb/deploy/inventory.yml delete mode 100644 gerboweb/deploy/iptables.rules delete mode 160000 gerboweb/deploy/library/inwx-collection delete mode 100644 gerboweb/deploy/mirrorlist delete mode 100644 gerboweb/deploy/nginx.conf delete mode 100644 gerboweb/deploy/nginx_nossl.conf delete mode 100644 gerboweb/deploy/notification_proxy.py delete mode 100644 gerboweb/deploy/notification_proxy_config.py.j2 delete mode 100644 gerboweb/deploy/nsd.conf delete mode 100644 gerboweb/deploy/playbook.yml delete mode 100644 gerboweb/deploy/pogojig-job-processor.service.j2 delete mode 100644 gerboweb/deploy/pogojig.cfg.j2 delete mode 100755 gerboweb/deploy/pogojig_generate.sh.j2 delete mode 100755 gerboweb/deploy/render.sh.j2 delete mode 100644 gerboweb/deploy/secure_download.cfg.j2 delete mode 100644 gerboweb/deploy/setup_clippy.yml delete mode 100644 gerboweb/deploy/setup_containers.yml delete mode 100644 gerboweb/deploy/setup_dyndns.yml delete mode 100644 gerboweb/deploy/setup_gerboweb.yml delete mode 100644 gerboweb/deploy/setup_git.yml delete mode 100644 gerboweb/deploy/setup_notification_proxy.yml delete mode 100644 gerboweb/deploy/setup_openjscad.yml delete mode 100644 gerboweb/deploy/setup_pogojig.yml delete mode 100644 gerboweb/deploy/setup_secure_download.yml delete mode 100644 gerboweb/deploy/setup_tracespace.yml delete mode 100644 gerboweb/deploy/setup_webserver.yml delete mode 100644 gerboweb/deploy/tmpfiles-gerboweb.conf.j2 delete mode 100644 gerboweb/deploy/tmpfiles-pogojig.conf.j2 delete mode 100644 gerboweb/deploy/tmpfiles-secure-download.conf.j2 delete mode 100644 gerboweb/deploy/uwsgi-app@.service delete mode 100644 gerboweb/deploy/uwsgi-app@.socket delete mode 100644 gerboweb/deploy/uwsgi-cgit.ini delete mode 100644 gerboweb/deploy/uwsgi-dyndns.ini delete mode 100644 gerboweb/deploy/uwsgi-gerboweb.ini delete mode 100644 gerboweb/deploy/uwsgi-notification-proxy.ini delete mode 100644 gerboweb/deploy/uwsgi-pogojig.ini delete mode 100644 gerboweb/deploy/uwsgi-secure-download.ini delete mode 100755 gerboweb/deploy/vector.sh.j2 (limited to 'gerboweb') diff --git a/gerboweb/deploy/.gitignore b/gerboweb/deploy/.gitignore deleted file mode 100644 index 2d2e2fc..0000000 --- a/gerboweb/deploy/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*_secret.txt -dyndns_secret_*.txt -*_apikey.txt -playbook.retry -credentials.ini diff --git a/gerboweb/deploy/README.rst b/gerboweb/deploy/README.rst deleted file mode 100644 index d74418d..0000000 --- a/gerboweb/deploy/README.rst +++ /dev/null @@ -1,33 +0,0 @@ -Admin foo howto -=============== - -Ansible -------- - -Selectively run ansible playbooks for the git service and webserver setup: - -.. code-block:: - - ansible-playbook -i inventory.yml -t git,www playbook.yml - -Gitolite/CGIT -------------- - -Remove ad-hoc repo from command line: - -.. code-block:: - - ssh git@git.jaseg.de unlock sjandrakei/pub/usb-remote - ssh git@git.jaseg.de D unlock sjandrakei/pub/usb-remote - -Set ad-hoc repo description from command line: - -.. code-block:: - - ssh git@git.jaseg.de desc sjandrakei/pub/kochbuch Bringing analog recipe books into the interwebs - -Create ad-hoc repo from command line: - -.. code-block:: - - git clone git@git.jaseg.de:sjandrakei/pub/repo-to-be-created.git diff --git a/gerboweb/deploy/bootstrap_arch_container.yml b/gerboweb/deploy/bootstrap_arch_container.yml deleted file mode 100644 index dfe677b..0000000 --- a/gerboweb/deploy/bootstrap_arch_container.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -- name: Set local path facts - set_fact: - image: "/var/lib/machines/{{ container }}.img" - root: "/var/lib/machines/{{ container }}" - "{{container}}_root": "/var/lib/machines/{{ container }}" - -- name: Create container image file - command: truncate -s 4G "{{image}}" - args: - creates: "{{image}}" - register: create_container - -- name: Download arch bootstrap image - get_url: - url: http://mirror.rackspace.com/archlinux/iso/2020.03.01/archlinux-bootstrap-2020.03.01-x86_64.tar.gz - dest: /tmp/arch-bootstrap.tar.xz - checksum: sha256:49c7aa8718e48f5a4ec570624520fa50616ed3e044af101ec3aa16c155136f82 - when: create_container is changed - -- name: Create container image filesystem - filesystem: - dev: "{{image}}" - fstype: btrfs - -- name: Create container image fstab entry - mount: - src: "{{image}}" - path: "{{root}}" - state: mounted - fstype: btrfs - opts: loop - -- name: Unpack bootstrap image - unarchive: - remote_src: yes - src: /tmp/arch-bootstrap.tar.xz - dest: "{{root}}" - extra_opts: --strip-components=1 - creates: "{{root}}/etc" - -- name: Copy mirrorlist into container - copy: - src: mirrorlist - dest: "{{root}}/etc/pacman.d/mirrorlist" - -- name: Initialize container pacman keyring - shell: arch-chroot "{{root}}" pacman-key --init && arch-chroot "{{root}}" pacman-key --populate archlinux - args: - creates: "{{root}}/etc/pacman.d/gnupg" - -- name: Fixup pacman.conf for pacman to work in chroot without its own root fs - lineinfile: - path: "{{root}}/etc/pacman.conf" - regexp: '^CheckSpace' - line: '#CheckSpace' - -- name: Update container keyring - shell: arch-chroot "{{root}}" pacman -Sy --noconfirm archlinux-keyring - -- name: Update container and install software - shell: arch-chroot "{{root}}" pacman -Syu --noconfirm - diff --git a/gerboweb/deploy/cgit-favicon.ico b/gerboweb/deploy/cgit-favicon.ico deleted file mode 100644 index c4ad2ef..0000000 Binary files a/gerboweb/deploy/cgit-favicon.ico and /dev/null differ diff --git a/gerboweb/deploy/cgit-logo-orig.png b/gerboweb/deploy/cgit-logo-orig.png deleted file mode 100644 index f781fdd..0000000 Binary files a/gerboweb/deploy/cgit-logo-orig.png and /dev/null differ diff --git a/gerboweb/deploy/cgit-logo.png b/gerboweb/deploy/cgit-logo.png deleted file mode 100644 index b1c0322..0000000 Binary files a/gerboweb/deploy/cgit-logo.png and /dev/null differ diff --git a/gerboweb/deploy/cgitrc b/gerboweb/deploy/cgitrc deleted file mode 100644 index eebcc09..0000000 --- a/gerboweb/deploy/cgitrc +++ /dev/null @@ -1,48 +0,0 @@ -css=/cgit.css -logo=/cgit.png -favicon=/favicon.png - -root-title=git.jaseg.de -root-desc=jaseg's git repositories -snapshots=tar.gz tar.bz2 zip - -clone-url=git@git.jaseg.de:$CGIT_REPO_URL https://git.jaseg.de/$CGIT_REPO_URL - -enable-http-clone=1 -robots=noindex, nofollow -virtual-root=/ - -readme=:README.rst -readme=:readme.rst -readme=:README.md -readme=:readme.md -readme=:README.txt -readme=:readme.txt -readme=:README.mkd -readme=:readme.mkd -readme=:README.htm -readme=:readme.htm -readme=:README.html -readme=:readme.html -readme=:README -readme=:readme -about-filter=/usr/libexec/cgit/filters/about-formatting.sh - -enable-index-links=1 -enable-commit-grpah=1 -enable-log-filecount=1 -enable-log-linecount=1 -enable-git-config=1 - -source-filter=/usr/libexec/cgit/filters/syntax-highlighting.py - -project-list=/var/lib/gitolite3/projects.list -scan-path=/var/lib/gitolite3/repositories - -mimetype.gif=image/gif -mimetype.html=text/html -mimetype.jpg=image/jpeg -mimetype.jpeg=image/jpeg -mimetype.pdf=application/pdf -mimetype.png=image/png -mimetype.svg=image/svg+xml diff --git a/gerboweb/deploy/checkouts/pogojig b/gerboweb/deploy/checkouts/pogojig deleted file mode 160000 index 13a5721..0000000 --- a/gerboweb/deploy/checkouts/pogojig +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 13a57211f0d0feb34b452b3e19be83a095707ed6 diff --git a/gerboweb/deploy/clippy-nspawn.service b/gerboweb/deploy/clippy-nspawn.service deleted file mode 100644 index 8dbedbd..0000000 --- a/gerboweb/deploy/clippy-nspawn.service +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1+ -# -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=Clippy container -PartOf=machines.target -Before=machines.target -After=network.target systemd-resolved.service -RequiresMountsFor=/var/lib/machines - -[Service] -ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --ephemeral --boot -U --settings=override --machine=clippy -KillMode=mixed -Type=notify -RestartForceExitStatus=133 -SuccessExitStatus=133 -WatchdogSec=3min -Slice=machine.slice -Delegate=yes -TasksMax=512 - -# Enforce a strict device policy, similar to the one nspawn configures when it -# allocates its own scope unit. Make sure to keep these policies in sync if you -# change them! -DevicePolicy=closed -DeviceAllow=/dev/net/tun rwm -DeviceAllow=char-pts rw - -[Install] -WantedBy=machines.target diff --git a/gerboweb/deploy/clippy.nspawn b/gerboweb/deploy/clippy.nspawn deleted file mode 100644 index dfe2935..0000000 --- a/gerboweb/deploy/clippy.nspawn +++ /dev/null @@ -1,2 +0,0 @@ -[Network] -VirtualEthernet=no diff --git a/gerboweb/deploy/clippy.service.j2 b/gerboweb/deploy/clippy.service.j2 deleted file mode 100644 index 22b3d7d..0000000 --- a/gerboweb/deploy/clippy.service.j2 +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Clippy listener daemon - -[Service] -WorkingDirectory=/var/lib/clippy.git -ExecStart=/usr/bin/python3 clippy.py -s -x 60x30 -e - -[Install] -WantedBy=multi-user.target diff --git a/gerboweb/deploy/credentials.ini.example b/gerboweb/deploy/credentials.ini.example deleted file mode 100644 index 9b87321..0000000 --- a/gerboweb/deploy/credentials.ini.example +++ /dev/null @@ -1,3 +0,0 @@ -[inwx] -user=... -pass=... diff --git a/gerboweb/deploy/dns.yml b/gerboweb/deploy/dns.yml deleted file mode 100644 index 0fd753a..0000000 --- a/gerboweb/deploy/dns.yml +++ /dev/null @@ -1,91 +0,0 @@ -- name: Setup subdomain A records pointing to wendelstein - inwx: - domain: "{{item.partition('.')[2]}}" - record: "{{item.partition('.')[0]}}" - type: A - value: "{{ hostvars['wendelstein']['ansible_default_ipv4']['address'] }}" - loop: "{{subdomains}}" - -- name: Setup dyndns A record - inwx: - domain: jaseg.de - record: ns - type: A - value: "{{ hostvars['wendelstein']['ansible_default_ipv4']['address'] }}" - -- name: Setup dyndns NS record - inwx: - domain: jaseg.de - record: dyn - type: NS - value: 'ns.jaseg.de' - -- name: Setup subdomain AAAA records pointing to wendelstein - inwx: - domain: "{{item.partition('.')[2]}}" - record: "{{item.partition('.')[0]}}" - type: AAAA - value: "{{ hostvars['wendelstein']['ansible_default_ipv6']['address'] }}" - loop: "{{subdomains}}" - -- name: Setup jaseg.net subdomain MX records pointing to fastmail - inwx: - domain: "{{item.partition('.')[2]}}" - record: "{{item.partition('.')[0]}}" - type: MX - priority: 10 - value: in1-smtp.messagingengine.com - loop: "{{subdomains}}" - -- name: Setup jaseg.net subdomain MX records pointing to fastmail - inwx: - domain: "{{item.partition('.')[2]}}" - record: "{{item.partition('.')[0]}}" - type: MX - priority: 20 - value: in2-smtp.messagingengine.com - loop: "{{subdomains}}" - -- name: Setup sendgrid gateway - inwx: - domain: jaseg.de - type: CNAME - record: "{{item.split(' ')[0]}}" - value: "{{item.split(' ')[1]}}" - loop: - - em6100.automation u14518136.wl137.sendgrid.net - - s1._domainkey.automation s1.domainkey.u14518136.wl137.sendgrid.net - - s2._domainkey.automation s2.domainkey.u14518136.wl137.sendgrid.net - -- name: Set fastmail DNS entry template - set_fact: - fastmail_dns_entries: - - {rtype: MX, record: ".", prio: 10, value: in1-smtp.messagingengine.com} - - {rtype: MX, record: ".", prio: 20, value: in2-smtp.messagingengine.com} - - {rtype: MX, record: "*", prio: 10, value: in1-smtp.messagingengine.com} - - {rtype: MX, record: "*", prio: 20, value: in2-smtp.messagingengine.com} - - {rtype: TXT, record: ".", value: "v=spf1 include:spf.messagingengine.com ?all"} - - {rtype: CNAME, record: mesmtp._domainkey, value: mesmtp.jaseg.de.dkim.fmhosted.com} - - {rtype: CNAME, record: fm1._domainkey, value: fm1.jaseg.de.dkim.fmhosted.com} - - {rtype: CNAME, record: fm2._domainkey, value: fm2.jaseg.de.dkim.fmhosted.com} - - {rtype: CNAME, record: fm3._domainkey, value: fm3.jaseg.de.dkim.fmhosted.com} - - {rtype: SRV, record: _submission._tcp, prio: 0, weight: 1, port: 587, value: smtp.fastmail.com} - - {rtype: SRV, record: _imap._tcp, prio: 0, weight: 0, port: 0, value: "."} - - {rtype: SRV, record: _imaps._tcp, prio: 0, weight: 1, port: 993, value: imap.fastmail.com} - - {rtype: SRV, record: _pop3._tcp, prio: 0, weight: 0, port: 0, value: "."} - - {rtype: SRV, record: _pop3s._tcp, prio: 10, weight: 1, port: 995, value: pop.fastmail.com} - - {rtype: SRV, record: _jmap._tcp, prio: 0, weight: 1, port: 443, value: jmap.fastmail.com} - - {rtype: SRV, record: _carddav._tcp, prio: 0, weight: 0, port: 0, value: "."} - - {rtype: SRV, record: _carddavs._tcp, prio: 0, weight: 1, port: 443, value: carddav.fastmail.com} - -- name: Setup fastmail DNS entries - inwx: - domain: "{{ item[1] }}" - type: "{{ item[0]['rtype'] }}" - record: "{{ item[0]['record'] | regex_replace('\\.*$', '') }}" - priority: "{{ item[0].get('prio') | int }}" - port: "{{ item[0].get('port') | int}}" - weight: "{{ item[0].get('weight') | int }}" - value: "{{ item[0]['value'] }}" - loop: "{{ fastmail_dns_entries | product(fastmail_domains) | list }}" - diff --git a/gerboweb/deploy/dyndns.py b/gerboweb/deploy/dyndns.py deleted file mode 100644 index 2546dce..0000000 --- a/gerboweb/deploy/dyndns.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 - -import time -from contextlib import contextmanager -import re -import os -import os.path -import random -import string -import subprocess -import sqlite3 -import hmac -from ipaddress import IPv4Address, IPv6Address - -from flask import Flask, request, abort -import uwsgidecorators - -app = Flask(__name__) -app.config.update(dict( - RECORD_EXPIRY_S = 86400, - NSD_CONTROL = 'nsd-control' - )) -app.config.from_pyfile('config.py') - - -ZONEFILE_TEMPLATE = '''\ -; #################################################### ; -; THIS FILE IS AUTOMATICALLY GENERATED! DO NOT MODIFY! ; -; #################################################### ; - -$ORIGIN {zone}. -$TTL 1800 -@ IN SOA {ns}. {mail}. ( - {serial} ; serial number - 60 ; refresh - 60 ; retry - {expire} ; expire - 60 ; ttl - ) -; Name servers - IN NS {ns}. - -; Additional A records from template -; @ IN A 192.0.2.3 -; www IN A 192.0.2.3 - -; Dynamically generated records -{dynamic_records} -''' - -db = sqlite3.connect(app.config['SQLITE_DB'], check_same_thread=False) -with db as conn: - conn.execute('''CREATE TABLE IF NOT EXISTS zone_versions (date TEXT)''') - conn.execute('''CREATE TABLE IF NOT EXISTS records - (name TEXT PRIMARY KEY, ipv4 TEXT, ipv6 TEXT, last_update INTEGER)''') - -def purge_expired_records(): - with db as conn: - conn.execute('DELETE FROM records WHERE last_update < ?', - (int(time.time()) - app.config['RECORD_EXPIRY_S'],)) - -def update_record(record, ipv4=None, ipv6=None): - with db as conn: - old_v4, old_v6 = conn.execute('SELECT ipv4, ipv6 FROM records WHERE name=?', (record,)).fetchone() or (None, None) - conn.execute('INSERT OR REPLACE INTO records VALUES (?, ?, ?, ?)', (record, ipv4, ipv6, int(time.time()))) - return ipv4 != old_v4 or ipv6 != old_v6 - -@contextmanager -def inplace_rewrite(filename, cleanup=True): - print('Writing', filename) - filename = os.path.abspath(filename) - if cleanup: - basename = os.path.basename(filename) - for entry in os.scandir(os.path.dirname(filename)): - if entry.name.startswith(basename) and re.match(r'\.tmp-[a-zA-Z0-9]{8}', entry.name[len(basename):]): - os.remove(entry.path) - - tmp_fn = filename + f'.tmp-' + ''.join(random.choices(string.ascii_letters + string.digits, k=8)) - with open(tmp_fn, 'w') as tmp_f: - yield tmp_f - tmp_f.flush() - os.fsync(tmp_f.fileno()) - os.rename(tmp_fn, filename) - -def write_zonefile(): - # Find the next free zonefile version number - with db as conn: - conn.execute('INSERT INTO zone_versions VALUES (DATE())') - date, version_num, = conn.execute('SELECT zone_versions.date, COUNT(*) FROM zone_versions WHERE zone_versions.date = DATE()').fetchone() - zone_version = f'{date.replace("-", "")}{version_num:02d}' - - # Generate dynamic record block - with db as conn: - records = db.execute('SELECT name, "A", ipv4 FROM records UNION SELECT name, "AAAA", ipv6 FROM records') - dynamic_records = '\n'.join(f'{name:<20} IN {rtype:<4} {value}' for name, rtype, value in records if value is not None) - - # Template zone file content - content = ZONEFILE_TEMPLATE.format( - zone = app.config['ZONE'], - ns = app.config['NAMESERVER'], - mail = app.config['NAMESERVER_MAIL'].replace('@', '.'), - serial = zone_version, - dynamic_records = dynamic_records, - expire = app.config['RECORD_EXPIRY_S'] - ) - - with inplace_rewrite(app.config['ZONEFILE'], cleanup=True) as f: - f.write(content) - -def kick_nsd(): - prog = app.config['NSD_CONTROL'] - if isinstance(prog, str): - prog = [prog] - subprocess.run([*prog, 'reload', app.config['ZONE']], check=True) - -@app.before_first_request -@uwsgidecorators.timer(300) -def update_zonefile(): - purge_expired_records() - write_zonefile() - kick_nsd() - -@app.route('/update', methods=['POST']) -def route_update(): - if request.authorization is None: - abort(403) - - record = request.authorization['username'] - record_config = app.config['DYNAMIC_RECORDS'].get(record) - if record_config is None: - abort(403) - - *supported_formats, password = record_config - if not hmac.compare_digest(request.authorization['password'], password): - abort(403) - - ipv4 = request.args.get('ipv4', '127.0.0.1') - ipv6 = request.args.get('ipv6', '::1') - ipv4 = str(IPv4Address(ipv4)) if 'v4' in supported_formats else None - ipv6 = str(IPv6Address(ipv6)) if 'v6' in supported_formats else None - if update_record(record, ipv4=ipv4, ipv6=ipv6): - update_zonefile() - - return 'success' - - -if __name__ == '__main__': - app.run() - diff --git a/gerboweb/deploy/dyndns_config.py.j2 b/gerboweb/deploy/dyndns_config.py.j2 deleted file mode 100644 index 3212a1e..0000000 --- a/gerboweb/deploy/dyndns_config.py.j2 +++ /dev/null @@ -1,14 +0,0 @@ - -SQLITE_DB = '{{dyndns_sqlite_dbfile}}' - -NAMESERVER = 'ns.jaseg.de' -NAMESERVER_MAIL = 'dns@jaseg.de' -ZONEFILE = 'dyn.jaseg.de.zone' -ZONE = 'dyn.jaseg.de' -NSD_CONTROL = 'sudo -u nsd nsd-control'.split() - -DYNAMIC_RECORDS = { - 'bigdata': ('v6', '{{ lookup('password', 'dyndns_secret_bigdata.txt length=32') }}'), - 'raspi': ('v6', '{{ lookup('password', 'dyndns_secret_raspi.txt length=32') }}'), -} - diff --git a/gerboweb/deploy/gerboweb-job-processor.service.j2 b/gerboweb/deploy/gerboweb-job-processor.service.j2 deleted file mode 100644 index 517d8b8..0000000 --- a/gerboweb/deploy/gerboweb-job-processor.service.j2 +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Gerboweb gerber job processor - -[Service] -WorkingDirectory=/var/lib/gerboweb -ExecStart=/usr/bin/python3 job_processor.py {{gerboweb_cache}}/job_queue.sqlite3 - -[Install] -WantedBy=uwsgi-app@gerboweb.service diff --git a/gerboweb/deploy/gerboweb.cfg.j2 b/gerboweb/deploy/gerboweb.cfg.j2 deleted file mode 100644 index 994cd08..0000000 --- a/gerboweb/deploy/gerboweb.cfg.j2 +++ /dev/null @@ -1,4 +0,0 @@ -MAX_CONTENT_LENGTH=10000000 -SECRET_KEY="{{lookup('password', 'gerboweb_flask_secret.txt length=32')}}" -UPLOAD_PATH="{{gerboweb_cache}}/upload" -JOB_QUEUE_DB="{{gerboweb_cache}}/job_queue.sqlite3" diff --git a/gerboweb/deploy/gitolite.rc b/gerboweb/deploy/gitolite.rc deleted file mode 100644 index ad1d2bb..0000000 --- a/gerboweb/deploy/gitolite.rc +++ /dev/null @@ -1,202 +0,0 @@ -# configuration variables for gitolite - -# This file is in perl syntax. But you do NOT need to know perl to edit it -- -# just mind the commas, use single quotes unless you know what you're doing, -# and make sure the brackets and braces stay matched up! - -# (Tip: perl allows a comma after the last item in a list also!) - -# HELP for commands can be had by running the command with "-h". - -# HELP for all the other FEATURES can be found in the documentation (look for -# "list of non-core programs shipped with gitolite" in the master index) or -# directly in the corresponding source file. - -%RC = ( - - # ------------------------------------------------------------------ - - # default umask gives you perms of '0700'; see the rc file docs for - # how/why you might change this - UMASK => 0027, - - # look for "git-config" in the documentation - GIT_CONFIG_KEYS => 'core\.sharedRepository gitweb.owner gitweb.description gitweb.category', - - # comment out if you don't need all the extra detail in the logfile - LOG_EXTRA => 1, - # logging options - # 1. leave this section as is for 'normal' gitolite logging (default) - # 2. uncomment this line to log ONLY to syslog: - # LOG_DEST => 'syslog', - # 3. uncomment this line to log to syslog and the normal gitolite log: - # LOG_DEST => 'syslog,normal', - # 4. prefixing "repo-log," to any of the above will **also** log just the - # update records to "gl-log" in the bare repo directory: - # LOG_DEST => 'repo-log,normal', - # LOG_DEST => 'repo-log,syslog', - # LOG_DEST => 'repo-log,syslog,normal', - # syslog 'facility': defaults to 'local0', uncomment if needed. For example: - # LOG_FACILITY => 'local4', - - # roles. add more roles (like MANAGER, TESTER, ...) here. - # WARNING: if you make changes to this hash, you MUST run 'gitolite - # compile' afterward, and possibly also 'gitolite trigger POST_COMPILE' - ROLES => { - READERS => 1, - WRITERS => 1, - }, - - # enable caching (currently only Redis). PLEASE RTFM BEFORE USING!!! - # CACHE => 'Redis', - - # ------------------------------------------------------------------ - - # rc variables used by various features - - # the 'info' command prints this as additional info, if it is set - # SITE_INFO => 'Please see http://blahblah/gitolite for more help', - - # the CpuTime feature uses these - # display user, system, and elapsed times to user after each git operation - # DISPLAY_CPU_TIME => 1, - # display a warning if total CPU times (u, s, cu, cs) crosses this limit - # CPU_TIME_WARN_LIMIT => 0.1, - - # the Mirroring feature needs this - # HOSTNAME => "foo", - - # TTL for redis cache; PLEASE SEE DOCUMENTATION BEFORE UNCOMMENTING! - # CACHE_TTL => 600, - - # ------------------------------------------------------------------ - - # suggested locations for site-local gitolite code (see cust.html) - - # this one is managed directly on the server - # LOCAL_CODE => "$ENV{HOME}/local", - - # or you can use this, which lets you put everything in a subdirectory - # called "local" in your gitolite-admin repo. For a SECURITY WARNING - # on this, see http://gitolite.com/gitolite/non-core.html#pushcode - # LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local", - - # ------------------------------------------------------------------ - - # List of commands and features to enable - - ENABLE => [ - - # COMMANDS - - # These are the commands enabled by default - 'help', - 'desc', - 'info', - 'perms', - 'writable', - - # Uncomment or add new commands here. - # 'create', - # 'fork', - # 'mirror', - # 'readme', - # 'sskm', - 'D', - - # These FEATURES are enabled by default. - - # essential (unless you're using smart-http mode) - 'ssh-authkeys', - - # creates git-config entries from gitolite.conf file entries like 'config foo.bar = baz' - 'git-config', - - # creates git-daemon-export-ok files; if you don't use git-daemon, comment this out - 'daemon', - - # creates projects.list file; if you don't use gitweb, comment this out - 'gitweb', - - # These FEATURES are disabled by default; uncomment to enable. If you - # need to add new ones, ask on the mailing list :-) - - # user-visible behaviour - - # prevent wild repos auto-create on fetch/clone - # 'no-create-on-read', - # no auto-create at all (don't forget to enable the 'create' command!) - # 'no-auto-create', - - # access a repo by another (possibly legacy) name - # 'Alias', - - # give some users direct shell access. See documentation in - # sts.html for details on the following two choices. - # "Shell $ENV{HOME}/.gitolite.shell-users", - # 'Shell alice bob', - - # set default roles from lines like 'option default.roles-1 = ...', etc. - # 'set-default-roles', - - # show more detailed messages on deny - # 'expand-deny-messages', - - # show a message of the day - # 'Motd', - - # system admin stuff - - # enable mirroring (don't forget to set the HOSTNAME too!) - # 'Mirroring', - - # allow people to submit pub files with more than one key in them - # 'ssh-authkeys-split', - - # selective read control hack - # 'partial-copy', - - # manage local, gitolite-controlled, copies of read-only upstream repos - # 'upstream', - - # updates 'description' file instead of 'gitweb.description' config item - # 'cgit', - - # allow repo-specific hooks to be added - # 'repo-specific-hooks', - - # performance, logging, monitoring... - - # be nice - # 'renice 10', - - # log CPU times (user, system, cumulative user, cumulative system) - # 'CpuTime', - - # syntactic_sugar for gitolite.conf and included files - - # allow backslash-escaped continuation lines in gitolite.conf - # 'continuation-lines', - - # create implicit user groups from directory names in keydir/ - # 'keysubdirs-as-groups', - - # allow simple line-oriented macros - # 'macros', - - # Kindergarten mode - - # disallow various things that sensible people shouldn't be doing anyway - # 'Kindergarten', - ], - -); - -# ------------------------------------------------------------------------------ -# per perl rules, this should be the last line in such a file: -1; - -# Local variables: -# mode: perl -# End: -# vim: set syn=perl: diff --git a/gerboweb/deploy/inventory.yml b/gerboweb/deploy/inventory.yml deleted file mode 100644 index 913ea5f..0000000 --- a/gerboweb/deploy/inventory.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -all: - hosts: - wendelstein: - ansible_host: wendelstein.jaseg.net - ansible_ssh_identity_file: ~/.ssh/id_ed25519 - ansible_user: root - ansible_python_interpreter: /usr/bin/python3 - localhost: - ansible_connection: local - ansible_python_interpreter: "{{ansible_playbook_python}}" diff --git a/gerboweb/deploy/iptables.rules b/gerboweb/deploy/iptables.rules deleted file mode 100644 index 620c4d3..0000000 --- a/gerboweb/deploy/iptables.rules +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by iptables-save v1.8.0 on Thu Apr 4 11:06:33 2019 -*nat -:PREROUTING ACCEPT [13:648] -:INPUT ACCEPT [8:440] -:OUTPUT ACCEPT [18:1260] -:POSTROUTING ACCEPT [18:1260] --A PREROUTING -i eth0 -p tcp -m tcp --dport 23 -j REDIRECT --to-ports 2342 -COMMIT -# Completed on Thu Apr 4 11:06:33 2019 -# Generated by iptables-save v1.8.0 on Thu Apr 4 11:06:33 2019 -*filter -:INPUT ACCEPT [0:0] -:FORWARD ACCEPT [0:0] -:OUTPUT ACCEPT [360:761646] --A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT --A INPUT -p icmp -j ACCEPT --A INPUT -i lo -j ACCEPT --A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT --A INPUT -p tcp -m state --state NEW -m tcp --dport 2342 -j ACCEPT --A INPUT -p tcp -m state --state NEW -m tcp --dport 23 -j ACCEPT --A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT --A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT --A INPUT -p udp --dport 53 -j ACCEPT --A INPUT -j REJECT --reject-with icmp-host-prohibited --A FORWARD -j REJECT --reject-with icmp-host-prohibited -COMMIT -# Completed on Thu Apr 4 11:06:33 2019 diff --git a/gerboweb/deploy/library/inwx-collection b/gerboweb/deploy/library/inwx-collection deleted file mode 160000 index 2928298..0000000 --- a/gerboweb/deploy/library/inwx-collection +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2928298f35d66d265679e8188029ce5834b28983 diff --git a/gerboweb/deploy/mirrorlist b/gerboweb/deploy/mirrorlist deleted file mode 100644 index a2fd58c..0000000 --- a/gerboweb/deploy/mirrorlist +++ /dev/null @@ -1,474 +0,0 @@ -## -## Arch Linux repository mirrorlist -## Generated on 2017-06-06 -## - -## Worldwide -#Server = https://archlinux.surlyjake.com/archlinux/$repo/os/$arch -#Server = http://mirrors.evowise.com/archlinux/$repo/os/$arch -Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch - -## Australia -#Server = https://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch -#Server = http://archlinux.mirror.digitalpacific.com.au/$repo/os/$arch -#Server = http://ftp.iinet.net.au/pub/archlinux/$repo/os/$arch -#Server = http://mirror.internode.on.net/pub/archlinux/$repo/os/$arch -#Server = http://ftp.swin.edu.au/archlinux/$repo/os/$arch -#Server = http://archlinux.uberglobalmirror.com/$repo/os/$arch - -## Austria -#Server = http://mirror.digitalnova.at/archlinux/$repo/os/$arch -#Server = http://mirror.easyname.at/archlinux/$repo/os/$arch -#Server = http://mirror1.htu.tugraz.at/archlinux/$repo/os/$arch - -## Belarus -#Server = http://ftp.byfly.by/pub/archlinux/$repo/os/$arch -#Server = http://mirror.datacenter.by/pub/archlinux/$repo/os/$arch - -## Belgium -#Server = http://archlinux.cu.be/$repo/os/$arch -#Server = http://archlinux.mirror.kangaroot.net/$repo/os/$arch - -## Bosnia and Herzegovina -#Server = http://burek.archlinux.ba/$repo/os/$arch -#Server = http://archlinux.mirror.ba/$repo/os/$arch - -## Brazil -#Server = http://br.mirror.archlinux-br.org/$repo/os/$arch -#Server = http://archlinux.c3sl.ufpr.br/$repo/os/$arch -#Server = http://linorg.usp.br/archlinux/$repo/os/$arch -#Server = http://pet.inf.ufsc.br/mirrors/archlinux/$repo/os/$arch -#Server = http://archlinux.pop-es.rnp.br/$repo/os/$arch - -## Bulgaria -#Server = http://mirror.host.ag/archlinux/$repo/os/$arch -#Server = http://mirrors.netix.net/archlinux/$repo/os/$arch -#Server = http://mirror.telepoint.bg/archlinux/$repo/os/$arch -#Server = http://mirrors.uni-plovdiv.net/archlinux/$repo/os/$arch -#Server = https://mirrors.uni-plovdiv.net/archlinux/$repo/os/$arch - -## Canada -#Server = http://mirror.cedille.club/archlinux/$repo/os/$arch -#Server = http://archlinux.mirror.colo-serv.net/$repo/os/$arch -#Server = http://mirror.csclub.uwaterloo.ca/archlinux/$repo/os/$arch -#Server = https://mirror.csclub.uwaterloo.ca/archlinux/$repo/os/$arch -#Server = http://mirror.frgl.pw/archlinux/$repo/os/$arch -#Server = https://mirror.frgl.pw/archlinux/$repo/os/$arch -#Server = http://mirror.its.dal.ca/archlinux/$repo/os/$arch -#Server = http://muug.ca/mirror/archlinux/$repo/os/$arch -#Server = https://muug.ca/mirror/archlinux/$repo/os/$arch -#Server = http://archlinux.mirror.rafal.ca/$repo/os/$arch - -## Chile -#Server = http://mirror.archlinux.cl/$repo/os/$arch - -## China -#Server = http://mirrors.163.com/archlinux/$repo/os/$arch -#Server = http://mirror.lzu.edu.cn/archlinux/$repo/os/$arch -#Server = http://mirrors.neusoft.edu.cn/archlinux/$repo/os/$arch -#Server = https://mirrors.skyshe.cn/archlinux/$repo/os/$arch -#Server = http://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch -#Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch -#Server = http://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch -#Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch -#Server = http://mirrors.xjtu.edu.cn/archlinux/$repo/os/$arch -#Server = https://mirrors.xjtu.edu.cn/archlinux/$repo/os/$arch -#Server = http://mirrors.zju.edu.cn/archlinux/$repo/os/$arch - -## Colombia -#Server = http://mirror.edatel.net.co/archlinux/$repo/os/$arch -#Server = http://mirror.upb.edu.co/archlinux/$repo/os/$arch - -## Croatia -#Server = http://archlinux.iskon.hr/$repo/os/$arch - -## Czech Republic -#Server = http://mirror.dkm.cz/archlinux/$repo/os/$arch -#Server = https://mirror.dkm.cz/archlinux/$repo/os/$arch -#Server = http://ftp.fi.muni.cz/pub/linux/arch/$repo/os/$arch -#Server = http://ftp.linux.cz/pub/linux/arch/$repo/os/$arch -#Server = http://gluttony.sin.cvut.cz/arch/$repo/os/$arch -#Server = https://gluttony.sin.cvut.cz/arch/$repo/os/$arch -#Server = http://mirrors.nic.cz/archlinux/$repo/os/$arch -#Server = http://ftp.sh.cvut.cz/arch/$repo/os/$arch -#Server = https://ftp.sh.cvut.cz/arch/$repo/os/$arch -#Server = http://mirror.vpsfree.cz/archlinux/$repo/os/$arch - -## Denmark -#Server = http://mirrors.dotsrc.org/archlinux/$repo/os/$arch -#Server = https://mirrors.dotsrc.org/archlinux/$repo/os/$arch -#Server = http://ftp.klid.dk/ftp/archlinux/$repo/os/$arch -#Server = http://mirror.one.com/archlinux/$repo/os/$arch -#Server = https://mirror.one.com/archlinux/$repo/os/$arch - -## Ecuador -#Server = http://mirror.cedia.org.ec/archlinux/$repo/os/$arch -#Server = http://mirror.espoch.edu.ec/archlinux/$repo/os/$arch -#Server = http://mirror.uta.edu.ec/archlinux/$repo/os/$arch - -## Finland -#Server = http://arch.mirror.far.fi/$repo/os/$arch - -## France -#Server = http://archlinux.de-labrusse.fr/$repo/os/$arch -#Server = http://mirror.archlinux.ikoula.com/archlinux/$repo/os/$arch -#Server = http://archlinux.vi-di.fr/$repo/os/$arch -#Server = https://archlinux.vi-di.fr/$repo/os/$arch -#Server = http://mirror.armbrust.me/archlinux/$repo/os/$arch -#Server = https://mirror.armbrust.me/archlinux/$repo/os/$arch -#Server = https://archlinux.ec-tech.fr/$repo/os/$arch -#Server = http://fooo.biz/archlinux/$repo/os/$arch -#Server = https://fooo.biz/archlinux/$repo/os/$arch -#Server = http://mirror.gerhard.re/archlinux/$repo/os/$arch -#Server = http://mirror.ibcp.fr/pub/archlinux/$repo/os/$arch -#Server = http://mirror.lastmikoi.net/archlinux/$repo/os/$arch -#Server = http://archlinux.mailtunnel.eu/$repo/os/$arch -#Server = https://www.mailtunnel.eu/archlinux/$repo/os/$arch -#Server = http://mir.archlinux.fr/$repo/os/$arch -#Server = http://archlinux.mirrors.ovh.net/archlinux/$repo/os/$arch -#Server = http://archlinux.mirror.pkern.at/$repo/os/$arch -#Server = https://archlinux.mirror.pkern.at/$repo/os/$arch -#Server = http://archlinux.polymorf.fr/$repo/os/$arch -#Server = http://mirrors.standaloneinstaller.com/archlinux/$repo/os/$arch -#Server = http://arch.tamcore.eu/$repo/os/$arch -#Server = http://mirror.tyborek.pl/arch/$repo/os/$arch -#Server = https://mirror.tyborek.pl/arch/$repo/os/$arch -#Server = http://ftp.u-strasbg.fr/linux/distributions/archlinux/$repo/os/$arch -#Server = https://mirror.wormhole.eu/archlinux/$repo/os/$arch -#Server = http://arch.yourlabs.org/$repo/os/$arch - -## Germany -#Server = http://mirror.23media.de/archlinux/$repo/os/$arch -#Server = https://arch.32g.eu/$repo/os/$arch -#Server = http://artfiles.org/archlinux.org/$repo/os/$arch -#Server = https://fabric-mirror.vps.hosteurope.de/archlinux/$repo/os/$arch -#Server = https://mirror.bethselamin.de/$repo/os/$arch -#Server = http://mirror.euserv.net/linux/archlinux/$repo/os/$arch -#Server = http://mirror.f4st.host/archlinux/$repo/os/$arch -#Server = https://mirror.f4st.host/archlinux/$repo/os/$arch -#Server = http://ftp.fau.de/archlinux/$repo/os/$arch -#Server = https://ftp.fau.de/archlinux/$repo/os/$arch -#Server = http://mirror.fluxent.de/archlinux/$repo/os/$arch -#Server = https://mirror.fluxent.de/archlinux/$repo/os/$arch -#Server = http://mirror.gnomus.de/$repo/os/$arch -#Server = http://www.gutscheindrache.com/mirror/archlinux/$repo/os/$arch -#Server = http://ftp.gwdg.de/pub/linux/archlinux/$repo/os/$arch -#Server = http://mirror.hactar.xyz/$repo/os/$arch -#Server = https://mirror.hactar.xyz/$repo/os/$arch -#Server = http://archlinux.honkgong.info/$repo/os/$arch -#Server = http://ftp.hosteurope.de/mirror/ftp.archlinux.org/$repo/os/$arch -#Server = http://ftp-stud.hs-esslingen.de/pub/Mirrors/archlinux/$repo/os/$arch -#Server = http://archlinux.mirror.iphh.net/$repo/os/$arch -#Server = http://repo.itmettke.de/archlinux/$repo/os/$arch -#Server = https://repo.itmettke.de/archlinux/$repo/os/$arch -#Server = https://mirror.jankoppe.de/archlinux/$repo/os/$arch -#Server = http://arch.jensgutermuth.de/$repo/os/$arch -#Server = https://arch.jensgutermuth.de/$repo/os/$arch -#Server = http://mirror.js-webcoding.de/pub/archlinux/$repo/os/$arch -#Server = https://mirror.js-webcoding.de/pub/archlinux/$repo/os/$arch -#Server = http://k42.ch/mirror/archlinux/$repo/os/$arch -#Server = https://k42.ch/mirror/archlinux/$repo/os/$arch -#Server = http://mirror.de.leaseweb.net/archlinux/$repo/os/$arch -Server = https://mirror.de.leaseweb.net/archlinux/$repo/os/$arch -#Server = http://mirror.loli.forsale/arch/$repo/os/$arch -#Server = https://mirror.loli.forsale/arch/$repo/os/$arch -#Server = http://mirror.metalgamer.eu/archlinux/$repo/os/$arch -#Server = https://mirror.metalgamer.eu/archlinux/$repo/os/$arch -#Server = http://mirror.michael-eckert.net/archlinux/$repo/os/$arch -#Server = https://mirror.michael-eckert.net/archlinux/$repo/os/$arch -#Server = http://mirrors.n-ix.net/archlinux/$repo/os/$arch -#Server = https://mirrors.n-ix.net/archlinux/$repo/os/$arch -#Server = http://mirror.netcologne.de/archlinux/$repo/os/$arch -Server = https://mirror.netcologne.de/archlinux/$repo/os/$arch -#Server = http://mirrors.niyawe.de/archlinux/$repo/os/$arch -#Server = https://mirrors.niyawe.de/archlinux/$repo/os/$arch -#Server = http://archlinux.nullpointer.io/$repo/os/$arch -#Server = https://archlinux.nullpointer.io/$repo/os/$arch -#Server = http://mirror.pseudoform.org/$repo/os/$arch -#Server = https://mirror.pseudoform.org/$repo/os/$arch -#Server = https://www.ratenzahlung.de/mirror/archlinux/$repo/os/$arch -#Server = http://ftp.halifax.rwth-aachen.de/archlinux/$repo/os/$arch -#Server = http://linux.rz.rub.de/archlinux/$repo/os/$arch -#Server = http://mirror.selfnet.de/archlinux/$repo/os/$arch -#Server = http://ftp.spline.inf.fu-berlin.de/mirrors/archlinux/$repo/os/$arch -#Server = https://ftp.spline.inf.fu-berlin.de/mirrors/archlinux/$repo/os/$arch -#Server = http://archlinux.thaller.ws/$repo/os/$arch -#Server = https://archlinux.thaller.ws/$repo/os/$arch -#Server = http://archlinux.thelinuxnetworx.rocks/$repo/os/$arch -#Server = https://archlinux.thelinuxnetworx.rocks/$repo/os/$arch -#Server = http://archmirror.tomforb.es/$repo/os/$arch -#Server = https://archmirror.tomforb.es/$repo/os/$arch -#Server = http://ftp.tu-chemnitz.de/pub/linux/archlinux/$repo/os/$arch -#Server = http://mirror.ubrco.de/archlinux/$repo/os/$arch -#Server = https://mirror.ubrco.de/archlinux/$repo/os/$arch -#Server = http://ftp.uni-bayreuth.de/linux/archlinux/$repo/os/$arch -#Server = http://ftp.uni-hannover.de/archlinux/$repo/os/$arch -#Server = http://ftp.uni-kl.de/pub/linux/archlinux/$repo/os/$arch -#Server = http://mirror.united-gameserver.de/archlinux/$repo/os/$arch -#Server = http://mirror.vfn-nrw.de/archlinux/$repo/os/$arch -#Server = https://mirror.vfn-nrw.de/archlinux/$repo/os/$arch - -## Greece -#Server = http://ftp.cc.uoc.gr/mirrors/linux/archlinux/$repo/os/$arch -#Server = http://foss.aueb.gr/mirrors/linux/archlinux/$repo/os/$arch -#Server = https://foss.aueb.gr/mirrors/linux/archlinux/$repo/os/$arch -#Server = http://mirrors.myaegean.gr/linux/archlinux/$repo/os/$arch -#Server = http://ftp.ntua.gr/pub/linux/archlinux/$repo/os/$arch -#Server = http://ftp.otenet.gr/linux/archlinux/$repo/os/$arch - -## Hong Kong -#Server = http://arch-mirror.wtako.net/$repo/os/$arch -#Server = https://arch-mirror.wtako.net/$repo/os/$arch - -## Hungary -#Server = http://ftp.energia.mta.hu/pub/mirrors/ftp.archlinux.org/$repo/os/$arch -#Server = http://archmirror.hbit.sztaki.hu/archlinux/$repo/os/$arch - -## Iceland -#Server = http://mirror.system.is/arch/$repo/os/$arch -#Server = https://mirror.system.is/arch/$repo/os/$arch - -## India -#Server = http://mirror.cse.iitk.ac.in/archlinux/$repo/os/$arch -#Server = http://ftp.iitm.ac.in/archlinux/$repo/os/$arch - -## Indonesia -#Server = http://mirror.devilzc0de.org/archlinux/$repo/os/$arch -#Server = http://mirror.poliwangi.ac.id/archlinux/$repo/os/$arch -#Server = http://suro.ubaya.ac.id/archlinux/$repo/os/$arch - -## Iran -#Server = http://repo.sadjad.ac.ir/arch/$repo/os/$arch -#Server = https://repo.sadjad.ac.ir/arch/$repo/os/$arch - -## Ireland -#Server = http://ftp.heanet.ie/mirrors/ftp.archlinux.org/$repo/os/$arch -#Server = https://ftp.heanet.ie/mirrors/ftp.archlinux.org/$repo/os/$arch - -## Israel -#Server = http://mirror.isoc.org.il/pub/archlinux/$repo/os/$arch - -## Italy -#Server = http://archlinux.prometeolibero.eu/archlinux/$repo/os/$arch -#Server = https://archlinux.prometeolibero.eu/archlinux/$repo/os/$arch -#Server = https://archlinux.beccacervello.it/archlinux/$repo/os/$arch -#Server = http://mi.mirror.garr.it/mirrors/archlinux/$repo/os/$arch -#Server = http://mirrors.prometeus.net/archlinux/$repo/os/$arch -#Server = http://archlinux.students.cs.unibo.it/$repo/os/$arch - -## Japan -#Server = http://ftp.tsukuba.wide.ad.jp/Linux/archlinux/$repo/os/$arch -Server = http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/$repo/os/$arch - -## Kazakhstan -#Server = http://mirror.neolabs.kz/archlinux/$repo/os/$arch - -## Latvia -#Server = http://archlinux.koyanet.lv/archlinux/$repo/os/$arch - -## Lithuania -#Server = http://mirrors.atviras.lt/archlinux/$repo/os/$arch -#Server = https://mirrors.atviras.lt/archlinux/$repo/os/$arch - -## Luxembourg -#Server = http://archlinux.mirror.root.lu/$repo/os/$arch - -## Macedonia -#Server = http://arch.softver.org.mk/archlinux/$repo/os/$arch -#Server = http://mirror.t-home.mk/archlinux/$repo/os/$arch -#Server = https://mirror.t-home.mk/archlinux/$repo/os/$arch - -## Netherlands -#Server = http://arch.apt-get.eu/$repo/os/$arch -#Server = http://mirror.i3d.net/pub/archlinux/$repo/os/$arch -#Server = https://mirror.i3d.net/pub/archlinux/$repo/os/$arch -#Server = http://mirror.nl.leaseweb.net/archlinux/$repo/os/$arch -#Server = https://mirror.nl.leaseweb.net/archlinux/$repo/os/$arch -#Server = http://mirror.netrouting.net/archlinux/$repo/os/$arch -#Server = http://ftp.nluug.nl/os/Linux/distr/archlinux/$repo/os/$arch -#Server = http://ftp.snt.utwente.nl/pub/os/linux/archlinux/$repo/os/$arch -#Server = http://archlinux.mirror.wearetriple.com/$repo/os/$arch -#Server = https://archlinux.mirror.wearetriple.com/$repo/os/$arch - -## New Caledonia -#Server = http://mirror.lagoon.nc/pub/archlinux/$repo/os/$arch -#Server = http://archlinux.nautile.nc/archlinux/$repo/os/$arch - -## New Zealand -#Server = https://mirror.smith.geek.nz/archlinux/$repo/os/$arch - -## Norway -#Server = http://mirror.archlinux.no/$repo/os/$arch -#Server = http://archlinux.uib.no/$repo/os/$arch -#Server = http://mirror.neuf.no/archlinux/$repo/os/$arch -#Server = https://mirror.neuf.no/archlinux/$repo/os/$arch - -## Philippines -#Server = http://mirror.rise.ph/archlinux/$repo/os/$arch - -## Poland -#Server = http://mirror.chmuri.net/archmirror/$repo/os/$arch -#Server = http://arch.midov.pl/arch/$repo/os/$arch -#Server = http://mirror.onet.pl/pub/mirrors/archlinux/$repo/os/$arch -#Server = http://piotrkosoft.net/pub/mirrors/ftp.archlinux.org/$repo/os/$arch -#Server = http://ftp.vectranet.pl/archlinux/$repo/os/$arch - -## Portugal -#Server = http://glua.ua.pt/pub/archlinux/$repo/os/$arch -#Server = https://glua.ua.pt/pub/archlinux/$repo/os/$arch -#Server = http://ftp.rnl.tecnico.ulisboa.pt/pub/archlinux/$repo/os/$arch - -## Qatar -#Server = http://mirror.qnren.qa/archlinux/$repo/os/$arch - -## Romania -#Server = http://mirror.archlinux.ro/archlinux/$repo/os/$arch -#Server = http://archlinux.mirrors.linux.ro/$repo/os/$arch -#Server = http://mirrors.m247.ro/archlinux/$repo/os/$arch -#Server = http://mirrors.pidginhost.com/arch/$repo/os/$arch - -## Russia -#Server = http://mirror.aur.rocks/$repo/os/$arch -#Server = https://mirror.aur.rocks/$repo/os/$arch -#Server = http://mirror.rol.ru/archlinux/$repo/os/$arch -#Server = https://mirror.rol.ru/archlinux/$repo/os/$arch -#Server = http://mirror.yandex.ru/archlinux/$repo/os/$arch -#Server = https://mirror.yandex.ru/archlinux/$repo/os/$arch - -## Serbia -#Server = http://mirror.pmf.kg.ac.rs/archlinux/$repo/os/$arch - -## Singapore -#Server = http://mirror.0x.sg/archlinux/$repo/os/$arch -#Server = http://download.nus.edu.sg/mirror/arch/$repo/os/$arch - -## Slovakia -#Server = http://mirror.lnx.sk/pub/linux/archlinux/$repo/os/$arch -#Server = https://mirror.lnx.sk/pub/linux/archlinux/$repo/os/$arch -#Server = http://tux.rainside.sk/archlinux/$repo/os/$arch - -## Slovenia -#Server = http://archimonde.ts.si/archlinux/$repo/os/$arch -#Server = https://archimonde.ts.si/archlinux/$repo/os/$arch - -## South Africa -#Server = http://za.mirror.archlinux-br.org/$repo/os/$arch -#Server = http://ftp.wa.co.za/pub/archlinux/$repo/os/$arch -#Server = http://mirror.is.co.za/mirror/archlinux.org/$repo/os/$arch -#Server = http://mirror.wbs.co.za/archlinux/$repo/os/$arch - -## South Korea -#Server = http://ftp.kaist.ac.kr/ArchLinux/$repo/os/$arch -#Server = http://mirror.premi.st/archlinux/$repo/os/$arch - -## Spain -#Server = http://osl.ugr.es/archlinux/$repo/os/$arch -#Server = http://sunsite.rediris.es/mirror/archlinux/$repo/os/$arch - -## Sweden -#Server = http://ftp.acc.umu.se/mirror/archlinux/$repo/os/$arch -#Server = https://ftp.acc.umu.se/mirror/archlinux/$repo/os/$arch -#Server = http://archlinux.dynamict.se/$repo/os/$arch -#Server = https://archlinux.dynamict.se/$repo/os/$arch -#Server = http://ftp.lysator.liu.se/pub/archlinux/$repo/os/$arch -#Server = https://ftp.lysator.liu.se/pub/archlinux/$repo/os/$arch -#Server = http://ftp.myrveln.se/pub/linux/archlinux/$repo/os/$arch -#Server = https://ftp.myrveln.se/pub/linux/archlinux/$repo/os/$arch -#Server = https://mirror.osbeck.com/archlinux/$repo/os/$arch -#Server = http://ftp.portlane.com/pub/os/linux/archlinux/$repo/os/$arch - -## Switzerland -#Server = http://pkg.adfinis-sygroup.ch/archlinux/$repo/os/$arch -#Server = https://pkg.adfinis-sygroup.ch/archlinux/$repo/os/$arch -#Server = http://archlinux.puzzle.ch/$repo/os/$arch - -## Taiwan -#Server = http://archlinux.cs.nctu.edu.tw/$repo/os/$arch -#Server = http://shadow.ind.ntou.edu.tw/archlinux/$repo/os/$arch -#Server = http://ftp.tku.edu.tw/Linux/ArchLinux/$repo/os/$arch -#Server = http://ftp.yzu.edu.tw/Linux/archlinux/$repo/os/$arch - -## Thailand -#Server = http://mirror.adminbannok.com/archlinux/$repo/os/$arch -#Server = http://mirror.kku.ac.th/archlinux/$repo/os/$arch -#Server = https://mirror.kku.ac.th/archlinux/$repo/os/$arch - -## Turkey -#Server = http://ftp.linux.org.tr/archlinux/$repo/os/$arch - -## Ukraine -#Server = http://archlinux.ip-connect.vn.ua/$repo/os/$arch -#Server = https://archlinux.ip-connect.vn.ua/$repo/os/$arch -#Server = http://mirrors.nix.org.ua/linux/archlinux/$repo/os/$arch -#Server = https://mirrors.nix.org.ua/linux/archlinux/$repo/os/$arch - -## United Kingdom -#Server = http://mirror.bytemark.co.uk/archlinux/$repo/os/$arch -#Server = http://mirrors.manchester.m247.com/arch-linux/$repo/os/$arch -#Server = http://www.mirrorservice.org/sites/ftp.archlinux.org/$repo/os/$arch -#Server = http://arch.serverspace.co.uk/arch/$repo/os/$arch -#Server = http://archlinux.mirrors.uk2.net/$repo/os/$arch - -## United States -#Server = http://mirrors.acm.wpi.edu/archlinux/$repo/os/$arch -#Server = http://mirrors.advancedhosters.com/archlinux/$repo/os/$arch -#Server = http://mirrors.aggregate.org/archlinux/$repo/os/$arch -#Server = http://ca.us.mirror.archlinux-br.org/$repo/os/$arch -#Server = http://il.us.mirror.archlinux-br.org/$repo/os/$arch -#Server = http://archlinux.surlyjake.com/archlinux/$repo/os/$arch -#Server = http://arlm.tyzoid.com/$repo/os/$arch -#Server = http://mirror.as65535.net/archlinux/$repo/os/$arch -#Server = http://mirrors.cat.pdx.edu/archlinux/$repo/os/$arch -#Server = http://mirror.cc.columbia.edu/pub/linux/archlinux/$repo/os/$arch -#Server = http://arch.mirror.constant.com/$repo/os/$arch -#Server = https://arch.mirror.constant.com/$repo/os/$arch -#Server = http://cosmos.cites.illinois.edu/pub/archlinux/$repo/os/$arch -#Server = http://mirror.cs.pitt.edu/archlinux/$repo/os/$arch -#Server = http://mirror.cs.vt.edu/pub/ArchLinux/$repo/os/$arch -#Server = http://mirror.epiphyte.network/archlinux/$repo/os/$arch -#Server = https://mirror.epiphyte.network/archlinux/$repo/os/$arch -#Server = http://mirror.es.its.nyu.edu/archlinux/$repo/os/$arch -#Server = http://mirrors.gigenet.com/archlinux/$repo/os/$arch -#Server = http://mirror.grig.io/archlinux/$repo/os/$arch -#Server = https://mirror.grig.io/archlinux/$repo/os/$arch -#Server = http://www.gtlib.gatech.edu/pub/archlinux/$repo/os/$arch -#Server = http://mirror1.hackingand.coffee/arch/$repo/os/$arch -#Server = http://mirror2.hackingand.coffee/arch/$repo/os/$arch -#Server = http://mirror3.hackingand.coffee/arch/$repo/os/$arch -#Server = http://mirror.htnshost.com/archlinux/$repo/os/$arch -#Server = http://mirror.jmu.edu/pub/archlinux/$repo/os/$arch -#Server = http://mirrors.kernel.org/archlinux/$repo/os/$arch -#Server = https://mirrors.kernel.org/archlinux/$repo/os/$arch -#Server = http://mirror.us.leaseweb.net/archlinux/$repo/os/$arch -#Server = https://mirror.us.leaseweb.net/archlinux/$repo/os/$arch -#Server = http://il.mirrors.linaxe.net/archlinux/$repo/os/$arch -#Server = http://mirrors.liquidweb.com/archlinux/$repo/os/$arch -#Server = http://arch.localmsp.org/arch/$repo/os/$arch -#Server = https://arch.localmsp.org/arch/$repo/os/$arch -#Server = http://mirror.lty.me/archlinux/$repo/os/$arch -#Server = https://mirror.lty.me/archlinux/$repo/os/$arch -#Server = http://mirrors.lug.mtu.edu/archlinux/$repo/os/$arch -#Server = https://mirrors.lug.mtu.edu/archlinux/$repo/os/$arch -#Server = http://mirror.math.princeton.edu/pub/archlinux/$repo/os/$arch -#Server = http://mirror.metrocast.net/archlinux/$repo/os/$arch -#Server = http://mirror.kaminski.io/archlinux/$repo/os/$arch -#Server = https://mirror.kaminski.io/archlinux/$repo/os/$arch -#Server = http://mirror.nexcess.net/archlinux/$repo/os/$arch -#Server = http://mirrors.ocf.berkeley.edu/archlinux/$repo/os/$arch -#Server = https://mirrors.ocf.berkeley.edu/archlinux/$repo/os/$arch -#Server = http://ftp.osuosl.org/pub/archlinux/$repo/os/$arch -#Server = http://arch.mirrors.pair.com/$repo/os/$arch -#Server = http://mirrors.rit.edu/archlinux/$repo/os/$arch -#Server = https://mirrors.rit.edu/archlinux/$repo/os/$arch -#Server = http://mirrors.rutgers.edu/archlinux/$repo/os/$arch -#Server = https://mirrors.rutgers.edu/archlinux/$repo/os/$arch -#Server = https://mirrors.tuxns.net/archlinux/$repo/os/$arch -#Server = http://mirror.umd.edu/archlinux/$repo/os/$arch -#Server = http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch -#Server = http://mirrors.xmission.com/archlinux/$repo/os/$arch -#Server = http://mirror.yellowfiber.net/archlinux/$repo/os/$arch - -## Vietnam -#Server = http://f.archlinuxvn.org/archlinux/$repo/os/$arch -#Server = http://mirror-fpt-telecom.fpt.net/archlinux/$repo/os/$arch - diff --git a/gerboweb/deploy/nginx.conf b/gerboweb/deploy/nginx.conf deleted file mode 100644 index f14f370..0000000 --- a/gerboweb/deploy/nginx.conf +++ /dev/null @@ -1,458 +0,0 @@ -# For more information on configuration, see: -# * Official English Documentation: http://nginx.org/en/docs/ -# * Official Russian Documentation: http://nginx.org/ru/docs/ - -user nginx; -worker_processes auto; -error_log /var/log/nginx/error.log; -pid /run/nginx.pid; - -# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. -include /usr/share/nginx/modules/*.conf; - -events { - worker_connections 1024; -} - -http { - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 4096; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - # Load modular configuration files from the /etc/nginx/conf.d directory. - # See http://nginx.org/en/docs/ngx_core_module.html#include - # for more information. - include /etc/nginx/conf.d/*.conf; - - server { - listen 80; - listen [::]:80; - server_name .jaseg.net; - return 301 https://$host$request_uri; - } - - server { - listen 443 ssl http2 default_server; - listen [::]:443 ssl http2 default_server; - server_name gerbolyze.jaseg.net; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/gerbolyze.jaseg.net/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/gerbolyze.jaseg.net/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location ^~ /static/ { - root /var/lib/gerboweb; - } - - location / { - include uwsgi_params; - uwsgi_pass unix:/run/uwsgi/gerboweb.socket; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name blog.jaseg.net; - - ssl_certificate "/etc/letsencrypt/live/blog.jaseg.net/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/blog.jaseg.net/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - return 301 https://blog.jaseg.de$request_uri; - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name blog.jaseg.de; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/blog.jaseg.de/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/blog.jaseg.de/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location / { - root /var/www/blog.jaseg.de; - } - - location /d/ { - access_log off; - log_not_found off; - rewrite ^/d/(.*)$ /$1 break; - include uwsgi_params; - uwsgi_pass unix:/run/uwsgi/secure-download.socket; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name automation.jaseg.de; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/automation.jaseg.de/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/automation.jaseg.de/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location / { - include uwsgi_params; - uwsgi_pass unix:/run/uwsgi/notification-proxy.socket; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name kochbuch.jaseg.net; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/kochbuch.jaseg.net/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/kochbuch.jaseg.net/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location / { - auth_basic "blubb"; - auth_basic_user_file /etc/nginx/kochbuch.htpasswd; - root /var/www/kochbuch.jaseg.net; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name pogojig.jaseg.net; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/pogojig.jaseg.net/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/pogojig.jaseg.net/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - client_max_body_size 10M; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location ^~ /pogospace/ { - root /var/lib/pogojig/pogospace; - } - - location / { - include uwsgi_params; - uwsgi_pass unix:/run/uwsgi/pogojig.socket; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name tracespace.jaseg.net; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/tracespace.jaseg.net/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/tracespace.jaseg.net/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location / { - root /var/www/tracespace.jaseg.net; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name openjscad.jaseg.net; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/openjscad.jaseg.net/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/openjscad.jaseg.net/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location / { - root /var/www/openjscad.jaseg.net; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name git.jaseg.net; - - ssl_certificate "/etc/letsencrypt/live/git.jaseg.net/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/git.jaseg.net/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - return 301 https://git.jaseg.de$request_uri; - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name git.jaseg.de; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/git.jaseg.de/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/git.jaseg.de/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location ~ ^/(cgit.css|robots.txt) { - root /usr/share/cgit; - expires 30d; - } - - location ~ ^/(cgit.png|favicon.png) { - alias /var/www/git.jaseg.de/cgit.png; - } - - location ~ ^/favicon.ico { - alias /var/www/git.jaseg.de/favicon.ico; - } - - location / { - include uwsgi_params; - uwsgi_modifier1 9; - uwsgi_pass unix:/run/uwsgi/cgit.socket; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } - - server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name dyndns.jaseg.de; - root /usr/share/nginx/html; - - ssl_certificate "/etc/letsencrypt/live/dyndns.jaseg.de/fullchain.pem"; - ssl_certificate_key "/etc/letsencrypt/live/dyndns.jaseg.de/privkey.pem"; - ssl_dhparam "/etc/letsencrypt/ssl-dhparams.pem"; - include /etc/letsencrypt/options-ssl-nginx.conf; - - ssl_stapling on; - ssl_stapling_verify on; - - resolver 67.207.67.2 67.207.67.3 valid=300s; - resolver_timeout 10s; - - add_header Strict-Transport-Security "max-age=86400"; - - # Load configuration files for the default server block. - include /etc/nginx/default.d/*.conf; - - location / { - include uwsgi_params; - uwsgi_pass unix:/run/uwsgi/dyndns.socket; - } - - error_page 404 /404.html; - location = /40x.html { - root /usr/share/nginx/html; - } - - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /usr/share/nginx/html; - } - } -} - diff --git a/gerboweb/deploy/nginx_nossl.conf b/gerboweb/deploy/nginx_nossl.conf deleted file mode 100644 index 87de478..0000000 --- a/gerboweb/deploy/nginx_nossl.conf +++ /dev/null @@ -1,59 +0,0 @@ -# For more information on configuration, see: -# * Official English Documentation: http://nginx.org/en/docs/ -# * Official Russian Documentation: http://nginx.org/ru/docs/ - -user nginx; -worker_processes auto; -error_log /var/log/nginx/error.log; -pid /run/nginx.pid; - -# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. -include /usr/share/nginx/modules/*.conf; - -events { - worker_connections 1024; -} - -http { - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 4096; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - # Load modular configuration files from the /etc/nginx/conf.d directory. - # See http://nginx.org/en/docs/ngx_core_module.html#include - # for more information. - include /etc/nginx/conf.d/*.conf; - - server { - listen 80 default_server; - listen [::]:80 default_server; - server_name gerbolyze.jaseg.net; - return 301 https://$host$request_uri; - } - - server { - listen 80; - listen [::]:80; - server_name blog.jaseg.net; - return 301 https://$host$request_uri; - } - - server { - listen 80; - listen [::]:80; - server_name blog.jaseg.de; - return 301 https://$host$request_uri; - } -} - diff --git a/gerboweb/deploy/notification_proxy.py b/gerboweb/deploy/notification_proxy.py deleted file mode 100644 index 117f8e1..0000000 --- a/gerboweb/deploy/notification_proxy.py +++ /dev/null @@ -1,179 +0,0 @@ -import smtplib -import ssl -import email.utils -import hmac -from email.mime.text import MIMEText -from datetime import datetime -import time -import functools -import json -import binascii -import uwsgidecorators - -import sqlite3 - -from flask import Flask, request, abort - -app = Flask(__name__) -app.config.from_pyfile('config.py') - -db = sqlite3.connect(app.config['SQLITE_DB'], check_same_thread=False) -with db as conn: - conn.execute('''CREATE TABLE IF NOT EXISTS seqs_seen - (route_name TEXT PRIMARY KEY, - seq INTEGER)''') - conn.execute('''CREATE TABLE IF NOT EXISTS time_seen - (route_name TEXT PRIMARY KEY)''') - - conn.execute('''CREATE TABLE IF NOT EXISTS heartbeats_seen - (route_name TEXT PRIMARY KEY, - timestamp INTEGER, - notified INTEGER)''') - # Clear table on startup to avoid spurious notifications - conn.execute('''DELETE FROM heartbeats_seen''') - -mail_routes = {} - -def mail_route(name, receiver, secret): - def wrap(func): - global routes - mail_routes[name] = (receiver, func, secret) - return func - return wrap - - -def authenticate(route_name, secret, clock_delta_tolerance:'s'=120): - with db as conn: - if not request.is_json: - print('Rejecting notification: Incorrect content type') - abort(400) - - if not 'auth' in request.json and 'payload' in request.json: - print('Rejecting notification: signature or payload not found') - abort(400) - - if not isinstance(request.json['auth'], str): - print('Rejecting notification: signature is of incorrect type') - abort(400) - their_digest = binascii.unhexlify(request.json['auth']) - - our_digest = hmac.digest(secret.encode('utf-8'), request.json['payload'].encode('utf-8'), 'sha256') - if not hmac.compare_digest(their_digest, our_digest): - print('Rejecting notification: Incorrect signature') - abort(403) - - try: - payload = json.loads(request.json['payload']) - except: - print('Rejecting notification: Payload is not JSON') - abort(400) - - last_seqnum = conn.execute('SELECT seq FROM seqs_seen WHERE route_name = ?', (route_name,)).fetchone() or 0 - # We can check for seq here: Only an attacker with knowledge of the secret would be able to remove - # seq from a message. This means for a single key, only messages with or without seq may ever be used. - if 'seq' in payload: - seq = payload['seq'] - if not isinstance(seq, int): - print('Rejecting notification: seq of wrong type') - abort(400) - - if seq <= last_seqnum: - print('Rejecting notification: seq out of order') - abort(400) - - conn.execute('INSERT OR REPLACE INTO seqs_seen VALUES (?, ?)', (route_name, seq)) - - elif last_seqnum: - print('Rejecting notification: seq not included but past messages included seq') - abort(400) - - msg_time = None - if 'time' in payload: - msg_time = payload['time'] - if not isinstance(msg_time, int): - print('Rejecting notification: time of wrong type') - abort(400) - - if abs(msg_time - int(time.time())) > clock_delta_tolerance: - print('Rejecting notification: timestamp too far in the future or past') - abort(400) - - conn.execute('INSERT OR REPLACE INTO time_seen VALUES (?)', (route_name,)) - - elif conn.execute('SELECT * FROM time_seen WHERE route_name = ?', (route_name,)).fetchone(): - print('Rejecting notification: time not included but past messages included time') - abort(400) - - if msg_time is None: - msg_time = int(time.time()) - - return msg_time, payload['scope'], payload['d'] - -@mail_route('klingel', 'computerstuff@jaseg.de', app.config['SECRET_KLINGEL']) -def klingel(classification='somewhere', rms=None, capture=None, **kwargs): - return (f'It rang {classification}!', - f'rms={rms}\ncapture={capture}\nextra_args={kwargs}') - - -def send_mail(route_name, receiver, subject, body): - try: - context = ssl.create_default_context() - smtp = smtplib.SMTP_SSL(app.config['SMTP_HOST'], app.config['SMTP_PORT']) - smtp.login('apikey', app.config['SENDGRID_APIKEY']) - - sender = f'{route_name}@{app.config["DOMAIN"]}' - - msg = MIMEText(body) - msg['Subject'] = subject - msg['From'] = sender - msg['To'] = receiver - msg['Date'] = email.utils.formatdate() - - smtp.sendmail(sender, receiver, msg.as_string()) - finally: - smtp.quit() - -@app.route('/v1/notify/', methods=['POST']) -def notify(route_name): - receiver, func, secret = mail_routes[route_name] - msg_time, scope, kwargs = authenticate(route_name, secret) - - if scope == 'default': - # Exceptions will yield a 500 error - subject, body = func(**kwargs) - send_mail(route_name, receiver, subject, body or 'empty message') - - elif scope == 'info': - send_mail(route_name, receiver, f'System info: {kwargs["info_msg"]}', f'Logged data: {kwargs}') - - elif scope == 'boot': - formatted = datetime.utcfromtimestamp(msg_time).isoformat() - send_mail(route_name, receiver, 'System startup', f'System powered up at {formatted}') - - elif scope == 'heartbeat': - with db as conn: - conn.execute('INSERT OR REPLACE INTO heartbeats_seen VALUES (?, ?, 0)', (route_name, int(time.time()))) - - elif scope == 'error': - print(f'Device error: {kwargs}') - - return 'success' - -@uwsgidecorators.timer(60) -def heartbeat_timer(_uwsgi_signum): - threshold = int(time.time()) - app.config['HEARTBEAT_TIMEOUT'] - with db as conn: - for route, ts in db.execute( - 'SELECT route_name, timestamp FROM heartbeats_seen WHERE timestamp <= ? AND notified == 0', - (threshold,)).fetchall(): - print(f'Heartbeat expired for {route}: {ts} < {threshold}') - - receiver, *_ = mail_routes[route] - last = datetime.utcfromtimestamp(ts).isoformat() - - send_mail(route, receiver, 'Heartbeat timeout', f'Last heartbeat at {last}') - db.execute('UPDATE heartbeats_seen SET notified = ? WHERE route_name = ?', (int(time.time()), route)) - -if __name__ == '__main__': - app.run() - diff --git a/gerboweb/deploy/notification_proxy_config.py.j2 b/gerboweb/deploy/notification_proxy_config.py.j2 deleted file mode 100644 index 2ecf571..0000000 --- a/gerboweb/deploy/notification_proxy_config.py.j2 +++ /dev/null @@ -1,9 +0,0 @@ - -SENDGRID_APIKEY = '{{lookup('file', 'notification_proxy_sendgrid_apikey.txt')}}' -DOMAIN = 'automation.jaseg.de' -SMTP_HOST = "smtp.sendgrid.net" -SMTP_PORT = 465 -HEARTBEAT_TIMEOUT = 300 -SQLITE_DB = '{{notification_proxy_sqlite_dbfile}}' - -SECRET_KLINGEL = '{{lookup('password', 'notification_proxy_klingel_secret.txt length=32')}}' diff --git a/gerboweb/deploy/nsd.conf b/gerboweb/deploy/nsd.conf deleted file mode 100644 index d4b577f..0000000 --- a/gerboweb/deploy/nsd.conf +++ /dev/null @@ -1,372 +0,0 @@ -# -# nsd.conf -- the NSD(8) configuration file, nsd.conf(5). -# -# Copyright (c) 2001-2011, NLnet Labs. All rights reserved. -# -# See LICENSE for the license. -# - -# This is a comment. -# Sample configuration file -# include: "file" # include that file's text over here. Globbed, "*.conf" - -# options for the nsd server -server: - # Number of NSD servers to fork. Put the number of CPUs to use here. - server-count: 1 - - # uncomment to specify specific interfaces to bind (default are the - # wildcard interfaces 0.0.0.0 and ::0). - # For servers with multiple IP addresses, list them one by one, - # or the source address of replies could be wrong. - # Use ip-transparent to be able to list addresses that turn on later. - # ip-address: 1.2.3.4 - # ip-address: 1.2.3.4@5678 - # ip-address: 12fe::8ef0 - - # Allow binding to non local addresses. Default no. - # ip-transparent: no - - # Allow binding to addresses that are down. Default no. - # ip-freebind: no - - # use the reuseport socket option for performance. Default no. - reuseport: yes - - # override maximum socket send buffer size. Default of 0 results in - # send buffer size being set to 1048576 (bytes). - # send-buffer-size: 1048576 - - # override maximum socket receive buffer size. Default of 0 results in - # receive buffer size being set to 1048576 (bytes). - # receive-buffer-size: 1048576 - - # enable debug mode, does not fork daemon process into the background. - # debug-mode: no - - # listen on IPv4 connections - # do-ip4: yes - - # listen on IPv6 connections - # do-ip6: yes - - # port to answer queries on. default is 53. - # port: 53 - - # Verbosity level. - # verbosity: 0 - - # After binding socket, drop user privileges. - # can be a username, id or id.gid. - # username: nsd - - # Run NSD in a chroot-jail. - # make sure to have pidfile and database reachable from there. - # by default, no chroot-jail is used. - # chroot: "/etc/nsd" - - # The directory for zonefile: files. The daemon chdirs here. - zonesdir: "/etc/nsd" - - # the list of dynamically added zones. - # zonelistfile: "/var/lib/nsd/zone.list" - - # the database to use - # if set to "" then no disk-database is used, less memory usage. - database: "" - - # log messages to file. Default to stderr and syslog (with - # facility LOG_DAEMON). stderr disappears when daemon goes to bg. - # logfile: "/var/log/nsd.log" - - # File to store pid for nsd in. - # pidfile: "/run/nsd/nsd.pid" - - # The file where secondary zone refresh and expire timeouts are kept. - # If you delete this file, all secondary zones are forced to be - # 'refreshing' (as if nsd got a notify). Set to "" to disable. - # xfrdfile: "/var/lib/nsd/ixfr.state" - - # The directory where zone transfers are stored, in a subdir of it. - # xfrdir: "/tmp" - - # don't answer VERSION.BIND and VERSION.SERVER CHAOS class queries - hide-version: yes - - # don't answer HOSTNAME.BIND and ID.SERVER CHAOS class queries - hide-identity: yes - - # version string the server responds with for chaos queries. - # default is 'NSD x.y.z' with the server's version number. - # version: "NSD" - - # identify the server (CH TXT ID.SERVER entry). - # identity: "unidentified server" - - # NSID identity (hex string, or "ascii_somestring"). default disabled. - # nsid: "aabbccdd" - - # Maximum number of concurrent TCP connections per server. - # tcp-count: 100 - - # Accept (and immediately close) TCP connections after maximum number - # of connections is reached to prevent kernel connection queue from - # growing. - # tcp-reject-overflow: no - - # Maximum number of queries served on a single TCP connection. - # By default 0, which means no maximum. - # tcp-query-count: 0 - - # Override the default (120 seconds) TCP timeout. - # tcp-timeout: 120 - - # Maximum segment size (MSS) of TCP socket on which the server - # responds to queries. Default is 0, system default MSS. - # tcp-mss: 0 - - # Maximum segment size (MSS) of TCP socket for outgoing AXFR request. - # Default is 0, system default MSS. - # outgoing-tcp-mss: 0 - - # Preferred EDNS buffer size for IPv4. - # ipv4-edns-size: 4096 - - # Preferred EDNS buffer size for IPv6. - # ipv6-edns-size: 4096 - - # statistics are produced every number of seconds. Prints to log. - # Default is 0, meaning no statistics are produced. - # statistics: 3600 - - # Number of seconds between reloads triggered by xfrd. - # xfrd-reload-timeout: 1 - - # log timestamp in ascii (y-m-d h:m:s.msec), yes is default. - # log-time-ascii: yes - - # round robin rotation of records in the answer. - round-robin: yes - - # minimal-responses only emits extra data for referrals. - minimal-responses: yes - - # Do not return additional information if the apex zone of the - # additional information is configured but does not match the apex zone - # of the initial query. - # confine-to-zone: no - - # refuse queries of type ANY. For stopping floods. - refuse-any: yes - - # check mtime of all zone files on start and sighup - # zonefiles-check: yes - - # write changed zonefiles to disk, every N seconds. - # default is 0(disabled) or 3600(if database is ""). - # zonefiles-write: 3600 - - # RRLconfig - # Response Rate Limiting, size of the hashtable. Default 1000000. - # rrl-size: 1000000 - - # Response Rate Limiting, maximum QPS allowed (from one query source). - # If set to 0, ratelimiting is disabled. Also set - # rrl-whitelist-ratelimit to 0 to disable ratelimit processing. - # Default is on. - # rrl-ratelimit: 200 - - # Response Rate Limiting, number of packets to discard before - # sending a SLIP response (a truncated one, allowing an honest - # resolver to retry with TCP). Default is 2 (one half of the - # queries will receive a SLIP response, 0 disables SLIP (all - # packets are discarded), 1 means every request will get a - # SLIP response. When the ratelimit is hit the traffic is - # divided by the rrl-slip value. - # rrl-slip: 2 - - # Response Rate Limiting, IPv4 prefix length. Addresses are - # grouped by netblock. - # rrl-ipv4-prefix-length: 24 - - # Response Rate Limiting, IPv6 prefix length. Addresses are - # grouped by netblock. - # rrl-ipv6-prefix-length: 64 - - # Response Rate Limiting, maximum QPS allowed (from one query source) - # for whitelisted types. Default is on. - # rrl-whitelist-ratelimit: 2000 - # RRLend - - # Optional local server config - include: "/etc/nsd/server.d/*.conf" - -# Include optional local configs. -include: "/etc/nsd/conf.d/*.conf" - -# Fedora: DNSTAP not yet enabled -# dnstap: - # set this to yes and set one or more of dnstap-log-..-messages to yes. - # dnstap-enable: no - # dnstap-socket-path: "/var/run/dnstap.sock" - # dnstap-send-identity: no - # dnstap-send-version: no - # dnstap-identity: "" - # dnstap-version: "" - # dnstap-log-auth-query-messages: no - # dnstap-log-auth-response-messages: no - - # Service clients over TLS (on the TCP sockets), with plain DNS inside - # the TLS stream. Give the certificate to use and private key. - # Default is "" (disabled). Requires restart to take effect. - # tls-service-key: "path/to/privatekeyfile.key" - # tls-service-pem: "path/to/publiccertfile.pem" - # tls-service-ocsp: "path/to/ocsp.pem" - # tls-port: 853 - -# Remote control config section. -remote-control: - # Enable remote control with nsd-control(8) here. - # set up the keys and certificates with nsd-control-setup. - control-enable: yes - - # what interfaces are listened to for control, default is on localhost. - # with an absolute path, a unix local named pipe is used for control - # (and key and cert files are not needed, use directory permissions). - # control-interface: 127.0.0.1 - # control-interface: ::1 - control-interface: /run/nsd/nsd.ctl - - # port number for remote control operations (uses TLS over TCP). - # control-port: 8952 - - # nsd server key file for remote control. - # server-key-file: "/etc/nsd/nsd_server.key" - - # nsd server certificate file for remote control. - # server-cert-file: "/etc/nsd/nsd_server.pem" - - # nsd-control key file. - # control-key-file: "/etc/nsd/nsd_control.key" - - # nsd-control certificate file. - # control-cert-file: "/etc/nsd/nsd_control.pem" - - -# Secret keys for TSIGs that secure zone transfers. -# You could include: "secret.keys" and put the 'key:' statements in there, -# and give that file special access control permissions. -# -# key: - # The key name is sent to the other party, it must be the same - #name: "keyname" - # algorithm hmac-md5, or sha1, sha256, sha224, sha384, sha512 - #algorithm: sha256 - # secret material, must be the same as the other party uses. - # base64 encoded random number. - # e.g. from dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64 - #secret: "K2tf3TRjvQkVCmJF3/Z9vA==" - - -# Patterns have zone configuration and they are shared by one or more zones. -# -# pattern: - # name by which the pattern is referred to - #name: "myzones" - # the zonefile for the zones that use this pattern. - # if relative then from the zonesdir (inside the chroot). - # the name is processed: %s - zone name (as appears in zone:name). - # %1 - first character of zone name, %2 second, %3 third. - # %z - topleveldomain label of zone, %y, %x next labels in name. - # if label or character does not exist you get a dot '.'. - # for example "%s.zone" or "zones/%1/%2/%3/%s" or "secondary/%z/%s" - #zonefile: "%s.zone" - - # If no master and slave access control elements are provided, - # this zone will not be served to/from other servers. - - # A master zone needs notify: and provide-xfr: lists. A slave - # may also allow zone transfer (for debug or other secondaries). - # notify these slaves when the master zone changes, address TSIG|NOKEY - # IP can be ipv4 and ipv6, with @port for a nondefault port number. - #notify: 192.0.2.1 NOKEY - # allow these IPs and TSIG to transfer zones, addr TSIG|NOKEY|BLOCKED - # address range 192.0.2.0/24, 1.2.3.4&255.255.0.0, 3.0.2.20-3.0.2.40 - #provide-xfr: 192.0.2.0/24 my_tsig_key_name - # set the number of retries for notify. - #notify-retry: 5 - - # uncomment to provide AXFR to all the world - # provide-xfr: 0.0.0.0/0 NOKEY - # provide-xfr: ::0/0 NOKEY - - # A slave zone needs allow-notify: and request-xfr: lists. - #allow-notify: 2001:db8::0/64 my_tsig_key_name - # By default, a slave will request a zone transfer with IXFR/TCP. - # If you want to make use of IXFR/UDP use: UDP addr tsigkey - # for a master that only speaks AXFR (like NSD) use AXFR addr tsigkey - #request-xfr: 192.0.2.2 the_tsig_key_name - # Attention: You cannot use UDP and AXFR together. AXFR is always over - # TCP. If you use UDP, we higly recommend you to deploy TSIG. - # Allow AXFR fallback if the master does not support IXFR. Default - # is yes. - #allow-axfr-fallback: yes - # set local interface for sending zone transfer requests. - # default is let the OS choose. - #outgoing-interface: 10.0.0.10 - # limit the refresh and retry interval in seconds. - #max-refresh-time: 2419200 - #min-refresh-time: 0 - #max-retry-time: 1209600 - #min-retry-time: 0 - - # Slave server tries zone transfer to all masters and picks highest - # zone version available, for when masters have different versions. - #multi-master-check: no - - # limit the zone transfer size (in bytes), stops very large transfers - # 0 is no limits enforced. - # size-limit-xfr: 0 - - # if compiled with --enable-zone-stats, give name of stat block for - # this zone (or group of zones). Output from nsd-control stats. - # zonestats: "%s" - - # if you give another pattern name here, at this point the settings - # from that pattern are inserted into this one (as if it were a - # macro). The statement can be given in between other statements, - # because the order of access control elements can make a difference - # (which master to request from first, which slave to notify first). - #include-pattern: "common-masters" - - -# Fixed zone entries. Here you can config zones that cannot be deleted. -# Zones that are dynamically added and deleted are put in the zonelist file. -# -# zone: - # name: "example.com" - # you can give a pattern here, all the settings from that pattern - # are then inserted at this point - # include-pattern: "master" - # You can also specify (additional) options directly for this zone. - # zonefile: "example.com.zone" - # request-xfr: 192.0.2.1 example.com.key - - # RRLconfig - # Response Rate Limiting, whitelist types - # rrl-whitelist: nxdomain - # rrl-whitelist: error - # rrl-whitelist: referral - # rrl-whitelist: any - # rrl-whitelist: rrsig - # rrl-whitelist: wildcard - # rrl-whitelist: nodata - # rrl-whitelist: dnskey - # rrl-whitelist: positive - # rrl-whitelist: all - # RRLend - -zone: - name: "dyn.jaseg.de" - zonefile: "/var/lib/dyndns/dyn.jaseg.de.zone" - diff --git a/gerboweb/deploy/playbook.yml b/gerboweb/deploy/playbook.yml deleted file mode 100644 index a34e8fe..0000000 --- a/gerboweb/deploy/playbook.yml +++ /dev/null @@ -1,166 +0,0 @@ -- name: DNS setup - hosts: localhost - tags: dns - module_defaults: - inwx: - username: "{{lookup('ini', 'user section=inwx file=credentials.ini')}}" - password: "{{lookup('ini', 'pass section=inwx file=credentials.ini')}}" - vars: - subdomains: - - git.jaseg.net - - git.jaseg.de - - blog.jaseg.net - - blog.jaseg.de - - kochbuch.jaseg.net - - gerbolyze.jaseg.net - - tracespace.jaseg.net - - openjscad.jaseg.net - - pogojig.jaseg.net - - automation.jaseg.de - - dyndns.jaseg.de - fastmail_domains: - - jaseg.net - - jaseg.de - tasks: - - name: Gather wendelstein facts - setup: - delegate_to: wendelstein - delegate_facts: True - - - name: Setup DNS - include_tasks: dns.yml - - -- name: Wendelstein setup - hosts: wendelstein - tasks: - - name: Set hostname - tags: setup - hostname: - name: wendelstein.jaseg.net - - - name: Install common admin tools - tags: setup - dnf: - name: htop,tmux,fish,mosh,neovim,sqlite - state: latest - - - name: Install host requisites - tags: setup - dnf: - name: nginx,uwsgi,python3-flask,python3-flask-wtf,uwsgi-plugin-python3,certbot,python3-certbot-nginx,python3-libselinux,git,iptables-services,python3-pycryptodomex,zip,python3-uwsgidecorators,nsd - state: latest - - - name: Disable password-based root login - tags: setup - lineinfile: - path: /etc/ssh/sshd_config - regexp: '^PermitRootLogin' - line: 'PermitRootLogin without-password' - register: disable_root_pw_ssh - - - name: Restart sshd - tags: setup - systemd: - name: sshd - state: restarted - when: disable_root_pw_ssh is changed - - - name: Configure iptables firewall service - tags: setup - copy: - src: iptables.rules - dest: /etc/sysconfig/iptables - owner: root - group: root - mode: 0664 - - - name: Enable iptables firewall service - tags: setup - systemd: - name: iptables - enabled: yes - state: started - - - name: Create containers - tags: setup - include_tasks: - file: setup_containers.yml - apply: - tags: setup - vars: - containers: - - gerboweb - - clippy - - pogojig - - - name: Setup web server - tags: www - include_tasks: - file: setup_webserver.yml - apply: - tags: www - - - name: Setup gerboweb - tags: gerboweb - include_tasks: - file: setup_gerboweb.yml - apply: - tags: gerboweb - - - name: Setup clippy - tags: clippy - include_tasks: - file: setup_clippy.yml - apply: - tags: clippy - - - name: Setup secure download - tags: secure-download - include_tasks: - file: setup_secure_download.yml - apply: - tags: secure-download - - - name: Setup tracespace - tags: pogojig - include_tasks: - file: setup_tracespace.yml - apply: - tags: pogojig - - - name: Setup openjscad - tags: pogojig - include_tasks: - file: setup_openjscad.yml - apply: - tags: pogojig - - - name: Setup pogojig - tags: pogojig - include_tasks: - file: setup_pogojig.yml - apply: - tags: pogojig - - - name: Setup notification proxy - tags: notification-proxy - include_tasks: - file: setup_notification_proxy.yml - apply: - tags: - notification-proxy - - - name: Setup semi-public git server - tags: git - include_tasks: - file: setup_git.yml - apply: - tags: git - - - name: Setup private DynDNS service - tags: dyndns - include_tasks: - file: setup_dyndns.yml - apply: - tags: dyndns diff --git a/gerboweb/deploy/pogojig-job-processor.service.j2 b/gerboweb/deploy/pogojig-job-processor.service.j2 deleted file mode 100644 index 5ca9a8b..0000000 --- a/gerboweb/deploy/pogojig-job-processor.service.j2 +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Pogojig render job processor - -[Service] -WorkingDirectory=/var/lib/pogojig -ExecStart=/usr/bin/python3 job_processor.py {{pogojig_cache}}/job_queue.sqlite3 - -[Install] -WantedBy=uwsgi-app@pogojig.service diff --git a/gerboweb/deploy/pogojig.cfg.j2 b/gerboweb/deploy/pogojig.cfg.j2 deleted file mode 100644 index 3dd7160..0000000 --- a/gerboweb/deploy/pogojig.cfg.j2 +++ /dev/null @@ -1,4 +0,0 @@ -MAX_CONTENT_LENGTH=10000000 -SECRET_KEY="{{lookup('password', 'pogojig_flask_secret.txt length=32')}}" -UPLOAD_PATH="{{pogojig_cache}}/upload" -JOB_QUEUE_DB="{{pogojig_cache}}/job_queue.sqlite3" diff --git a/gerboweb/deploy/pogojig_generate.sh.j2 b/gerboweb/deploy/pogojig_generate.sh.j2 deleted file mode 100755 index c1cc023..0000000 --- a/gerboweb/deploy/pogojig_generate.sh.j2 +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -[ $# != 1 ] && exit 1 -ID=$1 -egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 - -systemd-nspawn \ - -D {{pogojig_root}} \ - -x --bind={{pogojig_cache}}/upload/$ID:/mnt \ - /bin/sh -c "set -euo pipefail -cd /mnt - -date; echo 'Cleaning up previous output' -rm -rf pcb_shape.dxf jig.stl kicad kicad.zip sources.zip - -date; echo 'Rendering' -cp -r /var/lib/pogojig_renderer sources -cp input.svg sources/ -make -C sources - -date; echo 'Packing source bundle' -cp -r sources/out/pcb_shape.dxf sources/out/jig.stl sources/out/kicad ./ -zip -r sources.zip sources -zip -r kicad.zip kicad -rm -rf sources" diff --git a/gerboweb/deploy/render.sh.j2 b/gerboweb/deploy/render.sh.j2 deleted file mode 100755 index ceb837d..0000000 --- a/gerboweb/deploy/render.sh.j2 +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -[ $# != 1 ] && exit 1 -ID=$1 -egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 - -systemd-nspawn \ - -D {{gerboweb_root}} \ - -x --bind={{gerboweb_cache}}/upload/$ID:/mnt \ - /bin/sh -c "set -euo pipefail -unzip -j -d /tmp/gerber /mnt/gerber.zip -rm -f /mnt/render_top.png /mnt/render_bottom.png /mnt/render_top.small.png /mnt/render_bottom.small.png -date; echo 'Rendering bottom layer' -gerbolyze render top /tmp/gerber /mnt/render_top.png -date; echo 'Scaling down' -convert /mnt/render_top.png -resize 500x500 -negate -brightness-contrast 30x30 -colorspace gray /mnt/render_top.small.png -date; echo 'Rendering top layer' -gerbolyze render bottom /tmp/gerber /mnt/render_bottom.png -date; echo 'Scaling down' -convert /mnt/render_bottom.png -resize 500x500 -negate -brightness-contrast 30x30 -colorspace gray /mnt/render_bottom.small.png" diff --git a/gerboweb/deploy/secure_download.cfg.j2 b/gerboweb/deploy/secure_download.cfg.j2 deleted file mode 100644 index 36d86c1..0000000 --- a/gerboweb/deploy/secure_download.cfg.j2 +++ /dev/null @@ -1 +0,0 @@ -SERVE_PATH="{{secure_download_dir}}" diff --git a/gerboweb/deploy/setup_clippy.yml b/gerboweb/deploy/setup_clippy.yml deleted file mode 100644 index 26142b6..0000000 --- a/gerboweb/deploy/setup_clippy.yml +++ /dev/null @@ -1,85 +0,0 @@ ---- -- name: Clone pixelterm git - git: - repo: https://github.com/jaseg/pixelterm - dest: "{{clippy_root}}/var/lib/pixelterm.git" - -- name: Clone clippy git - git: - repo: https://github.com/jaseg/clippy - dest: "{{clippy_root}}/var/lib/clippy.git" - -- name: Setup required packages for clippy - command: arch-chroot "{{clippy_root}}" pacman -Syu --noconfirm python3 python-pip python-numpy python-pillow - -- name: Setup pixelterm - command: arch-chroot "{{clippy_root}}" sh -c "cd /var/lib/pixelterm.git && python3 setup.py install" - -- name: Setup container clippy systemd service file - template: - src: clippy.service.j2 - dest: "{{clippy_root}}/etc/systemd/system/clippy.service" - owner: root - group: root - mode: 0664 - -- name: Enable systemd machines target - systemd: - name: machines.target - enabled: yes - -- name: Copy over clippy container auto boot service file - copy: - src: clippy-nspawn.service - dest: /etc/systemd/system/clippy-nspawn.service - owner: root - group: root - mode: 0664 - -- name: Create systemd-nspawn config dir - file: - path: /etc/systemd/nspawn - state: directory - owner: root - group: root - mode: 0775 - -- name: Copy over clippy container config - copy: - src: clippy.nspawn - dest: /etc/systemd/nspawn/clippy.nspawn - owner: root - group: root - mode: 0664 - -- name: Enable clippy container auto boot - systemd: - daemon-reload: yes - name: clippy-nspawn.service - enabled: yes - -- name: Restart clippy container - shell: | - systemctl stop clippy-nspawn - sleep 1 - systemctl start clippy-nspawn - for x in $(seq 0 30); do - systemctl -M clippy is-system-running && exit - sleep 1 - done - -- name: Enable clippy systemd service in container - command: systemctl enable -M clippy clippy.service - -- name: Restart clippy systemd service in container - command: systemctl restart -M clippy clippy.service - -#- name: Enable host networkd -# systemd: -# name: systemd-networkd -# enabled: yes -# state: started - -#- name: Enable clippy container networkd -# command: systemctl enable -M clippy systemd-networkd - diff --git a/gerboweb/deploy/setup_containers.yml b/gerboweb/deploy/setup_containers.yml deleted file mode 100644 index 8adb9da..0000000 --- a/gerboweb/deploy/setup_containers.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: Install host requisites - dnf: - name: btrfs-progs,arch-install-scripts,systemd-container,python3-libselinux - state: latest - -- name: Create individual containers - include_tasks: bootstrap_arch_container.yml - with_items: "{{ containers }}" - loop_control: - loop_var: container - -- name: Cleanup bootstrap image - file: - path: /tmp/arch-bootstrap.tar.xz - state: absent - diff --git a/gerboweb/deploy/setup_dyndns.yml b/gerboweb/deploy/setup_dyndns.yml deleted file mode 100644 index d9735c7..0000000 --- a/gerboweb/deploy/setup_dyndns.yml +++ /dev/null @@ -1,80 +0,0 @@ ---- -- name: Set local facts - set_fact: - dyndns_sqlite_dbfile: /var/lib/dyndns/db.sqlite3 - -- name: Copy nsd config - copy: - src: nsd.conf - dest: /etc/nsd/nsd.conf - owner: root - group: root - mode: 0644 - -- name: Enable and launch nsd systemd service - systemd: - name: nsd.service - enabled: yes - state: restarted - -- name: Create dyndns worker user and group - user: - name: uwsgi-dyndns - create_home: no - group: uwsgi - password: '!' - shell: /sbin/nologin - system: yes - -- name: Allow dyndns app to kick nsd - lineinfile: - path: /etc/sudoers - line: 'uwsgi-dyndns ALL=(nsd) NOPASSWD: /usr/sbin/nsd-control reload dyn.jaseg.de' - -- name: Create webapp dir - file: - path: /var/lib/dyndns - state: directory - owner: uwsgi-dyndns - group: nsd - mode: 0750 - -- name: Copy webapp sources - copy: - src: dyndns.py - dest: /var/lib/dyndns/ - owner: uwsgi-dyndns - group: uwsgi - mode: 0440 - -- name: Template webapp config - template: - src: dyndns_config.py.j2 - dest: /var/lib/dyndns/config.py - owner: uwsgi-dyndns - group: root - mode: 0660 - -- name: Copy uwsgi config - copy: - src: uwsgi-dyndns.ini - dest: /etc/uwsgi.d/dyndns.ini - owner: uwsgi-dyndns - group: uwsgi - mode: 0440 - -- name: Enable uwsgi systemd socket - systemd: - daemon-reload: yes - name: uwsgi-app@dyndns.socket - enabled: yes - -- name: Create sqlite db file - file: - path: "{{dyndns_sqlite_dbfile}}" - owner: uwsgi-dyndns - group: uwsgi - mode: 0660 - state: touch - - diff --git a/gerboweb/deploy/setup_gerboweb.yml b/gerboweb/deploy/setup_gerboweb.yml deleted file mode 100644 index 6a20eed..0000000 --- a/gerboweb/deploy/setup_gerboweb.yml +++ /dev/null @@ -1,100 +0,0 @@ ---- -- name: Set local facts - set_fact: - gerboweb_cache: /var/cache/gerboweb - -- name: Copy render script - template: - src: render.sh.j2 - dest: /usr/local/sbin/gerbolyze_render.sh - mode: ug+x - -- name: Copy vector script - template: - src: vector.sh.j2 - dest: /usr/local/sbin/gerbolyze_vector.sh - mode: ug+x - -- name: Install packages into gerbolyze container - shell: arch-chroot "{{gerboweb_root}}" pacman -Syu --noconfirm python3 opencv hdf5 gtk3 python-numpy python-pip imagemagick unzip zip - -- name: Workaround for cairoffi problem - shell: arch-chroot "{{gerboweb_root}}" pip install -U --upgrade-strategy=eager wheel - - # TODO maybe install directly from local git checkout? -- name: Install gerbolyze - shell: arch-chroot "{{gerboweb_root}}" pip install -U --upgrade-strategy=eager gerbolyze - -- name: Copy webapp sources - synchronize: - # FIXME: make this path configurable - src: ~/gerbolyze/gerboweb/ - dest: /var/lib/gerboweb/ - rsync_opts: - - "--exclude=/deploy" - group: no - owner: no - -- name: Create uwsgi worker user and group - user: - name: uwsgi-gerboweb - create_home: no - group: uwsgi - password: '!' - shell: /sbin/nologin - system: yes - -- name: Template webapp config - template: - src: gerboweb.cfg.j2 - dest: /var/lib/gerboweb/gerboweb_prod.cfg - owner: uwsgi-gerboweb - group: root - mode: 0660 - -- name: Copy uwsgi config - copy: - src: uwsgi-gerboweb.ini - dest: /etc/uwsgi.d/gerboweb.ini - owner: uwsgi-gerboweb - group: uwsgi - mode: 0440 - -- name: Copy job processor systemd service config - template: - src: gerboweb-job-processor.service.j2 - dest: /etc/systemd/system/gerboweb-job-processor.service - -- name: Enable uwsgi systemd socket - systemd: - daemon-reload: yes - name: uwsgi-app@gerboweb.socket - enabled: yes - -- name: Copy gerboweb cache dir tmpfiles.d config - template: - src: tmpfiles-gerboweb.conf.j2 - dest: /etc/tmpfiles.d/gerboweb.conf - owner: root - group: root - mode: 0644 - register: tmpfiles_config - -- name: Kick systemd tmpfiles service to create cache dir - command: systemd-tmpfiles --create - when: tmpfiles_config is changed - -- name: Create job queue db - file: - path: "{{gerboweb_cache}}/job_queue.sqlite3" - owner: root - group: uwsgi - mode: 0660 - state: touch - -- name: Enable and launch job processor - systemd: - name: gerboweb-job-processor.service - enabled: yes - state: restarted - diff --git a/gerboweb/deploy/setup_git.yml b/gerboweb/deploy/setup_git.yml deleted file mode 100644 index 2f4c59f..0000000 --- a/gerboweb/deploy/setup_git.yml +++ /dev/null @@ -1,134 +0,0 @@ -- name: Install host requisites - dnf: - name: cgit,gitolite3,python3-pygments,python3-docutils,nodejs-markdown,python3-markdown - state: latest - -- name: Copy cgit logo - copy: - src: cgit-logo.png - dest: /var/www/git.jaseg.de/cgit.png - -- name: Copy cgit favicon - copy: - src: cgit-favicon.ico - dest: /var/www/git.jaseg.de/favicon.ico - -- name: Create cgit instance config dir - file: - path: /var/lib/cgit - state: directory - mode: 0755 - -- name: Copy cgit rc - copy: - src: cgitrc - dest: /var/lib/cgit/cgitrc-gitolite-public - mode: 0644 - -- name: Create uwsgi worker user and group - user: - name: uwsgi-cgit - create_home: no - group: uwsgi - password: '!' - shell: /sbin/nologin - system: yes - -- name: Copy uwsgi config - copy: - src: uwsgi-cgit.ini - dest: /etc/uwsgi.d/cgit.ini - owner: uwsgi-cgit - group: uwsgi - mode: 0440 - -- name: Enable uwsgi systemd socket - systemd: - daemon-reload: yes - name: uwsgi-app@cgit.socket - enabled: yes - -- name: Check if gitolite ssh config exists - stat: - path: /var/lib/gitolite3/.ssh/authorized_keys - register: gitolite_ssh_keys_stat - -- name: Gitolite admin key setup - block: - - name: Copy gitolite admin pubkey - copy: - src: ~/.ssh/id_ed25519.gitolite.pub - dest: /tmp/jaseg-gitolite.pub - owner: gitolite3 - group: gitolite3 - - - name: Run gitolite initialization - command: gitolite setup -pk /tmp/jaseg-gitolite.pub - become: true - become_method: su - become_user: gitolite3 - become_flags: '-s /bin/sh' - args: - creates: /var/lib/gitolite3/projects.list - - - name: Remove leftover admin pubkey - file: - state: absent - path: /tmp/jaseg-gitolite.pub - when: not gitolite_ssh_keys_stat.stat.exists - -- name: Allow uwsgi group to access gitolite repo dir - file: - path: /var/lib/gitolite3 - state: directory - owner: gitolite3 - group: uwsgi - -- name: Add cgit uwsgi user to gitolite group - user: - name: uwsgi-cgit - groups: gitolite3 - append: yes - -- name: Allow cgit uwsgi user to access gitolite repos - file: - path: /var/lib/gitolite3/repositories - mode: 0750 - -- name: Allow cgit uwsgi user to gitolite repo list - file: - path: /var/lib/gitolite3/projects.list - mode: 0640 - -- name: Copy gitolite rc - copy: - src: gitolite.rc - dest: /var/lib/gitolite3/.gitolite.rc - owner: gitolite3 - group: gitolite3 - mode: 0600 - -- name: Query system user account info - getent: - database: passwd - key: gitolite3 - -- name: Create git alias user - user: - name: git - create_home: no - group: gitolite3 - password: '!' - comment: Alias for gitolite3 user - shell: "{{ getent_passwd['gitolite3'][5] }}" - system: yes - non_unique: yes - home: "{{ getent_passwd['gitolite3'][4] }}" - uid: "{{ getent_passwd['gitolite3'][1] }}" - -- name: Hack to fix cgit handling for restructuredtext readmes - file: - src: /usr/bin/rst2html - dest: /usr/bin/rst2html.py - state: link - diff --git a/gerboweb/deploy/setup_notification_proxy.yml b/gerboweb/deploy/setup_notification_proxy.yml deleted file mode 100644 index b47af05..0000000 --- a/gerboweb/deploy/setup_notification_proxy.yml +++ /dev/null @@ -1,61 +0,0 @@ ---- -- name: Set local facts - set_fact: - notification_proxy_sqlite_dbfile: /var/lib/notification-proxy/db.sqlite3 - -- name: Create notification proxy worker user and group - user: - name: uwsgi-notification-proxy - create_home: no - group: uwsgi - password: '!' - shell: /sbin/nologin - system: yes - -- name: Create webapp dir - file: - path: /var/lib/notification-proxy - state: directory - owner: uwsgi-notification-proxy - group: uwsgi - mode: 0750 - -- name: Copy webapp sources - copy: - src: notification_proxy.py - dest: /var/lib/notification-proxy/ - owner: uwsgi-notification-proxy - group: uwsgi - mode: 0440 - -- name: Template webapp config - template: - src: notification_proxy_config.py.j2 - dest: /var/lib/notification-proxy/config.py - owner: uwsgi-notification-proxy - group: root - mode: 0660 - -- name: Copy uwsgi config - copy: - src: uwsgi-notification-proxy.ini - dest: /etc/uwsgi.d/notification-proxy.ini - owner: uwsgi-notification-proxy - group: uwsgi - mode: 0440 - -- name: Enable uwsgi systemd socket - systemd: - daemon-reload: yes - name: uwsgi-app@notification-proxy.socket - enabled: yes - -- name: Create sqlite db file - file: - path: "{{notification_proxy_sqlite_dbfile}}" - owner: uwsgi-notification-proxy - group: uwsgi - mode: 0660 - state: touch - - diff --git a/gerboweb/deploy/setup_openjscad.yml b/gerboweb/deploy/setup_openjscad.yml deleted file mode 100644 index dea4ad2..0000000 --- a/gerboweb/deploy/setup_openjscad.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Copy openjscad webapp sources - synchronize: - # FIXME: make this path configurable - src: ~/openjscad_dist/ - dest: /var/www/openjscad.jaseg.net/ - group: no - owner: no - diff --git a/gerboweb/deploy/setup_pogojig.yml b/gerboweb/deploy/setup_pogojig.yml deleted file mode 100644 index cf49fbe..0000000 --- a/gerboweb/deploy/setup_pogojig.yml +++ /dev/null @@ -1,125 +0,0 @@ ---- -- name: Set local facts - set_fact: - pogojig_cache: /var/cache/pogojig - -- name: Copy render script - template: - src: pogojig_generate.sh.j2 - dest: /usr/local/sbin/pogojig_generate.sh - mode: ug+x - -- name: Install packages into pogojig container - shell: arch-chroot "{{pogojig_root}}" pacman -Syu --noconfirm python3 python-pip imagemagick unzip zip openscad inkscape make python-lxml xorg-server-xvfb - -- name: Install python dependencies into pogojig container - shell: arch-chroot "{{pogojig_root}}" pip install -U --upgrade-strategy=eager ezdxf xvfbwrapper - -- name: Install pogojig - synchronize: - # FIXME: make this path configurable - src: checkouts/pogojig/renderer/ - dest: "{{pogojig_root}}/var/lib/pogojig_renderer" - group: no - -- name: Copy webapp sources - synchronize: - # FIXME: make this path configurable - src: checkouts/pogojig/webapp/ - dest: /var/lib/pogojig - delete: true - group: no - owner: no - -- name: Pack makefile template zip - archive: - path: "{{pogojig_root}}/var/lib/pogojig_renderer" - dest: /var/lib/pogojig/static/pogojig_makefile_template.zip - format: zip - -- name: Create web home for modified tracespace - file: - path: /var/lib/pogojig/pogospace - state: directory - owner: nginx - group: nginx - mode: 0550 - -- name: Unpack modified tracespace sources - unarchive: - src: resource/pogojig-tracespace.tar.gz - dest: /var/lib/pogojig/pogospace - extra_opts: [--strip-components=1] - owner: nginx - group: nginx - -- name: Create uwsgi worker user and group - user: - name: uwsgi-pogojig - create_home: no - group: uwsgi - password: '!' - shell: /sbin/nologin - system: yes - -- name: Template webapp config - template: - src: pogojig.cfg.j2 - dest: /var/lib/pogojig/pogojig_prod.cfg - owner: uwsgi-pogojig - group: root - mode: 0660 - -- name: Copy uwsgi config - copy: - src: uwsgi-pogojig.ini - dest: /etc/uwsgi.d/pogojig.ini - owner: uwsgi-pogojig - group: uwsgi - mode: 440 - -- name: Copy job processor systemd service config - template: - src: pogojig-job-processor.service.j2 - dest: /etc/systemd/system/pogojig-job-processor.service - -- name: Enable uwsgi systemd socket - systemd: - daemon-reload: yes - name: uwsgi-app@pogojig.socket - enabled: yes - -# FIXME the socket doesn't seem to work properly -- name: Enable uwsgi systemd service - systemd: - daemon-reload: yes - name: uwsgi-app@pogojig.service - enabled: yes - -- name: Copy pogojig cache dir tmpfiles.d config - template: - src: tmpfiles-pogojig.conf.j2 - dest: /etc/tmpfiles.d/pogojig.conf - owner: root - group: root - mode: 0644 - register: pogojig_tmpfiles_config - -- name: Kick systemd tmpfiles service to create cache dir - command: systemd-tmpfiles --create - when: pogojig_tmpfiles_config is changed - -- name: Create job queue db - file: - path: "{{pogojig_cache}}/job_queue.sqlite3" - owner: root - group: uwsgi - mode: 0660 - state: touch - -- name: Enable and launch job processor - systemd: - name: pogojig-job-processor.service - enabled: yes - state: restarted - diff --git a/gerboweb/deploy/setup_secure_download.yml b/gerboweb/deploy/setup_secure_download.yml deleted file mode 100644 index aa94a53..0000000 --- a/gerboweb/deploy/setup_secure_download.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- -- name: Set local facts - set_fact: - secure_download_dir: /var/cache/secure_download - -- name: Copy webapp sources - synchronize: - # FIXME: make this path configurable - src: ~/secure_download/ - dest: /var/lib/secure_download/ - group: no - owner: no - -- name: Create secure download worker user and group - user: - name: uwsgi-secure-download - create_home: no - group: uwsgi - password: '!' - shell: /sbin/nologin - system: yes - -- name: Template webapp config - template: - src: secure_download.cfg.j2 - dest: /var/lib/secure_download/secure_download_prod.cfg - owner: uwsgi-secure-download - group: root - mode: 0660 - -- name: Copy uwsgi config - copy: - src: uwsgi-secure-download.ini - dest: /etc/uwsgi.d/secure-download.ini - owner: uwsgi-secure-download - group: uwsgi - mode: 440 - -- name: Enable uwsgi systemd socket - systemd: - daemon-reload: yes - name: uwsgi-app@secure-download.socket - enabled: yes - -- name: Copy server dir tmpfiles.d config - template: - src: tmpfiles-secure-download.conf.j2 - dest: /etc/tmpfiles.d/secure-download.conf - owner: root - group: root - mode: 0644 - register: sec_dl_tmpfiles_config - -- name: Kick systemd tmpfiles service to create serve dir - command: systemd-tmpfiles --create - when: sec_dl_tmpfiles_config is changed - diff --git a/gerboweb/deploy/setup_tracespace.yml b/gerboweb/deploy/setup_tracespace.yml deleted file mode 100644 index 2975967..0000000 --- a/gerboweb/deploy/setup_tracespace.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: Copy tracespace webapp sources - synchronize: - # FIXME: make this path configurable - src: ~/tracespace_dist/ - dest: /var/www/tracespace.jaseg.net/ - group: no - owner: no - diff --git a/gerboweb/deploy/setup_webserver.yml b/gerboweb/deploy/setup_webserver.yml deleted file mode 100644 index 4711ad0..0000000 --- a/gerboweb/deploy/setup_webserver.yml +++ /dev/null @@ -1,79 +0,0 @@ -- name: Copy first stage nginx config - copy: - src: nginx_nossl.conf - dest: /etc/nginx/nginx.conf - -- name: Add nginx user to uwsgi group for access to uwsgi socket - user: - name: nginx - groups: uwsgi - append: yes - -- name: Create subdomain content dirs - file: - path: /var/www/{{item}} - state: directory - owner: nginx - group: nginx - mode: 0550 - loop: - - git.jaseg.de - - blog.jaseg.de - - kochbuch.jaseg.net - - tracespace.jaseg.net - - openjscad.jaseg.net - - automation.jaseg.de - -- name: Copy uwsgi systemd socket config - copy: - src: uwsgi-app@.socket - dest: /etc/systemd/system/ - -- name: Copy uwsgi systemd service config - copy: - src: uwsgi-app@.service - dest: /etc/systemd/system/ - -- name: Set SELinux to permissive mode # FIXME this is to let nginx talk to uwsgi - selinux: - state: permissive - policy: targeted - -- name: Enable and launch nginx systemd service - systemd: - name: nginx.service - enabled: yes - state: restarted - -- name: Create subdomain letsencrypt certificates - command: certbot --nginx certonly -d {{item}} -n --agree-tos --email {{item}}-letsencrypt@jaseg.de - args: - creates: /etc/letsencrypt/live/{{item}}/fullchain.pem - loop: - - git.jaseg.net - - git.jaseg.de - - blog.jaseg.net - - blog.jaseg.de - - kochbuch.jaseg.net - - gerbolyze.jaseg.net - - tracespace.jaseg.net - - openjscad.jaseg.net - - pogojig.jaseg.net - - automation.jaseg.de - - dyndns.jaseg.de - -- name: Copy final nginx config - copy: - src: nginx.conf - dest: /etc/nginx/nginx.conf - -- name: Restart nginx to load new cert - systemd: - name: nginx.service - state: restarted - -- name: Enable certbot renewal timer - systemd: - name: certbot-renew.timer - enabled: yes - diff --git a/gerboweb/deploy/tmpfiles-gerboweb.conf.j2 b/gerboweb/deploy/tmpfiles-gerboweb.conf.j2 deleted file mode 100644 index 18469b7..0000000 --- a/gerboweb/deploy/tmpfiles-gerboweb.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -d {{gerboweb_cache}} 770 uwsgi-gerboweb uwsgi 2d diff --git a/gerboweb/deploy/tmpfiles-pogojig.conf.j2 b/gerboweb/deploy/tmpfiles-pogojig.conf.j2 deleted file mode 100644 index 4e9fef1..0000000 --- a/gerboweb/deploy/tmpfiles-pogojig.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -d {{pogojig_cache}} 770 uwsgi-pogojig uwsgi 2d diff --git a/gerboweb/deploy/tmpfiles-secure-download.conf.j2 b/gerboweb/deploy/tmpfiles-secure-download.conf.j2 deleted file mode 100644 index 84d7add..0000000 --- a/gerboweb/deploy/tmpfiles-secure-download.conf.j2 +++ /dev/null @@ -1 +0,0 @@ -d {{secure_download_dir}} 770 uwsgi-download uwsgi 45d diff --git a/gerboweb/deploy/uwsgi-app@.service b/gerboweb/deploy/uwsgi-app@.service deleted file mode 100644 index bdae8fd..0000000 --- a/gerboweb/deploy/uwsgi-app@.service +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -Description=%i uWSGI app -After=syslog.target - -[Service] -ExecStart=/usr/sbin/uwsgi \ - --ini /etc/uwsgi.d/%i.ini \ - --chmod-socket=660 \ - --socket=/run/uwsgi/%i.socket -User=uwsgi-%i -Group=uwsgi -Restart=on-failure -KillSignal=SIGQUIT -Type=notify -StandardError=syslog -NotifyAccess=all diff --git a/gerboweb/deploy/uwsgi-app@.socket b/gerboweb/deploy/uwsgi-app@.socket deleted file mode 100644 index ae06d71..0000000 --- a/gerboweb/deploy/uwsgi-app@.socket +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Socket for uWSGI app %i - -[Socket] -ListenStream=/run/uwsgi/%i.socket -SocketUser=uwsgi-%i -SocketGroup=nginx -SocketMode=0660 - -[Install] -WantedBy=sockets.target diff --git a/gerboweb/deploy/uwsgi-cgit.ini b/gerboweb/deploy/uwsgi-cgit.ini deleted file mode 100644 index 9a10350..0000000 --- a/gerboweb/deploy/uwsgi-cgit.ini +++ /dev/null @@ -1,8 +0,0 @@ -[uwsgi] -master = True -plugins = cgi -chdir = /var/lib/gitolite3 -processes = 1 -threads = 2 -cgi = /var/www/cgi-bin/cgit -env = CGIT_CONFIG=/var/lib/cgit/cgitrc-gitolite-public diff --git a/gerboweb/deploy/uwsgi-dyndns.ini b/gerboweb/deploy/uwsgi-dyndns.ini deleted file mode 100644 index b62e2af..0000000 --- a/gerboweb/deploy/uwsgi-dyndns.ini +++ /dev/null @@ -1,10 +0,0 @@ -[uwsgi] -master = True -cheap = True -die-on-idle = False -manage-script-name = True -log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) [URI hidden] => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core)) -plugins = python3 -chdir = /var/lib/dyndns -mount = /=dyndns:app - diff --git a/gerboweb/deploy/uwsgi-gerboweb.ini b/gerboweb/deploy/uwsgi-gerboweb.ini deleted file mode 100644 index 155d01a..0000000 --- a/gerboweb/deploy/uwsgi-gerboweb.ini +++ /dev/null @@ -1,10 +0,0 @@ -[uwsgi] -master = True -cheap = True -die-on-idle = False -manage-script-name = True -plugins = python3 -chdir = /var/lib/gerboweb -mount = /=gerboweb:app -env = GERBOWEB_SETTINGS=gerboweb_prod.cfg - diff --git a/gerboweb/deploy/uwsgi-notification-proxy.ini b/gerboweb/deploy/uwsgi-notification-proxy.ini deleted file mode 100644 index aab2b5a..0000000 --- a/gerboweb/deploy/uwsgi-notification-proxy.ini +++ /dev/null @@ -1,10 +0,0 @@ -[uwsgi] -master = True -cheap = True -die-on-idle = False -manage-script-name = True -log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) [URI hidden] => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core)) -plugins = python3 -chdir = /var/lib/notification-proxy -mount = /=notification_proxy:app - diff --git a/gerboweb/deploy/uwsgi-pogojig.ini b/gerboweb/deploy/uwsgi-pogojig.ini deleted file mode 100644 index 003702d..0000000 --- a/gerboweb/deploy/uwsgi-pogojig.ini +++ /dev/null @@ -1,10 +0,0 @@ -[uwsgi] -master = True -cheap = True -die-on-idle = False -manage-script-name = True -plugins = python3 -chdir = /var/lib/pogojig -mount = /=pogojig:app -env = POGOJIG_SETTINGS=pogojig_prod.cfg - diff --git a/gerboweb/deploy/uwsgi-secure-download.ini b/gerboweb/deploy/uwsgi-secure-download.ini deleted file mode 100644 index 4a4aa65..0000000 --- a/gerboweb/deploy/uwsgi-secure-download.ini +++ /dev/null @@ -1,11 +0,0 @@ -[uwsgi] -master = True -cheap = True -die-on-idle = False -manage-script-name = True -log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) [URI hidden] => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core)) -plugins = python3 -chdir = /var/lib/secure_download -mount = /=server:app -env = SECURE_DOWNLOAD_SETTINGS=secure_download_prod.cfg - diff --git a/gerboweb/deploy/vector.sh.j2 b/gerboweb/deploy/vector.sh.j2 deleted file mode 100755 index b17116e..0000000 --- a/gerboweb/deploy/vector.sh.j2 +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -[ $# != 2 ] && exit 1 -ID=$1 -egrep -x -q '^[-0-9A-Za-z]{36}$'<<<"$ID" || exit 2 -LAYER=$2 -egrep -x -q '^(top|bottom)$'<<<"$LAYER" || exit 2 - -systemd-nspawn \ - -D {{gerboweb_root}} \ - -x --bind={{gerboweb_cache}}/upload/$ID:/mnt \ - /bin/sh -c "set -euo pipefail -cd /tmp -unzip -j -d gerber_in /mnt/gerber.zip -gerbolyze vectorize $LAYER gerber_in gerber /mnt/overlay.png -rm -f /mnt/gerber_out.zip -zip -r /mnt/gerber_out.zip gerber" - -- cgit