Skip to content
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
15 changes: 13 additions & 2 deletions contrib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,22 @@ exports_files(["push-all.sh.tpl"])

exports_files(["structure-test.sh.tpl"])

exports_files(["compare_ids_test.sh.tpl"])
exports_files(["compare_ids_test.py"])

exports_files(["compare_ids_test.bzl"])

exports_files(["extract_image_id.sh"])
exports_files(["extract_image_id.py"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should not need to export this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use this file in the compare_ids_fail_test.bzl as it needs to copy it into the new workspace it produces to test the failing cases of the compare_ids_test rule.


py_binary(
name = "extract_image_id",
srcs = [":extract_image_id.py"],
)

py_binary(
name = "compare_ids_test",
srcs = [":compare_ids_test.py"],
deps = ["extract_image_id"],
)

alias(
name = "structure_test_executable",
Expand Down
31 changes: 12 additions & 19 deletions contrib/compare_ids_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,17 @@ def _compare_ids_test_impl(ctx):
if (len(tar_files) == 1 and not ctx.attr.id):
fail("One tar provided. Need either second tar or an id to compare it to.")

tars_string = ""
for tar in tar_files:
tars_string += tar.short_path + " "
runfiles = ctx.runfiles(files = tar_files + ctx.files._compare_ids_test_script)

runfiles = ctx.runfiles(files = tar_files + [ctx.file._id_extract_script])
id_args = []
if ctx.attr.id:
id_args = ["--id", ctx.attr.id]

ctx.actions.expand_template(
template = ctx.file._executable_template,
args = " ".join([f.short_path for f in tar_files] + id_args)

ctx.actions.write(
output = ctx.outputs.executable,
substitutions = {
"{id}": ctx.attr.id,
"{tars}": tars_string,
"{id_script_path}": ctx.file._id_extract_script.short_path,
},
content = "python {} {}".format(ctx.executable._compare_ids_test_script.short_path, args),
is_executable = True,
)

Expand Down Expand Up @@ -80,15 +77,11 @@ compare_ids_test = rule(
mandatory = False,
default = "",
),
"_executable_template": attr.label(
allow_files = True,
single_file = True,
default = "compare_ids_test.sh.tpl",
),
"_id_extract_script": attr.label(
"_compare_ids_test_script": attr.label(
allow_files = True,
single_file = True,
default = "extract_image_id.sh",
default = ":compare_ids_test",
executable = True,
cfg = "host",
),
},
test = True,
Expand Down
63 changes: 63 additions & 0 deletions contrib/compare_ids_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright 2015 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Compares the ids of the given valid image tarballs.

usage: compare_ids_test.py [-h] [--id ID] tars [tars ...]

positional arguments:
tars

optional arguments:
-h, --help show this help message and exit
--id ID

Used in compare_ids_test.bzl
More info can be found there

"""
import argparse

from extract_image_id import get_id


def compare_ids(tars, id_=None):
"""Compares the ids of the given valid image tarballs.

Args:
tars: list of str paths to the image tarballs
id_: (optional) the id we want the images to have
if None, just makes sure they are all the same

"""

for image in tars:
current_id = get_id(image)
if id_ is None:
id_ = current_id
elif current_id != id_:
exit(1)

exit(0)


if __name__ == "__main__":
parser = argparse.ArgumentParser()

parser.add_argument("tars", nargs="+", type=str, default=[])

parser.add_argument("--id", type=str, default=None)

args = parser.parse_args()

compare_ids(args.tars, args.id)
31 changes: 0 additions & 31 deletions contrib/compare_ids_test.sh.tpl

This file was deleted.

64 changes: 64 additions & 0 deletions contrib/extract_image_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2015 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Extracts the id of a docker image from its tarball.

Takes one argument, the path to the tarball.
"""


from __future__ import print_function
from json import JSONDecoder
import sys
import tarfile


def get_id(tar_path):
"""Extracts the id of a docker image from its tarball.

Args:
tar_path: str path to the tarball


Returns:
str id of the image

"""
tar = tarfile.open(tar_path, mode="r")

decoder = JSONDecoder()
try:
# Extracts it as a file object (not to the disk)
manifest = tar.extractfile("manifest.json").read().decode("utf-8")
except Exception as e:
print((
"Unable to extract manifest.json, make sure {} "
"is a valid docker image.\n").format(tar_path),
e,
file=sys.stderr)
exit(1)

# Get the manifest dictionary from JSON
manifest = decoder.decode(manifest)[0]

# The name of the config file is of the form <image_id>.json
config_file = manifest["Config"]

# Get the id
id_ = config_file.split(".")[0]

return id_


if __name__ == "__main__":
print(get_id(sys.argv[1]))
38 changes: 0 additions & 38 deletions contrib/extract_image_id.sh

This file was deleted.

19 changes: 13 additions & 6 deletions tests/contrib/compare_ids_fail_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def _impl(ctx):
load("//:compare_ids_test.bzl", "compare_ids_test")

compare_ids_test(
name = "test",
name = "test_for_failure",
id = {id},
images = {tars},
)
Expand All @@ -40,8 +40,9 @@ compare_ids_test(

runfiles = ctx.runfiles(files = tar_files + [
ctx.file._compare_ids_test_bzl,
ctx.file._compare_ids_test_sh_tpl,
ctx.file._compare_ids_test,
ctx.file._extract_image_id,
ctx.file._BUILD,
])

# Produces string of form (Necessary because of spaces): " 'reg exp 1' 'reg exp 2'"
Expand All @@ -56,10 +57,11 @@ compare_ids_test(
"{tars}": tars_string,
"{test_code}": test_code,
"{bzl_path}": ctx.file._compare_ids_test_bzl.short_path,
"{tpl_path}": ctx.file._compare_ids_test_sh_tpl.short_path,
"{test_bin_path}": ctx.file._compare_ids_test.short_path,
"{extractor_path}": ctx.file._extract_image_id.short_path,
"{name}": ctx.attr.name,
"{reg_exps}": reg_exps,
"{BUILD_path}": ctx.file._BUILD.short_path,
},
is_executable = True,
)
Expand Down Expand Up @@ -110,15 +112,20 @@ compare_ids_fail_test = rule(
single_file = True,
default = "//contrib:compare_ids_test.bzl",
),
"_compare_ids_test_sh_tpl": attr.label(
"_compare_ids_test": attr.label(
allow_files = True,
single_file = True,
default = "//contrib:compare_ids_test.sh.tpl",
default = "//contrib:compare_ids_test.py",
),
"_extract_image_id": attr.label(
allow_files = True,
single_file = True,
default = "//contrib:extract_image_id.sh",
default = "//contrib:extract_image_id.py",
),
"_BUILD": attr.label(
allow_files = True,
single_file = True,
default = "//contrib:BUILD",
),
},
)
20 changes: 12 additions & 8 deletions tests/contrib/compare_ids_fail_test.sh.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ mkdir -p new_temp_workspace_{name}
cd new_temp_workspace_{name}

touch WORKSPACE

echo > BUILD {test_code}
mkdir test_folder
echo > test_folder/BUILD {test_code}

# Link the test files we will be using and make sure the links point to real files
# No second operand means it just links the file in the current directory,
Expand All @@ -36,27 +36,32 @@ echo > BUILD {test_code}
ln -s ../{bzl_path}
test -f $(basename {bzl_path})

# Link compare_ids_test.sh.tpl
ln -s ../{tpl_path}
test -f $(basename {tpl_path})
# Link compare_ids_test.py
ln -s ../{test_bin_path}
test -f $(basename {test_bin_path})

# Link extract_image_id.sh
ln -s ../{extractor_path}
test -f $(basename {extractor_path})

# Link BUILD
ln -s ../{BUILD_path}
test -f $(basename {BUILD_path})

cd test_folder
tar_num=0
for tar in {tars}
do
# Link the supplied tars and rename them to 0.tar, 1.tar, etc.
eval mv $(ln -vs ../$tar | cut -d " " -f1) ${tar_num}.tar
eval mv $(ln -vs ../../$tar | cut -d " " -f1) ${tar_num}.tar
test -f ${tar_num}.tar
tar_num=$(expr $tar_num + 1)
done
cd ..

# Save the output from the bazel call (this is in an if because the bazel
# call is expected to fail, but should not terminate the script)
if out="$(bazel test --test_output=all //:test 2>&1)"
if out="$(bazel test --test_output=all //test_folder:test_for_failure 2>&1)"
then
exit 1;
fi
Expand All @@ -71,4 +76,3 @@ do
done

exit 0