1 Commits

Author SHA1 Message Date
29980517f6 publish experimental apparatus plugin 2017-12-18 22:53:02 -07:00
12 changed files with 181 additions and 465 deletions

View File

@ -1,14 +0,0 @@
---
kind: pipeline
name: publish docker image
steps:
- name: build and publish
image: plugins/docker
settings:
username: 3wordchant
password:
from_secret: git_coopcloud_tech_token_3wc
repo: git.coopcloud.tech/wiki-cafe/wiki-farm
auto_tag: true
tags: latest
registry: git.coopcloud.tech

View File

@ -1,35 +1,20 @@
FROM node:lts-alpine FROM node:8-slim
RUN apk add --update --no-cache \
dumb-init \
git \
jq
WORKDIR "/home/node"
ARG WIKI_PACKAGE=wiki@0.37.0
USER node
RUN npm install -g --prefix . $WIKI_PACKAGE
RUN cd lib/node_modules/wiki/node_modules && \
rm -r wiki-security-passportjs && \
git clone https://git.coopcloud.tech/wiki-cafe/wiki-security-passportjs.git
RUN cd lib/node_modules/wiki/node_modules/wiki-security-passportjs && \
npm install && \
node_modules/grunt/bin/grunt
RUN mkdir -p .wiki
VOLUME "/home/node/.wiki"
RUN useradd --create-home app \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
jq \
git
WORKDIR /home/app
ARG WIKI_PACKAGE='dobbs/wiki#apparatus'
RUN su app -c "npm install -g --prefix . $WIKI_PACKAGE"
RUN su app -c "mkdir .wiki"
COPY configure-and-launch-wiki set-owner-name ./
RUN chown app configure-and-launch-wiki set-owner-name
VOLUME "/home/app/.wiki"
ENV DOMAIN=localhost
ENV OWNER_NAME="The Owner"
ENV COOKIE=insecure
EXPOSE 3000 EXPOSE 3000
USER app
ENV PATH="${PATH}:/home/node/bin" CMD ["./configure-and-launch-wiki"]
ENV NPM_CONFIG_PREFIX="${HOME}"
ENTRYPOINT ["dumb-init"]
CMD ["wiki", "--farm"]

104
README.md
View File

@ -1,80 +1,62 @@
# Federated Wiki Farm # Federated Wiki Farm
Start Playing Federated Wiki: http://start.fed.wiki http://fed.wiki.org
### Run a local wiki farm ### Get acquainted with wiki.
Launch the container:
``` bash
docker run -p 3000:3000 -it --rm \ docker run -p 3000:3000 -it --rm \
dobbs/farm dobbs/farm
```
Visit http://localhost:3000 and http://anything.localhost:3000 Visit http://localhost:3000
### Run a local wiki that will survive a reboot ### Make your wiki survive a reboot
Create a volume:
``` bash
docker volume create dot-wiki
```
Launch the container:
``` bash
docker run -p 3000:3000 -it --rm \ docker run -p 3000:3000 -it --rm \
-v ~/.wiki:/home/node/.wiki \ -v dot-wiki:/home/app/.wiki \
dobbs/farm dobbs/farm
```
Your wiki pages and configuration will be saved in the ~/.wiki folder. Visit http://localhost:3000
### Make your wiki a local farm
We're going to use http://localtest.me instead of localhost for our
domain name. See http://readme.localtest.me for more info.
Let's also use a different volume for this one:
``` bash
docker volume create localtest.me
```
Specify the domain name when you launch your wiki
``` bash
docker run -p 3000:3000 -it --rm \
-v localtest.me:/home/app/.wiki \
-e DOMAIN=localtest.me \
dobbs/farm
```
Open http://this.localtest.me:3000 in one tab.
Open http://that.localtest.me:3000 in another.
# Development # Development
This image's tag does not match the version of the included wiki This image's tag matches the version of the included wiki software.
software. Our version indicates the scale of changes in this tiny
devops pipeline.
Testing new images locally:
``` bash ``` bash
TAG=1.0.14-prefer-title git tag -am "" '0.13.0'
IMAGE=dobbs/farm:$TAG git push --tags
docker build --tag $IMAGE .
``` ```
You might also want to remember the most recent tag: The repos in Dockerhub and GitHub are configured to automatically build new tags.
``` bash
git tag --list | tail -1
```
Update WIKI_VERSIONS.txt
``` bash
docker run --rm $IMAGE wiki --version > WIKI_VERSIONS.txt
```
# Publish container images
End-to-end recipe to publish a new version. May require judgment in
the steps before git push and docker push.
``` bash
# Emit current version to standard error and next version to standard out.
# use that to assign the next TAG
TAG="$(git tag --list | tail -1 | perl -lne 'print STDERR $_;s/(\d+)$/$1+1/e;print $_;')"
IMAGE=dobbs/farm:$TAG
docker build --no-cache --tag $IMAGE .
docker build --tag dobbs/farm:latest .
docker run --rm $IMAGE wiki --version > WIKI_VERSIONS.txt
git add .
git commit -m "update WIKI_VERSIONS.txt for $TAG"
git tag -am "" "$TAG"
git push --atomic origin main "$TAG"
docker push $IMAGE
docker push dobbs/farm:latest
```
Sometimes we publish a docker image with no changes to the wiki source
code. This allows us to pick up non-breaking changes to some of the
plugins. Using `--no-cache` ensures docker re-runs this line from the
`Dockerfile` in particular: `npm install -g --prefix . $WIKI_PACKAGE`.
# Experiment with K8S
With the local kubernetes example (see [examples/k8s/README.md](./examples/k8s/README.md)):
``` bash
k3d image import $IMAGE --cluster wiki
kubectl patch deployment.apps/wiki-deployment \
--type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"'$IMAGE'"}]'
```

View File

@ -1,15 +0,0 @@
# Release Notes for 1.0.0
This is a significant **breaking** change from pre-1.0 releases. Especially:
* changed the user from `app` (`uid=1001(app) gid=1001(app) groups=1001(app)`)
to `node` (`uid=1000(node) gid=1000(node) groups=1000(node),1000(node)`)
* no longer installing `bash`, `configure-wiki`, nor `set-owner-name`
* no longer creating `/home/app/.wiki/wiki.json`
Those changes in particular will impose some work on authors upgrading
from previous versions.
The last non-breaking revision is 0.52.0 https://github.com/dobbs/farm/tree/0.52.0#readme

View File

@ -1,46 +0,0 @@
wiki: 0.37.0
wiki-server: 0.25.2
wiki-client: 0.30.1
wiki-security-friends: 0.2.5
wiki-security-passportjs: 0.10.0
wiki-plugin-activity: 0.6.1
wiki-plugin-assets: 0.5.1
wiki-plugin-audio: 0.2.0
wiki-plugin-bars: 0.5.0
wiki-plugin-calculator: 0.5.0
wiki-plugin-calendar: 0.3.0
wiki-plugin-changes: 0.4.0
wiki-plugin-chart: 0.4.0
wiki-plugin-code: 0.4.0
wiki-plugin-data: 0.3.0
wiki-plugin-factory: 0.3.0
wiki-plugin-favicon: 0.3.0
wiki-plugin-flagmatic: 0.2.0
wiki-plugin-force: 0.5.0
wiki-plugin-frame: 0.10.3
wiki-plugin-future: 0.4.0
wiki-plugin-graphviz: 0.11.3
wiki-plugin-grep: 1.1.0
wiki-plugin-html: 0.5.1
wiki-plugin-image: 0.5.0
wiki-plugin-line: 0.5.0
wiki-plugin-map: 0.8.0
wiki-plugin-markdown: 0.4.2
wiki-plugin-math: 0.1.0
wiki-plugin-metabolism: 0.3.0
wiki-plugin-method: 0.3.0
wiki-plugin-pagefold: 0.3.0
wiki-plugin-paragraph: 0.3.0
wiki-plugin-plugmatic: 1.3.1
wiki-plugin-pushpin: 0.5.0
wiki-plugin-radar: 0.5.0
wiki-plugin-recycler: 0.3.0
wiki-plugin-reduce: 0.3.0
wiki-plugin-reference: 0.3.0
wiki-plugin-report: 0.3.0
wiki-plugin-rollup: 0.3.0
wiki-plugin-roster: 0.3.0
wiki-plugin-scatter: 0.5.0
wiki-plugin-search: 0.2.0
wiki-plugin-transport: 0.2.0
wiki-plugin-video: 0.3.1

77
configure-and-launch-wiki Executable file
View File

@ -0,0 +1,77 @@
#!/bin/bash -eu
set -o pipefail
main() {
initialize-environment-vars
assert-file-privileges || report-errors-and-exit
ensure-owner-file
ensure-config-file
show-configs
exec-wiki
}
initialize-environment-vars() {
ERRORS=''
readonly OWNER_FILE=/home/app/.wiki/$DOMAIN.owner.json
readonly CONFIG_FILE=/home/app/.wiki/config.json
}
assert-file-privileges() {
[ -w /home/app/.wiki ] \
|| ERRORS="app cannot write to /home/app/.wiki\n${ERRORS}"
[ ${#ERRORS} == 0 ]
}
report-errors-and-exit() {
echo -e $ERRORS
echo "exiting."
exit 1
}
ensure-owner-file() {
if [ ! -r "$OWNER_FILE" ]; then
jq -n --arg name "$OWNER_NAME" --arg secret $(random-string) \
'.name = $name | .friend.secret = $secret' > $OWNER_FILE
fi
}
ensure-config-file() {
if [ ! -r "$CONFIG_FILE" ]; then
> $CONFIG_FILE \
jq -n -M \
--arg admin $(jq -r .friend.secret $OWNER_FILE) \
--arg random $(random-string) \
--arg cookie $COOKIE \
--arg domain $DOMAIN \
--arg owner $OWNER_FILE \
'
.admin = $admin
| .autoseed = true
| .farm = true
| .cookieSecret = $random
| .secure_cookie = ("secure" == $cookie)
| .security_type = "friends"
| .wikiDomains[$domain].id = "/home/app/.wiki/\($domain).owner.json"
'
fi
}
random-string() {
node -e 'console.log(require("crypto").randomBytes(64).toString("hex"))'
}
show-configs() {
set -x
ls -l $OWNER_FILE $CONFIG_FILE
cat $OWNER_FILE
cat $CONFIG_FILE
set +x
}
exec-wiki() {
exec /home/app/bin/wiki
}
main

View File

@ -1,56 +0,0 @@
# Wiki Farm in Kubernetes
There are easier ways to get started with federated wiki. Here we are
using wiki to drive some learning about kubernetes.
# We're using MacOS, Docker Desktop, and k3d
brew install --cask docker
brew install k3d
mkdir -p ~/.wiki-k8s ~/workspace/fedwiki
k3d create \
--server-arg --tls-san="127.0.0.1" \
--publish 80:80 \
-v "$HOME/.wiki-k8s:/macos/.wiki-k8s" \
-v "$HOME/workspace/fedwiki:/macos/fedwiki" \
--name wiki
# example ~/.wiki-k8s/config.json
{
"admin": "any memorable password",
"autoseed": true,
"farm": true,
"cookieSecret": "any random string",
"secure_cookie": false,
"security_type": "friends",
"wikiDomains": {
"localhost": {
"id": "/home/node/.wiki/localhost.owner.json"
},
"example.com": {
"id": "/home/node/.wiki/example.com.owner.json"
}
}
}
# example ~/.wiki-k8s/localhost.owner.json
`.friend.secret` must match the `.admin` field from `config.json`
{
"name": "The Owner",
"friend": {
"secret": "any memorable password"
}
}
# Deploy Wiki
kubectl apply -f http://deploy.wiki.do/assets/wiki/wiki.yaml
# Play with the wiki
open http://wiki.localhost

View File

@ -1,29 +0,0 @@
# HashiCorp Vault in kubernetes
HashiCorp recomend installing vault via helm. Your author prefers
plain old kubernetes configs.
So we generated the yaml via helm's template command.
helm template incubator/vault \
--name-template=vault \
--replicaCount=1 \
--set vault.dev=false \
--set vault.config.storage.file.path=/macos/.wiki-k8s/vault \
| egrep -v 'heritage: "?Helm"?' \
> vault.html
kubectl apply -k .
kubectl port-forward svc/vault 8200:8200 &> /dev/null &
export VAULT_ADDR=http://127.0.0.1:8200
vault status
vault operator init
vault operator unseal
# paste key-fragment 1
vault operator unseal
# paste key-fragment 2
vault operator unseal
# paste key-fragment 3
vault login
# paste root token

View File

@ -1,16 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vault
spec:
template:
spec:
containers:
- name: vault
volumeMounts:
- name: vault-data
mountPath: /macos/.wiki-k8s/vault
volumes:
- name: vault-data
hostPath:
path: /macos/.wiki-k8s/vault

View File

@ -1,10 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: vault
newName: vault
newTag: 1.3.1
resources:
- vault.yaml
patchesStrategicMerge:
- deployment-volumes.yaml

View File

@ -1,181 +0,0 @@
---
# Source: vault/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: vault
labels:
app: vault
release: "vault"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: vault
namespace: default
---
# Source: vault/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: "vault-config"
labels:
app: "vault"
release: "vault"
data:
config.json: |
{"listener":{"tcp":{"address":"[::]:8200","cluster_address":"[::]:8201","tls_disable":true}},"storage":{"file":{"path":"/macos/.wiki-k8s/vault"}}}
---
# Source: vault/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vault
labels:
app: vault
release: vault
annotations:
{}
spec:
selector:
matchLabels:
app: vault
release: vault
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
app: vault
release: vault
annotations:
checksum/config: 6868eb00aa48ca9485c365c3523ae431e7031233a1c046817a32c61e24ea817d
spec:
containers:
- name: vault
image: "vault:1.2.3"
imagePullPolicy: IfNotPresent
command: ["vault", "server", "-config", "/vault/config/config.json"]
ports:
- containerPort: 8200
name: api
- containerPort: 8201
name: cluster-address
livenessProbe:
# Alive if Vault is successfully responding to requests
httpGet:
path: /v1/sys/health?standbyok=true&uninitcode=204&sealedcode=204&
port: 8200
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
# Ready depends on preference
httpGet:
path: /v1/sys/health?standbycode=204&uninitcode=204&
port: 8200
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
securityContext:
readOnlyRootFilesystem: true
capabilities:
add:
- IPC_LOCK
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: VAULT_API_ADDR
value: "http://$(POD_IP):8200"
- name: VAULT_CLUSTER_ADDR
value: "https://$(POD_IP):8201"
- name: VAULT_LOG_LEVEL
value: "info"
resources:
{}
volumeMounts:
- name: vault-config
mountPath: /vault/config/
- name: vault-root
mountPath: /root/
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels:
app: 'vault'
release: 'vault'
topologyKey: kubernetes.io/hostname
weight: 100
serviceAccountName: vault
volumes:
- name: vault-config
configMap:
name: "vault-config"
- name: vault-root
emptyDir: {}
---
# Source: vault/templates/pdb.yaml
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: vault
spec:
maxUnavailable: 1
selector:
matchLabels:
app: vault
release: vault
---
# Source: vault/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: vault
labels:
app: vault
release: vault
spec:
type: ClusterIP
ports:
- port: 8200
protocol: TCP
targetPort: 8200
name: api
selector:
app: vault
release: vault
---
# Source: vault/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault
labels:
app: vault
release: "vault"
---
# Source: vault/templates/tests/test-vault-status.yaml
apiVersion: v1
kind: Pod
metadata:
name: "vault-vault-status-test"
annotations:
"helm.sh/hook": test-success
spec:
containers:
- name: vault-vault-status-test
image: "vault:1.2.3"
env:
- name: VAULT_ADDR
value: http://vault.default:8200
command: ["sh", "-c", "vault status"]
restartPolicy: Never

39
set-owner-name Executable file
View File

@ -0,0 +1,39 @@
#!/bin/bash -eu
set -o pipefail
usage() {
cat <<EOF
Usage: $(basename $0) NAME
replaces the owner's name in $OWNER_FILE
EOF
}
main() {
initialize-environment-vars $@ || { usage; exit 1; }
backup-and-save-name
report-success
}
initialize-environment-vars() {
readonly OWNER_FILE=/home/app/.wiki/$DOMAIN.owner.json
readonly OWNER_BACKUP_FILE=$OWNER_FILE-saved-$(date --iso-8601=minutes)
readonly NAME=${@:-missing}
[ ! "$NAME" == "missing" ]
}
backup-and-save-name() {
mv $OWNER_FILE $OWNER_BACKUP_FILE
jq ".name = \"$NAME\"" $OWNER_BACKUP_FILE > $OWNER_FILE
}
report-success() {
cat <<EOF
Owner's name changed to "$NAME"
Previous config is saved in ${OWNER_BACKUP_FILE##$PWD/}
EOF
}
main "$@"