apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: ${ cr.metadata.namespace.asString }
  name: ${ cr.metadata.name.asString }
  labels:
    app.kubernetes.io/name: ${ constants.APP_NAME }
    app.kubernetes.io/instance: ${ cr.metadata.name.asString }
    app.kubernetes.io/managed-by: ${ constants.VM_OP_NAME }
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ${ constants.APP_NAME }
      app.kubernetes.io/instance: ${ cr.metadata.name.asString }
  replicas: ${ (cr.spec.vm.state.asString == "Running")?then(1, 0) }
  template:
    metadata:
      namespace: ${ cr.metadata.namespace.asString }
      name: ${ cr.metadata.name.asString }
      labels:
        app.kubernetes.io/name: ${ constants.APP_NAME }
        app.kubernetes.io/instance: ${ cr.metadata.name.asString }
        app.kubernetes.io/managed-by: ${ constants.VM_OP_NAME }
      annotations:
        # Triggers update of config map mounted in pod
        # See https://ahmet.im/blog/kubernetes-secret-volumes-delay/
        vmrunner.jdrupes.org/cmVersion: "${ cm.metadata.resourceVersion.asString }"
    spec:
      containers:
      - name: ${ cr.metadata.name.asString }
        <#assign image = cr.spec.image>
        image: ${ image.repository.asString }/${ image.path.asString }:${ image.version.asString }
        resources: {}
        imagePullPolicy: ${ image.pullPolicy.asString }
        volumeMounts:
        # Not needed because pod is priviledged:
        # - mountPath: /dev/kvm
        #   name: dev-kvm
        # - mountPath: /dev/net/tun
        #   name: dev-tun
        # - mountPath: /sys/fs/cgroup
        #   name: cgroup
        - name: config
          mountPath: /etc/opt/vmrunner
        - name: runner-data
          mountPath: /var/local/vm-data
        - name: vmop-image-repository
          mountPath: ${ constants.IMAGE_REPO_PATH }
        volumeDevices:
        <#assign diskCounter = 0/>
        <#list cr.spec.vm.disks.asList() as disk>
        <#if disk.volumeClaimTemplate??>
        <#if disk.volumeClaimTemplate.metadata??
          && disk.volumeClaimTemplate.metadata.name??>
          <#assign diskName = disk.volumeClaimTemplate.metadata.name.asString + "-disk">
        <#else>
          <#assign diskName = "disk-" + diskCounter>
        </#if>
        - name: ${ diskName }
          devicePath: /dev/${ diskName }
        <#assign diskCounter = diskCounter + 1/>
        </#if>
        </#list>
        securityContext:
          privileged: true
      volumes:
      # Not needed because pod is priviledged:
      # - name: dev-kvm
      #   hostPath:
      #     path: /dev/kvm
      #     type: CharDevice
      # - hostPath:
      #     path: /dev/net/tun
      #     type: CharDevice
      #   name: dev-tun
      # - name: cgroup
      #   hostPath:
      #     path: /sys/fs/cgroup
      - name: config
        configMap:
          name: ${ cr.metadata.name.asString }
      - name: vmop-image-repository
        persistentVolumeClaim:
          claimName: vmop-image-repository
      hostNetwork: true
      terminationGracePeriodSeconds: ${ (cr.spec.vm.powerdownTimeout.asInt + 5)?c }
  volumeClaimTemplates:
  - metadata:
      namespace: ${ cr.metadata.namespace.asString }
      name: runner-data
      labels:
        app.kubernetes.io/name: ${ constants.APP_NAME }
        app.kubernetes.io/instance: ${ cr.metadata.name.asString }
        app.kubernetes.io/managed-by: ${ constants.VM_OP_NAME }
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Mi
  <#assign diskCounter = 0/>
  <#list cr.spec.vm.disks.asList() as disk>
  <#if disk.volumeClaimTemplate??>
  <#if disk.volumeClaimTemplate.metadata??
    && disk.volumeClaimTemplate.metadata.name??>
    <#assign diskName = disk.volumeClaimTemplate.metadata.name.asString + "-disk">
  <#else>
    <#assign diskName = "disk-" + diskCounter>
  </#if>
  - metadata:
      namespace: ${ cr.metadata.namespace.asString }
      name: ${ diskName }
      labels:
        app.kubernetes.io/name: ${ constants.APP_NAME }
        app.kubernetes.io/instance: ${ cr.metadata.name.asString }
        app.kubernetes.io/managed-by: ${ constants.VM_OP_NAME }
      <#if disk.volumeClaimTemplate.metadata??
        && disk.volumeClaimTemplate.metadata.annotations??>
      annotations:
        ${ disk.volumeClaimTemplate.metadata.annotations.toString() }
      </#if>
    spec:
      ${ disk.volumeClaimTemplate.spec.toString() }
  <#assign diskCounter = diskCounter + 1/>
  </#if>
  </#list>
