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

Replace Graphene with Gramine everywhere #10

Merged
merged 1 commit into from
Sep 28, 2021
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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Please provide as much information as possible.
Paste any logs using three backticks (```).

IMPORTANT: please do not post general questions here;
if you have questions, please use mailing list: [email protected]
if you have questions, please use mailing list: [email protected]
-->

## Description of the problem
Expand Down
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!--
Please fill in the following form before submitting this PR
and ensure that your code follows our coding style guideline:
https://graphene.readthedocs.io/en/latest/devel/coding-style.html -->
https://gramine.readthedocs.io/en/latest/devel/coding-style.html -->

## Description of the changes <!-- (reasons and measures) -->

Expand Down
8 changes: 4 additions & 4 deletions config.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
# Dockerfiles (compile, build, sign) under templates/
Distro: "ubuntu18.04"

# If you're using your own fork and branch of Graphene, specify the GitHub link and the branch name
# If you're using your own fork and branch of Gramine, specify the GitHub link and the branch name
# below; typically, you want to keep the default values though
Graphene:
Repository: "https://github.com/oscarlab/graphene.git"
Gramine:
Repository: "https://github.com/gramineproject/gramine.git"
Branch: "master"

# Specify the Intel SGX driver installed on your machine (more specifically, on the machine where
# the graphenized Docker container will run); there are several variants of the SGX driver:
# the graminized Docker container will run); there are several variants of the SGX driver:
#
# - legacy out-of-tree driver: use something like the below values, but adjust the branch name
# Repository: "https://github.com/01org/linux-sgx-driver.git"
Expand Down
2 changes: 1 addition & 1 deletion finalize_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def generate_trusted_files(root_dir, already_added_files):
r'|etc/mtab'
r'|dev/.*'
r'|etc/rc(\d|.)\.d/.*'
r'|graphene/python/.*'
r'|gramine/python/.*'
r'|finalize_manifest\.py'
r'|proc/.*'
r'|sys/.*'
Expand Down
106 changes: 53 additions & 53 deletions gsc.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def extract_build_args(args):
return buildargs_dict


# Command 1: Build unsigned graphenized Docker image from original app Docker image.
# Command 1: Build unsigned graminized Docker image from original app Docker image.
def gsc_build(args):
original_image_name = args.image # input original-app image name
unsigned_image_name = gsc_unsigned_image_name(args.image) # output unsigned image name
Expand All @@ -137,15 +137,15 @@ def gsc_build(args):
docker_socket = docker.from_env()

if get_docker_image(docker_socket, signed_image_name) is not None:
print(f'Final graphenized image `{signed_image_name}` already exists.')
print(f'Final graminized image `{signed_image_name}` already exists.')
sys.exit(0)

original_image = get_docker_image(docker_socket, original_image_name)
if original_image is None:
print(f'Cannot find original application Docker image `{original_image_name}`.')
sys.exit(1)

print(f'Building unsigned graphenized Docker image `{unsigned_image_name}` from original '
print(f'Building unsigned graminized Docker image `{unsigned_image_name}` from original '
f'application image `{original_image_name}`...')

# initialize Jinja env with configurations extracted from the original Docker image
Expand All @@ -160,7 +160,7 @@ def gsc_build(args):
os.makedirs(tmp_build_path, exist_ok=True)

# generate Dockerfile.build from Jinja-style templates/Dockerfile.<distro>.build.template
# using the user-provided config file with info on OS distro, Graphene version and SGX driver
# using the user-provided config file with info on OS distro, Gramine version and SGX driver
# and other env configurations generated above
build_template = env.get_template(f'Dockerfile.{env.globals["Distro"]}.build.template')
with open(tmp_build_path / 'Dockerfile.build', 'w') as dockerfile:
Expand Down Expand Up @@ -188,42 +188,42 @@ def gsc_build(args):
entrypoint_manifest.write(base_image_environment)
entrypoint_manifest.write('\n')

# copy helper script to finalize the manifest from within graphenized Docker image
# copy helper script to finalize the manifest from within graminized Docker image
shutil.copyfile('finalize_manifest.py', tmp_build_path / 'finalize_manifest.py')

build_docker_image(docker_socket.api, tmp_build_path, unsigned_image_name, 'Dockerfile.build',
rm=args.rm, nocache=args.no_cache, buildargs=extract_build_args(args))

# Check if docker build failed
if get_docker_image(docker_socket, unsigned_image_name) is None:
print(f'Failed to build unsigned graphenized docker image `{unsigned_image_name}`.')
print(f'Failed to build unsigned graminized docker image `{unsigned_image_name}`.')
sys.exit(1)

print(f'Successfully built an unsigned graphenized Docker image `{unsigned_image_name}` from '
print(f'Successfully built an unsigned graminized Docker image `{unsigned_image_name}` from '
f'original application image `{original_image_name}`.')


# Command 2: Build a "base Graphene" Docker image with the compiled runtime of Graphene.
def gsc_build_graphene(args):
graphene_image_name = gsc_image_name(args.image) # output base-Graphene image name
# Command 2: Build a "base Gramine" Docker image with the compiled runtime of Gramine.
def gsc_build_gramine(args):
gramine_image_name = gsc_image_name(args.image) # output base-Gramine image name
tmp_build_path = gsc_tmp_build_path(args.image) # pathlib obj with build artifacts

config = yaml.safe_load(args.config_file)
if 'Image' in config['Graphene']:
print('`gsc build-graphene` does not allow `Graphene.Image` to be set.')
if 'Image' in config['Gramine']:
print('`gsc build-gramine` does not allow `Gramine.Image` to be set.')
sys.exit(1)

docker_socket = docker.from_env()

if get_docker_image(docker_socket, graphene_image_name) is not None:
print(f'Base-Graphene Docker image `{graphene_image_name}` already exists.')
if get_docker_image(docker_socket, gramine_image_name) is not None:
print(f'Base-Gramine Docker image `{gramine_image_name}` already exists.')
sys.exit(0)

print(f'Building base-Graphene image `{graphene_image_name}`...')
print(f'Building base-Gramine image `{gramine_image_name}`...')

# generate Dockerfile.compile from Jinja-style templates/Dockerfile.<distro>.compile.template
# using the user-provided config file with info on OS distro, Graphene version and SGX driver
# and other user-provided args (see argparser::gsc_build_graphene below)
# using the user-provided config file with info on OS distro, Gramine version and SGX driver
# and other user-provided args (see argparser::gsc_build_gramine below)
env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates/'))
env.globals.update(config)
env.globals.update(vars(args))
Expand All @@ -234,18 +234,18 @@ def gsc_build_graphene(args):
dockerfile.write(compile_template.render())

if args.file_only:
print(f'Successfully created Dockerfile.compile for base-Graphene image '
f'`{graphene_image_name}`.')
print(f'Successfully created Dockerfile.compile for base-Gramine image '
f'`{gramine_image_name}`.')
return

build_docker_image(docker_socket.api, tmp_build_path, graphene_image_name, 'Dockerfile.compile',
build_docker_image(docker_socket.api, tmp_build_path, gramine_image_name, 'Dockerfile.compile',
rm=args.rm, nocache=args.no_cache, buildargs=extract_build_args(args))

if get_docker_image(docker_socket, graphene_image_name) is None:
print(f'Failed to build a base-Graphene image `{graphene_image_name}`.')
if get_docker_image(docker_socket, gramine_image_name) is None:
print(f'Failed to build a base-Gramine image `{gramine_image_name}`.')
sys.exit(1)

print(f'Successfully built a base-Graphene image `{graphene_image_name}`.')
print(f'Successfully built a base-Gramine image `{gramine_image_name}`.')


# Command 3: Sign Docker image which was previously built via `gsc build`.
Expand All @@ -258,14 +258,14 @@ def gsc_sign_image(args):

unsigned_image = get_docker_image(docker_socket, unsigned_image_name)
if unsigned_image is None:
print(f'Cannot find unsigned graphenized Docker image `{unsigned_image_name}`.\n'
print(f'Cannot find unsigned graminized Docker image `{unsigned_image_name}`.\n'
f'You must first build this image via `gsc build` command.')
sys.exit(1)

print(f'Signing graphenized Docker image `unsigned_image_name` -> `{signed_image_name}`...')
print(f'Signing graminized Docker image `unsigned_image_name` -> `{signed_image_name}`...')

# generate Dockerfile.sign from Jinja-style templates/Dockerfile.<distro>.sign.template
# using the user-provided config file with info on OS distro, Graphene version and SGX driver
# using the user-provided config file with info on OS distro, Gramine version and SGX driver
env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates/'))
env.globals.update(yaml.safe_load(args.config_file))
sign_template = env.get_template(f'Dockerfile.{env.globals["Distro"]}.sign.template')
Expand All @@ -287,14 +287,14 @@ def gsc_sign_image(args):
os.remove(tmp_build_key_path)

if get_docker_image(docker_socket, signed_image_name) is None:
print(f'Failed to build a signed graphenized Docker image `{signed_image_name}`.')
print(f'Failed to build a signed graminized Docker image `{signed_image_name}`.')
sys.exit(1)

print(f'Successfully built a signed Docker image `{signed_image_name}` from '
f'`{unsigned_image_name}`.')


# Simplified version of read_sigstruct from python/graphenelibos/sgx_get_token.py
# Simplified version of read_sigstruct from python/graminelibos/sgx_get_token.py
def read_sigstruct(sig):
# Offsets for fields in SIGSTRUCT (defined by the SGX HW architecture, they never change)
SGX_ARCH_ENCLAVE_CSS_DATE = 20
Expand All @@ -318,13 +318,13 @@ def read_sigstruct(sig):

return attr

# Retrieve information about a previously built graphenized Docker image
# Retrieve information about a previously built graminized Docker image
def gsc_info_image(args):
docker_socket = docker.from_env()
gsc_image = get_docker_image(docker_socket, args.image)
if gsc_image is None:
print(f'Could not find graphenized Docker image {args.image}.\n'
'Please make sure to build the graphenized image first by using \'gsc build\''
print(f'Could not find graminized Docker image {args.image}.\n'
'Please make sure to build the graminized image first by using \'gsc build\''
' command.')
sys.exit(1)

Expand Down Expand Up @@ -358,17 +358,17 @@ def gsc_info_image(args):
subcommands = argparser.add_subparsers(metavar='<command>')
subcommands.required = True

sub_build = subcommands.add_parser('build', help='Build graphenized Docker image')
sub_build = subcommands.add_parser('build', help='Build graminized Docker image')
sub_build.set_defaults(command=gsc_build)
sub_build.add_argument('-d', '--debug', action='store_true',
help='Compile Graphene with debug flags and output.')
help='Compile Gramine with debug flags and output.')
sub_build.add_argument('-L', '--linux', action='store_true',
help='Compile Graphene with Linux PAL in addition to Linux-SGX PAL.')
help='Compile Gramine with Linux PAL in addition to Linux-SGX PAL.')
sub_build.add_argument('--insecure-args', action='store_true',
help='Allow to specify untrusted arguments during Docker run. '
'Otherwise arguments are ignored.')
sub_build.add_argument('-nc', '--no-cache', action='store_true',
help='Build graphenized Docker image without any cached images.')
help='Build graminized Docker image without any cached images.')
sub_build.add_argument('--rm', action='store_true',
help='Remove intermediate Docker images when build is successful.')
sub_build.add_argument('--build-arg', action='append', default=[],
Expand All @@ -378,38 +378,38 @@ def gsc_info_image(args):
sub_build.add_argument('image', help='Name of the application Docker image.')
sub_build.add_argument('manifest', help='Manifest file to use.')

sub_build_graphene = subcommands.add_parser('build-graphene',
help='Build base-Graphene Docker image')
sub_build_graphene.set_defaults(command=gsc_build_graphene)
sub_build_graphene.add_argument('-d', '--debug', action='store_true',
help='Compile Graphene with debug flags and output.')
sub_build_graphene.add_argument('-L', '--linux', action='store_true',
help='Compile Graphene with Linux PAL in addition to Linux-SGX PAL.')
sub_build_graphene.add_argument('-nc', '--no-cache', action='store_true',
help='Build graphenized Docker image without any cached images.')
sub_build_graphene.add_argument('--rm', action='store_true',
sub_build_gramine = subcommands.add_parser('build-gramine',
help='Build base-Gramine Docker image')
sub_build_gramine.set_defaults(command=gsc_build_gramine)
sub_build_gramine.add_argument('-d', '--debug', action='store_true',
help='Compile Gramine with debug flags and output.')
sub_build_gramine.add_argument('-L', '--linux', action='store_true',
help='Compile Gramine with Linux PAL in addition to Linux-SGX PAL.')
sub_build_gramine.add_argument('-nc', '--no-cache', action='store_true',
help='Build graminized Docker image without any cached images.')
sub_build_gramine.add_argument('--rm', action='store_true',
help='Remove intermediate Docker images when build is successful.')
sub_build_graphene.add_argument('--build-arg', action='append', default=[],
sub_build_gramine.add_argument('--build-arg', action='append', default=[],
help='Set build-time variables (same as "docker build --build-arg").')
sub_build_graphene.add_argument('-c', '--config_file',
sub_build_gramine.add_argument('-c', '--config_file',
type=argparse.FileType('r', encoding='UTF-8'),
default='config.yaml', help='Specify configuration file.')
sub_build_graphene.add_argument('-f', '--file-only', action='store_true',
sub_build_gramine.add_argument('-f', '--file-only', action='store_true',
help='Stop after Dockerfile is created and do not build the Docker image.')
sub_build_graphene.add_argument('image',
help='Name of the output base-Graphene Docker image.')
sub_build_gramine.add_argument('image',
help='Name of the output base-Gramine Docker image.')

sub_sign = subcommands.add_parser('sign-image', help='Sign graphenized Docker image')
sub_sign = subcommands.add_parser('sign-image', help='Sign graminized Docker image')
sub_sign.set_defaults(command=gsc_sign_image)
sub_sign.add_argument('-c', '--config_file', type=argparse.FileType('r', encoding='UTF-8'),
default='config.yaml', help='Specify configuration file.')
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_info = subcommands.add_parser('info-image', help='Retrieve information about a graphenized '
sub_info = subcommands.add_parser('info-image', help='Retrieve information about a graminized '
'Docker image')
sub_info.set_defaults(command=gsc_info_image)
sub_info.add_argument('image', help='Name of the graphenized Docker image.')
sub_info.add_argument('image', help='Name of the graminized Docker image.')

def main(args):
args = argparser.parse_args()
Expand Down
26 changes: 11 additions & 15 deletions templates/Dockerfile.ubuntu18.04.build.template
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Include previously-prepared Docker image with Graphene (if any) or compile Graphene from sources
{% if Graphene.Image %}
FROM gsc-{{Graphene.Image}} AS graphene
# Include previously-prepared Docker image with Gramine (if any) or compile Gramine from sources
{% if Gramine.Image %}
FROM gsc-{{Gramine.Image}} AS gramine
{% else %}
{% include "Dockerfile.ubuntu18.04.compile.template" %}
{% endif %}

# Combine Graphene image with the original app image
# Combine Gramine image with the original app image
FROM {{app_image}}

RUN apt-get update \
Expand All @@ -18,7 +18,7 @@ RUN apt-get update \
python3 \
python3-pip \
python3-protobuf \
&& python3 -B -m pip install protobuf jinja2 toml>=0.10
&& python3 -B -m pip install protobuf jinja2 'toml>=0.10'

{% if debug %}
RUN env DEBIAN_FRONTEND=noninteractive apt-get install -y gdb less strace vim python3-pyelftools
Expand All @@ -29,30 +29,26 @@ ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8

# Copy Graphene runtime and signer tools to /graphene/meson_build_output
RUN mkdir -p /graphene/Tools \
&& mkdir -p /graphene/meson_build_output
# Copy path-specific installation of Gramine
COPY --from=gramine /gramine/meson_build_output /gramine/meson_build_output

# TODO: remove this copy after argv_serializer becomes a part of Meson build
COPY --from=graphene /graphene/Tools/argv_serializer /graphene/Tools
COPY --from=graphene /graphene/meson_build_output /graphene/meson_build_output

# Copy helper scripts and Graphene manifest
# Copy helper scripts and Gramine manifest
COPY *.py /
COPY apploader.sh /
COPY entrypoint.manifest /

# Generate trusted arguments if required
{% if not insecure_args %}
RUN /graphene/Tools/argv_serializer {{binary}} {{binary_arguments}} "{{"\" \"".join(cmd)}}" > /trusted_argv
RUN /gramine/meson_build_output/bin/gramine-argv-serializer \
{{binary}} {{binary_arguments}} "{{"\" \"".join(cmd)}}" > /trusted_argv
{% endif %}

# Docker entrypoint/cmd typically contains only the basename of the executable so create a symlink
RUN cd / \
&& which {{binary}} | xargs ln -s || true

# Include Meson build output directory in $PATH
ENV PATH="/graphene/meson_build_output/bin:$PATH"
ENV PATH="/gramine/meson_build_output/bin:$PATH"

# Mark apploader.sh executable, finalize manifest, and remove intermediate scripts
RUN chmod u+x /apploader.sh \
Expand Down
Loading