blob: 145bf4ea03c9e62a6a56edc2fa996b6fc136582c [file] [log] [blame]
John DeNisco68b0ee32017-09-27 16:35:23 -04001#!/usr/bin/python
2
3# Copyright (c) 2016 Cisco and/or its affiliates.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at:
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16"""VPP Configuration Main Entry"""
17
18import re
19import os
20import sys
21import logging
John DeNiscoddecfb32017-11-15 08:50:57 -050022import argparse
John DeNisco68b0ee32017-09-27 16:35:23 -040023
24from vpplib.AutoConfig import AutoConfig
25from vpplib.VPPUtil import VPPUtil
26
27VPP_DRYRUNDIR = '/vpp/vpp-config/dryrun'
28VPP_AUTO_CONFIGURATION_FILE = '/vpp/vpp-config/configs/auto-config.yaml'
29VPP_HUGE_PAGE_FILE = '/vpp/vpp-config/dryrun/sysctl.d/80-vpp.conf'
30VPP_STARTUP_FILE = '/vpp/vpp-config/dryrun/vpp/startup.conf'
31VPP_GRUB_FILE = '/vpp/vpp-config/dryrun/default/grub'
32VPP_REAL_HUGE_PAGE_FILE = '/etc/sysctl.d/80-vpp.conf'
33VPP_REAL_STARTUP_FILE = '/etc/vpp/startup.conf'
34VPP_REAL_GRUB_FILE = '/etc/default/grub'
35
36rootdir = ''
37
38
39def autoconfig_yn(question, default):
40 """
41 Ask the user a yes or no question.
42
43 :param question: The text of the question
44 :param default: Value to be returned if '\n' is entered
45 :type question: string
46 :type default: string
47 :returns: The Answer
48 :rtype: string
49 """
50 input_valid = False
51 default = default.lower()
52 answer = ''
53 while not input_valid:
54 answer = raw_input(question)
55 if len(answer) == 0:
56 answer = default
57 if re.findall(r'[YyNn]', answer):
58 input_valid = True
59 answer = answer[0].lower()
60 else:
61 print "Please answer Y, N or Return."
62
63 return answer
64
65
66def autoconfig_cp(node, src, dst):
67 """
68 Copies a file, saving the original if needed.
69
70 :param node: Node dictionary with cpuinfo.
71 :param src: Source File
72 :param dst: Destination file
73 :type node: dict
74 :type src: string
75 :type dst: string
76 :raises RuntimeError: If command fails
77 """
78
79 # If the destination file exist, create a copy if one does not already
80 # exist
81 ofile = dst + '.orig'
82 (ret, stdout, stderr) = VPPUtil.exec_command('ls {}'.format(dst))
83 if ret == 0:
84 cmd = 'cp {} {}'.format(dst, ofile)
85 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
86 if ret != 0:
87 raise RuntimeError('{} failed on node {} {} {}'.
88 format(cmd,
89 node['host'],
90 stdout,
91 stderr))
92
93 # Copy the source file
94 cmd = 'cp {} {}'.format(src, os.path.dirname(dst))
95 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
96 if ret != 0:
97 raise RuntimeError('{} failed on node {} {}'.
98 format(cmd, node['host'], stderr))
99
100
101def autoconfig_diff(node, src, dst):
102 """
103 Returns the diffs of 2 files.
104
105 :param node: Node dictionary with cpuinfo.
106 :param src: Source File
107 :param dst: Destination file
108 :type node: dict
109 :type src: string
110 :type dst: string
111 :returns: The Answer
112 :rtype: string
113 :raises RuntimeError: If command fails
114 """
115
116 # Diff the files and return the output
117 cmd = "diff {} {}".format(src, dst)
118 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
119 if stderr != '':
120 raise RuntimeError('{} failed on node {} {} {}'.
121 format(cmd,
122 node['host'],
123 ret,
124 stderr))
125
126 return stdout
127
128
129def autoconfig_show_system():
130 """
131 Shows the system information.
132
133 """
134
135 acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
136
137 acfg.discover()
138
139 acfg.sys_info()
140
141
John DeNiscoddecfb32017-11-15 08:50:57 -0500142def autoconfig_hugepage_apply(node, ask_questions=True):
John DeNisco68b0ee32017-09-27 16:35:23 -0400143 """
144 Apply the huge page configuration.
145 :param node: The node structure
146 :type node: dict
John DeNiscoddecfb32017-11-15 08:50:57 -0500147 :param ask_questions: When True ask the user questions
148 :type ask_questions: bool
John DeNisco68b0ee32017-09-27 16:35:23 -0400149 :returns: -1 if the caller should return, 0 if not
150 :rtype: int
151
152 """
153
154 diffs = autoconfig_diff(node, VPP_REAL_HUGE_PAGE_FILE, rootdir + VPP_HUGE_PAGE_FILE)
155 if diffs != '':
156 print "These are the changes we will apply to"
157 print "the huge page file ({}).\n".format(VPP_REAL_HUGE_PAGE_FILE)
158 print diffs
John DeNiscoddecfb32017-11-15 08:50:57 -0500159 if ask_questions:
160 answer = autoconfig_yn("\nAre you sure you want to apply these changes [Y/n]? ", 'y')
161 if answer == 'n':
162 return -1
John DeNisco68b0ee32017-09-27 16:35:23 -0400163
164 # Copy and sysctl
165 autoconfig_cp(node, rootdir + VPP_HUGE_PAGE_FILE, VPP_REAL_HUGE_PAGE_FILE)
166 cmd = "sysctl -p {}".format(VPP_REAL_HUGE_PAGE_FILE)
167 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
168 if ret != 0:
169 raise RuntimeError('{} failed on node {} {} {}'.
170 format(cmd, node['host'], stdout, stderr))
171 else:
172 print '\nThere are no changes to the huge page configuration.'
173
174 return 0
175
176
John DeNiscoddecfb32017-11-15 08:50:57 -0500177def autoconfig_vpp_apply(node, ask_questions=True):
John DeNisco68b0ee32017-09-27 16:35:23 -0400178 """
179 Apply the vpp configuration.
180
181 :param node: The node structure
182 :type node: dict
John DeNiscoddecfb32017-11-15 08:50:57 -0500183 :param ask_questions: When True ask the user questions
184 :type ask_questions: bool
John DeNisco68b0ee32017-09-27 16:35:23 -0400185 :returns: -1 if the caller should return, 0 if not
186 :rtype: int
187
188 """
189
John DeNisco68b0ee32017-09-27 16:35:23 -0400190 diffs = autoconfig_diff(node, VPP_REAL_STARTUP_FILE, rootdir + VPP_STARTUP_FILE)
191 if diffs != '':
192 print "These are the changes we will apply to"
193 print "the VPP startup file ({}).\n".format(VPP_REAL_STARTUP_FILE)
194 print diffs
John DeNiscoddecfb32017-11-15 08:50:57 -0500195 if ask_questions:
196 answer = autoconfig_yn("\nAre you sure you want to apply these changes [Y/n]? ", 'y')
197 if answer == 'n':
198 return -1
John DeNisco68b0ee32017-09-27 16:35:23 -0400199
200 # Copy the VPP startup
201 autoconfig_cp(node, rootdir + VPP_STARTUP_FILE, VPP_REAL_STARTUP_FILE)
202 else:
203 print '\nThere are no changes to VPP startup.'
204
205 return 0
206
207
John DeNiscoddecfb32017-11-15 08:50:57 -0500208def autoconfig_grub_apply(node, ask_questions=True):
John DeNisco68b0ee32017-09-27 16:35:23 -0400209 """
210 Apply the grub configuration.
211
212 :param node: The node structure
213 :type node: dict
John DeNiscoddecfb32017-11-15 08:50:57 -0500214 :param ask_questions: When True ask the user questions
215 :type ask_questions: bool
John DeNisco68b0ee32017-09-27 16:35:23 -0400216 :returns: -1 if the caller should return, 0 if not
217 :rtype: int
218
219 """
John DeNiscoddecfb32017-11-15 08:50:57 -0500220
John DeNisco68b0ee32017-09-27 16:35:23 -0400221 print "\nThe configured grub cmdline looks like this:"
222 configured_cmdline = node['grub']['default_cmdline']
223 current_cmdline = node['grub']['current_cmdline']
224 print configured_cmdline
225 print "\nThe current boot cmdline looks like this:"
226 print current_cmdline
John DeNiscoddecfb32017-11-15 08:50:57 -0500227 if ask_questions:
228 question = "\nDo you want to keep the current boot cmdline [Y/n]? "
229 answer = autoconfig_yn(question, 'y')
230 if answer == 'y':
231 return
John DeNisco68b0ee32017-09-27 16:35:23 -0400232
John DeNiscoddecfb32017-11-15 08:50:57 -0500233 node['grub']['keep_cmdline'] = False
234
235 # Diff the file
236 diffs = autoconfig_diff(node, VPP_REAL_GRUB_FILE, rootdir + VPP_GRUB_FILE)
237 if diffs != '':
238 print "These are the changes we will apply to"
239 print "the GRUB file ({}).\n".format(VPP_REAL_GRUB_FILE)
240 print diffs
241 if ask_questions:
242 answer = autoconfig_yn("\nAre you sure you want to apply these changes [y/N]? ", 'n')
John DeNisco68b0ee32017-09-27 16:35:23 -0400243 if answer == 'n':
244 return -1
245
John DeNiscoddecfb32017-11-15 08:50:57 -0500246 # Copy and update grub
247 autoconfig_cp(node, rootdir + VPP_GRUB_FILE, VPP_REAL_GRUB_FILE)
248 distro = VPPUtil.get_linux_distro()
249 if distro[0] == 'Ubuntu':
250 cmd = "update-grub"
John DeNisco68b0ee32017-09-27 16:35:23 -0400251 else:
John DeNiscoddecfb32017-11-15 08:50:57 -0500252 cmd = "grub2-mkconfig -o /boot/grub2/grub.cfg"
253
254 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
255 if ret != 0:
256 raise RuntimeError('{} failed on node {} {} {}'.
257 format(cmd, node['host'], stdout, stderr))
258
259 print "There have been changes to the GRUB config a",
260 print "reboot will be required."
261 return -1
262 else:
263 print '\nThere are no changes to the GRUB config.'
John DeNisco68b0ee32017-09-27 16:35:23 -0400264
265 return 0
266
267
John DeNiscoddecfb32017-11-15 08:50:57 -0500268def autoconfig_apply(ask_questions=True):
John DeNisco68b0ee32017-09-27 16:35:23 -0400269 """
270 Apply the configuration.
271
272 Show the diff of the dryrun file and the actual configuration file
273 Copy the files from the dryrun directory to the actual file.
274 Peform the system function
275
John DeNiscoddecfb32017-11-15 08:50:57 -0500276 :param ask_questions: When true ask the user questions
277 :type ask_questions: bool
278
John DeNisco68b0ee32017-09-27 16:35:23 -0400279 """
280
281 vutil = VPPUtil()
282 pkgs = vutil.get_installed_vpp_pkgs()
283 if len(pkgs) == 0:
284 print "\nVPP is not installed, Install VPP with option 4."
285 return
286
287 acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
288
John DeNiscoddecfb32017-11-15 08:50:57 -0500289 if ask_questions:
290 print "\nWe are now going to configure your system(s).\n"
291 answer = autoconfig_yn("Are you sure you want to do this [Y/n]? ", 'y')
292 if answer == 'n':
293 return
John DeNisco68b0ee32017-09-27 16:35:23 -0400294
295 nodes = acfg.get_nodes()
296 for i in nodes.items():
297 node = i[1]
298
299 # Check the system resources
300 if not acfg.min_system_resources(node):
301 return
302
John DeNiscoddecfb32017-11-15 08:50:57 -0500303 # Stop VPP
304 VPPUtil.stop(node)
305
John DeNisco68b0ee32017-09-27 16:35:23 -0400306 # Huge Pages
John DeNiscoddecfb32017-11-15 08:50:57 -0500307 ret = autoconfig_hugepage_apply(node, ask_questions)
John DeNisco68b0ee32017-09-27 16:35:23 -0400308 if ret != 0:
309 return
310
311 # VPP
John DeNiscoddecfb32017-11-15 08:50:57 -0500312 ret = autoconfig_vpp_apply(node, ask_questions)
John DeNisco68b0ee32017-09-27 16:35:23 -0400313 if ret != 0:
314 return
315
316 # Grub
John DeNiscoddecfb32017-11-15 08:50:57 -0500317 ret = autoconfig_grub_apply(node, ask_questions)
John DeNisco68b0ee32017-09-27 16:35:23 -0400318 if ret != 0:
John DeNiscoddecfb32017-11-15 08:50:57 -0500319 # We can still start VPP, even if we haven't configured grub
320 VPPUtil.start(node)
John DeNisco68b0ee32017-09-27 16:35:23 -0400321 return
322
323 # Everything is configured start vpp
John DeNiscoddecfb32017-11-15 08:50:57 -0500324 VPPUtil.start(node)
John DeNisco68b0ee32017-09-27 16:35:23 -0400325
John DeNiscoa7da67f2018-01-26 14:55:33 -0500326
John DeNiscoddecfb32017-11-15 08:50:57 -0500327def autoconfig_dryrun(ask_questions=True):
John DeNisco68b0ee32017-09-27 16:35:23 -0400328 """
329 Execute the dryrun function.
330
John DeNiscoddecfb32017-11-15 08:50:57 -0500331 :param ask_questions: When true ask the user for paraameters
332 :type ask_questions: bool
333
John DeNisco68b0ee32017-09-27 16:35:23 -0400334 """
335
336 vutil = VPPUtil()
337 pkgs = vutil.get_installed_vpp_pkgs()
338 if len(pkgs) == 0:
John DeNiscoddecfb32017-11-15 08:50:57 -0500339 print "\nVPP is not installed, please install VPP."
John DeNisco68b0ee32017-09-27 16:35:23 -0400340 return
341
John DeNiscoddecfb32017-11-15 08:50:57 -0500342 acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE, clean=True)
John DeNisco68b0ee32017-09-27 16:35:23 -0400343
344 # Stop VPP on each node
345 nodes = acfg.get_nodes()
346 for i in nodes.items():
347 node = i[1]
348 VPPUtil.stop(node)
349
350 # Discover
351 acfg.discover()
352
353 # Check the system resources
354 nodes = acfg.get_nodes()
355 for i in nodes.items():
356 node = i[1]
357 if not acfg.min_system_resources(node):
358 return
359
360 # Modify the devices
John DeNiscoddecfb32017-11-15 08:50:57 -0500361 if ask_questions:
362 acfg.modify_devices()
363 else:
364 acfg.update_interfaces_config()
John DeNisco68b0ee32017-09-27 16:35:23 -0400365
366 # Modify CPU
John DeNiscoddecfb32017-11-15 08:50:57 -0500367 acfg.modify_cpu(ask_questions)
John DeNisco68b0ee32017-09-27 16:35:23 -0400368
369 # Calculate the cpu parameters
370 acfg.calculate_cpu_parameters()
371
372 # Acquire TCP stack parameters
John DeNiscoddecfb32017-11-15 08:50:57 -0500373 if ask_questions:
374 acfg.acquire_tcp_params()
John DeNisco68b0ee32017-09-27 16:35:23 -0400375
376 # Apply the startup
377 acfg.apply_vpp_startup()
378
379 # Apply the grub configuration
380 acfg.apply_grub_cmdline()
381
382 # Huge Pages
John DeNiscoddecfb32017-11-15 08:50:57 -0500383 if ask_questions:
384 acfg.modify_huge_pages()
John DeNisco68b0ee32017-09-27 16:35:23 -0400385 acfg.apply_huge_pages()
386
387
388def autoconfig_install():
389 """
390 Install or Uninstall VPP.
391
392 """
393
394 # Since these commands will take a while, we
395 # want to see the progress
396 logger = logging.getLogger()
397
398 acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
399 vutil = VPPUtil()
400
401 nodes = acfg.get_nodes()
402 for i in nodes.items():
403 node = i[1]
404
405 pkgs = vutil.get_installed_vpp_pkgs()
406
407 if len(pkgs) > 0:
408 print "\nThese packages are installed on node {}" \
409 .format(node['host'])
410 print "{:25} {}".format("Name", "Version")
411 for pkg in pkgs:
412 if 'version' in pkg:
413 print "{:25} {}".format(
414 pkg['name'], pkg['version'])
415 else:
416 print "{}".format(pkg['name'])
417
418 question = "\nDo you want to uninstall these "
419 question += "packages [y/N]? "
420 answer = autoconfig_yn(question, 'n')
421 if answer == 'y':
422 logger.setLevel(logging.INFO)
423 vutil.uninstall_vpp(node)
424 else:
425 print "\nThere are no VPP packages on node {}." \
426 .format(node['host'])
427 question = "Do you want to install VPP [Y/n]? "
428 answer = autoconfig_yn(question, 'y')
429 if answer == 'y':
jdeniscob0b9dad2018-12-18 15:29:45 -0500430 question = "Do you want to install the release version [Y/n]? "
431 answer = autoconfig_yn(question, 'y')
432 if answer == 'y':
433 branch = 'release'
434 else:
435 branch = 'master'
John DeNisco68b0ee32017-09-27 16:35:23 -0400436 logger.setLevel(logging.INFO)
jdeniscob0b9dad2018-12-18 15:29:45 -0500437 vutil.install_vpp(node, branch)
John DeNisco68b0ee32017-09-27 16:35:23 -0400438
439 # Set the logging level back
440 logger.setLevel(logging.ERROR)
441
442
443def autoconfig_patch_qemu():
444 """
445 Patch the correct qemu version that is needed for openstack
446
447 """
448
449 # Since these commands will take a while, we
450 # want to see the progress
451 logger = logging.getLogger()
452
453 acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
454
455 nodes = acfg.get_nodes()
456 for i in nodes.items():
457 node = i[1]
458
459 logger.setLevel(logging.INFO)
460 acfg.patch_qemu(node)
461
462
John DeNiscoa3db0782017-10-17 11:07:22 -0400463def autoconfig_ipv4_setup():
464 """
465 Setup IPv4 interfaces
466
467 """
468
469 acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
470 acfg.ipv4_interface_setup()
471
472
John DeNisco9fa5cf42018-02-06 15:23:05 -0500473def autoconfig_create_iperf_vm():
John DeNiscoc6b2a202017-11-01 12:37:47 -0400474 """
475 Setup IPv4 interfaces
476
477 """
478
479 acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
John DeNisco9fa5cf42018-02-06 15:23:05 -0500480 acfg.destroy_iperf_vm('iperf-server')
481 acfg.create_and_bridge_iperf_virtual_interface()
482 acfg.create_iperf_vm('iperf-server')
John DeNiscoc6b2a202017-11-01 12:37:47 -0400483
484
John DeNisco68b0ee32017-09-27 16:35:23 -0400485def autoconfig_not_implemented():
486 """
487 This feature is not implemented
488
489 """
490
491 print "\nThis Feature is not implemented yet...."
492
493
John DeNiscoa3db0782017-10-17 11:07:22 -0400494def autoconfig_basic_test_menu():
495 """
496 The auto configuration basic test menu
497
498 """
499
500 basic_menu_text = '\nWhat would you like to do?\n\n\
5011) List/Create Simple IPv4 Setup\n\
John DeNisco9fa5cf42018-02-06 15:23:05 -05005022) Create an iperf VM and Connect to VPP an interface\n\
John DeNiscoa3db0782017-10-17 11:07:22 -04005039 or q) Back to main menu.'
John DeNiscoddecfb32017-11-15 08:50:57 -0500504
John DeNiscoa3db0782017-10-17 11:07:22 -0400505 print "{}".format(basic_menu_text)
506
507 input_valid = False
508 answer = ''
509 while not input_valid:
510 answer = raw_input("\nCommand: ")
511 if len(answer) > 1:
512 print "Please enter only 1 character."
513 continue
514 if re.findall(r'[Qq1-29]', answer):
515 input_valid = True
516 answer = answer[0].lower()
517 else:
518 print "Please enter a character between 1 and 2 or 9."
519
520 if answer == '9':
521 answer = 'q'
522
523 return answer
524
525
526def autoconfig_basic_test():
527 """
528 The auto configuration basic test menu
529
530 """
531 vutil = VPPUtil()
532 pkgs = vutil.get_installed_vpp_pkgs()
533 if len(pkgs) == 0:
534 print "\nVPP is not installed, install VPP with option 4."
535 return
536
537 answer = ''
538 while answer != 'q':
539 answer = autoconfig_basic_test_menu()
540 if answer == '1':
541 autoconfig_ipv4_setup()
John DeNisco9fa5cf42018-02-06 15:23:05 -0500542 elif answer == '2':
543 autoconfig_create_iperf_vm()
John DeNiscoa3db0782017-10-17 11:07:22 -0400544 elif answer == '9' or answer == 'q':
545 return
546 else:
547 autoconfig_not_implemented()
548
549
John DeNisco68b0ee32017-09-27 16:35:23 -0400550def autoconfig_main_menu():
551 """
552 The auto configuration main menu
553
554 """
555
556 main_menu_text = '\nWhat would you like to do?\n\n\
5571) Show basic system information\n\
jdenisco7c37a672018-11-20 11:25:17 -05005582) Dry Run (Saves the configuration files in {}/vpp/vpp-config/dryrun.\n\
John DeNisco68b0ee32017-09-27 16:35:23 -04005593) Full configuration (WARNING: This will change the system configuration)\n\
5604) List/Install/Uninstall VPP.\n\
jdeniscob9875092018-11-06 16:10:04 -0500561q) Quit'.format(rootdir, rootdir)
John DeNisco68b0ee32017-09-27 16:35:23 -0400562
563 # 5) Dry Run from {}/vpp/vpp-config/auto-config.yaml (will not ask questions).\n\
564 # 6) Install QEMU patch (Needed when running openstack).\n\
565
566 print "{}".format(main_menu_text)
567
568 input_valid = False
569 answer = ''
570 while not input_valid:
571 answer = raw_input("\nCommand: ")
572 if len(answer) > 1:
573 print "Please enter only 1 character."
574 continue
jdeniscob9875092018-11-06 16:10:04 -0500575 if re.findall(r'[Qq1-4]', answer):
John DeNisco68b0ee32017-09-27 16:35:23 -0400576 input_valid = True
577 answer = answer[0].lower()
578 else:
jdeniscob9875092018-11-06 16:10:04 -0500579 print "Please enter a character between 1 and 4 or q."
John DeNisco68b0ee32017-09-27 16:35:23 -0400580
John DeNisco68b0ee32017-09-27 16:35:23 -0400581 return answer
582
583
584def autoconfig_main():
585 """
586 The auto configuration main entry point
587
588 """
589
John DeNiscoddecfb32017-11-15 08:50:57 -0500590 # Setup
591 autoconfig_setup()
592
John DeNisco68b0ee32017-09-27 16:35:23 -0400593 answer = ''
594 while answer != 'q':
595 answer = autoconfig_main_menu()
596 if answer == '1':
597 autoconfig_show_system()
598 elif answer == '2':
599 autoconfig_dryrun()
600 elif answer == '3':
601 autoconfig_apply()
602 elif answer == '4':
603 autoconfig_install()
jdeniscob9875092018-11-06 16:10:04 -0500604 elif answer == 'q':
John DeNisco68b0ee32017-09-27 16:35:23 -0400605 return
606 else:
607 autoconfig_not_implemented()
608
609
John DeNiscoddecfb32017-11-15 08:50:57 -0500610def autoconfig_setup(ask_questions=True):
John DeNisco68b0ee32017-09-27 16:35:23 -0400611 """
612 The auto configuration setup function.
613
614 We will copy the configuration files to the dryrun directory.
615
616 """
617
618 global rootdir
619
John DeNisco68b0ee32017-09-27 16:35:23 -0400620 distro = VPPUtil.get_linux_distro()
621 if distro[0] == 'Ubuntu':
622 rootdir = '/usr/local'
623 else:
624 rootdir = '/usr'
625
626 # If there is a system configuration file use that, if not use the initial auto-config file
627 filename = rootdir + VPP_AUTO_CONFIGURATION_FILE
628 if os.path.isfile(filename) is True:
629 acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
630 else:
631 raise RuntimeError('The Auto configuration file does not exist {}'.
632 format(filename))
633
John DeNiscoddecfb32017-11-15 08:50:57 -0500634 if ask_questions:
635 print "\nWelcome to the VPP system configuration utility"
John DeNisco68b0ee32017-09-27 16:35:23 -0400636
John DeNiscoddecfb32017-11-15 08:50:57 -0500637 print "\nThese are the files we will modify:"
638 print " /etc/vpp/startup.conf"
639 print " /etc/sysctl.d/80-vpp.conf"
640 print " /etc/default/grub"
John DeNisco68b0ee32017-09-27 16:35:23 -0400641
John DeNiscoddecfb32017-11-15 08:50:57 -0500642 print "\nBefore we change them, we'll create working copies in {}".format(rootdir + VPP_DRYRUNDIR)
643 print "Please inspect them carefully before applying the actual configuration (option 3)!"
John DeNisco68b0ee32017-09-27 16:35:23 -0400644
645 nodes = acfg.get_nodes()
646 for i in nodes.items():
647 node = i[1]
648
649 if (os.path.isfile(rootdir + VPP_STARTUP_FILE) is not True) and \
650 (os.path.isfile(VPP_REAL_STARTUP_FILE) is True):
651 autoconfig_cp(node, VPP_REAL_STARTUP_FILE, '{}'.format(rootdir + VPP_STARTUP_FILE))
652 if (os.path.isfile(rootdir + VPP_HUGE_PAGE_FILE) is not True) and \
653 (os.path.isfile(VPP_REAL_HUGE_PAGE_FILE) is True):
654 autoconfig_cp(node, VPP_REAL_HUGE_PAGE_FILE, '{}'.format(rootdir + VPP_HUGE_PAGE_FILE))
655 if (os.path.isfile(rootdir + VPP_GRUB_FILE) is not True) and \
656 (os.path.isfile(VPP_REAL_GRUB_FILE) is True):
657 autoconfig_cp(node, VPP_REAL_GRUB_FILE, '{}'.format(rootdir + VPP_GRUB_FILE))
658
John DeNiscoa7da67f2018-01-26 14:55:33 -0500659 # Be sure the uio_pci_generic driver is installed
660 cmd = 'modprobe uio_pci_generic'
661 (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
662 if ret != 0:
John DeNisco4dc83972018-03-30 10:50:19 -0400663 logging.warning('{} failed on node {} {}'. format(cmd, node['host'], stderr))
John DeNiscoa7da67f2018-01-26 14:55:33 -0500664
John DeNisco68b0ee32017-09-27 16:35:23 -0400665
John DeNisco9fa5cf42018-02-06 15:23:05 -0500666# noinspection PyUnresolvedReferences
John DeNiscoddecfb32017-11-15 08:50:57 -0500667def execute_with_args(args):
668 """
669 Execute the configuration utility with agruments.
670
671 :param args: The Command line arguments
672 :type args: tuple
673 """
674
675 # Setup
676 autoconfig_setup(ask_questions=False)
677
678 # Execute the command
679 if args.show:
680 autoconfig_show_system()
681 elif args.dry_run:
682 autoconfig_dryrun(ask_questions=False)
683 elif args.apply:
684 autoconfig_apply(ask_questions=False)
685 else:
686 autoconfig_not_implemented()
687
688
689def config_main():
690 """
691 The vpp configuration utility main entry point.
692
693 """
John DeNisco68b0ee32017-09-27 16:35:23 -0400694
695 # Check for root
696 if not os.geteuid() == 0:
697 sys.exit('\nPlease run the VPP Configuration Utility as root.')
698
John DeNiscoa7da67f2018-01-26 14:55:33 -0500699 if len(sys.argv) > 1 and ((sys.argv[1] == '-d') or (sys.argv[1] == '--debug')):
700 logging.basicConfig(level=logging.DEBUG)
701 else:
702 logging.basicConfig(level=logging.ERROR)
703
John DeNiscoddecfb32017-11-15 08:50:57 -0500704 # If no arguments were entered, ask the user questions to get the main parameters
705 if len(sys.argv) == 1:
John DeNiscoa7da67f2018-01-26 14:55:33 -0500706 autoconfig_main()
707 return
708 elif len(sys.argv) == 2 and (sys.argv[1] == '-d' or sys.argv[1] == '--debug'):
John DeNiscoddecfb32017-11-15 08:50:57 -0500709 autoconfig_main()
710 return
John DeNisco68b0ee32017-09-27 16:35:23 -0400711
John DeNiscoddecfb32017-11-15 08:50:57 -0500712 # There were arguments specified, so execute the utility using command line arguments
713 description = 'The VPP configuration utility allows the user to configure VPP in a simple and safe manner. \
714The utility takes input from the user or the speficfied .yaml file. The user should then examine these files \
715to be sure they are correct and then actually apply the configuration. When run without arguments the utility run \
716in an interactive mode'
717
718 main_parser = argparse.ArgumentParser(prog='arg-test', description=description,
719 epilog='See "%(prog)s help COMMAND" for help on a specific command.')
720 main_parser.add_argument('--apply', '-a', action='store_true', help='Apply the cofiguration.')
721 main_parser.add_argument('--dry-run', '-dr', action='store_true', help='Create the dryrun configuration files.')
722 main_parser.add_argument('--show', '-s', action='store_true', help='Shows basic system information')
723 main_parser.add_argument('--debug', '-d', action='count', help='Print debug output (multiple levels)')
724
725 args = main_parser.parse_args()
726
727 return execute_with_args(args)
728
729
730if __name__ == '__main__':
John DeNiscoddecfb32017-11-15 08:50:57 -0500731 config_main()