Compare commits

..

1 Commits

Author SHA1 Message Date
René Jochum 36d9340385
v1.0.5 5 years ago

@ -1,28 +0,0 @@
---
kind: pipeline
type: docker
name: default
platform:
os: linux
arch: amd64
trigger:
event:
- cron
- custom
- tag
steps:
- name: build
image: plugins/docker
settings:
registry: registry.fk.jochum.dev
username: robot$jochum+drone
password:
from_secret: registry.fk.jochum.dev-robot
repo: registry.fk.jochum.dev/jochum/homepage
auto_tag: true
build_args:
- HUGO_VERSION=${DRONE_TAG:1}
- URL=https://jochum.dev

@ -0,0 +1,22 @@
stages:
- name: Build
steps:
- publishImageConfig:
dockerfilePath: ./Dockerfile
buildContext: .
tag: registry.wmk8s.com/rene.jochums.at/homepage:v1.0.5
pushRemote: true
registry: registry.wmk8s.com
- name: Deploy
steps:
- applyYamlConfig:
path: ./deployment.yaml
timeout: 60
notification:
recipients:
- recipient: rene@webmeisterei.com
notifier: local:n-mtzwd
condition:
- Success
- Changed
- Failed

@ -1,20 +1,18 @@
# Build with selfmade hugo
FROM registry.fk.jochum.dev/jochum/hugo:latest
ARG HUGO_VERSION=unknown
ENV HUGO_VERSION ${HUGO_VERSION}
ARG URL=https://example.com
# Build public with hugo
FROM jguyomard/hugo-builder:latest
COPY . /build
WORKDIR /build
RUN /go/bin/hugo -b $URL -v -t persona
# Copy to a caddy container
FROM registry.fk.jochum.dev/docker_hub_cache/library/caddy:alpine
RUN hugo -b https://rene.jochums.at -v -t persona
# Copy to a nginx container
FROM nginx:1.17-alpine
LABEL maintainer="René Jochum <rene@jochum.dev>"
LABEL maintainer="René Jochum <rene@jochums.at>"
COPY docker/caddy/Caddyfile /etc/caddy/
COPY docker/nginx/nginx.conf /etc/nginx/
COPY docker/nginx/default.conf /etc/nginx/conf.d/
COPY --from=0 /build/public/ /usr/share/caddy/
COPY --from=0 /build/public /var/www/rene.jochums.at

@ -1,3 +1,3 @@
#!/bin/sh
podman build --build-arg HUGO_VERSION=1.2.3-development --build-arg URL=http://localhost:8080 -t homepage:latest .
podman run --rm -p "8080:80" homepage:latest
go get github.com/spf13/hugo
$GOPATH/bin/hugo server --bind="::1" -b http://localhost:3031/ -w -D -v -t persona --disableFastRender

@ -8,11 +8,6 @@ canonifyurls: true
PostFormat: true
markup:
highlight:
noClasses: false
lineNos: false
blackfriday:
Fractions: false
hrefTargetBlank: true
@ -20,7 +15,7 @@ blackfriday:
- noEmptyLineBeforeBlock
- hardLineBreak
title: René Jochum
title: Blog of René Jochum
author:
name: René Jochum
@ -40,30 +35,28 @@ params:
ShowTopProfile: true
ShowTopSocial: false
AuthorName: "René Jochum"
# Settings
DateFormat: 2. Jan 2006
edit_link_url: https://git.jochum.dev/jochum/homepage/src/branch/master/content/
description: "Blog of René Jochum - A FOSS enthusiast who's programming since 2002."
logo: "/static/author/jochum_240x240.png"
edit_link_url: https://git.webmeisterei.com/jochum/rene.jochums.at/tree/master/content/
description: "Blogging about Programming, Security, Linux, Networking and Web Apps."
logo: "/static/author/pcdummy_240x240.png"
Social:
bitbucket: "pcdummy"
# gitlab: pcdummy
github: jochumdev
github: pcdummy
# flickr: "pcdummy"
# twitter: "pcdummy"
# facebook: "pcdummy"
linkedin: pcdummy
email: rene@jochum.dev
email: rene@jochums.at
skype: pc-dummy
Authors:
default: jochum
jochum:
default: pcdummy
pcdummy:
Name: "René Jochum"
Link: "/author/jochum/"
Avatar: "/static/author/jochum_240x240.png"
Link: "/author/pcdummy/"
Avatar: "/static/author/pcdummy_240x240.png"
ShortBio: "Is an <a href=\"https://www.gnu.org/philosophy/free-sw\" target=\"_blank\">FOSS</a> enthusiast who has been programming since <a href=\"http://www.vbarchiv.net/tipps/details.php?id=676\" target=\"_blank\">2002</a>, currently he loves to develop in <a href=\"https://www.python.org/\" target=\"_blank\">Python</a> and <a href=\"http://golang.org/\" target=\"_blank\">Go</a>."

@ -1,162 +0,0 @@
---
date: 2023-07-09T00:00:00+02:00
title: René Jochum
description: Is an FOSS enthusiast who has been programming since 2002, currently he loves to develop in Go.
address: Nenzing
email: rene@jochum.dev
phone: +43 664 750 77 653
pgp: F2A7235C1ECFD2F7EADB6D1FF7D906F5E51E8E5E
pgppubfile: /static/author/jochum_pub_pgp.asc
img: /static/author/jochum_240x240.png
---
## About me
I am a passionate programmer with experience in nine different programming languages, of which I excel in three in particular. However, I am not just a technology enthusiast; I am also a social person who enjoys collaborating with others and advocating for their needs.
My experience as a peer has shown me the importance of building positive working relationships and being responsive to the needs of others. I am constantly striving to improve my skills and embrace new challenges to grow both personally and professionally.
### Knowledge
Programming Languages (in order of preference):
Language | Years of Knowledge
--------------|-------------------------------------------------------------------------
Go | [11+](https://github.com/jochumdev/golxml)
Python | [13+](https://github.com/jochumdev/socketrpc)
C++ | [13+](https://github.com/jochumdev/Warzone-QML-Frontend)
PHP | 20+
Javascript | 21+
Visual Basic | [21+](http://www.vbarchiv.net/tipps/details.php?id=680)
VB.NET | 14+
C# | [10+](https://github.com/jochumdev/SharpFlame)
Operating Systems: Linux, OS-X, Windows
Languages: German (first language), English (fluent)
### OpenSource Activities
#### 2023: [go-micro - Development of the upcoming V5](https://github.com/go-orb/go-micro)
[me](https://github.com/jochumdev) and [@Davincible](https://github.com/Davincible) work on the next version of go-micro.
#### 2022: [MicroLobby - 3rd gen lobbyserver for Warzone 2100](https://github.com/jochumdev/microlobby)
MicroLobby is the next, next gen lobbyserver for Warzone 2100 after wzlobbserver-ng.
For this I also have written [jo-micro/router](https://git.jochum.dev/jo-micro/router) and [jo-micro/auth2](https://git.jochum.dev/jo-micro/auth2).
#### 2021: [lql+api](https://git.jochum.dev/jochum/lql-api) + LetsCheck for CheckMK
A interface to the LQL of CheckMK + a Mobile App written in flutter.
#### 2018: LXD Module and States are now part of Salt Fluorine [original PR](https://github.com/saltstack/salt/pull/46231)
Finaly the LXD Module and its States are now part of Saltstack Fluorine. :)
#### 2016 [Presentation at the Linuxday Vorarlberg (German)](https://www.youtube.com/watch?v=0WIyYOsSvQw)
I hold a presentation about Saltstack at the Linuxday Vorarlberg.
#### 2016 - 2017: [saltstack-lxd-formula](https://github.com/saltstack-formulas/lxd-formula)
Working on automatic deployed LXD containers - You say **you want** a Website - **you get** a container with a website in it and ofc all its routing and stuff.
#### 2015 - ca. 2018: [LXD](https://linuxcontainers.org/lxd/)
Smaller stuff.
Intodruced the new [Storage API](https://github.com/lxc/lxd/commits/main?author=rene@jochums.at) for BTRFS and big parts of the LVM version.
#### 2009 - current: IRC
In german theres a wording "Girl for everything" - I help where I can under the name "jochum".
#### 2010 - 2015: [Warzone 2100](http://www.wz2100.net/)
Hosting and maintenance of the website.
Intodruced the [buildbot](http://buildbot.wz2100.net/).
Introduced a new [Lobby Server](https://github.com/jochumdev/wzlobbyserver-ng) in Python.
#### 2002 - ca. 2006: [Apachefriends](https://www.apachefriends.org) XAMPP
Smaller scripts, Moderation in the forums and smaller work.
#### 2002: vb@rchiv
[.m3u reader](http://www.vbarchiv.net/tipps/details.php?id=680)
[ID3v2 Tag reader](http://www.vbarchiv.net/tipps/details.php?id=676)
### CAREER SUMMARY
#### Mai 2023: [Institut für Sozialdienste gGbmH](https://ifs.at)
IT Technican.
#### Januar 2022 - June 2022: [Jochum Development](https://jochum.dev)
Freelance Developer.
#### August 2018 - Oktober 2021: [Webmeisterei GmbH](https://webmeisterei.com)
Worked as DevOp
Tools I have been working with:
- Saltstack
- Debian
- Nutanix CE
- MariaDB Galera Cluster
- Check_MK
- Kubernetes with Rancher
- Gitlab
- borgbackup with borgmatic
- HyCU Backup
#### Mai 2018 - June 2018: [Proxmox Server Solutions GmbH](https://www.proxmox.com/en)
Development in Perl, mainly developed a Client for Proxmox Virtual Environment.
- [pmxc](https://github.com/jochumdev/pmxc)
- [pve-client](https://git.proxmox.com/?p=pve-client.git;a=shortlog)
#### November 2016 January 2017: [Stiftung Maria Ebene](http://mariaebene.at)
Developing interfaces between Apps (SAP / Filemaker / ELGA uvm.).
- [py-restfmclient](https://github.com/jochumdev/py-restfmclient) python client library for Filemaker over [RESTfm](http://restfm.com)
#### August 2015 October 2016: [Webmeisterei GmbH](https://webmeisterei.com)
Worked as Plone developer.
#### June 2013 July 2015: [Stiftung Maria Ebene](http://mariaebene.at)
Apprenticeship as an IT Technican over the [FAB](http://www.fab.at), did a lot of Filemaker developements.
#### October 2012 May 2013: [EPOS Computer](https://www.eposcomputer.com/)
Technical field service as a Apple Service Technican and programming.
#### Januar 2012 June 2012: ITC Energy AG
Filemaker Development of a ERP.
HTML5 2D CAD Tool.
#### Oktober 2008 December 2011: [JR IT Solutions](http://jrit.at)
Self employed as Software developer and IT Consultant.
Developed a inhouse ERP Solution for [InAndOut](https://www.inandout-distribution.com/en/) this Solution is still in use in 2023.
#### July 2007 September 2008: [EPOS Computer](https://www.eposcomputer.com/)
Technical field service as a Apple Service Technican and programming.
#### June 2005 July 2007: Community service + Employment [Stiftung Maria Ebene](http://mariaebene.at)
IT and software developer.
#### Jan 2004 May 2005: [ABF/Landeskrankenhaus Feldkirch](http://www.lkhf.at/)
Development of a MS Access Databases.

@ -0,0 +1,115 @@
---
date: 2018-08-12T00:00:00+01:00
title: René Jochum
description: Is an FOSS enthusiast who has been programming since 2002, currently he loves to develop in Python and Go.
email: rene@jochums.at
phone: 0043 664 750 77 653
pgp: 1B0D 3560 3C4F 372D FF0F CA4E 9E8B 1C32 F5F3 18A9
pgppubfile: /static/author/pcdummy_pub_pgp.asc
img: /static/author/pcdummy_240x240.png
---
## About me
I love to work with Linux, I love Networking I love Programming. If I can FOSS first. Currently my main interest is Cloud computing.
### Knowledge
Programming Languages (in order of preference):
Language | Years of Knowledge
--------------|-------------------------------------------------------------------------
Python | [6+](https://github.com/pcdummy/socketrpc)
Go | [5+](https://github.com/pcdummy/golxml)
C++ (with Qt) | [6+](https://github.com/pcdummy/Warzone-QML-Frontend)
PHP | 13+
Javascript | 14+
Visual Basic | [15+](http://www.vbarchiv.net/tipps/details.php?id=680)
VB.NET | 7+
C# | [4+](https://github.com/pcdummy/SharpFlame)
Operating Systems: Linux, OS-X, Windows
Languages: German (first language), English (fluent but not perfect)
### OpenSource Activities
#### 2018: LXD Module and States are now part of Salt Fluorine [original PR](https://github.com/saltstack/salt/pull/46231)
Finaly the LXD Module and its States are now part of Saltstack Fluorine. :)
#### 2016 [Presentation at the Linuxday Vorarlberg (German)](https://www.youtube.com/watch?v=0WIyYOsSvQw)
I hold a presentation about Saltstack at the Linuxday Vorarlberg.
#### 2016 - 2017: [saltstack-lxd-formula](https://github.com/saltstack-formulas/lxd-formula)
Working on automatic deployed LXD containers - You say **you want** a Website - **you get** a container with a website in it and ofc all its routing and stuff.
#### 2015 - current: [LXD](https://linuxcontainers.org/lxd/)
Smaller stuff.
Intodruced the new [Storage API](https://github.com/lxc/lxd/commits?author=pcdummy) for BTRFS and big parts of the LVM version.
#### 2009 - current: IRC
In german theres a wording "Girl for everything" - I help where I can.
#### 2010 - 2015: [Warzone 2100](http://www.wz2100.net/)
Hosting and maintenance of the website.
Intodruced the [buildbot](http://buildbot.wz2100.net/).
Introduced a new [Lobby Server](https://github.com/pcdummy/wzlobbyserver-ng) in Python.
#### 2002 - ca. 2006: [Apachefriends](https://www.apachefriends.org) XAMPP
Smaller scripts, Moderation in the forums and smaller work.
#### 2002: vb@rchiv
[.m3u reader](http://www.vbarchiv.net/tipps/details.php?id=680)
[ID3v2 Tag reader](http://www.vbarchiv.net/tipps/details.php?id=676)
### CAREER SUMMARY
#### August 2018 - current: [Webmeisterei GmbH](https://webmeisterei.com)
Working as DevOp
Tools working with:
- Saltstack
- Debian
- Nutanix
- MariaDB Galera Cluster
- Check_MK
- Kubernetes with Rancher
- Gitlab
- borgbackup with borgmatic
- HyCU Backup
#### Mai 2018 - June 2018: [Proxmox Server Solutions GmbH](https://www.proxmox.com/en)
Development in Perl, mainly developed a Client for Proxmox Virtual Environment.
- [pmxc](https://github.com/pcdummy/pmxc)
- [pve-client](https://git.proxmox.com/?p=pve-client.git;a=shortlog)
#### November 2016 January 2017: [Stiftung Maria Ebene](http://mariaebene.at)
Developing interfaces between Apps (SAP / Filemaker / ELGA uvm.).
- [py-restfmclient](https://github.com/pcdummy/py-restfmclient) python client library for Filemaker over [RESTfm](http://restfm.com)
#### August 2015 October 2016: [Webmeisterei GmbH](https://webmeisterei.com)
Worked as Plone developer.
#### June 2013 July 2015: [Stiftung Maria Ebene](http://mariaebene.at)
Apprenticeship as IT Technican over the [FAB](http://www.fab.at), did a lot of Filemaker developements.
#### October 2012 May 2013: [EPOS Computer](https://www.eposcomputer.com/)
Technical field service as Apple Service Technican and programming.
#### Januar 2012 June 2012: ITC Energy AG
Filemaker Development of a ERP.
HTML5 2D CAD Tool.
#### Oktober 2008 December 2011: [JR IT Solutions](http://jrit.at)
Self employed as Software developer and IT Consultant.
#### July 2007 September 2008: [EPOS Computer](https://www.eposcomputer.com/)
Technical field service as Apple Service Technican and programming.
#### June 2005 July 2007: Community service + Employment [Stiftung Maria Ebene](http://mariaebene.at)
IT and software developer.
#### Jan 2004 May 2005: [ABF/Landeskrankenhaus Feldkirch](http://www.lkhf.at/)
Development of MS Access Databases.

@ -1,7 +1,7 @@
---
date: 2015-06-12T00:00:00+01:00
title: Imprint
author: jochum
author: pcdummy
---
As this blog is hosted in Germany, it is subject to German media regulations and German media law, the Telemediengesetz (TMG). Please note that your comments have no right to publication on Rene&#39;s blog and might be deleted or shortened by me. All content on this website is subject to German intellectual property law.

@ -1,351 +0,0 @@
---
date: 2020-09-08T23:00:00+01:00
title: Flutter simple router
author: jochum
tags:
- flutter
- Let's Check
---
For the [Let's Check](https://forum.checkmk.com/t/lets-check-an-android-ios-app-for-check-mk/20895/2) App I'm writing I needed a simple router. I haven't found anything that suited my needs so I decided to role my own.
<!--more-->
My implementation supports:
* Regex named Args
* All routes named, this allows usage like: ( `GlobalRouter().buildUri(routeSettingsConnection, buildArgs: {"alias": "JOCHUM"});`)
* Static/Dynamic routes (Static string or Regex)
* Dynamicaly register/deregister routes as needed
#### The Router implementation
I have this saved as **GlobalRouter.dart**
```dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
const routeHome = 'home';
const routeSplash = 'splash';
const routeSettings = 'settings';
const routeSettingsConnection = 'settings_connection';
const routeNotFound = 'not_found';
const routeHosts = 'hosts';
const routeServices = 'services';
const routeHost = 'host';
const routeService = 'service';
typedef RouteBuilder = Route<dynamic> Function(RouteSettings context);
class BuildError implements Exception {
final String message;
BuildError(this.message);
String toString() => message;
}
abstract class GlobalRoute {
String get key;
RouteBuilder get route;
bool matchesRoute(String route);
Map<String, String> extractNamedArgs(BuildContext context);
String buildUri({Map<String, String> buildArgs});
}
class ExactRoute implements GlobalRoute {
final String key;
final String uri;
final RouteBuilder route;
ExactRoute({@required this.key, @required this.uri, @required this.route});
bool matchesRoute(String route) => route == uri;
Map<String, String> extractNamedArgs(BuildContext context) => {};
String buildUri({Map<String, String> buildArgs}) {
assert(buildArgs == null);
return uri;
}
}
class NamedArgsRoute implements GlobalRoute {
final String key;
final String builderUri;
final RegExp regex;
final Map<String, int> args;
final RouteBuilder route;
final bool lastArgOptional;
NamedArgsRoute(
{@required this.key,
@required this.builderUri,
@required this.regex,
@required this.args,
@required this.route,
this.lastArgOptional = false});
bool matchesRoute(String route) {
return regex.hasMatch(route);
}
Map<String, String> extractNamedArgs(BuildContext context) {
var uri = ModalRoute.of(context).settings.name;
if (!matchesRoute(uri)) {
return {};
}
final match = regex.firstMatch(uri);
Map<String, String> result = {};
for (var name in args.keys) {
if (match.groupCount >= args[name] && match.group(args[name]) != null) {
result[name] = Uri.decodeComponent(match.group(args[name]));
}
}
return result;
}
String buildUri({Map<String, String> buildArgs}) {
if (buildArgs == null && lastArgOptional && args.length == 1) {
return builderUri.replaceFirst(r'/{' + args.keys.first + r'}', "");
} else if (buildArgs == null) {
throw new BuildError("BuildArgs are not optional for route '$key'");
}
if (lastArgOptional && buildArgs.keys.length < args.keys.length - 1) {
throw new BuildError("Not all args given for route '$key'");
} else if (buildArgs.keys.length < args.keys.length) {
throw new BuildError("Not all args given for route '$key'");
}
var result = builderUri;
for (var argName in buildArgs.keys) {
result = result.replaceAll('{$argName}', Uri.encodeComponent(buildArgs[argName]));
}
if (lastArgOptional && result.contains('{')) {
result = result.replaceFirst(RegExp(r"(\/?\{\S+\})$"), "");
}
return result;
}
}
GlobalRoute buildRoute(
{@required String key,
@required String uri,
bool lastArgOptional = false,
RouteBuilder route}) {
var matches = RegExp(r"\{(\w+)\}").allMatches(uri);
if (!matches.isNotEmpty) {
return ExactRoute(key: key, uri: uri, route: route);
}
Map<String, int> args = {};
var regex = r'^' + uri.replaceAll("/", r"\/") + r'$';
var i = 1;
for (var match in matches) {
if (lastArgOptional && i == matches.length) {
regex = regex.replaceFirst(r'\/{' + match.group(1) + r'}', r"((\/([^\/]+))?)\/?");
args[match.group(1)] = i + 2;
break;
}
regex = regex.replaceFirst('{' + match.group(1) + '}', r"([^\/]+)");
args[match.group(1)] = i;
i++;
}
return NamedArgsRoute(
key: key,
builderUri: uri,
regex: new RegExp(regex),
args: args,
route: route,
lastArgOptional: lastArgOptional);
}
class GlobalRouter {
Map<String, GlobalRoute> routes = {};
List<GlobalRoute> dynamicRoutes = [];
Map<String, ExactRoute> exactRoutes = {};
final List<String> requiredRoutes = [
routeHome,
routeSplash,
routeSettings,
routeSettingsConnection,
routeNotFound
];
static final GlobalRouter _singleton = GlobalRouter._internal();
GlobalRouter._internal();
factory GlobalRouter() {
return _singleton;
}
bool validateRoutes() {
requiredRoutes.forEach((name) {
if (!routes.containsKey(name)) {
return false;
}
});
return true;
}
void clear() {
routes.clear();
exactRoutes.clear();
dynamicRoutes.clear();
}
void add<T extends GlobalRoute>(T route) {
routes[route.key] = route;
if (route is ExactRoute) {
exactRoutes[route.uri] = route;
} else {
dynamicRoutes.add(route);
}
}
String buildUri(String key, {Map<String, String> buildArgs}) {
return routes[key].buildUri(buildArgs: buildArgs);
}
Map<String, String> extractNamedArgs(BuildContext context, String key) {
return routes[key].extractNamedArgs(context);
}
bool isCurrentRoute(BuildContext context, String key) {
return routes[key].matchesRoute(ModalRoute.of(context).settings.name);
}
Route<dynamic> generateRoute(RouteSettings context) {
if (kDebugMode) {
print("Generating route for '${context.name}'");
}
if (exactRoutes.containsKey(context.name)) {
if (kDebugMode) {
print("... found route: ${context.name}");
}
return exactRoutes[context.name].route(context);
}
for (var route in dynamicRoutes) {
if (route.matchesRoute(context.name)) {
if (kDebugMode) {
print("... found route: ${route.key}");
}
return route.route(context);
}
}
print("... going to 404");
return routes[routeNotFound].route(context);
}
}
```
#### Usage of GlobalRouter
This is how a static route definition looks like:
```dart
class HomeScreen extends BaseSlimScreen {
static final route = buildRoute(
key: routeHome,
uri: "/",
route: (context) => MaterialPageRoute(
settings: context,
builder: (context) => HomeScreen(),
));
```
And this is a Regex Route:
```dart
class HostScreen extends BaseSlimScreen {
static final route = buildRoute(
key: routeHost,
uri: "/conn/{alias}/host/{hostname}",
lastArgOptional: false,
route: (context) => MaterialPageRoute(
settings: context,
builder: (context) => HostScreen(),
));
```
Somewhere I have register Routes with GlobalRouter():
File is **lib/screen/slim/slim_router.dart**
```dart
import '../../global_router.dart';
import 'splash_screen.dart';
import 'home_screen.dart';
import 'settings_screen.dart';
import 'settings_connection_screen.dart';
import 'not_found_screen.dart';
import 'hosts_screen.dart';
import 'services_screen.dart';
import 'host_screen.dart';
import 'service_screen.dart';
export '../../global_router.dart';
void registerSlimRoutes() {
GlobalRouter().add(HomeScreen.route);
GlobalRouter().add(SplashScreen.route);
GlobalRouter().add(SettingsScreen.route);
GlobalRouter().add(SettingsConnectionScreen.route);
GlobalRouter().add(NotFoundScreen.route);
GlobalRouter().add(HostsScreen.route);
GlobalRouter().add(ServicesScreen.route);
GlobalRouter().add(HostScreen.route);
GlobalRouter().add(ServiceScreen.route);
assert(GlobalRouter().validateRoutes());
}
```
In **main.dart** i configure the router:
```dart
Future<void> main() async {
var mediaWidth = MediaQueryData.fromWindow(window).size.width;
mediaWidth >= ultraWideLayoutThreshold
? registerSlimRoutes() // UltraWide
: mediaWidth > wideLayoutThreshold
? registerSlimRoutes() // Wide
: registerSlimRoutes(); // Slim
}
```
And with that GlobalRouter() is in use:
```dart
class App extends StatelessWidget {
App({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
...
onGenerateRoute: (routeContext) =>
GlobalRouter().generateRoute(routeContext),
);
}
}
```
#### License
This is MIT Licensed do whatever you want with it but don't blame me. I hope it helps you to make your own Router.

@ -1,150 +0,0 @@
---
date: 2022-09-04T05:04:00+01:00
title: Kubernetes/k3s Rancher with Traefik for HTTP/3
author: jochum
tags:
- kubernetes
- rancher
- traefik
---
Yesterday a friend of mine [Rei Bauer](https://my.stargazer.at/) told me about HTTP/3 and how much faster it made her website.
She got new tools, I WANT THAT TOO.
For me that wasn't a 5 minutes job as I had to replace [ingress-nginx](https://github.com/kubernetes/ingress-nginx) with [traefik](https://traefik.io/).
<!--more-->
### Remove the current L7 Loadbalancer
- Remove Traefik
I have choosen to not use the k3s/rancher version (v2.6.x) of Traefik but use the latest and greatest (v2.8.x), so i modified my k3s with the following command:
**Do NOT use that command as is**
```bash
curl -sfL https://get.k3s.io | sh -s - server --datastore-endpoint="mysql://k3s:<mysqlpw>@tcp(maxscale-rw.example.com:3306)/k3s" --disable servicelb --disable traefik
```
Let's see what it does:
- *--disable servicelb* - Do not install servicelb, I replaced it with metallb.
- *--disable traefik* - Do not install traefik
When you use the given command (with your own "datastore-endpoint") you will see that you loose access to all L7 Ingresses, so please be aware of that and make sure you have access over ssh to your cluster.
- Remove ingress-nginx
```bash
helm uninstall -n kube-system ingress-nginx
```
If you haven't lost layer 7 access to your cluster in the last step you will loose it now :)
### Install traefik from the upstream sources
- Add the upstream helm catalog
```bash
helm repo add traefik https://helm.traefik.io/traefik
```
- Save my *traefik-values.yaml* somewhere:
```yaml
rbac:
enabled: true
ports:
web:
hostPort: 80
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
hostPort: 443
http3:
advertisedPort: 443
tls:
enabled: true
websecure-udp:
port: 8443
hostPort: 443
protocol: UDP
podAnnotations:
prometheus.io/port: "8082"
prometheus.io/scrape: "true"
providers:
kubernetesIngress:
publishedService:
enabled: true
allowExternalNameServices: true
kubernetesCRD:
allowExternalNameServices: true
priorityClassName: "system-cluster-critical"
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
experimental:
http3:
enabled: true
additionalArguments:
- "--certificatesresolvers.letsencrypt-prod.acme.caserver=https://acme-v02.api.letsencrypt.org/directory"
image:
name: traefik
tag: v2.8.4
proxyProtocol:
enabled: true
trustedIPs:
- 10.0.0.0/8
forwardedHeaders:
enabled: true
trustedIPs:
- 10.0.0.0/8
ssl:
enabled: true
permanentRedirect: true
certResolvers:
letsencrypt-prod:
email: support@jochum.dev
tlsChallenge: true
storage: /data/acme.json
logs:
# general:
# format: json
access:
enabled: true
# format: json
fields:
headers:
defaultmode: drop
names:
User-Agent: keep
Content-Type: keep
RequestLine: keep
persistence:
enabled: true
```
- Change the acme email address there
- Install traefik
```bash
helm install -n kube-system traefik traefik/traefik -f traefik-values.yaml
```
Have fun with Traefik, it's internal ACME resolver and HTTP/3.

@ -1,49 +0,0 @@
---
date: 2022-09-16T04:33:00+01:00
title: Homeserver
author: jochum
tags:
- homeserver
---
My Homeserver runs a lot of Free Open Source Software, maybe you find something for yourself?
<!--more-->
#### Debian GNU/Linux
[Debian](https://debian.org) what to say about Debian, I have it on my Desktop and all of my Servers since around version 4.0. On my Desktop i use Debian Testing/sid.
#### Proxmox VE and Proxmox Backup Server
Im a big fan of [Proxmox](https://proxmox.com/en/), I use theier [Virtual Environment](https://proxmox.com/en/proxmox-ve) which runs both LXC and KVM Machines since a long time and the [Backup Server](https://proxmox.com/en/proxmox-backup-server) since it's out there. It's just ROCK Stable.
#### SUSE Rancher with it's K3S
[k3s](https://k3s.io/) the lightweight alternative to Kubernetes Mainline, you can select your K/V storage, so no etcd which is using all of my disk IO/s :)
#### MariaDB
[MariaDB](https://mariadb.org) power's my K3S and some other stuff
#### PowerDNS with phpIPAM for splitdns
I have all my Domains in a splitdns environment for that I use a [PowerDNS](https://www.powerdns.com/) and [phpIPAM](https://phpipam.net/) as Mangement UI.
#### Unbound DNS Cacher
Rock solid DNS Cacher from cz labs
#### Public Services
- [Drone](https://www.drone.io/) for CI/CD Pipelines
- [Gitea](https://gitea.io/en-us/) my private Github
- [GoHarbor](https://goharbor.io/) docker registry WITH caching of other registries!
- [Traefik](https://traefik.io/) HTTP/3 ready proxy which integrates nicely into Kubernetes.
- [NextCloud](https://nextcloud.com/) Syncing files with it, also using Calobora CODE to have in Browser/online office.
- Mail: Postfix, Dovecot, postfixAdmin, roundcube in custom build containers
- [PostgreSQL](https://www.postgresql.org/) All apps that do Postgres are running on Postgres with help of PostgresOperator from Zalando.
- [pgAdmin](https://www.pgadmin.org/)
- [phpMyAdmin](https://www.phpmyadmin.net/)
- [Vaultwarden](https://github.com/dani-garcia/vaultwarden) - Bitwarden Server replacement in lightweight rust
- [Zitadel](https://zitadel.com/) My IAM of choice

@ -1,246 +0,0 @@
---
date: 2023-07-09T01:53:00+02:00
title: Kubernetes/k3s Rancher with Traefik for HTTP/3 - v20230709
author: jochum
tags:
- kubernetes
- rancher
- traefik
---
A little update to [rancher-traefik](https://jochum.dev/20220904-rancher-traefik/), this contains the values in it's newest format.
<!--more-->
### Install with helm
Save this as **2023-traefik-values.yaml** and adjust it for your needs:
```yaml
additionalArguments: []
additionalVolumeMounts: []
affinity: {}
autoscaling:
enabled: false
certResolvers:
letsencrypt-prod:
email: support@jochum.dev
tlsChallenge: true
httpChallenge:
entryPoint: "web"
# It has to match the path with a persistent volume
storage: /data/acme.json
commonLabels: {}
deployment:
additionalContainers: []
additionalVolumes: []
annotations: {}
dnsConfig: {}
enabled: true
imagePullSecrets: []
initContainers: []
kind: Deployment
labels: {}
lifecycle: {}
minReadySeconds: 0
podAnnotations: {}
podLabels: {}
replicas: 1
shareProcessNamespace: false
terminationGracePeriodSeconds: 60
env: []
envFrom: []
experimental:
kubernetesGateway:
enabled: false
gateway:
enabled: true
plugins:
enabled: false
v3:
enabled: false
http3:
enabled: true
extraObjects: []
globalArguments: []
hostNetwork: false
image:
pullPolicy: IfNotPresent
registry: docker.io
repository: traefik
tag: v2.10.3
name: traefik
ingressClass:
enabled: true
isDefaultClass: true
ingressRoute:
dashboard:
annotations: {}
enabled: false
entryPoints:
- traefik
labels: {}
matchRule: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
middlewares: []
tls: {}
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
logs:
access:
enabled: true
fields:
general:
defaultmode: keep
names: {}
headers:
defaultmode: drop
names:
Content-Type: keep
RequestLine: keep
User-Agent: keep
filters: {}
general:
level: ERROR
metrics:
prometheus:
entryPoint: metrics
nodeSelector: {}
persistence:
accessMode: ReadWriteOnce
annotations: {}
enabled: true
name: data
path: /data
size: 128Mi
podDisruptionBudget:
enabled: false
podSecurityContext:
fsGroupChangePolicy: OnRootMismatch
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532
podSecurityPolicy:
enabled: false
ports:
metrics:
expose: false
exposedPort: 9100
port: 9100
protocol: TCP
traefik:
expose: false
exposedPort: 9000
port: 9000
protocol: TCP
web:
expose: true
exposedPort: 80
port: 80
protocol: TCP
nodePort: 80
websecure:
expose: true
exposedPort: 443
nodePort: 443
http3:
enabled: true
advertisedPort: 443
middlewares: []
port: 443
protocol: TCP
tls:
certResolver: 'letsencrypt-prod'
domains: []
enabled: true
options: ''
priorityClassName: system-cluster-critical
providers:
kubernetesCRD:
allowCrossNamespace: false
allowEmptyServices: false
allowExternalNameServices: true
enabled: true
namespaces: []
kubernetesIngress:
allowEmptyServices: false
allowExternalNameServices: true
enabled: true
namespaces: []
publishedService:
enabled: true
rbac:
enabled: true
namespaced: false
readinessProbe:
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
resources: {}
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
service:
annotations: {}
annotationsTCP: {}
annotationsUDP: {}
enabled: true
externalIPs: []
labels: {}
loadBalancerSourceRanges: []
single: true
spec: {}
type: NodePort
serviceAccount:
name: ''
serviceAccountAnnotations: {}
tlsOptions: {}
tlsStore: {}
tolerations:
- key: CriticalAddonsOnly
operator: Exists
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Exists
topologySpreadConstraints: []
tracing: {}
updateStrategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
volumes: []
forwardedHeaders:
enabled: true
trustedIPs:
- 10.0.0.0/8
global:
cattle:
systemDefaultRegistry: ''
systemProjectId: p-g2j9j
systemDefaultRegistry: ''
proxyProtocol:
enabled: true
trustedIPs:
- 10.0.0.0/8
ssl:
enabled: true
permanentRedirect: true
```
Then run:
```bash
helm uninstall -n kube-system traefik
helm repo update
helm install traefik traefik/traefik -n kube-system -f 2023-traefik-values.yaml
```

@ -1,7 +1,7 @@
---
date: 2019-07-31T00:00:00+01:00
title: Æ-DIR installation
author: jochum
author: pcdummy
tags:
- HOWTO
- Æ-DIR

@ -1,7 +1,7 @@
---
date: 2014-04-12T00:00:00+01:00
title: Afrika und die IT (german)
author: jochum
author: pcdummy
---
Auf der suche nach Afrika Projekten bin ich auf folgende Webseiten gesto&szlig;en:

@ -1,7 +1,7 @@
---
date: 2015-06-14T21:09:00+01:00
title: Atom.io my editor of choice
author: jochum
author: pcdummy
tags:
- atom
- markdown

@ -1,7 +1,7 @@
---
date: 2015-06-14T21:00:00+01:00
title: Diff-configs.sh a nice tool to get your configuration changes
author: jochum
author: pcdummy
tags:
- Ubuntu
- Debian

@ -15,14 +15,14 @@ OpenVSwitch would allow me to add features like **Firewall as a Service** or **I
BUT these servers are all in production, i can&#39;t play on them, this is where [Mininet](http://mininet.org/ "Mininet") comes in use, it allows me to emulate a full network on a single VM, without touching these root Servers.
Have a look at this [Script](https://gist.github.com/jochumdev/9b9d1589289b649d8207 "hetzner.py") if you also need a lab to test your Hetzner Networking.
Have a look at this [Script](https://gist.github.com/pcdummy/9b9d1589289b649d8207 "hetzner.py") if you also need a lab to test your Hetzner Networking.
Setup from start:
1. At first get and install a [Mininet Download and Guide](http://mininet.org/download/ "Mininet Download and Guide") also see this [Guide](http://www.brianlinkletter.com/set-up-mininet/ "Mininet Setup guide by Brian Kletter")
2. Learn howto use Mininet [Sample Workflow.](http://mininet.org/sample-workflow/ "Mininet Sample Workflow")
3. Edit the Script parameters in &quot;[root_network](https://gist.github.com/jochumdev/9b9d1589289b649d8207#file-hetzner-py-L257 "Script root_network")&quot; (get the gw mac with `$ arp -n` on your root.
4. Next copy the [Script](https://gist.github.com/jochumdev/9b9d1589289b649d8207 "Script") to your VM: `$ scp hetzner.py mininet@<vm-ip>:/home/mininet/` (you might want to use sshfs).
3. Edit the Script parameters in &quot;[root_network](https://gist.github.com/pcdummy/9b9d1589289b649d8207#file-hetzner-py-L257 "Script root_network")&quot; (get the gw mac with `$ arp -n` on your root.
4. Next copy the [Script](https://gist.github.com/pcdummy/9b9d1589289b649d8207 "Script") to your VM: `$ scp hetzner.py mininet@<vm-ip>:/home/mininet/` (you might want to use sshfs).
5. Run hetzner.py as root `$ sudo ./hetzner.py`
6. Play arround with it: `h1 ping gw`

@ -1,7 +1,7 @@
---
date: 2014-12-15T00:00:00+01:00
title: Encrypt your Dropbox (or parts of it) on Linux
author: jochum
author: pcdummy
---
#### UPDATE: EncFS is considered to be insecure (see this [Audit](https://defuse.ca/audits/encfs.htm)), i will use eCryptFS instead, see this [manual](https://help.ubuntu.com/community/EncryptedPrivateDirectory). If you still want to use EncFS use [gnome-encfs-manager](http://www.libertyzero.com/GEncfsM/) instead of gnome-encfs below.

@ -1,7 +1,7 @@
---
date: 2015-06-14T19:42:00+01:00
title: Firefox Addons i use
author: jochum
author: pcdummy
tags:
- Firefox Addons
---

@ -1,7 +1,7 @@
---
date: 2015-02-08T13:00:00+01:00
title: First hugo post
author: jochum
author: pcdummy
tags:
- hugo
- atom
@ -9,7 +9,7 @@ tags:
- sublime
- My Blog
---
Today i moved my wordpress blog to hugo, it will allow me to **post faster** use **less resources** and i can **share** my content **on [github](https://github.com/jochumdev/pc-dummy.net)**.
Today i moved my wordpress blog to hugo, it will allow me to **post faster** use **less resources** and i can **share** my content **on [github](https://github.com/pcdummy/pc-dummy.net)**.
I've been using Markdown a lot recently to document my own stuff,
now i'm able to just copy it to my blog and publish it.

@ -1,7 +1,7 @@
---
date: 2018-04-17T22:54:00+02:00
title: gitlab-runner docker with debian systemd
author: jochum
author: pcdummy
tags:
- HOWTO
- Debian
@ -12,12 +12,12 @@ tags:
An howto on systemd with a Debian stretch/buster docker container and Gitlab.
<!--more-->
Find all code on Github [stretch](https://github.com/jochumdev/proxmox-dockerfiles/tree/master/stretch-systemd) and [buster](https://github.com/jochumdev/proxmox-dockerfiles/tree/master/buster-systemd).
Find all code on Github [stretch](https://github.com/pcdummy/proxmox-dockerfiles/tree/master/stretch-systemd) and [buster](https://github.com/pcdummy/proxmox-dockerfiles/tree/master/buster-systemd).
### Debian Stretch
This didn't work at all with systemd from Debian stretch, but as i knew from my LXD experience systemd in stretch is buggy with containers,
so i tried systemd from [stretch-backports](https://github.com/jochumdev/proxmox-dockerfiles/blob/master/stretch-systemd/Dockerfile#L18) which worked well.
so i tried systemd from [stretch-backports](https://github.com/pcdummy/proxmox-dockerfiles/blob/master/stretch-systemd/Dockerfile#L18) which worked well.
Now to have systemd finaly working in a stretch container you need to mount a tmpfs into /run and /run/lock else systemd tries to mount those - fails with permission denied and freezes.

@ -1,7 +1,7 @@
---
date: 2016-07-12T13:00:00+01:00
title: Having fun with Saltstack and ext_pillar mongo
author: jochum
author: pcdummy
tags:
- HOWTO
- saltstack
@ -259,8 +259,8 @@ apt:
This uses the following states:
- [apt](https://github.com/jochumdev/saltstack-apt-formula)
- [network](https://github.com/jochumdev/saltstack-network-formula)
- [apt](https://github.com/pcdummy/saltstack-apt-formula)
- [network](https://github.com/pcdummy/saltstack-network-formula)
- check_mk - not available to public yet.

@ -29,18 +29,18 @@ It's a **step by step guide even for newcomers to Plone**.<!--more-->
- [plonetheme.persona](https://github.com/collective/plonetheme.persona) - Port of the clean and well-readable Persona theme to Plone 5.
- First ported by [@aries1980](https://github.com/aries1980/hugo-theme-persona) to [hugo](https://github.com/spf13/hugo)
- Then improved by [@pcdummy](https://github.com/jochumdev/hugo-theme-persona)
- Now ported to Plone 5 by [@pcdummy](https://github.com/jochumdev/)
- Then improved by [@pcdummy](https://github.com/pcdummy/hugo-theme-persona)
- Now ported to Plone 5 by [@pcdummy](https://github.com/pcdummy/)
- [mockup-highlightjs](https://github.com/collective/mockup-highlightjs) - [highlightjs](https://highlightjs.org/) for plonetheme.persona.
- [rj.site](https://github.com/jochumdev/rj.site) - A simple integration package
- [rj.site](https://github.com/pcdummy/rj.site) - A simple integration package
Currently a very simple integration package that installs `collective.blog` and `plonetheme.persona`.
I plan to extend this via an Upgrade Step to set some options on the site i currently manualy set.
- [rj.buildout](https://github.com/jochumdev/rj.buildout)
- [rj.buildout](https://github.com/pcdummy/rj.buildout)
A buildout based on `starzel/buildout` to generate a Plone site, named last but the root to build
your clone.
@ -58,7 +58,7 @@ sudo apt-get -y install git pwgen
2.) Create a clone of rj.buildout into a folder named `plone`
```bash
git clone https://github.com/jochumdev/rj.buildout.git plone
git clone https://github.com/pcdummy/rj.buildout.git plone
```
3.) Create a virtualenv for the buildout (a Python environment inside "plone")

@ -1,7 +1,7 @@
---
date: 2017-12-14T13:00:00+01:00
title: Using httrack on a Webserver without beeing able to install it
author: jochum
author: pcdummy
tags:
- HOWTO
- GNU/Linux

@ -1,7 +1,7 @@
---
date: 2017-12-08T09:30:00+01:00
title: Install spotify on Debian Buster/Testing
author: jochum
author: pcdummy
tags:
- Debian
- Buster

@ -1,7 +1,7 @@
---
date: 2015-06-14T22:54:00+01:00
title: Install the latest salt-minion
author: jochum
author: pcdummy
tags:
- HOWTO
- Ubuntu

@ -1,7 +1,7 @@
---
date: 2015-04-05T13:00:00+01:00
title: My installation of Ubuntu Mate 14.10 (Utopic)
author: jochum
author: pcdummy
tags:
- HOWTO
- Ubuntu

@ -1,7 +1,7 @@
---
date: 2015-06-10T13:00:00+01:00
title: My installation of Ubuntu Mate 15.04 (Vivid)
author: jochum
author: pcdummy
tags:
- HOWTO
- Ubuntu

@ -1,7 +1,7 @@
---
date: 2019-07-17T00:00:00+01:00
title: Kubernetes-Rancher CI/CD Pipeline
author: jochum
author: pcdummy
tags:
- HOWTO
- Kubernetes
@ -12,8 +12,6 @@ tags:
Today I moved my [gohugo.io](https://gohugo.io/) blog from a lxd hosting to our Kubernetes -dev Cluster at the [Webmeisterei](https://webmeisterei.com).
We have our own [Gitlab](https://git.webmeisterei.com) so and we run our own registry on the -dev Cluster, I thought it will be easy to do so but it wasn't that easy and I lost about 8 Hours until I found out that had to open the required Ports on the Firewall :).
See this works.
<!--more-->
#### Tools in use
@ -85,7 +83,3 @@ notification:
- Changed
- Failed
```
#### If it doesn't trigger
Look at [this](https://forums.rancher.com/t/pipeline-not-triggering/12691/5) if it doesn't trigger your build.

@ -1,7 +1,7 @@
---
date: 2013-02-10T00:00:00+01:00
title: Linux (Gnome) and Android Phones
author: jochum
author: pcdummy
---
Ever wondered Howto Sync your Android 4 ICS Phone with Linux?

@ -1,7 +1,7 @@
---
date: 2016-12-02T07:32:00+01:00
title: LXD and live migration / Canonical needs support for CRIU
author: jochum
author: pcdummy
tags:
- LXD
- CRIU

@ -2,7 +2,7 @@
date: 2015-07-07T13:00:00+01:00
description: This is what i do to install and configure lxd
title: LXD getting started
author: jochum
author: pcdummy
tags:
- HOWTO
- Ubuntu

@ -1,7 +1,7 @@
---
date: 2014-12-15T00:00:00+01:00
title: Froxlor + Nginx + WordPress iThemes Rules
author: jochum
author: pcdummy
tag:
- howto
---

@ -1,7 +1,7 @@
---
date: 2013-02-22T00:00:00+01:00
title: Nice Howto on OpenVPN and KVM (libvirt) bridges.
author: jochum
author: pcdummy
tag:
- howto
---

@ -1,7 +1,7 @@
---
date: 2015-02-23T00:00:00+01:00
title: Home firewall (a pc-engines apu1d4)
author: jochum
author: pcdummy
---
{{< lightslider name="pc-engines_apu1d4" url="data/post/pc-engines_apu1d4.json" >}}

@ -1,7 +1,7 @@
---
date: 2018-04-19T13:55:00+02:00
title: UNOFFICIAL Proxmox with Debian GNU/Linux Buster
author: jochum
author: pcdummy
tags:
- HOWTO
- Debian

@ -1,7 +1,7 @@
---
date: 2015-06-14T00:19:30+01:00
title: Pulseaudio as network audio sender/receiver
author: jochum
author: pcdummy
tags:
- Howto
- Linux

@ -1,562 +0,0 @@
---
date: 2020-05-08T02:21:00+02:00
description: Installing Rancher k3s with MariaDB Galera
tags:
- HOWTO
- Kubernetes
- Galera
title: Howto Install Rancher k3s with MariaDB Galera
---
In this blog Post we gonna install a HA Rancher Kubernetes Cluster with a MariaDB Galera Cluster as Datastore.
<!--more-->
#### Outline
- [Prepare Ubuntu Bionic Server]()
- [Install MariaDB Galera]()
- [Deploy K3S]()
- [Install kubectl and helm]()
- [Install MetalLB]()
- [Install cert-manager for Let's Encrypt]()
- [Install Rancher]()
- [Forward HTTP/HTTPS to the Rancher Load Balancer IP]()
#### Prepare Ubuntu Bionic Server
You need 3 Nodes, 4 CPU, >8GiB RAM, 100GiB Disk, I have 3 Nodes 4 CPU, 24 GiB RAM, 250GiB Disk.
Install Ubuntu on one Server, remove snapd, ufw, cloud-init.
Then clone it and edit /etc/hosts /etc/hostname /etc/netplan/50-cloud-init.yaml and `rm -f /etc/ssh/ssh_host_*` - reboot.
#### Install MariaDB Galera
Install the [MariaDB repo](https://downloads.mariadb.org/mariadb/repositories/#distro=Ubuntu&distro_release=bionic--ubuntu_bionic&mirror=host-europe&version=10.4) on each server.
```bash
sudo apt-get install software-properties-common
sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
sudo add-apt-repository 'deb [arch=amd64] http://ftp.hosteurope.de/mirror/mariadb.org/repo/10.4/ubuntu bionic main'
sudo apt update
sudo apt install mariadb-server mariadb-client mariadb-backup
```
##### Secure MariaDB on each Node
Set Password with mysql_secure_installation:
```bash
pcdummy@rancher01:~$ sudo mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.
Enter current password for root (enter for none):
OK, successfully used password, moving on...
Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.
You already have your root account protected, so you can safely answer 'n'.
Switch to unix_socket authentication [Y/n] n
... skipping.
You already have your root account protected, so you can safely answer 'n'.
Change the root password? [Y/n]
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n] Y
... Success!
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] n
... skipping.
By default, MariaDB comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n] Y
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n] Y
... Success!
Cleaning up...
All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!
```
##### Configure Galera on each Node
Stop Mariadb
```bash
sudo systemctl stop mariadb
```
Liste on all Interfaces (if you want configure it to listen only on a specific address):
```bash
sudo sed -i 's/max_connections\t\t= 100/max_connections\t\t= 1000/g' /etc/mysql/my.cnf
sudo sed -i 's/bind-address\t\t= 127.0.0.1/#bind-address\t\t= 127.0.0.1/g' /etc/mysql/my.cnf
```
Enable Galera, Paste the following into /etc/mysql/mariadb.conf.d/99-cluster.cnf
```INI
[galera]
wsrep_on = on
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_address = gcomm://10.128.1.17,10.128.1.18,10.128.1.19
wsrep_cluster_name = k3s_cluster_0
wsrep_provider_options="gcache.size=512M"
wsrep_sst_method = mariabackup
wsrep_sst_auth = root:SuperSecretRootPassword
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
innodb_doublewrite = 1
binlog_format = ROW
```
And change the ip addresse for `wsrep_cluster_address`
Some tuning if you use this Galera cluster for other purposes
```bash
sudo nano /etc/mysql/mariadb.conf.d/98-tuning.cnf
```
```INI
[mysqld]
key_buffer_size=256M
thread_stack=192K
thread_cache_size=8
max_connections=1000
innodb_buffer_pool_size=2G
query_cache_limit=2M
query_cache_size=0
query_cache_type=0
table_open_cache=128
join_buffer_size=512k
table_definition_cache=-1
performance_schema=ON
innodb_log_file_size=256M
innodb_buffer_pool_instances=2
tmp_table_size=32M
max_heap_table_size=32M
```
##### Bootstrap the cluster
One **one** node run `sudo galera_new_cluster`
One the other 2 nodes run: `sudo systemctl start mariadb.service`
##### Check the MariaDB Galera Cluster
```bash
mysql -u root -p -e "SELECT * FROM information_schema.global_status WHERE variable_name IN ('WSREP_CLUSTER_STATUS','WSREP_LOCAL_STATE_COMMENT','WSREP_CLUSTER_SIZE','WSREP_EVS_REPL_LATENCY','WSREP_EVS_DELAYED','WSREP_READY');"
```
##### Install and configure MaxScale
```bash
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 135659E928C12247
sudo add-apt-repository 'deb [arch=amd64] http://downloads.mariadb.com/MaxScale/2.2/ubuntu bionic main'
sudo apt install maxscale
```
```sql
mysql -u root -p
CREATE USER 'maxscale'@'%' IDENTIFIED BY 'SuperSecretPassword';
GRANT SELECT ON mysql.user TO 'maxscale'@'%';
GRANT SELECT ON mysql.db TO 'maxscale'@'%';
GRANT SELECT ON mysql.tables_priv TO 'maxscale'@'%';
GRANT SELECT ON mysql.roles_mapping TO 'maxscale'@'%';
GRANT SHOW DATABASES ON *.* TO 'maxscale'@'%';
GRANT REPLICATION CLIENT ON *.* TO 'maxscale'@'%';
GRANT SUPER ON *.* TO maxscale@'%';
FLUSH PRIVILEGES;
exit
```
Generate MaxScale Keys **note the encrypted password** and write replace it in /etc/maxscale.cnf
```bash
sudo systemctl stop maxscale
sudo maxkeys /var/lib/maxscale/
sudo maxpasswd 'SuperSecretPassword'
sudo chown maxscale: /var/lib/maxscale/.secrets
```
/etc/maxscale.cnf
```INI
# MaxScale documentation:
# https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale-22/
# Global parameters
#
# Complete list of configuration options:
# https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale-22-mariadb-maxscale-configuration-usage-scenarios/
[maxscale]
threads=auto
# Server definitions
#
# Set the address of the server to the network
# address of a MariaDB server.
#
[server1]
type=server
address=10.248.8.1
port=3306
protocol=MariaDBBackend
[server2]
type=server
address=10.248.8.2
port=3306
protocol=MariaDBBackend
[server3]
type=server
address=10.248.8.3
port=3306
protocol=MariaDBBackend
# Monitor for the servers
#
# This will keep MaxScale aware of the state of the servers.
# MariaDB Monitor documentation:
# https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale-22-mariadb-monitor/
[MariaDB-Monitor]
type=monitor
module=galeramon
servers=server1,server2,server3
user=maxscale
passwd=D83ED4E84351BD822950FDE5C2991889
monitor_interval=2000
# Service definitions
#
# Service Definition for a read-only service and
# a read/write splitting service.
#
# ReadWriteSplit documentation:
# https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale-22-readwritesplit/
[Read-Write-Service]
type=service
router=readwritesplit
servers=server1,server2,server3
user=maxscale
passwd=D83ED4E84351BD822950FDE5C2991889
# This service enables the use of the MaxAdmin interface
# MaxScale administration guide:
# https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale-22-maxadmin-admin-interface/
[MaxAdmin-Service]
type=service
router=cli
# Listener definitions for the services
#
# These listeners represent the ports the
# services will listen on.
#
[Read-Write-Listener]
type=listener
service=Read-Write-Service
protocol=MariaDBClient
port=4006
[MaxAdmin-Listener]
type=listener
service=MaxAdmin-Service
protocol=maxscaled
socket=default
```
```bash
sudo systemctl start maxscale
sudo systemctl enable maxscale
```
##### Create the k3s Database
One one node run:
```bash
mysql -u root -p
```
```sql
CREATE DATABASE `k3s`;
GRANT ALL PRIVILEGES ON `k3s`.* TO 'k3s'@'%' IDENTIFIED BY '<superSecret>';
```
#### Deploy k3s
Install k3s one each nodes, one after another:
```bash
curl -sfL https://get.k3s.io | sh -s - server --datastore-endpoint="mysql://k3s:SuperSecretPassword@tcp(localhost:4006)/k3s" --no-deploy servicelb --no-deploy traefik
```
Check the nodes after.
```bash
sudo k3s kubectl get nodes
```
One one node copy the config (I choose node1 for that):
```bash
mkdir ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown -R $(whoami): ~/.kube
```
#### Install kubectl and helm
Install kubectl
```bash
sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
```
Install helm to ~/bin
```bash
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
```
#### Install MetalLB
Install MetalLB (change the address range!)
See: [metallb install](https://metallb.universe.tf/installation/)
```bash
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
# On first install only
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
```
metallb.yaml -> kubectl apply -f metallb.yaml
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 10.248.11.1-10.248.11.253
```
Check the deployment
```bash
kubectl get pods -n metallb-system -l app=metallb -o wide
```
#### Install cert-manager for Let's Encrypt
```bash
kubectl create namespace cert-manager
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.crds.yaml
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v0.15.0
```
```bash
$ kubectl get pods --namespace cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-6bcdf8c5cc-5bcrg 1/1 Running 0 54s
cert-manager-cainjector-6659d6844d-zrr5h 1/1 Running 0 54s
cert-manager-webhook-547567b88f-ptrlg 1/1 Running 0 54s
```
#### Install Nginx
```bash
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace kube-system \
--set controller.image.runAsUser=101 \
--set defaultBackend.enabled=false
```
#### Install Rancher
```bash
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
helm repo update
kubectl create namespace cattle-system
helm install rancher rancher-latest/rancher \
--namespace cattle-system \
--set hostname=rancher.example.org \
--set ingress.tls.source=letsEncrypt \
--set letsEncrypt.email=support@example.org
```
```bash
$ kubectl -n cattle-system rollout status deploy/rancher
Waiting for deployment "rancher" rollout to finish: 0 of 3 updated replicas are available...
Waiting for deployment "rancher" rollout to finish: 1 of 3 updated replicas are available...
Waiting for deployment "rancher" rollout to finish: 2 of 3 updated replicas are available...
deployment "rancher" successfully rolled out
```
#### Forward HTTP/HTTPS to the Rancher Load Balancer IP
```bash
$ kubectl -n kube-system describe service/traefik
Name: traefik
Namespace: kube-system
Labels: app=traefik
chart=traefik-1.81.0
heritage=Helm
release=traefik
Annotations: field.cattle.io/publicEndpoints:
[{"addresses":["10.128.3.1"],"port":80,"protocol":"TCP","serviceName":"kube-system:traefik","allNodes":false},{"addresses":["10.128.3.1"],...
Selector: app=traefik,release=traefik
Type: LoadBalancer
IP: 10.43.47.63
LoadBalancer Ingress: 10.128.3.1
Port: http 80/TCP
TargetPort: http/TCP
NodePort: http 32316/TCP
Endpoints: 10.42.0.6:80
Port: https 443/TCP
TargetPort: https/TCP
NodePort: https 30752/TCP
Endpoints: 10.42.0.6:443
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal IPAllocated 16m metallb-controller Assigned IP "10.128.3.1"
Normal nodeAssigned 3m10s (x5 over 16m) metallb-speaker announcing from node "rancher01"
```
Here the IP is 10.128.3.1 i forward HTTP (80) and HTTPS (443) to it.
Wait for the Let's Encrypt Cert
```bash
$ kubectl -n cattle-system describe certificate
Name: tls-rancher-ingress
Namespace: cattle-system
Labels: app=rancher
chart=rancher-2.4.3
heritage=Tiller
release=rancher
Annotations: <none>
API Version: cert-manager.io/v1alpha2
Kind: Certificate
Metadata:
Creation Timestamp: 2020-05-07T23:07:41Z
Generation: 1
Owner References:
API Version: extensions/v1beta1
Block Owner Deletion: true
Controller: true
Kind: Ingress
Name: rancher
UID: 625bd78c-819a-4ba5-8ed0-4e8cf0497860
Resource Version: 23050
Self Link: /apis/cert-manager.io/v1alpha2/namespaces/cattle-system/certificates/tls-rancher-ingress
UID: 6e0886ec-8b2d-4459-8c60-f994f269a146
Spec:
Dns Names:
rancher.example.org
Issuer Ref:
Group: cert-manager.io
Kind: Issuer
Name: rancher
Secret Name: tls-rancher-ingress
Status:
Conditions:
Last Transition Time: 2020-05-07T23:07:41Z
Message: Waiting for CertificateRequest "tls-rancher-ingress-2753661366" to complete
Reason: InProgress
Status: False
Type: Ready
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal GeneratedKey 18m cert-manager Generated a new private key
Normal Requested 18m cert-manager Created new CertificateRequest resource "tls-rancher-ingress-2753661366"
```
I had some troubles with cert-manager where it wasn't able to access http://<rancher-FQDN> without that it is not able to generate the certificate.
#### Links
[kauri.io](https://kauri.io/38-install-and-configure-a-kubernetes-cluster-with/418b3bc1e0544fbc955a4bbba6fff8a9/a) - Some Informations from there
[howtoforge Galera](https://www.howtoforge.com/how-to-setup-mariadb-galera-multi-master-synchronous-replication-using-debian-10/) - Install Galera

@ -1,7 +1,7 @@
---
date: 2018-12-12T00:00:00+01:00
title: refugeejob.at - Eine neue Plattform die Arbeitgeber und Flüchtlinge in Österreich verbinden soll
author: jochum
author: pcdummy
tag:
- Social
- Flucht und Arbeit

@ -1,7 +1,7 @@
---
date: 2014-12-15T00:00:00+01:00
title: Restore lost data with Photorec
author: jochum
author: pcdummy
tag:
- howto
- photorec

@ -1,7 +1,7 @@
---
date: 2015-01-10T00:00:00+01:00
title: Save some bandwith with squid as transparent proxy and apt-cacher-ng as peer.
author: jochum
author: pcdummy
tag:
- howto
---

@ -1,7 +1,7 @@
---
date: 2013-01-26T00:00:00+01:00
title: Syscp to Foxlor move on Ubuntu 12.10 with high security.
author: jochum
author: pcdummy
tag:
- howto
---

@ -1,7 +1,7 @@
---
date: 2019-08-05T00:00:00+01:00
title: Todoist <-> Taskwarrior Sync
author: jochum
author: pcdummy
tags:
- Todoist
- Taskwarrior

@ -1,7 +1,7 @@
---
date: 2013-01-28T00:00:00+01:00
title: T Surge's introduction to Virtualbox (Run Windows Virtual on top of Linux)
author: jochum
author: pcdummy
---
Virtual Box (VBox in short) from Oracle is a great technology that helps us to install multiple operating systems on a machine and run them side by side. Hence it is called a Virtualization Software.

@ -1,7 +1,7 @@
---
date: 2013-08-13T00:00:00+01:00
title: Ubuntu 13.04 und Postfix 2.10
author: jochum
author: pcdummy
---
Nachdem ich jetzt einen Tag nach einer L&ouml;sung gesucht warum mein Postfix immer ein 5.7.1 Relay Access Denied ausspuckt... hier die L&ouml;sung:

@ -1,7 +1,7 @@
---
date: 2015-01-25T14:00:00+01:00
title: Prepare a minimal lxc image for salt
author: jochum
author: pcdummy
tags:
- HOWTO
- Ubuntu

@ -1,7 +1,7 @@
---
date: 2015-01-25T13:00:00+01:00
title: Install lxc and prepare it for a unprivileged user
author: jochum
author: pcdummy
tags:
- HOWTO
- Ubuntu

@ -1,7 +1,7 @@
---
date: 2018-04-22T21:24:00+02:00
title: "vcs-mirrors: Git/Bazaar/SVN mirroring"
author: jochum
author: pcdummy
tags:
- GIT
- VCS
@ -13,7 +13,7 @@ As Gitlab CE (Community Edition) does not support Mirroring people came up with
one i found fast is: [gitlab-mirrors](https://github.com/samrocketman/gitlab-mirrors/) but i had troubles
with it (it did always prune) so i decided to write my own python-only fork of it.
I came up with [vcs-mirrors](https://git.jochum.dev/jochum/vcs-mirrors) which i released on [PyPi](https://pypi.org/project/vcs-mirrors/).
I came up with [vcs-mirrors](https://git.lxch.eu/pcdummy/vcs-mirrors) which i released on [PyPi](https://pypi.org/project/vcs-mirrors/).
<!--more-->
### Requirements
@ -24,12 +24,12 @@ I came up with [vcs-mirrors](https://git.jochum.dev/jochum/vcs-mirrors) which i
### Features
- Mirror different types of source repositories: Bazaar, Git, Subversion. Mirror all into git.
- GitLab mirror adding.
- When adding a mirror if the project doesn't exist in GitLab it will be auto-created.
- Set project creation defaults (e.g. issues enabled, wiki enabled, etc.)
- Github mirror adding.
- Same as with Gitlab.
- mirror anything to Git (not just Gitlab and Github).
- Update a single mirror.
- Update all known mirrors.
* Mirror different types of source repositories: Bazaar, Git, Subversion. Mirror all into git.
* GitLab mirror adding.
* When adding a mirror if the project doesn't exist in GitLab it will be auto-created.
* Set project creation defaults (e.g. issues enabled, wiki enabled, etc.)
* Github mirror adding.
* Same as with Gitlab.
* mirror anything to Git (not just Gitlab and Github).
* Update a single mirror.
* Update all known mirrors.

@ -1,7 +1,7 @@
---
date: 2015-06-14T00:15:30+01:00
title: Mass convert WMA to mp3
author: jochum
author: pcdummy
tags:
- Howto
- Linux

@ -1,7 +1,7 @@
---
date: 2013-01-28T00:00:00+01:00
title: Youtube and youtube-mp3.org
author: jochum
author: pcdummy
---
Today i tried to Download some great songs from one of my favorite Artists, [Alex Boyle.](https://www.youtube.com/user/ALEXBOYETV)<!--more-->

@ -0,0 +1,88 @@
apiVersion: v1
kind: List
items:
- apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
generation: 3
name: nginx
namespace: rene-jochums-at
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
container: nginx
template:
metadata:
labels:
container: nginx
spec:
containers:
- image: registry.wmk8s.com/rene.jochums.at/homepage:v1.0.5
imagePullPolicy: Always
name: nginx
resources: {}
securityContext:
allowPrivilegeEscalation: false
capabilities: {}
privileged: false
procMount: Default
readOnlyRootFilesystem: false
runAsNonRoot: false
stdin: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
tty: true
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: wmk8s
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
- kind: Service
apiVersion: v1
metadata:
name: nginx
spec:
type: ClusterIP
selector:
workloadID_nginx: "true"
ports:
- protocol: TCP
port: 80
targetPort: 80
- kind: Ingress
apiVersion: extensions/v1beta1
metadata:
annotations:
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
generation: 2
name: website
namespace: rene-jochums-at
spec:
rules:
- host: rene.jochums.at
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
path: /
tls:
- hosts:
- rene.jochums.at
secretName: website-prod-tls

@ -0,0 +1,141 @@
#!/bin/bash
# This script will make a best-effort attempt at showing modifications
# to package-provided config files on a Debian system.
#
# It's subject to some pretty significant limitations: most notably,
# there's no way to identify all such config files. We approximate the
# answer by looking first at dpkg-managed conffiles, and then hoping
# that most of the time, if maintainer scripts are managing files
# themselves, they're using ucf. So, DO NOT TRUST THIS SCRIPT to find
# everything... but it should help to find most customisation.
# Set this non-empty to see a diff against empty for apparently-deleted
# files; leave it empty for a single 'file deleted' note.
diff_empty=
# Space-separated list of directory *trees* to be searched for package
# files. This is the only means of locating packages that can't be
# installed by apt. Note that we do a recursive search in here *before*
# we ask apt to download the package; don't point it at a stupidly-large
# tree.
local_packages="/var/cache/puppet"
package_version() {
pkg="$1"
dpkg-query -W -f='${Version}\n' "$pkg"
}
# I've made no attempt to create a sensible overall ordering; we keep
# files grouped by package within a particular section, then hope that
# most packages won't mix config file types.
#############
# conffiles
package_file() {
pkg="$1"
exec 3< <(dpkg-query -W -f='${Version} ${Architecture} ${Status}\n' "$pkg")
read -u3 version arch status
if [ "$status" != "install ok installed" -o -z "$version" ]; then
# Package isn't actually installed; ignore it.
exit 0
fi
basename="${pkg}_${version//:/%3a}_${arch}.deb"
filename="/var/cache/apt/archives/$basename"
if [ -f "$filename" ]; then
echo "$filename"
exit
fi
found="$(find $local_packages -name "$basename" -print -quit)"
if [ -n "$found" ]; then
echo "$found"
exit
fi
if [ "$UID" -gt 0 ]; then
echo "Package ${pkg} (${version}, ${arch}) is not available; need to install, but not root" >&2
exit 1
fi
apt-get -qq --download-only --reinstall install "${pkg}=${version}"
if [ -f "$filename" ]; then
echo "$filename"
else
echo "Failed to download ${pkg} (${version}, ${arch})" >&2
exit 1
fi
}
original_content() {
pkg="$1"
file="$2"
deb="$(package_file "$pkg")"
if [ "$?" -ne 0 -o -z "$deb" ]; then
exit 1
fi
dpkg-deb --fsys-tarfile "$deb" | tar -x -O ".$file"
}
dpkg-query -W -f='${Conffiles}\n' '*' |
awk 'OFS=" "{print $2,$1}' |
md5sum -c 2>/dev/null |
awk -F': ' '$2 !~ /OK/{print $1}' |
xargs dpkg -S |
sort -u |
awk -F ': ' 'OFS=" "{print $1,$2}' |
while read pkg file; do
if [ ! -f "$file" -a -z "$diff_empty" ]; then
echo "Deleted: $file (from $pkg)"
else
content="$(original_content "$pkg" "$file")"
if [ "$?" -eq 0 ]; then
echo "package $pkg"
diff -u --new-file --report-identical-files --label "$pkg $(package_version "$pkg")" <(echo "$content") "$file"
else
echo "Failed to load original for $file from $pkg"
fi
fi
echo
done
#######
# ucf
md5sum -c /var/lib/ucf/hashfile 2>/dev/null |
awk -F': ' '$2 !~ /OK/{print $1}' |
xargs ucfq -w |
sort -t ':' -k 2,1 | uniq |
awk -F: 'OFS=" " {print $1,$2}' |
while read file pkg; do
if [ ! -f "$file" -a -z "$diff_empty" ]; then
echo "Deleted: $file (from ${pkg:-??})"
else
cache="/var/lib/ucf/cache/${file//\//:}"
if [ -f "$cache" ]; then
if [ -n "$pkg" ]; then
echo "package $pkg"
label="$pkg $(package_version "$pkg")"
else
label="original"
fi
diff -u --new-file --report-identical-files --label "$label" "$cache" "$file"
else
echo "Failed to load original for $file from ${pkg:-??}"
fi
fi
echo
done

@ -1,19 +0,0 @@
:80 {
log
# Set this path to your site's directory.
root * /usr/share/caddy
# Compress responses according to Accept-Encoding headers
encode zstd gzip
# Client side caching
@static {
file
path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.woff2
}
header @static Cache-Control max-age=31536000
# Enable the static file server.
file_server
}

@ -0,0 +1,8 @@
server {
listen 80 default_server;
error_log /dev/stderr;
access_log /dev/stdout;
root /var/www/rene.jochums.at;
}

@ -0,0 +1,30 @@
user nginx;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 15;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log off;
error_log off;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
open_file_cache max=100;
client_body_temp_path /tmp 1 2;
client_body_buffer_size 256k;
client_body_in_file_only off;
}

@ -2,10 +2,7 @@
<div class="sidebar_wraper">
<div class="sidebar_inner">
<div class="text_widget">
<p>&copy; 2013-2022 by René Jochum, under a <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank">CC BY 4.0</a> license.</p>
</div>
<div class="text_widget">
<p>v{{ os.Getenv "HUGO_VERSION" }}</p>
<p>&copy; 2015-2018 by René Jochum, under a <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank">CC BY 4.0</a> license.</p>
</div>
</div>
</div>

@ -25,7 +25,7 @@
</li>
<li><a href="shortcode.html">Shortcode</a></li>
<li><a href="#">Archives</a></li> -->
<li><a href="/author/jochum/">About me</a></li>
<li><a href="/author/pcdummy/">Contact</a></li>
<li><a href="/imprint/">Imprint</a></li>
</ul>
</div>

@ -1,6 +1,11 @@
<div class="home_single_post comment_area">
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-8 col-lg-8 col-xs-offset-0 col-sm-offset-2 col-md-offset-2 col-lg-offset-2">
{{"<!-- begin comments //-->" | safeHTML}}
<section id="isso-thread">
</section>
{{"<!-- end comments //-->" | safeHTML}}
</div>
</div>
</div>

@ -1,10 +1,3 @@
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9ET9Z12C0F"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-9ET9Z12C0F');
</script>
<!-- EDN GTAG -->
{{ "<!-- isso -->" | safeHTML }}
<script data-isso="{{ .Site.BaseURL }}isso/" src="{{ .Site.BaseURL }}isso/js/embed.min.js"></script>
{{ "<!-- end isso -->" | safeHTML }}

@ -1,4 +0,0 @@
#!/bin/bash
podman build --rm --build-arg=URL=http://localhost -t homepage:latest .
podman run --rm -p "80:80" homepage:latest

@ -0,0 +1 @@
google-site-verification: googled7a55c2994884381.html

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/jo-micro/auth2 git https://git.jochum.dev/jo-micro/auth2.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/auth2'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/auth2">project page</a>...
</body>
</html>

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/jo-micro/buncomponent git https://git.jochum.dev/jo-micro/buncomponent.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/buncomponent'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/buncomponent">project page</a>...
</body>
</html>

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/jo-micro/components git https://git.jochum.dev/jo-micro/components.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/components'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/components">project page</a>...
</body>
</html>

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/jo-micro/geoip git https://git.jochum.dev/jo-micro/geoip.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/geoip'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/geoip">project page</a>...
</body>
</html>

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/jo-micro/logruscomponent git https://git.jochum.dev/jo-micro/logruscomponent.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/logruscomponent'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/logruscomponent">project page</a>...
</body>
</html>

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/jo-micro/router git https://git.jochum.dev/jo-micro/router.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/router'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/router">project page</a>...
</body>
</html>

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/jo-micro/settings git https://git.jochum.dev/jo-micro/settings.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/jo-micro/settings'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/jo-micro/settings">project page</a>...
</body>
</html>

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/orb/config git https://git.jochum.dev/orb-org/config.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/orb-org/config'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/orb-org/config">project page</a>...
</body>
</html>

@ -1,9 +0,0 @@
<html>
<head>
<meta name="go-import" content="jochum.dev/orb/orb git https://git.jochum.dev/orb-org/orb.git">
<meta http-equiv="refresh" content="0;URL='https://git.jochum.dev/orb-org/orb'">
</head>
<body>
Redirecting you to the <a href="https://git.jochum.dev/orb-org/orb">project page</a>...
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

@ -1,51 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGMb6WMBEADTv3wx85Yudfzb8uiI/fIuEMVgnpXwdp/Wue5XQp9eJyK+lxRM
oB3nwcS1S1Y3F6dZIrX7bWAWiFbYsn3Q6EfmE2w5xTtSQ/QEoZ0OZmxEFZs313Rc
6wvraYgwX9Dz8vuA85w/FLwD1O7jSuBApx3p+04YlLoqJUXRBYbGYwSU+PgUMHZN
td/1eh2U1OQzCuI+SBeYOR5pUbobodxS9dEkw/9sGtNHWnn2sRwEHrnIgXk/c86L
bQ8g8h+7AV1ehW9QMBex+3heY6oMTYiSrVa1WHgZ1fC8+abrDtq8Dmv/xozRB/X0
Qn1RrnKVqnUrvSRNaDKY2wQ+BLvBPlqHdilDAZFBImjs7Eo4BL8BrcXDgni4yKQZ
ATH5PJe9XlS7L+o2Hh1P44j8GSQO6fFLmqXsIYI5NnumKLejjY4rbioh3THyMZNG
ntBMCbSdsR4M4w5YG73OkJQUCNRgUISUyU2j+AoTDB1lSGJRZVYsNoLXfZ9H40jl
set+YrO1mktH3v3bUYjtIWUIVblQf8uFQBppAXHwTlbo0BFDpElCdDZw4mDOqec7
5ebIhVq6r9F3S5AvEv0V1EyIIdGbOQEyFUUGbd7rkM2I+WldEwZXJcnRy/Dul9Sn
r4UE/nJxTDmHuNaRYwHFYvzNb+WpojiZFd/eH9gha2iMoJpw9yTpD52J0wARAQAB
tB5SZW7DqSBKb2NodW0gPHJlbmVAam9jaHVtLmRldj6JAk4EEwEKADgWIQTypyNc
Hs/S9+rbbR/32Qb15R6OXgUCYxvpYwIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIX
gAAKCRD32Qb15R6OXoA3D/9wbf0k7ilyVbXXs1SVYn+LCP6l1XyJLgf3scklLCkL
rjZCJjjCXiVz97AD8mkXiZvNDXjiKZg1rao+3d7q/JU597NAhTNXsg2l075c9ZDe
tA2S3GmCNql67+egU9fg7Fxpa1kvHXgjh85HDRrXKGjEQYCpkXySIR2cmFsyK19w
9v58oNR2vYBrTT8vL0vV3YvIvRlo98cp/KuL9bE7c79VIT3uB6ZltW6TsXzHVByX
UIXkuX640UA0pIWPeyws2o4r1AKHTnQ7atwkn1itAh7EdUpNuprrLAeQaYfjylsx
rwxHH8vxj31OASVMQfmXbj2pBrgM3gBPXUHWoULtEp+tJwOce7kPAkbMu5+F0WRZ
QTaaMyBUY5OPljBwLvsFiwM1d0SSbty9FXBPrM7CJQDK+37i9k8U8vUfA17LxorL
mOTxwm1Jd4U1V970wvY56a0+zpYpWrL0q36I4sSEYyhOJhezPgLssKMm3sqd9vFn
MWSq72vn3Ivwhn+lnUCzcECvmpHHeENWrtCBVwj3jyMZoh+k2yMm13LKDI36kiM/
l7bKlockBc/T3D/qnYfT27zeHxvYmwWLNDohXRKoGNJ2wN2TwMqUSD+5V6JI8gyH
fjMYRNtSfJLmCu9LZ//kLMG4ssBsmkGKu699/AGJolb8tB0y3GuM4gMGw+hgQNW8
DbkCDQRjG+ljARAAnrNPqN4IDb5KRJFIGBuWSe/9uELYhydN1rAoPiyYGrxulNG1
7C7QWjC9fUTKGfUE2y14mtw6x1zztSPe8yhn65A5KLAXH7sJpEoJY/3QrqYx82Fc
x8fzO7LzeYmA/BaRXL359hbzqj6SVX72xduEwiEZkIlSGAXxdzc31a1lZp9vICVK
rlLA2iXX23HnnvUMN5WA3Z6EBfzLeC3IU07OkpnRer/o62Moaoqp4EeCFGF3l81/
CBBk3QySIHxVLkh1/jXEzCmwsEgpuTq784d5HMeM3LqwYM/0Cx7xc38Ogsh8PVt3
5/wXenaKSKXawnuYCcf+0ayQ9WPdtpNnIslR6VfPPSSJhpcVON4pqjKl6qMo9+or
bfIomkodrb1YAQkIwOhRno34JnMabSP3y6NzNlBkuLPoV/XcUBSW7+iA/nTVqKBy
Y4DOlBNBn9dX8Drd8GyzN5fPiyxIBqY4rD0Vz2W9AswCHR8Ec5MFVs6udg7kST6r
ew9njXhxGQg4i9dlD2zsth/jxbfXtPE8LXxu3EmJR4FAQyTvIDCBdAh3+27dKC1w
wYp9ln1GLsARIS9JfWwQVvCtvFdMgjybePXguUPDOD7QmtLSMIrSR/OGjfrtUGo7
B3q5y6jXAp5qglogjcTW3SYeuPVyWKjkHjsdxePnwZ+ub/xKdIhtKhtkQEkAEQEA
AYkCNgQYAQoAIBYhBPKnI1wez9L36tttH/fZBvXlHo5eBQJjG+ljAhsMAAoJEPfZ
BvXlHo5eh4kP/18XXq3Nu93LFEiJpydTwKfrXUqrl44Y15nRU31MiB5cxAhJ3YJu
K+HvG3luZg00U3FFhr4ybtaJcGul4KgVmi5LcNXgf6ZiVRJhiNnzoPCYuUtA8yxu
9NVhlWi24TgOA2QUekigAeMjlr101yntwaxMN3SwxoGuVuJTp1OSj2WFuneYlKyd
FEkXSq5wvufEI63uKwNjWhTCObNV6G+WdG4RHIbuDAcemOW8OKxlvtdO+gOcDB9B
I8kDOmRO3OvT00EPzb+F3OeCFHezV+2YsKnFKJKNTPM/x1NyPEQnki93DnlPhqY2
kRGDgU8YOunl/HN0sCaXH1pyz8+dkpuueOQVSMHRectstKJ4DP/3PXSbFILwgWkK
KHmR+39wvjKkAn5OgbInIbD21piGntYmLFZJQjvATm5jFVBkMzA17B/Y5hCr78Nl
1XxOJD502HhD0iMbScGmU6/7VKGGWrbKDNrONgaSoCFHQI36zKE4p1rqsCHXBbJm
WtsY/pWqn9ky+k8K3bFsQrAvLDR0jSymtty5/Jd9IaICZgBzmy2Ts1lycjZK3tL8
K77c6y+ceVGc87mDMM3ytzLydlK9CNfOPfA0v9L2dQOxWUTgWi3UcFcYI+6Cy3b5
DfHrb9uRZIpscUG6RNX+kO7uGlFwmYirUPnPjIasM0a7fZOwsJmLoDyH
=WT8e
-----END PGP PUBLIC KEY BLOCK-----

@ -1 +0,0 @@
node_modules/

@ -0,0 +1,9 @@
[submodule "vendor/lightslider"]
path = vendor/lightslider
url = https://github.com/sachinchoolur/lightslider.git
[submodule "vendor/lightGallery"]
path = vendor/lightgallery
url = https://github.com/sachinchoolur/lightGallery.git
[submodule "vendor/fontawesome"]
path = vendor/fontawesome
url = https://github.com/FortAwesome/Font-Awesome.git

@ -1,41 +0,0 @@
module.exports = function (grunt) {
'use strict';
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.initConfig({
copy: {
main: {
files: [
// jQuery
{ expand: true, flatten: true, src: ['node_modules/jquery/dist/jquery.min.js'], dest: 'static/static/js/' },
// Bootstrap
{ expand: true, flatten: true, src: ['node_modules/bootstrap/dist/css/bootstrap.min.css'], dest: 'static/static/css/' },
{ expand: true, flatten: true, src: ['node_modules/bootstrap/dist/css/bootstrap-theme.min.css'], dest: 'static/static/css/' },
{ expand: true, flatten: true, src: ['node_modules/bootstrap/dist/js/bootstrap.min.js'], dest: 'static/static/js/' },
// lightgallery
{ expand: true, flatten: true, src: ['node_modules/lightgallery/dist/css/lightgallery.min.css'], dest: 'static/static/css/' },
{ expand: true, flatten: true, src: ['node_modules/lightgallery/dist/js/lightgallery.min.js'], dest: 'static/static/js/' },
{ expand: true, flatten: true, src: ['node_modules/lightgallery/dist/fonts/*'], dest: 'static/static/fonts/' },
// lightslider
{ expand: true, flatten: true, src: ['node_modules/lightslider/dist/css/lightslider.min.css'], dest: 'static/static/css/' },
{ expand: true, flatten: true, src: ['node_modules/lightslider/dist/js/lightslider.min.js'], dest: 'static/static/js/' },
{ expand: true, flatten: true, src: ['node_modules/lightslider/dist/img/*'], dest: 'static/static/img/' },
// Fontawesome 4.x
{ expand: true, flatten: true, src: ['node_modules/font-awesome/css/font-awesome.min.css'], dest: 'static/static/css/' },
{ expand: true, flatten: true, src: ['node_modules/font-awesome/fonts/*'], dest: 'static/static/fonts/' },
// fortawesome
// { expand: true, flatten: true, src: ['node_modules/@fortawesome/fontawesome-free/css/all.min.css'], dest: 'static/static/css/' },
// { expand: true, flatten: true, src: ['node_modules/@fortawesome/fontawesome-free/webfonts/*'], dest: 'static/static/webfonts/' },
],
},
},
});
grunt.registerTask('default', ['copy:main']);
};

@ -9,8 +9,7 @@
<div class="container">
<div class="row">
<div class="col-md-12">
{{- $mainSections := .Site.Params.mainSections }}
{{- $paginator := .Paginate (where .Site.RegularPages "Type" "in" $mainSections) }}
{{ $paginator := .Paginate (where .Data.Pages "Type" "post") }}
{{ range $paginator.Pages }}
{{ .Render "summary" }}
{{ end }}

@ -4,7 +4,9 @@
<div class="tag_widget">
<h2>Tags</h2>
<ul>
{{ range .Site.Taxonomies.tags.Alphabetical }}<li><a href="/tags/{{ .Name | urlize }}/">{{ .Name }}</a></li>{{ end }}
{{ range .Site.Taxonomies.tags.ByCount }}
<li><a href="/tags/{{ .Name | urlize }}">{{ .Name }}</a></li>
{{ end }}
</ul>
</div>
</div>

@ -1,16 +1,20 @@
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/thirdparties.js"></script>
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/jquery.min.js"></script>
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/lightGallery.min.js"></script>
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/lightslider.min.js"></script>
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/bootstrap.min.js"></script>
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/main.js"></script>
<!-- <script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/highlight.pack.min.js"></script> -->
<!-- <script>
<script type="text/javascript" src="{{ .Site.BaseURL }}/static/js/highlight.pack.js"></script>
<script>
hljs.configure({
languages: ['bash', 'html']
});
hljs.initHighlightingOnLoad();
</script> -->
</script>
{{ partial "analytics.html" }}
</body>
</html>

@ -3,6 +3,7 @@
<head>
{{ partial "meta.html" . }}
{{ partial "header.includes.html" . }}
{{ `<!--[if lt IE 9]><script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script><script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script><![endif]-->` | safeHTML }}
<!-- RSS -->
{{ with .OutputFormats.Get "RSS" }}
<link href="{{ .RelPermalink }}" rel="alternate" type="application/rss+xml" title="{{ $.Site.Title }}" />

@ -1,14 +1,20 @@
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/bootstrap.min.css" rel="stylesheet"/>
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/bootstrap-theme.min.css" rel="stylesheet"/>
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/persona-icons.css" rel="stylesheet"/>
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/persona-icons.css" rel="stylesheet"/>
<!-- Fonts ni style.css -->
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/font-awesome.min.css" rel="stylesheet" />
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/lato-font.css" rel="stylesheet"/>
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/notoserif-font.css" rel="stylesheet"/>
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/lato-font.css" rel="stylesheet"/>
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/notoserif-font.css" rel="stylesheet"/>
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/style.css" rel="stylesheet"/>
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/responsive.css" rel="stylesheet"/>
<link type="text/css" media="print" onload="this.onload=null;this.removeAttribute('media');" href="{{ .Site.BaseURL }}/static/css/chromastyles-monokai.css" rel="stylesheet"/>
<link type="text/css" href="{{ .Site.BaseURL }}/static/css/highlight/googlecode.css" rel="stylesheet"/>
<!-- start hugo lightslider -->
<!-- you need this jquery include if you want lightslider without includejs="true". -->
<script src="{{ $.Site.BaseURL }}/static/js/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="{{ .Site.BaseURL }}/static/css/lightGallery.css" />
<link rel="stylesheet" type="text/css" href="{{ .Site.BaseURL }}/static/css/lightslider.css" />
<!-- end hugo lightslider -->

@ -7,14 +7,14 @@
<meta name="twitter:card" content="summary">
{{ with .Site.Params.twitter }}<meta name="twitter:site" content="{{ . }}" />{{ end }}
<meta name="twitter:title" content="{{ if ne .Title .Site.Title }}{{ .Title }} &middot; {{ .Site.Title }}{{ else }}{{ .Site.Title }}{{ end }}">
<meta name="twitter:title" content="{{ .Title }} &middot; {{ .Site.Title }}">
<meta name="twitter:description" content="{{ if .IsNode }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ else }}{{ with .Description }}{{ . }}{{ end }}{{ end }}">
<meta property="og:type" content="article">
<meta property="og:title" content="{{ if ne .Title .Site.Title }}{{ .Title }} &middot; {{ .Site.Title }}{{ else }}{{ .Site.Title }}{{ end }}">
<meta property="og:title" content="{{ .Title }} &middot; {{ .Site.Title }}">
<meta property="og:description" content="{{ if .IsNode }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ else }}{{ with .Description }}{{ . }}{{ end }}{{ end }}">
<title>{{ if ne .Title .Site.Title }}{{ .Title }} &middot; {{ .Site.Title }}{{ else }}{{ .Site.Title }}{{ end }}</title>
<title>{{ .Title }} &middot; {{ .Site.Title }}</title>
<link rel="canonical" href="{{ .Permalink }}">
{{ partial "meta.extra.html" . }}

@ -11,9 +11,9 @@
<li><time property="datePublished" datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "2 Jan, 2006" }}</time></li>
{{ end }}
<!-- Tags -->
{{ if isset .Params "tags" }}<li class="tags" property="keywords">{{ range .Params.tags }}<a href="/tags/{{ . | urlize }}/">{{ . }}</a>{{ end }}</li>{{ end }}
{{ if isset .Params "tags" }}<li class="tags" property="keywords">{{ range .Params.tags }}<a href="/tags/{{ . | urlize }}">{{ . }}</a>{{ end }}</li>{{ end }}
<!-- Edit link -->
{{ with .Site.Params.edit_link_url }}<li><a href="{{ . }}{{ with $.File }}{{ .Path }}{{ end }}" title="Edit" target="_blank"><i class="edit_post"></i></a></li>{{ end }}
{{ with .Site.Params.edit_link_url }}<li><a href="{{ . }}{{ $.File.Path }}" title="Edit" target="_blank"><i class="edit_post"></i></a></li>{{ end }}
</ul>
</div>
</aside>

@ -1,4 +1,4 @@
{{ if or (.Prev) (.Next) }}
{{ if (.Prev) or (.Next) }}
<div class="paginating_area">
<ul>
{{ if .Prev }}<li><a href="{{ .Prev.RelPermalink }}" class="p_arrow" title="Previous blog post: {{ .Prev.Title }}"><i>&lsaquo;</i></a></li>{{ end }}

File diff suppressed because it is too large Load Diff

@ -1,16 +0,0 @@
{
"name": "@pcdummy/persona",
"version": "1.0.0",
"description": "Persona theme",
"author": "",
"license": "MIT",
"dependencies": {
"bootstrap": "^3.4.1",
"font-awesome": "^4.7.0",
"grunt": "^1.5.3",
"grunt-contrib-copy": "^1.0.0",
"jquery": "^3.6.1",
"lightgallery": "^2.6.0",
"lightslider": "^1.1.6"
}
}

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
../../../vendor/bootstrap/css/bootstrap-theme.min.css

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
../../../vendor/bootstrap/css/bootstrap.min.css

@ -1,85 +0,0 @@
/* Background */ .bg { color: #f8f8f2; background-color: #272822; }
/* PreWrapper */ .chroma { color: #f8f8f2; background-color: #272822; }
/* Other */ .chroma .x { }
/* Error */ .chroma .err { color: #960050; background-color: #1e0010 }
/* CodeLine */ .chroma .cl { }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #ffffcc }
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* Line */ .chroma .line { display: flex; }
/* Keyword */ .chroma .k { color: #66d9ef }
/* KeywordConstant */ .chroma .kc { color: #66d9ef }
/* KeywordDeclaration */ .chroma .kd { color: #66d9ef }
/* KeywordNamespace */ .chroma .kn { color: #f92672 }
/* KeywordPseudo */ .chroma .kp { color: #66d9ef }
/* KeywordReserved */ .chroma .kr { color: #66d9ef }
/* KeywordType */ .chroma .kt { color: #66d9ef }
/* Name */ .chroma .n { }
/* NameAttribute */ .chroma .na { color: #a6e22e }
/* NameBuiltin */ .chroma .nb { }
/* NameBuiltinPseudo */ .chroma .bp { }
/* NameClass */ .chroma .nc { color: #a6e22e }
/* NameConstant */ .chroma .no { color: #66d9ef }
/* NameDecorator */ .chroma .nd { color: #a6e22e }
/* NameEntity */ .chroma .ni { }
/* NameException */ .chroma .ne { color: #a6e22e }
/* NameFunction */ .chroma .nf { color: #a6e22e }
/* NameFunctionMagic */ .chroma .fm { }
/* NameLabel */ .chroma .nl { }
/* NameNamespace */ .chroma .nn { }
/* NameOther */ .chroma .nx { color: #a6e22e }
/* NameProperty */ .chroma .py { }
/* NameTag */ .chroma .nt { color: #f92672 }
/* NameVariable */ .chroma .nv { }
/* NameVariableClass */ .chroma .vc { }
/* NameVariableGlobal */ .chroma .vg { }
/* NameVariableInstance */ .chroma .vi { }
/* NameVariableMagic */ .chroma .vm { }
/* Literal */ .chroma .l { color: #ae81ff }
/* LiteralDate */ .chroma .ld { color: #e6db74 }
/* LiteralString */ .chroma .s { color: #e6db74 }
/* LiteralStringAffix */ .chroma .sa { color: #e6db74 }
/* LiteralStringBacktick */ .chroma .sb { color: #e6db74 }
/* LiteralStringChar */ .chroma .sc { color: #e6db74 }
/* LiteralStringDelimiter */ .chroma .dl { color: #e6db74 }
/* LiteralStringDoc */ .chroma .sd { color: #e6db74 }
/* LiteralStringDouble */ .chroma .s2 { color: #e6db74 }
/* LiteralStringEscape */ .chroma .se { color: #ae81ff }
/* LiteralStringHeredoc */ .chroma .sh { color: #e6db74 }
/* LiteralStringInterpol */ .chroma .si { color: #e6db74 }
/* LiteralStringOther */ .chroma .sx { color: #e6db74 }
/* LiteralStringRegex */ .chroma .sr { color: #e6db74 }
/* LiteralStringSingle */ .chroma .s1 { color: #e6db74 }
/* LiteralStringSymbol */ .chroma .ss { color: #e6db74 }
/* LiteralNumber */ .chroma .m { color: #ae81ff }
/* LiteralNumberBin */ .chroma .mb { color: #ae81ff }
/* LiteralNumberFloat */ .chroma .mf { color: #ae81ff }
/* LiteralNumberHex */ .chroma .mh { color: #ae81ff }
/* LiteralNumberInteger */ .chroma .mi { color: #ae81ff }
/* LiteralNumberIntegerLong */ .chroma .il { color: #ae81ff }
/* LiteralNumberOct */ .chroma .mo { color: #ae81ff }
/* Operator */ .chroma .o { color: #f92672 }
/* OperatorWord */ .chroma .ow { color: #f92672 }
/* Punctuation */ .chroma .p { }
/* Comment */ .chroma .c { color: #75715e }
/* CommentHashbang */ .chroma .ch { color: #75715e }
/* CommentMultiline */ .chroma .cm { color: #75715e }
/* CommentSingle */ .chroma .c1 { color: #75715e }
/* CommentSpecial */ .chroma .cs { color: #75715e }
/* CommentPreproc */ .chroma .cp { color: #75715e }
/* CommentPreprocFile */ .chroma .cpf { color: #75715e }
/* Generic */ .chroma .g { }
/* GenericDeleted */ .chroma .gd { color: #f92672 }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericError */ .chroma .gr { }
/* GenericHeading */ .chroma .gh { }
/* GenericInserted */ .chroma .gi { color: #a6e22e }
/* GenericOutput */ .chroma .go { }
/* GenericPrompt */ .chroma .gp { }
/* GenericStrong */ .chroma .gs { font-weight: bold }
/* GenericSubheading */ .chroma .gu { color: #75715e }
/* GenericTraceback */ .chroma .gt { }
/* GenericUnderline */ .chroma .gl { }
/* TextWhitespace */ .chroma .w { }

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/arta.css

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/ascetic.css

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/atelier-dune.dark.css

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/atelier-dune.light.css

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/atelier-forest.dark.css

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/atelier-forest.light.css

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/atelier-heath.dark.css

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/atelier-heath.light.css

@ -0,0 +1 @@
../../../../vendor/highlightjs/styles/atelier-lakeside.dark.css

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save