| 10 | | class KforgeAdmin(cmd.Cmd): |
|---|
| 11 | | "KForge command line interface." |
|---|
| 12 | | |
|---|
| 13 | | def __init__(self, envPath=None, systemPath=None): |
|---|
| 14 | | cmd.Cmd.__init__(self) # Class cmd.Cmd isn't new style. |
|---|
| 15 | | self.interactive = 0 |
|---|
| 16 | | self.envPath = None |
|---|
| 17 | | self.systemPath = systemPath |
|---|
| 18 | | if envPath is not None: |
|---|
| 19 | | self.set_environment(envPath) |
|---|
| 20 | | |
|---|
| 21 | | def set_environment(self, envPath): |
|---|
| 22 | | self.envPath = os.path.abspath(envPath) |
|---|
| 23 | | os.environ['KFORGEHOME'] = self.envPath # system dictionary needs this |
|---|
| 24 | | self.prompt = 'Kforge [%s]$ ' % self.envPath |
|---|
| 25 | | |
|---|
| 26 | | def run_interactive(self): |
|---|
| 27 | | """Run an interactive session. |
|---|
| 28 | | """ |
|---|
| 29 | | print 'Welcome to the kforge-admin interactive mode\n' |
|---|
| 30 | | print 'Type: "?" or "help" for help on commands.\n' |
|---|
| 31 | | self.do_about() |
|---|
| 32 | | while 1: |
|---|
| 33 | | try: |
|---|
| 34 | | self.cmdloop() |
|---|
| 35 | | break |
|---|
| 36 | | except KeyboardInterrupt: |
|---|
| 37 | | raise |
|---|
| 38 | | # print '\n** Interrupt. Use "quit" to exit **' |
|---|
| 39 | | |
|---|
| 40 | | # ========================= |
|---|
| 41 | | # START OF Commands section |
|---|
| 42 | | |
|---|
| 43 | | def do_data(self, line=None): |
|---|
| 44 | | args = self._lineToArgs(line) |
|---|
| 45 | | if len(args) != 1: |
|---|
| 46 | | print 'ERROR: Insufficient arguments\n' |
|---|
| 47 | | self.help_data(line) |
|---|
| 48 | | return 1 |
|---|
| 49 | | elif args[0] == 'create': |
|---|
| 50 | | from kforge.utils.admin import InitialiseEnvCmd |
|---|
| 51 | | cmd = InitialiseEnvCmd(self.envPath, self.systemPath) |
|---|
| 52 | | cmd.execute() |
|---|
| 53 | | return 0 |
|---|
| 54 | | else: |
|---|
| 55 | | self.help_data() |
|---|
| 56 | | return 1 |
|---|
| 57 | | |
|---|
| 58 | | def help_data(self, line=None): |
|---|
| 59 | | usage = \ |
|---|
| 60 | | '''data <action> |
|---|
| 61 | | action = create |
|---|
| 62 | | |
|---|
| 63 | | Create environment data |
|---|
| 64 | | ''' |
|---|
| 65 | | print usage |
|---|
| 66 | | |
|---|
| 67 | | def do_backup(self, line): |
|---|
| 68 | | args = self._lineToArgs(line) |
|---|
| 69 | | import kforge.application |
|---|
| 70 | | app = kforge.application.Application() |
|---|
| 71 | | if len(args) != 1: |
|---|
| 72 | | print 'ERROR: Insufficient arguments\n' |
|---|
| 73 | | self.help_backup(line) |
|---|
| 74 | | return 1 |
|---|
| 75 | | else: |
|---|
| 76 | | cmd = app.commands['Backup'](args[0]) |
|---|
| 77 | | cmd.execute() |
|---|
| 78 | | return 0 |
|---|
| 79 | | |
|---|
| 80 | | def help_backup(self, line=None): |
|---|
| 81 | | usage = 'backup dest\n' |
|---|
| 82 | | usage += '\tdest is the path to which you wish to backup' |
|---|
| 83 | | print usage |
|---|
| 84 | | |
|---|
| 85 | | def do_db(self, line=None): |
|---|
| 86 | | """Run db commands |
|---|
| 87 | | """ |
|---|
| 88 | | args = self._lineToArgs(line) |
|---|
| 89 | | if len(args) != 1: |
|---|
| 90 | | print 'ERROR: Insufficient arguments\n' |
|---|
| 91 | | self.help_db(line) |
|---|
| 92 | | return 1 |
|---|
| 93 | | # let's do this reflectively |
|---|
| 94 | | from kforge.utils.db import Database |
|---|
| 95 | | db = Database() |
|---|
| 96 | | try: |
|---|
| 97 | | Database.__dict__[args[0]](db) |
|---|
| 98 | | except Exception, inst: |
|---|
| 99 | | print 'Command failed. Details: %s' % inst |
|---|
| 100 | | return 1 |
|---|
| 101 | | |
|---|
| 102 | | def help_db(self): |
|---|
| 103 | | usage = \ |
|---|
| 104 | | '''db <action> |
|---|
| 105 | | action = create | delete | init | rebuild |
|---|
| 106 | | |
|---|
| 107 | | NB: a known issue is that due to a persisted db connection once you |
|---|
| 108 | | have run init or rebuild you cannot run any of the other commands |
|---|
| 109 | | again in the same session''' |
|---|
| 110 | | # [[TODO: display docstrings for each function from db class here |
|---|
| 111 | | # Database.__dict__[cmd].__doc__ |
|---|
| 112 | | print usage |
|---|
| 113 | | |
|---|
| 114 | | def do_upgrade(self, line=None): |
|---|
| 115 | | # TODO use KForge version to specify upgrade script used |
|---|
| 116 | | args = self._lineToArgs(line) |
|---|
| 117 | | import kforge.utils.upgrade |
|---|
| 118 | | if len(args) != 1: |
|---|
| 119 | | self.help_upgrade(line) |
|---|
| 120 | | return 1 |
|---|
| 121 | | elif args[0] == 'data': |
|---|
| 122 | | cmd = kforge.utils.upgrade.UpgradeDataTo0Point11( |
|---|
| 123 | | self.envPath, self.systemPath) |
|---|
| 124 | | cmd.execute() |
|---|
| 125 | | return 0 |
|---|
| 126 | | elif args[0] == 'db': |
|---|
| 127 | | cmd = kforge.utils.upgrade.UpgradeDbTo0Point11() |
|---|
| 128 | | cmd.execute() |
|---|
| 129 | | return 0 |
|---|
| 130 | | else: |
|---|
| 131 | | print 'Unknown arguments: %s' % args |
|---|
| 132 | | self.help_upgrade() |
|---|
| 133 | | |
|---|
| 134 | | def help_upgrade(self, line=None): |
|---|
| 135 | | usage = \ |
|---|
| 136 | | '''upgrade <object> |
|---|
| 137 | | object = data | db |
|---|
| 138 | | |
|---|
| 139 | | Upgrade a KForge environment (data and db)''' |
|---|
| 140 | | print usage |
|---|
| 141 | | |
|---|
| 142 | | def do_www(self, line=None): |
|---|
| 143 | | args = self._lineToArgs(line) |
|---|
| 144 | | if len(args) == 0: |
|---|
| 145 | | self.help_www(line) |
|---|
| 146 | | return 1 |
|---|
| 147 | | import kforge |
|---|
| 148 | | kforge.getA() # have to do this to set up features (dictionary etc) |
|---|
| 149 | | from kforge.apache.apacheconfig import ApacheConfigBuilder |
|---|
| 150 | | configBuilder = ApacheConfigBuilder() |
|---|
| 151 | | if args[0] == 'build': |
|---|
| 152 | | configBuilder.buildConfig() |
|---|
| 153 | | elif args[0] == 'reload': |
|---|
| 154 | | configBuilder.reloadConfig() |
|---|
| 155 | | else: |
|---|
| 156 | | self.help_www(line) |
|---|
| 157 | | return 1 |
|---|
| 158 | | |
|---|
| 159 | | def help_www(self, line=None): |
|---|
| 160 | | help = 'www [ build | reload ]\n' |
|---|
| 161 | | help += '\tbuild: build web server configuration\n' |
|---|
| 162 | | help += '\treload: reload web server configuration\n' |
|---|
| 163 | | print help |
|---|
| 164 | | |
|---|
| 165 | | def do_shell(self, line=None): |
|---|
| 166 | | import code |
|---|
| 167 | | code.interact() |
|---|
| 168 | | |
|---|
| 169 | | def help_shell(self, line=None): |
|---|
| 170 | | help = \ |
|---|
| 171 | | '''shell (or !): run a python shell |
|---|
| 172 | | |
|---|
| 173 | | Used to administer domain objects. Read docs/cli_shell.txt for a full |
|---|
| 174 | | guide to use of the shell for administration of the domain model. |
|---|
| 175 | | |
|---|
| 176 | | Preferred to direct invocation of a python shell as this ensures all relevant |
|---|
| 177 | | environment variables are correctly set. |
|---|
| 178 | | ''' |
|---|
| 179 | | print help |
|---|
| 180 | | |
|---|
| 181 | | def do_about(self, args=None): |
|---|
| 182 | | import kforge |
|---|
| 183 | | version = kforge.__version__ |
|---|
| 184 | | about = \ |
|---|
| 185 | | '''KForge version %s |
|---|
| 186 | | Copyright the Open Knowledge Foundation. KForge is open-source software |
|---|
| 187 | | licensed under the GPL v2.0. See COPYING for details. |
|---|
| 188 | | ''' % version |
|---|
| 189 | | print about |
|---|
| 190 | | |
|---|
| 191 | | def do_help(self, line=None): |
|---|
| 192 | | cmd.Cmd.do_help(self, line) |
|---|
| 193 | | |
|---|
| 194 | | def do_quit(self, line=None): |
|---|
| 195 | | sys.exit() |
|---|
| 196 | | |
|---|
| 197 | | def do_EOF(self, *args): |
|---|
| 198 | | print '' |
|---|
| 199 | | sys.exit() |
|---|
| 200 | | |
|---|
| 201 | | def _lineToArgs(self, line): |
|---|
| 202 | | args = line.strip().split() |
|---|
| 203 | | args = [ x.strip() for x in args] |
|---|
| 204 | | return args |
|---|
| 205 | | |
|---|
| 206 | | def main(): |
|---|
| 207 | | usage = \ |
|---|
| 208 | | '''usage: %prog [options] [cmd] |
|---|
| 209 | | |
|---|
| 210 | | Administer a KForge environment/instance and its associated domain objects. |
|---|
| 211 | | |
|---|
| 212 | | Can be run in two modes: |
|---|
| 213 | | 1. single command: run the command provided and exit (Default) |
|---|
| 214 | | 2. interactive |
|---|
| 215 | | |
|---|
| 216 | | To obtain information about the commands available run the "help" command. |
|---|
| 217 | | |
|---|
| 218 | | Domain objects (e.g. persons, projects, etc) are administered by starting |
|---|
| 219 | | a python shell from within interactive mode. Run "help shell" for more details. |
|---|
| 220 | | ''' |
|---|
| 221 | | parser = optparse.OptionParser(usage) |
|---|
| 222 | | parser.add_option('-i', '--interactive', |
|---|
| 223 | | action='store_true', dest='interactive', default=False, |
|---|
| 224 | | help='Run in interactive mode. If this option is specified any commands at invocation will be ignored.' |
|---|
| 225 | | ) |
|---|
| 226 | | parser.add_option('--version', |
|---|
| 227 | | action='store_true', dest='version', default=False, |
|---|
| 228 | | help='Display version information' |
|---|
| 229 | | ) |
|---|
| 230 | | parser.add_option('--system', |
|---|
| 231 | | action='store', dest='system_path', default=None, |
|---|
| 232 | | help='If you have installed the KForge system to a path other\n' + \ |
|---|
| 233 | | 'than the default (sys.prefix) you need to specify the path here.' |
|---|
| 234 | | ) |
|---|
| 235 | | parser.add_option('--env', |
|---|
| 236 | | action='store', dest='env_path', default='', |
|---|
| 237 | | help='Path to environment you wish to administer. ' + \ |
|---|
| 238 | | 'If not provided use shell environment variable KFORGEHOME' |
|---|
| 239 | | ) |
|---|
| 240 | | |
|---|
| 241 | | (options, args) = parser.parse_args() |
|---|
| 242 | | # concatenate all arguments back together for cmd.Cmd |
|---|
| 243 | | line = '' |
|---|
| 244 | | if len(args) > 0: |
|---|
| 245 | | line = ' '.join(['%s' % s for s in args]) |
|---|
| 246 | | |
|---|
| 247 | | # special cases |
|---|
| 248 | | kforgeAdmin = KforgeAdmin() |
|---|
| 249 | | if len(args) > 0 and args[0] in [ 'help' ]: |
|---|
| 250 | | return kforgeAdmin.onecmd(line) |
|---|
| 251 | | elif options.version: |
|---|
| 252 | | return kforgeAdmin.onecmd('about') |
|---|
| 253 | | |
|---|
| 254 | | # going to administer an environment |
|---|
| 255 | | envPath = options.env_path |
|---|
| 256 | | if not envPath: |
|---|
| 257 | | if os.environ.has_key('KFORGEHOME'): |
|---|
| 258 | | envPath = os.environ['KFORGEHOME'] |
|---|
| 259 | | else: |
|---|
| 260 | | print 'ERROR. Please provide a path to the KForge environment you wish to administer\n\n' |
|---|
| 261 | | parser.print_help() |
|---|
| 262 | | sys.exit(1) |
|---|
| 263 | | kforgeAdmin = KforgeAdmin(envPath, options.system_path) |
|---|
| 264 | | if options.interactive: |
|---|
| 265 | | return kforgeAdmin.run_interactive() |
|---|
| 266 | | elif len(args) > 0: |
|---|
| 267 | | status = kforgeAdmin.onecmd(line) |
|---|
| 268 | | sys.exit(status) |
|---|
| 269 | | else: |
|---|
| 270 | | parser.print_help() |
|---|
| 271 | | |
|---|
| 272 | | if __name__ == '__main__': |
|---|
| 273 | | # unittest.main() |
|---|
| 274 | | main() |
|---|