2
0
mirror of https://github.com/frappe/bench.git synced 2024-11-13 16:56:33 +00:00

Add vm builder

This commit is contained in:
Pratik Vyas 2015-12-23 16:25:55 -08:00
parent 6ac1c0db41
commit 344183d2b9
48 changed files with 1283 additions and 0 deletions

10
vm/Readme.md Normal file
View File

@ -0,0 +1,10 @@
# ERPNext VM Builder
`./packer build vm.json` builds a new vm.
It uses packer (binary for x86_64 put here till https://github.com/mitchellh/packer/issues/2391 is resolved).
Ansible
=======

104
vm/ansible/base.yml Normal file
View File

@ -0,0 +1,104 @@
---
- name: Apply basic roles
hosts: all
become: yes
become_user: root
vars:
- mysql_secure_installation: True
- mysql_conf_tpl: templates/mariadb_config.cnf
- nginx_conf_file: templates/nginx.conf
roles:
- mariadb
- nginx
- wkhtmltopdf
tasks:
- name: Install the 'Development tools' package group (Redhat)
yum: name="@Development tools" state=present
when: ansible_os_family == 'RedHat'
- name: Install packages
yum: name={{ item }} state=present
with_items:
- git
- nginx
- zlib-devel
- bzip2-devel
- openssl-devel
- postfix
- python-devel
- mariadb
- redis
- libXrender
- libXext
- cronie
- sudo
- which
- xorg-x11-fonts-75dpi
- xorg-x11-fonts-Type1
- screen
- vim
- git
- nginx
- zlib-devel
- bzip2-devel
- openssl-devel
- postfix
- python-devel
- redis
- cronie
- sudo
- which
- supervisor
- nodejs
- npm
- libtiff-devel
- libjpeg-devel
- libzip-devel
- freetype-devel
- lcms2-devel
- libwebp-devel
- tcl-devel
- tk-devel
when: ansible_os_family == 'RedHat'
- name: Install packages
apt: pkg={{ item }} state=present
with_items:
- python-dev
- python-setuptools
- build-essential
- python-mysqldb
- git
- ntp
- vim
- screen
- htop
- mariadb-server
- mariadb-common
- libmariadbclient-dev
- libxslt1.1
- libxslt1-dev
- redis-server
- libssl-dev
- libcrypto++-dev
- postfix
- nginx
- supervisor
- python-pip
- fontconfig
- libxrender1
- libxext6
- xfonts-75dpi
- xfonts-base
- nodejs
- npm
- libtiff5-dev
- libjpeg8-dev
- zlib1g-dev
- libfreetype6-dev
- liblcms2-dev
- libwebp-dev
- tcl8.6-dev
- tk8.6-dev
- python-tk
when: ansible_os_family == 'Debian'
- user: name="{{ frappe_user }}"

View File

@ -0,0 +1,84 @@
#!/usr/bin/python
import os
import subprocess
import json
def init_bench(path, frappe_branch):
if not frappe_branch:
frappe_branch = 'master'
subprocess.check_call("bench init {} --frappe-branch {}".format(path, frappe_branch), shell=True)
def check_if_app_exists(app, bench_path):
return os.path.exists(os.path.join(bench_path, 'apps', app))
def check_if_site_exists(site, bench_path):
return os.path.exists(os.path.join(bench_path, 'sites', site))
def get_app(app, url, branch, bench_path):
subprocess.check_call("bench get-app {} {} --branch {}".format(app, url, branch), cwd=bench_path, shell=True)
def install_site(site, mariadb_root_password, bench_path):
admin_password = site.get('admin_password')
site_name = site['name']
subprocess.check_call("bench new-site {} --mariadb-root-password {} --admin-password {}".format(site_name, mariadb_root_password, admin_password), cwd=bench_path, shell=True)
for app in site['apps']:
subprocess.check_call("bench --site {} install-app {}".format(site['name'], app), cwd=bench_path, shell=True)
site_config_path = os.path.join(bench_path, 'sites', site_name, 'site_config.json')
with open(site_config_path) as f:
site_config = json.load(f)
site_config.update(site.get('site_config', {}))
with open(site_config_path, 'wb') as f:
json.dump(site_config, f)
def main():
module = AnsibleModule(
argument_spec=dict(
path=dict(required=True),
apps=dict(required=True),
sites=dict(required=True),
mariadb_root_password=dict(),
frappe_branch=dict(),
),
supports_check_mode=True
)
changed = False
bench_path = module.params['path']
if not os.path.exists(bench_path):
if module.check_mode:
module.exit_json(changed=True)
init_bench(bench_path, module.params['frappe_branch'])
changed = True
for app in module.params['apps']:
if not check_if_app_exists(app['name'], bench_path):
if module.check_mode:
module.exit_json(changed=True)
get_app(app['name'], app['url'], app.get('branch', 'master'), bench_path)
changed = True
for site in module.params['sites']:
if not check_if_site_exists(site['name'], bench_path):
if module.check_mode:
module.exit_json(changed=True)
mariadb_root_password = module.params.get('mariadb_root_password')
if not mariadb_root_password:
module.fail_json(msg="MariaDB root password not passed")
if not site.get('admin_password'):
module.fail_json(msg="Admin password not passed for {}".format(site['name']))
install_site(site, mariadb_root_password, bench_path)
changed = True
module.exit_json(changed=changed)
from ansible.module_utils.basic import *
main()

160
vm/ansible/playbook.yml Normal file
View File

@ -0,0 +1,160 @@
---
- name: Apply basic roles
hosts: all
become: yes
become_user: root
vars:
- mysql_secure_installation: True
- mysql_conf_tpl: templates/mariadb_config.cnf
- nginx_conf_file: templates/nginx.conf
vars_files:
- vars.yml
roles:
- mariadb
- nginx
- wkhtmltopdf
tasks:
- name: Install the 'Development tools' package group (Redhat)
yum: name="@Development tools" state=present
when: ansible_os_family == 'RedHat'
- name: Install packages
yum: name={{ item }} state=present
with_items:
- git
- nginx
- zlib-devel
- bzip2-devel
- openssl-devel
- postfix
- python-devel
- mariadb
- redis
- libXrender
- libXext
- cronie
- sudo
- which
- xorg-x11-fonts-75dpi
- xorg-x11-fonts-Type1
- screen
- vim
- git
- nginx
- zlib-devel
- bzip2-devel
- openssl-devel
- postfix
- python-devel
- redis
- cronie
- sudo
- which
- supervisor
- nodejs
- npm
- libtiff-devel
- libjpeg-devel
- libzip-devel
- freetype-devel
- lcms2-devel
- libwebp-devel
- tcl-devel
- tk-devel
when: ansible_os_family == 'RedHat'
- name: Install packages
apt: pkg={{ item }} state=present
with_items:
- python-dev
- python-setuptools
- build-essential
- python-mysqldb
- git
- ntp
- vim
- screen
- htop
- mariadb-server
- mariadb-common
- libmariadbclient-dev
- libxslt1.1
- libxslt1-dev
- redis-server
- libssl-dev
- libcrypto++-dev
- postfix
- nginx
- supervisor
- python-pip
- fontconfig
- libxrender1
- libxext6
- xfonts-75dpi
- xfonts-base
- nodejs
- npm
- libtiff5-dev
- libjpeg8-dev
- zlib1g-dev
- libfreetype6-dev
- liblcms2-dev
- libwebp-dev
- tcl8.6-dev
- tk8.6-dev
- python-tk
when: ansible_os_family == 'Debian'
- user: name=frappe
tags:
- base_packages
- name: Clone bench
hosts: all
user: frappe
tasks:
- git:
repo=https://github.com/frappe/bench
dest=/home/frappe/bench-repo
tags:
- bench_install
- name: Install bench
hosts: all
become: yes
become_user: root
tasks:
- easy_install: name=pip executable=easy_install-2.7
- pip: name=/home/frappe/bench-repo extra_args='-e'
tags:
- bench_install
- name: Setup bench
hosts: all
become: yes
become_user: frappe
become_method: sudo
gather_facts: false
vars_files:
- vars.yml
tasks:
- bench:
path: /home/frappe/frappe-bench
frappe_branch: develop
apps:
- name: erpnext
url: https://github.com/frappe/erpnext
- name: erpnext_demo
url: https://github.com/frappe/erpnext_demo
mariadb_root_password: "{{ mysql_root_password }}"
sites:
- name: erpnext.vm
admin_password: {{ admin_password or 'admin' }}
apps:
- erpnext
tags:
- bench_setup

View File

@ -0,0 +1,64 @@
# Ansible Role: MariaDB
Installs MariaDB
## Supported platforms
```
CentOS 6 & 7
Ubuntu 14.04
```
## Post install
Run `mysql_secure_installation`
## Requirements
None
## Role Variables
MariaDB version:
```
mariadb_version: 10.0
```
Configuration template:
```
mysql_conf_tpl: change_me
```
Configuration filename:
```
mysql_conf_file: settings.cnf
```
### Experimental unattended mysql_secure_installation
```
ansible-playbook release.yml --extra-vars "mysql_secure_installation=true mysql_root_password=your_very_secret_password"
```
## Dependencies
None
## Example Playbook
```
- hosts: servers
roles:
- { role: pcextreme.mariadb }
```
## License
MIT / BSD
## Author Information
Created by [Attila van der Velde](https://github.com/vdvm)

View File

@ -0,0 +1,7 @@
---
mariadb_version: 10.0
mysql_conf_tpl: change_me
mysql_conf_file: settings.cnf
mysql_secure_installation: false

View File

@ -0,0 +1,3 @@
---
- name: restart mysql
service: name=mysql state=restarted

View File

@ -0,0 +1,19 @@
---
galaxy_info:
author: "Attila van der Velde"
description: "Installs MariaDB"
company: "PCextreme B.V."
license: "license (MIT, BSD)"
min_ansible_version: 1.8
platforms:
- name: EL
versions:
- 6
- 7
- name: Ubuntu
versions:
- trusty
categories:
- database:sql
dependencies: []

View File

@ -0,0 +1,12 @@
---
- name: Add repo file
template: src=mariadb_centos.repo.j2 dest=/etc/yum.repos.d/mariadb.repo owner=root group=root mode=0644
- name: Install MariaDB
yum: name={{ item }} enablerepo=mariadb state=present
with_items:
- MariaDB-server
- MariaDB-client
- MySQL-python
- MariaDB-devel

View File

@ -0,0 +1,10 @@
---
- name: Add repo file
template: src=mariadb_centos.repo.j2 dest=/etc/yum.repos.d/mariadb.repo owner=root group=root mode=0644
- name: Install MariaDB
yum: name={{ item }} enablerepo=mariadb state=present
with_items:
- MariaDB-server
- MariaDB-client
- MySQL-python

View File

@ -0,0 +1,18 @@
---
- include: centos.yml
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version|int >= 6
- include: ubuntu.yml
when: ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04'
- name: Add configuration
template: src={{ mysql_conf_tpl }} dest={{ mysql_conf_dir[ansible_distribution] }}/{{ mysql_conf_file }} owner=root group=root mode=0644
when: mysql_conf_tpl != 'change_me'
notify: restart mysql
- name: Start and enable service
service: name=mysql state=started enabled=yes
- include: mysql_secure_installation.yml
debug: var=mysql_secure_installation
when: mysql_secure_installation and mysql_root_password is defined

View File

@ -0,0 +1,57 @@
---
# Set root password
# UPDATE mysql.user SET Password=PASSWORD('mysecret') WHERE User='root';
# FLUSH PRIVILEGES;
- name: Set root Password
mysql_user: name=root host={{ item }} password={{ mysql_root_password }} state=present
with_items:
- localhost
- name: Add .my.cnf
template: src=my.cnf.j2 dest=/root/.my.cnf owner=root group=root mode=0600
- name: Set root Password
mysql_user: name=root host={{ item }} password={{ mysql_root_password }} state=present
with_items:
- 127.0.0.1
- ::1
- name: Reload privilege tables
command: 'mysql -ne "{{ item }}"'
with_items:
- FLUSH PRIVILEGES
changed_when: False
- name: Reload privilege tables
command: 'mysql -ne "{{ item }}"'
with_items:
- FLUSH PRIVILEGES
changed_when: False
- name: Remove anonymous users
command: 'mysql -ne "{{ item }}"'
with_items:
- DELETE FROM mysql.user WHERE User=''
changed_when: False
- name: Disallow root login remotely
command: 'mysql -ne "{{ item }}"'
with_items:
- DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')
changed_when: False
- name: Remove test database and access to it
command: 'mysql -ne "{{ item }}"'
with_items:
- DROP DATABASE if exists test
- DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'
changed_when: False
ignore_errors: True
- name: Reload privilege tables
command: 'mysql -ne "{{ item }}"'
with_items:
- FLUSH PRIVILEGES
changed_when: False

View File

@ -0,0 +1,23 @@
---
- name: Add repo file
template: src=mariadb_ubuntu.list.j2 dest=/etc/apt/sources.list.d/mariadb.list owner=root group=root mode=0644
register: mariadb_list
- name: Add repo key
apt_key: id=1BB943DB url=http://keyserver.ubuntu.com/pks/lookup?op=get&search=0xCBCB082A1BB943DB state=present
register: mariadb_key
- name: Update apt cache
apt: update_cache=yes
when: mariadb_list.changed == True or mariadb_key.changed == True
- name: Unattended package installation
shell: export DEBIAN_FRONTEND=noninteractive
changed_when: false
- name: Install MariaDB
apt: pkg={{ item }} state=present
with_items:
- mariadb-server
- mariadb-client
- python-mysqldb

View File

@ -0,0 +1,7 @@
# MariaDB CentOS {{ ansible_distribution_major_version|int }} repository list
# http://mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/{{ mariadb_version }}/centos{{ ansible_distribution_major_version|int }}-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

View File

@ -0,0 +1,4 @@
# MariaDB Ubuntu {{ ansible_distribution_release | title }} repository list
# http://mariadb.org/mariadb/repositories/
deb http://ams2.mirrors.digitalocean.com/mariadb/repo/{{ mariadb_version }}/ubuntu {{ ansible_distribution_release | lower }} main
deb-src http://ams2.mirrors.digitalocean.com/mariadb/repo/{{ mariadb_version }}/ubuntu {{ ansible_distribution_release | lower }} main

View File

@ -0,0 +1,3 @@
[client]
user=root
password={{ mysql_root_password }}

View File

@ -0,0 +1,4 @@
---
mysql_conf_dir:
"CentOS": /etc/my.cnf.d
"Ubuntu": /etc/mysql/conf.d

View File

@ -0,0 +1,35 @@
---
language: python
python: "2.7"
env:
- SITE=test.yml
before_install:
- sudo apt-get update -qq
- sudo apt-get install -y curl
install:
# Install Ansible.
- pip install ansible
# Add ansible.cfg to pick up roles path.
- "{ echo '[defaults]'; echo 'roles_path = ../'; } >> ansible.cfg"
script:
# Check the role/playbook's syntax.
- "ansible-playbook -i tests/inventory tests/$SITE --syntax-check"
# Run the role/playbook with ansible-playbook.
- "ansible-playbook -i tests/inventory tests/$SITE --connection=local --sudo"
# Run the role/playbook again, checking to make sure it's idempotent.
- >
ansible-playbook -i tests/inventory tests/$SITE --connection=local --sudo
| grep -q 'changed=0.*failed=0'
&& (echo 'Idempotence test: pass' && exit 0)
|| (echo 'Idempotence test: fail' && exit 1)
# TODO - get the test working. Probably need to add a virtual host.
# Request a page via Nginx, to make sure Nginx is running and responds.
# - "curl http://localhost/"

View File

@ -0,0 +1,82 @@
# Ansible Role: Nginx
[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-nginx.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-nginx)
Installs Nginx on RedHat/CentOS or Debian/Ubuntu linux servers.
This role installs and configures the latest version of Nginx from the Nginx yum repository (on RedHat-based systems) or via apt (on Debian-based systems). You will likely need to do extra setup work after this role has installed Nginx, like adding your own [virtualhost].conf file inside `/etc/nginx/conf.d/`, describing the location and options to use for your particular website.
## Requirements
None.
## Role Variables
Available variables are listed below, along with default values (see `defaults/main.yml`):
nginx_vhosts: []
A list of vhost definitions (server blocks) for Nginx virtual hosts. If left empty, you will need to supply your own virtual host configuration. See the commented example in `defaults/main.yml` for available server options. If you have a large number of customizations required for your server definition(s), you're likely better off managing the vhost configuration file yourself, leaving this variable set to `[]`.
nginx_remove_default_vhost: false
Whether to remove the 'default' virtualhost configuration supplied by Nginx. Useful if you want the base `/` URL to be directed at one of your own virtual hosts configured in a separate .conf file.
nginx_upstreams: []
If you are configuring Nginx as a load balancer, you can define one or more upstream sets using this variable. In addition to defining at least one upstream, you would need to configure one of your server blocks to proxy requests through the defined upstream (e.g. `proxy_pass http://myapp1;`). See the commented example in `defaults/main.yml` for more information.
nginx_user: "nginx"
The user under which Nginx will run. Defaults to `nginx` for RedHat, and `www-data` for Debian.
nginx_worker_processes: "1"
nginx_worker_connections: "1024"
`nginx_worker_processes` should be set to the number of cores present on your machine. Connections (find this number with `grep processor /proc/cpuinfo | wc -l`). `nginx_worker_connections` is the number of connections per process. Set this higher to handle more simultaneous connections (and remember that a connection will be used for as long as the keepalive timeout duration for every client!).
nginx_error_log: "/var/log/nginx/error.log warn"
nginx_access_log: "/var/log/nginx/access.log main buffer=16k"
Configuration of the default error and access logs. Set to `off` to disable a log entirely.
nginx_sendfile: "on"
nginx_tcp_nopush: "on"
nginx_tcp_nodelay: "on"
TCP connection options. See [this blog post](https://t37.net/nginx-optimization-understanding-sendfile-tcp_nodelay-and-tcp_nopush.html) for more information on these directives.
nginx_keepalive_timeout: "65"
nginx_keepalive_requests: "100"
Nginx keepalive settings. Timeout should be set higher (10s+) if you have more polling-style traffic (AJAX-powered sites especially), or lower (<10s) if you have a site where most users visit a few pages and don't send any further requests.
nginx_client_max_body_size: "64m"
This value determines the largest file upload possible, as uploads are passed through Nginx before hitting a backend like `php-fpm`. If you get an error like `client intended to send too large body`, it means this value is set too low.
nginx_proxy_cache_path: ""
Set as the `proxy_cache_path` directive in the `nginx.conf` file. By default, this will not be configured (if left as an empty string), but if you wish to use Nginx as a reverse proxy, you can set this to a valid value (e.g. `"/var/cache/nginx keys_zone=cache:32m"`) to use Nginx's cache (further proxy configuration can be done in individual server configurations).
nginx_default_release: ""
(For Debian/Ubuntu only) Allows you to set a different repository for the installation of Nginx. As an example, if you are running Debian's wheezy release, and want to get a newer version of Nginx, you can install the `wheezy-backports` repository and set that value here, and Ansible will use that as the `-t` option while installing Nginx.
## Dependencies
None.
## Example Playbook
- hosts: server
roles:
- { role: geerlingguy.nginx }
## License
MIT / BSD
## Author Information
This role was created in 2014 by [Jeff Geerling](http://jeffgeerling.com/), author of [Ansible for DevOps](http://ansiblefordevops.com/).

View File

@ -0,0 +1,47 @@
---
# Used only for Debian/Ubuntu installation, as the -t option for apt.
nginx_default_release: ""
nginx_worker_processes: "1"
nginx_worker_connections: "1024"
nginx_error_log: "/var/log/nginx/error.log warn"
nginx_access_log: "/var/log/nginx/access.log main buffer=16k"
nginx_sendfile: "on"
nginx_tcp_nopush: "on"
nginx_tcp_nodelay: "on"
nginx_keepalive_timeout: "65"
nginx_keepalive_requests: "100"
nginx_client_max_body_size: "64m"
nginx_proxy_cache_path: ""
nginx_remove_default_vhost: false
nginx_vhosts: []
# Example vhost below, showing all available options:
# - {
# listen: "80 default_server", # default: "80 default_server"
# server_name: "example.com", # default: N/A
# root: "/var/www/example.com", # default: N/A
# index: "index.html index.htm", # default: "index.html index.htm"
#
# # Properties that are only added if defined:
# error_page: "",
# access_log: "",
# extra_config: "" # Can be used to add extra config blocks (multiline).
# }
nginx_upstreams: []
# - {
# name: myapp1,
# strategy: "ip_hash", # "least_conn", etc.
# servers: {
# "srv1.example.com",
# "srv2.example.com weight=3",
# "srv3.example.com"
# }
# }
nginx_conf_file: nginx.conf.j2

View File

@ -0,0 +1,3 @@
---
- name: restart nginx
service: name=nginx state=restarted

View File

@ -0,0 +1,23 @@
---
dependencies: []
galaxy_info:
author: geerlingguy
description: Nginx installation for Linux/UNIX.
company: "Midwestern Mac, LLC"
license: "license (BSD, MIT)"
min_ansible_version: 1.4
platforms:
- name: EL
versions:
- 6
- 7
- name: Debian
versions:
- all
- name: Ubuntu
versions:
- all
categories:
- development
- web

View File

@ -0,0 +1,31 @@
---
# Variable setup.
- name: Include OS-specific variables.
include_vars: "{{ ansible_os_family }}.yml"
- name: Define nginx_user.
set_fact:
nginx_user: "{{ __nginx_user }}"
when: nginx_user is not defined
# Setup/install tasks.
- include: setup-RedHat.yml
when: ansible_os_family == 'RedHat'
- include: setup-Debian.yml
when: ansible_os_family == 'Debian'
# Nginx setup.
- name: Copy nginx configuration in place.
template:
src: "{{ nginx_conf_file }}"
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: 0644
notify: restart nginx
- name: Ensure nginx is started and enabled to start at boot.
service: name=nginx state=started enabled=yes
- include: vhosts.yml

View File

@ -0,0 +1,6 @@
---
- name: Ensure nginx is installed.
apt:
pkg: nginx
state: installed
default_release: "{{ nginx_default_release }}"

View File

@ -0,0 +1,11 @@
---
- name: Enable nginx repo.
template:
src: nginx.repo.j2
dest: /etc/yum.repos.d/nginx.repo
owner: root
group: root
mode: 0644
- name: Ensure nginx is installed.
yum: pkg=nginx state=installed enablerepo=nginx

View File

@ -0,0 +1,22 @@
---
- name: Remove default nginx vhost config file (if configured).
file:
path: "{{ nginx_default_vhost_path }}"
state: absent
when: nginx_remove_default_vhost
notify: restart nginx
- name: Add managed vhost config file (if any vhosts are configured).
template:
src: vhosts.j2
dest: "{{ nginx_vhost_path }}/vhosts.conf"
mode: 0644
when: nginx_vhosts
notify: restart nginx
- name: Remove managed vhost config file (if no vhosts are configured).
file:
path: "{{ nginx_vhost_path }}/vhosts.conf"
state: absent
when: not nginx_vhosts
notify: restart nginx

View File

@ -0,0 +1,51 @@
user {{ nginx_user }};
error_log {{ nginx_error_log }};
pid /var/run/nginx.pid;
worker_processes {{ nginx_worker_processes }};
events {
worker_connections {{ nginx_worker_connections }};
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 64;
client_max_body_size {{ nginx_client_max_body_size }};
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log {{ nginx_access_log }};
sendfile {{ nginx_sendfile }};
tcp_nopush {{ nginx_tcp_nopush }};
tcp_nodelay {{ nginx_tcp_nodelay }};
keepalive_timeout {{ nginx_keepalive_timeout }};
keepalive_requests {{ nginx_keepalive_requests }};
#gzip on;
{% if nginx_proxy_cache_path %}
proxy_cache_path {{ nginx_proxy_cache_path }};
{% endif %}
{% for upstream in nginx_upstreams %}
upstream {{ upstream.name }} {
{% if upstream.strategy is defined %}
{{ upstream.strategy }};
{% endif %}
{% for server in upstream.servers %}
server {{ server }};
{% endfor %}
}
{% endfor %}
include {{ nginx_vhost_path }}/*;
}

View File

@ -0,0 +1,5 @@
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/{{ ansible_distribution_major_version }}/$basearch/
gpgcheck=0
enabled=1

View File

@ -0,0 +1,24 @@
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen | default('80 default_server') }};
server_name {{ vhost.server_name }};
root {{ vhost.root }};
index {{ vhost.index | default('index.html index.htm') }};
{% if vhost.error_page is defined %}
error_page {{ vhost.error_page }};
{% endif %}
{% if vhost.access_log is defined %}
access_log {{ vhost.access_log }};
{% endif %}
{% if vhost.return is defined %}
return {{ vhost.return }};
{% endif %}
{% if vhost.extra_parameters is defined %}
{{ vhost.extra_parameters }};
{% endif %}
}
{% endfor %}

View File

@ -0,0 +1 @@
localhost

View File

@ -0,0 +1,5 @@
---
- hosts: localhost
remote_user: root
roles:
- ansible-role-nginx

View File

@ -0,0 +1,4 @@
---
nginx_vhost_path: /etc/nginx/sites-enabled
nginx_default_vhost_path: /etc/nginx/sites-enabled/default
__nginx_user: "www-data"

View File

@ -0,0 +1,4 @@
---
nginx_vhost_path: /etc/nginx/conf.d
nginx_default_vhost_path: /etc/nginx/conf.d/default.conf
__nginx_user: "nginx"

View File

@ -0,0 +1 @@
swap_size_mb: 1024

View File

@ -0,0 +1,18 @@
- name: Create swap space
command: dd if=/dev/zero of=/extraswap bs=1M count={{swap_size_mb}}
when: ansible_swaptotal_mb < 1
- name: Make swap
command: mkswap /extraswap
when: ansible_swaptotal_mb < 1
- name: Add to fstab
action: lineinfile dest=/etc/fstab regexp="extraswap" line="/extraswap none swap sw 0 0" state=present
when: ansible_swaptotal_mb < 1
- name: Turn swap on
command: swapon -a
when: ansible_swaptotal_mb < 1
- name: Set swapiness
shell: echo 1 | tee /proc/sys/vm/swappiness

View File

@ -0,0 +1 @@
wkhtmltopdf_version: 0.12.2.1

View File

@ -0,0 +1,32 @@
---
- name: install base fonts
yum: name={{ item }} state=present
with_items:
- libXrender
- libXext
- xorg-x11-fonts-75dpi
- xorg-x11-fonts-Type1
when: ansible_os_family == 'RedHat'
- name: Install wkhtmltopdf rpm
yum: name=http://download.gna.org/wkhtmltopdf/0.12/{{ wkhtmltopdf_version }}/wkhtmltox-{{ wkhtmltopdf_version }}_linux-centos{{ ansible_distribution_major_version }}-{{ "amd64" if ansible_architecture == "x86_64" else "i386"}}.rpm
when: ansible_os_family == 'RedHat'
- name: install base fonts
apt: name={{ item }} state=present
with_items:
- libxrender1
- libxext6
- xfonts-75dpi
- xfonts-base
when: ansible_os_family == 'Debian'
- name: Download wkhtmltopdf
get_url:
url=http://download.gna.org/wkhtmltopdf/0.12/{{ wkhtmltopdf_version }}/wkhtmltox-{{ wkhtmltopdf_version }}_linux-{{ ansible_distribution_release }}-{{ "amd64" if ansible_architecture == "x86_64" else "i386"}}.deb
dest="/tmp/"
when: ansible_os_family == 'Debian'
- name: Install wkhtmltopdf deb
apt: deb=/tmp/wkhtmltox-{{ wkhtmltopdf_version }}_linux-{{ ansible_distribution_release }}-{{ "amd64" if ansible_architecture == "x86_64" else "i386"}}.deb
when: ansible_os_family == 'Debian'

View File

@ -0,0 +1,58 @@
[mysqld]
# GENERAL #
user = mysql
default-storage-engine = InnoDB
socket = /var/lib/mysql/mysql.sock
pid-file = /var/lib/mysql/mysql.pid
# MyISAM #
key-buffer-size = 32M
myisam-recover = FORCE,BACKUP
# SAFETY #
max-allowed-packet = 16M
max-connect-errors = 1000000
innodb = FORCE
# DATA STORAGE #
datadir = /var/lib/mysql/
# BINARY LOGGING #
log-bin = /var/lib/mysql/mysql-bin
expire-logs-days = 14
sync-binlog = 1
# CACHES AND LIMITS #
tmp-table-size = 32M
max-heap-table-size = 32M
query-cache-type = 0
query-cache-size = 0
max-connections = 500
thread-cache-size = 50
open-files-limit = 65535
table-definition-cache = 4096
table-open-cache = 10240
# INNODB #
innodb-flush-method = O_DIRECT
innodb-log-files-in-group = 2
innodb-log-file-size = 512M
innodb-flush-log-at-trx-commit = 1
innodb-file-per-table = 1
innodb-buffer-pool-size = {{ (ansible_memtotal_mb*0.685)|round|int }}M
innodb-file-format = barracuda
innodb-large-prefix = 1
collation-server = utf8mb4_unicode_ci
character-set-server = utf8mb4
character-set-client-handshake = FALSE
# LOGGING #
log-error = /var/lib/mysql/mysql-error.log
log-queries-not-using-indexes = 0
slow-query-log = 1
slow-query-log-file = /var/lib/mysql/mysql-slow.log
[mysql]
default-character-set = utf8mb4

View File

@ -0,0 +1,44 @@
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user www-data;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
index index.html index.htm;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
}

2
vm/ansible/vars.yml Normal file
View File

@ -0,0 +1,2 @@
---
mysql_root_password: frappe

63
vm/ansible/vm.yml Normal file
View File

@ -0,0 +1,63 @@
---
- include: base.yml
- name: Clone bench
hosts: all
user: "{{ frappe_user }}"
tasks:
- git:
repo=https://github.com/frappe/bench
dest=/home/frappe/bench-repo
tags:
- bench_install
- name: Install bench
hosts: all
become: yes
become_user: root
tasks:
- easy_install: name=pip executable=easy_install-2.7
- pip: name=/home/frappe/bench-repo extra_args='-e'
tags:
- bench_install
- name: Setup bench
hosts: all
become: yes
become_user: "{{ frappe_user }}"
become_method: sudo
gather_facts: false
tasks:
- bench:
path: /home/frappe/frappe-bench
frappe_branch: develop
apps:
- name: erpnext
url: https://github.com/frappe/erpnext
- name: erpnext_demo
url: https://github.com/frappe/erpnext_demo
mariadb_root_password: "{{ mysql_root_password }}"
sites:
- name: erpnext.vm
admin_password: "{{ admin_password or 'admin' }}"
apps:
- erpnext
tags:
- bench_setup
- name: Setup Production
hosts: all
become: yes
become_user: root
become_method: sudo
tasks:
- shell: "bench setup sudoers {{ frappe_user }}"
args:
chdir: "/home/{{ frappe_user }}/frappe-bench"
creates: "/home/{{ frappe_user }}/frappe-bench/config/supervisor.conf"
- shell: "bench setup production {{ frappe_user }}"
args:
chdir: "/home/{{ frappe_user }}/frappe-bench"
creates: "/home/{{ frappe_user }}/frappe-bench/config/supervisor.conf"
- file: path="/home/{{ frappe_user }}/frappe-bench/logs/" recurse=yes owner="{{ frappe_user }}"

View File

@ -0,0 +1,4 @@
---
mysql_root_password: frappe
frappe_user: frappe
admin_password: admin

50
vm/build.py Normal file
View File

@ -0,0 +1,50 @@
"""
Builds a vm and puts it in ~/public with a latest.json that has its filename and md5sum
"""
import os
import subprocess
import json
import stat
OUTPUT_DIR = 'output-virtualbox-ovf'
PUBLIC_DIR = os.path.join(os.path.expanduser('~'), 'public')
def main():
build_vm()
update_latest()
move_to_public()
cleanup()
def build_vm():
subprocess.check_call("./packer build vm.json", shell=True)
def move_to_public():
src = get_filepath()
dest = os.path.join(PUBLIC_DIR, os.path.join(PUBLIC_DIR, get_filename()))
os.rename(src, dest)
st = os.stat(dest)
os.chmod(dest, st.st_mode | stat.S_IROTH)
def update_latest():
with open(os.path.join(PUBLIC_DIR, "latest.json"), 'w') as f:
json.dump(get_latest(), f)
def get_latest():
md5 = subprocess.check_output("md5sum {}".format(get_filepath()), shell=True).split()[0]
return {
"filename": get_filename(),
"md5": md5
}
def get_filename():
return os.listdir(OUTPUT_DIR)[0]
def get_filepath():
filename = os.listdir(OUTPUT_DIR)[0]
return os.path.join(OUTPUT_DIR, filename)
def cleanup():
os.rmdir(OUTPUT_DIR)
if __name__ == "__main__":
main()

BIN
vm/packer Executable file

Binary file not shown.

View File

@ -0,0 +1,4 @@
sudo apt-get install -y software-properties-common
sudo apt-add-repository -y ppa:ansible/ansible
sudo apt-get update
sudo apt-get install -y ansible

17
vm/scripts/set_message.sh Normal file
View File

@ -0,0 +1,17 @@
#! /bin/bash
message="
ERPNext evaluation VM (built on `date +\"%B %d, %Y\"`)
Please access ERPNext by going to http://localhost:8080 on the host system.
Do consider donating at https://frappe.io/buy
To update, login as
username: frappe
password: frappe
cd frappe-bench
bench update
"
echo "$message" | sudo tee -a /etc/issue
echo "$message" | sudo tee -a /etc/motd

4
vm/scripts/zerofree.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/sh
sudo apt-get clean
sudo dd if=/dev/zero of=/EMPTY bs=1M
sudo rm -f /EMPTY

42
vm/vm.json Normal file
View File

@ -0,0 +1,42 @@
{
"builders":[{
"vm_name": "ERPNext-{{isotime \"020106\"}}",
"type": "virtualbox-ovf",
"format": "ova",
"headless": true,
"source_path": "base.ova",
"ssh_username": "frappe",
"ssh_password": "frappe",
"guest_additions_mode": "disable",
"ssh_port": 22,
"ssh_wait_timeout": "300s",
"export_opts": ["--vsys", "0", "--product", "ERPNext", "--producturl", "https://erpnext.com", "--vendor", "Frappe Techonologies", "--vendorurl", "https://frappe.io", "--description", "ERPNext Evaluation VM"],
"shutdown_command": " echo 'packer' | sudo shutdown -P -h now",
"vboxmanage": [
[ "modifyvm", "{{.Name}}", "--memory", "512" ],
[ "modifyvm", "{{.Name}}", "--audio", "none" ],
[ "modifyvm", "{{.Name}}", "--cpus", "1" ],
[ "modifyvm", "{{.Name}}", "--natpf1", "vm_ssh,tcp,,3022,,22" ],
[ "modifyvm", "{{.Name}}", "--natpf1", "vm_http,tcp,,8080,,80" ]
]
}
],
"provisioners": [{
"type": "shell",
"script": "scripts/install_ansible.sh"
}, {
"type": "ansible-local",
"playbook_file": "ansible/vm.yml",
"playbook_dir": "ansible",
"group_vars": "ansible/vm_vars",
"role_paths": [
"ansible/roles"
]
}, {
"type": "shell",
"script": "scripts/set_message.sh"
}, {
"type": "shell",
"script": "scripts/zerofree.sh"
}]
}