I will definitely be sending a follow-up patch to address your concerns as 
well as support block and networking devices. 

On Sunday, March 3, 2019 at 4:34:29 AM UTC-5, Nadav Har'El wrote:
>
>
> On Fri, Feb 22, 2019 at 4:15 PM Waldemar Kozaczuk <[email protected] 
> <javascript:>> wrote:
>
>> 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
>>
>
> I committed your patch, but have a few comments below for your 
> consideration for future incremental patches.
> Thanks!
>
>
>> Signed-off-by: Waldemar Kozaczuk <[email protected] <javascript:>>
>> ---
>>  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
>>
>
>
> I  had an annoying Python problem that's not related to your code, of 
> course, but maybe other people will encounter too.
> Trying to run firecracker.py I got Python errors complaining that urllib3 
> is trying to use ".util.queue" and it's missing.
> Or something like that. Took my a while to figure out that my urllib3, 
> which in the past I got from some manual
> "pip install", was somehow broken. I had to manually remove it, and 
> install from Fedora's package:
>
> # rm -r /usr/lib/python2.7/site-packages/urllib3
> # dnf install python2-urllib
>
> I don't know why this happens, but if someone else has the same problem on 
> Fedora 29, you can save a few minutes of frustration by doing the above.
>  
>
>> +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')
>>
>
> Personally I would prefer that instead of this appearing in my home 
> directory, we would just put firecracker in the current directory, i.e., 
> the OSv build directory.
> It's just 6MB, and if you "strip" it (we should. I don't know why it isn't 
> stripped by default!), it's just 2MB. Nobody will complain that each OSv 
> build directory will have a copy of that 2MB.
>
> So you can honor FIRECRACKER_PATH below to allow a user to set a fixed 
> location, but I'd personally prefer the default to be "." (or 
> "./firecracker" or whatever it needs to be).
>   
>
> +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]" %
>>
>
> "y/Y"? That's like an offer I cannot refuse :-)
> Looking at the code below, I guess you meant "y/N"?
>  
>
>> +                       (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
>>
>
> socket
>
> +if os.path.exists(socket_path):
>> +    os.unlink(socket_path)
>> +
>> +# Start firecracker process to communicate over specified UNIX socker 
>> file
>>
>
> socket
>
> +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")
>>
>
> In my case, where I didn't apply some of your patches yet so OSv doesn't 
> really work with firecracker, I didn't get an exception above, but got:
>
> 11:30:12.743018: Created OSv VM
> 2019-03-03T11:30:12.748831329 [anonymous-instance:ERROR:vmm/src/
> sigsys_handler.rs:70] Shutting down VM after intercepting a bad syscall 
> (131).
> 2019-03-03T11:30:12.748820490 [anonymous-instance:ERROR:vmm/src/
> lib.rs:1206] Failed to log metrics while stopping: Logger was not 
> initialized.
> 2019-03-03T11:30:12.748871644 [anonymous-instance:ERROR:vmm/src/
> sigsys_handler.rs:76] Failed to log metrics while stopping: Logger was 
> not initialized.
> /actions: 204
> 11:30:12.749496: Booted OSv VM
> 11:30:12.749533: Waiting for firecracker process to terminate
> 11:30:12.757930: End
>
> I can understand it's some sort of error, but it's not very clear what it 
> means.
> Anyway, not critical - it's more important that it works *with* your 
> patches to make it work :-)
>
> -- 
>> 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] <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
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