You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2016/02/05 22:56:22 UTC

[07/40] ambari git commit: AMBARI-14919. [Ambari tarballs] Create script to install ambari tar.gz into custom root (aonishuk)

AMBARI-14919. [Ambari tarballs] Create script to install ambari tar.gz into custom root (aonishuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/04b02273
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/04b02273
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/04b02273

Branch: refs/heads/branch-dev-patch-upgrade
Commit: 04b02273a611377602f023f4b6700856dc8eb115
Parents: ed3ca61
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Thu Feb 4 14:06:02 2016 +0200
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Thu Feb 4 14:06:02 2016 +0200

----------------------------------------------------------------------
 ambari-agent/pom.xml                            |  44 +++++-
 .../src/main/repo/install_ambari_tarball.py     | 145 +++++++++++++++++++
 ambari-server/conf/unix/install-helper.sh       |  52 ++++---
 ambari-server/pom.xml                           | 106 ++++++++++----
 .../src/main/package/deb/control/postinst       |   6 +-
 .../src/main/package/deb/control/preinst        |  23 +--
 .../src/main/package/deb/control/prerm          |   6 +-
 7 files changed, 313 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/04b02273/ambari-agent/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-agent/pom.xml b/ambari-agent/pom.xml
index 918065f..7531650 100644
--- a/ambari-agent/pom.xml
+++ b/ambari-agent/pom.xml
@@ -334,6 +334,48 @@
               </resources>
             </configuration>
           </execution>
+          <execution>
+            <id>copy-repo-resources</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${basedir}/target/repo</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>${project.basedir}/../ambari-common/src/main/repo</directory>
+                </resource>
+                <resource>
+                  <directory>${project.build.directory}</directory>
+                  <includes>
+                    <include>${project.artifactId}-${project.version}.tar.gz</include>
+                  </includes>
+                </resource>
+                <resource>
+                  <directory>${basedir}/src/main/package/deb/control</directory>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>com.coderplus.maven.plugins</groupId>
+        <artifactId>copy-rename-maven-plugin</artifactId>
+        <version>1.0.1</version>
+        <executions>
+          <execution>
+            <id>rename-file</id>
+            <phase>package</phase>
+            <goals>
+              <goal>rename</goal>
+            </goals>
+            <configuration>
+              <sourceFile>${basedir}/target/repo/${project.artifactId}-${project.version}.tar.gz</sourceFile>
+              <destinationFile>${basedir}/target/repo/${project.artifactId}.tar.gz</destinationFile>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
       <plugin>
@@ -449,7 +491,7 @@
             <executions>
               <execution>
                 <id>build-windows-zip</id>
-                <phase>prepare-package</phase>
+                <phase>package</phase>
                 <goals>
                   <goal>single</goal>
                 </goals>

http://git-wip-us.apache.org/repos/asf/ambari/blob/04b02273/ambari-common/src/main/repo/install_ambari_tarball.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/repo/install_ambari_tarball.py b/ambari-common/src/main/repo/install_ambari_tarball.py
new file mode 100644
index 0000000..aa33ede
--- /dev/null
+++ b/ambari-common/src/main/repo/install_ambari_tarball.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python2
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+'''
+
+import os
+import sys
+import logging
+import subprocess
+from optparse import OptionParser
+
+USAGE = "Usage: %prog [OPTION]... URL"
+DESCRIPTION = "URL should point to full tar.gz location e.g.: https://public-repo-1.hortonworks.com/something/ambari-server.tar.gz"
+
+logger = logging.getLogger("install_ambari_tarball")
+
+PREINST_SCRIPT = "preinst"
+PRERM_SCRIPT = "prerm"
+POSTINST_SCRIPT = "postinst"
+POSTRM_SCRIPT = "postrm"
+
+ROOT_FOLDER_ENV_VARIABLE = "AMBARI_ROOT_FOLDER"
+
+class Utils:
+  verbose = False
+  @staticmethod
+  def os_call(command, logoutput=None, env={}):
+    shell = not isinstance(command, list)
+    print_output = logoutput==True or (logoutput==None and Utils.verbose)
+    
+    if not print_output:
+      stdout = subprocess.PIPE
+      stderr = subprocess.STDOUT
+    else:
+      stdout = stderr = None
+    
+    logger.info("Running '{0}'".format(command))
+    proc = subprocess.Popen(command, shell=shell, stdout=stdout, stderr=stderr, env=env)
+      
+    if not print_output:
+      out = proc.communicate()[0].strip('\n')
+    else:
+      proc.wait()
+      out = None
+      
+    code = proc.returncode
+  
+    if code:
+      err_msg = ("Execution of '%s'\n returned %d. %s") % (command, code, out)
+      raise OsCallFailure(err_msg)
+      
+    return out
+  
+class OsCallFailure(RuntimeError):
+  pass
+
+class Installer:
+  def __init__(self, archive_url, root_folder, verbose):
+    splited_url = archive_url.split('/')
+    self.archive_name = splited_url[-1]
+    self.base_url = '/'.join(splited_url[0:-1])
+    self.root_folder = root_folder
+    self.verbose = verbose
+    
+  def download_files(self):
+    for name in [ self.archive_name, PREINST_SCRIPT, PRERM_SCRIPT, POSTINST_SCRIPT, POSTRM_SCRIPT]: 
+      url = "{0}/{1}".format(self.base_url, name)
+      logger.info("Downloading {0}".format(url))
+      Utils.os_call(["wget", "-O", name, url])
+    
+  def run(self):
+    self.download_files()
+    
+    self.run_script(PRERM_SCRIPT, ["remove"]) # in case we are upgrading
+    self.run_script(POSTRM_SCRIPT, ["remove"]) # in case we are upgrading
+    
+    self.run_script(PREINST_SCRIPT, ["install"])
+    self.extract_archive()
+    self.run_script(POSTINST_SCRIPT, ["configure"])
+    
+  def run_script(self, script_name, args):
+    bash_args = []
+    if self.verbose:
+      bash_args.append("-x")
+      
+    Utils.os_call(["bash"] + bash_args + [script_name] + args, env={ROOT_FOLDER_ENV_VARIABLE: self.root_folder})
+    
+
+class TargzInstaller(Installer):
+  def extract_archive(self):
+    Utils.os_call(['tar','--no-same-owner', '-xvf', self.archive_name, '-C', self.root_folder+os.sep], logoutput=False)
+
+
+class Runner:
+  def parse_opts(self):
+    parser = OptionParser(usage=USAGE, description=DESCRIPTION)
+    parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
+                      help="sets output level to more detailed")
+    parser.add_option("-r", "--root-folder", dest="root_folder", default="/",
+                      help="root folder to install Ambari to. E.g.: /opt")
+    
+    (self.options, args) = parser.parse_args()
+    
+    if len(args) != 1:
+      help = parser.print_help()
+      sys.exit(1)
+      
+    self.url = args[0]
+    
+  @staticmethod
+  def setup_logger(verbose):
+    logging_level = logging.DEBUG if verbose else logging.INFO
+    logger.setLevel(logging_level)
+
+    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
+    stdout_handler = logging.StreamHandler(sys.stdout)
+    stdout_handler.setLevel(logging_level)
+    stdout_handler.setFormatter(formatter)
+    logger.addHandler(stdout_handler)
+    
+  def run(self):
+    self.parse_opts()
+    Runner.setup_logger(self.options.verbose)
+    Utils.verbose = self.options.verbose
+    
+    # TODO: check if ends with tar.gz?
+    targz_installer = TargzInstaller(self.url, self.options.root_folder, self.options.verbose)
+    targz_installer.run()
+      
+if __name__ == '__main__':
+  Runner().run()
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/04b02273/ambari-server/conf/unix/install-helper.sh
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/install-helper.sh b/ambari-server/conf/unix/install-helper.sh
index c7d05b4..a1405e0 100644
--- a/ambari-server/conf/unix/install-helper.sh
+++ b/ambari-server/conf/unix/install-helper.sh
@@ -17,24 +17,33 @@
 #                      SERVER INSTALL HELPER                     #
 ##################################################################
 
-COMMON_DIR="/usr/lib/python2.6/site-packages/ambari_commons"
-RESOURCE_MANAGEMENT_DIR="/usr/lib/python2.6/site-packages/resource_management"
-JINJA_DIR="/usr/lib/python2.6/site-packages/ambari_jinja2"
-SIMPLEJSON_DIR="/usr/lib/python2.6/site-packages/ambari_simplejson"
-OLD_COMMON_DIR="/usr/lib/python2.6/site-packages/common_functions"
-AMBARI_SERVER="/usr/lib/python2.6/site-packages/ambari_server"
-INSTALL_HELPER_AGENT="/var/lib/ambari-agent/install-helper.sh"
-COMMON_DIR_SERVER="/usr/lib/ambari-server/lib/ambari_commons"
-RESOURCE_MANAGEMENT_DIR_SERVER="/usr/lib/ambari-server/lib/resource_management"
-JINJA_SERVER_DIR="/usr/lib/ambari-server/lib/ambari_jinja2"
-SIMPLEJSON_SERVER_DIR="/usr/lib/ambari-server/lib/ambari_simplejson"
-
-PYTHON_WRAPER_TARGET="/usr/bin/ambari-python-wrap"
-PYTHON_WRAPER_SOURCE="/var/lib/ambari-server/ambari-python-wrap"
+ROOT="${AMBARI_ROOT_FOLDER}"
+
+COMMON_DIR="${ROOT}/usr/lib/python2.6/site-packages/ambari_commons"
+RESOURCE_MANAGEMENT_DIR="${ROOT}/usr/lib/python2.6/site-packages/resource_management"
+JINJA_DIR="${ROOT}/usr/lib/python2.6/site-packages/ambari_jinja2"
+SIMPLEJSON_DIR="${ROOT}/usr/lib/python2.6/site-packages/ambari_simplejson"
+OLD_COMMON_DIR="${ROOT}/usr/lib/python2.6/site-packages/common_functions"
+AMBARI_SERVER="${ROOT}/usr/lib/python2.6/site-packages/ambari_server"
+INSTALL_HELPER_AGENT="${ROOT}/var/lib/ambari-agent/install-helper.sh"
+COMMON_DIR_SERVER="${ROOT}/usr/lib/ambari-server/lib/ambari_commons"
+RESOURCE_MANAGEMENT_DIR_SERVER="${ROOT}/usr/lib/ambari-server/lib/resource_management"
+JINJA_SERVER_DIR="${ROOT}/usr/lib/ambari-server/lib/ambari_jinja2"
+SIMPLEJSON_SERVER_DIR="${ROOT}/usr/lib/ambari-server/lib/ambari_simplejson"
+
+PYTHON_WRAPER_TARGET="${ROOT}/usr/bin/ambari-python-wrap"
+PYTHON_WRAPER_SOURCE="${ROOT}/var/lib/ambari-server/ambari-python-wrap"
+
+AMBARI_SERVER_EXECUTABLE_LINK="${ROOT}/usr/sbin/ambari-server"
+AMBARI_SERVER_EXECUTABLE="${ROOT}/etc/init.d/ambari-server"
+
+AMBARI_CONFIGS_DIR="${ROOT}/etc/ambari-server/conf"
+AMBARI_CONFIGS_DIR_SAVE="${ROOT}/etc/ambari-server/conf.save"
+AMBARI_CONFIGS_DIR_SAVE_BACKUP="${ROOT}/etc/ambari-server/conf_$(date '+%d_%m_%y_%H_%M').save"
 
 do_install(){
-  rm -f /usr/sbin/ambari-server
-  ln -s /etc/init.d/ambari-server /usr/sbin/ambari-server
+  rm -f "$AMBARI_SERVER_EXECUTABLE_LINK"
+  ln -s "$AMBARI_SERVER_EXECUTABLE" "$AMBARI_SERVER_EXECUTABLE_LINK"
  
   # setting ambari_commons shared resource
   rm -rf "$OLD_COMMON_DIR"
@@ -69,14 +78,13 @@ do_install(){
 }
 
 do_remove(){
-  /usr/sbin/ambari-server stop > /dev/null 2>&1
-  if [ -d "/etc/ambari-server/conf.save" ]; then
-      mv /etc/ambari-server/conf.save /etc/ambari-server/conf_$(date '+%d_%m_%y_%H_%M').save
+  $AMBARI_SERVER_EXECUTABLE stop > /dev/null 2>&1
+  if [ -d "$AMBARI_CONFIGS_DIR_SAVE" ]; then
+    mv "$AMBARI_CONFIGS_DIR_SAVE" "$AMBARI_CONFIGS_DIR_SAVE_BACKUP"
   fi
   # Remove link created during install
-  rm -f /usr/sbin/ambari-server
-
-  mv /etc/ambari-server/conf /etc/ambari-server/conf.save
+  rm -f "$AMBARI_SERVER_EXECUTABLE_LINK"
+  mv "$AMBARI_CONFIGS_DIR" "$AMBARI_CONFIGS_DIR_SAVE"
     
   if [ -f "$PYTHON_WRAPER_TARGET" ]; then
     rm -f "$PYTHON_WRAPER_TARGET"

http://git-wip-us.apache.org/repos/asf/ambari/blob/04b02273/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index c601baa..6fb090a 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -80,38 +80,6 @@
         </executions>
       </plugin>
       <plugin>
-        <artifactId>maven-resources-plugin</artifactId>
-        <version>2.6</version>
-        <executions>
-          <execution>
-            <id>copy-resources</id>
-            <phase>generate-test-resources</phase>
-            <goals>
-              <goal>copy-resources</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>${basedir}/target/</outputDirectory>
-              <resources>
-                <resource>
-                  <directory>${basedir}/../</directory>
-                  <includes>
-                    <include>version</include>
-                  </includes>
-                  <filtering>true</filtering>
-                </resource>
-                <resource>
-                  <directory>${basedir}/sbin/</directory>
-                  <includes>
-                    <include>ambari-server</include>
-                  </includes>
-                  <filtering>true</filtering>
-                </resource>
-              </resources>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.0</version>
       </plugin>
@@ -177,6 +145,80 @@
         </executions>
       </plugin>
       <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>2.6</version>
+        <executions>
+          <execution>
+            <id>copy-resources</id>
+            <phase>generate-test-resources</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${basedir}/target/</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>${basedir}/../</directory>
+                  <includes>
+                    <include>version</include>
+                  </includes>
+                  <filtering>true</filtering>
+                </resource>
+                <resource>
+                  <directory>${basedir}/sbin/</directory>
+                  <includes>
+                    <include>ambari-server</include>
+                  </includes>
+                  <filtering>true</filtering>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+          <execution>
+            <id>copy-repo-resources</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${basedir}/target/repo</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>${project.basedir}/../ambari-common/src/main/repo</directory>
+                </resource>
+                <resource>
+                  <directory>${project.build.directory}</directory>
+                  <includes>
+                    <include>${project.artifactId}-${project.version}-dist.tar.gz</include>
+                  </includes>
+                </resource>
+                <resource>
+                  <directory>${basedir}/src/main/package/deb/control</directory>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>com.coderplus.maven.plugins</groupId>
+        <artifactId>copy-rename-maven-plugin</artifactId>
+        <version>1.0.1</version>
+        <executions>
+          <execution>
+            <id>rename-file</id>
+            <phase>package</phase>
+            <goals>
+              <goal>rename</goal>
+            </goals>
+            <configuration>
+              <sourceFile>${basedir}/target/repo/${project.artifactId}-${project.version}-dist.tar.gz</sourceFile>
+              <destinationFile>${basedir}/target/repo/${project.artifactId}.tar.gz</destinationFile>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
         <groupId>org.apache.rat</groupId>
         <artifactId>apache-rat-plugin</artifactId>
         <configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/04b02273/ambari-server/src/main/package/deb/control/postinst
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/package/deb/control/postinst b/ambari-server/src/main/package/deb/control/postinst
index e8d12c3..886e4fc 100644
--- a/ambari-server/src/main/package/deb/control/postinst
+++ b/ambari-server/src/main/package/deb/control/postinst
@@ -16,9 +16,11 @@
 
 # Warning: don't add changes to this script directly, please add changes to install-helper.sh.
 
+INSTALL_HELPER="${AMBARI_ROOT_FOLDER}/var/lib/ambari-server/install-helper.sh"
+
 if [ "$1" == "configure" ] ; then
-  if [ -f "/var/lib/ambari-server/install-helper.sh" ]; then
-      /var/lib/ambari-server/install-helper.sh install
+  if [ -f "$INSTALL_HELPER" ]; then
+      "$INSTALL_HELPER" install
   fi
 fi
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/04b02273/ambari-server/src/main/package/deb/control/preinst
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/package/deb/control/preinst b/ambari-server/src/main/package/deb/control/preinst
index 7bf7365..db66d92 100644
--- a/ambari-server/src/main/package/deb/control/preinst
+++ b/ambari-server/src/main/package/deb/control/preinst
@@ -14,27 +14,30 @@
 # See the License for the specific language governing permissions and
 # limitations under the License
 
-STACKS_FOLDER="/var/lib/ambari-server/resources/stacks"
-STACKS_FOLDER_OLD=/var/lib/ambari-server/resources/stacks_$(date '+%d_%m_%y_%H_%M').old
+STACKS_FOLDER="${AMBARI_ROOT_FOLDER}/var/lib/ambari-server/resources/stacks"
+STACKS_FOLDER_OLD=${AMBARI_ROOT_FOLDER}/var/lib/ambari-server/resources/stacks_$(date '+%d_%m_%y_%H_%M').old
 
-COMMON_SERVICES_FOLDER="/var/lib/ambari-server/resources/common-services"
-COMMON_SERVICES_FOLDER_OLD=/var/lib/ambari-server/resources/common-services_$(date '+%d_%m_%y_%H_%M').old
+COMMON_SERVICES_FOLDER="${AMBARI_ROOT_FOLDER}/var/lib/ambari-server/resources/common-services"
+COMMON_SERVICES_FOLDER_OLD=${AMBARI_ROOT_FOLDER}/var/lib/ambari-server/resources/common-services_$(date '+%d_%m_%y_%H_%M').old
 
-AMBARI_PROPERTIES="/etc/ambari-server/conf/ambari.properties"
+AMBARI_PROPERTIES="${AMBARI_ROOT_FOLDER}/etc/ambari-server/conf/ambari.properties"
 AMBARI_PROPERTIES_OLD="$AMBARI_PROPERTIES.rpmsave"
 
-AMBARI_ENV="/var/lib/ambari-server/ambari-env.sh"
+AMBARI_ENV="${AMBARI_ROOT_FOLDER}/var/lib/ambari-server/ambari-env.sh"
 AMBARI_ENV_OLD="$AMBARI_ENV.rpmsave"
 
-AMBARI_KRB_JAAS_LOGIN_FILE="/etc/ambari-server/conf/krb5JAASLogin.conf"
+AMBARI_KRB_JAAS_LOGIN_FILE="${AMBARI_ROOT_FOLDER}/etc/ambari-server/conf/krb5JAASLogin.conf"
 AMBARI_KRB_JAAS_LOGIN_FILE_OLD="$AMBARI_KRB_JAAS_LOGIN_FILE.rpmsave"
 
-AMBARI_VIEWS_FOLDER="/var/lib/ambari-server/resources/views"
+AMBARI_VIEWS_FOLDER="${AMBARI_ROOT_FOLDER}/var/lib/ambari-server/resources/views"
 AMBARI_VIEWS_BACKUP_FOLDER="$AMBARI_VIEWS_FOLDER/backups"
 
-if [ -d "/etc/ambari-server/conf.save" ]
+SERVER_CONF_SAVE="${AMBARI_ROOT_FOLDER}/etc/ambari-server/conf.save"
+SERVER_CONF_SAVE_BACKUP="${AMBARI_ROOT_FOLDER}/etc/ambari-server/conf_$(date '+%d_%m_%y_%H_%M').save"
+
+if [ -d "$SERVER_CONF_SAVE" ]
 then
-    mv /etc/ambari-server/conf.save /etc/ambari-server/conf_$(date '+%d_%m_%y_%H_%M').save
+    mv "$SERVER_CONF_SAVE" "SERVER_CONF_SAVE_BACKUP"
 fi
 
 if [ -f "$AMBARI_PROPERTIES" ]

http://git-wip-us.apache.org/repos/asf/ambari/blob/04b02273/ambari-server/src/main/package/deb/control/prerm
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/package/deb/control/prerm b/ambari-server/src/main/package/deb/control/prerm
index 98e3be5..cac2abe 100644
--- a/ambari-server/src/main/package/deb/control/prerm
+++ b/ambari-server/src/main/package/deb/control/prerm
@@ -16,9 +16,11 @@
 
 # Warning: don't add changes to this script directly, please add changes to install-helper.sh.
 
+INSTALL_HELPER="${AMBARI_ROOT_FOLDER}/var/lib/ambari-server/install-helper.sh"
+
 if [ "$1" == "remove" ] ; then # Action is uninstall
-    if [ -f "/var/lib/ambari-server/install-helper.sh" ]; then
-      /var/lib/ambari-server/install-helper.sh remove
+    if [ -f "$INSTALL_HELPER" ]; then
+      $INSTALL_HELPER remove
     fi
 fi