| local kube = import "../../../kube/kube.libsonnet"; |
| |
| { |
| local radio = self, |
| local cfg = radio.cfg, |
| |
| cfg:: { |
| namespace: error "namespace must be set", |
| appName: "radio", |
| prefix: "", # if set, should be 'foo-' |
| port: 2137, |
| |
| icecast: { |
| location: error "location must be set", |
| admin: error "admin must be set", |
| limits: { |
| clients: 100, |
| sources: 2, |
| threadpool: 5, |
| queueSize: 524288, |
| clientTimeout: 30, |
| headerTimeout: 15, |
| sourceTimeout: 10, |
| burstOnConnect: true, |
| burstSize: 65535, |
| }, |
| authentication: { |
| sourcePassword: error "source password must be set", |
| relayPassword: error "relay password must be set", |
| adminPassword: error "admin password must be set", |
| }, |
| hostname: "localhost", |
| listenPort: 8080, |
| mounts: {}, |
| relays: {}, |
| }, |
| |
| tag: "latest", |
| image: "registry.k0.hswaw.net/app/radio:" + cfg.tag, |
| resources: { |
| requests: { |
| cpu: "25m", |
| memory: "50Mi", |
| }, |
| limits: { |
| cpu: "100m", |
| memory: "200Mi", |
| }, |
| }, |
| }, |
| |
| mount:: { |
| username: error "mount username must be defined", |
| password: error "mount password must be defined", |
| genre: "Classical", |
| bitrate: 128, |
| hidden: false, |
| fallbackMount: null, |
| }, |
| |
| makeName(suffix):: cfg.prefix + suffix, |
| |
| metadata:: { |
| namespace: cfg.namespace, |
| labels: { |
| "app.kubernetes.io/name": cfg.appName, |
| "app.kubernetes.io/managed-by": "kubecfg", |
| "app.kubernetes.io/component": "radio", |
| }, |
| }, |
| |
| configMap: kube.ConfigMap(radio.makeName("icecast")) { |
| metadata+: radio.metadata, |
| data: { |
| "icecast.xml": std.manifestXmlJsonml(["icecast", |
| ["location", cfg.icecast.location], |
| ["admin", cfg.icecast.admin], |
| ["limits", |
| ["clients", std.toString(cfg.icecast.limits.clients)], |
| ["sources", std.toString(cfg.icecast.limits.sources)], |
| ["threadpool", std.toString(cfg.icecast.limits.threadpool)], |
| ["queue-size", std.toString(cfg.icecast.limits.queueSize)], |
| ["client-timeout", std.toString(cfg.icecast.limits.clientTimeout)], |
| ["header-timeout", std.toString(cfg.icecast.limits.headerTimeout)], |
| ["source-timeout", std.toString(cfg.icecast.limits.sourceTimeout)], |
| ["burst-on-connect", if cfg.icecast.limits.burstOnConnect then "1" else "0"], |
| ["burst-size", std.toString(cfg.icecast.limits.burstSize)], |
| ], |
| ["authentication", |
| ["source-password", cfg.icecast.authentication.sourcePassword], |
| ["relay-user", "relay"], |
| ["relay-password", cfg.icecast.authentication.relayPassword], |
| ["admin-user", "admin"], |
| ["admin-password", cfg.icecast.authentication.adminPassword], |
| ], |
| ["hostname", cfg.icecast.hostname], |
| ["listen-socket", |
| ["port", std.toString(cfg.icecast.listenPort)], |
| ], |
| ["fileserve", "1"], |
| ["paths", |
| ["webroot", "/usr/share/icecast/web"], |
| ["adminroot", "/usr/share/icecast/admin"], |
| ], |
| ["logging", |
| ["accesslog", "-"], |
| ["errorlog", "-"], |
| ["loglevel", "2"], |
| ], |
| ["security", |
| ["chroot", "0"], |
| ], |
| ] + [ |
| ["mount", {type: "normal"}, |
| ["mount-name", m], |
| ["username", cfg.icecast.mounts[m].username], |
| ["password", cfg.icecast.mounts[m].password], |
| ["public", if cfg.icecast.mounts[m].public then "1" else "0"], |
| ["genre", cfg.icecast.mounts[m].genre], |
| ["bitrate", std.toString(cfg.icecast.mounts[m].bitrate)], |
| ["hidden", if cfg.icecast.mounts[m].hidden then "1" else "0"], |
| ] + (if cfg.icecast.mounts[m].fallbackMount != null then [ |
| ["fallback-mount", cfg.icecast.mounts[m].fallbackMount], |
| ["fallback-override", "1"], |
| ] else []) |
| for m in std.objectFields(cfg.icecast.mounts) |
| ] + [ |
| ["relay", |
| ["server", cfg.icecast.relays[r].server], |
| ["port", std.toString(cfg.icecast.relays[r].port)], |
| ["mount", cfg.icecast.relays[r].mount], |
| ["local-mount", r], |
| ["on-demand", "0"], |
| ] + (if cfg.icecast.relays[r].username != null then [ |
| ["username", cfg.icecast.relays[r].username] |
| ] else []) + (if cfg.icecast.relays[r].password != null then [ |
| ["password", cfg.icecast.relays[r].password], |
| ] else []) |
| for r in std.objectFields(cfg.icecast.relays) |
| ]), |
| }, |
| }, |
| |
| deployment: kube.Deployment(radio.makeName("icecast")) { |
| metadata+: radio.metadata, |
| spec+: { |
| replicas: 1, |
| template+: { |
| spec+: { |
| volumes_: { |
| config: kube.ConfigMapVolume(radio.configMap), |
| }, |
| containers_: { |
| radio: kube.Container(radio.makeName("radio")) { |
| image: cfg.image, |
| ports_: { |
| client: { containerPort: cfg.icecast.listenPort }, |
| }, |
| volumeMounts_: { |
| config: { mountPath: "/usr/share/icecast/icecast.xml", subPath: "icecast.xml" }, |
| }, |
| resources: cfg.resources, |
| }, |
| }, |
| }, |
| }, |
| }, |
| }, |
| svc: kube.Service(radio.makeName("icecast")) { |
| metadata+: radio.metadata, |
| target_pod:: radio.deployment.spec.template, |
| spec+: { |
| ports: [ |
| { name: "client", port: cfg.port, targetPort: cfg.icecast.listenPort, protocol: "TCP" }, |
| { name: "client80", port: 80, targetPort: cfg.icecast.listenPort, protocol: "TCP" }, |
| ], |
| type: "LoadBalancer", |
| }, |
| }, |
| } |