mzimage.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. #
  10. # mzimage.py — builds Materialize-specific Docker images.
  11. import argparse
  12. import sys
  13. from typing import Any
  14. from materialize import MZ_ROOT, mzbuild, ui
  15. def main() -> int:
  16. args = _parse_args()
  17. ui.Verbosity.init_from_env(explicit=None)
  18. repo = mzbuild.Repository.from_arguments(MZ_ROOT, args)
  19. if args.command == "list":
  20. for image in repo:
  21. print(image.name)
  22. else:
  23. if args.image not in repo.images:
  24. print(f"fatal: unknown image: {args.image}", file=sys.stderr)
  25. return 1
  26. deps = repo.resolve_dependencies([repo.images[args.image]])
  27. rimage = deps[args.image]
  28. if args.command == "run":
  29. deps.acquire()
  30. rimage.run(args.image_args)
  31. elif args.command == "acquire":
  32. deps.acquire()
  33. elif args.command == "ensure":
  34. deps.ensure()
  35. elif args.command == "fingerprint":
  36. print(rimage.fingerprint())
  37. elif args.command == "spec":
  38. print(rimage.spec())
  39. elif args.command == "describe":
  40. inputs = sorted(rimage.inputs(args.transitive))
  41. dependencies = sorted(rimage.list_dependencies(args.transitive))
  42. print(f"Image: {rimage.name}")
  43. print(f"Fingerprint: {rimage.fingerprint()}")
  44. print("Input files:")
  45. for inp in inputs:
  46. print(f" {inp}")
  47. print("Dependencies:")
  48. for d in dependencies:
  49. print(f" {d}")
  50. if not dependencies:
  51. print(" (none)")
  52. else:
  53. raise RuntimeError("unreachable")
  54. return 0
  55. def _parse_args() -> argparse.Namespace:
  56. parser = argparse.ArgumentParser(
  57. prog="mzimage",
  58. formatter_class=argparse.RawDescriptionHelpFormatter,
  59. description="Swiss army knife for mzbuild images.",
  60. epilog="For additional help on a subcommand, run:\n\n %(prog)s <command> -h",
  61. )
  62. subparsers = parser.add_subparsers(
  63. dest="command", metavar="<command>", required=True
  64. )
  65. def add_subcommand(name: str, **kwargs: Any) -> argparse.ArgumentParser:
  66. subparser = subparsers.add_parser(name, **kwargs)
  67. mzbuild.Repository.install_arguments(subparser)
  68. return subparser
  69. def add_image_subcommand(name: str, **kwargs: Any) -> argparse.ArgumentParser:
  70. subparser = add_subcommand(name, **kwargs)
  71. subparser.add_argument(
  72. "image", help="the name of an mzbuild image in this repository"
  73. )
  74. return subparser
  75. add_subcommand(
  76. "list",
  77. description="List all images in this repository.",
  78. help="list all images",
  79. )
  80. add_image_subcommand(
  81. "acquire", description="Download or build an image.", help="acquire an image"
  82. )
  83. add_image_subcommand(
  84. "ensure",
  85. description="Ensure an image exists in the remote registry.",
  86. help="ensure an image",
  87. )
  88. run_parser = add_image_subcommand(
  89. "run", description="Acquire and run an image.", help="run an image"
  90. )
  91. run_parser.add_argument("image_args", nargs=argparse.REMAINDER)
  92. add_image_subcommand(
  93. "fingerprint",
  94. description="Compute the fingerprint for an image.",
  95. help="fingerprint an image",
  96. )
  97. add_image_subcommand(
  98. "spec",
  99. description="Compute the Docker Hub specification for an image.",
  100. help="compute image spec",
  101. )
  102. describe_parser = add_image_subcommand(
  103. "describe",
  104. description="Print information about an image.",
  105. help="show image details",
  106. )
  107. describe_parser.add_argument(
  108. "--transitive",
  109. action="store_true",
  110. help="compute transitive inputs and dependencies",
  111. )
  112. return parser.parse_args()
  113. if __name__ == "__main__":
  114. sys.exit(main())