Esempio n. 1
0
def remDisk(srvObj, reqPropsObj, diskId, execute):
    """
    Select a disk for removal and remove the information if so specified
    from the NGAS DB and delete all information on the disk.

    srvObj:         Reference to NG/AMS server class object (ngamsServer).

    reqPropsObj:    Request Property object to keep track of actions done
                    during the request handling (ngamsReqProps).

    diskId:         ID of disk. Complete ID must be specified. I.e., no
                    wildcards are handled (string).

    execute:        If set to 1 the information about the disk will be deleted.
                    Otherwise only the information about the disk selected for
                    deletion will be queried (integer/0|1).

    Returns:        Status object contained information about disk
                    selected for deletion/deleted (ngamsStatus).
    """
    tmpFilePat = ngamsHighLevelLib.genTmpFilename(srvObj.getCfg(),
                                                  "REMDISK_CMD")
    try:
        status = _remDisk(srvObj, reqPropsObj, diskId, execute, tmpFilePat)
        return status
    finally:
        rmFile(tmpFilePat + "*")
Esempio n. 2
0
def _handleFileList(srvObj, reqPropsObj, httpRef):
    """
    Handle STATUS?file_list... Command.

    srvObj:         Reference to NG/AMS server class object (ngamsServer).

    reqPropsObj:    Request Property object to keep track of actions done
                    during the request handling (ngamsReqProps).

    httpRef:        Reference to the HTTP request handler
                    object (ngamsHttpRequestHandler).

    Returns:        The File List ID allocated for this request (string).
    """
    T = TRACE()

    # Should a lower limit for the ingestion date be taken into account.
    fromIngDate = None
    if (reqPropsObj.hasHttpPar("from_ingestion_date")):
        tmpTromIngDate = reqPropsObj.getHttpPar("from_ingestion_date")
        fromIngDate = fromiso8601(tmpTromIngDate)

    # Handle the unique flag. If this is specified, only information for unique
    # File ID/Version pairs are returned.
    unique = False
    if (reqPropsObj.hasHttpPar("unique")):
        unique = int(reqPropsObj.getHttpPar("unique"))

    # Dump the file information needed.
    fileListId = genUniqueId()
    dbmBaseName = STATUS_FILE_LIST_DBM_TAG % fileListId
    fileInfoDbmName = ngamsHighLevelLib.genTmpFilename(srvObj.getCfg(),
                                                       dbmBaseName)

    # Dump the file info from the DB. Deal with uniqueness quickly
    # (instead of using a new file like before)
    try:
        fileInfoDbm = ngamsDbm.ngamsDbm(fileInfoDbmName, 0, 1)
        fileCount = 1
        unique_files = set()
        for f in srvObj.db.files_in_host(srvObj.getHostId(),
                                         from_date=fromIngDate):
            if unique:
                key = str('%s_%d' % (f[2], f[3]))
                if key in unique_files:
                    continue
            else:
                key = str(fileCount)
            fileInfoDbm.add(key, f)
            fileCount += 1

    except Exception as e:
        rmFile(fileInfoDbmName)
        msg = "Problem generating file list for STATUS Command. " +\
              "Parameters: from_ingestion_date=%s. Error: %s" %\
              (str(fromIngDate), str(e))
        raise Exception(msg)

    return fileListId
Esempio n. 3
0
def remFile(srvObj, reqPropsObj, diskId, fileId, fileVersion, execute):
    """
    Function used to delete information about files in the NGAS DB and to
    delete files on the disks. Only local files are considered.

    The information selected for deletion is selected applying the
    following criterias:

      o diskId!="", fileId=="", fileVersion==-1:
        All files on the given disk are taken.

      o diskId!="", fileId!="", fileVersion==-1:
        All files with the given File ID on the disk with the given ID
        will be selected. No specific file version will be taken into account.

      o diskId!="", fileId!="", fileVersion!=-1:
        The referenced file with the given File ID and File Version on the
        given ID is selected (if this exists).

      o diskId=="", fileId!="", fileVersion==-1:
        Not allowed.

      o diskId=="", fileId!="", fileVersion!=-1:
        Not allowed.

      o diskId=="", fileId=="", fileVersion!=-1:
        Not allowed.

      o diskId!="", fileId=="", fileVersion!=-1:
        Not allowed


    The function will not carry out the actual deletion of the selected
    files if the 'execute' parameter is set to 0. In this case a report
    with the items selected for deletion will be generated.


    NOTE: No files are selected for deletion, unless there are at least three
          copies of the file (File ID + File Version), which apparently are
          accessible. In addition, these three copies have to be distributed
          on three different disks (storage media).

    srvObj:          Reference to NG/AMS server class object (ngamsServer).

    reqPropsObj:     Request Property object to keep track of actions done
                     during the request handling (ngamsReqProps).

    diskId:          ID of disk. It is not possible to specify a pattern,
                     must be exact ID (string).

    fileId:          ID of file. It is possible to specify a file pattern
                     using wild cards (string).

    fileVersion:     Version of file to delete. If not specified, all
                     files matching the Disk ID + File ID will be selected.
                     Otherwise it is possible to specify a single file for
                     deletion (integer).

    execute:         If set to 0, only a report of the information that has
                     been selected for deletion is generated (integer/0|1).

    Returns:         Status object with a list of disks and corresponding
                     files deleted (ngamsStatus).
    """
    T = TRACE()

    tmpFilePat = ngamsHighLevelLib.genTmpFilename(srvObj.getCfg(),
                                                  "REMFILE_CMD")
    try:
        status = _remFile(srvObj, reqPropsObj, diskId, fileId, fileVersion,
                          execute, tmpFilePat)
        return status
    finally:
        rmFile(tmpFilePat + "*")
Esempio n. 4
0
def clone(srvObj,
          diskId,
          fileId,
          fileVersion,
          targetDiskId="",
          reqPropsObj=None,
          httpRef=None):
    """
    Carry out the cloning. The conditions for carrying out the cloning
    are as follows:

      o diskId="", fileId!="", fileVersion=-1:
      Clone one file with the given ID. Latest version of the file is taken.

      o diskId!="", fileId!="", fileVersion=-1:
      Clone one file stored on the given disk. Latest version on that
      disk is taken.

      o diskId="", fileId!="", fileVersion!=-1:
      Clone all files found with the given File Version. Storage location
      (Disk ID) is not taken into account.

      o diskId!="", fileId!="", fileVersion!=-1:
      Clone one file on the given disk with the given File Version.

      o diskId!="", fileId="", fileVersion=-1:
      Clone all files from the disk with the given ID.

      o diskId!="", fileId="", fileVersion!=-1:
      Clone all files with the given File Version from the disk with
      the ID given.

      o diskId="", fileId="", fileVersion!=-1:
      Illegal. Not accepted to clone arbitrarily files given by only the
      File Version.

      o diskId="", fileId="", fileVersion=-1:
      Illegal. No files specified.

    srvObj:        Reference to instance of Server Object (ngamsServer).

    diskId:        ID of disk hosting file(s) to clone (string).

    fileId:        ID of file to clone (string).

    fileVersion:   Version of file(s) to clone (integer).

    targetDiskId:  ID of disk to where the files cloned should be written
                   (string).

    reqPropsObj:   If an NG/AMS Request Properties Object is given, the
                   Request Status will be updated as the request is carried
                   out (ngamsReqProps).

    httpRef:       Reference to the HTTP request handler
                   object (ngamsHttpRequestHandler).

    Returns:       Void.
    """
    T = TRACE()

    tmpFilePat = ngamsHighLevelLib.genTmpFilename(srvObj.getCfg(), "CLONE_CMD")
    try:
        _clone(srvObj, diskId, fileId, fileVersion, targetDiskId, reqPropsObj,
               httpRef, tmpFilePat)
    except Exception:
        rmFile(tmpFilePat + "*")
        raise
Esempio n. 5
0
def register(srvObj, path, mimeType="", reqPropsObj=None, httpRef=None):
    """
    Function to generate a list of candidate files to register, and to
    launch a thread that actually carries out the registration.

    When the possible candidate files haven been selected, a reply is sent
    back to the requestor if the 'httpRef' object is given.

    srvObj:       Instance of NG/AMS Server object (ngamsServer).

    path:         The path name, which is used as starting point for
                  the searching for files (string).

    mimeType:     Comma separated list of mime-types, which should be
                  considered for registration (string).

    reqPropsObj:  If an NG/AMS Request Properties Object is given, the
                  Request Status will be updated as the request is carried
                  out (ngamsReqProps).

    httpRef:      Reference to the HTTP request handler
                  object (ngamsHttpRequestHandler).

    Returns:      Void.
    """
    # Check if the given path or file exists.
    if (not os.path.exists(path)):
        errMsg = genLog("NGAMS_ER_FILE_REG_FAILED",
                        [path, "Non-existing file or path."])
        raise Exception(errMsg)

    # Check if the given path/file is on one of the NGAS Disks.
    foundPath = 0
    for slotId in srvObj.getDiskDic().keys():
        do = srvObj.getDiskDic()[slotId]
        if (path.find(do.getMountPoint()) == 0):
            foundPath = 1
            break
    if (not foundPath):
        errMsg = genLog("NGAMS_ER_FILE_REG_FAILED", [
            path, "File or path specified is not located on an "
            "NGAS Disk."
        ])
        raise Exception(errMsg)

    # Create file pattern for temporary files.
    tmpFilePat = ngamsHighLevelLib.genTmpFilename(srvObj.getCfg(),
                                                  "REGISTER_CMD")

    # Generate dictionary with mime-types to accept.
    mimeTypeDic = {}
    if (mimeType != ""):
        for mt in mimeType.split(","):
            try:
                mimeTypeDic[mt] = srvObj.getMimeTypeDic()[mt]
            except:
                errMsg = genLog("NGAMS_ER_REQ_HANDLING",
                                ["Mime-type specified: " + mt + " " +\
                                 "in connection with REGISTER command " +\
                                 "does not have a DAPI defined"])
                raise Exception(errMsg)
    else:
        mimeTypeDic = srvObj.getMimeTypeDic()

    # From the Disk Dictionary, generate a dictionary with mappings from
    # Disk ID + from Mount Point to the disk information for the disk.
    diskInfoDic = {}
    mtPt2DiskInfo = {}
    for slotId in srvObj.getDiskDic().keys():
        if (not srvObj.getCfg().getSlotIdDefined(slotId)): continue
        diskId = srvObj.getDiskDic()[slotId].getDiskId()
        mtPt = srvObj.getDiskDic()[slotId].getMountPoint()
        tmpDiskInfo         = ngamsDiskInfo.ngamsDiskInfo().\
                              read(srvObj.getDb(), diskId)
        diskInfoDic[diskId] = tmpDiskInfo
        mtPt2DiskInfo[mtPt] = tmpDiskInfo

    # Generate a list with all files found under the specified path, which
    # are candidates for being registered.
    fileListDbmName = tmpFilePat + "_FILE_LIST"
    rmFile(fileListDbmName + "*")
    fileListDbm = ngamsDbm.ngamsDbm(fileListDbmName, writePerm=1)
    mimeTypeMappings = srvObj.getCfg().getMimeTypeMappings()
    tmpGlobFile = tmpFilePat + "_FILE_GLOB.glob"
    fileCount = 0
    searchPath = os.path.normpath(path)
    foundVolume = False
    for mtPt in mtPt2DiskInfo.keys():
        mtPt2 = mtPt
        if (mtPt[-1] != "/"): mtPt2 += "/"
        if (searchPath.find(mtPt2) == 0):
            foundVolume = True
            if os.path.isdir(searchPath):
                for root, dirs, files in os.walk(searchPath):
                    for nextFile in files:
                        if nextFile not in \
                        [NGAMS_DISK_INFO, \
                         NGAMS_VOLUME_ID_FILE, \
                         NGAMS_VOLUME_INFO_FILE]:
                            mimeType = ngamsLib.detMimeType(
                                mimeTypeMappings, nextFile, 0)
                            tmpFileInfo = [
                                os.path.join(root, nextFile),
                                mtPt2DiskInfo[mtPt].getDiskId(), mimeType
                            ]
                            fileListDbm.add(os.path.join(root, nextFile),
                                            tmpFileInfo)

            elif os.path.isfile(
                    searchPath):  # the path is actually pointing to a file
                nextFile = os.path.basename(searchPath)
                root = os.path.dirname(searchPath)
                if nextFile not in \
                [NGAMS_DISK_INFO, \
                 NGAMS_VOLUME_ID_FILE, \
                 NGAMS_VOLUME_INFO_FILE]:
                    mimeType = ngamsLib.detMimeType(mimeTypeMappings, nextFile,
                                                    0)
                    tmpFileInfo = [
                        os.path.join(root, nextFile),
                        mtPt2DiskInfo[mtPt].getDiskId(), mimeType
                    ]
                    fileListDbm.add(os.path.join(root, nextFile), tmpFileInfo)
        if foundVolume: break


#    pattern = ""
#    # TODO: Portatibility issue. The usage of UNIX commands should be
#    #       avoided if possible.
#    while (1):
#        # Use a shell commands here to avoid building up maybe huge lists in
#        # memory/in the Python interpreter. A better way could maybe be found
#        # avoiding to invoke a shell command.
#        rmFile(tmpGlobFile)
#        searchPath = os.path.normpath(path + pattern)
#        tmpCmd = "find " + searchPath + " -maxdepth 1 > " + tmpGlobFile
#        stat, out = commands.getstatusoutput(tmpCmd)
#        if (stat != 0): break
#        fo = open(tmpGlobFile)
#        while (1):
#            nextFile = fo.readline().strip()
#            if (nextFile == ""): break
#            if (nextFile.find("/" + NGAMS_DISK_INFO) != -1): continue
#            if (nextFile.find("/" + NGAMS_VOLUME_ID_FILE) != -1): continue
#            if (nextFile.find("/" + NGAMS_VOLUME_INFO_FILE) != -1): continue
#            if (os.path.isfile(nextFile)):
#                nextFile = os.path.normpath(nextFile)
#
#                # Find the host disk. Only files located on mounted NGAS
#                # disks are considered.
#                for mtPt in mtPt2DiskInfo.keys():
#                    mtPt2 = mtPt
#                    if (mtPt[-1] != "/"): mtPt2 += "/"
#                    if (nextFile.find(mtPt2) == 0):
#                        info(4,"Found candidate file for registering: " +\
#                             nextFile)
#                        # Take only files with a Registration Plug-In defined.
#                        mimeType = ngamsLib.detMimeType(mimeTypeMappings,
#                                                        nextFile, 0)
#                        regPi = srvObj.getCfg().getRegPiFromMimeType(mimeType)
#                        if (regPi != None):
#                            tmpFileInfo = [nextFile,
#                                           mtPt2DiskInfo[mtPt].getDiskId(),
#                                           mimeType]
#                            fileListDbm.add(nextFile, tmpFileInfo)
#                            break
#        fo.close()
#        pattern += "/*"
#    rmFile(tmpGlobFile)
    fileListDbm.sync()
    del fileListDbm

    # Send intermediate reply if the HTTP Reference object is given.
    is_async = 'async' in reqPropsObj and int(reqPropsObj['async'])
    if httpRef and is_async:
        logger.debug("REGISTER command accepted - generating immediate " +\
             "confimation reply to REGISTER command")

        # Update the request status in the Request Properties Object.
        reqPropsObj.\
                      setExpectedCount(fileCount).\
                      setActualCount(0).setCompletionPercent(0)
        srvObj.updateRequestDb(reqPropsObj)
        status = srvObj.genStatus(NGAMS_SUCCESS,
                                  "Accepted REGISTER command for execution").\
                                  setReqStatFromReqPropsObj(reqPropsObj).\
                                  setActualCount(0)

    # Launch the register thread or run the command in foreground if wait=1
    if is_async:
        args = (srvObj, fileListDbmName, tmpFilePat, diskInfoDic, reqPropsObj,
                None)
        thrName = NGAMS_REGISTER_THR + threading.current_thread().getName()
        regThread = threading.Thread(None, _registerThread, thrName, args)
        regThread.setDaemon(0)
        regThread.start()
    else:
        # Carry out the REGISTER Command (directly in this thread) and send
        # reply when this is done.
        _registerExec(srvObj, fileListDbmName, tmpFilePat, diskInfoDic,
                      reqPropsObj)
        msg = "Successfully handled command REGISTER"
        logger.debug(msg)
        status = srvObj.genStatus(NGAMS_SUCCESS, msg).\
                 setReqStatFromReqPropsObj(reqPropsObj).setActualCount(0)

    # Send reply if possible.
    if (httpRef):
        xmlStat = status.genXmlDoc(0, 0, 0, 1, 0)
        xmlStat = ngamsHighLevelLib.addStatusDocTypeXmlDoc(srvObj, xmlStat)
        httpRef.send_data(six.b(xmlStat), NGAMS_XML_MT)