Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 1 | # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Implementation of the 'clean' chromite command.""" |
| 6 | |
| 7 | # Python imports |
| 8 | import optparse |
| 9 | import os |
| 10 | import sys |
| 11 | |
| 12 | |
| 13 | # Local imports |
| 14 | import chromite.lib.cros_build_lib as cros_lib |
| 15 | from chromite.shell import utils |
| 16 | from chromite.shell import subcmd |
| 17 | |
| 18 | |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 19 | def _DoClean(cros_env, chroot_config, build_config, want_force_yes): |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 20 | """Clean a target. |
| 21 | |
| 22 | Args: |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 23 | cros_env: Chromite environment to use for this command. |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 24 | chroot_config: A SafeConfigParser representing the config for the chroot. |
| 25 | build_config: A SafeConfigParser representing the build config. |
| 26 | want_force_yes: If True, we won't ask any questions--we'll just assume |
| 27 | that the user really wants to kill the directory. If False, we'll |
| 28 | show UI asking the user to confirm. |
| 29 | """ |
| 30 | # We'll need the directory so we can delete stuff; this is a chroot path. |
| 31 | board_dir = utils.GetBoardDir(build_config) |
| 32 | |
| 33 | # If not in the chroot, convert board_dir into a non-chroot path... |
| 34 | if not cros_lib.IsInsideChroot(): |
| 35 | chroot_dir = utils.GetChrootAbsDir(chroot_config) |
| 36 | |
| 37 | # We'll need to make the board directory relative to the chroot. |
| 38 | assert board_dir.startswith('/'), 'Expected unix-style, absolute path.' |
| 39 | board_dir = board_dir.lstrip('/') |
| 40 | board_dir = os.path.join(chroot_dir, board_dir) |
| 41 | |
| 42 | if not os.path.isdir(board_dir): |
| 43 | cros_lib.Die("Nothing to clean: the board directory doesn't exist.\n %s" % |
| 44 | board_dir) |
| 45 | |
| 46 | if not want_force_yes: |
| 47 | sys.stderr.write('\n' |
| 48 | 'Board dir is at: %s\n' |
| 49 | 'Are you sure you want to delete it (YES/NO)? ' % |
| 50 | board_dir) |
| 51 | answer = raw_input() |
| 52 | if answer.lower() not in ('y', 'ye', 'yes'): |
| 53 | cros_lib.Die("You must answer 'yes' if you want to proceed.") |
| 54 | |
| 55 | # Since we're about to do a sudo rm -rf, these are just extra precautions. |
| 56 | # This shouldn't be the only place testing these (assert fails are ugly and |
| 57 | # can be turned off), but better safe than sorry. |
| 58 | # Note that the restriction on '*' is a bit unnecessary, since no shell |
| 59 | # expansion should happen. ...but again, I'd rather be safe. |
| 60 | assert os.path.isabs(board_dir), 'Board dir better be absolute' |
| 61 | assert board_dir != '/', 'Board dir better not be /' |
| 62 | assert '*' not in board_dir, 'Board dir better not have any *s' |
Doug Anderson | 6f53061 | 2011-02-11 13:19:25 -0800 | [diff] [blame] | 63 | assert build_config.get('DEFAULT', 'target'), 'Target better not be blank' |
| 64 | assert build_config.get('DEFAULT', 'target') in board_dir, \ |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 65 | 'Target name better be in board dir' |
| 66 | |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 67 | arg_list = ['--', 'rm', '-rf', board_dir] |
| 68 | cros_env.RunScript('DELETING: %s' % board_dir, 'sudo', arg_list) |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 69 | |
| 70 | |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 71 | def _DoDistClean(cros_env, chroot_config, want_force_yes): |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 72 | """Remove the whole chroot. |
| 73 | |
| 74 | Args: |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 75 | cros_env: Chromite environment to use for this command. |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 76 | chroot_config: A SafeConfigParser representing the config for the chroot. |
| 77 | want_force_yes: If True, we won't ask any questions--we'll just assume |
| 78 | that the user really wants to kill the directory. If False, we'll |
| 79 | show UI asking the user to confirm. |
| 80 | """ |
| 81 | if cros_lib.IsInsideChroot(): |
| 82 | cros_lib.Die('Please exit the chroot before trying to delete it.') |
| 83 | |
| 84 | chroot_dir = utils.GetChrootAbsDir(chroot_config) |
| 85 | if not want_force_yes: |
| 86 | sys.stderr.write('\n' |
| 87 | 'Chroot is at: %s\n' |
| 88 | 'Are you sure you want to delete it (YES/NO)? ' % |
| 89 | chroot_dir) |
| 90 | answer = raw_input() |
| 91 | if answer.lower() not in ('y', 'ye', 'yes'): |
| 92 | cros_lib.Die("You must answer 'yes' if you want to proceed.") |
| 93 | |
| 94 | # Can pass argv and not shell=True, since no user flags. :) |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 95 | arg_list = ['--chroot=%s' % chroot_dir, '--delete'] |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 96 | |
| 97 | # Run it. Pass any failures upward. |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 98 | cros_env.RunScript('REMOVING CHROOT', './make_chroot', arg_list, cwd=cwd) |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 99 | |
| 100 | |
| 101 | class CleanCmd(subcmd.ChromiteCmd): |
| 102 | """Clean out built packages for a target; if target=host, deletes chroot.""" |
| 103 | |
| 104 | def Run(self, raw_argv, chroot_config=None): |
| 105 | """Run the command. |
| 106 | |
| 107 | Args: |
| 108 | raw_argv: Command line arguments, including this command's name, but not |
| 109 | the chromite command name or chromite options. |
| 110 | chroot_config: A SafeConfigParser for the chroot config; or None chromite |
| 111 | was called from within the chroot. |
| 112 | """ |
| 113 | # Parse options for command... |
| 114 | usage_str = ('usage: %%prog [chromite_options] %s [options] [target]' % |
| 115 | raw_argv[0]) |
| 116 | parser = optparse.OptionParser(usage=usage_str) |
Simon Glass | f5298ef | 2011-04-08 14:00:45 -0700 | [diff] [blame] | 117 | parser.add_option('-y', '--yes', default=False, action='store_true', |
| 118 | help='Answer "YES" to "are you sure?" questions.') |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 119 | (options, argv) = parser.parse_args(raw_argv[1:]) |
| 120 | |
| 121 | # Make sure the chroot exists first, before possibly prompting for board... |
| 122 | # ...not really required, but nice for the user... |
| 123 | if not cros_lib.IsInsideChroot(): |
| 124 | if not utils.DoesChrootExist(chroot_config): |
| 125 | cros_lib.Die("Nothing to clean: the chroot doesn't exist.\n %s" % |
| 126 | utils.GetChrootAbsDir(chroot_config)) |
| 127 | |
| 128 | # Load the build config... |
| 129 | argv, build_config = utils.GetBuildConfigFromArgs(argv) |
| 130 | if argv: |
| 131 | cros_lib.Die('Unknown arguments: %s' % ' '.join(argv)) |
| 132 | |
| 133 | # If they do clean host, we'll delete the whole chroot |
| 134 | if build_config is None: |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 135 | _DoDistClean(self.cros_env, chroot_config, options.yes) |
Doug Anderson | a9b1090 | 2011-02-01 17:54:31 -0800 | [diff] [blame] | 136 | else: |
Simon Glass | 5329b93 | 2011-03-14 16:49:04 -0700 | [diff] [blame] | 137 | _DoClean(self.cros_env, chroot_config, build_config, options.yes) |