Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Gramine dependencies that are not needed at runtime #144

Merged
merged 1 commit into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Documentation/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,16 @@ of the signing key in them.

Provide passphrase for the enclave signing key (if applicable)

.. option:: -D, --define

Set image sign-time variables during :command:`gsc sign`.

.. option:: --remove-gramine-deps

Remove Gramine dependencies that are not needed at runtime. This may have
a negative side effect of removing even those dependencies that are actually
needed by the original application. Use with care!

.. option:: IMAGE-NAME

Name of the application Docker image
Expand Down
35 changes: 34 additions & 1 deletion gsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
import tomli_w # pylint: disable=import-error
import yaml # pylint: disable=import-error

def test_trueish(value):
if not value:
return False
value = value.casefold()
if value in ('false', 'off', 'no'):
return False
if value in ('true', 'on', 'yes'):
return True
if value.isdigit():
return bool(int(value))
raise ValueError(f'Invalid value for trueish: {value!r}')

def gsc_image_name(original_image_name):
return f'gsc-{original_image_name}'

Expand Down Expand Up @@ -131,6 +143,17 @@ def extract_build_args(args):
sys.exit(1)
return buildargs_dict

def extract_define_args(args):
defineargs_dict = {}
for item in args.define:
if '=' in item:
key, value = item.split('=', maxsplit=1)
defineargs_dict[key] = value
else:
print(f'Invalid value for argument `{item}`, expected `--define {item}=<value>`')
sys.exit(1)
return defineargs_dict

def extract_user_from_image_config(config, env):
user = config['User']
if not user:
Expand Down Expand Up @@ -345,6 +368,9 @@ def gsc_sign_image(args):
# using the user-provided config file with info on OS distro, Gramine version and SGX driver
env = jinja2.Environment()
env.globals.update(yaml.safe_load(args.config_file))
extract_user_from_image_config(unsigned_image.attrs['Config'], env)
env.globals['args'] = extract_define_args(args)
env.tests['trueish'] = test_trueish
distro = env.globals['Distro']

distro, _ = distro.split(':')
Expand Down Expand Up @@ -510,7 +536,14 @@ def gsc_info_image(args):
sub_sign.add_argument('image', help='Name of the application (base) Docker image.')
sub_sign.add_argument('key', help='Key to sign the Intel SGX enclaves inside the Docker image.')
sub_sign.add_argument('-p', '--passphrase', help='Passphrase for the signing key.')

sub_sign.add_argument('-D','--define', action='append', default=[],
help='Set image sign-time variables.')
sub_sign.add_argument('--remove-gramine-deps', action='append_const', dest='define',
const='remove_gramine_deps=true', help='Remove Gramine dependencies that are not needed'
' at runtime.')
sub_sign.add_argument('--no-remove-gramine-deps', action='append_const', dest='define',
const='remove_gramine_deps=false', help='Retain Gramine dependencies that are not needed'
' at runtime.')
sub_info = subcommands.add_parser('info-image', help='Retrieve information about a graminized '
'Docker image')
sub_info.set_defaults(command=gsc_info_image)
Expand Down
10 changes: 10 additions & 0 deletions templates/Dockerfile.common.sign.template
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ FROM {{image}}

COPY --from=unsigned_image /gramine/app_files/*.sig /gramine/app_files/
COPY --from=unsigned_image /gramine/app_files/*.sgx /gramine/app_files/

{% if args.remove_gramine_deps is trueish %}
# Temporarily switch to the root user to uninstall packages
USER root

{% block uninstall %}{% endblock %}

# Switch back to original app_image user
USER {{app_user}}
{% endif %}
16 changes: 16 additions & 0 deletions templates/centos/Dockerfile.sign.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
{% extends "Dockerfile.common.sign.template" %}

{% block uninstall %}
RUN \
pip3 uninstall -y click jinja2 \
tomli tomli-w \
toml \
&& dnf remove -y binutils \
epel-release \
expect \
openssl \
python3-protobuf \
python3-pyelftools \
python3-cryptography \
tcl \
&& dnf -y clean all;
{% endblock %}

{% block path %}export PYTHONPATH="${PYTHONPATH}:$(find /gramine/meson_build_output/lib64 -type d -path '*/site-packages')" &&{% endblock %}
19 changes: 19 additions & 0 deletions templates/debian/Dockerfile.sign.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
{% extends "Dockerfile.common.sign.template" %}

{% block uninstall %}
RUN \
apt-get update -y \
&& apt-get install -y python3-pip \
&& pip3 uninstall -y click jinja2 \
tomli tomli-w \
toml \
&& apt-get remove -y binutils \
expect \
libcurl4-openssl-dev \
openssl \
python3-pip \
python3-protobuf \
python3-cryptography \
python3-pyelftools \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/*;
{% endblock %}

{% block path %}export PYTHONPATH="${PYTHONPATH}:$(find /gramine/meson_build_output/lib -type d -path '*/site-packages')" &&{% endblock %}