Manually added OpenStack API code
[osm/vim-emu.git] / src / emuvim / api / openstack / docker_util.py
1 from docker import DockerClient, APIClient
2 import time
3 import re
4
5
6 def docker_container_id(container_name):
7 """
8 Uses the container name to return the container ID.
9
10 :param container_name: The full name of the docker container.
11 :type container_name: ``str``
12 :return: Returns the container ID or None if the container is not running or could not be found.
13 :rtype: ``dict``
14 """
15 c = APIClient()
16 detail = c.inspect_container(container_name)
17 if bool(detail["State"]["Running"]):
18 return detail['Id']
19 return None
20
21
22 def docker_abs_cpu(container_id):
23 """
24 Returns the used CPU time since container startup and the system time in nanoseconds and returns the number
25 of available CPU cores.
26
27 :param container_id: The full ID of the docker container.
28 :type container_id: ``str``
29 :return: Returns a dict with CPU_used in nanoseconds, the current system time in nanoseconds and the number of
30 CPU cores available.
31 :rtype: ``dict``
32 """
33 with open('/sys/fs/cgroup/cpuacct/docker/' + container_id + '/cpuacct.usage_percpu', 'r') as f:
34 line = f.readline()
35 sys_time = int(time.time() * 1000000000)
36 numbers = [int(x) for x in line.split()]
37 cpu_usage = 0
38 for number in numbers:
39 cpu_usage += number
40 return {'CPU_used': cpu_usage, 'CPU_used_systime': sys_time, 'CPU_cores': len(numbers)}
41
42
43 def docker_mem_used(container_id):
44 """
45 Bytes of memory used from the docker container.
46
47 Note: If you have problems with this command you have to enable memory control group.
48 For this you have to add the following kernel parameters: `cgroup_enable=memory swapaccount=1`.
49 See: https://docs.docker.com/engine/admin/runmetrics/
50
51 :param container_id: The full ID of the docker container.
52 :type container_id: ``str``
53 :return: Returns the memory utilization in bytes.
54 :rtype: ``str``
55 """
56 with open('/sys/fs/cgroup/memory/docker/' + container_id + '/memory.usage_in_bytes', 'r') as f:
57 return int(f.readline())
58
59
60 def docker_max_mem(container_id):
61 """
62 Bytes of memory the docker container could use.
63
64 :param container_id: The full ID of the docker container.
65 :type container_id: ``str``
66 :return: Returns the bytes of memory the docker container could use.
67 :rtype: ``str``
68 """
69 with open('/sys/fs/cgroup/memory/docker/' + container_id + '/memory.limit_in_bytes', 'r') as f:
70 mem_limit = int(f.readline())
71 with open('/proc/meminfo', 'r') as f:
72 line = f.readline().split()
73 sys_value = int(line[1])
74 unit = line[2]
75 if unit == 'kB':
76 sys_value *= 1024
77 if unit == 'MB':
78 sys_value *= 1024 * 1024
79
80 if sys_value < mem_limit:
81 return sys_value
82 else:
83 return mem_limit
84
85
86 def docker_mem(container_id):
87 """
88 Calculates the current, maximal and percentage usage of the specified docker container.
89
90 :param container_id: The full ID of the docker container.
91 :type container_id: ``str``
92 :return: Returns a dictionary with the total memory usage, the maximal available memory and the percentage
93 memory usage.
94 :rtype: ``dict``
95 """
96 out_dict = dict()
97 out_dict['MEM_used'] = docker_mem_used(container_id)
98 out_dict['MEM_limit'] = docker_max_mem(container_id)
99 out_dict['MEM_%'] = float(out_dict['MEM_used']) / float(out_dict['MEM_limit'])
100 return out_dict
101
102
103 def docker_abs_net_io(container_id):
104 """
105 Network traffic of all network interfaces within the controller.
106
107 :param container_id: The full ID of the docker container.
108 :type container_id: ``str``
109 :return: Returns the absolute network I/O till container startup, in bytes. The return dict also contains the
110 system time.
111 :rtype: ``dict``
112 """
113 c = APIClient()
114 command = c.exec_create(container_id, 'ifconfig')
115 ifconfig = c.exec_start(command['Id'])
116 sys_time = int(time.time() * 1000000000)
117
118 in_bytes = 0
119 m = re.findall('RX bytes:(\d+)', str(ifconfig))
120 if m:
121 for number in m:
122 in_bytes += int(number)
123 else:
124 in_bytes = None
125
126 out_bytes = 0
127 m = re.findall('TX bytes:(\d+)', str(ifconfig))
128 if m:
129 for number in m:
130 out_bytes += int(number)
131 else:
132 out_bytes = None
133
134 return {'NET_in': in_bytes, 'NET_out': out_bytes, 'NET_systime': sys_time}
135
136
137 def docker_block_rw(container_id):
138 """
139 Determines the disk read and write access from the controller since startup.
140
141 :param container_id: The full ID of the docker container.
142 :type container_id: ``str``
143 :return: Returns a dictionary with the total disc I/O since container startup, in bytes.
144 :rtype: ``dict``
145 """
146 with open('/sys/fs/cgroup/blkio/docker/' + container_id + '/blkio.throttle.io_service_bytes', 'r') as f:
147 read = f.readline().split()
148 write = f.readline().split()
149 rw_dict = dict()
150 rw_dict['BLOCK_systime'] = int(time.time() * 1000000000)
151 if len(read) < 3:
152 rw_dict['BLOCK_read'] = 0
153 else:
154 rw_dict['BLOCK_read'] = read[2]
155 if len(write) < 3:
156 rw_dict['BLOCK_write'] = 0
157 else:
158 rw_dict['BLOCK_write'] = write[2]
159 return rw_dict
160
161
162 def docker_PIDS(container_id):
163 """
164 Determines the number of processes within the docker container.
165
166 :param container_id: The full ID of the docker container.
167 :type container_id: ``str``
168 :return: Returns the number of PIDS within a dictionary.
169 :rtype: ``dict``
170 """
171 with open('/sys/fs/cgroup/cpuacct/docker/' + container_id + '/tasks', 'r') as f:
172 return {'PIDS': len(f.read().split('\n')) - 1}
173
174
175 def monitoring_over_time(container_id):
176 """
177 Calculates the cpu workload and the network traffic per second.
178
179 :param container_id: The full docker container ID
180 :type container_id: ``str``
181 :return: A dictionary with disk read and write per second, network traffic per second (in and out),
182 the cpu workload and the number of cpu cores available.
183 :rtype: ``dict``
184 """
185 first_cpu_usage = docker_abs_cpu(container_id)
186 first = docker_abs_net_io(container_id)
187 first_disk_io = docker_block_rw(container_id)
188 time.sleep(1)
189 second_cpu_usage = docker_abs_cpu(container_id)
190 second = docker_abs_net_io(container_id)
191 second_disk_io = docker_block_rw(container_id)
192
193 # Disk access
194 time_div = (int(second_disk_io['BLOCK_systime']) - int(first_disk_io['BLOCK_systime']))
195 read_div = int(second_disk_io['BLOCK_read']) - int(first_disk_io['BLOCK_read'])
196 write_div = int(second_disk_io['BLOCK_write']) - int(first_disk_io['BLOCK_write'])
197 out_dict = {'BLOCK_read/s': int(read_div * 1000000000 / float(time_div) + 0.5),
198 'BLOCK_write/s': int(write_div * 1000000000 / float(time_div) + 0.5)}
199
200 # Network traffic
201 time_div = (int(second['NET_systime']) - int(first['NET_systime']))
202 in_div = int(second['NET_in']) - int(first['NET_in'])
203 out_div = int(second['NET_out']) - int(first['NET_out'])
204 out_dict.update({'NET_in/s': int(in_div * 1000000000 / float(time_div) + 0.5),
205 'NET_out/s': int(out_div * 1000000000 / float(time_div) + 0.5)})
206
207 # CPU utilization
208 time_div = (int(second_cpu_usage['CPU_used_systime']) - int(first_cpu_usage['CPU_used_systime']))
209 usage_div = int(second_cpu_usage['CPU_used']) - int(first_cpu_usage['CPU_used'])
210 out_dict.update({'CPU_%': usage_div / float(time_div), 'CPU_cores': first_cpu_usage['CPU_cores']})
211 return out_dict