moinsetup

Changeset

47:78fbcba0c3b9
2011-09-18 Paul Boddie raw files shortlog changelog graph Added support for migrating Wiki instances to the new layout.
README.txt (file) moinsetup.py (file)
     1.1 --- a/README.txt	Sat Sep 17 01:27:01 2011 +0200
     1.2 +++ b/README.txt	Sun Sep 18 21:37:22 2011 +0200
     1.3 @@ -7,6 +7,15 @@
     1.4  create and initialise new Wiki instances, install extensions, themes and
     1.5  related resources, and perform certain configuration changes.
     1.6  
     1.7 +Important Notices
     1.8 +-----------------
     1.9 +
    1.10 +Release 0.3 of moinsetup changes the Wiki instance directory hierarchy so that
    1.11 +the top-level directory, instead of containing the conf and wikidata
    1.12 +directories, contains the Wiki configuration file (unless located elsewhere -
    1.13 +see the site_config setting) plus data, underlay and htdocs directories. See
    1.14 +the migration section below for details.
    1.15 +
    1.16  Usage
    1.17  -----
    1.18  
    1.19 @@ -18,6 +27,51 @@
    1.20  created. See the supplied moinsetup.cfg file for an example file which can
    1.21  be modified and used for this purpose.
    1.22  
    1.23 +An alternative configuration file is specified using the -f option:
    1.24 +
    1.25 +  python moinsetup.py -f mywiki.cfg
    1.26 +
    1.27 +Configuration files provide information about the MoinMoin installation and a
    1.28 +particular Wiki instance and Web site where the instance is published.
    1.29 +
    1.30 +Migration from moinsetup 0.2
    1.31 +----------------------------
    1.32 +
    1.33 +The Wiki instance directory hierarchy has changed in moinsetup 0.3 as
    1.34 +illustrated below:
    1.35 +
    1.36 +wiki (old)
    1.37 +  conf
    1.38 +    (wikiconfig.py)
    1.39 +    data
    1.40 +    underlay
    1.41 +  wikidata
    1.42 +    ... (htdocs)
    1.43 +
    1.44 +wiki (new)
    1.45 +  (wikiconfig.py)
    1.46 +  data
    1.47 +  underlay
    1.48 +  (htdocs)
    1.49 +
    1.50 +Since the contents of wikidata is generally superfluous, since the files are
    1.51 +mostly shared resources, that directory is no longer created and such shared
    1.52 +resources are no longer copied into it. The htdocs directory is copied since
    1.53 +it can be convenient to maintain a separate collection of static files so that
    1.54 +they can be updated with theme-related changes without modifying common system
    1.55 +files.
    1.56 +
    1.57 +To migrate old Wiki instance layouts, run the following command:
    1.58 +
    1.59 +  python moinsetup.py -m migrate_instance
    1.60 +
    1.61 +Add an optional argument after the method name to run the migration method in
    1.62 +test mode:
    1.63 +
    1.64 +  python moinsetup.py -m migrate_instance test
    1.65 +
    1.66 +This will just print the actions to be taken when migrating the instance.
    1.67 +
    1.68  Configuration
    1.69  -------------
    1.70  
    1.71 @@ -225,7 +279,8 @@
    1.72      names; improved the error reporting when settings are missing or
    1.73      inappropriate.
    1.74    * Flattened the Wiki instance hierarchy, putting the configuration, data,
    1.75 -    underlay and htdocs in the same top-level directory.
    1.76 +    underlay and htdocs in the same top-level directory. (See the migration
    1.77 +    section in the documentation for information on updating the hierarchy.)
    1.78    * Changed the location of MoinMoin 1.9 resources, installing them in the
    1.79      prefix hierarchy and copying only static resources into Wiki instances.
    1.80    * Changed the handling of static resources with MoinMoin 1.9 to serve them
     2.1 --- a/moinsetup.py	Sat Sep 17 01:27:01 2011 +0200
     2.2 +++ b/moinsetup.py	Sun Sep 18 21:37:22 2011 +0200
     2.3 @@ -19,7 +19,8 @@
     2.4  this program.  If not, see <http://www.gnu.org/licenses/>.
     2.5  """
     2.6  
     2.7 -from os.path import abspath, exists, extsep, isdir, join, normpath, split
     2.8 +from os.path import abspath, exists, extsep, isdir, islink, join, normpath, split
     2.9 +from os import chdir, chmod, listdir, mkdir, makedirs, remove, rename, rmdir
    2.10  from getpass import getpass
    2.11  from glob import glob
    2.12  from zipfile import ZipFile
    2.13 @@ -299,11 +300,12 @@
    2.14          "add_superuser",
    2.15          "make_site_files",
    2.16          "make_post_install_script",
    2.17 -        "reconfigure_moin",
    2.18 -        "set_auth_method",
    2.19  
    2.20          # Post-installation activities.
    2.21  
    2.22 +        "reconfigure_moin",
    2.23 +        "set_auth_method",
    2.24 +        "migrate_instance",
    2.25          "install_theme",
    2.26          "install_extension_package",
    2.27          "install_plugins",
    2.28 @@ -495,14 +497,14 @@
    2.29          if self.moin_distribution:
    2.30              this_dir = os.getcwd()
    2.31              try:
    2.32 -                os.chdir(self.moin_distribution)
    2.33 +                chdir(self.moin_distribution)
    2.34                  version = self.get_moin_version_from_package_info() or \
    2.35                      self.get_moin_version_from_import()
    2.36                  if version:
    2.37                      return version
    2.38  
    2.39              finally:
    2.40 -                os.chdir(this_dir)
    2.41 +                chdir(this_dir)
    2.42  
    2.43          else:
    2.44              return self.get_moin_version_from_import()
    2.45 @@ -580,7 +582,7 @@
    2.46  
    2.47          for d in (self.common_dir, self.web_app_dir, self.web_static_dir, self.web_site_dir):
    2.48              if d is not None and not exists(d):
    2.49 -                os.makedirs(d)
    2.50 +                makedirs(d)
    2.51  
    2.52      def get_theme_directories(self, theme_name=None):
    2.53  
    2.54 @@ -589,7 +591,7 @@
    2.55          or for a single theme if the optional 'theme_name' is specified.
    2.56          """
    2.57  
    2.58 -        filenames = theme_name and [theme_name] or os.listdir(self.htdocs_dir)
    2.59 +        filenames = theme_name and [theme_name] or listdir(self.htdocs_dir)
    2.60          directories = []
    2.61  
    2.62          for filename in filenames:
    2.63 @@ -645,7 +647,7 @@
    2.64              raise SetupException, "Cannot install MoinMoin without a 'moin_distribution' setting being defined."
    2.65  
    2.66          this_dir = os.getcwd()
    2.67 -        os.chdir(self.moin_distribution)
    2.68 +        chdir(self.moin_distribution)
    2.69  
    2.70          log_filename = "install-%s.log" % split(self.common_dir)[-1]
    2.71  
    2.72 @@ -656,7 +658,7 @@
    2.73  
    2.74          os.system("python setup.py --quiet %s %s --force" % (install_cmd, options))
    2.75  
    2.76 -        os.chdir(this_dir)
    2.77 +        chdir(this_dir)
    2.78  
    2.79      def install_data(self):
    2.80  
    2.81 @@ -674,11 +676,11 @@
    2.82  
    2.83          for d in ("data", "underlay"):
    2.84              source = join(moin_data, d)
    2.85 -            source_tar = source + os.path.extsep + "tar"
    2.86 +            source_tar = source + extsep + "tar"
    2.87  
    2.88 -            if os.path.exists(source):
    2.89 +            if exists(source):
    2.90                  shutil.copytree(source, join(self.common_dir, d))
    2.91 -            elif os.path.exists(source_tar):
    2.92 +            elif exists(source_tar):
    2.93  
    2.94                  note("Copying archive %s instead of directory %s. Running...\n"
    2.95                      "make pagepacks\n"
    2.96 @@ -694,18 +696,22 @@
    2.97          "Install static Web data if appropriate."
    2.98  
    2.99          if not exists(self.htdocs_dir):
   2.100 -            os.mkdir(self.htdocs_dir)
   2.101 +            mkdir(self.htdocs_dir)
   2.102  
   2.103 -        for item in os.listdir(self.htdocs_dir_source):
   2.104 +        for item in listdir(self.htdocs_dir_source):
   2.105              path = join(self.htdocs_dir_source, item)
   2.106              if isdir(path):
   2.107                  shutil.copytree(path, join(self.htdocs_dir, item))
   2.108              else:
   2.109                  shutil.copy(path, join(self.htdocs_dir, item))
   2.110  
   2.111 -    def configure_moin(self):
   2.112 +    def configure_moin(self, reset=0):
   2.113  
   2.114 -        "Edit the Wiki configuration file."
   2.115 +        """
   2.116 +        Edit the Wiki configuration file. If the optional 'reset' parameter is
   2.117 +        specified as a true value, a default configuration will be copied from
   2.118 +        the distribution if appropriate.
   2.119 +        """
   2.120  
   2.121          moin_data = self.get_moin_data()
   2.122  
   2.123 @@ -730,7 +736,9 @@
   2.124  
   2.125          else:
   2.126              wikiconfig_py = join(self.common_dir, "wikiconfig.py")
   2.127 -            shutil.copyfile(join(moin_data, "config", "wikiconfig.py"), wikiconfig_py)
   2.128 +
   2.129 +            if not exists(wikiconfig_py) or reset:
   2.130 +                shutil.copyfile(join(moin_data, "config", "wikiconfig.py"), wikiconfig_py)
   2.131  
   2.132          status("Editing configuration from %s..." % wikiconfig_py)
   2.133  
   2.134 @@ -923,7 +931,7 @@
   2.135          have_setfacl = os.system("setfacl -m user:%(web_user)s:r %(file)s > /dev/null 2>&1" % {
   2.136              "web_user" : self.web_user, "file" : temp_filename}) == 0
   2.137  
   2.138 -        os.remove(temp_filename)
   2.139 +        remove(temp_filename)
   2.140  
   2.141          # Create the scripts.
   2.142  
   2.143 @@ -944,7 +952,7 @@
   2.144              s += extra % vars
   2.145  
   2.146              writefile(postinst_script, s)
   2.147 -            os.chmod(postinst_script, 0755)
   2.148 +            chmod(postinst_script, 0755)
   2.149  
   2.150          if have_setfacl:
   2.151              note("Run %s to set file ownership and permissions.\n"
   2.152 @@ -1054,6 +1062,63 @@
   2.153          finally:
   2.154              wikiconfig.close()
   2.155  
   2.156 +    def migrate_instance(self, test=0):
   2.157 +
   2.158 +        """
   2.159 +        Migrate the Wiki to the currently supported layout. If 'test' is
   2.160 +        specified and set to a true value, only print whether the migration can
   2.161 +        be performed.
   2.162 +        """
   2.163 +
   2.164 +        conf_dir = join(self.common_dir, "conf")
   2.165 +        if exists(conf_dir):
   2.166 +            for filename in listdir(conf_dir):
   2.167 +                pathname = join(conf_dir, filename)
   2.168 +                print "Move", filename, "from conf directory."
   2.169 +                if not test:
   2.170 +                    rename(pathname, join(self.common_dir, filename))
   2.171 +        else:
   2.172 +            print "No conf directory."
   2.173 +
   2.174 +        wikidata = join(self.common_dir, "wikidata")
   2.175 +        if exists(wikidata):
   2.176 +            htdocs = join(wikidata, "share", "moin", "htdocs")
   2.177 +            if exists(htdocs):
   2.178 +                print "Move htdocs from wikidata directory."
   2.179 +                if not test:
   2.180 +                    rename(htdocs, join(self.common_dir, "htdocs"))
   2.181 +        else:
   2.182 +            print "No wikidata directory."
   2.183 +
   2.184 +        # Remove links and directories.
   2.185 +
   2.186 +        for name in ("conf", "wikidata"):
   2.187 +            d = join(self.common_dir, name)
   2.188 +            if islink(d):
   2.189 +                print "Remove %s symbolic link." % name
   2.190 +                if not test:
   2.191 +                    remove(d)
   2.192 +
   2.193 +        if isdir(conf_dir):
   2.194 +            print "Remove conf directory."
   2.195 +            if not test:
   2.196 +                rmdir(conf_dir)
   2.197 +
   2.198 +        # Add any missing htdocs directory.
   2.199 +
   2.200 +        if not exists(self.htdocs_dir):
   2.201 +            print "Copy htdocs into the instance."
   2.202 +            if not test:
   2.203 +                self.install_static_data()
   2.204 +
   2.205 +        # Now attempt to reconfigure the Wiki.
   2.206 +
   2.207 +        print "Reconfigure the Wiki, the Web script and the site files."
   2.208 +        if not test:
   2.209 +            self.configure_moin()
   2.210 +            self.edit_moin_web_script()
   2.211 +            self.make_site_files()
   2.212 +
   2.213      def install_theme(self, theme_dir, theme_name=None):
   2.214  
   2.215          """
   2.216 @@ -1078,7 +1143,7 @@
   2.217          resources_dir = join(self.htdocs_dir, theme_name)
   2.218  
   2.219          if not exists(resources_dir):
   2.220 -            os.mkdir(resources_dir)
   2.221 +            mkdir(resources_dir)
   2.222  
   2.223          status("Copying theme resources to %s..." % resources_dir)
   2.224  
   2.225 @@ -1109,12 +1174,12 @@
   2.226          "Install any libraries from 'extension_dir' using a setup script."
   2.227  
   2.228          this_dir = os.getcwd()
   2.229 -        os.chdir(extension_dir)
   2.230 +        chdir(extension_dir)
   2.231  
   2.232          options = "install --install-lib=%s" % self.prefix_site_packages
   2.233  
   2.234          os.system("python setup.py %s" % options)
   2.235 -        os.chdir(this_dir)
   2.236 +        chdir(this_dir)
   2.237  
   2.238      def install_plugins(self, plugins_dir, plugin_type):
   2.239  
   2.240 @@ -1269,7 +1334,7 @@
   2.241          try:
   2.242              script = ["MoinMoinPackage|1"]
   2.243  
   2.244 -            for filename in os.listdir(page_directory):
   2.245 +            for filename in listdir(page_directory):
   2.246                  pathname = join(page_directory, filename)
   2.247  
   2.248                  # Add files as pages having the filename as page name.
   2.249 @@ -1286,7 +1351,7 @@
   2.250  
   2.251                      # Add each file as an attachment.
   2.252  
   2.253 -                    for attachment in os.listdir(pathname):
   2.254 +                    for attachment in listdir(pathname):
   2.255                          zipname = "%s_%s" % (filename, attachment)
   2.256                          package.write(join(pathname, attachment), zipname)
   2.257                          script.append("AddAttachment|%s|%s|%s||" % (zipname, attachment, parent))