diff --git a/.gitignore b/.gitignore index e9a0c00..8cdc439 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,17 @@ -venv .gunicorn.pid -*.log .sass-cache +.vagrant +.venv + +*.log *.un~ *.pgdump *.pyc settings_local.py -media/cache -tags +settings_local_server.py +media/cache media/css/pro.css media/css/snipt.css media/js/src/account.min.js @@ -22,3 +24,9 @@ media/js/src/modules/snipt.min.js media/js/src/pro.min.js media/js/snipt-all.min.js media/js/pro-all.min.js +static/admin +static/css +static/fonts +static/img +static/js +tags diff --git a/Makefile b/Makefile index d458e69..0afd10f 100644 --- a/Makefile +++ b/Makefile @@ -1,35 +1,37 @@ -deploy: - @git push heroku +pm = /var/www/.virtualenvs/snipt/bin/python /var/www/snipt/manage.py +ssh-server-deploy = ssh deploy@69.164.221.98 -p 55555 +ssh-server-root = ssh root@69.164.221.98 +ssh-vagrant = ssh vagrant@localhost -p 2222 -i ~/.vagrant.d/insecure_private_key -deploy-with-assets: +assets: @cat media/css/bootstrap.min.css \ - media/css/blog-themes/pro-adams/style.css \ - media/css/highlightjs-themes/tomorrow.css \ - media/css/themes.css \ - > media/css/pro.css + media/css/blog-themes/pro-adams/style.css \ + media/css/highlightjs-themes/tomorrow.css \ + media/css/themes.css \ + > media/css/pro.css @cat media/css/bootstrap.min.css \ - media/css/style.css \ - media/css/themes.css \ - media/css/chosen.css \ - media/css/codemirror.css \ - media/css/codemirror-themes/ambiance.css \ - media/css/codemirror-themes/blackboard.css \ - media/css/codemirror-themes/cobalt.css \ - media/css/codemirror-themes/eclipse.css \ - media/css/codemirror-themes/elegant.css \ - media/css/codemirror-themes/erlang-dark.css \ - media/css/codemirror-themes/lesser-dark.css \ - media/css/codemirror-themes/monokai.css \ - media/css/codemirror-themes/neat.css \ - media/css/codemirror-themes/night.css \ - media/css/codemirror-themes/rubyblue.css \ - media/css/codemirror-themes/solarized.css \ - media/css/codemirror-themes/twilight.css \ - media/css/codemirror-themes/vibrant-ink.css \ - media/css/codemirror-themes/xq-dark.css \ - media/css/highlightjs-themes/tomorrow.css \ - media/css/blog-themes/default/style.css \ - > media/css/snipt.css + media/css/style.css \ + media/css/themes.css \ + media/css/chosen.css \ + media/css/codemirror.css \ + media/css/codemirror-themes/ambiance.css \ + media/css/codemirror-themes/blackboard.css \ + media/css/codemirror-themes/cobalt.css \ + media/css/codemirror-themes/eclipse.css \ + media/css/codemirror-themes/elegant.css \ + media/css/codemirror-themes/erlang-dark.css \ + media/css/codemirror-themes/lesser-dark.css \ + media/css/codemirror-themes/monokai.css \ + media/css/codemirror-themes/neat.css \ + media/css/codemirror-themes/night.css \ + media/css/codemirror-themes/rubyblue.css \ + media/css/codemirror-themes/solarized.css \ + media/css/codemirror-themes/twilight.css \ + media/css/codemirror-themes/vibrant-ink.css \ + media/css/codemirror-themes/xq-dark.css \ + media/css/highlightjs-themes/tomorrow.css \ + media/css/blog-themes/default/style.css \ + > media/css/snipt.css @cat media/js/src/account.js|jsmin > media/js/src/account.min.js @cat media/js/src/snipts.js|jsmin > media/js/src/snipts.min.js @cat media/js/src/search.js|jsmin > media/js/src/search.min.js @@ -39,30 +41,113 @@ deploy-with-assets: @cat media/js/src/modules/snipt.js|jsmin > media/js/src/modules/snipt.min.js @cat media/js/src/pro.js|jsmin > media/js/src/pro.min.js @cat media/js/libs/jquery.min.js \ - media/js/libs/jquery-ui.min.js \ - media/js/libs/angular.min.js \ - media/js/libs/angular-route.min.js \ - media/js/libs/underscore.js \ - media/js/libs/json2.js \ - media/js/libs/backbone.js \ - media/js/libs/bootstrap.min.js \ - media/js/plugins/jquery.hotkeys.js \ - media/js/plugins/jquery.infieldlabel.js \ - media/js/plugins/jquery.chosen.js \ - media/js/src/application.min.js \ - media/js/src/modules/site.min.js \ - media/js/src/modules/snipt.min.js \ - media/js/src/account.min.js \ - media/js/src/snipts.min.js \ - media/js/src/search.min.js \ - media/js/src/jobs.min.js \ - media/js/libs/codemirror.js \ - media/js/libs/highlight.js \ - > media/js/snipt-all.min.js + media/js/libs/jquery-ui.min.js \ + media/js/libs/angular.min.js \ + media/js/libs/angular-route.min.js \ + media/js/libs/underscore.js \ + media/js/libs/json2.js \ + media/js/libs/backbone.js \ + media/js/libs/bootstrap.min.js \ + media/js/plugins/jquery.hotkeys.js \ + media/js/plugins/jquery.infieldlabel.js \ + media/js/plugins/jquery.chosen.js \ + media/js/src/application.min.js \ + media/js/src/modules/site.min.js \ + media/js/src/modules/snipt.min.js \ + media/js/src/account.min.js \ + media/js/src/snipts.min.js \ + media/js/src/search.min.js \ + media/js/src/jobs.min.js \ + media/js/libs/codemirror.js \ + media/js/libs/highlight.js \ + > media/js/snipt-all.min.js @cat media/js/libs/highlight.js \ - media/js/src/pro.js \ - > media/js/pro-all.min.js + media/js/src/pro.js \ + > media/js/pro-all.min.js /Users/Nick/.virtualenvs/snipt/bin/python manage.py collectstatic --noinput + +db: + @echo Creating database user snipt: + @sudo -u postgres bash -c 'createuser snipt -P' + @sudo -u postgres bash -c 'createdb snipt -O snipt' + +deploy: + @$(ssh-server-deploy) 'cd /var/www/snipt; git pull;' + @$(ssh-server-deploy) 'cd /var/www/snipt; make assets;' + @$(ssh-server-deploy) '$(pm) migrate' + @$(ssh-server-deploy) 'sudo supervisorctl restart snipt' + +deploy-heroku: @git push heroku -.PHONY: deploy, deploy-with-assets +salt-server: + @scp -q -P 55555 -r ./salt/ deploy@69.164.221.98:salt + @scp -q -P 55555 -r ./pillar/ deploy@69.164.221.98:pillar + @$(ssh-server-deploy) 'sudo rm -rf /srv' + @$(ssh-server-deploy) 'sudo mkdir /srv' + @$(ssh-server-deploy) 'sudo mv ~/salt /srv/salt' + @$(ssh-server-deploy) 'sudo mv ~/pillar /srv/pillar' + @$(ssh-server-deploy) 'sudo salt-call --local state.highstate' + +salt-vagrant: + @scp -q -P 2222 -i ~/.vagrant.d/insecure_private_key -r ./salt/ vagrant@localhost:salt + @scp -q -P 2222 -i ~/.vagrant.d/insecure_private_key -r ./pillar/ vagrant@localhost:pillar + @$(ssh-vagrant) 'sudo rm -rf /srv' + @$(ssh-vagrant) 'sudo mkdir /srv' + @$(ssh-vagrant) 'sudo mv ~/salt /srv/salt' + @$(ssh-vagrant) 'sudo mv ~/pillar /srv/pillar' + @$(ssh-vagrant) 'sudo salt-call --local state.highstate' + +server: + @$(ssh-server-root) 'sudo apt-get update' + @$(ssh-server-root) 'sudo apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade' + @$(ssh-server-root) 'sudo apt-get install -y software-properties-common python-software-properties' + @$(ssh-server-root) 'sudo add-apt-repository -y ppa:saltstack/salt' + @$(ssh-server-root) 'sudo apt-get update' + @$(ssh-server-root) 'sudo apt-get install -y salt-minion' + @scp -q -r ./salt/ root@69.164.221.98:salt + @scp -q -r ./pillar/ root@69.164.221.98:pillar + @$(ssh-server-root) 'sudo rm -rf /srv' + @$(ssh-server-root) 'sudo mkdir /srv' + @$(ssh-server-root) 'sudo mv ~/salt /srv/salt' + @$(ssh-server-root) 'sudo mv ~/pillar /srv/pillar' + @$(ssh-server-root) 'sudo salt-call --local state.highstate' + @scp -q -P 55555 settings_local_server.py deploy@69.164.221.98:/var/www/snipt/settings_local.py + @$(ssh-server-deploy) 'cd /var/www/snipt; make db;' + @$(ssh-server-deploy) '$(pm) syncdb;' + @$(ssh-server-deploy) '$(pm) migrate;' + @$(ssh-server-deploy) '$(pm) backfill_api_keys' + @$(ssh-server-deploy) '$(pm) rebuild_index --noinput' + +vagrant: + @vagrant up --provider=vmware_fusion + @$(ssh-vagrant) 'sudo apt-get update' + @$(ssh-vagrant) 'sudo apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade' + @$(ssh-vagrant) 'sudo apt-get install -y software-properties-common python-software-properties' + @$(ssh-vagrant) 'sudo add-apt-repository -y ppa:saltstack/salt' + @$(ssh-vagrant) 'sudo apt-get update' + @$(ssh-vagrant) 'sudo apt-get install -y salt-minion' + @scp -q -P 2222 -i ~/.vagrant.d/insecure_private_key -r ./salt/ vagrant@localhost:salt + @scp -q -P 2222 -i ~/.vagrant.d/insecure_private_key -r ./pillar/ vagrant@localhost:pillar + @$(ssh-vagrant) 'sudo rm -rf /srv' + @$(ssh-vagrant) 'sudo mkdir /srv' + @$(ssh-vagrant) 'sudo mv ~/salt /srv/salt' + @$(ssh-vagrant) 'sudo mv ~/pillar /srv/pillar' + @$(ssh-vagrant) 'sudo salt-call --local state.highstate' + @vagrant ssh -c 'cd /var/www/snipt; make db;' + @vagrant ssh -c '$(pm) syncdb;' + @$(ssh-vagrant) '$(pm) migrate;' + @$(ssh-vagrant) '$(pm) backfill_api_keys' + @$(ssh-vagrant) '$(pm) rebuild_index --noinput' + +.PHONY: assets, \ + db, \ + deploy, \ + deploy-heroku, \ + provision-server, \ + provision-vagrant, \ + salt-server, \ + salt-vagrant, \ + server-settings, \ + server, \ + vagrant diff --git a/README.md b/README.md index 382edc3..0699187 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,21 @@ This is the codebase for the website, [Snipt.net](https://snipt.net/). # Running the Django app +Install [Vagrant](https://www.vagrantup.com/) and either [VirtualBox](https://www.virtualbox.org/) or +[VMWare Fusion](http://www.vmware.com/products/fusion). + 1. Clone the repo. -2. Setup a virtualenv. -3. `pip install -r requirements.txt` -5. `python manage.py syncdb` -6. `python manage.py migrate` -7. `python manage.py runserver` -8. If you created a superuser in the syncdb step, you need to also run `python manage.py backfill_api_keys` to generate an API key for that user. +2. `cp settings_local.py-template settings_local.py` +3. Edit local settings (choose a database password - you'll be prompted for it). +4. `make vagrant` +5. Visit [http://local.snipt.net:8080/](http://local.snipt.net:8080/). + +# Deploying to a VM +1. Clone the repo. +2. `cp settings_local.py-template settings_local_server.py` +3. Edit local server settings (choose a database password - you'll be prompted for it). +4. Manually change the VM IP address in the Makefile. +5. `make server` # Deploying to Heroku @@ -18,9 +26,6 @@ This is the codebase for the website, [Snipt.net](https://snipt.net/). 2. `heroku create` 3. `heroku addons:add heroku-postgresql:hobby-dev` 4. `heroku addons:add searchbox` -5. `heroku config:add AWS_ACCESS_KEY_ID=` -6. `heroku config:add AWS_SECRET_ACCESS_KEY=` -7. `heroku config:add AWS_STORAGE_BUCKET_NAME=` 8. `heroku config:add DEBUG=False` 9. `heroku config:add INTERCOM_SECRET_KEY=` 9. `heroku config:add POSTMARK_API_KEY=` diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..fa6b204 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,6 @@ +Vagrant.configure("2") do |config| + config.vm.box = "phusion/ubuntu-14.04-amd64" + config.vm.hostname = "local.snipt.net" + config.vm.synced_folder ".", "/var/www/snipt/" + config.vm.network "forwarded_port", guest: 80, host: 80 +end diff --git a/accounts/views.py b/accounts/views.py index 2843e62..5b7b187 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.contrib.auth.decorators import login_required from annoying.decorators import ajax_request, render_to from snipts.models import Snipt @@ -18,7 +19,7 @@ def cancel_subscription(request): if request.user.profile.stripe_id is None: return {} else: - stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', '') + stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', settings.STRIPE_SECRET_KEY) customer = stripe.Customer.retrieve(request.user.profile.stripe_id) customer.delete() @@ -36,7 +37,7 @@ def stripe_account_details(request): if request.user.profile.stripe_id is None: return {} else: - stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', '') + stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', settings.STRIPE_SECRET_KEY) customer = stripe.Customer.retrieve(request.user.profile.stripe_id) data = { diff --git a/blogs/middleware.py b/blogs/middleware.py index c2c52b0..64b5778 100644 --- a/blogs/middleware.py +++ b/blogs/middleware.py @@ -12,7 +12,7 @@ class BlogMiddleware: host = request.META.get('HTTP_HOST', '') host_s = host.replace('www.', '').split('.') - if host != 'snipt.net' and host != 'snipt.localhost': + if host != 'snipt.net' and host != 'snipt.localhost' and host != 'local.snipt.net': if len(host_s) > 2: if host_s[1] == 'snipt': diff --git a/gunicorn.conf.py b/gunicorn.conf.py new file mode 100644 index 0000000..f48c9fb --- /dev/null +++ b/gunicorn.conf.py @@ -0,0 +1,12 @@ +bind = "0.0.0.0:8000" +daemon = False # Whether work in the background +debug = False # Some extra logging +logfile = ".gunicorn.log" # Name of the log file +loglevel = "info" # The level at which to log +pidfile = ".gunicorn.pid" # Path to a PID file +workers = 9 # Number of workers to initialize +umask = 0 # Umask to set when daemonizing +user = None # Change process owner to user +group = None # Change process group to group +proc_name = "gunicorn-snipt" # Change the process name +tmp_upload_dir = None # Set path used to store temporary uploads diff --git a/pillar/production.sls b/pillar/production.sls new file mode 100644 index 0000000..8d231cf --- /dev/null +++ b/pillar/production.sls @@ -0,0 +1,18 @@ +env_name: production +hostname: snipt.net +deploy_user: deploy + +users: + - + name: deploy + groups: + - deploy + - wheel + - + name: nick + groups: + - deploy + - wheel + +ssh: + port: 55555 diff --git a/pillar/top.sls b/pillar/top.sls new file mode 100644 index 0000000..ddb8304 --- /dev/null +++ b/pillar/top.sls @@ -0,0 +1,5 @@ +base: + 'local.snipt.net': + - vagrant + '*': + - production diff --git a/pillar/vagrant.sls b/pillar/vagrant.sls new file mode 100644 index 0000000..9a48eda --- /dev/null +++ b/pillar/vagrant.sls @@ -0,0 +1,13 @@ +env_name: vagrant +hostname: local.snipt.net +deploy_user: vagrant + +users: + - + name: vagrant + groups: + - deploy + - wheel + +ssh: + port: 22 diff --git a/requirements.txt b/requirements.txt index a7efbfe..815dcc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,7 +44,7 @@ stripe==1.7.10 Werkzeug==0.9.4 wsgiref==0.1.2 -hg+https://bitbucket.org/kubaz93/django-registration@django1.6#egg=django-registration +hg+https://bitbucket.org/kubazarz/django-registration@django1.6#egg=django-registration hg+https://bitbucket.org/birkenfeld/pygments-main#egg=Pygments git+git://github.com/toastdriven/django-haystack.git#egg=django-haystack diff --git a/salt/application/init.sls b/salt/application/init.sls new file mode 100644 index 0000000..897706a --- /dev/null +++ b/salt/application/init.sls @@ -0,0 +1,84 @@ +python-virtualenv: + pkg.installed + +virtualenvwrapper: + pip.installed + +/var/www: + file.directory: + - user: {{ pillar.deploy_user }} + - group: deploy + - mode: 775 + - require: + - user: {{ pillar.deploy_user }} + - group: deploy + +/var/www/.virtualenvs: + file.directory: + - user: {{ pillar.deploy_user }} + - group: deploy + - mode: 775 + - require: + - group: deploy + +{% if pillar.env_name != 'vagrant' %} + +/var/www/snipt: + file.directory: + - user: {{ pillar.deploy_user }} + - group: deploy + - mode: 775 + - require: + - group: deploy + + git.latest: + - name: git@github.com:nicksergeant/snipt.git + - target: /var/www/snipt + - user: deploy + +{% endif %} + +/var/www/.virtualenvs/snipt: + file.directory: + - user: {{ pillar.deploy_user }} + - group: deploy + - mode: 775 + - require: + - group: deploy + virtualenv.managed: + - system_site_packages: False + - requirements: /var/www/snipt/requirements.txt + +/home/{{ pillar.deploy_user }}/tmp: + file.absent + +/etc/supervisor/conf.d/snipt.conf: + file.managed: + - source: salt://application/snipt.supervisor.conf + - template: jinja + - makedirs: True + cmd.run: + - name: supervisorctl restart snipt + +snipt-site: + file.managed: + - name: /etc/nginx/sites-available/snipt + - source: salt://application/snipt.nginx.conf + - template: jinja + - group: deploy + - mode: 755 + - require: + - pkg: nginx + - group: deploy + +enable-snipt-site: + file.symlink: + - name: /etc/nginx/sites-enabled/snipt + - target: /etc/nginx/sites-available/snipt + - force: false + - require: + - pkg: nginx + cmd.run: + - name: service nginx restart + - require: + - pkg: nginx diff --git a/salt/application/snipt.nginx.conf b/salt/application/snipt.nginx.conf new file mode 100644 index 0000000..8c7e16d --- /dev/null +++ b/salt/application/snipt.nginx.conf @@ -0,0 +1,98 @@ +upstream backend_snipt { + server 127.0.0.1:8000; +} +{% if pillar.env_name != 'vagrant' %} + server { + listen 80; + server_name *.{{ pillar.hostname }}; + + if ($host ~* "^([^.]+(\.[^.]+)*)\.{{ pillar.hostname }}$"){ + set $subd $1; + rewrite ^(.*)$ https://$subd.{{ pillar.hostname }}$1 permanent; + break; + } + } + server { + listen 80; + server_name {{ pillar.hostname }} www.{{ pillar.hostname }} beta.{{ pillar.hostname }}; + rewrite ^(.*) https://{{ pillar.hostname }}$1 permanent; + } + server { + listen 443; + server_name www.{{ pillar.hostname }}; + + ssl on; + ssl_certificate /etc/certs/{{ pillar.hostname }}.crt; + ssl_certificate_key /etc/certs/{{ pillar.hostname }}.key; + + rewrite ^(.*) https://{{ pillar.hostname }}$1 permanent; + } + server { + listen 443; + server_name {{ pillar.hostname }} *.{{ pillar.hostname }}; + + ssl on; + ssl_certificate /etc/certs/{{ pillar.hostname }}.crt; + ssl_certificate_key /etc/certs/{{ pillar.hostname }}.key; + + location ~* /favicon.ico { + root /var/www/snipt/static/img/; + expires max; + } + + location / { + rewrite_by_lua ' + if string.find(ngx.var.host, "_") then + local newHost, n = ngx.re.gsub(ngx.var.host, "_", "-") + ngx.redirect(ngx.var.scheme .. "://" .. newHost .. ngx.var.uri) + end + '; + proxy_pass http://backend_snipt; + proxy_set_header Host $host; + } + + location /static/ { + alias /var/www/snipt/static/; + expires max; + } + + location /public/feed/ { + rewrite ^/public/feed/$ https://{{ pillar.hostname }}/public/?rss permanent; + } + } + server { + listen 80 default_server; + + location / { + proxy_pass http://backend_snipt; + proxy_set_header Host $host; + } + + location /static/ { + alias /var/www/snipt/static/; + expires max; + } + location ~* /favicon.ico { + root /var/www/snipt/static/img/; + expires max; + } + } +{% else %} + server { + listen 80 default_server; + + location / { + proxy_pass http://backend_snipt; + proxy_set_header Host $host; + } + + location /static/ { + alias /var/www/snipt/media/; + expires max; + } + location ~* /favicon.ico { + root /var/www/snipt/media/img/; + expires max; + } + } +{% endif %} diff --git a/salt/application/snipt.supervisor.conf b/salt/application/snipt.supervisor.conf new file mode 100644 index 0000000..1a63a53 --- /dev/null +++ b/salt/application/snipt.supervisor.conf @@ -0,0 +1,7 @@ +[program:snipt] +directory=/var/www/snipt +user={{ pillar.deploy_user }} +command={% if pillar.env_name != 'vagrant' %}/var/www/.virtualenvs/snipt/bin/python manage.py run_gunicorn -c /var/www/snipt/gunicorn.conf.py{% else %}/var/www/.virtualenvs/snipt/bin/python manage.py runserver{% endif %} +autostart=true +autorestart=true +environment=NODE_ENV=production diff --git a/salt/cron/init.sls b/salt/cron/init.sls new file mode 100644 index 0000000..e69de29 diff --git a/salt/elasticsearch/init.sls b/salt/elasticsearch/init.sls new file mode 100644 index 0000000..e627341 --- /dev/null +++ b/salt/elasticsearch/init.sls @@ -0,0 +1,24 @@ +elasticsearch-file: + file.managed: + - name: /tmp/elasticsearch-1.3.4.deb + - source: https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.3.4.deb + - unless: test -d /usr/local/elasticsearch/bin + - source_hash: sha1=6a4b6a12825f141245bb581c76052464d17de874 + +elasticsearch-install: + cmd: + - cwd: /tmp + - names: + - dpkg -i elasticsearch-1.3.4.deb + - unless: test -d /usr/local/elasticsearch/bin + - run + - require: + - file: elasticsearch-file + +elasticsearch: + service: + - running + - enable: True + - reload: True + - require: + - file: elasticsearch-file diff --git a/salt/fish/config.fish b/salt/fish/config.fish new file mode 100644 index 0000000..1ecb39e --- /dev/null +++ b/salt/fish/config.fish @@ -0,0 +1,103 @@ +# Directories {{{ + +function l + tree --dirsfirst -ChFL 1 $args +end +function ll + tree --dirsfirst -ChFupDaL 1 $args +end + +# }}} +# Directories {{{ + +set -g -x fish_greeting '' +set -g -x EDITOR vim + +# }}} +# Git and Mercurial functions {{{ + +function gca + git commit -a $argv +end +function gco + git checkout $argv +end +function gd + git diff HEAD +end +function gl + git pull $argv +end +function gp + git push $argv +end +function gst + git status $argv +end + +# }}} +# Programs {{{ + +function logs + sudo supervisorctl tail -f snipt stdout +end +function pm + python manage.py $argv +end +function run + sudo supervisorctl restart snipt + sudo supervisorctl tail -f snipt stdout +end +function rs + sudo supervisorctl restart snipt +end +function ssc + sudo supervisorctl $argv +end +function wo + workon (cat .venv) $argv +end + +# }}} +# Prompt {{{ + +set -x fish_color_command 005fd7\x1epurple +set -x fish_color_search_match --background=purple + +function prompt_pwd --description 'Print the current working directory, shortend to fit the prompt' + echo $PWD | sed -e "s|^$HOME|~|" +end + +function virtualenv_prompt + if [ -n "$VIRTUAL_ENV" ] + printf '\033[0;37m(%s) ' (basename "$VIRTUAL_ENV") $argv + end +end + +function fish_prompt + z --add "$PWD" + echo ' ' + printf '\033[0;31m%s\033[0;37m on ' (whoami) + printf '\033[0;31m%s ' (hostname -f) + printf '\033[0;32m%s' (prompt_pwd) + echo + virtualenv_prompt + printf '\033[0;37m> ' +end + +# }}} +# Virtualenv {{{ + +set -x WORKON_HOME '/var/www/.virtualenvs' +source ~/.config/fish/virtualenv.fish + +# }}} +# Z {{{ + +source /etc/z.fish + +function j + z $argv +end + +# }}} diff --git a/salt/fish/init.sls b/salt/fish/init.sls new file mode 100644 index 0000000..7178fce --- /dev/null +++ b/salt/fish/init.sls @@ -0,0 +1,35 @@ +fish: + pkgrepo.managed: + - ppa: fish-shell/release-2 + - require_in: + - pkg: fish + pkg.latest: + - name: fish + - refresh: True + +/etc/z.fish: + file.managed: + - source: salt://fish/z.fish + - mode: 755 + +{% for user in pillar.users %} + +fish-{{ user.name }}: + file.managed: + - name: /home/{{ user.name }}/.config/fish/config.fish + - user: {{ user.name }} + - source: salt://fish/config.fish + - makedirs: True + - require: + - user: {{ user.name }} + +fish-{{ user.name }}-virtualenv: + file.managed: + - name: /home/{{ user.name }}/.config/fish/virtualenv.fish + - user: {{ user.name }} + - source: salt://fish/virtualenv.fish + - makedirs: True + - require: + - user: {{ user.name }} + +{% endfor %} diff --git a/salt/fish/virtualenv.fish b/salt/fish/virtualenv.fish new file mode 100644 index 0000000..4872dcc --- /dev/null +++ b/salt/fish/virtualenv.fish @@ -0,0 +1,46 @@ +# mostly from http://coderseye.com/2010/using-virtualenv-with-fish-shell.html + +function workon -d "Activate virtual environment in $WORKON_HOME" + set tgt {$WORKON_HOME}/$argv[1] + + if [ ! -d $tgt ] + mkdir -p "$WORKON_HOME" + virtualenv $tgt + end + + if [ -d $tgt ] + cd $tgt + + deactivate + + set -gx VIRTUAL_ENV "$tgt" + set -gx _OLD_VIRTUAL_PATH $PATH + set -gx PATH "$VIRTUAL_ENV/bin" $PATH + + # unset PYTHONHOME if set + if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME + end + + cd - + echo "activated $tgt" + else + echo "$tgt not found" + end +end + +complete -c workon -a "(cd $WORKON_HOME; ls -d *)" + +function deactivate -d "Exit virtualenv and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + set -e VIRTUAL_ENV +end diff --git a/salt/fish/z.fish b/salt/fish/z.fish new file mode 100644 index 0000000..e1a239f --- /dev/null +++ b/salt/fish/z.fish @@ -0,0 +1,195 @@ +# maintains a jump-list of the directories you actually use +# +# INSTALL: +# * put something like this in your config.fish: +# . /path/to/z.fish +# * put something like this in your fish_prompt function: +# z --add "$PWD" +# * cd around for a while to build up the db +# * PROFIT!! +# +# USE: +# * z foo # goes to most frecent dir matching foo +# * z foo bar # goes to most frecent dir matching foo and bar +# * z -r foo # goes to highest ranked dir matching foo +# * z -t foo # goes to most recently accessed dir matching foo +# * z -l foo # list all dirs matching foo (by frecency) + +function z -d "Jump to a recent directory." + set -l datafile "$HOME/.z" + + # add entries + if [ "$argv[1]" = "--add" ] + set -e argv[1] + + # $HOME isn't worth matching + [ "$argv" = "$HOME" ]; and return + + set -l tempfile (mktemp $datafile.XXXXXX) + test -f $tempfile; or return + + # maintain the file + awk -v path="$argv" -v now=(date +%s) -F"|" ' + BEGIN { + rank[path] = 1 + time[path] = now + } + $2 >= 1 { + if( $1 == path ) { + rank[$1] = $2 + 1 + time[$1] = now + } else { + rank[$1] = $2 + time[$1] = $3 + } + count += $2 + } + END { + if( count > 1000 ) { + for( i in rank ) print i "|" 0.9*rank[i] "|" time[i] # aging + } else for( i in rank ) print i "|" rank[i] "|" time[i] + } + ' $datafile ^/dev/null > $tempfile + + mv -f $tempfile $datafile + + # tab completion + else + if [ "$argv[1]" = "--complete" ] + awk -v q="$argv[2]" -F"|" ' + BEGIN { + if( q == tolower(q) ) nocase = 1 + split(q,fnd," ") + } + { + if( system("test -d \"" $1 "\"") ) next + if( nocase ) { + for( i in fnd ) tolower($1) !~ tolower(fnd[i]) && $1 = "" + if( $1 ) print $1 + } else { + for( i in fnd ) $1 !~ fnd[i] && $1 = "" + if( $1 ) print $1 + } + } + ' "$datafile" 2>/dev/null + + else + # list/go + set -l last '' + set -l list 0 + set -l typ '' + set -l fnd '' + + while [ (count $argv) -gt 0 ] + switch "$argv[1]" + case -- '-h' + echo "z [-h][-l][-r][-t] args" >&2 + return + case -- '-l' + set list 1 + case -- '-r' + set typ "rank" + case -- '-t' + set typ "recent" + case -- '--' + while [ "$argv[1]" ] + set -e argv[1] + set fnd "$fnd $argv[1]" + end + case '*' + set fnd "$fnd $argv[1]" + end + set last $1 + set -e argv[1] + end + + [ "$fnd" ]; or set list 1 + + # if we hit enter on a completion just go there + [ -d "$last" ]; and cd "$last"; and return + + # no file yet + [ -f "$datafile" ]; or return + + set -l tempfile (mktemp $datafile.XXXXXX) + test -f $tempfile; or return + set -l target (awk -v t=(date +%s) -v list="$list" -v typ="$typ" -v q="$fnd" -v tmpfl="$tempfile" -F"|" ' + function frecent(rank, time) { + dx = t-time + if( dx < 3600 ) return rank*4 + if( dx < 86400 ) return rank*2 + if( dx < 604800 ) return rank/2 + return rank/4 + } + function output(files, toopen, override) { + if( list ) { + if( typ == "recent" ) { + cmd = "sort -nr >&2" + } else cmd = "sort -n >&2" + for( i in files ) if( files[i] ) printf "%-10s %s\n", files[i], i | cmd + if( override ) printf "%-10s %s\n", "common:", override > "/dev/stderr" + } else { + if( override ) toopen = override + print toopen + } + } + function common(matches, fnd, nc) { + for( i in matches ) { + if( matches[i] && (!short || length(i) < length(short)) ) short = i + } + if( short == "/" ) return + for( i in matches ) if( matches[i] && i !~ short ) x = 1 + if( x ) return + if( nc ) { + for( i in fnd ) if( tolower(short) !~ tolower(fnd[i]) ) x = 1 + } else for( i in fnd ) if( short !~ fnd[i] ) x = 1 + if( !x ) return short + } + BEGIN { split(q, a, " ") } + { + if( system("test -d \"" $1 "\"") ) next + print $0 >> tmpfl + if( typ == "rank" ) { + f = $2 + } else if( typ == "recent" ) { + f = t-$3 + } else f = frecent($2, $3) + wcase[$1] = nocase[$1] = f + for( i in a ) { + if( $1 !~ a[i] ) delete wcase[$1] + if( tolower($1) !~ tolower(a[i]) ) delete nocase[$1] + } + if( wcase[$1] > oldf ) { + cx = $1 + oldf = wcase[$1] + } else if( nocase[$1] > noldf ) { + ncx = $1 + noldf = nocase[$1] + } + } + END { + if( cx ) { + output(wcase, cx, common(wcase, a, 0)) + } else if( ncx ) output(nocase, ncx, common(nocase, a, 1)) + } + ' "$datafile") + + if [ $status -gt 0 ] + rm -f "$tempfile" + else + mv -f "$tempfile" "$datafile" + [ "$target" ]; and cd "$target" + end + end + end +end + +function __z_init -d 'Set up automatic population of the directory list for z' + functions fish_prompt | grep -q 'z --add' + if [ $status -gt 0 ] + functions fish_prompt | sed -e '$ i\\ + z --add "$PWD"' | . + end +end + +__z_init diff --git a/salt/iptables/init.sls b/salt/iptables/init.sls new file mode 100644 index 0000000..7e8fd1a --- /dev/null +++ b/salt/iptables/init.sls @@ -0,0 +1,27 @@ +/etc/iptables.up.rules: + file.managed: + - source: salt://iptables/iptables.up.rules + - template: jinja + - require: + - pkg: iptables + +flush-iptables: + cmd.run: + - names: + - /sbin/iptables -F + - /sbin/iptables-restore < /etc/iptables.up.rules + - watch: + - file: /etc/iptables.up.rules + - require: + - pkg: iptables + +/etc/network/if-pre-up.d/iptables: + file.managed: + - mode: 644 + - source: salt://iptables/iptables-restore.sh + - require: + - pkg: iptables + cmd.run: + - name: chmod +x /etc/network/if-pre-up.d/iptables + - require: + - pkg: iptables diff --git a/salt/iptables/iptables-restore.sh b/salt/iptables/iptables-restore.sh new file mode 100644 index 0000000..4a17ae8 --- /dev/null +++ b/salt/iptables/iptables-restore.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sudo sh -c '/sbin/iptables-restore < /etc/iptables.up.rules' diff --git a/salt/iptables/iptables.up.rules b/salt/iptables/iptables.up.rules new file mode 100644 index 0000000..d490618 --- /dev/null +++ b/salt/iptables/iptables.up.rules @@ -0,0 +1,43 @@ +*filter + + +# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0 +-A INPUT -i lo -j ACCEPT +-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT + + +# Accepts all established inbound connections +-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + + +# Allows all outbound traffic +# You can modify this to only allow certain traffic +-A OUTPUT -j ACCEPT + + +# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites) +-A INPUT -p tcp --dport 80 -j ACCEPT +-A INPUT -p tcp --dport 443 -j ACCEPT + + +# Allows SSH connections +# +# THE -dport NUMBER IS THE SAME ONE YOU SET UP IN THE SSHD_CONFIG FILE +# +-A INPUT -p tcp -m state --state NEW --dport {{ pillar.ssh.port }} -j ACCEPT + + +# Allow ping +-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT + + +# log iptables denied calls +-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 + + +# Reject all other inbound - default deny unless explicitly allowed policy +-A INPUT -j REJECT +-A FORWARD -j REJECT + + +COMMIT diff --git a/salt/nginx/init.sls b/salt/nginx/init.sls new file mode 100644 index 0000000..0c8e637 --- /dev/null +++ b/salt/nginx/init.sls @@ -0,0 +1,42 @@ +nginx: + pkg: + - installed + service: + - running + - enable: True + - watch: + - file: /etc/nginx/nginx.conf + - file: /etc/nginx/sites-enabled/* + +/etc/nginx/sites-available: + file.directory: + - mode: 755 + - require: + - pkg: nginx + +/etc/nginx/sites-enabled: + file.directory: + - mode: 755 + - require: + - pkg: nginx + +{% if pillar.env_name != 'vagrant' %} + +/etc/certs: + file.directory: + - mode: 644 + - require: + - pkg: nginx + +{% endif %} + +/etc/nginx/nginx.conf: + file.managed: + - source: salt://nginx/nginx.conf + - mode: 400 + - template: jinja + - require: + - pkg: nginx + +/etc/nginx/sites-enabled/default: + file.absent diff --git a/salt/nginx/nginx.conf b/salt/nginx/nginx.conf new file mode 100644 index 0000000..238d30c --- /dev/null +++ b/salt/nginx/nginx.conf @@ -0,0 +1,26 @@ +user {% if pillar.env_name == 'vagrant' %}vagrant{% else %}www-data{% endif %}; +worker_processes 4; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + + keepalive_timeout 65; + + gzip on; + gzip_disable "msie6"; + gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; + + include /etc/nginx/sites-enabled/*; + + types_hash_max_size 4096; + server_names_hash_bucket_size 64; +} diff --git a/salt/postgresql/init.sls b/salt/postgresql/init.sls new file mode 100644 index 0000000..0c21eb2 --- /dev/null +++ b/salt/postgresql/init.sls @@ -0,0 +1,29 @@ +postgresql: + pkg: + - installed + service.running: + - watch: + - file: /etc/postgresql/9.3/main/pg_hba.conf + - require: + - pkg: postgresql + +pg_hba.conf: + file.managed: + - name: /etc/postgresql/9.3/main/pg_hba.conf + - source: salt://postgresql/pg_hba.conf + - user: postgres + - group: postgres + - mode: 644 + - require: + - pkg: postgresql + +postgresql.conf: + file.managed: + - name: /etc/postgresql/9.3/main/postgresql.conf + - source: salt://postgresql/postgresql.conf + - template: jinja + - user: postgres + - group: postgres + - mode: 644 + - require: + - pkg: postgresql diff --git a/salt/postgresql/pg_hba.conf b/salt/postgresql/pg_hba.conf new file mode 100644 index 0000000..743fa9c --- /dev/null +++ b/salt/postgresql/pg_hba.conf @@ -0,0 +1,99 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: "local" is a Unix-domain +# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, +# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a +# plain TCP/IP socket. +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", +# "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert". Note that +# "password" sends passwords in clear text; "md5" is preferred since +# it sends encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# This file is read on server startup and when the postmaster receives +# a SIGHUP signal. If you edit the file on a running system, you have +# to SIGHUP the postmaster for the changes to take effect. You can +# use "pg_ctl reload" to do that. + +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + + + + +# DO NOT DISABLE! +# If you change this first entry you will need to make sure that the +# database superuser can access the database using some other method. +# Noninteractive access to all databases is required during automatic +# maintenance (custom daily cronjobs, replication, and similar tasks). +# +# Database administrative login by Unix domain socket +local all postgres peer + +# TYPE DATABASE USER ADDRESS METHOD + +# "local" is for Unix domain socket connections only +local all all peer +# IPv4 local connections: +host all all 127.0.0.1/32 md5 +# IPv6 local connections: +host all all ::1/128 md5 +# Allow replication connections from localhost, by a user with the +# replication privilege. +#local replication postgres peer +#host replication postgres 127.0.0.1/32 md5 +#host replication postgres ::1/128 md5 diff --git a/salt/postgresql/postgresql.conf b/salt/postgresql/postgresql.conf new file mode 100644 index 0000000..c69ca26 --- /dev/null +++ b/salt/postgresql/postgresql.conf @@ -0,0 +1,596 @@ +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, or use "pg_ctl reload". Some +# parameters, which are marked below, require a server shutdown and restart to +# take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: kB = kilobytes Time units: ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +data_directory = '/var/lib/postgresql/9.3/main' # use data in another directory + # (change requires restart) +hba_file = '/etc/postgresql/9.3/main/pg_hba.conf' # host-based authentication file + # (change requires restart) +ident_file = '/etc/postgresql/9.3/main/pg_ident.conf' # ident configuration file + # (change requires restart) + +# If external_pid_file is not explicitly set, no extra PID file is written. +external_pid_file = '/var/run/postgresql/9.3-main.pid' # write an extra PID file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +#listen_addresses = 'localhost' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +port = 5432 # (change requires restart) +max_connections = 100 # (change requires restart) +# Note: Increasing max_connections costs ~400 bytes of shared memory per +# connection slot, plus lock space (see max_locks_per_transaction). +#superuser_reserved_connections = 3 # (change requires restart) +unix_socket_directories = '/var/run/postgresql' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - Security and Authentication - + +#authentication_timeout = 1min # 1s-600s +ssl = true # (change requires restart) +#ssl_ciphers = 'DEFAULT:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers + # (change requires restart) +#ssl_renegotiation_limit = 512MB # amount of data between renegotiations +ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' # (change requires restart) +ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' # (change requires restart) +#ssl_ca_file = '' # (change requires restart) +#ssl_crl_file = '' # (change requires restart) +#password_encryption = on +#db_user_namespace = off + +# Kerberos and GSSAPI +#krb_server_keyfile = '' +#krb_srvname = 'postgres' # (Kerberos only) +#krb_caseins_users = off + +# - TCP Keepalives - +# see "man 7 tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +shared_buffers = 128MB # min 128kB + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory +# per transaction slot, plus lock space (see max_locks_per_transaction). +# It is not advisable to set max_prepared_transactions nonzero unless you +# actively intend to use prepared transactions. +#work_mem = 1MB # min 64kB +#maintenance_work_mem = 16MB # min 1MB +#max_stack_depth = 2MB # min 100kB + +# - Disk - + +#temp_file_limit = -1 # limits per-session temp file space + # in kB, or -1 for no limit + +# - Kernel Resource Usage - + +#max_files_per_process = 1000 # min 25 + # (change requires restart) +#shared_preload_libraries = '' # (change requires restart) + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds +#vacuum_cost_page_hit = 1 # 0-10000 credits +#vacuum_cost_page_miss = 10 # 0-10000 credits +#vacuum_cost_page_dirty = 20 # 0-10000 credits +#vacuum_cost_limit = 200 # 1-10000 credits + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # 0-1000 max buffers written/round +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multipler on buffers scanned/round + +# - Asynchronous Behavior - + +#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching + + +#------------------------------------------------------------------------------ +# WRITE AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = minimal # minimal, archive, or hot_standby + # (change requires restart) +#fsync = on # turns forced synchronization on or off +#synchronous_commit = on # synchronization level; + # off, local, remote_write, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux) + # fsync + # fsync_writethrough + # open_sync +#full_page_writes = on # recover from partial page writes +#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds + +#commit_delay = 0 # range 0-100000, in microseconds +#commit_siblings = 5 # range 1-1000 + +# - Checkpoints - + +#checkpoint_segments = 3 # in logfile segments, min 1, 16MB each +#checkpoint_timeout = 5min # range 30s-1h +#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 +#checkpoint_warning = 30s # 0 disables + +# - Archiving - + +#archive_mode = off # allows archiving to be done + # (change requires restart) +#archive_command = '' # command to use to archive a logfile segment + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a logfile segment switch after this + # number of seconds; 0 disables + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Server(s) - + +# Set these on the master and on any standby that will send replication data. + +#max_wal_senders = 0 # max number of walsender processes + # (change requires restart) +#wal_keep_segments = 0 # in logfile segments, 16MB each; 0 disables +#wal_sender_timeout = 60s # in milliseconds; 0 disables + +# - Master Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # comma-separated list of application_name + # from standby(s); '*' = all +#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed + +# - Standby Servers - + +# These settings are ignored on a master server. + +#hot_standby = off # "on" allows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from master + # in milliseconds; 0 disables + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_bitmapscan = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +#random_page_cost = 4.0 # same scale as above +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # same scale as above +#effective_cache_size = 128MB + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 + +# - Other Planner Options - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses + + +#------------------------------------------------------------------------------ +# ERROR REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - Where to Log - + +#log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, syslog, and eventlog, + # depending on platform. csvlog + # requires logging_collector to be on. + +# This is used when logging to stderr: +#logging_collector = off # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +#log_directory = 'pg_log' # directory where log files are written, + # can be absolute or relative to PGDATA +#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern, + # can include strftime() escapes +#log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation +#log_truncate_on_rotation = off # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. +#log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +#log_rotation_size = 10MB # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' + +# This is only relevant when logging to eventlog (win32): +#event_source = 'PostgreSQL' + +# - When to Log - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_checkpoints = off +#log_connections = off +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default # terse, default, or verbose messages +#log_hostname = off +log_line_prefix = '%t ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %p = process ID + # %t = timestamp without milliseconds + # %m = timestamp with milliseconds + # %i = command tag + # %e = SQL state + # %c = session ID + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # e.g. '<%u%%%d> ' +#log_lock_waits = off # log lock waits >= deadlock_timeout +#log_statement = 'none' # none, ddl, mod, all +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +log_timezone = 'UTC' + + +#------------------------------------------------------------------------------ +# RUNTIME STATISTICS +#------------------------------------------------------------------------------ + +# - Query/Index Statistics Collector - + +#track_activities = on +#track_counts = on +#track_io_timing = off +#track_functions = none # none, pl, all +#track_activity_query_size = 1024 # (change requires restart) +#update_process_title = on +#stats_temp_directory = 'pg_stat_tmp' + + +# - Statistics Monitoring - + +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off +#log_statement_stats = off + + +#------------------------------------------------------------------------------ +# AUTOVACUUM PARAMETERS +#------------------------------------------------------------------------------ + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum Multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#search_path = '"$user",public' # schema names +#default_tablespace = '' # a tablespace name, '' uses the default +#temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#statement_timeout = 0 # in milliseconds, 0 is disabled +#lock_timeout = 0 # in milliseconds, 0 is disabled +#vacuum_freeze_min_age = 50000000 +#vacuum_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_freeze_table_age = 150000000 +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' + +# - Locale and Formatting - + +datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +timezone = 'UTC' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia + # India + # You can create your own file in + # share/timezonesets/. +#extra_float_digits = 0 # min -15, max 3 +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +lc_messages = 'en_US.UTF-8' # locale for system error message + # strings +lc_monetary = 'en_US.UTF-8' # locale for monetary formatting +lc_numeric = 'en_US.UTF-8' # locale for number formatting +lc_time = 'en_US.UTF-8' # locale for time formatting + +# default configuration for text search +default_text_search_config = 'pg_catalog.english' + +# - Other Defaults - + +#dynamic_library_path = '$libdir' +#local_preload_libraries = '' + + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +#max_locks_per_transaction = 64 # min 10 + # (change requires restart) +# Note: Each lock table slot uses ~270 bytes of shared memory, and there are +# max_locks_per_transaction * (max_connections + max_prepared_transactions) +# lock table slots. +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) + + +#------------------------------------------------------------------------------ +# VERSION/PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#default_with_oids = off +#escape_string_warning = on +#lo_compat_privileges = off +#quote_all_identifiers = off +#sql_inheritance = on +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. + +#include_dir = 'conf.d' # include files ending in '.conf' from + # directory 'conf.d' +#include_if_exists = 'exists.conf' # include file only if it exists +#include = 'special.conf' # include file + + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here diff --git a/salt/ssh/init.sls b/salt/ssh/init.sls new file mode 100644 index 0000000..c3badc1 --- /dev/null +++ b/salt/ssh/init.sls @@ -0,0 +1,20 @@ +openssh-server: + pkg: + - installed + +/etc/ssh/sshd_config: + file.managed: + - user: root + - group: root + - mode: 644 + - source: salt://ssh/sshd_config + - template: jinja + +ssh: + service: + - running + - watch: + - file: /etc/ssh/sshd_config + - file: /etc/network/if-pre-up.d/iptables + - require: + - pkg: openssh-server diff --git a/salt/ssh/sshd_config b/salt/ssh/sshd_config new file mode 100644 index 0000000..22488df --- /dev/null +++ b/salt/ssh/sshd_config @@ -0,0 +1,90 @@ +# Package generated configuration file +# See the sshd_config(5) manpage for details + +# Use these options to restrict which interfaces/protocols sshd will bind to +#ListenAddress :: +#ListenAddress 0.0.0.0 +Protocol 2 +# HostKeys for protocol version 2 +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_dsa_key +HostKey /etc/ssh/ssh_host_ecdsa_key +#Privilege Separation is turned on for security +UsePrivilegeSeparation yes + +# Lifetime and size of ephemeral version 1 server key +KeyRegenerationInterval 3600 +ServerKeyBits 768 + +# Logging +SyslogFacility AUTH +LogLevel INFO + +# Authentication: +LoginGraceTime 120 +StrictModes yes + +RSAAuthentication yes +PubkeyAuthentication yes +#AuthorizedKeysFile %h/.ssh/authorized_keys + +# Don't read the user's ~/.rhosts and ~/.shosts files +IgnoreRhosts yes +# For this to work you will also need host keys in /etc/ssh_known_hosts +RhostsRSAAuthentication no +# similar for protocol version 2 +HostbasedAuthentication no +# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication +#IgnoreUserKnownHosts yes + +# To enable empty passwords, change to yes (NOT RECOMMENDED) +PermitEmptyPasswords no + +# Change to yes to enable challenge-response passwords (beware issues with +# some PAM modules and threads) +ChallengeResponseAuthentication no + +# Change to no to disable tunnelled clear text passwords +#PasswordAuthentication yes + +# Kerberos options +#KerberosAuthentication no +#KerberosGetAFSToken no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +X11Forwarding yes +X11DisplayOffset 10 +PrintMotd no +PrintLastLog yes +TCPKeepAlive yes +#UseLogin no + +#MaxStartups 10:30:60 +#Banner /etc/issue.net + +# Allow client to pass locale environment variables +AcceptEnv LANG LC_* + +Subsystem sftp /usr/lib/openssh/sftp-server + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the ChallengeResponseAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via ChallengeResponseAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and ChallengeResponseAuthentication to 'no'. +UsePAM yes +UseDNS no + +Port {{ pillar.ssh.port }} +PermitRootLogin no +PasswordAuthentication no +AllowUsers {% for user in pillar.users %}{{ user.name }} {% endfor %} diff --git a/salt/supervisor/init.sls b/salt/supervisor/init.sls new file mode 100644 index 0000000..34a4532 --- /dev/null +++ b/salt/supervisor/init.sls @@ -0,0 +1,35 @@ +python-pip: + pkg.installed + +supervisor: + pip.installed + +/etc/supervisord.conf: + file.managed: + - source: salt://supervisor/supervisord.conf + - mode: 755 + +/etc/init.d/supervisord: + file.managed: + - source: salt://supervisor/supervisord.init.d + - mode: 755 + +/var/log/supervisor: + file.directory + +/etc/supervisor: + file.directory + +/etc/supervisor/conf.d: + file.directory + +supervisord: + service.running: + - require: + - file: /etc/init.d/supervisord + - file: /var/log/supervisor + - watch: + - file: /etc/supervisord.conf + - file: /etc/supervisor/conf.d/* + cmd.run: + - name: update-rc.d supervisord defaults diff --git a/salt/supervisor/supervisord.conf b/salt/supervisor/supervisord.conf new file mode 100644 index 0000000..60bd772 --- /dev/null +++ b/salt/supervisor/supervisord.conf @@ -0,0 +1,17 @@ +[unix_http_server] +file = /var/run/supervisor.sock +chmod = 0700 + +[supervisord] +logfile = /var/log/supervisor/supervisord.log +pidfile = /var/run/supervisord.pid +childlogdir = /var/log/supervisor + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl = unix:///var/run/supervisor.sock + +[include] +files = /etc/supervisor/conf.d/*.conf diff --git a/salt/supervisor/supervisord.init.d b/salt/supervisor/supervisord.init.d new file mode 100644 index 0000000..76fa171 --- /dev/null +++ b/salt/supervisor/supervisord.init.d @@ -0,0 +1,187 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: supervisord +# Required-Start: $remote_fs +# Required-Stop: $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Example initscript +# Description: This file should be used to construct scripts to be +# placed in /etc/init.d. +### END INIT INFO + +# Author: Dan MacKinlay +# Based on instructions by Bertrand Mathieu +# http://zebert.blogspot.com/2009/05/installing-django-solr-varnish-and.html + +# Do NOT "set -e" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="Description of the service" +NAME=supervisord +DAEMON=/usr/local/bin/supervisord +DAEMON_ARGS="-c /etc/supervisord.conf" +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ + $DAEMON_ARGS \ + || return 2 + # Add code here, if necessary, that waits for the process to be ready + # to handle requests from services started subsequently which depend + # on this one. As a last resort, sleep for some time. +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +running_pid() +{ + # Check if a given process pid's cmdline matches a given name + pid=$1 + name=$2 + [ -z "$pid" ] && return 1 + [ ! -d /proc/$pid ] && return 1 + (cat /proc/$pid/cmdline | tr "\000" "\n"|grep -q $name) || return 1 + return 0 +} + +running() +{ +# Check if the process is running looking at /proc +# (works for all users) + + # No pidfile, probably no daemon present + [ ! -f "$PIDFILE" ] && return 1 + # Obtain the pid and check it against the binary name + pid=`cat $PIDFILE` + running_pid $pid $DAEMON || return 1 + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + echo -n "$NAME is " + if running ; then + echo "running" + else + echo "not running." + exit 1 + fi + ;; + #reload|force-reload) + # + # If do_reload() is not implemented then leave this commented out + # and leave 'force-reload' as an alias for 'restart'. + # + #log_daemon_msg "Reloading $DESC" "$NAME" + #do_reload + #log_end_msg $? + #;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: diff --git a/salt/system/init.sls b/salt/system/init.sls new file mode 100644 index 0000000..a71d31e --- /dev/null +++ b/salt/system/init.sls @@ -0,0 +1,25 @@ +build-essential: + pkg.installed: + - pkgs: + - build-essential + +iptables: + pkg.installed: + - pkgs: + - iptables + +system: + pkg.installed: + - pkgs: + - cmake + - curl + - exuberant-ctags + - git + - htop + - libpq-dev + - libxml2-dev + - libxslt1-dev + - mercurial + - python-dev + - tree + - openjdk-7-jdk diff --git a/salt/top.sls b/salt/top.sls new file mode 100644 index 0000000..47019bf --- /dev/null +++ b/salt/top.sls @@ -0,0 +1,13 @@ +base: + '*': + - system + - iptables + - ssh + - users + - fish + - elasticsearch + - postgresql + - nginx + - supervisor + - application + - cron diff --git a/salt/users/deploy.authorized_keys b/salt/users/deploy.authorized_keys new file mode 100644 index 0000000..d5054e6 --- /dev/null +++ b/salt/users/deploy.authorized_keys @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAKzhHc1iq/4P/kFcqnMFy/oP7fFOwDQjaKrQPGmMC1X19vb3AUjzyAKVbf4WolBDsnc2U8p9memnM1xfZ/s7VM2RRQMbAwgp0la5D/fVAhNd5cubeHlQlowt/6TFAUVISJVAyIEVs+zdb5gYtm9Bowsf/+8bV+JYG/bniIcTPKwXAAAAFQChvjdSMM4rgZ3CVECrLHOVFdyYTQAAAIBzB0z/gOTBB/CQ9mfo05b5Doplkxd+HYIyaLjNErs0R1WVkbIlFInvxeBsUWKv/t8yuwKwP4UuWzFzE+RS+WYzakd3H2WJryTnVEhyfhQGqyFvSnixqrHylJPNu14RAC2lMZFgJMOwJ9Rsw5YNgNnptwCj50sc5u49uadjoAUKYgAAAIAB7IRBOI+/iKDgeDU1fs8TuNkXKd8piP3zuEac/sgF/GzxCrTXM89yWPlWtVF/b76i5DLkdORFS0jKOILGOCCGoGnxvGuUfnB4IcvQIBJ4GVpSTaiVzq+nYgO6IelUKo2Zh7R8jYjvoOZulPZP7EwpaaAfYlWEbwPddqvX7OfiHg== nick@nicksergeant.com diff --git a/salt/users/init.sls b/salt/users/init.sls new file mode 100644 index 0000000..737f305 --- /dev/null +++ b/salt/users/init.sls @@ -0,0 +1,58 @@ +deploy-group: + group.present: + - name: deploy + +wheel-group: + group.present: + - name: wheel + +{% for user in pillar.users %} + +{{ user.name }}: + user.present: + - name: {{ user.name }} + - home: /home/{{ user.name }} + - groups: {{ user.groups }} + - require: + {% for group in user.groups %} + - group: {{ group }} + {% endfor %} + - pkg: fish + - shell: /usr/bin/fish + ssh_auth.present: + - user: {{ user.name }} + {% if user.name != 'vagrant' and user.name != 'deploy' %} + - source: salt://users/{{ user.name }}.pub + {% endif %} + - makedirs: True + +{% endfor %} + +{% if pillar.env_name != 'vagrant' %} + +deploy-authorized-keys: + file.managed: + - name: /home/deploy/.ssh/authorized_keys + - user: deploy + - group: deploy + - mode: 600 + - source: salt://users/deploy.authorized_keys + - makedirs: True + - require: + - user: deploy + +deploy-known-hosts: + file.managed: + - name: /home/deploy/.ssh/known_hosts + - user: deploy + - group: deploy + - mode: 700 + - source: salt://users/known_hosts + - makedirs: True + +{% endif %} + +/etc/sudoers: + file.managed: + - source: salt://users/sudoers + - mode: 440 diff --git a/salt/users/known_hosts b/salt/users/known_hosts new file mode 100644 index 0000000..de142d2 --- /dev/null +++ b/salt/users/known_hosts @@ -0,0 +1 @@ +github.com,207.97.227.239 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== diff --git a/salt/users/nick.pub b/salt/users/nick.pub new file mode 100644 index 0000000..d5054e6 --- /dev/null +++ b/salt/users/nick.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAKzhHc1iq/4P/kFcqnMFy/oP7fFOwDQjaKrQPGmMC1X19vb3AUjzyAKVbf4WolBDsnc2U8p9memnM1xfZ/s7VM2RRQMbAwgp0la5D/fVAhNd5cubeHlQlowt/6TFAUVISJVAyIEVs+zdb5gYtm9Bowsf/+8bV+JYG/bniIcTPKwXAAAAFQChvjdSMM4rgZ3CVECrLHOVFdyYTQAAAIBzB0z/gOTBB/CQ9mfo05b5Doplkxd+HYIyaLjNErs0R1WVkbIlFInvxeBsUWKv/t8yuwKwP4UuWzFzE+RS+WYzakd3H2WJryTnVEhyfhQGqyFvSnixqrHylJPNu14RAC2lMZFgJMOwJ9Rsw5YNgNnptwCj50sc5u49uadjoAUKYgAAAIAB7IRBOI+/iKDgeDU1fs8TuNkXKd8piP3zuEac/sgF/GzxCrTXM89yWPlWtVF/b76i5DLkdORFS0jKOILGOCCGoGnxvGuUfnB4IcvQIBJ4GVpSTaiVzq+nYgO6IelUKo2Zh7R8jYjvoOZulPZP7EwpaaAfYlWEbwPddqvX7OfiHg== nick@nicksergeant.com diff --git a/salt/users/sudoers b/salt/users/sudoers new file mode 100644 index 0000000..1473efd --- /dev/null +++ b/salt/users/sudoers @@ -0,0 +1,32 @@ +# +# This file MUST be edited with the 'visudo' command as root. +# +# Please consider adding local content in /etc/sudoers.d/ instead of +# directly modifying this file. +# +# See the man page for details on how to write a sudoers file. +# +Defaults env_reset +Defaults exempt_group=admin +Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + +# Host alias specification + +# User alias specification + +# Cmnd alias specification + +# User privilege specification +root ALL=(ALL:ALL) ALL + +# Members of the admin group may gain root privileges +%admin ALL=(ALL) NOPASSWD:ALL + +# Allow members of group sudo to execute any command +%sudo ALL=(ALL:ALL) ALL + +# See sudoers(5) for more information on "#include" directives: + +#includedir /etc/sudoers.d + +%wheel ALL=(ALL) NOPASSWD:ALL diff --git a/settings.py b/settings.py index c25d9fe..3a4174f 100644 --- a/settings.py +++ b/settings.py @@ -21,23 +21,6 @@ if 'DATABASE_URL' in os.environ: if es.username: HAYSTACK_CONNECTIONS['default']['KWARGS'] = {"http_auth": es.username + ':' + es.password} -else: - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'snipt', - 'USER': '', - 'PASSWORD': '', - 'HOST': 'localhost', - 'PORT': '' - } - } - HAYSTACK_CONNECTIONS = { - 'default': { - 'ENGINE': 'haystack.backends.simple_backend.SimpleEngine', - }, - } - ABSOLUTE_URL_OVERRIDES = { 'auth.user': lambda u: "/%s/" % u.username, } ACCOUNT_ACTIVATION_DAYS = 0 ADMINS = (('Nick Sergeant', 'nick@snipt.net'),) @@ -74,8 +57,9 @@ SESSION_COOKIE_SECURE = True if 'USE_SSL' in os.environ else False SITE_ID = 1 STATICFILES_DIRS = (os.path.join(BASE_PATH, 'media'),) STATICFILES_FINDERS = ('django.contrib.staticfiles.finders.FileSystemFinder','django.contrib.staticfiles.finders.AppDirectoriesFinder',) +STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage' STATIC_ROOT = os.path.join(BASE_PATH, 'static') -STATIC_URL = 'https://snipt.s3.amazonaws.com/' +STATIC_URL = '/static/' TASTYPIE_CANNED_ERROR = "There was an error with your request. The site developers have a record of this error, please email api@snipt.net and we'll help you out." TEMPLATE_DIRS = (os.path.join(PROJECT_PATH, 'templates'),) TEMPLATE_DEBUG = DEBUG diff --git a/settings_local.py-template b/settings_local.py-template index 07d8226..a80fa1c 100644 --- a/settings_local.py-template +++ b/settings_local.py-template @@ -1,8 +1,28 @@ -AWS_ACCESS_KEY_ID = '' -AWS_SECRET_ACCESS_KEY = '' -AWS_STORAGE_BUCKET_NAME = '' -DEBUG=True -S3_URL = 'https://%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME +CSRF_COOKIE_SECURE = False +DEBUG = True +INTERCOM_SECRET_KEY = '' +POSTMARK_API_KEY = '' +RAVEN_CONFIG = { 'dsn': '' } +SECRET_KEY = 'changeme' +SESSION_COOKIE_SECURE = False SSLIFY_DISABLE = True -STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage' -STATIC_URL = '/static/' +STRIPE_SECRET_KEY = '' +USE_HTTPS = False + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'snipt', + 'USER': 'snipt', + 'PASSWORD': 'password', + 'HOST': 'localhost', + 'PORT': '' + } +} +HAYSTACK_CONNECTIONS = { + 'default': { + 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', + 'URL': 'http://127.0.0.1:9200/', + 'INDEX_NAME': 'haystack', + }, +} diff --git a/snipts/models.py b/snipts/models.py index 22e6b59..15c0d33 100644 --- a/snipts/models.py +++ b/snipts/models.py @@ -15,7 +15,7 @@ from pygments.formatters import HtmlFormatter from snipts.utils import slugify_uniquely -import datetime, md5, random, re +import datetime, hashlib, random, re class Snipt(models.Model): @@ -52,7 +52,7 @@ class Snipt(models.Model): self.slug = slugify_uniquely(self.title, Snipt) if not self.key: - self.key = md5.new(self.slug + str(datetime.datetime.now()) + str(random.random())).hexdigest() + self.key = hashlib.md5(self.slug + str(datetime.datetime.now()) + str(random.random())).hexdigest() if self.lexer == 'markdown': self.stylized = markdown(self.code, 'default') @@ -168,7 +168,7 @@ class Snipt(models.Model): return u'https://{}.snipt.net/{}/'.format(self.user.username, self.slug) if settings.DEBUG: - root = 'http://snipt.localhost' + root = 'http://local.snipt.net' else: root = 'https://snipt.net' @@ -193,7 +193,7 @@ class Snipt(models.Model): filename = u'{}.txt'.format(self.slug) if settings.DEBUG: - root = 'http://snipt.localhost' + root = 'http://local.snipt.net' else: root = 'https://snipt.net' @@ -202,7 +202,7 @@ class Snipt(models.Model): def get_embed_url(self): if settings.DEBUG: - root = 'http://snipt.localhost' + root = 'http://local.snipt.net' else: root = 'https://snipt.net' @@ -211,7 +211,7 @@ class Snipt(models.Model): def get_raw_url(self): if settings.DEBUG: - root = 'http://snipt.localhost' + root = 'http://local.snipt.net' else: root = 'https://snipt.net' diff --git a/utils/templatetags/intercom.py b/utils/templatetags/intercom.py index b1bdade..8fc76c2 100644 --- a/utils/templatetags/intercom.py +++ b/utils/templatetags/intercom.py @@ -1,3 +1,4 @@ +from django.conf import settings from django import template import hmac, hashlib, os @@ -6,4 +7,4 @@ register = template.Library() @register.filter def intercom_sha_256(user_id): - return hmac.new(os.environ.get('INTERCOM_SECRET_KEY', ''), str(user_id), digestmod=hashlib.sha256).hexdigest() + return hmac.new(os.environ.get('INTERCOM_SECRET_KEY', settings.INTERCOM_SECRET_KEY), str(user_id), digestmod=hashlib.sha256).hexdigest() diff --git a/views.py b/views.py index ffb8507..c12b910 100644 --- a/views.py +++ b/views.py @@ -103,7 +103,7 @@ def pro_complete(request): if request.method == 'POST': token = request.POST['token'] - stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', '') + stripe.api_key = os.environ.get('STRIPE_SECRET_KEY', settings.STRIPE_SECRET_KEY) try: customer = stripe.Customer.create(email=request.user.email,