install pmu tools collectd plugin
[yardstick.git] / ansible / roles / download_pmu_tools / files / event_download_local.py
1 #!/usr/bin/env python
2 # Copyright (c) 2014, Intel Corporation
3 # Author: Andi Kleen
4 #
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms and conditions of the GNU General Public License,
7 # version 2, as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12 # more details.
13 #
14 # Automatic event list downloader
15 #
16 # event_download.py         download for current cpu
17 # event_download.py -a      download all
18 # event_download.py cpustr...  Download for specific CPU
19 import sys
20 import re
21 from urllib2 import urlopen, URLError
22 import os
23 import string
24 from fnmatch import fnmatch
25 from shutil import copyfile
26
27 urlpath = 'https://download.01.org/perfmon'
28 localpath = 'download.01.org/perfmon'
29 mapfile = 'mapfile.csv'
30 modelpath = localpath + "/" + mapfile
31 NSB_JSON = '/opt/nsb_bin/pmu_event.json'
32
33 def get_cpustr():
34     f = open('/proc/cpuinfo', 'r')
35     cpu = [None, None, None]
36     for j in f:
37         n = j.split()
38         if n[0] == 'vendor_id':
39             cpu[0] = n[2]
40         elif n[0] == 'model' and n[1] == ':':
41             cpu[2] = int(n[2])
42         elif n[0] == 'cpu' and n[1] == 'family':
43             cpu[1] = int(n[3])
44         if all(cpu):
45             break
46     return "%s-%d-%X" % (cpu[0], cpu[1], cpu[2])
47
48 def sanitize(s, a):
49     o = ""
50     for j in s:
51         if j in a:
52             o += j
53     return o
54
55 def getdir():
56     try:
57         d = os.getenv("XDG_CACHE_HOME")
58         xd = d
59         if not d:
60             home = os.getenv("HOME")
61             d = "%s/.cache" % (home)
62         d += "/pmu-events"
63         if not os.path.isdir(d):
64             # try to handle the sudo case
65             if not xd:
66                 user = os.getenv("SUDO_USER")
67                 if user:
68                     nd = os.path.expanduser("~" + user) + "/.cache/pmu-events"
69                     if os.path.isdir(nd):
70                         return nd
71             os.makedirs(d)
72         return d
73     except OSError:
74         raise Exception('Cannot access ' + d)
75
76 NUM_TRIES = 3
77
78 def getfile(url, dir, fn):
79     tries = 0
80     print "Downloading", url, "to", fn
81     while True:
82         try:
83             f = open(url)
84             data = f.read()
85         except IOError:
86             tries += 1
87             if tries >= NUM_TRIES:
88                 raise
89             print "retrying download"
90             continue
91         break
92     o = open(os.path.join(dir, fn), "w")
93     o.write(data)
94     o.close()
95     f.close()
96
97 allowed_chars = string.ascii_letters + '_-.' + string.digits
98 def download(match, key=None, link=True):
99     found = 0
100     dir = getdir()
101     try:
102         getfile(modelpath, dir, "mapfile.csv")
103         models = open(os.path.join(dir, "mapfile.csv"))
104         for j in models:
105             n = j.rstrip().split(",")
106             if len(n) < 4:
107                 if len(n) > 0:
108                     print "Cannot parse", n
109                 continue
110             cpu, version, name, type = n
111             if not fnmatch(cpu, match) or (key is not None and type not in key) or type.startswith("EventType"):
112                 continue
113             cpu = sanitize(cpu, allowed_chars)
114             url = localpath + name
115             fn = "%s-%s.json" % (cpu, sanitize(type, allowed_chars))
116             try:
117                 os.remove(os.path.join(dir, fn))
118             except OSError:
119                 pass
120             getfile(url, dir, fn)
121             if link:
122                 lname = re.sub(r'.*/', '', name)
123                 lname = sanitize(lname, allowed_chars)
124                 try:
125                     os.remove(os.path.join(dir, lname))
126                 except OSError:
127                     pass
128                 try:
129                     os.symlink(fn, os.path.join(dir, lname))
130                 except OSError as e:
131                     print >>sys.stderr, "Cannot link %s to %s:" % (name, lname), e
132             found += 1
133         models.close()
134         getfile(localpath + "/readme.txt", dir, "readme.txt")
135     except URLError as e:
136         print >>sys.stderr, "Cannot access event server:", e
137         print >>sys.stderr, "If you need a proxy to access the internet please set it with:"
138         print >>sys.stderr, "\texport https_proxy=http://proxyname..."
139         print >>sys.stderr, "If you are not connected to the internet please run this on a connected system:"
140         print >>sys.stderr, "\tevent_download.py '%s'" % (match)
141         print >>sys.stderr, "and then copy ~/.cache/pmu-events to the system under test"
142         print >>sys.stderr, "To get events for all possible CPUs use:"
143         print >>sys.stderr, "\tevent_download.py -a"
144     except OSError as e:
145         print >>sys.stderr, "Cannot write events file:", e
146     return found
147
148 def download_current(link=False):
149     """Download JSON event list for current cpu.
150        Returns >0 when a event list is found"""
151     return download(get_cpustr(), link=link)
152
153 def eventlist_name(name=None, key="core"):
154     if not name:
155         name = get_cpustr()
156     cache = getdir()
157     return "%s/%s-%s.json" % (cache, name, key)
158
159 if __name__ == '__main__':
160     # only import argparse when actually called from command line
161     # this makes ocperf work on older python versions without it.
162     import argparse
163     p = argparse.ArgumentParser(usage='download Intel event files')
164     p.add_argument('--all', '-a', help='Download all available event files', action='store_true')
165     p.add_argument('--verbose', '-v', help='Be verbose', action='store_true')
166     p.add_argument('--mine', help='Print name of current CPU', action='store_true')
167     p.add_argument('--link', help='Create links with the original event file name', action='store_true', default=True)
168     p.add_argument('cpus', help='CPU identifiers to download', nargs='*')
169     args = p.parse_args()
170
171     cpustr = get_cpustr()
172     if args.verbose or args.mine:
173         print "My CPU", cpustr
174     if args.mine:
175         sys.exit(0)
176     d = getdir()
177     if args.all:
178         found = download('*', link=args.link)
179     elif len(args.cpus) == 0:
180         found = download_current(link=args.link)
181     else:
182         found = 0
183         for j in args.cpus:
184             found += download(j, link=args.link)
185
186     if found == 0:
187         print >>sys.stderr, "Nothing found"
188
189     el = eventlist_name()
190     if os.path.exists(el):
191         print "my event list", el 
192         copyfile(el,NSB_JSON)
193         print "File copied to ", NSB_JSON