Give a person a picture
people-operator reads the picture that a Person’s spec.avatar
names, and writes a square thumbnail of it, 256 by 256 pixels, into
status.thumbnail. Every screen draws that one field, so a new
picture reaches every screen with no restart. A Person with no
picture gets a thumbnail of their initials, in white on a colour that
the operator takes from the Person’s name.
Name the picture
Set spec.avatar to the URI of a JPEG, PNG, GIF, or WebP file:
apiVersion: people.liken.sh/v1alpha1
kind: Person
metadata:
name: ada
spec:
displayName: Ada Lovelace
avatar: https://pictures.example/people/ada.jpg
spec.avatar takes these schemes:
| Scheme | Who reads it |
|---|---|
https://<host>/<path> and http://<host>/<path> |
The operator fetches the file. |
data:image/png;base64,<data> |
The picture is in the field, and the operator decodes it. |
nfs://<server>/<path> |
A pod mounts the file’s directory from the NFS server, read-only. |
claim://<namespace>/<claim>/<path> |
A pod in the claim’s namespace mounts the claim, read-only. |
A Person has no namespace, so a claim URI names the claim’s
namespace first. The pod for an nfs:// picture runs in
liken-system.
The operator crops the centre square of the picture. Put the face in the middle. A transparent part of the picture shows the person’s colour.
The limits on a picture
The operator refuses a picture that breaks one of these limits:
- a file larger than 10 MiB;
- a picture wider or taller than 8192 pixels;
- a fetch that takes longer than 15 seconds;
- a pod that does not finish within two minutes.
Read whether the picture worked
The Picture column of kubectl get people shows the reason of the
AvatarReady condition. kubectl get people -o wide adds a Message
column with the condition’s message. The condition is True when the
thumbnail was made from the current spec.avatar, and False when the
picture did not read. The condition’s reason and message say why:
kubectl get person ada -o jsonpath='{.status.conditions[?(@.type=="AvatarReady")]}'
| Reason | Status | Meaning |
|---|---|---|
Fetched |
True |
The operator fetched the picture over HTTP. |
Inline |
True |
The operator decoded the data: URI. |
Baked |
True |
A pod read the picture from NFS or a claim. |
Initials |
True |
spec.avatar is empty, so the thumbnail shows the initials. |
FetchFailed |
False |
The server did not answer 200, the file is larger than 10 MiB, or the fetch took longer than 15 seconds. |
BakeFailed |
False |
The pod did not find the file, did not finish in two minutes, or wrote no result. A claim in a namespace that does not exist also fails this way. |
DecodeFailed |
False |
The file is not a JPEG, PNG, GIF, or WebP picture, or it is larger than 8192 pixels on a side. |
UnsupportedScheme |
False |
spec.avatar is not a URI in one of the five schemes. |
When a picture that worked before fails, the last good picture stays
in status.thumbnail. A Person that never had a good picture shows
their initials.
The condition holds only its last change. The operator also posts a
Kubernetes Event for each change of the condition’s status or
reason, with the same reason and message, so a source that failed and
then worked again is visible for an hour after. A change to False is
a Warning. A new picture that leaves the condition as it was, such
as a replaced picture at the same URL, posts AvatarUpdated. A
Person is cluster-scoped, so its Events are in the namespace
default:
kubectl describe person ada
kubectl events -n default --for person/ada
A pod that reads a claim runs as root with the DAC_OVERRIDE
capability, so it reads a file whatever its owner. An NFS server maps
root to its anonymous user unless the export says otherwise, so a
picture on NFS must be readable by that user.
Show a replaced picture
A URL, a file on NFS, and a file on a claim can change with no edit to
the Person, and the operator gets no event for that change. Every
six hours the operator reads each such picture again: it sends a
conditional GET with the ETag and Last-Modified it recorded, or
it starts a pod that compares the file’s time and size. A picture
that did not change costs one small request or one short pod, and
changes nothing.
To show a replaced picture at once, set the
people.liken.sh/check-avatar annotation to a new value. The value
has no meaning. A value that differs from status.avatar.checked is
the request. A timestamp is a convenient value:
kubectl annotate person ada --overwrite people.liken.sh/check-avatar="$(date -u +%FT%TZ)"
The operator reads the picture again, whether it changed or not, and
records the value in status.avatar.checked.