Compare commits
194 Commits
Author | SHA1 | Date | |
---|---|---|---|
9bbfef4c39 | |||
b796f72abc | |||
22e4b4d5a4 | |||
7fbdfac786 | |||
131e84bd17 | |||
2906fb1b88 | |||
e9bd63decb | |||
9c6215d9a1 | |||
aa539af15d | |||
3dbafe08e7 | |||
d081a79f6d | |||
419686eb0c | |||
aa2b945765 | |||
e49b97a80a | |||
07b479d3bf | |||
9ec1a876d1 | |||
2a8ef46357 | |||
a3a5a19710 | |||
cf1a632e3e | |||
d8e801a178 | |||
df3d9c644f | |||
fb351a2e8d | |||
ad9a9e679f | |||
3a6fe46e26 | |||
6928c45106 | |||
057ca6edba | |||
3020a43ca2 | |||
3b36350faf | |||
759d7a1ccb | |||
c4bea59899 | |||
f680d0cefa | |||
e29cf10b03 | |||
b720c1224b | |||
44ae248e72 | |||
698f3f0329 | |||
fe2aba1e74 | |||
5c258c0b8b | |||
f47d06eded | |||
6e25befe64 | |||
b023e6bcba | |||
bbe295aea9 | |||
df4791a3b1 | |||
f363952d13 | |||
9b08a69426 | |||
4912d1f9e8 | |||
3b9343debf | |||
fab63e3eee | |||
7a178b29af | |||
937621ae7e | |||
f36a545c93 | |||
20b3218aab | |||
87138d7b1e | |||
c88a02c101 | |||
04eeda81c7 | |||
8afe3e0524 | |||
6e1039893d | |||
051903761c | |||
f7d9892205 | |||
e358a0d1a4 | |||
bf16d9d763 | |||
90aca411aa | |||
31ea1683aa | |||
6923776886 | |||
bcd6f3bf1a | |||
26bc3d7d61 | |||
084258ee6c | |||
b0dc51e14c | |||
e20bf87831 | |||
c68a84082f | |||
c9553bf7e5 | |||
35b2cd330c | |||
9ae12826a8 | |||
5df1659c6f | |||
a894b9eff5 | |||
e314f788e7 | |||
c3a29bef55 | |||
cfe496dcb7 | |||
d0c61e4847 | |||
20c220ffee | |||
20665dc119 | |||
0a3136a291 | |||
ffd7a943f4 | |||
a8ac5aa872 | |||
c99432ea52 | |||
ee7acd7c1b | |||
2c4b9a8546 | |||
c6a7db63d7 | |||
30be2871f2 | |||
1432f7e50d | |||
bb5d6b632e | |||
0b8d7d92ae | |||
8fe0e155d3 | |||
aaccd2356b | |||
5ca65d3410 | |||
c6e71ec9e9 | |||
d0899c6c81 | |||
b67aaf5aa3 | |||
34bf219bde | |||
a0e38dd2ef | |||
66528553a3 | |||
09a8c3fb60 | |||
7222724254 | |||
363f26fe3e | |||
990832b664 | |||
b0a6084bd6 | |||
fa4c50301c | |||
554fbb6afd | |||
fbc4c7115d | |||
ac4ddd5c18 | |||
e01813e8d4 | |||
564d834865 | |||
2b74d3d58e | |||
8d3959c30f | |||
a6961ff0c3 | |||
d23e961b70 | |||
666bb63477 | |||
06da04bb5c | |||
8a1821c416 | |||
6fcef0ce11 | |||
6425917e1c | |||
ebd51c2d54 | |||
2cb4922ffb | |||
744f521684 | |||
327c48ab68 | |||
5dfb0bd0b7 | |||
a72f41d56e | |||
d865915b40 | |||
b58f935123 | |||
6b52682f57 | |||
aa95981741 | |||
cea59cbb28 | |||
f9a8603770 | |||
7f8fcbde52 | |||
e10bbd74f8 | |||
8378656cb7 | |||
2d58181837 | |||
d6510fbd9b | |||
d529a0fc14 | |||
886e536f08 | |||
c0ccf94ac5 | |||
eab16418c8 | |||
f7f260687a | |||
cd91d1d165 | |||
c151237ac0 | |||
5b633c04ed | |||
63ff3e500b | |||
18878ee14a | |||
9488645cef | |||
1fbe690f7f | |||
462797e135 | |||
a744eae7b8 | |||
ee41b9b69e | |||
83d300260c | |||
b3954d5257 | |||
efb4329e73 | |||
b91a5163c6 | |||
125be40daf | |||
39a5ba03c8 | |||
8d6207186f | |||
2c7b38da0a | |||
8deb3583d4 | |||
152cbeaff8 | |||
60f20f7d6f | |||
e25153d118 | |||
4801a792b6 | |||
2efd79e1e4 | |||
5317325ab0 | |||
384177911c | |||
0247a036a9 | |||
50ea242c33 | |||
41099802c2 | |||
112e77ce67 | |||
6d242de66d | |||
8db0e145c4 | |||
5921aaa5bb | |||
f126cfc597 | |||
f5353973c2 | |||
2d589bf19f | |||
dc63b52b14 | |||
8f9ba57983 | |||
956141ae7b | |||
99f8f53326 | |||
56f49276b0 | |||
ee547ad4c4 | |||
148e343cc0 | |||
d80c31f3ca | |||
cd791c4298 | |||
873ce9b590 | |||
1b1994c12c | |||
3534b16cbc | |||
c44522d06a | |||
6640239616 | |||
e9e287ebec | |||
eafc98b394 |
446
.drone.yml
446
.drone.yml
@ -6,61 +6,376 @@ name: pull
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: fedora-hugo
|
||||
pull: always
|
||||
image: immawanderer/fedora-hugo:latest
|
||||
commands:
|
||||
- uname -r
|
||||
- cat /etc/fedora-release
|
||||
trigger:
|
||||
event:
|
||||
exclude: [push, pull_request]
|
||||
|
||||
- name: alpine-rsync
|
||||
pull: always
|
||||
image: immawanderer/alpine-rsync:latest
|
||||
commands:
|
||||
- uname -r
|
||||
steps:
|
||||
- name: alpine-hugo
|
||||
pull: always
|
||||
image: docker.io/immawanderer/alpine-hugo:hugo-v0.115.3
|
||||
commands:
|
||||
- hugo version
|
||||
|
||||
- name: alpine-rsync
|
||||
pull: always
|
||||
image: docker.io/immawanderer/alpine-rsync:latest
|
||||
commands:
|
||||
- uname -r
|
||||
|
||||
- name: hadolint
|
||||
pull: always
|
||||
image: docker.io/hadolint/hadolint:2.10.0-alpine
|
||||
commands:
|
||||
- uname -r
|
||||
- hadolint --version
|
||||
|
||||
- name: golang
|
||||
pull: always
|
||||
image: docker.io/library/golang:1.21.0-alpine3.18
|
||||
commands:
|
||||
- uname -r
|
||||
- go version
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: build
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
branch: [master, testing]
|
||||
event: pull_request
|
||||
|
||||
depends_on:
|
||||
- pull
|
||||
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
|
||||
steps:
|
||||
- name: submodules
|
||||
image: docker.io/alpine/git:v2.36.2
|
||||
depends_on: [clone]
|
||||
commands:
|
||||
- git submodule init
|
||||
- git submodule update --recursive
|
||||
|
||||
- name: hugo-extended
|
||||
pull: always
|
||||
image: docker.io/immawanderer/alpine-hugo:hugo-v0.115.3
|
||||
depends_on: [submodules]
|
||||
commands:
|
||||
- hugo version
|
||||
- hugo --gc=true --minify
|
||||
|
||||
- name: go fmt
|
||||
image: docker.io/library/golang:1.21.0-alpine3.18
|
||||
volumes:
|
||||
- name: gopath
|
||||
path: /go
|
||||
depends_on:
|
||||
- clone
|
||||
commands:
|
||||
- go fmt
|
||||
|
||||
- name: go vet
|
||||
image: docker.io/library/golang:1.21.--alpine3.18
|
||||
volumes:
|
||||
- name: gopath
|
||||
path: /go
|
||||
depends_on:
|
||||
- go fmt
|
||||
commands:
|
||||
- go vet
|
||||
|
||||
- name: go build
|
||||
pull: if-not-exists
|
||||
image: docker.io/library/golang:1.21.0-alpine3.18
|
||||
volumes:
|
||||
- name: gopath
|
||||
path: /go
|
||||
depends_on:
|
||||
- go vet
|
||||
# wait until the site is output into './public'.
|
||||
- hugo-extended
|
||||
environment:
|
||||
GOFLAGS: -trimpath -mod=readonly -modcacherw
|
||||
commands:
|
||||
- go build -v -ldflags "-s -w -X main.Version=${DRONE_COMMIT}" .
|
||||
|
||||
volumes:
|
||||
- name: gopath
|
||||
temp: {}
|
||||
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: 'build and deploy'
|
||||
name: docker-compose-build
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
branch: master
|
||||
event: pull_request
|
||||
|
||||
depends_on:
|
||||
- pull
|
||||
- build
|
||||
|
||||
steps:
|
||||
- name: hugo-extended
|
||||
pull: if-not-exists
|
||||
image: immawanderer/fedora-hugo:latest
|
||||
when:
|
||||
status:
|
||||
- success
|
||||
commands:
|
||||
- git submodule init
|
||||
- git submodule update
|
||||
- hugo version
|
||||
- hugo --gc=true --minify
|
||||
- name: hadolint
|
||||
image: docker.io/hadolint/hadolint:v2.10.0-alpine
|
||||
depends_on: [clone]
|
||||
commands:
|
||||
- hadolint --version
|
||||
- hadolint Dockerfile
|
||||
|
||||
- name: deploy
|
||||
pull: if-not-exists
|
||||
image: immawanderer/alpine-rsync:latest
|
||||
when:
|
||||
status:
|
||||
- success
|
||||
depends_on:
|
||||
- hugo-extended
|
||||
environment:
|
||||
OL:
|
||||
from_secret: hugo_user
|
||||
OL_P:
|
||||
from_secret: hugo_passwd
|
||||
OL_D:
|
||||
from_secret: hugo_dir
|
||||
commands:
|
||||
- echo $OL_P > nupass
|
||||
- export RSYNC_RSH='sshpass -f ./nupass ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
||||
- rsync -av --delete --chown $OL public/ $OL@dotya.ml:$OL_D
|
||||
- name: check compose
|
||||
pull: always
|
||||
image: docker.io/tmaier/docker-compose:latest
|
||||
depends_on: [clone]
|
||||
volumes:
|
||||
- name: s
|
||||
path: /var/run/docker.sock
|
||||
environment:
|
||||
COMPOSE_DOCKER_CLI_BUILD: 1
|
||||
DOCKER_BUILDKIT: 1
|
||||
commands:
|
||||
- docker compose -f docker-compose.yml config -q
|
||||
|
||||
- name: build
|
||||
pull: always
|
||||
image: docker.io/tmaier/docker-compose:latest
|
||||
depends_on: [hadolint, check compose]
|
||||
volumes:
|
||||
- name: s
|
||||
path: /var/run/docker.sock
|
||||
environment:
|
||||
COMPOSE_DOCKER_CLI_BUILD: 1
|
||||
DOCKER_BUILDKIT: 1
|
||||
commands:
|
||||
- docker compose build --build-arg VCS_REF=${DRONE_COMMIT} --no-cache --pull
|
||||
|
||||
volumes:
|
||||
- name: s
|
||||
host:
|
||||
path: /run/docker.sock
|
||||
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: deploy-staging
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- testing
|
||||
event:
|
||||
exclude: [pull_request, tag]
|
||||
|
||||
depends_on:
|
||||
- build
|
||||
|
||||
steps:
|
||||
- name: submodules
|
||||
image: docker.io/alpine/git:v2.36.2
|
||||
depends_on: [clone]
|
||||
commands:
|
||||
- git submodule init
|
||||
- git submodule update --recursive
|
||||
|
||||
- name: hugo-extended
|
||||
pull: always
|
||||
image: docker.io/immawanderer/alpine-hugo:hugo-v0.115.3
|
||||
depends_on: [submodules]
|
||||
commands:
|
||||
- hugo version
|
||||
- hugo --gc=true --minify
|
||||
|
||||
- name: deploy
|
||||
pull: if-not-exists
|
||||
image: docker.io/library/alpine:3.15.0
|
||||
when:
|
||||
status:
|
||||
- success
|
||||
branch:
|
||||
- testing
|
||||
depends_on:
|
||||
- hugo-extended
|
||||
environment:
|
||||
OL:
|
||||
from_secret: hugo_user
|
||||
OL_P:
|
||||
from_secret: hugo_passwd
|
||||
OL_D:
|
||||
from_secret: hugo_dir
|
||||
commands:
|
||||
- apk update
|
||||
- apk -U upgrade --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing
|
||||
- apk add --no-cache ca-certificates rsync openssh-client sshpass --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing
|
||||
- echo $OL_P > nupass
|
||||
- export RSYNC_RSH='sshpass -f ./nupass ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
|
||||
- rsync -av --delete --chown $OL public/ $OL@dotya.ml:$OL_D
|
||||
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: deploy
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
exclude: [pull_request, tag]
|
||||
|
||||
environment:
|
||||
# ref: https://www.docker.com/blog/faster-builds-in-compose-thanks-to-buildkit-support/
|
||||
COMPOSE_DOCKER_CLI_BUILD: 1
|
||||
DOCKER_BUILDKIT: 1
|
||||
|
||||
node:
|
||||
r: main
|
||||
|
||||
depends_on:
|
||||
- build
|
||||
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
|
||||
steps:
|
||||
- name: submodules
|
||||
image: docker.io/alpine/git:v2.36.2
|
||||
depends_on: [clone]
|
||||
commands:
|
||||
- git submodule init
|
||||
- git submodule update --recursive
|
||||
|
||||
- name: hugo-extended
|
||||
pull: always
|
||||
image: docker.io/immawanderer/alpine-hugo:hugo-v0.115.3
|
||||
depends_on: [submodules]
|
||||
commands:
|
||||
- hugo version
|
||||
- hugo --gc=true --minify
|
||||
|
||||
- name: hadolint
|
||||
image: docker.io/hadolint/hadolint:v2.10.0-alpine
|
||||
depends_on:
|
||||
- clone
|
||||
commands:
|
||||
- hadolint --version
|
||||
- hadolint Dockerfile
|
||||
|
||||
- name: check compose
|
||||
pull: always
|
||||
image: docker.io/tmaier/docker-compose:latest
|
||||
depends_on: [clone]
|
||||
volumes:
|
||||
- name: s
|
||||
path: /var/run/docker.sock
|
||||
environment:
|
||||
COMPOSE_DOCKER_CLI_BUILD: 1
|
||||
DOCKER_BUILDKIT: 1
|
||||
commands:
|
||||
- docker compose -f docker-compose.yml config -q
|
||||
|
||||
- name: go fmt
|
||||
image: docker.io/library/golang:1.21.0-alpine3.18
|
||||
volumes:
|
||||
- name: gopath
|
||||
path: /go
|
||||
depends_on:
|
||||
- clone
|
||||
commands:
|
||||
- go fmt
|
||||
|
||||
- name: go vet
|
||||
image: docker.io/library/golang:1.21.0-alpine3.18
|
||||
volumes:
|
||||
- name: gopath
|
||||
path: /go
|
||||
depends_on:
|
||||
- go fmt
|
||||
# wait until the site is output into './public'.
|
||||
- hugo-extended
|
||||
commands:
|
||||
- go vet
|
||||
|
||||
- name: go build
|
||||
image: docker.io/library/golang:1.21.0-alpine3.18
|
||||
volumes:
|
||||
- name: gopath
|
||||
path: /go
|
||||
depends_on:
|
||||
- go vet
|
||||
commands:
|
||||
- go build -v -ldflags "-s -w -X main.Version=${DRONE_COMMIT}" .
|
||||
|
||||
- name: rm-intermediate
|
||||
pull: if-not-exists
|
||||
image: docker.io/immawanderer/fedora-hugo:linux-amd64
|
||||
depends_on:
|
||||
- go build
|
||||
commands:
|
||||
- rm -rf ./public
|
||||
|
||||
- name: build
|
||||
pull: always
|
||||
image: docker.io/tmaier/docker-compose:latest
|
||||
depends_on:
|
||||
- rm-intermediate
|
||||
- hadolint
|
||||
- check compose
|
||||
- go fmt
|
||||
- go vet
|
||||
- go build
|
||||
volumes:
|
||||
- name: s
|
||||
path: /var/run/docker.sock
|
||||
commands:
|
||||
- docker compose build --build-arg VCS_REF=${DRONE_COMMIT} --no-cache
|
||||
when:
|
||||
branch: master
|
||||
status: success
|
||||
|
||||
- name: deploy
|
||||
pull: always
|
||||
image: docker.io/tmaier/docker-compose:latest
|
||||
depends_on:
|
||||
- build
|
||||
volumes:
|
||||
- name: s
|
||||
path: /var/run/docker.sock
|
||||
commands:
|
||||
- docker compose -p ${DRONE_REPO_NAME} up
|
||||
-d
|
||||
--remove-orphans
|
||||
--scale homepage=1
|
||||
when:
|
||||
branch: master
|
||||
status: success
|
||||
|
||||
volumes:
|
||||
- name: s
|
||||
host:
|
||||
path: /run/docker.sock
|
||||
- name: gopath
|
||||
temp: {}
|
||||
|
||||
|
||||
---
|
||||
@ -76,22 +391,21 @@ clone:
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- "dev*"
|
||||
- master
|
||||
- testing
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- push
|
||||
- tag
|
||||
status:
|
||||
- success
|
||||
- failure
|
||||
- success
|
||||
- failure
|
||||
|
||||
depends_on:
|
||||
- 'build and deploy'
|
||||
depends_on: [deploy, deploy-staging]
|
||||
|
||||
steps:
|
||||
- name: discord
|
||||
pull: if-not-exists
|
||||
image: appleboy/drone-discord:latest
|
||||
image: docker.io/appleboy/drone-discord:latest
|
||||
settings:
|
||||
message: >
|
||||
{{#success build.status}}
|
||||
@ -122,30 +436,24 @@ clone:
|
||||
disable: true
|
||||
|
||||
trigger:
|
||||
event:
|
||||
- cron
|
||||
cron:
|
||||
- hourly
|
||||
- hourly-build
|
||||
status:
|
||||
- success
|
||||
- failure
|
||||
event: cron
|
||||
cron: [hourly, nightly]
|
||||
status: [success, failure]
|
||||
|
||||
depends_on:
|
||||
- 'build and deploy'
|
||||
depends_on: [deploy]
|
||||
|
||||
steps:
|
||||
- name: discord
|
||||
pull: always
|
||||
image: appleboy/drone-discord:latest
|
||||
image: docker.io/appleboy/drone-discord:latest
|
||||
settings:
|
||||
message: >
|
||||
{{#success build.status}}
|
||||
✅ [Hourly build #{{build.number}}]({{build.link}}) of `{{repo.name}}` has been successfully deployed.
|
||||
✅ [Cron build #{{build.number}}]({{build.link}}) of `{{repo.name}}` has been successfully deployed.
|
||||
event: **`{{build.event}}`**
|
||||
commit [`${DRONE_COMMIT_SHA:0:7}`](https://git.dotya.ml/${DRONE_REPO}/commit/${DRONE_COMMIT_SHA}) by {{commit.author}} on `{{commit.branch}}`
|
||||
{{else}}
|
||||
❌ [Hourly build #{{build.number}}]({{build.link}}) of `{{repo.name}}` failed to deploy.
|
||||
❌ [Cron build #{{build.number}}]({{build.link}}) of `{{repo.name}}` failed to deploy.
|
||||
event: **`${DRONE_BUILD_EVENT}`**
|
||||
failed stage(s): **`${DRONE_FAILED_STAGES}`**
|
||||
commit [`${DRONE_COMMIT_SHA:0:7}`](https://git.dotya.ml/${DRONE_REPO}/commit/${DRONE_COMMIT_SHA}) by {{commit.author}} on `{{commit.branch}}`
|
||||
@ -155,3 +463,9 @@ steps:
|
||||
from_secret: discord_webhook_hourly_id
|
||||
webhook_token:
|
||||
from_secret: discord_webhook_hourly_token
|
||||
|
||||
---
|
||||
kind: signature
|
||||
hmac: 4e178bb873563499a7b3b00fdb372acc239dedfb8b151858598a29778349f44c
|
||||
|
||||
...
|
||||
|
8
.gitea/issue_template/bug.md
Normal file
8
.gitea/issue_template/bug.md
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
name: "Bug :bug:"
|
||||
title: "[Bug] "
|
||||
about: "A bug :bug: template"
|
||||
labels:
|
||||
- bug
|
||||
---
|
||||
<!-- This is a bug template -->
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,3 +2,6 @@
|
||||
public/
|
||||
resources/
|
||||
*.swp
|
||||
|
||||
# go binary
|
||||
homepage
|
||||
|
96
.golangci.yml
Normal file
96
.golangci.yml
Normal file
@ -0,0 +1,96 @@
|
||||
---
|
||||
run:
|
||||
go: '1.20'
|
||||
tests: true
|
||||
skip-dirs:
|
||||
- static
|
||||
- public
|
||||
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- bidichk
|
||||
- dupl
|
||||
- decorder
|
||||
- dogsled
|
||||
- exportloopref
|
||||
- forbidigo
|
||||
- gas
|
||||
- gocognit
|
||||
- goconst
|
||||
- gocritic
|
||||
- godot
|
||||
- govet
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goimports
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- ineffassign
|
||||
- misspell
|
||||
# - prealloc
|
||||
- revive
|
||||
- tparallel
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- wastedassign
|
||||
- whitespace
|
||||
- wsl
|
||||
|
||||
linter-settings:
|
||||
dupl:
|
||||
threshold: 100
|
||||
gocritic:
|
||||
enabled-tags:
|
||||
- diagnostic
|
||||
- experimental
|
||||
- opinionated
|
||||
- performance
|
||||
- style
|
||||
disabled-checks:
|
||||
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
||||
- ifElseChain
|
||||
- octalLiteral
|
||||
- whyNoLint
|
||||
- wrapperFunc
|
||||
gocyclo:
|
||||
min-complexity: 15
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
lang-version: "1.20"
|
||||
govet:
|
||||
check-shadowing: true
|
||||
revive:
|
||||
severity: warning
|
||||
confidence: 0.8
|
||||
errorCode: 1
|
||||
warningCode: 1
|
||||
rules:
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: exported
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
- name: package-comments
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: duplicated-imports
|
||||
- name: modifies-value-receiver
|
||||
wsl:
|
||||
allow-cuddle-declaration: true
|
||||
...
|
2
.hadolint.yaml
Normal file
2
.hadolint.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
ignored:
|
47
.pre-commit-config.yaml
Normal file
47
.pre-commit-config.yaml
Normal file
@ -0,0 +1,47 @@
|
||||
---
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: check-merge-conflict
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
exclude: .drone.yml # drone's yaml is somewhat strange sometimes
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: hugo-version-check
|
||||
name: hugo version check
|
||||
entry: |
|
||||
bash -c "
|
||||
files='.drone.yml Dockerfile'
|
||||
count=$(grep -oE '(hugo-v)[0-9].[0-9].[0-9].[0-9]' $files | cut -d':' -f2 | sed -e 's/^ *//g' -e 's/hugo-v//g' | uniq | wc -l)
|
||||
if [ $count -gt 1 ]; then
|
||||
echo hugo versions inconsistent:
|
||||
grep -noE --color=always '(hugo-v)[0-9].[0-9].[0-9].[0-9]' $files
|
||||
exit 1
|
||||
fi
|
||||
"
|
||||
language: system
|
||||
pass_filenames: false
|
||||
- id: check-compose-file
|
||||
name: check compose file
|
||||
language: system
|
||||
entry: docker-compose -f docker-compose.yml config
|
||||
pass_filenames: false
|
||||
- id: yamllint
|
||||
name: yamllint
|
||||
language: system
|
||||
entry: yamllint .
|
||||
pass_filenames: false
|
||||
- repo: https://git.dotya.ml/wanderer/hadolint-pre-commit
|
||||
rev: v0.0.1
|
||||
hooks:
|
||||
- id: hadolint-container
|
||||
- repo: https://github.com/dnephin/pre-commit-golang
|
||||
rev: v0.5.0
|
||||
hooks:
|
||||
- id: go-mod-tidy
|
||||
- id: go-unit-tests
|
||||
- id: golangci-lint
|
||||
- id: go-build
|
||||
...
|
13
.yamllint
Normal file
13
.yamllint
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
|
||||
yaml-files:
|
||||
- '*.yaml'
|
||||
- '*.yml'
|
||||
- '.yamllint'
|
||||
|
||||
rules:
|
||||
line-length:
|
||||
level: warning
|
||||
|
||||
# vim: ft=yaml bs=2 ts=2
|
||||
...
|
36
Dockerfile
Normal file
36
Dockerfile
Normal file
@ -0,0 +1,36 @@
|
||||
# syntax=docker/dockerfile-upstream:master-labs
|
||||
# refs:
|
||||
# https://docs.docker.com/develop/develop-images/build_enhancements/#overriding-default-frontends
|
||||
# https://pythonspeed.com/articles/docker-buildkit/
|
||||
FROM docker.io/alpine/git:v2.36.2 AS submodules
|
||||
|
||||
WORKDIR /homepage
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN git submodule init && \
|
||||
git submodule update --recursive
|
||||
|
||||
FROM docker.io/immawanderer/alpine-hugo:hugo-v0.115.3 AS hugobuild
|
||||
|
||||
COPY --from=submodules /homepage/ /homepage/
|
||||
|
||||
WORKDIR /homepage
|
||||
|
||||
RUN hugo version && \
|
||||
hugo --minify --gc=true --cleanDestinationDir
|
||||
|
||||
FROM docker.io/library/golang:1.21.0-alpine3.18 AS gobuild
|
||||
COPY --from=hugobuild /homepage/ /homepage/
|
||||
|
||||
WORKDIR /homepage
|
||||
|
||||
ARG VCS_REF=development
|
||||
|
||||
RUN CGO_ENABLED=0 GOFLAGS='-trimpath -mod=readonly -modcacherw' \
|
||||
go build -o homepage-app -v -ldflags "-s -w -X main.version=$VCS_REF" .
|
||||
|
||||
FROM scratch
|
||||
COPY --from=gobuild /homepage/homepage-app /homepage
|
||||
|
||||
ENTRYPOINT ["/homepage"]
|
16
LICENSE
16
LICENSE
@ -1,13 +1,13 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
Copyright (C) 2019-2021 dotya.ml authors
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
@ -1,6 +1,10 @@
|
||||
# dotya.ml
|
||||
# [dotya.ml](https://git.dotya.ml/dotya.ml/homepage/)
|
||||
|
||||
[![Build Status](https://drone.dotya.ml/api/badges/dotya.ml/dotya_homepage/status.svg?ref=refs/heads/master)](https://drone.dotya.ml/dotya.ml/dotya_homepage)
|
||||
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
|
||||
[![Build Status](https://drone.dotya.ml/api/badges/dotya.ml/homepage/status.svg?ref=refs/heads/master)](https://drone.dotya.ml/dotya.ml/homepage)
|
||||
[![Mozilla HTTP Observatory Grade](https://img.shields.io/mozilla-observatory/grade-score/dotya.ml)](https://observatory.mozilla.org/analyze/dotya.ml)
|
||||
[![Security Headers](https://img.shields.io/security-headers?url=https%3A%2F%2Fdotya.ml)](https://securityheaders.com/?q=https%3A%2F%2Fdotya.ml)
|
||||
![Chromium HSTS preload](https://img.shields.io/hsts/preload/dotya.ml)
|
||||
|
||||
sawce that makes up the dotya.ml landing page.
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
lastmod: {{ .Date }}
|
||||
enableGitInfo: true
|
||||
draft: true
|
||||
---
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
// Colors
|
||||
//
|
||||
$theme: #D8D8D8;
|
||||
$text: #D8D8D8;
|
||||
$light-grey: #282a2b; // Background
|
||||
$dark-grey: #282a2b; // Hover Bar
|
||||
$highlight-grey: #151718; // Highlight background of `keyword`
|
||||
$midnightblue: #151718; // Code Background
|
||||
$theme: #613583; // hyperlink highlight background colour, .post-info
|
||||
// site-local link :hover highlight colour
|
||||
$text: #21fa45; // colour of normal text
|
||||
$light-grey: #010000; // background
|
||||
$dark-grey: #111115; // hover bar
|
||||
$highlight-grey: #9141ac; // code (not in pre) background
|
||||
$midnightblue: #151718; // code text (not in pre) colour
|
||||
|
||||
// Fonts
|
||||
//
|
||||
|
@ -48,19 +48,20 @@ pre {
|
||||
letter-spacing: normal;
|
||||
white-space: pre;
|
||||
color: #eee;
|
||||
background: $midnightblue;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
border-radius: 5px;
|
||||
// -webkit-overflow-scrolling: touch;
|
||||
|
||||
code {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: $midnightblue;
|
||||
color: #eee;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
color: #eee;
|
||||
color: $midnightblue;
|
||||
background: $highlight-grey;
|
||||
border-radius: 3px;
|
||||
padding: 0 3px;
|
||||
@ -90,12 +91,11 @@ a {
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
transition-property: color;
|
||||
transition-duration: .4s;
|
||||
transition-duration: .1s;
|
||||
transition-timing-function: ease-out;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
text-shadow: 0 0 1px #fff;
|
||||
color: $highlight-grey;
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,6 +230,7 @@ table {
|
||||
box-sizing: border-box;
|
||||
box-shadow: -1px -2px 3px rgba(0, 0, 0, 0.45);
|
||||
background-color: $dark-grey;
|
||||
animation-duration: .3s;
|
||||
}
|
||||
|
||||
.hdr-wrapper {
|
||||
@ -379,6 +380,7 @@ p.img-404 {
|
||||
|
||||
&:hover {
|
||||
border-color: #fff;
|
||||
color: $highlight-grey;
|
||||
}
|
||||
|
||||
svg {
|
||||
@ -576,6 +578,14 @@ hr.post-end {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
a img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding: 0;
|
||||
@ -628,7 +638,7 @@ hr.post-end {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&.footnote-return {
|
||||
&.footnote-backref {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
@ -638,12 +648,18 @@ hr.post-end {
|
||||
}
|
||||
}
|
||||
|
||||
.footnote-ref a {
|
||||
a.footnote-ref {
|
||||
box-shadow: none;
|
||||
text-decoration: none;
|
||||
padding: 2px;
|
||||
border-radius: 2px;
|
||||
background-color: $midnightblue;
|
||||
|
||||
&:hover{
|
||||
box-shadow: none;
|
||||
background-color: $theme;
|
||||
transition-property: background-color;
|
||||
}
|
||||
}
|
||||
|
||||
.post-info {
|
||||
@ -656,7 +672,7 @@ hr.post-end {
|
||||
}
|
||||
|
||||
a:hover {
|
||||
border-bottom: 1px solid $theme;
|
||||
border-bottom: 2px solid $theme;
|
||||
}
|
||||
|
||||
svg {
|
||||
|
81
config.toml
81
config.toml
@ -1,32 +1,39 @@
|
||||
baseurl = "/"
|
||||
languageCode = "en-us"
|
||||
languageCode = "en-gb"
|
||||
defaultContentLanguage = "en"
|
||||
theme = "hermit"
|
||||
license = "WTFPL"
|
||||
copyright = '<a href="http://www.wtfpl.net/about/" rel="noopener">WTFPL</a>'
|
||||
enableGitInfo = true
|
||||
|
||||
pygmentsCodefences = true
|
||||
pygmentsUseClasses = true
|
||||
pygmentsStyle = "fruity"
|
||||
enableEmoji = true
|
||||
|
||||
[author]
|
||||
name = "dotya.ml"
|
||||
|
||||
[params]
|
||||
dateform = "Jan 2, 2006"
|
||||
dateformShort = "Jan 2"
|
||||
dateformNum = "2006-02-01"
|
||||
dateformNumTime = "2006-02-01 15:04 +0000"
|
||||
[taxonomies]
|
||||
tag = 'tags'
|
||||
|
||||
[permalinks]
|
||||
posts = '/:year/:month/:title/'
|
||||
|
||||
[params]
|
||||
dateform = "02 Jan 2006"
|
||||
dateformShort = "02 Jan"
|
||||
dateformNum = "02 Jan 2006"
|
||||
dateformNumTime = "Mon, 02 Jan 2006 15:04:05 -0700"
|
||||
# Metadata mostly used in document's head
|
||||
description = "dotya.ml"
|
||||
description = "dotya.ml homepage"
|
||||
keywords = "homepage, development, git, programming"
|
||||
images = [""]
|
||||
themeColor = "#282a2b"
|
||||
justifyContent = false
|
||||
relatedPosts = false
|
||||
relatedPosts = true
|
||||
gitUrl = "https://git.dotya.ml/dotya.ml/homepage/src/commit/"
|
||||
|
||||
# Directory name of your blog content (default is `content/posts`)
|
||||
contentTypeName = "posts"
|
||||
contentTypeName = "content/posts"
|
||||
# Default theme "light" or "dark"
|
||||
defaultTheme = "dark"
|
||||
|
||||
@ -53,36 +60,38 @@ enableEmoji = true
|
||||
alt = "dockerhub profile page"
|
||||
|
||||
[languages]
|
||||
[languages.logo.params.en]
|
||||
logoText = "dotya.ml"
|
||||
logoHomeLink = "/"
|
||||
|
||||
[languages.en]
|
||||
title = "dotya.ml"
|
||||
subtitle = ""
|
||||
|
||||
[languages.en.params]
|
||||
keywords = "homepage, development, git, programming"
|
||||
subtitle = "hello friend. hello friend? that's lame. maybe I should give you a name."
|
||||
readOtherPosts = ""
|
||||
|
||||
[languages.en.params.logo]
|
||||
logoText = "dotya.ml"
|
||||
logoHomeLink = "/"
|
||||
|
||||
# You can create a language based menu
|
||||
[languages.en.menu]
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "about"
|
||||
name = "about"
|
||||
url = "/about/"
|
||||
alt = "dotya.ml status"
|
||||
weight = 1
|
||||
# [[languages.en.menu.main]]
|
||||
# identifier = "posts"
|
||||
# name = "posts"
|
||||
# url = "/posts"
|
||||
# alt = "dotya.ml posts"
|
||||
# weight = 2
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "contact"
|
||||
name = "contact"
|
||||
url = "/contact/"
|
||||
alt = "dotya.ml contact"
|
||||
weight = 3
|
||||
# You can create a language based menu
|
||||
[languages.en.menu]
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "about"
|
||||
name = "about"
|
||||
url = "/about/"
|
||||
alt = "about dotya.ml"
|
||||
weight = 1
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "posts"
|
||||
name = "posts"
|
||||
url = "/posts/"
|
||||
alt = "dotya.ml posts"
|
||||
weight = 2
|
||||
[[languages.en.menu.main]]
|
||||
identifier = "contact"
|
||||
name = "contact"
|
||||
url = "/contact/"
|
||||
alt = "dotya.ml contact"
|
||||
weight = 3
|
||||
|
||||
[privacy]
|
||||
[privacy.disqus]
|
||||
|
@ -1,5 +1,6 @@
|
||||
---
|
||||
title: "0x28bd2388"
|
||||
description: "instructions on how to verify 0x28bd2388 gpg key"
|
||||
date: 2020-03-07T16:22:03+01:00
|
||||
draft: false
|
||||
---
|
||||
|
@ -1,12 +1,47 @@
|
||||
---
|
||||
title: "about dotya.ml"
|
||||
date: 2020-03-07T02:12:03+01:00
|
||||
description: "an overview of dotya.ml's activities and mission"
|
||||
date: 2020-08-06T17:15:03+01:00
|
||||
lastmod: 2022-09-06T16:11:32+02:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
Free services provided for fun as a hobby with passion and :heart:\
|
||||
So far we have [Gitea](https://git.dotya.ml) and a [Drone](https://drone.dotya.ml) ci/cd instance (login with a Gitea account).
|
||||
Free services provided for fun as a hobby with passion and :white_heart:
|
||||
|
||||
### Clearnet services
|
||||
see what we have so far: [list of services]({{< relref "services.md" >}}).
|
||||
|
||||
### Onion services
|
||||
for increased privacy of our users, *some* services are also available
|
||||
natively via [TOR](https://www.torproject.org/), have a look at
|
||||
[onions 🧅]({{< relref "onions.md" >}}) for details.
|
||||
|
||||
### Observability
|
||||
to enable long-term monitoring of trends for services we're running:
|
||||
* [prometheus](https://prometheus.io) at https://metrics.dotya.ml
|
||||
* [grafana](https://grafana.com) at https://grafana.dotya.ml
|
||||
|
||||
### Status
|
||||
* in-house status monitor at https://status.dotya.ml (courtesy of [statping-ng](https://statping-ng.github.io))
|
||||
* UptimeRobot ([affiliate link](https://uptimerobot.com/?rid=a60f8392870bc9)) hosted dashboard at https://stats.uptimerobot.com/93yPqFmmx8
|
||||
|
||||
You can see the [current status here](/status/).
|
||||
### Security
|
||||
[HSTS](https://tools.ietf.org/rfc/rfc6797.txt) has been enabled early on for `dotya.ml`,
|
||||
which means that all major browsers (Firefox, Chromium, Safari and Opera) today know that this site,
|
||||
as well as **all** of its subdomains, communicate with you only using TLS to secure the data in transit
|
||||
(they check the [preload list](https://source.chromium.org/chromium/chromium/src/+/master:net/http/transport_security_state_static.json)),
|
||||
i.e. no plain HTTP connections.
|
||||
|
||||
#### Misc
|
||||
* HTTP headers insight for https://dotya.ml as per [Mozilla HTTP Observatory](https://observatory.mozilla.org/analyze/dotya.ml)\
|
||||
Scoring 130 out of 100 points
|
||||
|
||||
* [SecurityHeaders](https://securityheaders.com/) report at https://securityheaders.com/?q=https%3A%2F%2Fdotya.ml
|
||||
|
||||
* SSL Labs [TLS rating](https://www.ssllabs.com/ssltest/analyze.html?d=dotya.ml): *A+*
|
||||
|
||||
* [cryptcheck.fr](https://cryptcheck.fr/https/dotya.ml): *A+*
|
||||
|
||||
### Privacy
|
||||
see [privacy]({{< relref "privacy" >}}), the short version being *we are not
|
||||
selling you out* 🎉.
|
||||
|
@ -1,39 +1,52 @@
|
||||
---
|
||||
title: "contact"
|
||||
description: "ways to get in contact with dotya.ml maintainers"
|
||||
date: 2020-03-07T01:53:03+01:00
|
||||
draft: false
|
||||
---
|
||||
\-- wanderer
|
||||
|
||||
## \-- wanderer
|
||||
```bash
|
||||
echo a_mirre.utb.cz | sed 's/\./@/'
|
||||
echo wanderer+hello.dotya.ml | sed 's/\./@/'
|
||||
```
|
||||
|
||||
fingerprint:
|
||||
use [age](https://github.com/FiloSottile/age) if possible.\
|
||||
pubkey:
|
||||
```sh
|
||||
age16xdcxvnnhcekv59ncj5fmdarhm8csdgd9nk7nzxpywg5xtehq4kq49880e
|
||||
```
|
||||
|
||||
gpg fingerprint:
|
||||
|
||||
```bash
|
||||
E860 AB3C D007 8D30 E86C DA74 7B28 D8DC 28BD 2388
|
||||
```
|
||||
|
||||
the corresponding pubkey: [0x28bd2388](/28bd2388/)
|
||||
plain key file: [0x28bd2388.asc](/store/0x28bd2388.asc)
|
||||
the corresponding pubkey: [0x28bd2388]({{< relref "28bd2388.md" >}})
|
||||
plain key file: [0x28bd2388.asc](/store/0x28bd2388.asc)
|
||||
openpgp key server link: [0x28bd2388](https://keys.openpgp.org/vks/v1/by-fingerprint/E860AB3CD0078D30E86CDA747B28D8DC28BD2388)
|
||||
|
||||
## \-- 2EEEB
|
||||
```bash
|
||||
echo andrej.pillar,vutbr.cz | sed 's/\,/@/'
|
||||
```
|
||||
|
||||
fingerprint:
|
||||
```bash
|
||||
4413 88B1 4509 04C0 E435 6F16 AA07 F3B7 1F41 8FEE
|
||||
```
|
||||
|
||||
the pubkey can be found in a [key repo](https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xaa07f3b71f418fee)
|
||||
|
||||
communication using gpg is *preferable*
|
||||
|
||||
## Privacy policy
|
||||
|
||||
Since I don't like such practices myself, this site *does not* collect
|
||||
*any* kind of user/browser/device/user agent/network identifier,
|
||||
which - for simplicity's sake is - ANY data.\
|
||||
Period.\
|
||||
No IP addresses are stored, no user
|
||||
agents logged, no cookies are used to identify users.
|
||||
|
||||
Therefore **no data is collected** and can't be passed on to third parties,
|
||||
nor is there any intention of ever doing so.
|
||||
## Privacy
|
||||
see [privacy]({{< relref "about#privacy" >}}), or in case of questions, say
|
||||
hi and ask away at:
|
||||
```sh
|
||||
hello at dotya dot ml
|
||||
```
|
||||
|
||||
## Long live the libre world!
|
||||
|
||||
Feel at home.\
|
||||
Cheers.
|
||||
|
||||
|
42
content/onions.md
Normal file
42
content/onions.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
title: "onions 🧅"
|
||||
description: "summary of onion services dotya.ml provides - a more anonymous way to access your stuff"
|
||||
date: 2022-08-30T12:00:42+02:00
|
||||
lastmod: 2022-08-30T12:00:42+02:00
|
||||
enableGitInfo: true
|
||||
draft: false
|
||||
---
|
||||
|
||||
> Note: This is a work in progress - more services are to come
|
||||
|
||||
> Note 2: the `http` part of the links below is misleading, as (our) [onion
|
||||
> services](https://community.torproject.org/onion-services/) are in fact
|
||||
> fully encrypted every step of the way using `https`, only the certs are not
|
||||
> signed by a conventional CA (certificate authority), which means
|
||||
> conventional browsers (including Firefox-based TorBrowser) would cry if the
|
||||
> sites were served with explicit `https` prefix.
|
||||
> this decreases the security by exactly zero and unless LetsEncrypt starts
|
||||
> issuing certs for `.onion` domains, we're not going to see broad usage of
|
||||
> *explicit* `https` prefix on onion services, since only the likes of NY
|
||||
> Times, BBC, Twitter or Facebook are going to make their CAs to sign them a
|
||||
> neat little `.onion` cert.
|
||||
|
||||
Gitea: http://2crftbzxbcoqolvzreaaeyrod5qwycayef55gxgzgfcpqlaxrnh3kkqd.onion\
|
||||
this site: http://6426tqrh4y5uobmo5y2csaip3m3avmjegd2kpa24sadekpxglbm34aqd.onion\
|
||||
prometheus: http://vognfwm7c6wq2gxqcmswi2flwckuxryefd7n3axxkvlpasdjhns5buqd.onion\
|
||||
grafana: http://6t3ydf7sl7iso2wbymbfjtaq6qqlrms37ffik2siulsljc3ubobklnid.onion\
|
||||
statuspage: http://o4irro4dspyuytbw2b2g2ac4ukkh2ex53oolhzw7hrfjmq6tiklrtwqd.onion
|
||||
|
||||
#### current progress on onion drone
|
||||
https://git.dotya.ml/dotya.ml/community/issues/5
|
||||
|
||||
Making `DroneCI` available as a hidden service would require either
|
||||
a) spinning up another instance, for which we currently don't have capacities, or
|
||||
b) some kind of an evil hack that we've not yet discovered.\
|
||||
We're open to ideas - if you know how to make this work, please, send us a patch,
|
||||
PR or an email with anything interesting and worthwile.
|
||||
|
||||
set-up-but-not-properly-working drone: http://c3vqfx2dqltvdbsqu3ndqwcxsp3uk3vcxo2jsigie5zfajub3j3y35id.onion
|
||||
|
||||
### clearnet
|
||||
also check out [services]({{< relref "services" >}})...
|
119
content/posts/dnscrypt.md
Normal file
119
content/posts/dnscrypt.md
Normal file
@ -0,0 +1,119 @@
|
||||
---
|
||||
title: "DNSCrypt - running the server"
|
||||
description: "How we run a DNSCrypt server using docker-compose"
|
||||
date: 2021-08-06T23:38:45+02:00
|
||||
author: wanderer - https://git.dotya.ml/wanderer
|
||||
draft: false
|
||||
toc: true
|
||||
enableGitInfo: true
|
||||
tags: [dnscrypt, dns, privacy, security, censorship]
|
||||
---
|
||||
|
||||
## why are you doing this?
|
||||
There are many publicly available [open resolvers using DoT, DoH or
|
||||
DNSCrypt](https://dnscrypt.info/public-servers) just sitting around the
|
||||
interwebs, waiting to secure the DNS traffic and protect it from whoever is
|
||||
looking.
|
||||
|
||||
However, we have still felt the need to run our own, especially since
|
||||
DNS is such a critical piece of infrastructure.
|
||||
|
||||
And now we're offering it for public use.
|
||||
|
||||
## so what is it?
|
||||
What we're running is a non-censoring, non-logging, DNSSEC-capable, DNSCrypt-enabled DNS
|
||||
resolver using
|
||||
[dnscrypt-server-docker](https://github.com/dnscrypt/dnscrypt-server-docker) project.
|
||||
Of course, our resolver is available over both IPv4 and IPv6.
|
||||
|
||||
## can I haz some plz
|
||||
Yes! As a matter of fact, you should even be able to get records on
|
||||
[OpenNIC](https://www.opennic.org/) domains.
|
||||
|
||||
You can try some using the awesome tool [`doggo`](https://github.com/mr-karan/doggo), like so:
|
||||
```shell
|
||||
doggo --debug --json NS epic. @sdns://AQcAAAAAAAAAETE0NC45MS43MC42Mjo1NDQzIHF-JiN46cNwFXJleEVWGWgrhe2QeysUtZoo9HwzYCMzITIuZG5zY3J5cHQtY2VydC5kbnNjcnlwdC5kb3R5YS5tbA
|
||||
```
|
||||
example response:
|
||||
```shell
|
||||
DEBUG[2022-09-01T00:22:23+02:00] initiating DNSCrypt resolver
|
||||
|
||||
DEBUG[2022-09-01T00:22:23+02:00] Starting doggo 🐶
|
||||
|
||||
DEBUG[2022-09-01T00:22:23+02:00] Attempting to resolve domain=epic. nameserver="144.91.70.62:5443" ndots=0
|
||||
[
|
||||
{
|
||||
"answers": [
|
||||
{
|
||||
"name": "epic.",
|
||||
"type": "NS",
|
||||
"class": "IN",
|
||||
"ttl": "86400s",
|
||||
"address": "ns13.opennic.glue.",
|
||||
"status": "",
|
||||
"rtt": "45ms",
|
||||
"nameserver": "144.91.70.62:5443"
|
||||
}
|
||||
],
|
||||
"authorities": null,
|
||||
"questions": [
|
||||
{
|
||||
"name": "epic.",
|
||||
"type": "NS",
|
||||
"class": "IN"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### `dnscrypt-proxy` configuration tips
|
||||
If you'd, for some reason, like to use exclusively our name servers, simply set
|
||||
the `server_names` in the root section of your `dnscrypt-proxy.toml` config
|
||||
file:
|
||||
```toml
|
||||
server_names = ['dotya.ml', 'dotya.ml-ipv6']
|
||||
```
|
||||
|
||||
By default servers are picked based on latency, which is a sane default and it
|
||||
is in fact what we use.
|
||||
|
||||
If in need of more granular nameserver selection based on anything other than
|
||||
latency they can additionally easily be filtered (without being explicitly
|
||||
listed) based on:
|
||||
* logging
|
||||
* filtering
|
||||
* DNSSEC capabilities
|
||||
* DoH, ODoH or DNSCrypt capabilities
|
||||
* IPv4 or IPv6 availability
|
||||
|
||||
Further, we also remove certain players from the equation by simply listing
|
||||
them in `disabled_server_names`, like so:
|
||||
```toml
|
||||
disabled_server_names = ['google-ipv6', 'cloudflare', 'cloudflare-ipv6', 'cisco', 'cisco-ipv6', 'cisco-familyshield', 'cisco-familyshield-ipv6', 'yandex', 'apple', 'doh.dns.apple.com']
|
||||
```
|
||||
|
||||
### old news
|
||||
> Update 2022-09-01: the servers are now a part of the official listing at
|
||||
> https://dnscrypt.info/public-servers/, so there is no point in adding them
|
||||
> manually anymore. Keeping this for posterity.
|
||||
|
||||
Paste one or both of the following entries in the `[static]` section of your
|
||||
`dnscrypt-proxy.toml` configuration file.
|
||||
|
||||
```toml
|
||||
[static]
|
||||
# IPv4 (144.91.70.62, port 5443)
|
||||
[static. 'dnscrypt.dotya.ml-ipv4']
|
||||
stamp = 'sdns://AQcAAAAAAAAAETE0NC45MS43MC42Mjo1NDQzIHF-JiN46cNwFXJleEVWGWgrhe2QeysUtZoo9HwzYCMzITIuZG5zY3J5cHQtY2VydC5kbnNjcnlwdC5kb3R5YS5tbA'
|
||||
|
||||
# IPv6 (2a02:c207:2030:396::1, port 5443)
|
||||
[static. 'dnscrypt.dotya.ml-ipv6']
|
||||
stamp = 'sdns://AQcAAAAAAAAAHFsyYTAyOmMyMDc6MjAzMDozOTY6OjFdOjU0NDMgcX4mI3jpw3AVcmV4RVYZaCuF7ZB7KxS1mij0fDNgIzMhMi5kbnNjcnlwdC1jZXJ0LmRuc2NyeXB0LmRvdHlhLm1s'
|
||||
```
|
||||
|
||||
## server configuration
|
||||
Files used to set up and run this service can be found here:\
|
||||
https://git.dotya.ml/dotya.ml/dnscrypt-server.
|
||||
It's a `docker-compose` setup managed with `systemd`, similar to how Drone CI
|
||||
is handled.
|
157
content/posts/m32.md
Normal file
157
content/posts/m32.md
Normal file
@ -0,0 +1,157 @@
|
||||
---
|
||||
title: "Compiling C programs using -m32 on Arch in 2023"
|
||||
description: "Compiling C programs for 32bit on Arch in 2023"
|
||||
date: 2023-06-14T12:32:52+02:00
|
||||
author: wanderer - https://git.dotya.ml/wanderer
|
||||
draft: false
|
||||
toc: true
|
||||
enableGitInfo: true
|
||||
images:
|
||||
tags:
|
||||
- archlinux
|
||||
- compilation
|
||||
- 32bit
|
||||
---
|
||||
|
||||
## Intro
|
||||
|
||||
> **Preliminary:** To be clear, this short post is not primarily concerned with
|
||||
> *running* the 32bit programs, instead specifically *compiling C programs for
|
||||
> 32bit (x86)*.
|
||||
|
||||
Compiling a `C` program for a 32bit architecture in 2023?
|
||||
|
||||
Well, one might still want to poke at reversing smaller address-space programs,
|
||||
*even in 2023*, and contrary to the popular belief, there still exist pieces of
|
||||
software not ported to 64bit and architectures in use that are 32bit. Whatever
|
||||
the motivation, the *compilation* process might not be as straight-forward on
|
||||
Arch as one would maybe expect, so this post shows how it can be done. Unless
|
||||
specified otherwise, the `x86` architecture is assumed.
|
||||
|
||||
### Example program
|
||||
|
||||
> Just show the example program already!
|
||||
|
||||
Nothing fancy, just saying hi and printing the value of `esp`. All that is
|
||||
needed is to compile this into a 32bit binary.
|
||||
|
||||
```c
|
||||
/* 32ftw.c */
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("hey 32!\n");
|
||||
|
||||
register int e asm("esp");
|
||||
printf("esp: 0x%08x\n", e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
For reference, the`GCC` version used was `gcc (GCC) 13.1.1 20230429`.
|
||||
|
||||
## TL;DR
|
||||
|
||||
To compile a 32bit `C` program on
|
||||
[64bit-only](https://wiki.archlinux.org/title/Frequently_asked_questions#What_architectures_does_Arch_support?)
|
||||
Arch, additional packages (on top of compilers/linkers) are required. As of
|
||||
2023-06-14 these are:
|
||||
* `core/lib32-glibc`
|
||||
* `core/libr32-gcc-libs`,
|
||||
|
||||
which are the GNU C library (could also use [musl libc](https://musl.libc.org/)
|
||||
but that would probably necessitate compiler wrapping as GCC seems to prefer
|
||||
the GNU versions), and the 32bit version of the GCC libraries, respectively.
|
||||
|
||||
|
||||
### Installing deps and calling it a day
|
||||
|
||||
```sh
|
||||
~ % sudo pacman -S lib32-glibc lib32-gcc-libs
|
||||
resolving dependencies...
|
||||
looking for conflicting packages...
|
||||
|
||||
Package (2) New Version Net Change
|
||||
|
||||
core/lib32-gcc-libs 13.1.1-1 113.12 MiB
|
||||
core/lib32-glibc 2.37-3 18.06 MiB
|
||||
|
||||
Total Installed Size: 131.18 MiB
|
||||
|
||||
:: Proceed with installation? [Y/n]
|
||||
```
|
||||
|
||||
## The longer version
|
||||
|
||||
If you ever needed to compile some `C` sources (such as the example listed
|
||||
[here](#example-program)) on Arch into a 32 bit binary? You might have
|
||||
encountered the following:
|
||||
|
||||
```sh
|
||||
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
|
||||
In file included from /usr/include/features.h:515,
|
||||
from /usr/include/bits/libc-header-start.h:33,
|
||||
from /usr/include/stdio.h:27,
|
||||
from 32ftw.c:2:
|
||||
/usr/include/gnu/stubs.h:7:11: fatal error: gnu/stubs-32.h: No such file or directory
|
||||
7 | # include <gnu/stubs-32.h>
|
||||
| ^~~~~~~~~~~~~~~~
|
||||
compilation terminated.
|
||||
```
|
||||
|
||||
Alright, a quick search and [an answer on Arch
|
||||
forums](https://bbs.archlinux.org/viewtopic.php?pid=1136063#p1136063) points to
|
||||
a (spoiler: *partial*) solution: `lib32-glibc` is needed, so let's install it
|
||||
|
||||
```sh
|
||||
~ % sudo pacman -S lib32-glibc
|
||||
```
|
||||
|
||||
and try again:
|
||||
|
||||
```sh
|
||||
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
/usr/sbin/ld: cannot find libgcc_s.so.1: No such file or directory
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/gcc/x86_64-pc-linux-gnu/13.1.1/../../../libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
/usr/sbin/ld: skipping incompatible /usr/lib/libgcc_s.so.1 when searching for libgcc_s.so.1
|
||||
collect2: error: ld returned 1 exit status
|
||||
```
|
||||
|
||||
> Oh no, it still refuses to work.
|
||||
|
||||
As is *somewhat* hinted in the linker's error message depicted above, the
|
||||
problem can be rectified by installing the GCC libraries (the 32bit version, of
|
||||
course), which in Arch's `core` repository lives under the name
|
||||
`lib32-gcc-libs`:
|
||||
|
||||
```sh
|
||||
~ % sudo pacman -S lib32-gcc-libs
|
||||
```
|
||||
|
||||
Now the program can finally be compiled and run and we can see it's a 32bit
|
||||
binary.
|
||||
|
||||
```sh
|
||||
~ % gcc -o 32ftw -m32 32ftw.c && ./32ftw
|
||||
hey 32!
|
||||
esp: 0xff8d27f0
|
||||
~ % file ./32ftw
|
||||
32ftw: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=2ff0c8dce8f64db4960aa6aef6cd9936326e990d, for GNU/Linux 4.4.0, not stripped
|
||||
~ % ldd ./32ftw
|
||||
linux-gate.so.1 (0xf7f50000)
|
||||
libc.so.6 => /usr/lib32/libc.so.6 (0xf7ce5000)
|
||||
/lib/ld-linux.so.2 => /usr/lib/ld-linux.so.2 (0xf7f52000)
|
||||
```
|
||||
|
||||
## Closing words
|
||||
To sum up, compiling a `C` program for 32bit on contemporary Arch works fine
|
||||
with just a handful of dependencies. In author's opinion, this could be
|
||||
highlighted better in the Archwiki, but perhaps the target audience is so small
|
||||
that it hasn't even been considered.
|
||||
|
||||
For a not-much-talking summary, check out [TL;DR's calling it a
|
||||
day](#installing-deps-and-calling-it-a-day).
|
22
content/privacy.md
Normal file
22
content/privacy.md
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
title: "privacy"
|
||||
description: "an overview of dotya.ml's information collection/use practices (spoiler - we don't sell your data)"
|
||||
date: 2022-08-30T12:47:37+02:00
|
||||
lastmod: 2022-08-30T12:47:37+02:00
|
||||
enableGitInfo: true
|
||||
draft: false
|
||||
---
|
||||
|
||||
### tl;dr
|
||||
[Access logs](https://en.wikipedia.org/wiki/Server_log) are stored for up to 30 days for the purpose of defending against abuse.
|
||||
|
||||
### the long version
|
||||
Since I don't like such practices myself, this site *does not* collect
|
||||
*any* kind of user/browser/device/user agent/network identifier,
|
||||
which - for simplicity's sake is - no data at all - **FOR PROFIT**.\
|
||||
Period.
|
||||
|
||||
No personally identifiable data is collected - actively or passively - and therefore can't be passed on to third parties (such as advertisement companies), nor is there any intention of *ever* doing so.
|
||||
|
||||
Visitor device's apparent IP address *is stored* in access log, along with a [user agent](https://duckduckgo.com/?t=ffab&q=user+agent) string, which allows us to defend against abuse.
|
||||
These logs are automatically overwriten approximately every 30 days.
|
25
content/services.md
Normal file
25
content/services.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
title: "services"
|
||||
description: "a non-exhaustive list of services hosted by dotya.ml available to the community"
|
||||
date: 2022-08-30T11:50:50+02:00
|
||||
lastmod: 2022-08-30T11:50:50+02:00
|
||||
enableGitInfo: true
|
||||
toc: true
|
||||
draft: false
|
||||
---
|
||||
|
||||
a non-exhaustive list of services available to the community:
|
||||
* [Gitea](https://gitea.io) SCM instance at https://git.dotya.ml
|
||||
* [DroneCI](https://drone.io) instance (login with a Gitea account) at https://drone.dotya.ml
|
||||
* DNS resolvers:
|
||||
* [DNSCrypt](https://dnscrypt.info/) resolver (see [DNSCrypt]({{< relref "posts/dnscrypt" >}}))
|
||||
* [CoreDNS](https://coredns.io/) serving
|
||||
[DNS-over-TLS](https://www.rfc-editor.org/rfc/rfc7858) at
|
||||
`dns.dotya.ml:853`, and
|
||||
[DNS-over-HTTPS](https://en.wikipedia.org/wiki/DNS_over_HTTPS) at
|
||||
`https://dns.dotya.ml/dns-query`|`https://dns.dotya.ml:4053/dns-query`
|
||||
([config](https://git.dotya.ml/dotya.ml/coredns)).
|
||||
* [SearXNG](https://github.com/searxng/searxng) *metasearch* engine instance at https://searxng.dotya.ml/
|
||||
* [tmate](https://tmate.io/) server (see https://git.dotya.ml/dotya.ml/tmate)
|
||||
|
||||
also check out [onions 🧅]({{< relref "onions" >}}) to learn about services accessible via TOR.
|
@ -1,18 +0,0 @@
|
||||
---
|
||||
title: "dotya.ml status"
|
||||
date: 2020-03-07T02:13:07+01:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
Any information regarding status of the site and services will be posted here.
|
||||
|
||||
### Security
|
||||
|
||||
* HTTP headers insight as per [Mozilla HTTP Observatory](https://observatory.mozilla.org/analyze/dotya.ml)\
|
||||
Scoring 125 out of 100 points
|
||||
|
||||
* SSL Labs [TLS rating](https://www.ssllabs.com/ssltest/analyze.html?d=dotya.ml): *A+*
|
||||
|
||||
### Uptime
|
||||
|
||||
* dotya.ml services [UptimeRobot stats](https://stats.uptimerobot.com/93yPqFmmx8)
|
56
docker-compose.yml
Normal file
56
docker-compose.yml
Normal file
@ -0,0 +1,56 @@
|
||||
---
|
||||
|
||||
version: '3'
|
||||
services:
|
||||
#reverse-proxy:
|
||||
# image: docker.io/library/traefik:2.9.6
|
||||
# command: --api=false --api.dashboard=false --providers.docker
|
||||
# mem_limit: 64m
|
||||
# networks:
|
||||
# - internal-nw
|
||||
# - default
|
||||
# ports:
|
||||
# - 127.0.0.1:1314:80
|
||||
# restart: always
|
||||
# volumes:
|
||||
# # So that traefik can listen to the Docker events
|
||||
# - /run/docker.sock:/var/run/docker.sock:ro
|
||||
# healthcheck:
|
||||
# # DON'T
|
||||
# # test: "/usr/bin/wget -q -Y off http://localhost:80/about -O /dev/null > /dev/null 2>&1"
|
||||
# # DO:
|
||||
# test: "/usr/bin/wget -q -Y off http://localhost:80/about -O /dev/null 2>&-"
|
||||
# interval: 10s
|
||||
# retries: 20
|
||||
|
||||
homepage:
|
||||
build:
|
||||
context: .
|
||||
image: homepage
|
||||
mem_limit: 8m
|
||||
networks:
|
||||
# - internal-nw
|
||||
- default
|
||||
ports:
|
||||
- 127.0.0.1:1314:1314
|
||||
restart: always
|
||||
#labels:
|
||||
# - traefik.enable=true
|
||||
# - traefik.http.services.homepage.loadbalancer.server.port=1314
|
||||
# - traefik.http.routers.homepage.rule=Host(`localhost`) || Host(`127.0.0.1`) || Host(`homepage`) || Host(`6426tqrh4y5uobmo5y2csaip3m3avmjegd2kpa24sadekpxglbm34aqd.onion`)
|
||||
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "5m"
|
||||
max-file: "5"
|
||||
|
||||
networks:
|
||||
# internal-nw:
|
||||
# internal: true
|
||||
default:
|
||||
|
||||
volumes:
|
||||
none:
|
||||
|
||||
...
|
3
go.mod
Normal file
3
go.mod
Normal file
@ -0,0 +1,3 @@
|
||||
module git.dotya.ml/dotya.ml/homepage
|
||||
|
||||
go 1.20
|
51
layouts/_default/baseof.html
Normal file
51
layouts/_default/baseof.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{.Site.LanguageCode}}">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
{{- with .Site.Params.themeColor }}
|
||||
<meta name="description" content="{{if $.IsHome}}{{ $.Site.Params.description }}{{else}}{{$.Description}}{{end}}">
|
||||
<meta name="theme-color" content="{{.}}">
|
||||
<meta name="msapplication-TileColor" content="{{.}}">
|
||||
{{- end }}
|
||||
{{- partial "structured-data.html" . }}
|
||||
{{- partial "favicons.html" }}
|
||||
<title>{{.Title}}</title>
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Title | safeHTML }}
|
||||
{{ end -}}
|
||||
{{ $style := resources.Get "scss/style.scss" | resources.ExecuteAsTemplate "css/style.css" . | toCSS | minify | fingerprint -}}
|
||||
<link rel="stylesheet" href="{{ $style.Permalink }}" {{ printf "integrity=%q" $style.Data.Integrity | safeHTMLAttr }} crossorigin="anonymous">
|
||||
{{- block "head" . -}}{{- end }}
|
||||
{{- range .Site.Params.customCSS }}
|
||||
<link rel="stylesheet" href="{{ . | absURL }}">
|
||||
{{- end }}
|
||||
{{- if templates.Exists "partials/extra-head.html" -}}
|
||||
{{ partial "extra-head.html" . }}
|
||||
{{- end }}
|
||||
</head>
|
||||
|
||||
<body id="page">
|
||||
{{ block "header" . -}}{{ end -}}
|
||||
{{ block "main" . -}}{{ end -}}
|
||||
{{ block "footer" . -}}{{ end }}
|
||||
|
||||
{{ $main := resources.Get "js/main.js" -}}
|
||||
{{ if .Site.Params.code_copy_button | default true -}}
|
||||
{{ $codeCopy := resources.Get "js/code-copy.js" -}}
|
||||
{{ $script := slice $main $codeCopy | resources.Concat "js/bundle.js" | minify | fingerprint -}}
|
||||
<script src="{{ $script.Permalink }}" {{ printf "integrity=%q" $script.Data.Integrity | safeHTMLAttr }} crossorigin="anonymous"></script>
|
||||
{{ else -}}
|
||||
{{ $script := $main | minify | fingerprint -}}
|
||||
<script src="{{ $script.Permalink }}" {{ printf "integrity=%q" $script.Data.Integrity | safeHTMLAttr }} crossorigin="anonymous"></script>
|
||||
{{ end }}
|
||||
|
||||
{{- partial "analytics.html" . }}
|
||||
{{- if templates.Exists "partials/extra-foot.html" -}}
|
||||
{{ partial "extra-foot.html" . }}
|
||||
{{- end }}
|
||||
</body>
|
||||
|
||||
</html>
|
26
layouts/_default/rss.xml
Normal file
26
layouts/_default/rss.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
|
||||
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
|
||||
<language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
|
||||
<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
|
||||
<webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
|
||||
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
|
||||
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
|
||||
{{ with .OutputFormats.Get "RSS" }}
|
||||
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
|
||||
{{ end }}
|
||||
{{ range .Pages }}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||
{{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
|
||||
<guid>{{ .Permalink }}</guid>
|
||||
<description>{{ .Content | html }}</description>
|
||||
</item>
|
||||
{{ end }}
|
||||
</channel>
|
||||
</rss>
|
@ -1,4 +1,7 @@
|
||||
{{ define "head" }}
|
||||
{{ with .OutputFormats.Get "rss" -}}
|
||||
{{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
|
||||
{{ end -}}
|
||||
{{ if .Site.Params.bgImg -}}
|
||||
<style>.bg-img {background-image: url('{{.Site.Params.bgImg}}');}</style>
|
||||
{{- else if .Site.Params.images -}}
|
||||
@ -27,9 +30,10 @@
|
||||
{{ partialCached "menu.html" . }}
|
||||
</nav>
|
||||
</div>
|
||||
<div id="home-footer">
|
||||
<div id="home-footer" role="contentinfo">
|
||||
<p>
|
||||
© {{ now.Format "2006" }} <a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a>{{ .Site.Params.footerCopyright | safeHTML }} · <a href="https://git.dotya.ml/dotya.ml/dotya_homepage" title="source code" target="_blank" rel="noopener">source</a>
|
||||
© {{ now.Format "2006" }} <a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a>{{ .Site.Params.footerCopyright | safeHTML }} · <a href="https://git.dotya.ml/dotya.ml/homepage" title="source code" target="_blank" rel="noopener">source</a> · <a href="https://status.dotya.ml" title="service status" target="_blank" rel="noopener">status</a>
|
||||
{{- with (not (in (.Site.Params.Language.Get "disabledKinds") "RSS")) }} · <a href="{{ "index.xml" | absLangURL }}" target="_blank" title="rss"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-rss"><path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg></a>{{ end }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,3 +1,3 @@
|
||||
<footer id="site-footer" class="section-inner thin animated fadeIn faster">
|
||||
<p>© {{ now.Format "2006" }} <a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a>{{ .Site.Params.footerCopyright | safeHTML }} · <a href="https://git.dotya.ml/dotya.ml/dotya_homepage" title="source code" target="_blank" rel="noopener">source</a></p>
|
||||
<footer id="site-footer" class="section-inner thin animated fadeIn faster" role="contentinfo">
|
||||
<p>© {{ now.Format "2006" }} <a href="{{ .Site.BaseURL }}">{{ .Site.Author.name }}</a>{{ .Site.Params.footerCopyright | safeHTML }} · <a href="https://git.dotya.ml/dotya.ml/homepage" title="source code" target="_blank" rel="noopener">source</a> · <a href="https://status.dotya.ml" title="service status" target="_blank" rel="noopener">status</a>{{if .Site.Params.enableGitInfo}}<br/><a href="https://git.dotya.ml/dotya.ml/homepage/commit/{{ .GitInfo.Hash }}" target="_blank" rel="noopener">commit {{ .GitInfo.AbbreviatedHash }}</a>{{end}}</p>
|
||||
</footer>
|
||||
|
File diff suppressed because one or more lines are too long
77
layouts/posts/single.html
Normal file
77
layouts/posts/single.html
Normal file
@ -0,0 +1,77 @@
|
||||
{{ define "head" }}
|
||||
{{ if .Params.featuredImg -}}
|
||||
<style>.bg-img {background-image: url('{{.Params.featuredImg}}');}</style>
|
||||
{{- else if .Params.images -}}
|
||||
{{- range first 1 .Params.images -}}
|
||||
<style>.bg-img {background-image: url('{{. | absURL}}');}</style>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
{{ define "header" }}
|
||||
{{ partial "header.html" . }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" }}
|
||||
{{- if (or .Params.images .Params.featuredImg) }}
|
||||
<div class="bg-img"></div>
|
||||
{{- end }}
|
||||
<main class="site-main section-inner animated fadeIn faster">
|
||||
<article class="thin">
|
||||
<header class="post-header">
|
||||
<div class="post-meta"><span>{{ .Date.Format .Site.Params.dateform }}</span></div>
|
||||
<h1>{{ .Title }}</h1>
|
||||
</header>
|
||||
<div class="content">
|
||||
{{ .Content | replaceRE "(<h[1-6] id=\"([^\"]+)\".+)(</h[1-6]+>)" `${1}<a href="#${2}" class="anchor" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path><line x1="8" y1="12" x2="16" y2="12"></line></svg></a>${3}` | safeHTML }}
|
||||
</div>
|
||||
{{- if .Site.Params.relatedPosts }}
|
||||
{{- partial "related-posts.html" . -}}
|
||||
{{- end }}
|
||||
<hr class="post-end">
|
||||
<footer class="post-info">
|
||||
{{- with $.Param "author" }}
|
||||
<p><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-feather"><path d="M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z"></path><line x1="16" y1="8" x2="2" y2="22"></line><line x1="17.5" y1="15" x2="9" y2="15"></line></svg>{{ . }}</p>
|
||||
{{- end }}
|
||||
{{- with .Params.tags }}
|
||||
<p>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-tag meta-icon"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path><line x1="7" y1="7" x2="7" y2="7"></line></svg>
|
||||
{{- range . -}}
|
||||
<span class="tag"><a href="{{ "tags/" | absLangURL }}{{ . | urlize }}">{{.}}</a></span>
|
||||
{{- end }}
|
||||
</p>
|
||||
{{- end }}
|
||||
<p><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file-text"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>{{ i18n "wordCount" . }}</p>
|
||||
<p><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-calendar"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>{{ dateFormat .Site.Params.dateformNumTime .Date.Local }}{{- if .Lastmod }} (last modified {{ dateFormat .Site.Params.dateformNumTime .Lastmod }}){{- end -}}</p>
|
||||
{{- if and .GitInfo .Site.Params.gitUrl }}
|
||||
<p><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-git-commit"><circle cx="12" cy="12" r="4"></circle><line x1="1.05" y1="12" x2="7" y2="12"></line><line x1="17.01" y1="12" x2="22.96" y2="12"></line></svg><a href="{{ .Site.Params.gitUrl -}}{{ .GitInfo.Hash }}" target="_blank" rel="noopener">{{ .GitInfo.AbbreviatedHash }}</a> @ {{ dateFormat .Site.Params.dateformNum .GitInfo.AuthorDate.Local }}</p>
|
||||
{{- end }}
|
||||
</footer>
|
||||
</article>
|
||||
{{- if .Params.toc }}
|
||||
<aside id="toc">
|
||||
<div class="toc-title">{{ i18n "tableOfContents" }}</div>
|
||||
{{ .TableOfContents }}
|
||||
</aside>
|
||||
{{- end }}
|
||||
<div class="post-nav thin">
|
||||
{{- with .NextInSection }}
|
||||
<a class="next-post" href="{{ .Permalink }}">
|
||||
<span class="post-nav-label"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg> {{ i18n "newer" }}</span><br><span>{{ .Title }}</span>
|
||||
</a>
|
||||
{{- end }}
|
||||
{{- with .PrevInSection }}
|
||||
<a class="prev-post" href="{{ .Permalink }}">
|
||||
<span class="post-nav-label">{{ i18n "older" }} <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg></span><br><span>{{ .Title }}</span>
|
||||
</a>
|
||||
{{- end }}
|
||||
</div>
|
||||
<div id="comments" class="thin">
|
||||
{{- partial "comments.html" . -}}
|
||||
</div>
|
||||
</main>
|
||||
{{ end }}
|
||||
|
||||
{{ define "footer" }}
|
||||
{{ partialCached "footer.html" . }}
|
||||
{{ end }}
|
2
layouts/shortcodes/rawhtml.html
Normal file
2
layouts/shortcodes/rawhtml.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!-- raw html -->
|
||||
{{.Inner}}
|
92
main.go
Normal file
92
main.go
Normal file
@ -0,0 +1,92 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
var version = "development"
|
||||
|
||||
//go:embed public/*
|
||||
var embeddedPublic embed.FS
|
||||
|
||||
// bytes of the 404.html page.
|
||||
var b404 []byte
|
||||
|
||||
// usrIP is a good way to read the src IP this way because we trust our proxy.
|
||||
// largely from: https://stackoverflow.com/a/55738279
|
||||
func usrIP(r *http.Request) string {
|
||||
ip := r.Header.Get("x-forwarded-for")
|
||||
if ip == "" {
|
||||
ip = r.Header.Get("x-real-ip")
|
||||
}
|
||||
|
||||
if ip == "" {
|
||||
ip = r.RemoteAddr
|
||||
}
|
||||
|
||||
return ip
|
||||
}
|
||||
|
||||
// notFound writes back 404 and the 404 page.
|
||||
func notFound(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write(b404)
|
||||
}
|
||||
|
||||
// handleNotFound allows us to override the response on e.g. 404.
|
||||
// inspired by https://stackoverflow.com/a/62747667
|
||||
func handleNotFound(fs http.FileSystem) http.Handler {
|
||||
fileServer := http.FileServer(fs)
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
p := r.URL.Path
|
||||
// so as not to allow path traversals.
|
||||
cleanedPath := path.Clean(p)
|
||||
_, err := fs.Open(cleanedPath)
|
||||
if os.IsNotExist(err) {
|
||||
log.Printf("Error 404 Not Found when serving path: %s, cleaned path: %s, IP: %s",
|
||||
p, cleanedPath, usrIP(r))
|
||||
notFound(w, r)
|
||||
return
|
||||
}
|
||||
fileServer.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
// TODO: ENV WHATPORT
|
||||
// TODO: add /ip endpoint that returns the src IP.
|
||||
f404, err := embeddedPublic.ReadFile("public/404.html")
|
||||
if err != nil {
|
||||
log.Fatalf("no 404.html in the folder, weird: %s", fmt.Errorf("err: %w", err))
|
||||
}
|
||||
|
||||
b404 = f404
|
||||
|
||||
root, err := fs.Sub(embeddedPublic, "public")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("Starting app built from revision '%s'\n", version)
|
||||
log.Print("Listening on :1314...")
|
||||
|
||||
// https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/
|
||||
srv := http.Server{
|
||||
ReadTimeout: 15 * time.Second,
|
||||
WriteTimeout: 15 * time.Second,
|
||||
Addr: ":1314",
|
||||
Handler: handleNotFound(http.FS(root)),
|
||||
}
|
||||
|
||||
err = srv.ListenAndServe()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ User-agent: Mediapartners*
|
||||
Disallow: /
|
||||
|
||||
User-Agent: *
|
||||
Disallow: /404.html
|
||||
Disallow: /categories/
|
||||
Disallow: /categories
|
||||
Disallow: /tags
|
||||
|
||||
Sitemap: https://dotya.ml/sitemap.xml
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "",
|
||||
"short_name": "",
|
||||
"name": "dotya.ml",
|
||||
"short_name": "dotya.ml",
|
||||
"start_url":"https://dotya.ml/",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
|
Loading…
Reference in New Issue
Block a user