Skip to content

Commit

Permalink
Fix container's deploy when used with keys.
Browse files Browse the repository at this point in the history
  • Loading branch information
jraygauthier committed Sep 8, 2016
1 parent 605c09f commit a19e697
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
2 changes: 1 addition & 1 deletion nixops/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MachineState(nixops.resources.ResourceState):
ssh_pinged = nixops.util.attr_property("sshPinged", False, bool)
ssh_port = nixops.util.attr_property("targetPort", 22, int)
public_vpn_key = nixops.util.attr_property("publicVpnKey", None)
store_keys_on_machine = nixops.util.attr_property("storeKeysOnMachine", True, bool)
store_keys_on_machine = nixops.util.attr_property("storeKeysOnMachine", False, bool)
keys = nixops.util.attr_property("keys", {}, 'json')
owners = nixops.util.attr_property("owners", [], 'json')

Expand Down
54 changes: 54 additions & 0 deletions nixops/backends/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import nixops.util
import nixops.ssh_util
import subprocess
import time
import threading
import sys

class ContainerDefinition(MachineDefinition):
"""Definition of a NixOS container."""
Expand Down Expand Up @@ -120,6 +123,8 @@ def create_after(self, resources, defn):
def create(self, defn, check, allow_reboot, allow_recreate):
assert isinstance(defn, ContainerDefinition)

self.set_common_state(defn)

if not self.client_private_key:
(self.client_private_key, self.client_public_key) = nixops.util.create_key_pair()

Expand Down Expand Up @@ -179,11 +184,60 @@ def stop(self):
self.host_ssh.run_command("nixos-container stop {0}".format(self.vm_id))
self.state = self.STOPPED


def get_container_status(self):
try:
status = self.host_ssh.run_command("nixos-container status {0}".format(self.vm_id), capture_stdout=True).rstrip()
except nixops.ssh_util.SSHConnectionFailed:
status = "unknown_ssh_connection_failed"
except nixops.ssh_util.SSHCommandFailed:
status = "unknown_ssh_command_failed"
return status

def wait_container_available(self):
# For some reason, it seems to work best if I wait before sending the command to
# check the status of the container instead of the reverse.
time.sleep(1)
while True:
status = self.get_container_status()
self.log("waiting for container... Current status: {0}".format(status))
if status in {"up", "down"}:
break
time.sleep(1)

def send_key_task(self):
# Do not attempt anything when there are no keys so as to
# avoid breaking setups with no keys to send.
if not self.get_keys().items():
return

# For some reason, it seems that when there are keys listed in the
# container deployment, it becomes impossible to use the start command
# after a stop. The instance simply hangs and it is impossible to even
# ping it. Once we solve this mystery, the following code should become
# useful.

# When performing the command `nixos-container status` on the container,
# I get: the following:
# `Failed to start container@webserv-18.service: Interactive authentication required.`
# which may give us some hint as to the source of the problem.

self.wait_container_available()
self.log("sending keys...")
self.send_keys()

def start(self):
if not self.vm_id: return True
self.log("starting container...")
# As the nixos-container is blocking, we need to lauch a
# thread so as to send the keys. Otherwise, the deployment
# would block on a service that depends on those keys and as such
# we would never get a chance to send them.
send_key_thread = threading.Thread(target=self.send_key_task)
send_key_thread.start()
self.host_ssh.run_command("nixos-container start {0}".format(self.vm_id))
self.state = self.STARTING
send_key_thread.join()

def _check(self, res):
if not self.vm_id:
Expand Down

0 comments on commit a19e697

Please sign in to comment.