heat_template_version: 2015-10-15
description: >
  OpenStack compute node post deployment for Docker.

parameters:
  servers:
    type: json
  NodeConfigIdentifiers:
     type: json
     description: Value which changes if the node configuration may need to be re-applied
  DockerNamespace:
    type: string
    default: tripleoupstream
  DockerComputeImage:
    type: string
  DockerComputeDataImage:
    type: string
  DockerLibvirtImage:
    type: string
  DockerOpenvswitchImage:
    type: string
  DockerOvsVswitchdImage:
    type: string
  DockerOpenvswitchDBImage:
    type: string
  LibvirtConfig:
    type: string
    default: "/etc/libvirt/libvirtd.conf"
  NovaConfig:
    type: string
    default: "/etc/nova/nova.conf,/etc/nova/rootwrap.conf"
  NeutronOpenvswitchAgentConfig:
    type: string
    default: "/etc/neutron/neutron.conf,/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini"
  NeutronOpenvswitchAgentPluginVolume:
    type: string
    default: "/var/lib/etc-data/neutron/plugins/ml2/openvswitch_agent.ini:/var/lib/kolla/config_files/ovs_neutron_plugin.ini:ro"
  NeutronOpenvswitchAgentOvsVolume:
    type: string
    default: " "

resources:

  ComputePuppetConfig:
    type: OS::Heat::SoftwareConfig
    properties:
      group: puppet
      options:
        enable_hiera: True
        enable_facter: False
        tags: package,file,concat,file_line,nova_config,neutron_config,neutron_agent_ovs,neutron_plugin_ml2
      inputs:
      - name: tripleo::packages::enable_install
        type: Boolean
        default: True
      outputs:
      - name: result
      config:
        get_file: ../puppet/manifests/overcloud_compute.pp

  ComputePuppetDeployment:
    type: OS::Heat::SoftwareDeployments
    properties:
      name: ComputePuppetDeployment
      servers:  {get_param: servers}
      config: {get_resource: ComputePuppetConfig}
      input_values:
        update_identifier: {get_param: NodeConfigIdentifiers}
        tripleo::packages::enable_install: True

  CopyEtcConfig:
    type: OS::Heat::SoftwareConfig
    properties:
      group: script
      outputs:
      - name: result
      config: {get_file: ./copy-etc.sh}

  CopyEtcDeployment:
    type: OS::Heat::SoftwareDeployments
    depends_on: ComputePuppetDeployment
    properties:
      name: CopyEtcDeployment
      config: {get_resource: CopyEtcConfig}
      servers:  {get_param: servers}

  CopyJsonConfig:
    type: OS::Heat::SoftwareConfig
    properties:
      group: script
      inputs:
      - name: libvirt_config
      - name: nova_config
      - name: neutron_openvswitch_agent_config
      config: |
        #!/bin/python
        import json
        import os

        data = {}
        file_perms = '600'
        libvirt_perms = '644'

        libvirt_config = os.getenv('libvirt_config').split(',')
        nova_config = os.getenv('nova_config').split(',')
        neutron_openvswitch_agent_config = os.getenv('neutron_openvswitch_agent_config').split(',')

        # Command, Config_files, Owner, Perms
        services = {'nova-libvirt': ['/usr/sbin/libvirtd', libvirt_config, 'root', libvirt_perms],
                    'nova-compute': ['/usr/bin/nova-compute', nova_config, 'nova', file_perms],
                    'neutron-openvswitch-agent': ['/usr/bin/neutron-openvswitch-agent', neutron_openvswitch_agent_config, 'neutron', file_perms],
                    'ovs-vswitchd': ['/usr/sbin/ovs-vswitchd unix:/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --log-file=/var/log/openvswitch/ovs-vswitchd.log'],
                    'ovsdb-server': ['/usr/sbin/ovsdb-server /etc/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/run/openvswitch/db.sock --log-file=/var/log/openvswitch/ovsdb-server.log']
                   }


        def build_config_files(config, owner, perms):
            config_source = '/var/lib/kolla/config_files/'
            config_files_dict = {}
            source = os.path.basename(config)
            dest = config
            config_files_dict.update({'source': config_source + source,
                                      'dest': dest,
                                      'owner': owner,
                                      'perm': perms})
            return config_files_dict


        for service in services:
            if service != 'ovs-vswitchd' and service != 'ovsdb-server':
                command = services.get(service)[0]
                config_files = services.get(service)[1]
                owner = services.get(service)[2]
                perms = services.get(service)[3]
                config_files_list = []
                for config_file in config_files:
                    if service == 'nova-libvirt':
                        command = command + ' --config ' + config_file
                    else:
                        command = command + ' --config-file ' + config_file
                    data['command'] = command
                    config_files_dict = build_config_files(config_file, owner, perms)
                    config_files_list.append(config_files_dict)
                data['config_files'] = config_files_list
            else:
                data['command'] = services.get(service)[0]
                data['config_files'] = []

            json_config_dir = '/var/lib/etc-data/json-config/'
            with open(json_config_dir + service + '.json', 'w') as json_file:
                json.dump(data, json_file, sort_keys=True, indent=4, separators=(',', ': '))

  CopyJsonDeployment:
    type: OS::Heat::SoftwareDeployments
    depends_on: CopyEtcDeployment
    properties:
      name: CopyJsonDeployment
      config: {get_resource: CopyJsonConfig}
      servers:  {get_param: servers}
      input_values:
        libvirt_config: {get_param: LibvirtConfig}
        nova_config: {get_param: NovaConfig}
        neutron_openvswitch_agent_config: {get_param: NeutronOpenvswitchAgentConfig}

  NovaComputeContainersDeploymentOVS:
    type: OS::Heat::StructuredDeployments
    depends_on: CopyJsonDeployment
    properties:
      name: NovaComputeContainersDeploymentOVS
      config: {get_resource: NovaComputeContainersConfigOVS}
      servers: {get_param: servers}

  NovaComputeContainersConfigOVS:
    type: OS::Heat::StructuredConfig
    properties:
      group: docker-compose
      config:
        ovsvswitchd:
          image:
            list_join:
            - '/'
            - [ {get_param: DockerNamespace}, {get_param: DockerOvsVswitchdImage} ]
          net: host
          privileged: true
          restart: always
          volumes:
           - /run:/run
           - /lib/modules:/lib/modules:ro
           - /var/lib/etc-data/json-config/ovs-vswitchd.json:/var/lib/kolla/config_files/config.json
          environment:
           - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS

        openvswitchdb:
          image:
            list_join:
            - '/'
            - [ {get_param: DockerNamespace}, {get_param: DockerOpenvswitchDBImage} ]
          net: host
          restart: always
          volumes:
           - /run:/run
           - /var/lib/etc-data/json-config/ovsdb-server.json:/var/lib/kolla/config_files/config.json
          environment:
           - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS

  NovaComputeContainersDeploymentNetconfig:
    type: OS::Heat::SoftwareDeployments
    depends_on: NovaComputeContainersDeploymentOVS
    properties:
      name: NovaComputeContainersDeploymentNetconfig
      config: {get_resource: NovaComputeContainersConfigNetconfig}
      servers: {get_param: servers}

  # We run os-net-config here because we depend on the ovs containers to be up
  # and running before we configure the network.  This allows explicit timing
  # of the network configuration.
  NovaComputeContainersConfigNetconfig:
    type: OS::Heat::SoftwareConfig
    properties:
      group: script
      outputs:
      - name: result
      config: |
        #!/bin/bash
        /usr/local/bin/run-os-net-config

  LibvirtContainersDeployment:
    type: OS::Heat::StructuredDeployments
    depends_on: [CopyJsonDeployment, CopyEtcDeployment, ComputePuppetDeployment, NovaComputeContainersDeploymentNetconfig]
    properties:
      name: LibvirtContainersDeployment
      config: {get_resource: LibvirtContainersConfig}
      servers: {get_param: servers}

  LibvirtContainersConfig:
    type: OS::Heat::StructuredConfig
    properties:
      group: docker-compose
      config:
        computedata:
          image:
            list_join:
            - '/'
            - [ {get_param: DockerNamespace}, {get_param: DockerComputeDataImage} ]
          container_name: computedata
          volumes:
           - /var/lib/nova/instances
           - /var/lib/libvirt

        libvirt:
          image:
            list_join:
            - '/'
            - [ {get_param: DockerNamespace}, {get_param: DockerLibvirtImage} ]
          net: host
          pid: host
          privileged: true
          restart: always
          volumes:
           - /run:/run
           - /lib/modules:/lib/modules:ro
           - /dev:/dev
           - /lib/udev:/lib/udev
           - /sys/fs/cgroup:/sys/fs/cgroup
           - /var/lib/etc-data/json-config/nova-libvirt.json:/var/lib/kolla/config_files/config.json
           - /var/lib/etc-data/libvirt/libvirtd.conf:/var/lib/kolla/config_files/libvirtd.conf
          environment:
           - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS
          volumes_from:
           - computedata

  NovaComputeContainersDeployment:
    type: OS::Heat::StructuredDeployments
    depends_on: [CopyJsonDeployment, CopyEtcDeployment, ComputePuppetDeployment, NovaComputeContainersDeploymentNetconfig, LibvirtContainersDeployment]
    properties:
      name: NovaComputeContainersDeployment
      config: {get_resource: NovaComputeContainersConfig}
      servers: {get_param: servers}

  NovaComputeContainersConfig:
    type: OS::Heat::StructuredConfig
    properties:
      group: docker-compose
      config:
        neutronovsagent:
          image:
            list_join:
            - '/'
            - [ {get_param: DockerNamespace}, {get_param: DockerOpenvswitchImage} ]
          net: host
          pid: host
          privileged: true
          restart: always
          volumes:
            str_split:
              - ","
              - list_join:
                 - ","
                 - [ "/run:/run", "/lib/modules:/lib/modules:ro",
                     "/var/lib/etc-data/json-config/neutron-openvswitch-agent.json:/var/lib/kolla/config_files/config.json",
                     "/var/lib/etc-data/neutron/neutron.conf:/var/lib/kolla/config_files/neutron.conf:ro",
                     "/var/lib/etc-data/neutron/plugins/ml2/ml2_conf.ini:/var/lib/kolla/config_files/ml2_conf.ini:ro",
                     {get_param: NeutronOpenvswitchAgentPluginVolume},
                     {get_param: NeutronOpenvswitchAgentOvsVolume} ]
          environment:
           - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS
          volumes_from:
           - computedata

        novacompute:
          image:
            list_join:
            - '/'
            - [ {get_param: DockerNamespace}, {get_param: DockerComputeImage} ]
          net: host
          privileged: true
          restart: always
          volumes:
           - /run:/run
           - /lib/modules:/lib/modules:ro
           - /dev:/dev
           - /lib/udev:/lib/udev
           - /etc/iscsi:/etc/iscsi
           - /var/lib/etc-data/json-config/nova-compute.json:/var/lib/kolla/config_files/config.json
           - /var/lib/etc-data/nova/nova.conf:/var/lib/kolla/config_files/nova.conf:ro
           - /var/lib/etc-data/nova/rootwrap.conf:/var/lib/kolla/config_files/rootwrap.conf:ro
          environment:
           - KOLLA_CONFIG_STRATEGY=COPY_ALWAYS
          volumes_from:
           - computedata

  ExtraConfig:
    depends_on: NovaComputeContainersDeployment
    type: OS::TripleO::NodeExtraConfigPost
    properties:
        servers: {get_param: servers}