You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
9.4 KiB

  1. #!/usr/bin/env python
  2. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  3. # not use this file except in compliance with the License. You may obtain
  4. # a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software
  9. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  10. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  11. # License for the specific language governing permissions and limitations
  12. # under the License.
  13. import copy
  14. import json
  15. import random
  16. import uuid
  17. from oslo_config import cfg
  18. from oslo_log import log
  19. from prettytable import PrettyTable
  20. import requests
  21. from faafo import version
  22. LOG = log.getLogger('faafo.client')
  23. CONF = cfg.CONF
  24. def get_random_task():
  25. random.seed()
  26. if CONF.command.width:
  27. width = int(CONF.command.width)
  28. else:
  29. width = random.randint(int(CONF.command.min_width),
  30. int(CONF.command.max_width))
  31. if CONF.command.height:
  32. height = int(CONF.command.height)
  33. else:
  34. height = random.randint(int(CONF.command.min_height),
  35. int(CONF.command.max_height))
  36. if CONF.command.iterations:
  37. iterations = int(CONF.command.iterations)
  38. else:
  39. iterations = random.randint(int(CONF.command.min_iterations),
  40. int(CONF.command.max_iterations))
  41. if CONF.command.xa:
  42. xa = float(CONF.command.xa)
  43. else:
  44. xa = random.uniform(float(CONF.command.min_xa),
  45. float(CONF.command.max_xa))
  46. if CONF.command.xb:
  47. xb = float(CONF.command.xb)
  48. else:
  49. xb = random.uniform(float(CONF.command.min_xb),
  50. float(CONF.command.max_xb))
  51. if CONF.command.ya:
  52. ya = float(CONF.command.ya)
  53. else:
  54. ya = random.uniform(float(CONF.command.min_ya),
  55. float(CONF.command.max_ya))
  56. if CONF.command.yb:
  57. yb = float(CONF.command.yb)
  58. else:
  59. yb = random.uniform(float(CONF.command.min_yb),
  60. float(CONF.command.max_yb))
  61. task = {
  62. 'uuid': str(uuid.uuid4()),
  63. 'width': width,
  64. 'height': height,
  65. 'iterations': iterations, 'xa': xa,
  66. 'xb': xb,
  67. 'ya': ya,
  68. 'yb': yb
  69. }
  70. return task
  71. def do_get_fractal():
  72. LOG.error("command 'download' not yet implemented")
  73. def do_show_fractal():
  74. LOG.info("showing fractal %s" % CONF.command.uuid)
  75. result = requests.get("%s/v1/fractal/%s" %
  76. (CONF.endpoint_url, CONF.command.uuid))
  77. if result.status_code == 200:
  78. data = json.loads(result.text)
  79. output = PrettyTable(["Parameter", "Value"])
  80. output.align["Parameter"] = "l"
  81. output.align["Value"] = "l"
  82. output.add_row(["uuid", data['uuid']])
  83. output.add_row(["duration", "%f seconds" % data['duration']])
  84. output.add_row(["dimensions", "%d x %d pixels" %
  85. (data['width'], data['height'])])
  86. output.add_row(["iterations", data['iterations']])
  87. output.add_row(["xa", data['xa']])
  88. output.add_row(["xb", data['xb']])
  89. output.add_row(["ya", data['ya']])
  90. output.add_row(["yb", data['yb']])
  91. output.add_row(["size", "%d bytes" % data['size']])
  92. output.add_row(["checksum", data['checksum']])
  93. output.add_row(["generated_by", data['generated_by']])
  94. print(output)
  95. else:
  96. LOG.error("fractal '%s' not found" % CONF.command.uuid)
  97. def do_list_fractals():
  98. LOG.info("listing all fractals")
  99. fractals = get_fractals()
  100. output = PrettyTable(["UUID", "Dimensions", "Filesize"])
  101. for fractal in fractals:
  102. output.add_row([
  103. fractal["uuid"],
  104. "%d x %d pixels" % (fractal["width"], fractal["height"]),
  105. "%d bytes" % (fractal["size"] or 0),
  106. ])
  107. print(output)
  108. def get_fractals(page=1):
  109. result = requests.get("%s/v1/fractal?page=%d" %
  110. (CONF.endpoint_url, page))
  111. fractals = []
  112. if result.status_code == 200:
  113. data = json.loads(result.text)
  114. if page < data['total_pages']:
  115. fractals = data['objects'] + get_fractals(page + 1)
  116. else:
  117. return data['objects']
  118. return fractals
  119. def do_delete_fractal():
  120. LOG.info("deleting fractal %s" % CONF.command.uuid)
  121. result = requests.delete("%s/v1/fractal/%s" %
  122. (CONF.endpoint_url, CONF.command.uuid))
  123. LOG.debug("result: %s" %result)
  124. def do_create_fractal():
  125. random.seed()
  126. if CONF.command.tasks:
  127. number = int(CONF.command.tasks)
  128. else:
  129. number = random.randint(int(CONF.command.min_tasks),
  130. int(CONF.command.max_tasks))
  131. LOG.info("generating %d task(s)" % number)
  132. for i in xrange(0, number):
  133. task = get_random_task()
  134. LOG.debug("created task %s" % task)
  135. # NOTE(berendt): only necessary when using requests < 2.4.2
  136. headers = {'Content-type': 'application/json',
  137. 'Accept': 'text/plain'}
  138. requests.post("%s/v1/fractal" % CONF.endpoint_url,
  139. json.dumps(task), headers=headers)
  140. def add_command_parsers(subparsers):
  141. parser = subparsers.add_parser('create')
  142. parser.set_defaults(func=do_create_fractal)
  143. parser.add_argument("--height", default=None,
  144. help="The height of the generate image.")
  145. parser.add_argument("--min-height", default=256,
  146. help="The minimum height of the generate image.")
  147. parser.add_argument("--max-height", default=1024,
  148. help="The maximum height of the generate image.")
  149. parser.add_argument("--width", default=None,
  150. help="The width of the generated image.")
  151. parser.add_argument("--min-width", default=256,
  152. help="The minimum width of the generated image.")
  153. parser.add_argument("--max-width", default=1024,
  154. help="The maximum width of the generated image.")
  155. parser.add_argument("--iterations", default=None,
  156. help="The number of iterations.")
  157. parser.add_argument("--min-iterations", default=128,
  158. help="The minimum number of iterations.")
  159. parser.add_argument("--max-iterations", default=512,
  160. help="The maximum number of iterations.")
  161. parser.add_argument("--tasks", default=None,
  162. help="The number of generated fractals.")
  163. parser.add_argument("--min-tasks", default=1,
  164. help="The minimum number of generated fractals.")
  165. parser.add_argument("--max-tasks", default=10,
  166. help="The maximum number of generated fractals.")
  167. parser.add_argument("--xa", default=None,
  168. help="The value for the parameter 'xa'.")
  169. parser.add_argument("--min-xa", default=-1.0,
  170. help="The minimum value for the parameter 'xa'.")
  171. parser.add_argument("--max-xa", default=-4.0,
  172. help="The maximum value for the parameter 'xa'.")
  173. parser.add_argument("--xb", default=None,
  174. help="The value for the parameter 'xb'.")
  175. parser.add_argument("--min-xb", default=1.0,
  176. help="The minimum value for the parameter 'xb'.")
  177. parser.add_argument("--max-xb", default=4.0,
  178. help="The maximum value for the parameter 'xb'.")
  179. parser.add_argument("--ya", default=None,
  180. help="The value for the parameter 'ya'.")
  181. parser.add_argument("--min-ya", default=-0.5,
  182. help="The minimum value for the parameter 'ya'.")
  183. parser.add_argument("--max-ya", default=-3,
  184. help="The maximum value for the parameter 'ya'.")
  185. parser.add_argument("--yb", default=None,
  186. help="The value for the parameter 'yb'.")
  187. parser.add_argument("--min-yb", default=0.5,
  188. help="The minimum value for the parameter 'yb'.")
  189. parser.add_argument("--max-yb", default=3,
  190. help="The maximum value for the parameter 'yb'.")
  191. parser = subparsers.add_parser('delete')
  192. parser.set_defaults(func=do_delete_fractal)
  193. parser.add_argument("uuid", help="Fractal to delete.")
  194. parser = subparsers.add_parser('show')
  195. parser.set_defaults(func=do_show_fractal)
  196. parser.add_argument("uuid", help="Fractal to show.")
  197. parser = subparsers.add_parser('get')
  198. parser.set_defaults(func=do_get_fractal)
  199. parser.add_argument("uuid", help="Fractal to download.")
  200. parser = subparsers.add_parser('list')
  201. parser.set_defaults(func=do_list_fractals)
  202. client_commands = cfg.SubCommandOpt('command', title='Commands',
  203. help='Show available commands.',
  204. handler=add_command_parsers)
  205. CONF.register_cli_opts([client_commands])
  206. client_cli_opts = [
  207. cfg.StrOpt('endpoint-url',
  208. default='http://localhost',
  209. help='API connection URL')
  210. ]
  211. CONF.register_cli_opts(client_cli_opts)
  212. if __name__ == '__main__':
  213. log.register_options(CONF)
  214. log.set_defaults()
  215. CONF(project='client', prog='faafo-client',
  216. version=version.version_info.version_string())
  217. log.setup(CONF, 'client',
  218. version=version.version_info.version_string())
  219. CONF.command.func()