diff --git a/Makefile b/Makefile index 724ab66a7be..eb4bddef943 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,6 @@ package_cloud: package_cloud push dokku/dokku/ubuntu/trusty herokuish*.deb package_cloud push dokku/dokku/ubuntu/trusty sshcommand*.deb package_cloud push dokku/dokku/ubuntu/trusty plugn*.deb - package_cloud push dokku/dokku/ubuntu/trusty rubygem*.deb package_cloud push dokku/dokku/ubuntu/trusty dokku*.deb packer: @@ -140,12 +139,7 @@ count: @find tests -type f -not -name .DS_Store | xargs cat | sed 's/^$$//g' | wc -l dokku-installer: - apt-get install -qq -y ruby - test -f /var/lib/dokku/.dokku-installer-created || gem install rack -v 1.5.2 --no-rdoc --no-ri - test -f /var/lib/dokku/.dokku-installer-created || gem install rack-protection -v 1.5.3 --no-rdoc --no-ri - test -f /var/lib/dokku/.dokku-installer-created || gem install sinatra -v 1.4.5 --no-rdoc --no-ri - test -f /var/lib/dokku/.dokku-installer-created || gem install tilt -v 1.4.1 --no-rdoc --no-ri - test -f /var/lib/dokku/.dokku-installer-created || ruby contrib/dokku-installer.rb onboot + test -f /var/lib/dokku/.dokku-installer-created || python contrib/dokku-installer.py onboot test -f /var/lib/dokku/.dokku-installer-created || service dokku-installer start test -f /var/lib/dokku/.dokku-installer-created || service nginx reload test -f /var/lib/dokku/.dokku-installer-created || touch /var/lib/dokku/.dokku-installer-created diff --git a/contrib/dokku-installer.py b/contrib/dokku-installer.py new file mode 100755 index 00000000000..fe76cf63bb4 --- /dev/null +++ b/contrib/dokku-installer.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python2.7 + +import cgi +import json +import os +import SimpleHTTPServer +import SocketServer +import subprocess +import sys +import threading + +VERSION = 'v0.4.6' + +hostname = '' +try: + command = "bash -c '[[ $(dig +short $HOSTNAME) ]] && echo $HOSTNAME || wget -q -O - icanhazip.com'" + hostname = subprocess.check_output(command, shell=True) + if ':' in hostname: + hostname = '' +except subprocess.CalledProcessError: + pass + +key_file = os.getenv('KEY_FILE', '/root/.ssh/authorized_keys') + +admin_keys = [] +if os.path.isfile(key_file): + try: + command = "cat {0}".format(key_file) + admin_keys = subprocess.check_output(command, shell=True).strip().split("\n") + except subprocess.CalledProcessError: + pass + + +def check_boot(): + if 'onboot' not in sys.argv: + return + init_dir = os.getenv('INIT_DIR', '/etc/init') + systemd_dir = os.getenv('SYSTEMD_DIR', '/etc/systemd/system') + nginx_dir = os.getenv('NGINX_DIR', '/etc/nginx/conf.d') + + if os.path.exists(init_dir): + with open('{0}/dokku-installer.conf'.format(init_dir), 'w') as f: + f.write("start on runlevel [2345]\n") + f.write("exec {0} selfdestruct\n".format(os.path.abspath(__file__))) + if os.path.exists(systemd_dir): + with open('{0}/dokku-installer.service'.format(systemd_dir), 'w') as f: + f.write("[Unit]\n") + f.write("Description=Dokku web-installer\n") + f.write("\n") + f.write("[Service]\n") + f.write("ExecStart=#{File.absolute_path(__FILE__)} selfdestruct\n") + f.write("\n") + f.write("[Install]\n") + f.write("WantedBy=multi-user.target\n") + f.write("WantedBy=graphical.target\n") + if os.path.exists(nginx_dir): + with open('{0}/dokku-installer.conf'.format(nginx_dir), 'w') as f: + f.write("upstream dokku-installer { server 127.0.0.1:2000; }\n") + f.write("server {\n") + f.write(" listen 80;\n") + f.write(" location / {\n") + f.write(" proxy_pass http://dokku-installer;\n") + f.write(" }\n") + f.write("}\n") + + subprocess.call('rm -f /etc/nginx/sites-enabled/*', shell=True) + sys.exit(0) + + +class GetHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): + def do_GET(self): + content = PAGE.replace('{VERSION}', VERSION) + content = content.replace('{HOSTNAME}', hostname) + content = content.replace('{ADMIN_KEYS}', "\n".join(admin_keys)) + self.send_response(200) + self.end_headers() + self.wfile.write(content) + + def do_POST(self): + if self.path not in ['/setup', '/setup/']: + return + + params = cgi.FieldStorage(fp=self.rfile, + headers=self.headers, + environ={ + 'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': self.headers['Content-Type']}) + + dokku_root = os.getenv('DOKKU_ROOT', '/home/dokku') + if 'vhost' in params and params['vhost'].value == 'true': + with open('{0}/VHOST'.format(dokku_root), 'w') as f: + f.write(params['hostname'].value) + else: + try: + os.remove('{0}/VHOST'.format(dokku_root)) + except OSError: + pass + + command = ['sshcommand', 'acl-add', 'dokku', 'admin'] + for key in params['keys'].value.split("\n"): + proc = subprocess.Popen(command, stdin=subprocess.PIPE) + proc.stdin.write(key) + proc.stdin.close() + proc.wait() + + if 'selfdestruct' in sys.argv: + DeleteInstallerThread() + + self.send_response(200) + self.end_headers() + self.wfile.write(json.dumps({'status': 'ok'})) + + +class DeleteInstallerThread(object): + def __init__(self, interval=1): + thread = threading.Thread(target=self.run, args=()) + thread.daemon = True + thread.start() + + def run(self): + command = "rm /etc/nginx/conf.d/dokku-installer.conf && /etc/init.d/nginx stop && /etc/init.d/nginx start" + try: + subprocess.call(command, shell=True) + except: + pass + + command = "rm -f /etc/init/dokku-installer.conf /etc/systemd/system/dokku-installer.service && stop dokku-installer" + try: + subprocess.call(command, shell=True) + except: + pass + + +def main(): + check_boot() + + port = int(os.getenv('PORT', 2000)) + httpd = SocketServer.TCPServer(("", port), GetHandler) + print "Listening on 0.0.0.0:{0}, CTRL+C to stop".format(port) + httpd.serve_forever() + + +PAGE = """ + + + Dokku Setup + + + + +
+
+

Dokku Setup {VERSION}

+
+

Admin Access

+
+ +
+
+

Hostname Configuration

+
+ + +
+
+ +
+

Your app URLs will look like:

+
http://hostname:port
+
+ +
+
+
+ + + +""" + +if __name__ == "__main__": + main() diff --git a/contrib/dokku-installer.rb b/contrib/dokku-installer.rb deleted file mode 100755 index 4762105c835..00000000000 --- a/contrib/dokku-installer.rb +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env ruby -require "sinatra" -require "open3" - -if ARGV[0] == "onboot" - File.open("/etc/init/dokku-installer.conf", "w") do |f| - f.puts "start on runlevel [2345]" - f.puts "exec #{File.absolute_path(__FILE__)} selfdestruct" - end if File.directory?("/etc/init") - File.open("/etc/systemd/system/dokku-installer.service", "w") do |f| - f.puts "[Unit]" - f.puts "Description=Dokku web-installer" - f.puts "" - f.puts "[Service]" - f.puts "ExecStart=#{File.absolute_path(__FILE__)} selfdestruct" - f.puts "" - f.puts "[Install]" - f.puts "WantedBy=multi-user.target" - f.puts "WantedBy=graphical.target" - end if File.directory?("/etc/systemd/system") - File.open("/etc/nginx/conf.d/dokku-installer.conf", "w") do |f| - f.puts "upstream dokku-installer { server 127.0.0.1:2000; }" - f.puts "server {" - f.puts " listen 80;" - f.puts " location / {" - f.puts " proxy_pass http://dokku-installer;" - f.puts " }" - f.puts "}" - end - `rm -f /etc/nginx/sites-enabled/*` - puts "Installed Upstart service and default Nginx virtualhost for installer to run on boot." - exit -end - -version = "v0.4.6" -dokku_root = ENV["DOKKU_ROOT"] || "/home/dokku" -admin_keys = `cat /root/.ssh/authorized_keys`.split("\n") -hostname = `bash -c '[[ $(dig +short $HOSTNAME) ]] && echo $HOSTNAME || wget -q -O - icanhazip.com'`.strip -template = DATA.read - -set :port, 2000 -set :environment, :production -disable :protection - -get "/" do - ERB.new(template).result binding -end - -post "/setup" do - if params[:vhost] == "true" - File.open("#{dokku_root}/VHOST", "w") {|f| f.write params[:hostname] } - else - `rm #{dokku_root}/VHOST` - end - File.open("#{dokku_root}/HOSTNAME", "w") {|f| f.write params[:hostname] } - keys = params[:keys].split("\n") - keys.each do |k| - Open3.capture2("sshcommand acl-add dokku admin", :stdin_data => k) - end - Thread.new { - `rm /etc/nginx/conf.d/dokku-installer.conf && /etc/init.d/nginx stop && /etc/init.d/nginx start` - `rm -f /etc/init/dokku-installer.conf /etc/systemd/system/dokku-installer.service && stop dokku-installer` - }.run if ARGV[0] == "selfdestruct" -end - -__END__ - - - Dokku Setup - - - - -
-
-

Dokku Setup <%= version %>

-
-

Admin Access

-
- -
-
-

Hostname Configuration

-
- - -
-
- -
-

Your app URLs will look like:

-
http://hostname:port
-
- -
-
-
- - - diff --git a/deb.mk b/deb.mk index 83c8f7ab50e..aab4a44fc2e 100644 --- a/deb.mk +++ b/deb.mk @@ -20,13 +20,11 @@ SSHCOMMAND_VERSION ?= 0.1.0 SSHCOMMAND_ARCHITECTURE = amd64 SSHCOMMAND_PACKAGE_NAME = sshcommand_$(SSHCOMMAND_VERSION)_$(SSHCOMMAND_ARCHITECTURE).deb -GEM_ARCHITECTURE = amd64 - GOROOT = /usr/lib/go GOBIN = /usr/bin/go GOPATH = /home/vagrant/gocode -.PHONY: install-from-deb deb-all deb-herokuish deb-dokku deb-gems deb-plugn deb-setup deb-sshcommand +.PHONY: install-from-deb deb-all deb-herokuish deb-dokku deb-plugn deb-setup deb-sshcommand install-from-deb: echo "--> Initial apt-get update" @@ -42,7 +40,7 @@ install-from-deb: sudo apt-get update -qq > /dev/null sudo apt-get install dokku -deb-all: deb-herokuish deb-dokku deb-gems deb-plugn deb-sshcommand +deb-all: deb-herokuish deb-dokku deb-plugn deb-sshcommand mv /tmp/*.deb . echo "Done" @@ -96,7 +94,7 @@ deb-dokku: deb-setup $(MAKE) help2man $(MAKE) addman cp /usr/local/share/man/man1/dokku.1 /tmp/build/usr/local/share/man/man1/dokku.1 - cp contrib/dokku-installer.rb /tmp/build/usr/local/share/dokku/contrib + cp contrib/dokku-installer.py /tmp/build/usr/local/share/dokku/contrib git describe --tags > /tmp/build/var/lib/dokku/VERSION cat /tmp/build/var/lib/dokku/VERSION | cut -d '-' -f 1 | cut -d 'v' -f 2 > /tmp/build/var/lib/dokku/STABLE_VERSION git rev-parse HEAD > /tmp/build/var/lib/dokku/GIT_REV @@ -104,18 +102,6 @@ deb-dokku: deb-setup dpkg-deb --build /tmp/build "/vagrant/dokku_`cat /tmp/build/var/lib/dokku/STABLE_VERSION`_$(DOKKU_ARCHITECTURE).deb" mv *.deb /tmp -deb-gems: deb-setup - rm -rf /tmp/tmp /tmp/build rubygem-*.deb - mkdir -p /tmp/tmp /tmp/build - - gem install --quiet --no-verbose --no-ri --no-rdoc --install-dir /tmp/tmp rack -v 1.5.2 > /dev/null - gem install --quiet --no-verbose --no-ri --no-rdoc --install-dir /tmp/tmp rack-protection -v 1.5.3 > /dev/null - gem install --quiet --no-verbose --no-ri --no-rdoc --install-dir /tmp/tmp sinatra -v 1.4.5 > /dev/null - gem install --quiet --no-verbose --no-ri --no-rdoc --install-dir /tmp/tmp tilt -v 1.4.1 > /dev/null - - find /tmp/tmp/cache -name '*.gem' | xargs -rn1 fpm -d ruby -d ruby --prefix /var/lib/gems/1.9.1 -s gem -t deb -a $(GEM_ARCHITECTURE) - mv *.deb /tmp - deb-plugn: deb-setup rm -rf /tmp/tmp /tmp/build $(PLUGN_PACKAGE_NAME) mkdir -p /tmp/tmp /tmp/build diff --git a/debian/control b/debian/control index 265058b9069..bb0b6838e8a 100644 --- a/debian/control +++ b/debian/control @@ -5,6 +5,7 @@ Priority: optional Architecture: amd64 Depends: locales, git, make, curl, gcc, man-db, sshcommand, docker-engine-cs | docker-engine | lxc-docker (> 1.6.1) | docker.io (> 1.6.1), software-properties-common, python-software-properties Recommends: herokuish -Pre-Depends: nginx (>= 1.4.6), dnsutils, apparmor, cgroupfs-mount | cgroup-lite, plugn, sudo, ruby, ruby-dev, rubygem-rack , rubygem-rack-protection, rubygem-sinatra, rubygem-tilt +Pre-Depends: nginx (>= 1.4.6), dnsutils, apparmor, cgroupfs-mount | cgroup-lite, plugn, sudo Maintainer: Jose Diaz-Gonzalez -Description: Docker powered mini-Heroku in around 100 lines of Bash +Description: A docker-powered PaaS that helps you build and manage the lifecycle of applications + diff --git a/debian/preinst b/debian/preinst index 669ffa3fa35..2f214d47258 100755 --- a/debian/preinst +++ b/debian/preinst @@ -13,7 +13,7 @@ case "$1" in rm -f $INIT_CONF touch $INIT_CONF echo 'start on runlevel [2345]' >> $INIT_CONF - echo 'exec /usr/local/share/dokku/contrib/dokku-installer.rb selfdestruct' >> $INIT_CONF + echo 'exec /usr/local/share/dokku/contrib/dokku-installer.py selfdestruct' >> $INIT_CONF rm -f $NGINX_CONF touch $NGINX_CONF diff --git a/docs/development/release-process.md b/docs/development/release-process.md index 1b8b0798d9b..2024a669833 100644 --- a/docs/development/release-process.md +++ b/docs/development/release-process.md @@ -4,7 +4,7 @@ Dokku is released in intervals *at most* three weeks apart, though may be releas To propose a release, the following tasks need to be performed: -- The installable version must be changed in the `contrib/dokku-installer.rb` file. +- The installable version must be changed in the `contrib/dokku-installer.py` file. - The installable version must be changed in the `debian/control` file. - The installable version must be changed in the `docs/home.html` file - The installable version must be changed in the `docs/index.md` file