From 833b8e4eae6295640354e97284f5e99c2acfa4d0 Mon Sep 17 00:00:00 2001
From: William Brown <firstyear@redhat.com>
Date: Wed, 25 Oct 2017 09:48:01 +1000
Subject: [PATCH] Ticket 17 - lib389 - dsremove support

Bug Description:  We need to support clean removal of our server
instances with pure python cli and test cases

Fix Description:  This fixes support for removing replicated
instances wth python, and adds support for dsctl <inst> remove.

https://pagure.io/lib389/issue/17

Author: wibrown

Review by: ???
---
 Makefile.am                           |  2 +-
 src/lib389/cli/dsctl                  |  4 ++--
 src/lib389/lib389/cli_ctl/instance.py | 40 +++++++++++++++++++++++++++++++++++
 src/lib389/lib389/instance/remove.py  |  3 +++
 src/lib389/lib389/instance/setup.py   |  8 ++++++-
 5 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 8e24957..95f6e1d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2218,7 +2218,7 @@ lib389: src/lib389/setup.py
 	cd $(srcdir)/src/lib389; $(PYTHON) setup.py build
 
 lib389-install: lib389
-	cd $(srcdir)/src/lib389; $(PYTHON) setup.py install --skip-build
+	cd $(srcdir)/src/lib389; $(PYTHON) setup.py install --skip-build --force
 
 tests: setup.py.in lib389
 	$(PYTHON) setup.py build
diff --git a/src/lib389/cli/dsctl b/src/lib389/cli/dsctl
index 8aa4f4b..36ecf99 100755
--- a/src/lib389/cli/dsctl
+++ b/src/lib389/cli/dsctl
@@ -61,7 +61,7 @@ if __name__ == '__main__':
     # Assert we have a resources to work on.
     if not hasattr(args, 'func'):
         log.error("No action provided")
-        log.error("USAGE: dsadm [options] <resource> <action> [action options]")
+        log.error("USAGE: dsctl [options] <resource> <action> [action options]")
         sys.exit(1)
 
     # Connect
@@ -94,7 +94,7 @@ if __name__ == '__main__':
         log.info('FAIL: Command failed. See output for details.')
 
     # Done!
-    log.debug("dsadm is brought to you by the letter R and the number 27.")
+    log.debug("dsctl is brought to you by the letter R and the number 27.")
 
     if result is False:
         sys.exit(1)
diff --git a/src/lib389/lib389/cli_ctl/instance.py b/src/lib389/lib389/cli_ctl/instance.py
index f59fb2b..385381a 100644
--- a/src/lib389/lib389/cli_ctl/instance.py
+++ b/src/lib389/lib389/cli_ctl/instance.py
@@ -10,6 +10,7 @@ from lib389._constants import *
 
 from lib389.tools import DirSrvTools
 from lib389.instance.setup import SetupDs
+from lib389.instance.remove import remove_ds_instance
 from getpass import getpass
 import os
 import time
@@ -114,10 +115,45 @@ def instance_example(inst, log, args):
     print(g2b.collect_help())
     print(s2b.collect_help())
 
+def instance_remove(inst, log, args):
+    if not args.ack:
+        sys.exit(0)
+    else:
+        log.info("""
+ _________________________________________
+/ This is not what you want! Press ctrl-c \\
+\ now ...                                 /
+ -----------------------------------------
+      \\                   / \\  //\\
+       \\    |\\___/|      /   \\//  \\\\
+            /0  0  \\__  /    //  | \\ \\
+           /     /  \\/_/    //   |  \\  \\
+           @_^_@'/   \\/_   //    |   \\   \\
+           //_^_/     \\/_ //     |    \\    \\
+        ( //) |        \\///      |     \\     \\
+      ( / /) _|_ /   )  //       |      \\     _\\
+    ( // /) '/,_ _ _/  ( ; -.    |    _ _\\.-~        .-~~~^-.
+  (( / / )) ,-{        _      `-.|.-~-.           .~         `.
+ (( // / ))  '/\\      /                 ~-. _ .-~      .-~^-.  \\
+ (( /// ))      `.   {            }                   /      \\  \\
+  (( / ))     .----~-.\\        \\-'                 .~         \\  `. \\^-.
+             ///.----..>        \\             _ -~             `.  ^-`  ^-_
+               ///-._ _ _ _ _ _ _}^ - - - - ~                     ~-- ,.-~
+                                                                  /.-~
+        """)
+    for i in range(1,6):
+        log.info('%s ...' % (5 - int(i)))
+        time.sleep(1)
+    log.info('Removing instance ...')
+    remove_ds_instance(inst)
+    log.info('Completed instance removal')
+
+
 def create_parser(subcommands):
     # list_parser = subcommands.add_parser('list', help="List installed instances of Directory Server")
     # list_parser.set_defaults(func=instance_list)
     # list_parser.set_defaults(noinst=True)
+
     restart_parser = subcommands.add_parser('restart', help="Restart an instance of Directory Server, if it is running: else start it.")
     restart_parser.set_defaults(func=instance_restart)
 
@@ -130,4 +166,8 @@ def create_parser(subcommands):
     status_parser = subcommands.add_parser('status', help="Check running status of an instance of Directory Server")
     status_parser.set_defaults(func=instance_status)
 
+    remove_parser = subcommands.add_parser('remove', help="Destroy an instance of Directory Server, and remove all data.")
+    remove_parser.add_argument('--doit', dest="ack", help="By default we do a dry run. This actually initiates the removal.", action='store_true', default=False)
+    remove_parser.set_defaults(func=instance_remove)
+
 
diff --git a/src/lib389/lib389/instance/remove.py b/src/lib389/lib389/instance/remove.py
index 689b5bd..9ce8505 100644
--- a/src/lib389/lib389/instance/remove.py
+++ b/src/lib389/lib389/instance/remove.py
@@ -24,6 +24,9 @@ def remove_ds_instance(dirsrv):
     remove_paths['cert_dir'] = dirsrv.ds_paths.cert_dir
     remove_paths['config_dir'] = dirsrv.ds_paths.config_dir
     remove_paths['db_dir'] = dirsrv.ds_paths.db_dir
+    ### WARNING: The changelogdb isn't removed. we assume it's in:
+    # db_dir ../changelogdb. So remove that too!
+    remove_paths['changelogdb_dir'] = os.path.join(dirsrv.ds_paths.db_dir, '../changelogdb')
     remove_paths['ldif_dir'] = dirsrv.ds_paths.ldif_dir
     remove_paths['lock_dir'] = dirsrv.ds_paths.lock_dir
     remove_paths['log_dir'] = dirsrv.ds_paths.log_dir
diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py
index 659c87e..55b7b6c 100644
--- a/src/lib389/lib389/instance/setup.py
+++ b/src/lib389/lib389/instance/setup.py
@@ -315,7 +315,10 @@ class SetupDs(object):
         with open("%s/dirsrv/config/template-initconfig" % slapd['sysconf_dir']) as template_init:
             for line in template_init.readlines():
                 initconfig += line.replace('{{', '{', 1).replace('}}', '}', 1).replace('-', '_')
-        os.makedirs("%s/sysconfig" % slapd['sysconf_dir'], mode=0o775)
+        try:
+            os.makedirs("%s/sysconfig" % slapd['sysconf_dir'], mode=0o775)
+        except FileExistsError:
+            pass
         with open("%s/sysconfig/dirsrv-%s" % (slapd['sysconf_dir'], slapd['instance_name']), 'w') as f:
             f.write(initconfig.format(
                 SERVER_DIR=slapd['lib_dir'],
@@ -432,6 +435,9 @@ class SetupDs(object):
         ds_instance.start(timeout=60)
         ds_instance.open()
 
+        # In some cases we may want to change log settings
+        # ds_instance.config.enable_log('audit')
+
         # Create the configs related to this version.
         base_config = get_config(general['defaults'])
         base_config_inst = base_config(ds_instance)
-- 
1.8.3.1

