README.md
# chef_eye cookbook
Cookbook for setup [eye](https://github.com/kostya/eye) services and applications
[![Code Climate](https://codeclimate.com/github/MurgaNikolay/chef-eye/badges/gpa.svg)](https://codeclimate.com/github/MurgaNikolay/chef-eye)
[![Build Status](https://travis-ci.org/MurgaNikolay/chef-eye.svg?branch=master)](https://travis-ci.org/MurgaNikolay/chef-eye)
### Related projects
[Capistrano chef eye](https://github.com/MurgaNikolay/capistrano-chef-eye) cookbook companion for Capistrano.
## Supported Platforms
* Ubuntu 12.04
* Ubuntu 14.04
## Attributes
| Key | Type | Description | Default |
|-----|------|-------------|---------|
| chef_eye.eye_bin | String | Path to eye executable file | /usr/local/bin/eye |
| chef_eye.leye_bin | String | Path to local eye executable file | /usr/local/bin/leye |
| chef_eye.services | Hash or Array | Array of users or Hash with users as keys and service options as value | ['root'] |
| chef_eye.service_provider | String | `'upstart'` or `'init'` | `'upstart'`|
| chef_eye.applications | Hash | Applications configurations | {} |
| chef_eye.install_ruby | Boolean | Try to install ruby packages `ruby`, `ruby-dev`. If you want to install ruby using another way, you should set this value to `false` | true |
## Usage
This cookbook provides two strategies of usage `eye`. "Eye" per user and "eye" per project (local eye).
First strategy run one eye daemon for all configurations and load it.
Eye per user file structure (for user vagrant):
/etc/init/eye_vagrant.conf # Eye service for user vagrant (generated by chef_eye::service recipe)
/etc/eye/config.eye # Main eye file. This file contains eye service settings and load config files from /etc/eye/vagrant/*.eye
/etc/eye/vagrant/application1.eye # Application config (generated by chef_eye_application lwrp)
/etc/eye/vagrant/application2.eye
/etc/eye/vagrant/*.eye
Eye per project (local eye) file structure (generated by provider `Chef::Provider::ChefEyeApplicationLocal` ):
/etc/init/leye_application.conf
/var/www/application/shared # Eye home
/var/www/application/shared/Eyefile # Local eye service configuration and loader for application config
/var/www/application/shared/.eye/sock
/var/www/application/shared/.eye/pid
/var/www/application/shared/config/application.eye # Configuration file for application. Default path <eye_home>/config/<application_name>.eye
## Recipes
### chef_eye::default
Include `chef_eye` in your node's `run_list`:
```json
{
"run_list": [
"recipe[chef_eye::default]"
]
}
```
### chef_eye::ruby
Cookbook used system ruby and try to install `ruby`, `ruby-dev` packages if `node['chef_eye']['install_ruby']` set to `true`
If you want to use custom system ruby, you need set `node['chef_eye']['install_ruby']` to `false` and install custom ruby before
before this cookbook. For example, if you want to use `uid` and `gid` [application options](https://github.com/kostya/eye/issues/50),
you need install ruby 2.0.0 as system ruby. Its installation is your concern.
## chef_eye::service
This recipe configure `chef_eye_service` for using with per user strategy
By default service named by `eye_<username>`. For example, service for user vagrant, will be named as `eye_vagrant`, service for user root as `eye_root`, etc.
If you need to reload service for user `vagrant`, you can use
```ruby
some_resource do
...
notifies :reload, 'chef_eye_service[eye_vagrant]'
end
```
If you want to change configuration for service for `ubuntu`:
```ruby
default['chef_eye']['services'] = {
ubuntu: {
'logger' => '/var/log/eye/ubuntu.log'
'mail' => {
'host' => 'mx.some.host',
'port' => 25,
'domain' => 'some.host'
},
contacts: {
'errors' => {
'type' => 'mail',
'contact' => 'error@some.host'
},
'dev' => {
'type' => 'mail',
'contact' => 'error@some.host',
'opts' => {}
},
}
}
}
```
### chef_eye::applications
This service generate `chef_eye_application` LWRP's using `node['chef_eye']['applications']` attributes.
For example:
```ruby
default['chef_eye']['applications']['my_app'] = {
type: 'local',
owner: 'vagrant', # required
group: 'vagrant',
config_dir: '/var/www/rails_sample/shared/config',
# for local version
eye_file: 'Eyefile',
eye_home: '/var/www/rails_sample/shared',
eye_config: {
logger: '/var/www/rails_sample/shared/log/eye.log'
},
service_provider: 'upstart',
#application config
config: {
working_dir: '/var/www/rails_sample/current',
checks: {
cpu: {
:every => 30,
:below => 80,
:times => 3
},
memory:{
:every => 30,
:below => 73400320,
:times => [ 3, 5 ]
}
},
process: {
unicorn: {
daemonize: true,
pid_file: 'puma.pid',
stdall: 'puma.log',
start_command: 'bundle exec unicorn --port 33280 --environment production Config.ru',
stop_signals: ['TERM', 5, 'KILL']
},
resque: {
pid_file: 'tmp/pids/resque.pid',
start_command: 'bin/resque work --queue=high',
checks: {
cpu: {
:every => 30,
:below => 80,
:times => 3
}
}
}
}
}
}
```
## LWRPs
### chef_eye_service
#### Attributes
| Name | Type | Description | Default Value |
|-------------|--------|--------------|----------------|
| service_name | String | Name of the system service and system configuration file (/etc/init/<service_name>.conf). | This is a name_attribute |
| type | String | Type need for set execution file `eye` or `leye`. Can be 'local' or 'user' | `'user'` |
| service_provider | String | `upstart` or `init` | `'upstart'` |
| owner | String | Owner of service | `'root'` |
| group |String | Group of service | `'root'` |
| cookbook | Symbol, String, NilClass | Cookbook name for searching templates | `nil` |
| eye_home | String, NilClass | Home directory for eye process. Used only for 'local' service type | `nil` |
| eye_file | String, NilClass | Main configuration file for loading by service. For `local` service this is `Eyefile` name, for `user` '/etc/<username>.eye'. This file must be generated by another LWRP. | `nil` |
#### Actions
| Name | Description | |
|---------------|--------------|--------------|
| :nothing | | default |
| :start | Start eye service | |
| :stop | Stop eye service | |
| :restart | Restart eye service | |
| :stop_all | Send start to all loaded applications | |
| :start_all | Send stop to all loaded applications | |
| :restart_all | Send restart to all loaded applications | |
### chef_eye_application
This is a main LWRP for configure eye application.
You can use any valid eye [options](https://github.com/kostya/eye/tree/master/examples) for config attribute.
#### Attributes:
| Name | Type | Description | Default Value |
|-------------|--------|--------------|----------------|
| owner | String | Owner fo application | `'root'` |
| group | String | Owner fo application | `'root'` |
| cookbook | String | Cookbook name for searching templates | `'chef_eye'` |
| config | Hash or Block | Application configuration | `{}` |
| config_dir | String, NilClass | Application configuration | nil (set dynamic: <eye_home>/config for `local`, /etc/eye/<user_name>/ for `user` strategies) |
| service_provider | string | Application configuration | node['chef_eye']['service_type'] |
| eye_home | String, NillClass | Home for `.eye` directory, used only for `local` strategy. If empty, provider try to resolve eye_home path by `eye_file`. If eye_file is relative path, and eye_home empty, provider raise exception. | |
| eye_file | String | Application service configuration file name (relative of eye_home) or absolute path, used only for `local` strategy | `'Eyefile'` |
| eye_config | Hash or Block | Application Service configuration, used only for `local` strategy | `{}` |
#### Providers
| Provider Name | Description |
|---------------|---------------------|
| Chef::Provider::ChefEyeApplication | Default provider. This provider implement `user` application strategy |
| Chef::Provider::ChefEyeApplicationLocal | Default provider. This provider implement `local` application strategy |
Cookbook provide `chef_eye_application` resource. This is a main resource for generate eye application configuration.
```ruby
chef_eye_application 'name_of_my_app' do
owner 'ubuntu'
group 'ubuntu'
working_dir '/var/www/rails_sample'
config do
env 'RAILS_ENV' => 'production'
working_dir '/var/www/my_app'
trigger :flapping, :times => 10, :within => 1.minute
process :puma do
daemonize true
pid_file "puma.pid"
stdall "puma.log"
start_command "bundle exec puma --port 33280 --environment production thin.ru"
stop_signals [:TERM, 5.seconds, :KILL]
restart_command "kill -USR2 {PID}"
restart_grace 10.seconds
check :cpu, :every => 30, :below => 80, :times => 3
check :memory, :every => 30, :below => 70.megabytes, :times => [3,5]
end
end
action :configure # or :delete
notifies :reload, 'chef_eye_service[eye_ubuntu]' # you need notify service for reload
end
```
Or as hash
```ruby
chef_eye_application 'name_of_my_app' do
owner 'ubuntu'
group 'ubuntu'
config({
env: {
RAILS_ENV: 'production'
},
working_dir: '/var/www/my_app',
triggers: {
flapping: {
:times => 10,
:within => 1.minute
}
},
processes: {
puma: {
daemonize: true,
pid_file: "puma.pid",
stdall: "puma.log",
start_command: "bundle exec puma --port 33280 --environment production thin.ru",
stop_signals: [:TERM, 5.seconds, :KILL],
restart_command: "kill -USR2 {PID}",
restart_grace: 10.seconds,
checks: {
cpu: {:every => 30, :below => 80, :times => 3},
memory: {:every => 30, :below => 70.megabytes, :times => [3, 5]}
}
}
}
})
action :configure # or :delete
notifies :reload, 'chef_eye_service[eye_ubuntu]' # you need notify service for reload
end
```
## TODO
* Add unit tests
* Add integration tests
## License and Authors
Author:: Nikolay Murga (nikolay.m@randrmusic.com)