Search code examples
salt-projectpacker

How to use Packer Salt provisioner to create docker images?


How to use Packer Salt provisioner to create docker images ?

here is my packer.json file. I will comment inline below

{
  "builders": [
    {
      "type": "docker",
      "image": "enonic/docker-salt-masterless-ubuntu",
      "export_path": "cassandra.tar" // Not sure what this is doing?
    }
  ],
  "provisioners": [
    {
      "type": "file",
      "source": "/srv/salt/cassandra", // This is where the cassandra directory is on my host machine which is ubuntu
      "destination": "/srv/salt/cassandra" // This is where I expect the cassandra directory on my host machine gets copied to inside a docker container
    },
    {
      "type": "salt-masterless",
      "local_state_tree": "/srv/salt/cassandra",
      "custom_state": "/srv/salt/cassandra/init.sls",
      "disable_sudo": true
    }
  ]
}

sudo docker build packer.json

I get the following error

Build 'docker' errored: Failed to upload to '/srv/salt/cassandra' in container: Error response from daemon: lstat /var/lib/docker/aufs/mnt/0c6a422400a073624a66b00580a6b9e5551e82a06495c46b1f840b38ca55699d/srv/salt: no such file or directory
. exit status 1.

==> Some builds didn't complete successfully and had errors:
--> docker: Failed to upload to '/srv/salt/cassandra' in container: Error response from daemon: lstat /var/lib/docker/aufs/mnt/0c6a422400a073624a66b00580a6b9e5551e82a06495c46b1f840b38ca55699d/srv/salt: no such file or directory

It would be great if I can get a simple working example on how to use salt state files from host machine and build a docker image using packer. My cassandra state files are same as https://github.com/salt-formulas/salt-formula-cassandra

My top.sls file looks like this

base:
  'client*-es-*':
    - roles-elasticsearch
  'client*-cassandra-*':
    - roles-cassandra


  'P@os:(Debian|Ubuntu) and P@roles:(elasticsearch|cassandra)':
    - match: compound
    - deb-common

  'roles:elasticsearch':
    - match: grain
    - disk-raid0-3volumes
    - disk-elasticsearch
    - elasticsearch
    - elasticsearch.cerebro
  'roles:cassandra':
    - match: grain
    - disk-raid0-3volumes
    - disk-cassandra
    - cassandra

I just want to build a docker container image only for cassandra but not for everything in my top.sls. so how do I do that?


Solution

  • I adjusted your example to be simpler and just install Apache 2.

    The shell provisioner is just because I don't know salt and din't spend any time on howto do apt-get update.

    First of all the base image already have salt installed so use skip_bootstrap. You shouldn't upload the state directory to the guest (Docker container) since this is done automatically, all this is in the documentation Packer - Salt Masterless. local_state_tree should point at the base of your salt state tree i.g. /srv/salt in you case.

    A working example:

    Tree

    .
    ├── salt
    │   ├── apache
    │   │   └── init.sls
    │   └── top.sls
    └── template.json
    

    Template.json

    {
      "builders": [
        {
          "type": "docker",
          "image": "enonic/docker-salt-masterless-ubuntu",
          "export_path": "apache2.tar"
        }
      ],
      "provisioners": [
        {
          "type": "shell",
          "inline": [
            "apt-get update"
          ]
        },
        {
          "type": "salt-masterless",
          "local_state_tree": "salt",
          "skip_bootstrap": true,
          "disable_sudo": true
        }
      ]
    }
    

    top.sls

    base:
      '*':
        - apache
    

    apache/init.sls

    apache2:
      pkg.installed: []
      service.running:
        - require:
          - pkg: apache2