saltstack / kitchen-salt

SaltStack provisioner for test-kitchen
MIT License
199 stars 111 forks source link

have salt states be in another location than current directory #92

Open ecks opened 7 years ago

ecks commented 7 years ago

I was not able to figure out a way to have the salt states be in a directory other than the current one where .kitchen.yaml is defined. For instance we have some_path/tests/kitchen_tests, where I would like to keep the yaml file. Then the actual salt state I want to use is in some_path/other_path/services/my_state_dir. It looks like the only way to get kitchen-salt to find the my_state_dir is if you put .kitchen.yaml inside the services dir.

It would be nice to have this functionality if it is not already there.

ek9 commented 7 years ago

I think this is similar to #83 . Can you please share your .kitchen.yml?

ecks commented 7 years ago

yea, essentially what I did was create a symbolic link to services dir in the current kitchen dir

---
driver:
  name: vagrant

platforms:
  - name: centos-7.3

provisioner:
  name: salt_solo
  salt_file_root: "/home/ecks/my_app/tests/kitchen_test/services"
  is_file_root: false
  require_chef: false
  state_top:
    base:
      '*':
        - users
        - my_state

suites:
  - name: server

verifier:
  name: shell
  command: testinfra ../infra_test/integration/$KITCHEN_SUITE

I quickly realized that salt_file_root refers to the root on the minion in vagrant, not on the host application. So I was trying different provisioner options but none of them worked. So now I have the following config inside services dir:

driver:
  name: vagrant

platforms:
  - name: centos-7.3

provisioner:
  name: salt_solo
  require_chef: false
  is_file_root: true
  state_top:
    base:
      '*':
        - users
        - my_app

suites:
  - name: server

verifier:
  name: shell
  command: testinfra infra_test/integration/$KITCHEN_SUITE

This works but is unfortunately undesired because we want to keep the testing code separate from the production code, ie the salt states.

ek9 commented 7 years ago

Thank you for the configuration. Could you give the directory tree information for your project (run tree path_to_formula) so I can understand the file-structure better?

Also, just a quick thought, would setting custom file_roots in minion's config would help? There's a PR for this that hasn't been merged yet.

ecks commented 7 years ago
❯❯❯ tree kitchen_test                                                  
kitchen_test
├── Gemfile
├── services -> ../../app/com/site/pivot/salt/salt/saltmaster/default/services
└── test
    ├── fixtures
    │   └── my_app.sls
    └── integration
        └── server
            └── testinfra
                └── test_my_app_server.py

Ideally I would not want to have that symbolic link there. This current setup does not work. I need to go right into the services dir and have that as my current working directory.

I believe if that PR is merged I can set file_roots to be /tmp/kitchen/srv/salt/services and it would work with that setup. What I would really would like to do is remove that symbolic link and just tell kitchen to copy all files from ../../app/com/site/pivot/salt/salt/saltmaster/default/services to the minion rather than start from the current dir. That way I wouldn't have to touch the minion config. Please lmk how difficult that would be to implement or whether there is another better solution.

daks commented 7 years ago

In fact, I think we have a similar need. Mine is to have a file structure like this for my formula.

.
├── pillar.example
├── README.rst
├── test
│   ├── integration
│   │   └── default
│   │       ├── controls
│   │       │   ├── groups.rb
│   │       │   └── users.rb
│   │       └── inspec.yml
│   └── salt
│       └── default
│           ├── pillar
│           │   ├──  top.sls
│           │   └── usersandgroups.sls
│           └── states
│               ├── top.sls
│               └── users.sls
└── usersandgroups
    ├── files
    ├── init.sls
    └── map.jinja

It let testing code separated from production code.

ek9 commented 7 years ago

Thanks for extensive explanations. I understand the workflow, however I personally think this isn't a way to keep testing code separate from production code. I would view a git repository as part of development, thus the integration as such is done on the repository wise.

If you would use a proper distribution method (e.g. SPM), you could have .gitattributes file and specify the tests (and other non-production) directories to be excluded in the SPM builds. That way, you can package your production code appropriately. I would say cloning a development build on production is the real problem here :)

Still, I think a PR for this would be welcome and a nice addition so we can cover more use-cases.

ek9 commented 7 years ago

Linking #76 and #83 as all of these issues basically request same feature and I believe this one contains the most detailed information to issue a PR against.

daks commented 7 years ago

For me, it's not a distribution problem, it's just a clarity one: to keep "real"/production/runtime code separated from testing one. And maybe also a question of coherence, because in most (if not all) testing frameworks, you can keep your test code separated from the "real" code.

ek9 commented 7 years ago

@daks looking by your example, I see you would just like to have a separate tests folder, so your use case is rather standard practice that should definitely be supported by this formula. For the time being until we get a PR, you can accomplish this by defining states / pillars in the .kitchen.yml file directly.

daks commented 7 years ago

@ek9 I agree with that, I want to have tests in the same repository as code, but I want to separate them in different directories.

gtmanfred commented 7 years ago

Looks like there is an undocumented option, local_salt_root If you set this as a different directory besides the root directory, that should just sync those files to the sandbox.

Can you test that and let me know if solves this issue?

Thanks, Daniel

daks commented 6 years ago

I tried to use this undocumented option, removing all previous use of pillars/state_top/pillars-from-files. My kitchen.yml looks like

driver:
  name: vagrant
  provision: false

provisioner:
  name: salt_solo
  formula: haproxy
  salt_install: bootstrap
  require_chef: false
  local_salt_root: test/salt/default

and directory is

tree test/salt/default/
test/salt/default/
├── pillar
│   ├── hosts.sls
│   └── top.sls
└── salt
    ├── hosts.sls
    └── top.sls

When I login to the Kitchen VM, pillar seems ok but not states

# tree /tmp/kitchen/srv/
/tmp/kitchen/srv/
|-- pillar
|   |-- hosts.sls
|   `-- top.sls
`-- salt
    |-- haproxy
    |   |-- hosts.sls
    |   `-- top.sls
    `-- top.sls

# cat pillar/top.sls
base:
  '*':
    - hosts

# cat salt/top.sls
--- {}

I'm not sure if I need to use this option with other ones, I'll try some.

[update] seems my original salt/ directory became salt/haproxy one. This option works for pillar files but not for states.

Moreover I'm not the sure it's the solution to my problem because I don't find my original formula directory.

anuriq commented 6 years ago

Hi @gtmanfred I think, there is a documentation problem here. After reading this https://github.com/saltstack/kitchen-salt/blob/master/docs/provisioner_options.md#state_top_from_file it feels like i can provide a path to a file and it will be used as top.sls, but in reality (after looking into code) this is just a trigger true/false.

gtmanfred commented 6 years ago

@anuriq that does not appear to be related to this issue, can you open a new issue?

Thanks, Daniel