-
Notifications
You must be signed in to change notification settings - Fork 5
Added support for 'grid_accounting' daemon #420
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
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
138f2e8
Added support for 'grid_accounting' daemon
Martin-Rehr 4f537f1
Fixed 'quota' vs. 'accounting' copy paste error
Martin-Rehr c84c47f
Fixed 'verbose' variable issue
Martin-Rehr ec79346
Added accounting to MiGserver--customised tests
Martin-Rehr cee7f77
Added accounting options to generateconfs
Martin-Rehr 83d0133
Changed 'accounting' name to 'showaccounting' as suggested by @jonasb…
Martin-Rehr fecb7cf
Fixed typos thanks to @jonasbardino
Martin-Rehr 8811c32
Replaced 'GDP' with mig.shared.gdp_distinguished_field as suggested b…
Martin-Rehr 5882a16
Updated doc-string and startup text as suggested by @jonasbardino
Martin-Rehr 8e39182
Removed 'lustre' reference as suggested by @jonasbardino
Martin-Rehr 5be5964
Adjusted import order as suggested by @jonasbardino
Martin-Rehr 1601adf
Fixed copy/paste quota -> accounting leftover as suggested by @jonasb…
Martin-Rehr 6a03b1d
Removed explicit 'keys' extraction from dict when creating list of di…
Martin-Rehr 08d6799
Cleaned up unittest as suggested by @jonasbardino
Martin-Rehr 4211761
Merge branch 'next' into addition/storage-usage-accounting
Martin-Rehr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,193 @@ | ||
| #!/usr/bin/env python | ||
| # -*- coding: utf-8 -*- | ||
| # | ||
| # --- BEGIN_HEADER --- | ||
| # | ||
| # showaccounting - Display storage accounting | ||
| # Copyright (C) 2003-2026 The MiG Project by the Science HPC Center at UCPH | ||
| # | ||
| # This file is part of MiG. | ||
| # | ||
| # MiG is free software: you can redistribute it and/or modify | ||
| # it under the terms of the GNU General Public License as published by | ||
| # the Free Software Foundation; either version 2 of the License, or | ||
| # (at your option) any later version. | ||
| # | ||
| # MiG is distributed in the hope that it will be useful, | ||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| # GNU General Public License for more details. | ||
| # | ||
| # You should have received a copy of the GNU General Public License | ||
| # along with this program; if not, write to the Free Software | ||
| # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
|
Check warning on line 23 in bin/showaccounting.py
|
||
| # | ||
| # -- END_HEADER --- | ||
| # | ||
|
|
||
| """Create accounting information for users""" | ||
|
|
||
| from __future__ import absolute_import, print_function | ||
|
|
||
| import datetime | ||
| import getopt | ||
| import re | ||
| import sys | ||
|
|
||
| from mig.lib.accounting import get_usage, human_readable_filesize | ||
| from mig.shared.conf import get_configuration_object | ||
| from mig.shared.defaults import gdp_distinguished_field | ||
|
|
||
|
|
||
| def usage(name='showaccounting.py'): | ||
| """Usage help""" | ||
|
|
||
| print("""Create accounting information based on quota. | ||
| Usage: | ||
| %(name)s [ACCOUNTING_OPTIONS] | ||
| Where ACCOUNTING_OPTIONS may be one or more of: | ||
| -h Show this help | ||
| -v Verbose output | ||
| -c CONF_FILE Use CONF_FILE as server configuration | ||
| -f User filter Regex user (CERT_DN) filter | ||
| -m Minimum usage Only show accounts using more than | ||
| minimum usage (TB). | ||
| -t TIMESTAMP Use specific timestamp, latest if unset | ||
| """ % {'name': name}) | ||
|
|
||
|
|
||
| def show_accounting(configuration, | ||
| timestamp, | ||
| user_filter, | ||
| minimum_usage, | ||
| verbose): | ||
| """Print user accounting report""" | ||
| user_filter_re = None | ||
| if user_filter: | ||
| try: | ||
| user_filter_re = re.compile(user_filter) | ||
| except Exception as err: | ||
| print("ERROR: Failed to compile user_filter: %r error: %s" | ||
| % (user_filter, err)) | ||
| return | ||
|
|
||
| usage = get_usage(configuration, | ||
| timestamp=timestamp, | ||
| verbose=verbose) | ||
|
|
||
| accounting = usage.get('accounting', {}) | ||
| accounting_timestamp = usage.get('timestamp', 0) | ||
| accounting_datestr \ | ||
| = datetime.datetime.fromtimestamp(accounting_timestamp) \ | ||
| .strftime('%d/%m/%Y-%H:%M:%S') | ||
|
|
||
| # Sorted by total bytes and print usage for users | ||
|
|
||
| report_total_users = 0 | ||
| report_shown_users = 0 | ||
| report_total_bytes = 0 | ||
| report_shown_bytes = 0 | ||
| total_bytes_map = {} | ||
| for username, values in accounting.items(): | ||
| # Do not show GDP project users | ||
| # projects are accounted for by the main user | ||
| if configuration.site_enable_gdp \ | ||
| and username.find("/%s=" % gdp_distinguished_field) != -1: | ||
| continue | ||
| report_total_users += 1 | ||
| total_bytes = values.get('total_bytes', 0) | ||
| report_total_bytes += total_bytes | ||
| if total_bytes < minimum_usage \ | ||
| or user_filter_re and not user_filter_re.fullmatch(username): | ||
| continue | ||
| report_shown_users += 1 | ||
| report_shown_bytes += total_bytes | ||
| total_bytes_map_userlist = total_bytes_map.get(total_bytes, []) | ||
| total_bytes_map_userlist.append(username) | ||
| total_bytes_map[total_bytes] = total_bytes_map_userlist | ||
| sorted_total_bytes = sorted(list(total_bytes_map), reverse=True) | ||
|
|
||
| print("\nAccounting (%d) %s for storage quota(s):" | ||
| % (accounting_timestamp, accounting_datestr)) | ||
| for quota_fs, values in usage.get('quota', {}).items(): | ||
| quota_mtime = values.get('mtime', 0) | ||
| quota_datestr = datetime.datetime.fromtimestamp(quota_mtime) \ | ||
| .strftime('%d/%m/%Y-%H:%M:%S') | ||
| print(" - %s (%d) %s" % (quota_fs, | ||
| quota_mtime, | ||
| quota_datestr)) | ||
|
|
||
| print("Found a total of %s users using %s storage" | ||
| % (report_total_users, | ||
| human_readable_filesize(report_total_bytes))) | ||
| print("Showing details for %s users using %s storage " | ||
| % (report_shown_users, | ||
| human_readable_filesize(report_shown_bytes))) | ||
| print("User filter: %r" % user_filter) | ||
| print("Minimum usage: %s" % human_readable_filesize(minimum_usage)) | ||
| for total_bytes in sorted_total_bytes: | ||
| total_bytes_human = human_readable_filesize(total_bytes) | ||
| for username in total_bytes_map[total_bytes]: | ||
| report = accounting[username] | ||
| home_report = report.get('home_report', '') | ||
| freeze_report = report.get('freeze_report', '') | ||
| vgrid_report = report.get('vgrid_report', '') | ||
| ext_users_report = report.get('ext_users_report', '') | ||
| peers_report = report.get('peers_report', '') | ||
| print("\n%s:" % username) | ||
| print("Total usage: %s" % total_bytes_human) | ||
| if home_report: | ||
| print(home_report) | ||
| if freeze_report: | ||
| print(freeze_report) | ||
| if vgrid_report: | ||
| print(vgrid_report) | ||
| if ext_users_report: | ||
| print(ext_users_report) | ||
| if peers_report: | ||
| print(peers_report) | ||
|
|
||
|
|
||
| if '__main__' == __name__: | ||
| conf_path = None | ||
| user_filter = None | ||
| timestamp = 0 | ||
| minimum_usage = 0 | ||
| verbose = False | ||
| opt_args = 'hvc:f:m:t:' | ||
| try: | ||
| (opts, args) = getopt.getopt(sys.argv[1:], opt_args) | ||
| for (opt, val) in opts: | ||
| if opt == '-h': | ||
| usage() | ||
| sys.exit(0) | ||
| if opt == '-v': | ||
| verbose = True | ||
| elif opt == '-c': | ||
| conf_path = val | ||
| elif opt == '-f': | ||
| user_filter = val | ||
| elif opt == '-m': | ||
| minimum_usage = float(val)*(1024**4) | ||
|
Check failure on line 171 in bin/showaccounting.py
|
||
| elif opt == '-t': | ||
| timestamp = int(val) | ||
| else: | ||
| print('Error: %s not supported!' % opt) | ||
| usage() | ||
| sys.exit(1) | ||
| except getopt.GetoptError as err: | ||
| print('Error: ', err.msg) | ||
| usage() | ||
| sys.exit(1) | ||
|
|
||
| configuration = get_configuration_object(config_file=conf_path, | ||
| skip_log=True, | ||
| disable_auth_log=True) | ||
|
|
||
| show_accounting(configuration, | ||
| timestamp, | ||
| user_filter, | ||
| minimum_usage, | ||
| verbose) | ||
|
|
||
| sys.exit(0) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.