diff --git a/README.rst b/README.rst index efa3f69..371e5fe 100644 --- a/README.rst +++ b/README.rst @@ -109,6 +109,16 @@ Steps to get up-and-running on Heroku: # to set the MCL_EC2_REGION variable $ heroku config:set MCL_EC2_REGION= + # Optional Dynamic DNS Settings + # If you don't want to have a constantly-changing IP address, you can add your + # login credentials for https://www.noip.com (which is free!) + # + # This service gives you a URL that Minecloud will automatically point + # to your server IP and keep up to date. + $ heroku config:set NO_IP_HOSTNAME=my-great-hostname.servegame.com + $ heroku config:set NO_IP_USERNAME=me@example.com + $ heroku config:set NO_IP_PASSWORD=secretpassword + # Review all your settings $ heroku config diff --git a/minecloud/launcher/tasks.py b/minecloud/launcher/tasks.py index cbed400..88c37c5 100644 --- a/minecloud/launcher/tasks.py +++ b/minecloud/launcher/tasks.py @@ -12,6 +12,11 @@ from .models import Instance from .sseview import send_event +import urllib +import urllib2 +import base64 +import string + @task def launch(instance_id): # Retrive instance obj from DB. @@ -21,7 +26,7 @@ def launch(instance_id): ec2_ami = os.getenv('MCL_EC2_AMI') ec2_region = os.getenv('MCL_EC2_REGION', 'us-west-2') ec2_keypair = os.getenv('MCL_EC2_KEYPAIR','MinecraftEC2') - ec2_instancetype = os.getenv('MCL_EC2_INSTANCE_TYPE', 'm1.small') + ec2_instancetype = os.getenv('MCL_EC2_INSTANCE_TYPE', 'm3.medium') ec2_secgroups = [os.getenv('MCL_EC2_SECURITY_GROUP', 'minecraft')] # ec2_env_vars populate the userdata.txt file. Cloud-init will append @@ -64,6 +69,17 @@ def launch(instance_id): instance.save() send_event('instance_state', instance.state) + # Update dynamic IP + dynamic_ip_hostname = os.getenv('NO_IP_HOSTNAME', None) + dynamic_ip_username = os.getenv('NO_IP_USERNAME', None) + dynamic_ip_password = os.getenv('NO_IP_PASSWORD', None) + if dynamic_ip_hostname and dynamic_ip_username and dynamic_ip_password: + opener = urllib2.build_opener() + auth = base64.encodestring('%s:%s' % (dynamic_ip_username, dynamic_ip_password)).replace('\n', '') + opener.addheaders = [('User-agent', 'Minecloud-No-IP/1.0 http://github.com/toffer/minecloud'), ("Authorization", "Basic %s" % auth)] + url = "http://dynupdate.no-ip.com/nic/update?hostname=" + urllib.quote_plus(dynamic_ip_hostname) + "&myip=" + urllib.quote_plus(server.ip_address) + opener.open(url) + # Send task to check if instance is running check_state.delay(instance_id, 'running') diff --git a/minecloud/launcher/views.py b/minecloud/launcher/views.py index 3560070..4032447 100644 --- a/minecloud/launcher/views.py +++ b/minecloud/launcher/views.py @@ -10,6 +10,7 @@ from .models import Instance, Session from .sseview import SseView, send_event +import os @login_required def index(request): @@ -17,7 +18,7 @@ def index(request): current_sessions = None err_msg = None running_instances = Instance.objects.exclude(state__exact='terminated') - if len(running_instances) == 1: + if len(running_instances) == 1: instance = running_instances[0] current_sessions = (Session.objects .filter(instance_id__exact=instance.id) @@ -25,12 +26,13 @@ def index(request): ) elif len(running_instances) > 1: err_msg = "Error: Multiple instances are running at once." - return render(request, + return render(request, 'launcher/index.html', {'instance': instance, 'sessions': current_sessions, + 'no_ip_hostname': os.getenv('NO_IP_HOSTNAME', None), 'err_msg': err_msg}) - + @login_required @require_POST def launch(request): diff --git a/requirements.txt b/requirements.txt index 8266f56..18b1bf6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,6 @@ billiard==2.7.3.19 boto==2.6.0 celery==3.0.12 celerymon==1.0.3 -distribute==0.6.24 dj-database-url==0.2.1 django-celery==3.0.11 django-heroku-memcacheify==0.4 @@ -16,12 +15,12 @@ django-pylibmc-sasl==0.2.4 django-registration==0.8 django-secure==0.1.2 django-sse==0.4.1 -gevent==0.13.8 -greenlet==0.4.0 -gunicorn==0.16.1 +gevent +greenlet +gunicorn honcho==0.2.0 kombu==2.5.3 -newrelic==1.10.2.38 +newrelic>=2.38.2.33 paramiko==1.9.0 psycopg2==2.4.5 pycrypto==2.6 @@ -30,4 +29,3 @@ python-dateutil==1.5 pytz==2012h redis==2.7.2 sse==1.2 -wsgiref==0.1.2 diff --git a/templates/launcher/index.html b/templates/launcher/index.html index 001b4ff..991759f 100644 --- a/templates/launcher/index.html +++ b/templates/launcher/index.html @@ -30,7 +30,15 @@

Server Info

{% elif instance and instance.state == 'pending' %}
-

Server is waking up at {{ instance.ip_address }}.

+

Server is waking up at + + {% if no_ip_hostname %} + {{ no_ip_hostname }} + {% else %} + {{ instance.ip_address }} + {% endif %} + +

Now, it's restoring saved game data. Almost ready...

@@ -41,6 +49,12 @@

Server Info

IP Address {{ instance.ip_address }} + {% if no_ip_hostname %} + + DDNS Hostname + {{ no_ip_hostname }} + + {% endif %} Start Time {{ instance.start }} @@ -56,14 +70,28 @@

Server Info

{% elif instance and instance.state == 'running' %}
-

Server is running at {{ instance.ip_address }}.

+

Server is running at + + {% if no_ip_hostname %} + {{ no_ip_hostname }} + {% else %} + {{ instance.ip_address }} + {% endif %} + +

Join the server!

    + {% if no_ip_hostname %} +
  • Open Minecraft, click Multiplayer, and add a new server.
  • +
  • Copy above hostname into the Server Address field.
  • + {% else %}
  • Open Minecraft, click Multiplayer, and edit the Server Info.
  • Copy the IP address into the Server Address field.
  • +
  • This IP address will change each time the server is restarted.
  • + {% endif %}
@@ -74,6 +102,12 @@

Server Info

IP Address {{ instance.ip_address }} + {% if no_ip_hostname %} + + DDNS Hostname + {{ no_ip_hostname }} + + {% endif %} Start Time {{ instance.start }} @@ -177,6 +211,6 @@

Server is sleeping.

location.reload(true) }, false); - }); + }); {% endblock content %} \ No newline at end of file