| Line | Revision | Contents |
| 1 | 118 | #!/usr/bin/python |
| 2 | # |
|
| 3 | # powernap_calculator - estimate power savings using statistcal analysis |
|
| 4 | # Copyright (C) 2009 Canonical Ltd. |
|
| 5 | # |
|
| 6 | # Authors: Dustin Kirkland <kirkland@canonical.com> |
|
| 7 | # |
|
| 8 | # This program is free software: you can redistribute it and/or modify |
|
| 9 | # it under the terms of the GNU General Public License as published by |
|
| 10 | # the Free Software Foundation, version 3 of the License. |
|
| 11 | # |
|
| 12 | # This program is distributed in the hope that it will be useful, |
|
| 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 15 | # GNU General Public License for more details. |
|
| 16 | # |
|
| 17 | # You should have received a copy of the GNU General Public License |
|
| 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
| 19 | ||
| 20 | ||
| 21 | import getopt |
|
| 22 | import sys |
|
| 23 | ||
| 24 | 128 | # command line options |
| 25 | 118 | short_opts = 'h:p:g:' |
| 26 | long_opts = ['hosts=', 'guests-per-host=', 'guests='] |
|
| 27 | usage_string = "Usage:\n powernap_calculator [-h|--hosts NUM] [-p|--guests-per-host NUM] [-g|--guests NUM]" |
|
| 28 | ||
| 29 | 124 | if len(sys.argv) != 7: |
| 30 | 123 | print(usage_string) |
| 31 | exit(1) |
|
| 32 | ||
| 33 | 118 | # parse getopt options |
| 34 | try: |
|
| 35 | opts, args = getopt.getopt(sys.argv[1:], short_opts, long_opts) |
|
| 36 | for k, v in opts: |
|
| 37 | if k in ('-h', '--hosts'): |
|
| 38 | hosts = int(v) |
|
| 39 | elif k in ('-p', '--guests-per-host'): |
|
| 40 | guests_per_host = int(v) |
|
| 41 | elif k in ('-g', '--guests'): |
|
| 42 | guests = int(v) |
|
| 43 | else: |
|
| 44 | print(usage_string) |
|
| 45 | exit(1) |
|
| 46 | except: |
|
| 47 | print(usage_string) |
|
| 48 | exit(1) |
|
| 49 | ||
| 50 | 128 | # convert an input num to a different base with each |
| 51 | # digit as an element in the list; |
|
| 52 | # ensure that the sum of the digits equals the number of guests; |
|
| 53 | # return the list representing the way vm's are allocated across hosts |
|
| 54 | def vm_allocations(num, base, hosts, guests): |
|
| 55 | 118 | list = [0]*hosts |
| 56 | i = 0 |
|
| 57 | while num != 0: |
|
| 58 | remainder = num % base |
|
| 59 | list[i] = remainder |
|
| 60 | i += 1 |
|
| 61 | num = num / base |
|
| 62 | if sum(list) == guests: |
|
| 63 | return list |
|
| 64 | else: |
|
| 65 | return -1 |
|
| 66 | ||
| 67 | 128 | # count the number of zero's found in the list |
| 68 | 118 | def count_zeros(list): |
| 69 | count = 0 |
|
| 70 | for i in list: |
|
| 71 | if i == 0: |
|
| 72 | count += 1 |
|
| 73 | return count |
|
| 74 | ||
| 75 | print("Calculating...\n ") |
|
| 76 | 128 | # this might be a *very* big number |
| 77 | 118 | upper_limit = (guests_per_host+1)**hosts |
| 78 | zeros = [0]*(hosts + 1) |
|
| 79 | total = 0 |
|
| 80 | 127 | num = 0 |
| 81 | 128 | # brute force all possible combinations |
| 82 | 127 | while num < upper_limit: |
| 83 | 128 | # determine the associated vm_allocations for this particular index |
| 84 | 118 | list = vm_allocations(num, guests_per_host+1, hosts, guests) |
| 85 | if list != -1: |
|
| 86 | 128 | # count the zeros in this list |
| 87 | 118 | c = count_zeros(list) |
| 88 | zeros[c] += 1 |
|
| 89 | total += 1 |
|
| 90 | 128 | # print a helpful running percent-done |
| 91 | 118 | if num % 100000 == 0: |
| 92 | 127 | print("\b\b\b\b\b\b\b\b\b\b%.3f%% " % (100.*num/upper_limit)) |
| 93 | num += 1 |
|
| 94 | 118 | |
| 95 | 126 | print("\nIn a cloud with [%d] hosts, which can handle [%d] guests-per-host, currently running [%d] guests,\nyou may expect the following:\n" % (hosts, guests_per_host, guests)) |
| 96 | 118 | |
| 97 | expected_savings = 0 |
|
| 98 | #print zeros |
|
| 99 | 128 | # do the calculations |
| 100 | 118 | for i in range(0, len(zeros)): |
| 101 | if zeros[i] > 0: |
|
| 102 | probability = 1. * zeros[i] / total |
|
| 103 | if probability > 0 and probability < .01: |
|
| 104 | pstr = "<1" |
|
| 105 | else: |
|
| 106 | pstr = "%.1f" % (100. * probability) |
|
| 107 | savings = 100.*i/hosts |
|
| 108 | print("[%5s%%] likely that [%d/%d] of your hosts would powernap, for a [%.0f%%] power savings" % (pstr, i, hosts, savings)) |
|
| 109 | expected_savings += probability * savings |
|
| 110 | ||
| 111 | print("\nThe overall expected value is [%.1f%%] power savings." % expected_savings) |
|
| 112 | ||
| 113 | exit(0) |
Loggerhead 1.10 is a web-based interface for Bazaar branches