Merge branch 'master' of code.ungleich.ch:ungleich-public/ungleich-staticcms
39
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,39 @@
|
|||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
image: debian:latest
|
||||
variables:
|
||||
BUILDDIR: "build/"
|
||||
|
||||
build:
|
||||
stage: build
|
||||
before_script:
|
||||
- apt-get update
|
||||
- apt-get install -y make lektor imagemagick
|
||||
script:
|
||||
- make build
|
||||
artifacts:
|
||||
expire_in: 12 hours
|
||||
paths:
|
||||
- "build/"
|
||||
|
||||
deploy:
|
||||
stage: deploy
|
||||
only:
|
||||
- master
|
||||
environment:
|
||||
name: production
|
||||
url: https://ungleich.ch/
|
||||
before_script:
|
||||
# Install dependencies
|
||||
- apt-get update
|
||||
- apt-get install -y make openssh-client rsync
|
||||
# Configure the SSH Agent
|
||||
- eval $(ssh-agent -s)
|
||||
- echo "$CD_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$CD_SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts
|
||||
- chmod 644 ~/.ssh/known_hosts
|
||||
script:
|
||||
- make deploy
|
7
Makefile
|
@ -1,4 +1,4 @@
|
|||
BUILDDIR=../ungleich-staticcms-build
|
||||
BUILDDIR?=../ungleich-staticcms-build
|
||||
DESTINATION=ungleichstatic@staticweb.ungleich.ch:/home/services/www/ungleichstatic/staticcms.ungleich.ch/www/u/
|
||||
|
||||
all: publish
|
||||
|
@ -6,8 +6,11 @@ all: publish
|
|||
pull:
|
||||
git pull
|
||||
|
||||
publish: pull build permissions
|
||||
publish: pull build deploy
|
||||
|
||||
deploy: permissions
|
||||
rsync -av --delete --exclude .lektor/ $(BUILDDIR)/u/ $(DESTINATION)
|
||||
rsync -av --delete $(BUILDDIR)/sitemap.xml $(DESTINATION)
|
||||
|
||||
permissions: build
|
||||
find $(BUILDDIR) -type f -exec chmod 0644 {} \;
|
||||
|
|
BIN
assets/u/image/carbonzero-energy-green.jpg
Normal file
After Width: | Height: | Size: 155 KiB |
BIN
assets/u/image/energy-source-by-country.jpg
Normal file
After Width: | Height: | Size: 274 KiB |
BIN
assets/u/image/pizol.jpg
Normal file
After Width: | Height: | Size: 185 KiB |
55
assets/u/image/ungleich-logo-black.svg
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 106.3 28.3" style="enable-background:new 0 0 106.3 28.3;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#050505;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M29.8,24.9c0-0.4,0.1-0.8,0.4-1.2c0.3-0.4,0.7-0.8,1.3-1.1v-0.1c-0.3-0.2-0.5-0.4-0.8-0.7
|
||||
c-0.2-0.3-0.3-0.7-0.3-1.1c0-0.3,0.1-0.7,0.3-1.1c0.2-0.4,0.5-0.7,0.9-0.9v-0.1c-0.4-0.3-0.7-0.6-1-1.1c-0.3-0.5-0.4-1-0.4-1.6
|
||||
c0-0.6,0.1-1.1,0.3-1.6c0.2-0.5,0.5-0.9,0.9-1.2c0.4-0.3,0.8-0.6,1.4-0.8c0.5-0.2,1.1-0.3,1.6-0.3c0.6,0,1.1,0.1,1.6,0.3h4.4V14H38
|
||||
c0.2,0.2,0.4,0.5,0.6,0.9c0.2,0.3,0.3,0.7,0.3,1.1c0,0.6-0.1,1.1-0.3,1.5c-0.2,0.5-0.5,0.8-0.9,1.1c-0.4,0.3-0.8,0.5-1.3,0.7
|
||||
c-0.5,0.2-1.1,0.2-1.6,0.2c-0.3,0-0.5,0-0.8-0.1c-0.3-0.1-0.6-0.1-0.9-0.3c-0.5,0.3-0.7,0.7-0.7,1.1c0,0.4,0.2,0.7,0.5,0.9
|
||||
c0.4,0.2,0.9,0.3,1.6,0.3h2.3c1.4,0,2.4,0.2,3.1,0.6c0.7,0.4,1,1.1,1,2c0,0.5-0.1,1-0.4,1.4c-0.3,0.5-0.7,0.8-1.2,1.2
|
||||
c-0.5,0.3-1.2,0.6-1.9,0.8c-0.7,0.2-1.6,0.3-2.5,0.3c-1.5,0-2.7-0.2-3.6-0.7C30.2,26.6,29.8,25.9,29.8,24.9z M31.6,24.7
|
||||
c0,0.5,0.3,0.9,0.8,1.2c0.6,0.3,1.4,0.5,2.4,0.5c0.6,0,1.1-0.1,1.5-0.2c0.5-0.1,0.9-0.3,1.2-0.4c0.3-0.2,0.6-0.4,0.8-0.6
|
||||
c0.2-0.2,0.3-0.5,0.3-0.7c0-0.5-0.2-0.8-0.6-0.9c-0.4-0.2-1-0.2-1.7-0.2h-1.9c-0.3,0-0.6,0-0.9,0c-0.3,0-0.5-0.1-0.7-0.1
|
||||
c-0.4,0.2-0.7,0.5-0.9,0.8C31.7,24.1,31.6,24.4,31.6,24.7z M34.6,18.3c0.6,0,1.1-0.2,1.6-0.6c0.4-0.4,0.7-1,0.7-1.7
|
||||
c0-0.7-0.2-1.3-0.7-1.7c-0.4-0.4-1-0.6-1.6-0.6c-0.6,0-1.1,0.2-1.6,0.6c-0.4,0.4-0.7,1-0.7,1.7c0,0.7,0.2,1.3,0.7,1.7
|
||||
C33.5,18.1,34,18.3,34.6,18.3z"/>
|
||||
</g>
|
||||
<path class="st0" d="M13.4,23.3h-1.8l-0.2-1.8h-0.1c-0.5,0.6-1.1,1.1-1.8,1.5c-0.6,0.4-1.4,0.6-2.2,0.6c-1.3,0-2.3-0.4-2.9-1.1
|
||||
c-0.6-0.8-0.9-1.9-0.9-3.3v-5.5l-2.9-0.1l5.2-2l0,1.5v5.8c0,1,0.2,1.7,0.5,2.2c0.3,0.5,0.9,0.7,1.8,0.7c0.6,0,1.1-0.1,1.6-0.4
|
||||
c0.5-0.3,1-0.7,1.5-1.4v-7.6h2.2L13.4,23.3L13.4,23.3z"/>
|
||||
<path class="st0" d="M17.1,12.3h1.8l0.2,1.8h0.1c0.6-0.6,1.2-1.1,1.8-1.5c0.6-0.4,1.4-0.6,2.3-0.6c1.3,0,2.2,0.4,2.8,1.1
|
||||
c0.6,0.8,0.9,1.9,0.9,3.3v6.8h-2.2v-6.5c0-1-0.2-1.7-0.5-2.1c-0.3-0.5-0.9-0.7-1.8-0.7c-0.6,0-1.1,0.1-1.6,0.4
|
||||
c-0.5,0.3-1,0.7-1.6,1.3v7.6h-2.2L17.1,12.3L17.1,12.3L17.1,12.3z"/>
|
||||
<path class="st0" d="M51.9,17.8c0-0.9,0.2-1.7,0.5-2.4c0.3-0.7,0.7-1.3,1.3-1.8c0.5-0.5,1.1-0.9,1.8-1.2c0.7-0.3,1.4-0.4,2.1-0.4
|
||||
c0.8,0,1.5,0.1,2.2,0.4c0.6,0.3,1.2,0.6,1.6,1.1c0.4,0.5,0.8,1,1,1.6c0.2,0.6,0.3,1.3,0.3,2.1c0,0.2,0,0.4,0,0.6
|
||||
c0,0.2,0,0.4-0.1,0.5h-8.3c0.1,1.1,0.5,1.9,1.2,2.5c0.7,0.6,1.6,0.9,2.8,0.9c0.6,0,1.2-0.1,1.7-0.2c0.5-0.2,1-0.4,1.5-0.7l0.8,1.4
|
||||
c-0.6,0.4-1.2,0.7-1.9,0.9c-0.7,0.2-1.5,0.4-2.4,0.4c-0.8,0-1.6-0.1-2.3-0.4c-0.7-0.3-1.4-0.6-1.9-1.1c-0.5-0.5-1-1.1-1.3-1.8
|
||||
C52.1,19.5,51.9,18.7,51.9,17.8z M60.6,16.8c0-1-0.3-1.8-0.8-2.3c-0.5-0.5-1.2-0.8-2.2-0.8c-0.8,0-1.6,0.3-2.2,0.8
|
||||
c-0.6,0.5-1,1.3-1.2,2.3H60.6z"/>
|
||||
<path class="st0" d="M70,11.9l0,11.6h-2.2v-8.5h-4.2L70,11.9z M68.7,9.7c-0.5,0-0.9-0.1-1.2-0.4C67.2,9,67,8.6,67,8.1
|
||||
c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.4,1.2-0.4c0.5,0,0.9,0.1,1.2,0.4c0.3,0.3,0.5,0.7,0.5,1.2c0,0.5-0.2,0.9-0.5,1.2
|
||||
C69.6,9.5,69.2,9.7,68.7,9.7z"/>
|
||||
<path class="st0" d="M73.1,18c0-0.9,0.2-1.7,0.5-2.5c0.3-0.7,0.8-1.3,1.4-1.8c0.6-0.5,1.2-0.9,2-1.1c0.7-0.3,1.5-0.4,2.4-0.4
|
||||
c0.9,0,1.7,0.2,2.4,0.5c0.7,0.3,1.2,0.7,1.7,1.1l-1.1,1.4c-0.4-0.4-0.9-0.6-1.4-0.8c-0.5-0.2-1-0.3-1.5-0.3c-0.6,0-1.1,0.1-1.6,0.3
|
||||
c-0.5,0.2-0.9,0.5-1.3,0.8c-0.4,0.3-0.6,0.8-0.8,1.3c-0.2,0.5-0.3,1-0.3,1.6c0,0.6,0.1,1.1,0.3,1.6c0.2,0.5,0.5,0.9,0.8,1.3
|
||||
c0.4,0.3,0.8,0.6,1.3,0.8c0.5,0.2,1,0.3,1.6,0.3c0.7,0,1.3-0.1,1.8-0.4c0.5-0.3,1-0.6,1.5-0.9l0.9,1.4c-0.6,0.5-1.3,1-2.1,1.3
|
||||
c-0.8,0.3-1.5,0.4-2.3,0.4c-0.9,0-1.7-0.1-2.4-0.4c-0.7-0.3-1.4-0.6-1.9-1.1c-0.5-0.5-1-1.1-1.3-1.8C73.2,19.8,73.1,19,73.1,18z"/>
|
||||
<path class="st0" d="M83.7,7.6l4.7-2.3v6.5l-0.1,2.5c0.6-0.6,1.2-1.1,1.8-1.4c0.6-0.4,1.4-0.6,2.3-0.6c1.3,0,2.2,0.4,2.8,1.1
|
||||
c0.6,0.8,0.9,1.9,0.9,3.3v6.8h-2.2V17c0-1-0.2-1.7-0.5-2.1c-0.3-0.5-0.9-0.7-1.8-0.7c-0.6,0-1.1,0.1-1.6,0.4c-0.5,0.3-1,0.7-1.6,1.3
|
||||
v7.6h-2.2l0-16L83.7,7.6z"/>
|
||||
<g>
|
||||
<polygon class="st0" points="96.4,2.6 95.7,4.2 105,4.2 105.8,2.6 "/>
|
||||
<polygon class="st0" points="95.7,6.1 94.9,7.7 104.3,7.7 105,6.1 "/>
|
||||
<polygon class="st0" points="97.5,9.6 101.8,0.4 103.5,0.5 99.2,9.6 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M46.3,19.7c0,0.7,0.2,1.3,0.6,1.6c0.4,0.3,0.9,0.5,1.4,0.5c0.3,0,0.6,0,0.9-0.1c0.3-0.1,0.6-0.2,1-0.3l0.5,1.6
|
||||
c-0.2,0.1-0.5,0.2-0.7,0.2c-0.2,0.1-0.5,0.1-0.7,0.2c-0.2,0.1-0.5,0.1-0.7,0.1c-0.3,0-0.5,0.1-0.8,0.1c-1.2,0-2.1-0.3-2.7-1
|
||||
c-0.6-0.7-0.9-1.7-0.9-3V5.1h-3.5l5.6-4"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
55
assets/u/image/ungleich-logo-white.svg
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 106.3 28.3" style="enable-background:new 0 0 106.3 28.3;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M29.8,24.9c0-0.4,0.1-0.8,0.4-1.2c0.3-0.4,0.7-0.8,1.3-1.1v-0.1c-0.3-0.2-0.5-0.4-0.8-0.7
|
||||
c-0.2-0.3-0.3-0.7-0.3-1.1c0-0.3,0.1-0.7,0.3-1.1c0.2-0.4,0.5-0.7,0.9-0.9v-0.1c-0.4-0.3-0.7-0.6-1-1.1c-0.3-0.5-0.4-1-0.4-1.6
|
||||
c0-0.6,0.1-1.1,0.3-1.6c0.2-0.5,0.5-0.9,0.9-1.2c0.4-0.3,0.8-0.6,1.4-0.8c0.5-0.2,1.1-0.3,1.6-0.3c0.6,0,1.1,0.1,1.6,0.3h4.4V14H38
|
||||
c0.2,0.2,0.4,0.5,0.6,0.9c0.2,0.3,0.3,0.7,0.3,1.1c0,0.6-0.1,1.1-0.3,1.5c-0.2,0.5-0.5,0.8-0.9,1.1c-0.4,0.3-0.8,0.5-1.3,0.7
|
||||
c-0.5,0.2-1.1,0.2-1.6,0.2c-0.3,0-0.5,0-0.8-0.1c-0.3-0.1-0.6-0.1-0.9-0.3c-0.5,0.3-0.7,0.7-0.7,1.1c0,0.4,0.2,0.7,0.5,0.9
|
||||
c0.4,0.2,0.9,0.3,1.6,0.3h2.3c1.4,0,2.4,0.2,3.1,0.6c0.7,0.4,1,1.1,1,2c0,0.5-0.1,1-0.4,1.4c-0.3,0.5-0.7,0.8-1.2,1.2
|
||||
c-0.5,0.3-1.2,0.6-1.9,0.8c-0.7,0.2-1.6,0.3-2.5,0.3c-1.5,0-2.7-0.2-3.6-0.7C30.2,26.6,29.8,25.9,29.8,24.9z M31.6,24.7
|
||||
c0,0.5,0.3,0.9,0.8,1.2c0.6,0.3,1.4,0.5,2.4,0.5c0.6,0,1.1-0.1,1.5-0.2c0.5-0.1,0.9-0.3,1.2-0.4c0.3-0.2,0.6-0.4,0.8-0.6
|
||||
c0.2-0.2,0.3-0.5,0.3-0.7c0-0.5-0.2-0.8-0.6-0.9c-0.4-0.2-1-0.2-1.7-0.2h-1.9c-0.3,0-0.6,0-0.9,0c-0.3,0-0.5-0.1-0.7-0.1
|
||||
c-0.4,0.2-0.7,0.5-0.9,0.8C31.7,24.1,31.6,24.4,31.6,24.7z M34.6,18.3c0.6,0,1.1-0.2,1.6-0.6c0.4-0.4,0.7-1,0.7-1.7
|
||||
c0-0.7-0.2-1.3-0.7-1.7c-0.4-0.4-1-0.6-1.6-0.6c-0.6,0-1.1,0.2-1.6,0.6c-0.4,0.4-0.7,1-0.7,1.7c0,0.7,0.2,1.3,0.7,1.7
|
||||
C33.5,18.1,34,18.3,34.6,18.3z"/>
|
||||
</g>
|
||||
<path class="st0" d="M13.4,23.3h-1.8l-0.2-1.8h-0.1c-0.5,0.6-1.1,1.1-1.8,1.5c-0.6,0.4-1.4,0.6-2.2,0.6c-1.3,0-2.3-0.4-2.9-1.1
|
||||
c-0.6-0.8-0.9-1.9-0.9-3.3v-5.5l-2.9-0.1l5.2-2l0,1.5v5.8c0,1,0.2,1.7,0.5,2.2c0.3,0.5,0.9,0.7,1.8,0.7c0.6,0,1.1-0.1,1.6-0.4
|
||||
c0.5-0.3,1-0.7,1.5-1.4v-7.6h2.2L13.4,23.3L13.4,23.3z"/>
|
||||
<path class="st0" d="M17.1,12.3h1.8l0.2,1.8h0.1c0.6-0.6,1.2-1.1,1.8-1.5c0.6-0.4,1.4-0.6,2.3-0.6c1.3,0,2.2,0.4,2.8,1.1
|
||||
c0.6,0.8,0.9,1.9,0.9,3.3v6.8h-2.2v-6.5c0-1-0.2-1.7-0.5-2.1c-0.3-0.5-0.9-0.7-1.8-0.7c-0.6,0-1.1,0.1-1.6,0.4
|
||||
c-0.5,0.3-1,0.7-1.6,1.3v7.6h-2.2L17.1,12.3L17.1,12.3L17.1,12.3z"/>
|
||||
<path class="st0" d="M51.9,17.8c0-0.9,0.2-1.7,0.5-2.4c0.3-0.7,0.7-1.3,1.3-1.8c0.5-0.5,1.1-0.9,1.8-1.2c0.7-0.3,1.4-0.4,2.1-0.4
|
||||
c0.8,0,1.5,0.1,2.2,0.4c0.6,0.3,1.2,0.6,1.6,1.1c0.4,0.5,0.8,1,1,1.6c0.2,0.6,0.3,1.3,0.3,2.1c0,0.2,0,0.4,0,0.6
|
||||
c0,0.2,0,0.4-0.1,0.5h-8.3c0.1,1.1,0.5,1.9,1.2,2.5c0.7,0.6,1.6,0.9,2.8,0.9c0.6,0,1.2-0.1,1.7-0.2c0.5-0.2,1-0.4,1.5-0.7l0.8,1.4
|
||||
c-0.6,0.4-1.2,0.7-1.9,0.9c-0.7,0.2-1.5,0.4-2.4,0.4c-0.8,0-1.6-0.1-2.3-0.4c-0.7-0.3-1.4-0.6-1.9-1.1c-0.5-0.5-1-1.1-1.3-1.8
|
||||
C52.1,19.5,51.9,18.7,51.9,17.8z M60.6,16.8c0-1-0.3-1.8-0.8-2.3c-0.5-0.5-1.2-0.8-2.2-0.8c-0.8,0-1.6,0.3-2.2,0.8
|
||||
c-0.6,0.5-1,1.3-1.2,2.3H60.6z"/>
|
||||
<path class="st0" d="M70,11.9l0,11.6h-2.2v-8.5h-4.2L70,11.9z M68.7,9.7c-0.5,0-0.9-0.1-1.2-0.4C67.2,9,67,8.6,67,8.1
|
||||
c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.4,1.2-0.4c0.5,0,0.9,0.1,1.2,0.4c0.3,0.3,0.5,0.7,0.5,1.2c0,0.5-0.2,0.9-0.5,1.2
|
||||
C69.6,9.5,69.2,9.7,68.7,9.7z"/>
|
||||
<path class="st0" d="M73.1,18c0-0.9,0.2-1.7,0.5-2.5c0.3-0.7,0.8-1.3,1.4-1.8c0.6-0.5,1.2-0.9,2-1.1c0.7-0.3,1.5-0.4,2.4-0.4
|
||||
c0.9,0,1.7,0.2,2.4,0.5c0.7,0.3,1.2,0.7,1.7,1.1l-1.1,1.4c-0.4-0.4-0.9-0.6-1.4-0.8c-0.5-0.2-1-0.3-1.5-0.3c-0.6,0-1.1,0.1-1.6,0.3
|
||||
c-0.5,0.2-0.9,0.5-1.3,0.8c-0.4,0.3-0.6,0.8-0.8,1.3c-0.2,0.5-0.3,1-0.3,1.6c0,0.6,0.1,1.1,0.3,1.6c0.2,0.5,0.5,0.9,0.8,1.3
|
||||
c0.4,0.3,0.8,0.6,1.3,0.8c0.5,0.2,1,0.3,1.6,0.3c0.7,0,1.3-0.1,1.8-0.4c0.5-0.3,1-0.6,1.5-0.9l0.9,1.4c-0.6,0.5-1.3,1-2.1,1.3
|
||||
c-0.8,0.3-1.5,0.4-2.3,0.4c-0.9,0-1.7-0.1-2.4-0.4c-0.7-0.3-1.4-0.6-1.9-1.1c-0.5-0.5-1-1.1-1.3-1.8C73.2,19.8,73.1,19,73.1,18z"/>
|
||||
<path class="st0" d="M83.7,7.6l4.7-2.3v6.5l-0.1,2.5c0.6-0.6,1.2-1.1,1.8-1.4c0.6-0.4,1.4-0.6,2.3-0.6c1.3,0,2.2,0.4,2.8,1.1
|
||||
c0.6,0.8,0.9,1.9,0.9,3.3v6.8h-2.2V17c0-1-0.2-1.7-0.5-2.1c-0.3-0.5-0.9-0.7-1.8-0.7c-0.6,0-1.1,0.1-1.6,0.4c-0.5,0.3-1,0.7-1.6,1.3
|
||||
v7.6h-2.2l0-16L83.7,7.6z"/>
|
||||
<g>
|
||||
<polygon class="st0" points="96.4,2.6 95.7,4.2 105,4.2 105.8,2.6 "/>
|
||||
<polygon class="st0" points="95.7,6.1 94.9,7.7 104.3,7.7 105,6.1 "/>
|
||||
<polygon class="st0" points="97.5,9.6 101.8,0.4 103.5,0.5 99.2,9.6 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st0" d="M46.3,19.7c0,0.7,0.2,1.3,0.6,1.6c0.4,0.3,0.9,0.5,1.4,0.5c0.3,0,0.6,0,0.9-0.1c0.3-0.1,0.6-0.2,1-0.3l0.5,1.6
|
||||
c-0.2,0.1-0.5,0.2-0.7,0.2c-0.2,0.1-0.5,0.1-0.7,0.2c-0.2,0.1-0.5,0.1-0.7,0.1c-0.3,0-0.5,0.1-0.8,0.1c-1.2,0-2.1-0.3-2.7-1
|
||||
c-0.6-0.7-0.9-1.7-0.9-3V5.1h-3.5l5.6-4"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
BIN
assets/u/image/zerocarbon-no.jpg
Normal file
After Width: | Height: | Size: 229 KiB |
BIN
assets/u/image/zerocarbon-yes.jpg
Normal file
After Width: | Height: | Size: 231 KiB |
BIN
assets/u/image/zerocarbon_no.jpg
Normal file
After Width: | Height: | Size: 164 KiB |
BIN
assets/u/image/zerocarbon_shop.jpg
Normal file
After Width: | Height: | Size: 38 KiB |
56
assets/u/static/generic-header.css
Normal file
|
@ -0,0 +1,56 @@
|
|||
:root {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.mb-5 {
|
||||
margin-bottom: 1.5rem !important;
|
||||
}
|
||||
|
||||
/* Extra large devices (large laptops and desktops, 1200px and up) */
|
||||
@media only screen and (min-width: 1200px) {
|
||||
:root {
|
||||
font-size: 16px;
|
||||
}
|
||||
.mb-5 {
|
||||
margin-bottom: 3rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.blue-bg {
|
||||
background-color: #40a9e3;
|
||||
}
|
||||
|
||||
.black-bg {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.red-bg {
|
||||
background-color: #d1240c;
|
||||
}
|
||||
|
||||
.green-bg {
|
||||
background-color: #5cab06;
|
||||
}
|
||||
|
||||
|
||||
h1.generic-header {
|
||||
line-height: 6rem;
|
||||
font-size: 7rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1068px){
|
||||
h1.generic-header {
|
||||
font-size: 10vw;
|
||||
line-height: 12vw;
|
||||
}
|
||||
}
|
3
content/sitemap.xml/contents.lr
Normal file
|
@ -0,0 +1,3 @@
|
|||
_template: sitemap.xml
|
||||
---
|
||||
_model: none
|
|
@ -0,0 +1,197 @@
|
|||
title: How to build an OpenStack alternative: Step 1, the prototype
|
||||
---
|
||||
pub_date: 2020-01-11
|
||||
---
|
||||
author: ungleich virtualisation team
|
||||
---
|
||||
twitter_handle: ungleich
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
_discoverable: yes
|
||||
---
|
||||
abstract:
|
||||
The step by step guide for doing it yourself
|
||||
---
|
||||
body:
|
||||
|
||||
In this article we describe a first
|
||||
|
||||
## Find out what you need
|
||||
|
||||
When we say building an alternative to OpenStack, we have something
|
||||
specific in our mind. This might be different from what you think
|
||||
OpenStack is for. For us it is running a lot of virtual machines for
|
||||
customers with a lot of storage attached. With self service and
|
||||
automated payments.
|
||||
|
||||
All code I refer to in this article can be found on
|
||||
[code.ungleich.ch](https://code.ungleich.ch/uncloud/uncloud/tree/master/uncloud/hack/hackcloud).
|
||||
|
||||
## Creating a network
|
||||
|
||||
The current setup at [Data Center
|
||||
Light](/u/projects/data-center-light) relies heavily on VLANs. VLANs
|
||||
however have a similar problem as IPv4 addresses: there are not that
|
||||
many of them. So for our Openstack replacement we decided to go with
|
||||
[VXLANs](https://en.wikipedia.org/wiki/Virtual_Extensible_LAN)
|
||||
instead. We also considered
|
||||
[SRV6](https://www.segment-routing.net/tutorials/2017-12-05-srv6-introduction/),
|
||||
however we did not see a advantage for our use case. In fact, VXLANs
|
||||
seems to be much simpler.
|
||||
|
||||
So before running a VM, we create a new VXLAN device and add it to a
|
||||
bridge. This roughly looks as follows:
|
||||
|
||||
```
|
||||
netid=100
|
||||
dev=eth0
|
||||
|
||||
vxlandev=vxlan${netid}
|
||||
bridgedev=br${netid}
|
||||
|
||||
# Create the vxlan device
|
||||
ip -6 link add ${vxlandev} type vxlan \
|
||||
id ${netid} \
|
||||
dstport 4789 \
|
||||
group ff05::${netid} \
|
||||
dev ${dev} \
|
||||
ttl 5
|
||||
|
||||
ip link set ${vxlandev} up
|
||||
|
||||
# Create the bridge
|
||||
ip link add ${bridgedev} type bridge
|
||||
ip link set ${bridgedev} up
|
||||
|
||||
# Add the vxlan device into the bridge
|
||||
ip link set ${vxlandev} master ${bridgedev} up
|
||||
```
|
||||
|
||||
As you can see, we are using IPv6 multicast underlying the VXLAN,
|
||||
which is very practical in an IPv6 first data center.
|
||||
|
||||
## IP address management (IPAM)
|
||||
|
||||
Speaking of IPv6 first, all VMs in our new setup will again be IPv6
|
||||
only and IPv4 addresses will be mapped to it via NAT64. This is very
|
||||
similar to what you see at AWS, just that AWS uses
|
||||
[RFC1918](https://tools.ietf.org/html/rfc1918) private IPv4 space
|
||||
instead of [global unique IPv6
|
||||
addresses](https://tools.ietf.org/html/rfc3587), which we do.
|
||||
|
||||
The advantage of using IPv6 here is that you will never ever have a
|
||||
collision and that your VM is very clean: no need to think about IPv4
|
||||
firewall rules, you only need to configure IPv6 settings.
|
||||
|
||||
In the IPv6 world, we use router advertisements as an alternative to
|
||||
DHCP in the IPv4 world. This has the advantage that no state is kept
|
||||
on the server.
|
||||
|
||||
To enable our IPAM, we add an IPv6 address to our bridge and enable
|
||||
the radvd daemon:
|
||||
|
||||
```
|
||||
ip addr add ${ip} dev ${bridgedev}
|
||||
radvd -C ./radvd.conf -n -p ./radvdpid
|
||||
```
|
||||
|
||||
A sample radvd configuration we used for testing looks like this:
|
||||
|
||||
```
|
||||
interface br100
|
||||
{
|
||||
AdvSendAdvert on;
|
||||
MinRtrAdvInterval 3;
|
||||
MaxRtrAdvInterval 5;
|
||||
AdvDefaultLifetime 3600;
|
||||
|
||||
prefix 2a0a:e5c1:111:888::/64 {
|
||||
};
|
||||
|
||||
RDNSS 2a0a:e5c0::3 2a0a:e5c0::4 { AdvRDNSSLifetime 6000; };
|
||||
DNSSL place7.ungleich.ch { AdvDNSSLLifetime 6000; } ;
|
||||
};
|
||||
```
|
||||
|
||||
With this, we are ready to spawn a VM!
|
||||
|
||||
## Create a VM
|
||||
|
||||
The current setup at Data Center Light uses libvirtd for creating
|
||||
VMs. This is problematic, because libvirtd is not very reliabe:
|
||||
sometimes it stops to answer `virsh` commands or begins to use 100%
|
||||
CPU and needs to be killed and restarted regularly. We have seen this
|
||||
behaviour on CentOS 5, CentOS 6, Debian 8 and Devuan 9.
|
||||
|
||||
So in our version, we skip libvirt and run qemu directly. It turns out
|
||||
that this is actually not that hard and can be done using the
|
||||
following script:
|
||||
|
||||
|
||||
```
|
||||
vmid=$1; shift
|
||||
|
||||
qemu=/usr/bin/qemu-system-x86_64
|
||||
|
||||
accel=kvm
|
||||
#accel=tcg
|
||||
|
||||
memory=1024
|
||||
cores=2
|
||||
uuid=732e08c7-84f8-4d43-9571-263db4f80080
|
||||
|
||||
export bridge=br100
|
||||
|
||||
$qemu -name uc${vmid} \
|
||||
-machine pc,accel=${accel} \
|
||||
-m ${memory} \
|
||||
-smp ${cores} \
|
||||
-uuid ${uuid} \
|
||||
-drive file=alpine-virt-3.11.2-x86_64.iso,media=cdrom \
|
||||
-netdev tap,id=netmain,script=./ifup.sh \
|
||||
-device virtio-net-pci,netdev=netmain,id=net0,mac=02:00:f0:a9:c4:4e
|
||||
```
|
||||
|
||||
This starts a VM with a hard coded mac address using KVM
|
||||
acceleration. We give the VM 2 cores and assign it an UUID so that we
|
||||
can easily find it again later. For testing, we have attached an
|
||||
[Alpine Linux ISO](https://alpinelinux.org/).
|
||||
|
||||
The interesting part is however the network part. We create a virtio
|
||||
based network card and execute `ifup.sh` after qemu has been started.
|
||||
|
||||
The ifup.sh script looks as follows:
|
||||
|
||||
```
|
||||
dev=$1; shift
|
||||
|
||||
# bridge is setup from outside
|
||||
ip link set dev "$dev" master ${bridge}
|
||||
ip link set dev "$dev" up
|
||||
```
|
||||
|
||||
It basically adds the tap device to the previously created bridge.
|
||||
|
||||
## That's all there is
|
||||
|
||||
Only using above steps we spawned a test VM on a test machine that is
|
||||
reachable at `2a0a:e5c1:111:888:0:f0ff:fea9:c44e`, world wide. If our
|
||||
test machine is on, you should be able to reach it from anywhere in
|
||||
the world.
|
||||
|
||||
Obviously this is not a full OpenStack replacement. However we wanted
|
||||
to share the small steps that we take for creating it. And we really
|
||||
like running a virtual machine hosting and wanted to show you how
|
||||
much fun it can be.
|
||||
|
||||
## Next step
|
||||
|
||||
A lot of things in the above example are hard code and aren't usable
|
||||
for customers directly. In the next step we will generalise some of
|
||||
the above functions to get more and more nearby to provide a fully
|
||||
usable OpenStack alternative.
|
||||
|
||||
If you are interested in this topic, you can join us on the [ungleich
|
||||
chat](https://chat.ungleich.ch), the full development of our
|
||||
alternative is open source.
|
|
@ -0,0 +1,155 @@
|
|||
title: How to build an OpenStack alternative: Step 2, secure the network
|
||||
---
|
||||
pub_date: 2020-01-12
|
||||
---
|
||||
author: ungleich virtualisation team
|
||||
---
|
||||
twitter_handle: ungleich
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
_discoverable: yes!
|
||||
---
|
||||
abstract:
|
||||
Let's secure the VM network
|
||||
---
|
||||
body:
|
||||
|
||||
In the second step of building an OpenStack alternative we have a look
|
||||
on how to secure the network.
|
||||
|
||||
In the first step we described [how to setup a
|
||||
protoype](../how-to-build-an-openstack-alternative-step-1).
|
||||
|
||||
Note: the name of our OpenStack alternative is
|
||||
**uncloud**.
|
||||
|
||||
## Securing the network - of what?
|
||||
|
||||
Users should be able to do what they want and not limited in their
|
||||
actions. On the other hand, users should be unable to disturb other
|
||||
users. It's very much like in real life.
|
||||
|
||||
## General policy: no firewall
|
||||
|
||||
So for most of the user generated traffic there should be no firewall
|
||||
rules in uncloud. Users should be free to configure
|
||||
their own policies on the VM.
|
||||
|
||||
## Network types
|
||||
|
||||
Before applying any security mechanism, we have to think about what
|
||||
kind of networks can exist in a cloud environment. We see two types of
|
||||
networks:
|
||||
|
||||
* shared networks - more than one customer is in this network
|
||||
* private networks - only one customer has access in this network
|
||||
|
||||
## Filtering IP address management packets
|
||||
|
||||
So when we share a network, we don't want one customer to be able to
|
||||
assign IP addresses to other customers. Instead IP addresses should
|
||||
only be assigned from the operator.
|
||||
|
||||
This means that we need to prevent rogue
|
||||
|
||||
* [Router advertisements (IPv6)](https://en.wikipedia.org/wiki/Neighbor_Discovery_Protocol)
|
||||
* [DHCPv6](https://en.wikipedia.org/wiki/DHCPv6) server answers
|
||||
* [DHCPv4](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol) server answers
|
||||
|
||||
In our prototype we are using [nftables instead of
|
||||
iptables](https://ungleich.ch/en-us/cms/blog/2018/08/18/iptables-vs-nftables/)
|
||||
for firewalling, but the rules can be translated from one to another
|
||||
firewall system.
|
||||
|
||||
To drop router advertisements, we can use the following rule:
|
||||
|
||||
```
|
||||
icmpv6 type nd-router-advert drop
|
||||
```
|
||||
|
||||
To drop DHCPv6 server answers we can use
|
||||
|
||||
```
|
||||
ip6 version 6 udp sport 547 drop
|
||||
```
|
||||
|
||||
And finally to prevent DHCPv4 server anwers, we use
|
||||
|
||||
```
|
||||
ip version 4 udp sport 67 drop
|
||||
```
|
||||
|
||||
Note: while uncloud does not use IPv4 or DHCPv4 to the VMs, a rogue
|
||||
DHCPv4 server might still trick other VMs into assigning themself an
|
||||
IPv4 address. So we also need to block this one.
|
||||
|
||||
## Filtering MAC and IP spoofing
|
||||
|
||||
A VM should not be able to spoof the
|
||||
[MAC address](https://en.wikipedia.org/wiki/MAC_address) or
|
||||
IP address of another machine. We can achieve this by adding a chain
|
||||
specific for each VM network interface:
|
||||
|
||||
```
|
||||
iifname tap1 ether saddr 02:00:f0:a9:c4:4e ip6 saddr 2a0a:e5c1:111:888:0:f0ff:fea9:c44e accept
|
||||
```
|
||||
|
||||
With this we can even allow routing a network to a VM and allowing
|
||||
it to use any IPv6 address in that network:
|
||||
|
||||
```
|
||||
iifname v343a-0 ether saddr 02:00:f0:a9:c4:4f ip6 saddr 2a0a:e5c1:111:888:0:f0ff:fea9:c44f accept
|
||||
iifname v343a-0 ether saddr 02:00:f0:a9:c4:4f ip6 saddr 2a0a:e5c1:111:1234::/64 accept
|
||||
```
|
||||
|
||||
## Putting it all together
|
||||
|
||||
The following code is a full nftable ruleset
|
||||
for securing the VM network traffic.
|
||||
Note that it uses the prerouting hook so
|
||||
that we can use the **ibrname** statement.
|
||||
This is necessary because we don't want to
|
||||
filter after routing or in a forwarding mode, but we want to already filter it
|
||||
**prerouting** (hence the name).
|
||||
|
||||
```
|
||||
flush ruleset
|
||||
|
||||
table bridge filter {
|
||||
chain prerouting {
|
||||
type filter hook prerouting priority 0;
|
||||
policy accept;
|
||||
|
||||
ibrname br100 jump br100
|
||||
}
|
||||
|
||||
chain br100 {
|
||||
# Allow all incoming traffic from outside
|
||||
iifname vxlan100 accept
|
||||
|
||||
# Default blocks: router advertisements, dhcpv6, dhcpv4
|
||||
icmpv6 type nd-router-advert drop
|
||||
ip6 version 6 udp sport 547 drop
|
||||
ip version 4 udp sport 67 drop
|
||||
|
||||
jump br100_vmlist
|
||||
drop
|
||||
}
|
||||
chain br100_vmlist {
|
||||
# VM1
|
||||
iifname tap1 ether saddr 02:00:f0:a9:c4:4e ip6 saddr 2a0a:e5c1:111:888:0:f0ff:fea9:c44e accept
|
||||
|
||||
# VM2
|
||||
iifname v343a-0 ether saddr 02:00:f0:a9:c4:4f ip6 saddr 2a0a:e5c1:111:888:0:f0ff:fea9:c44f accept
|
||||
iifname v343a-0 ether saddr 02:00:f0:a9:c4:4f ip6 saddr 2a0a:e5c1:111:1234::/64 accept
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Status
|
||||
|
||||
With this second step we create the basis for actually running VMs
|
||||
that we (as an operator) don't trust. So now we have a prototype and
|
||||
we have network security. We probably want to begin to automate things
|
||||
in the next step.
|
|
@ -0,0 +1,122 @@
|
|||
title: How to build an OpenStack alternative: Step 3, Generating Mac Addresses
|
||||
---
|
||||
pub_date: 2020-01-13
|
||||
---
|
||||
author: ungleich virtualisation team
|
||||
---
|
||||
twitter_handle: ungleich
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
_discoverable: yes
|
||||
---
|
||||
abstract:
|
||||
First step to automation
|
||||
---
|
||||
body:
|
||||
|
||||
This time we describe how to begin automation in uncloud,
|
||||
our OpenStack alternative.
|
||||
|
||||
The previous time we described
|
||||
[how to secure the network](../how-to-build-an-openstack-alternative-step-2-secure-the-network/).
|
||||
|
||||
## Mac Addresses
|
||||
|
||||
Mac addresses are identifiers for network cards. Like a street number
|
||||
is for a house. A virtual machine can have one or more network
|
||||
interfaces. Each of these interfaces need a unique number, the mac
|
||||
address.
|
||||
|
||||
## Choosing the prefix
|
||||
|
||||
We checked how [OpenNebula](https://opennebula.org/) is doing it.
|
||||
They basically use the **02:00** prefix and generate mac addresses after
|
||||
that. The
|
||||
[QEMU mac address
|
||||
prefix](https://gist.github.com/ashee/9241ab6281e6f4d1ef9b)
|
||||
seems to be 52:54:00.
|
||||
According to [Michael
|
||||
Stapelberg](https://michael.stapelberg.ch/posts/2012-11-21-kvm_best_practices_2012/)
|
||||
the **f6** prefix can be used due to the second lowest bit set to 1.
|
||||
|
||||
Checking with [Wikipedia](https://en.wikipedia.org/wiki/MAC_address),
|
||||
this bit indeed specifies whether or not a mac address is locally or
|
||||
universally administrated.
|
||||
|
||||
For that reason we will use **42** as our prefix, which is **1000010**
|
||||
in binary and thus has the second least significant bit set to 1.
|
||||
|
||||
## Generating Mac addresses
|
||||
|
||||
Mac addresses are basically just numbers and so we treat them as
|
||||
such. We need to store the index of which is the current mac address
|
||||
and for the next time we create a VM, use the next mac address.
|
||||
|
||||
The python code to generate a new mac address looks as follows:
|
||||
|
||||
```
|
||||
@staticmethod
|
||||
def int_to_mac(number):
|
||||
b = number.to_bytes(6, byteorder="big")
|
||||
return ':'.join(format(s, '02x') for s in b)
|
||||
|
||||
def getnext(self):
|
||||
if self.last:
|
||||
last_number = int(self.last[0], 16)
|
||||
|
||||
if last_number == int('0xffffff', 16):
|
||||
raise Error("Exhausted all possible mac addresses - try to free some")
|
||||
|
||||
next_number = last_number + 1
|
||||
else:
|
||||
next_number = 0
|
||||
|
||||
next_number_string = "{:012x}".format(next_number)
|
||||
|
||||
next_mac_number = self.prefix + next_number
|
||||
next_mac = self.int_to_mac(next_mac_number)
|
||||
```
|
||||
|
||||
It basically says:
|
||||
|
||||
* If there has been a mac address used add 1 to it and use the next
|
||||
one
|
||||
* Produce an error, if the whole prefix has been used
|
||||
* If no mac address has been used, use the first one
|
||||
* Convert the number to the standard format (aa:bb:cc:dd:ee:ff)
|
||||
|
||||
There is some additional logic on saving the MAC address to which we
|
||||
will come back in one of the next posts.
|
||||
|
||||
## Using the MAC address generator
|
||||
|
||||
From our prototype, we modify the original `vm.sh` script to include a
|
||||
call to the mac address generator as follows:
|
||||
|
||||
```
|
||||
...
|
||||
mac=$(./mac-gen.py)
|
||||
...
|
||||
$qemu -name "uncloud-${uuid}" \
|
||||
-machine pc,accel=${accel} \
|
||||
-m ${memory} \
|
||||
-smp ${cores} \
|
||||
-uuid ${uuid} \
|
||||
-drive file=alpine-virt-3.11.2-x86_64.iso,media=cdrom \
|
||||
-netdev tap,id=netmain,script=./ifup.sh,downscript=./ifdown.sh \
|
||||
-device virtio-net-pci,netdev=netmain,id=net0,mac=${mac}
|
||||
```
|
||||
|
||||
In good UNIX manner, the generator simply outputs the MAC address on
|
||||
stdout to be used by any software.
|
||||
|
||||
## Status
|
||||
|
||||
While being a small and very specific tool, the mac address generator
|
||||
is actually a key element of creating a virtualisation
|
||||
framework. Without it, it is practically impossible to spawn a dynamic
|
||||
amount of virtual machines.
|
||||
|
||||
With our prototype, a secured network and the mac address generator we
|
||||
are not far from being able to migrate some test VMs to uncloud.
|
|
@ -0,0 +1,71 @@
|
|||
title: How to build an OpenStack alternative: Step 4, adding a database
|
||||
---
|
||||
pub_date: 2020-01-14
|
||||
---
|
||||
author: ungleich virtualisation team
|
||||
---
|
||||
twitter_handle: ungleich
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
_discoverable: yes
|
||||
---
|
||||
abstract:
|
||||
Data begins to accumulate
|
||||
---
|
||||
body:
|
||||
|
||||
This time we describe how to
|
||||
store information in a database and why we selected etcd as the
|
||||
primary database.
|
||||
|
||||
The previous time we described
|
||||
[how to generate MAC
|
||||
addresses](../how-to-build-an-openstack-alternative-step-3-automating-mac-addresses/),
|
||||
a key element of uncloud.
|
||||
|
||||
## More Data
|
||||
|
||||
We now have a couple of running VMs, we want to remember which VMs
|
||||
are running and also add more information. Who owns a VM? And later
|
||||
also where is the VM running.
|
||||
|
||||
## Database
|
||||
|
||||
We decided to use [etcd](https://etcd.io/) as our primary database.
|
||||
The main reason for it is that we don't want to add a single point of
|
||||
failure into uncloud and we don't need guarantees provided by
|
||||
standard SQL.
|
||||
|
||||
An alternative we still consider is postgresql. While it is not
|
||||
inherently distributed (at all), it also
|
||||
supports storing JSON and has quite a sophisticated messaging system.
|
||||
|
||||
## Refactoring: phasing in a database
|
||||
|
||||
So far we used a couple of python and shell scripts to create the base
|
||||
of uncloud. Now that things become a bit more serious, we needed to
|
||||
refactor our code. Shell and python scripts are cleaned up and
|
||||
become python a proper python module, which we lovely call
|
||||
`uncloud.hack`.
|
||||
|
||||
## Python, ETCD and JSON
|
||||
|
||||
We decided to use [python-etcd3](https://python-etcd3.readthedocs.io/)
|
||||
to access etcd from the python world, as it supports the API version
|
||||
3.
|
||||
|
||||
For the data format we decided to use JSON, as it is easy to read.
|
||||
|
||||
Each VM is identified by a random UUID, so we don't need to store a
|
||||
counter for VMs.
|
||||
|
||||
## Status
|
||||
|
||||
At this point uncloud can create VMs and the VMs are registered
|
||||
in etcd as the database. So while we don't have logic yet for
|
||||
(automatic) VM migration, the information about VMs is already stored
|
||||
in a distributed database.
|
||||
|
||||
So if one of our hosts vanishes, we can in theory already redeploy the
|
||||
existing VMs.
|
|
@ -0,0 +1,130 @@
|
|||
title: How to build an OpenStack alternative: Step 5, adding metadata
|
||||
---
|
||||
pub_date: 2020-01-15
|
||||
---
|
||||
author: ungleich virtualisation team
|
||||
---
|
||||
twitter_handle: ungleich
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
_discoverable: yes
|
||||
---
|
||||
abstract:
|
||||
Let the VMs get information about themselves
|
||||
---
|
||||
body:
|
||||
|
||||
This time we describe how virtual machines can get information about
|
||||
themselves like which ssh keys should have access to it.
|
||||
|
||||
The previous time we
|
||||
[added a database to
|
||||
uncloud](../how-to-build-an-openstack-alternative-step-4-adding-a-database/).
|
||||
|
||||
## Motivation
|
||||
|
||||
If we were to start VMs without a metadata service, all of the VMs
|
||||
would be looking identical and would not be able to know, whom to
|
||||
allow access to it.
|
||||
|
||||
To customise a VM or to make it usable, we need to tell it who has
|
||||
access to it and potentially inject even more information.
|
||||
|
||||
## Metadata service: how others do it
|
||||
|
||||
Enters the metadata service. OpenNebula solves this problem quite
|
||||
nicely by attaching a virtual cdrom to the VMs. That cdrom contains
|
||||
only one file, `context.sh`. This file contains information about
|
||||
|
||||
* networking
|
||||
* ssh keys
|
||||
|
||||
OpenStack with cloud-init on the other side uses an HTTP based
|
||||
service that is found on the address `http://169.254.169.254/`.
|
||||
|
||||
Both schemes come with disadvantages that we don't want to replicate
|
||||
in uncloud:
|
||||
|
||||
In the opennebula case changing metadata information while the VM is
|
||||
running requires to create a new CDROM and if that one is still
|
||||
mounted, the VM might not get the up-to-date information. This is a
|
||||
bit of a theorethical case, as the metadata is rarely re-used after
|
||||
booting.
|
||||
|
||||
However changing the information provided in the context.sh inside the
|
||||
ISO always requires to generate a new ISO. While technical possible,
|
||||
not very elegant.
|
||||
|
||||
The OpenStack based approach has (from our point of view) a much
|
||||
bigger problem: it relies on IPv4. VMs running on uncloud primarily
|
||||
run IPv6 and should function without any IPv4 stack.
|
||||
|
||||
The motivation for using the 169.254.0.0/16 network is clear: it works
|
||||
without having an IP address management system in place.
|
||||
|
||||
## Solving it the smart way
|
||||
|
||||
So it seems like the general approach of OpenStack/cloud-init is
|
||||
actually quite elegant, if it wasn't forcing IPv4.
|
||||
|
||||
In the IPv6 world, we always have link local addresses in the
|
||||
**fe80::/10** network. Should we just replace the OpenStack approach
|
||||
with IPv6?
|
||||
|
||||
We don't think so, it has the same argument in favor for IPv4 networks
|
||||
that we have in favor for IPv6 networks.
|
||||
|
||||
Instead, we suggest to add a simple change to the OpenStack approach:
|
||||
Use http://metadata instead of using an IP address.
|
||||
|
||||
## http://metadata
|
||||
|
||||
So how should this work and why is this better than using
|
||||
http://169.254.169.254/?
|
||||
|
||||
Using a name, it doesn't matter whether the VM is on an IPv4 ore
|
||||
IPv6 network.
|
||||
|
||||
Using just the hostname, not an FQDN (i.e. metadata.example.com) makes
|
||||
it portable.
|
||||
|
||||
The name can be resolved via various methods:
|
||||
|
||||
* uncloud: it will be delivered by DNS
|
||||
* openstack: either via DNS (like uncloud) or if there is no IPAM, it
|
||||
can be statically set in /etc/hosts
|
||||
|
||||
In the DNS resolving case, this actually gets even more interesting,
|
||||
because we can use the **DNS search path**. So while the client tries
|
||||
to resolve the hostname **metadata**, the underlying resolver library
|
||||
will also look for **metadata.example.com**, if example.com is in the
|
||||
search path.
|
||||
|
||||
## uncloud implementation
|
||||
|
||||
In uncloud we have implemented a sample [metadata
|
||||
service](https://code.ungleich.ch/uncloud/uncloud/tree/master/uncloud/metadata).
|
||||
|
||||
However IPAM (i.e. router advertisements) and DNS servers are not part
|
||||
of uncloud and can be used from the regular system infrastructure.
|
||||
|
||||
In one of the next versions we plan to include helpers that allow you
|
||||
to bootstrap IPAM and DNS easily.
|
||||
|
||||
|
||||
## Status
|
||||
|
||||
At this point uncloud can create VMs and the VMs can get the ssh keys
|
||||
that should have access from the metadata service.
|
||||
|
||||
With this latest add-on uncloud gets near the range of a usable
|
||||
prototype. A lot of things will probably need to be refactored in the
|
||||
future, but at the moment uncloud supports already:
|
||||
|
||||
* creating VMs (using qemu)
|
||||
* securing the VM network (using nftables)
|
||||
* generating unique mac addresses (uncloud python code)
|
||||
* storing information in a distributed database (using pytho-etcd3 and
|
||||
etcd)
|
||||
* providing basic metadata inforamtion (uncloud python code)
|
|
@ -0,0 +1,59 @@
|
|||
title: Redesign into Zero Carbon
|
||||
---
|
||||
pub_date: 2020-01-26
|
||||
---
|
||||
author: ungleich
|
||||
---
|
||||
twitter_handle: ungleich
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
_discoverable: no
|
||||
---
|
||||
abstract:
|
||||
We need to redesign ourself into zero carbon
|
||||
---
|
||||
body:
|
||||
|
||||
## Reality check: it's been warm and it's not right
|
||||
|
||||
In our small mountain village in the Swiss Alps, we’ve been having an exceptionally warm winter. Max. 11°C in January, is still cold enough for our servers but some of the local businesses are suffering from not having enough visitors to the region, since people usually come here to enjoy skiing and other winter sports that require snow and colder weather.
|
||||
|
||||
![](/u/image/december2019-weather.jpg)
|
||||
|
||||
While one strangely warm and snowless winter is not direct evidence of climate change, we can’t help but wonder what will happen if this continues every year: with such warm weather, what will happen to our mountain ecosystem and ultimately to us humans? What will happen when there is no snow left on top of the Alps?
|
||||
We are in fact witnessing this change right now - the Pizol glacier in the Glarus Alps has been melting with an unprecedented speed and it is [due to disappear completely by 2030.] (https://www.swissinfo.ch/eng/reuters/climate-activists-hold-event-to-mark-vanishing-swiss-glacier/45247240) And it is just one of the many glaciers we are hopelessly watching while it melts away.
|
||||
|
||||
![](/u/image/world-4c-higher.jpg)
|
||||
|
||||
No snow on the Alps and having most parts of southern Europe turning into deserts is not a part of dystopian sci-fi scenario, but our reality that environmental scientists are forecasting with gravitas. UK Met Office researchers warn that [by 2060, the world could warm up by 4 °C](https://www.newscientist.com/article/dn19778-royal-society-paints-picture-of-a-world-4-c-warmer/) which will likely cause a serious food and water shortage for the world: animals and plants will die and so will people.
|
||||
|
||||
## Every fraction of degree matters, and that requires our action.
|
||||
|
||||
According to the environmental scientists we are living a critical time: meaning we can still change things but we don't have any time to waste before it is really too late. Last Tuesday at the World Economic Forum Davos, [Greta Thunberg read out an inspiring speech](https://youtu.be/rJ8Q_1r9L8U) which told the world that "Every fraction of degree matters." Every effort we do to reduce carbon emission matters and those of us who can, we need to do this in scale and with speed. One of the point she stressed is that richer countries need to get down to zero emission much faster than now - because we could, when we really mean to.
|
||||
|
||||
## The physical reality of our digital world
|
||||
|
||||
So what can we do? Probably most of you do some things for the environment, no doubt about that. Today what we want to talk about is reducing carbon emission from our digital world. To be specific, going zero carbon for our digital activities.
|
||||
We don't assume you to be stupid, but this is often very well hidden to all of us: that everything we do online actually has carbon footprint. We just don't see it so we tend to go on without really thinking about it, but we are still responsible for everything we do - searching, clicking, downloading, uploading, transferring, streaming, really every byte counts. Because although not so apparent on the digital surface, every data exists somewhere as physical infrastructure that runs with power generated by some source, 24/7. [10 minutes of YouTube equals 1g of CO2e,](https://www.creditangel.co.uk/blog/consumption-and-carbon-footprint-of-the-internet) [30 minutes of Netflix equals 1.6 kg(!) of CO2,](https://www.news18.com/news/buzz/half-an-hour-of-netflix-and-chill-emits-the-same-amount-of-co2-as-6-km-drive-2364791.html) and the list goes on and on. You got the idea.
|
||||
|
||||
## How to reduce your digital CO2 emission
|
||||
|
||||
A very good practice you can do easily is slimming down your digital acitivity. It's also healthier for most of us to get away from the screen once in a while. Pick up a book from your local library instead of that bad movie you downloaded from torrent. (And of course walk or bike to that library if you can.) Problem solved.
|
||||
No, problem not solved. Most of us do this digital thing for a living. We need to use data and some of us are actually saving the world by doing what we do. Many of us are in fact on the good side in fighting the evil (and/or) stupid side. Then what?
|
||||
Then what you need to do is go renewable for your digital data. Go with renewable energy as much as you can, as fast you can.
|
||||
|
||||
## How do I know where my cloud is at?
|
||||
|
||||
True, most people don't really know or care where their data is at. We kind of know what's bad with fast fashion or disposable plastics but we didn't have to think about what kind of energy our cloud uses. In the meantime the [IT service industry grew as big as aviation industry in terms of carbon emission](https://time.com/46777/your-data-is-dirty-the-carbon-price-of-cloud-computing/) and now it takes about 2% of total global carbon emissions. So it is really about time we start to feel towards and act responsible with our cloud choices. You can start by finding out where your data physically is, and what kind of energy it uses. Most of the times it's not that hard to find out, and if it's hidden, you need to request the information to be disclosed to your provider. Where are they keeping their servers, and what is the energy source they are using? Are they running servers with coal or other fossil fuels? Or nuclear power? Or renewable energy such as water, solar or windpower?
|
||||
|
||||
## Zero Carbon VS. Carbon Offset
|
||||
|
||||
This should be an obvious point, but it's not always so obvious for most of us. Zero carbon emission from the energy source (meaning produced by 100% renewable source such as water or solarpower) is a better choice than carbon offsetting. Carbon offsetting, roughly translates into using whatever energy source available (say coal or nuclear) and paying money for funding projects for reducing the CO2 already added to the air. Carbon offsetting is a solution with its own goals and values, but it is not an answer for our critical environmental situation especially if we have zero carbon as an option. Imagine, when a glass is full, not adding any drop to it would be the sane approach if we do not want to overflow the glass.
|
||||
|
||||
## Where do I find the zero carbon solutions?
|
||||
|
||||
## What is available as Zero Carbon cloud now?
|
||||
|
||||
- cloud storage
|
||||
- chat (mattermost and matrix)
|
87
content/u/blog/redesign-zero-carbon/contents.lr
Normal file
|
@ -0,0 +1,87 @@
|
|||
title: Zero Carbon for Digital World
|
||||
---
|
||||
pub_date: 2020-01-29
|
||||
---
|
||||
author: ungleich
|
||||
---
|
||||
twitter_handle: ungleich
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
_discoverable: yes
|
||||
---
|
||||
abstract:
|
||||
We need to redesign our digital use into zero carbon
|
||||
---
|
||||
body:
|
||||
|
||||
## The temperature is rising
|
||||
|
||||
In our small mountain village in the Swiss Alps, we’ve been having an exceptionally warm winter. We had Maximum 18°C in December and 11°C in January, that is still cold enough for our servers but some of the local businesses are struggling with not having enough visitors to the region, since people usually come here to enjoy skiing and other winter sports that require snow and colder temperature.
|
||||
|
||||
While one strangely warm and snowless winter is not direct evidence of climate change, we can’t help but wonder what will happen if this continues every year: are we in the middle of watching something that is going away for good?
|
||||
|
||||
![](/u/image/december2019-weather.jpg)
|
||||
|
||||
In the Swiss Alps one of the things we see going away every year is the glacier - the Pizol glacier in the Glarus Alps, just around the corner for us, has been melting with unprecedented speed and it is [due to disappear completely by 2030.](https://www.swissinfo.ch/eng/reuters/climate-activists-hold-event-to-mark-vanishing-swiss-glacier/45247240) And it is just one of the many glaciers we are hopelessly watching while it melts away.
|
||||
|
||||
![](/u/image/pizol.jpg)
|
||||
|
||||
When the temperature is rising and no ice is left to lock the cool air within, what will happen to our mountain ecosystem and to us people? It will certainly look different from today, and not in a good way.
|
||||
No snow on the Alps and having most parts of southern Europe turning into deserts is what environmental scientists are forecasting with gravitas. UK Met Office researchers warn that [by 2060, the world could warm up by 4 °C](https://www.newscientist.com/article/dn19778-royal-society-paints-picture-of-a-world-4-c-warmer/) which will likely cause a serious food and water shortage for the world: animals and plants will face an existential threat and so will people.
|
||||
|
||||
![](/u/image/world-4c-higher.jpg)
|
||||
|
||||
## We need to keep it cool
|
||||
|
||||
It is important to note that we are living a critical time. Last Tuesday at the World Economic Forum Davos, the young environmental activist [Greta Thunberg told the world](https://youtu.be/rJ8Q_1r9L8U) that we have less than 8 years to stop the temperature rising from more than 1.5°C, and for that "every fraction of degree matters."
|
||||
Every effort we do to reduce carbon emission matters and those of us who can, we need to do this in scale and with speed. Especially the ones residing in wealthier countries need to get down to zero emission much faster than now.
|
||||
But how? We recycle our bottles and paper, we say no to plastic bags, we use more trains than planes, but is that enough to keep the world from getting hotter?
|
||||
There's still something missing. When every fraction of degree matters we need to look at every aspect of our daily life with attention - especially the invisible parts.
|
||||
|
||||
## The physical reality of our digital world
|
||||
|
||||
The missing part we need to look at is the carbon emission from our digital activities: everything we do online actually has carbon footprints. We just don't see it so we tend to go on without really thinking about it, but we are still responsible for every byte we touch: searching, clicking, downloading, uploading, transferring, streaming. And our digital carbon footprint is in fact significant. Let's see some very relatable examples, [10 minutes of YouTube equals 1g of CO2e,](https://www.creditangel.co.uk/blog/consumption-and-carbon-footprint-of-the-internet) [30 minutes of Netflix equals 1.6 kg(!) of CO2,](https://www.news18.com/news/buzz/half-an-hour-of-netflix-and-chill-emits-the-same-amount-of-co2-as-6-km-drive-2364791.html).
|
||||
The truth is not so apparent on the digital surface, but every data *exists* somewhere as physical infrastructure that runs 24/7 with power generated by *some* source. And it is emitting more and more CO2 into the air we are living in.
|
||||
|
||||
## How to reduce your digital carbon footprint
|
||||
|
||||
Now the question is how do we reduce, or avoid the CO2 emission from our digital use. A very good practice you can do easily is slimming down your digital activity. It's also *healthier* for most of us to get away from the screen once in a while. Pick up a book from your local library instead of that bad movie you downloaded from torrent. And of course walk or bike to that library if you can. Problem solved.
|
||||
No, problem not solved. Most of us do these digital activities for a living. We need to use data and some of us are actually saving the world by doing what we do. Many of us are in fact on the good side of fighting the evil and/or stupid side. Then what?
|
||||
Then what you need to do is going renewable for your digital data. Go with clean energy as much as you can, as fast you can.
|
||||
|
||||
## How is my digital world powered?
|
||||
|
||||
Maybe your digital service provider such as your chat app or photo cloud, is already run by clean energy. [But likely they are not.](http://lab.cccb.org/en/how-polluting-is-the-internet/) The picture below gives you an overview of what the energy sources are per country in Europe - and remember, Europe is on the better side of the world in terms of energy sources. But even in Europe you can see most countries still depend on non-renewable energy sources.
|
||||
|
||||
![](/u/image/energy-source-by-country.jpg)
|
||||
|
||||
We already know that fast fashion and disposable plastics are bad - that they are easy to use but destroys our environment and creates too much carbon emission in its lifecycle - and the same logic applies to our digital data. We need to acknowledge that the widely available digital services are in fact bad for the environment, say the messenger or the chat everybody around you uses, or the cloud that just comes with your device by default. As a matter of fact the IT service industry [grew as big as the aviation industry in terms of carbon emission](https://time.com/46777/your-data-is-dirty-the-carbon-price-of-cloud-computing/) and now it takes about 2% of total global carbon emissions. So it is really about time we start to act responsibly for our digital choices.
|
||||
The first step for reducing your digital carbon footprint is finding out where your data physically is to know what kind of energy the infrastructure uses. If the information is hidden, you need to request your provider to disclose it. Where are they keeping their servers, and what is the energy source they are using? Are they [running servers with coal, oil or other fossil fuels?](https://www.nytimes.com/roomfordebate/2012/09/23/informations-environmental-cost/clean-it-means-clean-energy-suppliers-too) Or is your digital service run by nuclear power?
|
||||
|
||||
## Zero Carbon VS. Carbon Offset
|
||||
|
||||
When you pay attention to the energy sources of your digital services, you see that some of the service providers claim they are *green* because they do carbon offset. Then we need to ask, can carbon offset be an answer for keeping the temperature down?
|
||||
The short answer is no. Imagine, when a glass is full, not adding any drop to it would be the best approach if we do not want to overflow the glass. What we need right now is *zero* carbon emission from the energy source (meaning produced by 100% renewable sources such as water or solar power) and not carbon offsetting. Carbon offsetting, roughly translates into using whatever energy source available (say fossil fuel or nuclear) and paying money for funding projects for reducing the CO2 that is already added into the air. Carbon offsetting is obviously better than not offsetting, but not emitting CO2 from the energy source is ultimately better than CO2 offsetting.
|
||||
|
||||
## Use small and renewable digital services
|
||||
|
||||
There are two ways to reduce the carbon footprint from our digital data. One is finding [the ones who are running by zero carbon already,](https://github.com/vrde/notes/tree/master/zero-carbon) and supporting them by using those instead of others. This means your digital life will be only enabled by clean energy, and you will have zero carbon emission in terms of energy used for running your services. By supporting zero carbon standard you encourage the new service providers coming into the market to start clean with renewable energy.
|
||||
The second way is pushing your current service provider to change how they are running their servers, to go fully renewable. The advantage of this will be that the change will affect a bigger number of people, when really done. The disadvantage of it is that bigger companies take much more time in changing their huge infrastructure, while even more CO2 will be emitted from them into the air.
|
||||
We want to stress that, for those who care and who are capable, go for the first option. It is for the same reason as the zero carbon vs. carbon offset. When there are those who already doing the right things, go with them now, instead of continuing with [those who plan to reach their goal in the coming decades.](https://www.bloomberg.com/news/articles/2019-09-20/amazon-s-emissions-bigger-than-some-rivals-trail-walmart)
|
||||
|
||||
## Zero Carbon to take over the status quo
|
||||
|
||||
So how do the small and renewable zero carbon digital services look in reality? We can take us as one of the examples.
|
||||
In this small Alpine village we are located at, we are running [servers with only renewable energy.](https://datacenterlight.ch/en-us/cms/hydropower/) That is 99.9% hydropower and 0.1% solar power. Our case is a bit special because we brought our servers into old buildings that used to work as spinning and weaving factories that are built many years ago when Switzerland hosted a strong textile industry. Now the textile industry all moved out of the country looking for lower labour cost, leaving vast empty industrial buildings. Thanks to the infrastructure previously built, we directly produce the hydroelectricity a few meters away from our servers, by the water melted from the glacier on the Alps.
|
||||
What we do is [we only use recycled servers,](https://ungleich.ch/en-us/cms/blog/2019/06/28/how-run-really-green-datacenter/) so we can extend their lifecycle as long as possible before they end up in the landfill. And we do not waste energy for cooling the servers: the mountain temperature is cool enough throughout the year, and the big space we have helps the servers from being overheated.
|
||||
|
||||
![](/u/image/zerocarbon_no.jpg)
|
||||
|
||||
On top of this fully renewable and recycled infrastructure runs the digital services such as cloud storage, [Zero Carbon Cloud](https://ungleich.ch/u/products/zero-carbon-cloud/) and team chat, [Zero Carbon Chat.](https://ungleich.ch/u/products/zero-carbon-chat/) These are cutting-edge applications that are developed by the fantastic open source community ([Nextcloud](https://nextcloud.com/) and [Mattermost,](https://mattermost.com/) respectively), and we make it a rule that only the services used and tested extensively by our team internally are offered to external customers. Digital services for everyday use such as Dropbox, Google Photos, iCloud, Slack, Whatsapp can be easily replaced by its Zero Carbon alternatives.
|
||||
|
||||
## There are more Zero Carbon to come
|
||||
|
||||
Our plan is releasing more zero carbon options that can replace digital services with big carbon footprints. Our next one to come is Zero Carbon Matrix which is a chat service with bridging different platforms and end-to-end encryption features, and also in the queue is Zero Carbon Code Hosting which can replace GitHub. Do you have an idea what should be our next Zero Carbon project? Share your thoughts. Talk to us via [Twitter @ungleich](https://twitter.com/ungleich)(which we plan to offer as a Zero Carbon Social soon), or you can join [our chat](https://chat.ungleich.ch) (which is also a nice test for you in using Zero Carbon Chat) or you can drop us a mail at zerocarbon@ungleich.ch.
|
||||
|
||||
|
BIN
content/u/blog/redesign-zero-carbon/zerocarbon-meditation.jpg
Normal file
After Width: | Height: | Size: 488 KiB |
74
content/u/blog/uncloud-next
Normal file
|
@ -0,0 +1,74 @@
|
|||
x step 4 = database!
|
||||
- image contextualisation
|
||||
- dnsmasq
|
||||
- metadata
|
||||
- for getting keys
|
||||
- user metadata
|
||||
- user authentication
|
||||
- otp or ldap or plain file
|
||||
- for registering keys
|
||||
- for creating VMs
|
||||
- automating
|
||||
- trigger / postgres / etcd
|
||||
- building vm images!
|
||||
- generate tap names matching vm??? problem, because inteerfaces are
|
||||
limited in length!
|
||||
|
||||
[root@diamond hackcloud]# ip link add b23456789012345 type bridge
|
||||
[root@diamond hackcloud]# ip link add b234567890123456 type bridge
|
||||
Error: argument "b234567890123456" is wrong: "dev" not a valid ifname
|
||||
[root@diamond hackcloud]#
|
||||
|
||||
- VMID is not uuid, but counter; using hexa; using 16**10,
|
||||
gives 1099511627776 VMs
|
||||
|
||||
>>> (16**10)/(1000*24*365)
|
||||
125515.02600182648
|
||||
|
||||
interface names:
|
||||
|
||||
x = vxlan ?
|
||||
b = bridge
|
||||
v = vm
|
||||
|
||||
|
||||
=> 16 types possible
|
||||
|
||||
10+1 used => 4 left
|
||||
|
||||
2 positions for interface id? => 256 interfaces per VM
|
||||
|
||||
mac:
|
||||
|
||||
48 bits = 6 bytes
|
||||
1 byte = 2hexa positions
|
||||
|
||||
prefix is 02:00: = 2 bytes
|
||||
we have 4 bytes = 8 hexa left!!!!
|
||||
embed mac suffix as ID!
|
||||
full mac = 12 bytes
|
||||
|
||||
No vmprefix + counter -> because counter size might always be wrong
|
||||
(how many interfaces? 16? 256? ... )
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
No stale firewall entries as we regnerate, not keep the list!
|
||||
|
||||
table bridge filter {
|
||||
chain prerouting {
|
||||
type filter hook prerouting priority 0;
|
||||
policy accept;
|
||||
|
||||
ibrname br100 jump netpublic-$version
|
||||
}
|
||||
chain netpublic-10 {
|
||||
...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
can generate new full chain, change only the jump
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Much later:
|
||||
- rate limiting
|
29
content/u/events/contents.lr
Normal file
|
@ -0,0 +1,29 @@
|
|||
_model: page-2020
|
||||
---
|
||||
title: Events
|
||||
---
|
||||
content:
|
||||
|
||||
The following is a list of events we provide or participate in.
|
||||
|
||||
## 2020
|
||||
|
||||
* [2020-12-04..2020-12-06: Hack4Glarus 2020 Winter Edition @ Data Center Light, Linthal](https://hack4glarus.ch/)
|
||||
* [2020-06-05..2020-06-07: Hack4Glarus 2020 Summer Edition @ Data Center Light, Linthal](https://hack4glarus.ch/)
|
||||
* [2020-04-25: IPv6 in der Bildung - Open Education Day @ PHBern, Bern](https://openeducationday.ch/programm-2020/ipv6-in-der-bildung/)
|
||||
* [2020-02-18: 9. Glarner Innovationsapéro: Digitalisierung in der Praxis @ Linthpark, Linthal](https://www.myswitzerland.com/en-ca/experiences/events/9-glarner-innovationsapero-digitalisierung-in-der-praxis/)
|
||||
|
||||
|
||||
## 2019
|
||||
|
||||
* [2019-12-12: Ungleich IPv6-only Hosting @ IPv6 Council Annual Meeting 2019, UK IPv6 Council, London](https://www.ipv6.org.uk/2019/09/06/ipv6-council-annual-meeting-2019/)
|
||||
* [Ungleich IPv6-only Hosting Presentation](https://www.ipv6.org.uk/wp-content/uploads/2019/12/UKIPv6Council_meeting_2019_Ungleich_IPv6-only_Hosting.pdf)
|
||||
* [2019-11-29..2019-12-01: Hack4Glarus 2019 Winter Edition @ Data Center Light, Linthal](https://hack4glarus.ch/)
|
||||
* [2019-10-18..2019-10-18: RIPE79, Rotterdam](https://ripe79.ripe.net/)
|
||||
* [RIPE79 Presentation](https://ripe79.ripe.net/presentations/19-How-to-Build-Maintain-and-Market-an-IPv6-only-Data-Center-RIPE79.pdf)
|
||||
* [RIPE79 Recording](https://ripe79.ripe.net/archives/video/165/)
|
||||
* [2019-09-03: The reasons for IPv6-only hosting @ Cloud and IPv6 Workshop, UK IPv6 Council, London](https://www.ipv6.org.uk/2019/08/08/cloud-and-ipv6-workshop/)
|
||||
* [The reasons for IPv6-only hosting: Presentation](https://www.ipv6.org.uk/wp-content/uploads/2019/08/2019-IPv6-Cloud-ipv6-only-hosting.pdf)
|
||||
* [2019-05-31..2019-06-02: Hack4Glarus 2019 Summer Edition @ Data Center Light, Linthal](https://hack4glarus.ch/)
|
||||
* [2019-10-25: White Hat Hacking @ Digital Bridge Forum, Nur-Sultan](http://digitalbridge.kz/)
|
||||
* [Profession of a White Hat Hacker (Presentation)](profession_of_a_white_hat_hacker-20191025_digitalbridge.pdf)
|
|
@ -2,7 +2,11 @@ _discoverable: no
|
|||
---
|
||||
_hidden: no
|
||||
---
|
||||
title: Cloud Backup
|
||||
title: Backup
|
||||
---
|
||||
subtitle: Your insurance in Switzerland
|
||||
---
|
||||
|
||||
Pricing:
|
||||
|
||||
"VM" (IP?)
|
|
@ -36,7 +36,7 @@ average 4m² surrounding area). This way we don't need to actively cool.
|
|||
If you want to bring your own hardware, you can select from the
|
||||
following options:
|
||||
|
||||
## Space
|
||||
### Space
|
||||
|
||||
For one server we provide you with 1m² of physical shelf space. We
|
||||
call this our "base unit".
|
||||
|
@ -45,12 +45,12 @@ Your server can be 1U, 2U or even 4U high. Contact us for special sizes.
|
|||
We expect your server to not create more warmth than 3000 BTU/h. If it
|
||||
produces more heat, you will need to add more base units.
|
||||
|
||||
## Electricity
|
||||
### Electricity
|
||||
|
||||
Your electricity usage is monitored and charged monthly. The price for
|
||||
electricity is 0.2 CHF/kWh.
|
||||
|
||||
## Connectivity
|
||||
### Connectivity
|
||||
|
||||
We offer 3 levels of connectivity:
|
||||
|
||||
|
@ -64,7 +64,7 @@ Bandwidth exceeding the booked tarif is charged at 2.5 CHF/Mbps.
|
|||
|
||||
You get a multi mode fiber cable (850nm transceivers) to your shelf.
|
||||
|
||||
## IP addresses
|
||||
### IP addresses
|
||||
|
||||
* Colocation includes a /48 IPv6 network for free
|
||||
* IPv4 addresses are provided using NAT64 for 9 CHF/IPv4 address/month
|
||||
|
|
|
@ -29,21 +29,8 @@ application with a good conscience and without emitting extra carbon.
|
|||
content1_text:
|
||||
## Development flow
|
||||
|
||||
The below diagram gives an overview of a typical development flow with
|
||||
our Django hosting:
|
||||
|
||||
---
|
||||
content1_image: djangohosting.svg
|
||||
---
|
||||
description2:
|
||||
|
||||
## How it works
|
||||
|
||||
## Components
|
||||
|
||||
Our Django hosting consists of 1-2 virtual machines and an optional
|
||||
backup. Our customers often start with a development system
|
||||
|
||||
The diagram gives an overview of a typical development flow with
|
||||
our Django hosting.
|
||||
|
||||
We strongly recommend to develop Django (like any other application)
|
||||
with a version control system, even if you are just a single
|
||||
|
@ -52,6 +39,20 @@ repository](https://code.ungleich.ch) for free
|
|||
(you only need to [register an account](https://account.ungleich.ch)).
|
||||
|
||||
|
||||
|
||||
---
|
||||
content1_image: djangohosting.svg
|
||||
---
|
||||
description2:
|
||||
|
||||
## Components
|
||||
|
||||
Depending on your stage of development, a Django hosting may contain
|
||||
1 virtual machine (production), 2 virtual machines (staging +
|
||||
production) and optionally a backup.
|
||||
|
||||
|
||||
|
||||
## Pricing
|
||||
|
||||
* Setup fee is 35 CHF
|
||||
|
|
|
@ -36,14 +36,14 @@
|
|||
<!-- editor -->
|
||||
<g id="node1" class="node">
|
||||
<title>editor</title>
|
||||
<polygon fill="none" stroke="black" points="247.5,-419 146.5,-419 146.5,-383 247.5,-383 247.5,-419"/>
|
||||
<text text-anchor="middle" x="197" y="-397.3" font-family="Times,serif" font-size="14.00">Local editor</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="247.5,-419 146.5,-419 146.5,-383 247.5,-383 247.5,-419"/>
|
||||
<text text-anchor="middle" x="197" y="-397.3" font-family="Times,serif" font-size="14.00" fill="#ffffff">Local editor</text>
|
||||
</g>
|
||||
<!-- git -->
|
||||
<g id="node2" class="node">
|
||||
<title>git</title>
|
||||
<polygon fill="none" stroke="black" points="182,-325 16,-325 16,-289 182,-289 182,-325"/>
|
||||
<text text-anchor="middle" x="99" y="-303.3" font-family="Times,serif" font-size="14.00">Local version control</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="182,-325 16,-325 16,-289 182,-289 182,-325"/>
|
||||
<text text-anchor="middle" x="99" y="-303.3" font-family="Times,serif" font-size="14.00" fill="#ffffff">Local version control</text>
|
||||
</g>
|
||||
<!-- editor->git -->
|
||||
<g id="edge1" class="edge">
|
||||
|
@ -54,8 +54,8 @@
|
|||
<!-- localweb -->
|
||||
<g id="node3" class="node">
|
||||
<title>localweb</title>
|
||||
<polygon fill="none" stroke="black" points="391.5,-325 200.5,-325 200.5,-289 391.5,-289 391.5,-325"/>
|
||||
<text text-anchor="middle" x="296" y="-303.3" font-family="Times,serif" font-size="14.00">Development webserver</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="391.5,-325 200.5,-325 200.5,-289 391.5,-289 391.5,-325"/>
|
||||
<text text-anchor="middle" x="296" y="-303.3" font-family="Times,serif" font-size="14.00" fill="#ffffff">Development webserver</text>
|
||||
</g>
|
||||
<!-- editor->localweb -->
|
||||
<g id="edge3" class="edge">
|
||||
|
@ -66,9 +66,9 @@
|
|||
<!-- repo -->
|
||||
<g id="node5" class="node">
|
||||
<title>repo</title>
|
||||
<polygon fill="none" stroke="black" points="256.5,-186 125.5,-186 125.5,-148 256.5,-148 256.5,-186"/>
|
||||
<text text-anchor="middle" x="191" y="-170.8" font-family="Times,serif" font-size="14.00">Code repository</text>
|
||||
<text text-anchor="middle" x="191" y="-155.8" font-family="Times,serif" font-size="14.00">(f.i. git)</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="256.5,-186 125.5,-186 125.5,-148 256.5,-148 256.5,-186"/>
|
||||
<text text-anchor="middle" x="191" y="-170.8" font-family="Times,serif" font-size="14.00" fill="#ffffff">Code repository</text>
|
||||
<text text-anchor="middle" x="191" y="-155.8" font-family="Times,serif" font-size="14.00" fill="#ffffff">(f.i. git)</text>
|
||||
</g>
|
||||
<!-- git->repo -->
|
||||
<g id="edge2" class="edge">
|
||||
|
@ -79,15 +79,15 @@
|
|||
<!-- prodvm -->
|
||||
<g id="node4" class="node">
|
||||
<title>prodvm</title>
|
||||
<polygon fill="none" stroke="black" points="398,-62 228,-62 228,-24 398,-24 398,-62"/>
|
||||
<text text-anchor="middle" x="313" y="-46.8" font-family="Times,serif" font-size="14.00">Production Server</text>
|
||||
<text text-anchor="middle" x="313" y="-31.8" font-family="Times,serif" font-size="14.00">uwsgi,nginx,postgres</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="398,-62 228,-62 228,-24 398,-24 398,-62"/>
|
||||
<text text-anchor="middle" x="313" y="-46.8" font-family="Times,serif" font-size="14.00" fill="#ffffff">Production Server</text>
|
||||
<text text-anchor="middle" x="313" y="-31.8" font-family="Times,serif" font-size="14.00" fill="#ffffff">uwsgi,nginx,postgres</text>
|
||||
</g>
|
||||
<!-- backupvm -->
|
||||
<g id="node8" class="node">
|
||||
<title>backupvm</title>
|
||||
<polygon fill="none" stroke="black" points="699.5,-325 580.5,-325 580.5,-289 699.5,-289 699.5,-325"/>
|
||||
<text text-anchor="middle" x="640" y="-303.3" font-family="Times,serif" font-size="14.00">Backup server</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="699.5,-325 580.5,-325 580.5,-289 699.5,-289 699.5,-325"/>
|
||||
<text text-anchor="middle" x="640" y="-303.3" font-family="Times,serif" font-size="14.00" fill="#ffffff">Backup server</text>
|
||||
</g>
|
||||
<!-- prodvm->backupvm -->
|
||||
<g id="edge6" class="edge">
|
||||
|
@ -106,8 +106,8 @@
|
|||
<!-- stagingvm -->
|
||||
<g id="node7" class="node">
|
||||
<title>stagingvm</title>
|
||||
<polygon fill="none" stroke="black" points="600.5,-61 475.5,-61 475.5,-25 600.5,-25 600.5,-61"/>
|
||||
<text text-anchor="middle" x="538" y="-39.3" font-family="Times,serif" font-size="14.00">Staging Server</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="600.5,-61 475.5,-61 475.5,-25 600.5,-25 600.5,-61"/>
|
||||
<text text-anchor="middle" x="538" y="-39.3" font-family="Times,serif" font-size="14.00" fill="#ffffff">Staging Server</text>
|
||||
</g>
|
||||
<!-- repo->stagingvm -->
|
||||
<g id="edge5" class="edge">
|
||||
|
@ -119,8 +119,8 @@
|
|||
<!-- monitoring -->
|
||||
<g id="node6" class="node">
|
||||
<title>monitoring</title>
|
||||
<polygon fill="none" stroke="black" points="436,-185 290,-185 290,-149 436,-149 436,-185"/>
|
||||
<text text-anchor="middle" x="363" y="-163.3" font-family="Times,serif" font-size="14.00">Monitoring server</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="436,-185 290,-185 290,-149 436,-149 436,-185"/>
|
||||
<text text-anchor="middle" x="363" y="-163.3" font-family="Times,serif" font-size="14.00" fill="#ffffff">Monitoring server</text>
|
||||
</g>
|
||||
<!-- monitoring->prodvm -->
|
||||
<g id="edge7" class="edge">
|
||||
|
@ -133,8 +133,8 @@
|
|||
<!-- monitoringmonitor -->
|
||||
<g id="node9" class="node">
|
||||
<title>monitoringmonitor</title>
|
||||
<polygon fill="none" stroke="black" points="562,-325 416,-325 416,-289 562,-289 562,-325"/>
|
||||
<text text-anchor="middle" x="489" y="-303.3" font-family="Times,serif" font-size="14.00">Monitoring server</text>
|
||||
<polygon fill="#40a9e3" stroke="#40a9e3" points="562,-325 416,-325 416,-289 562,-289 562,-325"/>
|
||||
<text text-anchor="middle" x="489" y="-303.3" font-family="Times,serif" font-size="14.00" fill="#ffffff">Monitoring server</text>
|
||||
</g>
|
||||
<!-- monitoringmonitor->monitoring -->
|
||||
<g id="edge8" class="edge">
|
||||
|
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 8.1 KiB |
143
content/u/products/zero-carbon-chat/contents.lr
Normal file
|
@ -0,0 +1,143 @@
|
|||
_discoverable: no
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
title: Zero Carbon Chat
|
||||
---
|
||||
subtitle: backed by 100% renewable energy
|
||||
---
|
||||
link: https://link-to-the-real-product.ch
|
||||
---
|
||||
feature1_title: Hosted in Switzerland
|
||||
---
|
||||
feature1_text:
|
||||
|
||||
Zero Carbon Chat is hosted exclusively in Switzerland, offering its political stability and strict privacy laws as advantages
|
||||
|
||||
---
|
||||
feature2_title: Full control over your privacy
|
||||
---
|
||||
feature2_text:
|
||||
|
||||
Have full control over your privacy with zero compromise. Your Zero Carbon Chat conversation stays only with you without 3rd parties access.
|
||||
---
|
||||
feature3_title: Thoroughly sustainable
|
||||
---
|
||||
feature3_text: With Zero Carbon Chat you are not using fossil fuels or unsustainable energy sources. Your chat is running on infrastructure 100% run by renewable energy.
|
||||
---
|
||||
content1_text:
|
||||
|
||||
## What is Zero Carbon Chat?
|
||||
|
||||
Zero Carbon Chat is a secure and sustainable alternative to your Slack or Skype, Whatsapp. Our chat offers enhanced security and full control over your privacy, and it is hosted at a datacenter run by 100% renewable energy. By using Zero Carbon Chat instead of other environmentally unsustainable chats, you and your community will help our planet stay cooler while keeping your message private.
|
||||
|
||||
## Whom is Zero Carbon Chat for?
|
||||
|
||||
Zero carbon chat is suitable for everybody who ueses chat or messanger, and wants to
|
||||
make a better choice for our environmental future. It is especially
|
||||
suitable for the following use case.
|
||||
|
||||
* If you are looking for a team chat with as little carbon footprint as possible
|
||||
* If you are using Slack and want to move away from it to a secure alternative without confusing your users: Zero Carbon Chat has a very enduser-friendly user interface that offers a seamless transition from Slack in terms of UX.
|
||||
* If you are looking for a team chat/group communication with an extremely easy invitation management fit for people with diverse backgrounds
|
||||
* If you are looking for a team chat that is fast for joining different channels/rooms
|
||||
* If you are looking for a chat with linear scaling for system overheads
|
||||
* If you are dealing with sensitive data over your chat that needs to be protected against the unstable political situation
|
||||
* If your team needs a communication platform that does not betray the team's values: in other words, if your team values protecting the environment.
|
||||
|
||||
## How can I access it?
|
||||
|
||||
You can access the chat easily from your browser or from the mobile app.
|
||||
|
||||
## Zero Carbon Chat Plans
|
||||
|
||||
You can start Zero Carbon Chat with below pricing plans. The cost is made of two parts, a one-time initial setup fee and the monthly plan you choose. Our team will get in touch with you as soon as we receive the order and will give you the access to the chat in 2 business days. Growing your chat after starting a plan is very easy and can be done anytime: you can schedule your upgrade with our team for free to find the ideal time for you.
|
||||
|
||||
---
|
||||
content1_image: /u/image/carbonzero-energy-green.jpg
|
||||
---
|
||||
content2_text:
|
||||
|
||||
## Tech stack
|
||||
|
||||
Zero Carbon Chat is your own Mattermost instance maintained and hosted at our [hydroelectric datacenter](https://datacenterlight.ch) located in Switzerland.
|
||||
|
||||
At Zero Carbon Chat you will have
|
||||
|
||||
* Every connection to the chat secured by https
|
||||
* Fully scalable chat
|
||||
* Unlimited bandwidth under fair use policy
|
||||
* Our Zero Carbon emission chat badge exposable on your website
|
||||
* Your chat data protected by Swiss privacy laws
|
||||
* Monthly or yearly credit card, or wire transfer as the payment option
|
||||
* Discount for larger plans so you can be compensated more for the carbon emission you avoided
|
||||
|
||||
At Zero Carbon Chat you will not have
|
||||
|
||||
* Chat data physically hosted at servers powered by fossil fuel or other unsustainable energy sources
|
||||
* Your privacy compromise from storing your data in a country where authorities have global access to your data
|
||||
* Spam mails from us that use unnecessary bytes that cost all of us from our environment
|
||||
* Cryptocurrency as payment option
|
||||
* Unnecessary frills in our web interface which require more computing power and result in more carbon emission
|
||||
|
||||
|
||||
---
|
||||
content2_image: /u/image/zerocarbon-no.jpg
|
||||
---
|
||||
offer1_title: Light Chat 36 CHF/Month
|
||||
---
|
||||
offer1_text:
|
||||
|
||||
* Up to 50 users
|
||||
* Fully scalable anytime (1.5 CHF/Month for 100 GB HDD)
|
||||
* Application firewall included
|
||||
* [Initial setup fee 30 CHF](https://ungleich.ch/product/0carbonchat-setup/)
|
||||
|
||||
Recommended for a small group
|
||||
|
||||
---
|
||||
offer1_link: https://ungleich.ch/product/0carbonchat-light/
|
||||
---
|
||||
offer2_title: Community Chat 63 CHF/Month
|
||||
---
|
||||
offer2_text:
|
||||
|
||||
* Up to 100 users
|
||||
* Fully scalable anytime (1.5 CHF/Month for 100 GB HDD)
|
||||
* Application firewall included
|
||||
* [Initial setup fee 30 CHF](https://ungleich.ch/product/0carbonchat-setup/)
|
||||
|
||||
Recommended for small to medium groups
|
||||
|
||||
---
|
||||
offer2_link: https://ungleich.ch/product/0carbonchat-community/
|
||||
---
|
||||
offer3_title: Power Chat 157 CHF/Month
|
||||
---
|
||||
offer3_text:
|
||||
|
||||
* Up to 1000 users
|
||||
* Fully scalable anytime (1.5 CHF/Month for 100 GB HDD)
|
||||
* Application firewall included
|
||||
* [Initial setup fee 30 CHF](https://ungleich.ch/product/0carbonchat-setup/)
|
||||
|
||||
Recommended for large groups
|
||||
|
||||
---
|
||||
offer3_link: https://ungleich.ch/product/0carbonchat-power/
|
||||
---
|
||||
header:
|
||||
|
||||
#### generic-header ####
|
||||
headers:
|
||||
|
||||
zero carbon chat
|
||||
team chat
|
||||
made clean
|
||||
|
||||
----
|
||||
primary_color: #4da553
|
||||
----
|
||||
header_color: text-light
|
||||
----
|
||||
nav_link_color: navbar-dark
|
137
content/u/products/zero-carbon-cloud/contents.lr
Normal file
|
@ -0,0 +1,137 @@
|
|||
_discoverable: yes
|
||||
---
|
||||
_hidden: no
|
||||
---
|
||||
title: Zero Carbon Cloud
|
||||
---
|
||||
subtitle: backed by 100% renewable energy
|
||||
---
|
||||
link: https://link-to-the-real-product.ch
|
||||
---
|
||||
feature1_title: Fully renewable
|
||||
---
|
||||
feature1_text: Stop storing your data in servers run by dirty energy, we use 100% renewable power from Swiss Alps for running our computers for storing your data.
|
||||
---
|
||||
feature2_title: Fully sustainable
|
||||
---
|
||||
feature2_text: New hardware is as bad as fast fashion for the environment. We opt for fully reusing hardware and buildings to extend the lifecycle of the technology.
|
||||
---
|
||||
feature3_title: Fully conscious
|
||||
---
|
||||
feature3_text: We slim down everything as much as possible to reduce computing power and energy consumption.
|
||||
---
|
||||
content1_text:
|
||||
|
||||
## What is Zero Carbon Cloud?
|
||||
|
||||
In the era of rapid climate change and sea-level rise, Zero Carbon Cloud is here to provide a future-orientated data storage that does not use environmentally harmful energy sources. Zero Carbon Cloud is a safe and clean alternative to your dropbox or Google cloud. Our cloud storage service is built with sustainability to its core, with fully renewable energy and with fully recycled infrastructure.
|
||||
|
||||
## Whom is Zero Carbon Cloud for?
|
||||
|
||||
Zero Carbon Cloud is suitable for everybody who uses digital data but wants to
|
||||
make a better choice for our environmental future. It is especially
|
||||
suitable for the following use case.
|
||||
|
||||
* If you deal with 100 GB data or more per month from your phone, tablet, desktop computer,
|
||||
laptop computer, servers.
|
||||
* If your work requires to store or to back up data digitally.
|
||||
* If your work requires to move 100 GB data or more from one device to another.
|
||||
* If you need to store your data without compromising your privacy.
|
||||
* If your country’s privacy laws are less reliable than Switzerland.
|
||||
* If you are located at a geographic region where its political climate is less stable than your data need to be.
|
||||
|
||||
## How can I access it?
|
||||
|
||||
You can access the storage easily from your desktop, mobile phone, tablet and of course laptop.
|
||||
|
||||
## Zero Carbon Cloud Plans
|
||||
|
||||
You can start Zero Carbon Cloud with below plans. The cost is made of two parts, a one-time initial setup fee and the monthly plan you choose. Our team will get in touch with you as soon as we receive the order and will give you the access to the cloud in 1 business day. Growing your cloud after starting a plan is very easy and can be done anytime, 100 GB HDD is 1.5 CHF per month.
|
||||
|
||||
---
|
||||
content1_image: /u/image/zerocarbon-yes.jpg
|
||||
---
|
||||
content2_text:
|
||||
|
||||
## Tech stack
|
||||
|
||||
Zero Carbon cloud is your own Nextcloud instance stored and run at our datacenter located in Switzerland.
|
||||
|
||||
At Zero Carbon Cloud you will have
|
||||
* Fully scalable storage and backup
|
||||
* Your offsite backup for your own NAS
|
||||
* Unlimited bandwidth under fair use policy
|
||||
* Our zero carbon emission cloud badge exposable on your website
|
||||
* Safe data storage protected by Swiss privacy laws
|
||||
* Monthly or yearly credit card payment option, or wire transfer payment option
|
||||
* Discount for larger plans so you can be compensated more for the carbon emission you saved
|
||||
|
||||
At Zero Carbon Cloud you will not have
|
||||
|
||||
* Storage run by fossil fuel and other unsustainable energy sources
|
||||
* Spam mails from us that use unnecessary bytes that cost all of us from our environment
|
||||
* Cryptocurrency payment option
|
||||
* Unnecessary frills in our web interface which again increase the
|
||||
computing power and result in more carbon emission
|
||||
|
||||
|
||||
---
|
||||
content2_image: /u/image/zerocarbon-no.jpg
|
||||
---
|
||||
offer1_title: 100 GB @ 23CHF/month
|
||||
---
|
||||
offer1_text:
|
||||
|
||||
* **One free IPv6 VPN** included for increased security
|
||||
* Datacenter location: Glarus, Switzerland
|
||||
* Enhanced security by limiting access to only your devices
|
||||
* [1 time initial setup fee 35 CHF](https://ungleich.ch/product/0carboncloud-setup/)
|
||||
|
||||
Recommended for your private use or for a smaller project
|
||||
|
||||
---
|
||||
offer1_link: https://ungleich.ch/product/0carboncloud-100GB/
|
||||
---
|
||||
offer2_title: 1 TB @ 36.5CHF/month
|
||||
---
|
||||
offer2_text:
|
||||
|
||||
* **Two free IPv6 VPNs** included for increased security
|
||||
* Datacenter location: Glarus, Switzerland
|
||||
* Enhanced security by limiting access to only your devices
|
||||
* [1 time initial setup fee 35 CHF](https://ungleich.ch/product/0carboncloud-setup/)
|
||||
|
||||
Recommended for small to medium organisations
|
||||
|
||||
---
|
||||
offer2_link: https://ungleich.ch/product/0carboncloud-1TB/
|
||||
---
|
||||
offer3_title: 50 TB @ 540 CHF/month
|
||||
---
|
||||
offer3_text:
|
||||
|
||||
* **Ten free IPv6 VPNs** included for increased security
|
||||
* Datacenter location: Glarus, Switzerland
|
||||
* Enhanced security by limiting access to only your devices
|
||||
* [1 time initial setup fee 35 CHF](https://ungleich.ch/product/0carboncloud-setup/)
|
||||
* **30% large scale discount** applied
|
||||
|
||||
Recommended for medium to large organisations
|
||||
|
||||
---
|
||||
offer3_link: https://ungleich.ch/product/0carboncloud-50TB/
|
||||
---
|
||||
header:
|
||||
|
||||
#### generic-header ####
|
||||
headers:
|
||||
|
||||
don't offset,
|
||||
do zero carbon.
|
||||
zero carbon cloud
|
||||
----
|
||||
primary_color: #40a9e3
|
||||
----
|
||||
header_color: text-light
|
||||
----
|
||||
nav_link_color: navbar-dark
|
22
content/u/projects/ipv6-chat/contents.lr
Normal file
|
@ -0,0 +1,22 @@
|
|||
title: IPv6.Chat
|
||||
---
|
||||
subtitle: Let's talk about IPv6
|
||||
---
|
||||
content:
|
||||
|
||||
## IPv6 chat
|
||||
|
||||
IPv6 deployment and usage is growing and with that the need to find
|
||||
answers to common IPv6 questions.
|
||||
|
||||
We have created a chat room dedicated to IPv6 so that anyone can
|
||||
exchange their ideas about IPv6.
|
||||
|
||||
You can join the chat via
|
||||
|
||||
* [IPv6.chat](https://IPv6.chat) (via Mattermost)
|
||||
* #ipv6:ungleich.ch (via Matrix)
|
||||
|
||||
Note: there is also an #ipv6 channel on Freenode. We are currently
|
||||
trying to figure out whether we can bridge IPv6.chat into the IRC room
|
||||
to combine them.
|
16
content/u/projects/open-chat/contents.lr
Normal file
|
@ -0,0 +1,16 @@
|
|||
title: Open Chat
|
||||
---
|
||||
subtitle: Open Source requires Open Communication
|
||||
---
|
||||
content:
|
||||
|
||||
You can chat with us either via Mattermost on
|
||||
[chat.ungleich.ch](https://chat.ungleich.ch) or
|
||||
Matrix on [matrix.ungleich.ch](https://matrix.ungleich.ch).
|
||||
For matrix you can find our public channels on **+public:ungleich.ch**.
|
||||
|
||||
To foster IPv6 deployement, we created [IPv6.chat](../ipv6-chat),
|
||||
which is also reachable on both chat systems.
|
||||
|
||||
And some of our channels are also available on IRC, you can find them
|
||||
on the [list of bridged channels](https://redmine.ungleich.ch/projects/open-infrastructure/wiki/CHATting_with_ungleich).
|
84
content/u/projects/opensource/contents.lr
Normal file
|
@ -0,0 +1,84 @@
|
|||
title: Open Source
|
||||
---
|
||||
subtitle: Open Source literally created ungleich
|
||||
---
|
||||
content:
|
||||
|
||||
## History of Open Source at ungleich
|
||||
|
||||
Open Source at ungleich is deeply rooted. It is actually Open Source
|
||||
that started ungleich in 2013: You might now that
|
||||
[Nico](https://www.nico.schottelius.org), the founder of ungleich,
|
||||
is one of the two
|
||||
original authors of [cdist](https://cdi.st), an Open Source
|
||||
configuration management system (Steven Armstrong being the other
|
||||
crazy person).
|
||||
|
||||
In 2013 a company from France requested commercial support for
|
||||
cdist and soon after other Swiss companies were asking for Open Source
|
||||
Software consultancy. This is how ungleich was originally born.
|
||||
|
||||
Whenever possible, we ask our customers to make the code that we
|
||||
create for them also Open Source and some of our customers very much
|
||||
welcome this approach.
|
||||
|
||||
In 2017 we started the [Data Center Light
|
||||
project](../data-center-light), which turns old buildings (like
|
||||
factory halls) into data centers.
|
||||
We realised that many problems that we solve are repeating
|
||||
infrastructure problems.
|
||||
For that reason we created the [Open
|
||||
Infrastructure project](https://redmine.ungleich.ch/projects/open-infrastructure).
|
||||
in 2018 to open source our infrastructure and have others profit from
|
||||
our experiences. Also in 2017 we released an
|
||||
[Open Source Crowdfunding Platform together with
|
||||
200ok](https://200ok.ch/posts/joint-release-of-swiss-crowdfunder.html).
|
||||
|
||||
We also released the
|
||||
[ungleich-tools](https://code.ungleich.ch/ungleich-public/ungleich-tools)
|
||||
that we use to manage or support the infrastructure. Or you can find
|
||||
checkout the [backup tool
|
||||
ccollect](https://www.nico.schottelius.org/software/ccollect/) that we
|
||||
maintain. Or if you are ever in the need to track your time,
|
||||
we have [time tracking for
|
||||
geeks](https://www.nico.schottelius.org/software/ctt/).
|
||||
|
||||
|
||||
## Open Source at ungleich today
|
||||
|
||||
Almost all of our products are based on Open Source Software, which is
|
||||
why we contribute back to projects that we use.
|
||||
|
||||
While we still have [our github
|
||||
account](https://github.com/orgs/ungleich/), most of our public code
|
||||
can be found on
|
||||
[code.ungleich.ch](https://code.ungleich.ch/ungleich-public/).
|
||||
|
||||
We also think that **Open Communication** is important and for that
|
||||
reason we allow [free access to our company chat](../open-chat) via
|
||||
Mattermost and Matrix.
|
||||
|
||||
We started the [Digital Glarus project](../digital-glarus) to
|
||||
support the local community and just recently opened the [Hacking
|
||||
Hotel](../hacking-hotel) in Diesbach to welcome (FOSS) hackers from
|
||||
all around the world.
|
||||
|
||||
And twice per year we welcome hackers to our (strongly Open Source
|
||||
driven) hackathon [Hack4Glarus](https://hack4glarus.ch).
|
||||
|
||||
Even this website is fully Open Source and if you don't like something
|
||||
on it, we look forward to a merge request against the
|
||||
[ungleich-staticcms](https://code.ungleich.ch/ungleich-public/ungleich-staticcms)
|
||||
repository.
|
||||
|
||||
|
||||
## SEE ALSO
|
||||
|
||||
* [ccollect](https://www.nico.schottelius.org/software/ccollect/)
|
||||
* [ctt](https://www.nico.schottelius.org/software/ctt/)
|
||||
* [Open Chat](../open-chat)
|
||||
* [Open Infrastructure](https://redmine.ungleich.ch/projects/open-infrastructure)
|
||||
* [Public ungleich git repositories](https://code.ungleich.ch/ungleich-public/)
|
||||
* [uncloud repository](https://code.ungleich.ch/uncloud/uncloud)
|
||||
* [ungleich-staticcms](https://code.ungleich.ch/ungleich-public/ungleich-staticcms)
|
||||
* [ungleich-tools](https://code.ungleich.ch/ungleich-public/ungleich-tools)
|
26
flowblocks/generic-header.ini
Normal file
|
@ -0,0 +1,26 @@
|
|||
[block]
|
||||
name = generic-header
|
||||
|
||||
[fields.headers]
|
||||
label = headers
|
||||
type = strings
|
||||
|
||||
[fields.primary_color]
|
||||
name = Landing Page Primary Color
|
||||
label = primary_color
|
||||
type = string
|
||||
|
||||
[fields.header_color]
|
||||
name = Header Color
|
||||
label = header_color
|
||||
type = select
|
||||
choices = text-light, text-dark
|
||||
choice_labels = light, dark
|
||||
default = text-light
|
||||
|
||||
[fields.nav_link_color]
|
||||
name = Navigation Link Color
|
||||
type = select
|
||||
choices = navbar-light, navbar-dark
|
||||
choice_labels = dark, light
|
||||
default = dark
|
|
@ -12,6 +12,10 @@ size = large
|
|||
label = Subtitle
|
||||
type = string
|
||||
|
||||
[fields.header]
|
||||
type = flow
|
||||
flow_blocks = generic-header
|
||||
|
||||
[fields.description1]
|
||||
label = Description 1
|
||||
type = markdown
|
||||
|
@ -51,7 +55,7 @@ type = markdown
|
|||
|
||||
[fields.content1_text]
|
||||
label = Content1 Text
|
||||
type = text
|
||||
type = markdown
|
||||
|
||||
[fields.content1_image]
|
||||
label = Content 1 Image
|
||||
|
@ -59,7 +63,7 @@ type = url
|
|||
|
||||
[fields.content2_text]
|
||||
label = Content 2 Text
|
||||
type = text
|
||||
type = markdown
|
||||
|
||||
[fields.content2_image]
|
||||
label = Content 2 Image
|
||||
|
@ -71,7 +75,7 @@ type = string
|
|||
|
||||
[fields.offer1_text]
|
||||
label = Offer 1 Text
|
||||
type = text
|
||||
type = markdown
|
||||
|
||||
[fields.offer1_link]
|
||||
label = Offer 1 Link
|
||||
|
@ -83,7 +87,7 @@ type = string
|
|||
|
||||
[fields.offer2_text]
|
||||
label = Offer 2 Text
|
||||
type = text
|
||||
type = markdown
|
||||
|
||||
[fields.offer2_link]
|
||||
label = Offer 2 Link
|
||||
|
@ -95,7 +99,7 @@ type = string
|
|||
|
||||
[fields.offer3_text]
|
||||
label = Offer 3 Text
|
||||
type = text
|
||||
type = markdown
|
||||
|
||||
[fields.offer3_link]
|
||||
label = Offer 3 Link
|
||||
|
|
7
templates/blocks/generic-header.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<div class="jumbotron jumbotron-fluid" style="background-color: {{this.primary_color}};">
|
||||
<div class="container-fluid">
|
||||
{% for h in this.headers %}
|
||||
<h1 class="display-1 generic-header {{this.header_color}}" style="font-weight: bolder;">{{h}}</h1>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
|
@ -5,12 +5,13 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<title>{% block title %}Welcome to ungleich.ch{% endblock %}</title>
|
||||
<title>ungleich.ch - {% block title %}Welcome!{% endblock %}</title>
|
||||
<!-- Bootstrap + helpers2 -->
|
||||
<link rel="stylesheet"
|
||||
href="/u/static/bootstrap-4.4.1-dist/css/bootstrap.min.css">
|
||||
|
||||
<link rel="shortcut icon" href="/u/static/images/favicon.ico"/>
|
||||
<link rel="stylesheet" href="/u/static/generic-header.css"/>
|
||||
|
||||
<!-- Google analytics -->
|
||||
<script>
|
||||
|
@ -26,8 +27,21 @@
|
|||
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="https://ungleich.ch">ungleich</a>
|
||||
{% if this.header %}
|
||||
{% set nav_style = 'background-color:' + this.header.blocks[0].primary_color + ';' %}
|
||||
{% set nav_classes = this.header.blocks[0].nav_link_color %}
|
||||
{% else %}
|
||||
{% set nav_classes = 'navbar-light bg-light' %}
|
||||
{% endif %}
|
||||
|
||||
<nav class="navbar navbar-expand-lg {{ nav_classes }}" style="{{ nav_style }}">
|
||||
<a class="navbar-brand" href="https://ungleich.ch">
|
||||
{% if 'navbar-dark' in nav_classes %}
|
||||
<img src="/u/image/ungleich-logo-white.svg" width="100px" alt="ungleich" style='padding-top: 0.5rem; padding-bottom: 0.8rem;'>
|
||||
{% else %}
|
||||
<img src="/u/image/ungleich-logo-black.svg" width="100px" alt="ungleich" style='padding-top: 0.5rem; padding-bottom: 0.8rem;'>
|
||||
{% endif %}
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button"
|
||||
data-toggle="collapse"
|
||||
data-target="#navbarSupportedContent"
|
||||
|
@ -39,22 +53,25 @@
|
|||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/blog/">Old Blog<a/>
|
||||
<a class="nav-link" href="/blog/">OLD BLOG<a/>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/u/blog/">New Blog<a/>
|
||||
<a class="nav-link" href="/u/blog/">NEW BLOG<a/>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="https://chat.ungleich.ch/">Chat<a/>
|
||||
<a class="nav-link" href="https://chat.ungleich.ch/">CHAT<a/>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/u/products/">Products</a>
|
||||
<a class="nav-link" href="/u/products/">PRODUCTS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/u/projects/">Projects</a>
|
||||
<a class="nav-link" href="/u/projects/">PROJECTS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/u/deals/">Deals</a>
|
||||
<a class="nav-link" href="/u/deals/">DEALS</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/u/events/">EVENTS</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0"
|
||||
|
@ -62,17 +79,12 @@
|
|||
<input class="form-control mr-sm-2" type="search"
|
||||
placeholder="Search" name="query" aria-label="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
|
||||
<a class="nav-link" href="/u/">
|
||||
<button type="button" class="btn btn-info"
|
||||
style="margin-left: 8px;">
|
||||
BETA Website
|
||||
</button>
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% if this.header %}
|
||||
{{ this.header.blocks[0] }}
|
||||
{% else %}
|
||||
<div class="position-relative overflow-hidden p-3 p-md-5 m-md-3 text-center bg-light">
|
||||
<div class="col-md-5 p-lg-5 mx-auto my-5">
|
||||
<h1 class="display-4 font-weight-normal">{{ self.title() }}
|
||||
|
@ -83,6 +95,7 @@
|
|||
<div class="product-device shadow-sm d-none d-md-block"></div>
|
||||
<div class="product-device product-device-2 shadow-sm d-none d-md-block"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
|
|
7
templates/sitemap.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
{%- for page in [site.root] if page != this recursive %}
|
||||
<url><loc>{{ page|url(external=true) }}</loc></url>
|
||||
{{- loop(page.children) }}
|
||||
{%- endfor %}
|
||||
</urlset>
|