Skip to content

Instantly share code, notes, and snippets.

@PeterCorless
Last active April 8, 2020 15:48
Show Gist options
  • Save PeterCorless/5a928534deebe18ae04d16bd565e3773 to your computer and use it in GitHub Desktop.
Save PeterCorless/5a928534deebe18ae04d16bd565e3773 to your computer and use it in GitHub Desktop.
Scylla's Portable Python Interpreter, or Snakes on a Data Plane
#!/usr/bin/python3
import yaml
a = yaml.load("string: hello world!")
print(a['string'])
$ cython -3 --embed -o hello.c hello.py
$ gcc -O2 -I $(python3-config --includes) -o hello hello.c -lpthread -lm -lutil -ldl $(python3-config --libs)
$ ldd hello
linux-vdso.so.1 (0x00007ffff4d99000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f37e792a000)
libm.so.6 => /lib64/libm.so.6 (0x00007f37e7596000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007f37e7393000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f37e718f000)
libpython3.6m.so.1.0 => /lib64/libpython3.6m.so.1.0 (0x00007f37e6c33000)
libc.so.6 => /lib64/libc.so.6 (0x00007f37e6874000)
/lib64/ld-linux-x86-64.so.2 (0x00007f37e7b49000)
$ strace -f -e trace=openat ./hello 2>&1 | egrep ".*yaml.*so"
openat(AT_FDCWD, "/usr/lib64/python3.6/site-packages/yaml/__pycache__/resolver.cpython-36.pyc", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib64/python3.6/site-packages/_yaml.cpython-36m-x86_64-linux-gnu.so", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib64/libyaml-0.so.2", O_RDONLY|O_CLOEXEC) = 3
$ ls dist/hello/*yaml*
dist/hello/libyaml-0.so.2
dist/hello/_yaml.cpython-36m-x86_64-linux-gnu.so
$ ldd dist/hello/hello
linux-vdso.so.1 (0x00007ffd80045000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f221c2fa000)
libz.so.1 => /lib64/libz.so.1 (0x00007f221c0e3000)
libc.so.6 => /lib64/libc.so.6 (0x00007f221bd24000)
/lib64/ld-linux-x86-64.so.2 (0x00007f221c4fe000)
./create-relocatable-python.py --output python3.tar.gz \
python3-PyYAML python3-urwid python3-pyparsing \
python3-requests python3-pyudev python3-setuptools
output = subprocess.check_output(['repoquery',
'--archlist=noarch,{machine}'.format(machine=os.uname().machine),
'--cacheonly',
'--installed',
'--resolve',
'--requires',
'--recursive'] + package_list,
universal_newlines=True).splitlines()
#!/bin/bash
x="$(readlink -f "$0")"
b="$(basename "$x")"
d="$(dirname "$x")/.."
ldso="$d/libexec/ld.so"
realexe="$d/libexec/$b.bin"
PYTHONPATH="$d/{sitepackages}:$d/{sitepackages64}:$PYTHONPATH" exec -a "$0" "$ldso" "$realexe" -s "$@"
$ ./bin/python3
Python 3.6.7 (default, Nov 23 2018, 12:11:28)
[GCC 8.2.1 20181105 (Red Hat 8.2.1-5)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
$ ldd ./libexec/python3.6.bin
linux-vdso.so.1 (0x00007ffe92a95000)
libpython3.6m.so.1.0 => /tmp/python/./libexec/../lib64/libpython3.6m.so.1.0 (0x00007fd027801000)
libpthread.so.0 => /tmp/python/./libexec/../lib64/libpthread.so.0 (0x00007fd0275e2000)
libdl.so.2 => /tmp/python/./libexec/../lib64/libdl.so.2 (0x00007fd0273de000)
libutil.so.1 => /tmp/python/./libexec/../lib64/libutil.so.1 (0x00007fd0271db000)
libm.so.6 => /tmp/python/./libexec/../lib64/libm.so.6 (0x00007fd026e47000)
libc.so.6 => /tmp/python/./libexec/../lib64/libc.so.6 (0x00007fd026a88000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd027f61000)
$ strace -f -e trace=openat ./hello.py 2>&1 | grep libyaml
openat(AT_FDCWD, "/tmp/python/lib64/python3.6/site-packages/../../../lib64/libyaml-0.so.2", O_RDONLY|O_CLOEXEC) = 3
./relocate_python_scripts.py --installroot /tmp/test \
--with-python3 /tmp/test/opt/scylladb/python3/bin/python3 \
scylla_blocktune.py
$ cat scylla_blocktune.py
#!/usr/bin/env bash
x="$(readlink -f "$0")"
b="$(basename "$x")"
d="$(dirname "$x")"
PYTHONPATH="${d}:${d}/libexec:$PYTHONPATH" PATH="${d}/opt/scylladb/python3/bin:${PATH}" exec -a "$0" "${d}/libexec/${b}" "$@"
./create-relocatable-python.py --output python3-pip.tar.gz \
python3-pip python3-setuptools
./relocate_python_scripts.py --installroot /tmp/test/pipdemo/ \
--with-python3 /tmp/test/pipdemo/bin/python3 \
/usr/bin/pip3 ./hello.py
$ ./hello.py
Traceback (most recent call last):
File "/tmp/test/pipdemo/libexec/hello.py", line 2, in <module>
import yaml
ModuleNotFoundError: No module named 'yaml'
$ ./pip3 install pyyaml
Collecting pyyaml
Using cached https://files.pythonhosted.org/packages/9e/a3/1d13970c3f36777c583f136c136f804d70f500168edc1edea6daa7200769/PyYAML-3.13.tar.gz
Installing collected packages: pyyaml
Running setup.py install for pyyaml ... done
Successfully installed pyyaml
$ find | grep cyaml.py
./local/lib64/python3.6/site-packages/yaml/cyaml.py
$ ./bin/python3 -c "import sys; [print(x) for x in sys.path]"
/tmp/test/pipdemo/local/lib/python3.6/site-packages
/tmp/test/pipdemo/local/lib64/python3.6/site-packages
/tmp/test/pipdemo
/tmp/test/pipdemo/lib64/python36.zip
/tmp/test/pipdemo/lib64/python3.6
/tmp/test/pipdemo/lib64/python3.6/lib-dynload
/tmp/test/pipdemo/lib64/python3.6/site-packages
$ ./hello.py
hello world!
@PeterCorless
Copy link
Author

Fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment