# File lib/openshift-origin-node/model/unix_user.rb, line 159
    def destroy
      if @uid.nil? and (not File.directory?(@homedir.to_s))
        # gear seems to have been destroyed already... suppress any error
        # TODO : remove remaining stuff if it exists, e.g. .httpd/#{uuid}* etc
        return nil
      end
      raise UserDeletionException.new(
            "ERROR: unable to destroy user account #{@uuid}"
            ) if @uid.nil? || @homedir.nil? || @uuid.nil?

      # Don't try to delete a gear that is being scaled-up|created|deleted
      uuid_lock_file = "/var/lock/oo-create.#{@uuid}"
      File.open(uuid_lock_file, File::RDWR|File::CREAT, 0o0600) do | lock |
        lock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
        lock.flock(File::LOCK_EX)

        # These calls and their order is designed to release pam_namespace's
        #   locks on .tmp and .sandbox. Change then at your peril. 
        #
        # 1. Kill off the easy processes
        # 2. Lock down the user from creating new processes (cgroups freeze, nprocs 0)
        # 3. Attempt to move any processes that didn't die into state 'D' (re: cgroups freeze)
        kill_procs(@uid)
        notify_observers(:before_unix_user_destroy)
        kill_procs(@uid)

        purge_sysvipc(uuid)
        initialize_openshift_port_proxy

        if @config.get("CREATE_APP_SYMLINKS").to_i == 1
          Dir.foreach(File.dirname(@homedir)) do |dent|
            unobfuscate = File.join(File.dirname(@homedir), dent)
            if (File.symlink?(unobfuscate)) &&
                (File.readlink(unobfuscate) == File.basename(@homedir))
              File.unlink(unobfuscate)
            end
          end
        end

        basedir = @config.get("GEAR_BASE_DIR")
        path = File.join(basedir, ".httpd.d", "#{uuid}_*")
        FileUtils.rm_rf(Dir.glob(path))

# Lock inside httpd_singular causing gear destroys to fail. BZ874712
#        cartdir = @config.get("CARTRIDGE_BASE_PATH")
#        out, err, rc = shellCmd("#{cartdir}/abstract/info/bin/httpd_singular graceful")
#        Syslog.alert("ERROR: failure from httpd_singular(#{rc}): #{@uuid} stdout: #{out} stderr:#{err}") unless rc == 0

        dirs = list_home_dir(@homedir)
        out,err,rc = shellCmd("userdel -f \"#{@uuid}\"")
        raise UserDeletionException.new(
              "ERROR: unable to destroy user account(#{rc}): #{@uuid} stdout: #{out} stderr:#{err}") unless rc == 0

        # 1. Don't believe everything you read on the userdel man page...
        # 2. If there are any active processes left pam_namespace is not going
        #      to let polyinstantiated directories be deleted.
        FileUtils.rm_rf(@homedir)
        if File.exists?(@homedir)
          # Ops likes the verbose verbage
          Syslog.alert "1st attempt to remove \'#{@homedir}\' from filesystem failed."
          Syslog.alert "Dir(before)   #{@uuid}/#{@uid} => #{dirs}"
          Syslog.alert "Dir(after)    #{@uuid}/#{@uid} => #{list_home_dir(@homedir)}"
        end

        # release resources (cgroups thaw), this causes Zombies to get killed
        notify_observers(:after_unix_user_destroy)

        # try one last time...
        if File.exists?(@homedir)
          sleep(5)                    # don't fear the reaper
          FileUtils.rm_rf(@homedir)   # This is our last chance to nuke the polyinstantiated directories
          Syslog.alert "2nd attempt to remove \'#{@homedir}\' from filesystem failed." if File.exists?(@homedir)
        end

        lock.flock(File::LOCK_UN)
        File.unlink(uuid_lock_file)
      end
    end