This patch adds simple Python script that allows
booting OSv loader.elf on firecracker.

It also automates process of downloading and installing
firecracker. Evenntually it might be incorporated
into scripts/run.py

Signed-off-by: Waldemar Kozaczuk <[email protected]>
---
 scripts/firecracker.py | 126 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)
 create mode 100755 scripts/firecracker.py

diff --git a/scripts/firecracker.py b/scripts/firecracker.py
new file mode 100755
index 00000000..bed4cf58
--- /dev/null
+++ b/scripts/firecracker.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+#
+# pip install requests-unixsocket
+import sys
+import os
+import stat
+import json
+import subprocess
+import time
+from os.path import expanduser
+from datetime import datetime
+import requests_unixsocket
+
+
+class ApiClient(object):
+    def __init__(self, domain_socket_path):
+        self.socket_path = domain_socket_path
+        self.session = requests_unixsocket.Session()
+
+    def api_socket_url(self, path):
+        return "http+unix://%s%s" % (self.socket_path, path)
+
+    def make_put_call(self, path, request_body):
+        url = self.api_socket_url(path)
+        res = self.session.put(url, data=json.dumps(request_body))
+        print("%s: %s" % (path, res.status_code))
+        if res.status_code != 204:
+            print(res.text)
+        return res.status_code
+
+    def create_instance(self, kernel_image_path, cmdline):
+        self.make_put_call('/boot-source', {
+            'kernel_image_path': kernel_image_path,
+            'boot_args': cmdline
+        })
+
+    def start_instance(self):
+        self.make_put_call('/actions', {
+            'action_type': 'InstanceStart'
+        })
+
+    def configure_logging(self):
+        self.make_put_call('/logger', {
+            "log_fifo": "log.fifo",
+            "metrics_fifo": "metrics.fifo",
+            "level": "Info",
+            "show_level": True,
+            "show_log_origin": True
+        })
+
+
+def print_time(msg):
+    now = datetime.now()
+    print("%s: %s" % (now.strftime('%H:%M:%S.%f'), msg))
+
+
+# Check if firecracker is installed
+home_dir = expanduser("~")
+firecracker_path = os.path.join(home_dir, '.firecracker/firecracker')
+if os.environ.get('FIRECRACKER_PATH'):
+    firecracker_path = os.environ.get('FIRECRACKER_PATH')
+
+# And offer to install if not found
+if not os.path.exists(firecracker_path):
+    download_url = 
'https://github.com/firecracker-microvm/firecracker/releases/download/v0.14.0/firecracker-v0.14.0'
+    answer = raw_input("Firecracker executable has not been found under %s. "
+                       "Would you like to download it from %s and place it 
under %s? [y|Y]" %
+                       (firecracker_path, download_url, firecracker_path))
+    if answer.capitalize() != 'Y':
+        print("Firecracker not available. Exiting ...")
+        sys.exit(-1)
+
+    directory = os.path.dirname(firecracker_path)
+    if not os.path.exists(directory):
+        os.mkdir(directory)
+    subprocess.call(['wget', download_url, '-O', firecracker_path])
+    os.chmod(firecracker_path, stat.S_IRUSR | stat.S_IXUSR)
+
+# Firecracker is installed so lets start
+print_time("Start")
+socket_path = '/tmp/firecracker.socket'
+
+# Delete socker file if exists
+if os.path.exists(socket_path):
+    os.unlink(socket_path)
+
+# Start firecracker process to communicate over specified UNIX socker file
+firecracker = subprocess.Popen([firecracker_path, '--api-sock', socket_path],
+                                 stdin=subprocess.PIPE, stdout=sys.stdout,
+                                 stderr=subprocess.STDOUT)
+
+# Prepare arguments we are going to pass when creating VM instance
+dirname = os.path.dirname(os.path.abspath(__file__))
+kernel_path = os.path.join(dirname, '../build/release/loader-stripped.elf')
+
+if len(sys.argv) > 1:
+    cmdline = sys.argv[1]
+else:
+    with open(os.path.join(dirname, '../build/release/cmdline'), 'r') as f:
+        cmdline = f.read()
+
+# Create API client and make API calls
+client = ApiClient(socket_path.replace("/", "%2F"))
+
+try:
+    # Very often on the very first run firecracker process
+    # is not ready yet to accept calls over socket file
+    # so we poll existence of this file as an good
+    # enough indicator of firecracker readyness
+    while not os.path.exists(socket_path):
+        time.sleep(0.01)
+    print_time("Firecracker ready")
+
+    client.create_instance(kernel_path, cmdline)
+    print_time("Created OSv VM")
+
+    client.start_instance()
+    print_time("Booted OSv VM")
+except Exception as e:
+    print("Failed to run OSv on firecracker due to: ({0}): {1} 
!!!".format(e.errno, e.strerror))
+    firecracker.kill()
+    exit(-1)
+
+print_time("Waiting for firecracker process to terminate")
+firecracker.wait()
+print_time("End")
-- 
2.19.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to