Search in sources :

Example 1 with UploadEntity

use of org.apache.cloudstack.storage.template.UploadEntity in project cloudstack by apache.

the class HttpUploadServerHandler method channelRead0.

@Override
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
    if (msg instanceof HttpRequest) {
        HttpRequest request = this.request = (HttpRequest) msg;
        responseContent.setLength(0);
        if (request.getMethod().equals(HttpMethod.POST)) {
            URI uri = new URI(request.getUri());
            String signature = null;
            String expires = null;
            String metadata = null;
            String hostname = null;
            long contentLength = 0;
            for (Entry<String, String> entry : request.headers()) {
                switch(entry.getKey()) {
                    case HEADER_SIGNATURE:
                        signature = entry.getValue();
                        break;
                    case HEADER_METADATA:
                        metadata = entry.getValue();
                        break;
                    case HEADER_EXPIRES:
                        expires = entry.getValue();
                        break;
                    case HEADER_HOST:
                        hostname = entry.getValue();
                        break;
                    case HttpHeaders.Names.CONTENT_LENGTH:
                        contentLength = Long.parseLong(entry.getValue());
                        break;
                }
            }
            logger.info("HEADER: signature=" + signature);
            logger.info("HEADER: metadata=" + metadata);
            logger.info("HEADER: expires=" + expires);
            logger.info("HEADER: hostname=" + hostname);
            logger.info("HEADER: Content-Length=" + contentLength);
            QueryStringDecoder decoderQuery = new QueryStringDecoder(uri);
            Map<String, List<String>> uriAttributes = decoderQuery.parameters();
            uuid = uriAttributes.get("uuid").get(0);
            logger.info("URI: uuid=" + uuid);
            UploadEntity uploadEntity = null;
            try {
                // Validate the request here
                storageResource.validatePostUploadRequest(signature, metadata, expires, hostname, contentLength, uuid);
                //create an upload entity. This will fail if entity already exists.
                uploadEntity = storageResource.createUploadEntity(uuid, metadata, contentLength);
            } catch (InvalidParameterValueException ex) {
                logger.error("post request validation failed", ex);
                responseContent.append(ex.getMessage());
                writeResponse(ctx.channel(), HttpResponseStatus.BAD_REQUEST);
                requestProcessed = true;
                return;
            }
            if (uploadEntity == null) {
                logger.error("Unable to create upload entity. An exception occurred.");
                responseContent.append("Internal Server Error");
                writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
                requestProcessed = true;
                return;
            }
            //set the base directory to download the file
            DiskFileUpload.baseDirectory = uploadEntity.getInstallPathPrefix();
            logger.info("base directory: " + DiskFileUpload.baseDirectory);
            try {
                //initialize the decoder
                decoder = new HttpPostRequestDecoder(factory, request);
            } catch (ErrorDataDecoderException | IncompatibleDataDecoderException e) {
                logger.error("exception while initialising the decoder", e);
                responseContent.append(e.getMessage());
                writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
                requestProcessed = true;
                return;
            }
        } else {
            logger.warn("received a get request");
            responseContent.append("only post requests are allowed");
            writeResponse(ctx.channel(), HttpResponseStatus.BAD_REQUEST);
            requestProcessed = true;
            return;
        }
    }
    // check if the decoder was constructed before
    if (decoder != null) {
        if (msg instanceof HttpContent) {
            // New chunk is received
            HttpContent chunk = (HttpContent) msg;
            try {
                decoder.offer(chunk);
            } catch (ErrorDataDecoderException e) {
                logger.error("data decoding exception", e);
                responseContent.append(e.getMessage());
                writeResponse(ctx.channel(), HttpResponseStatus.INTERNAL_SERVER_ERROR);
                requestProcessed = true;
                return;
            }
            if (chunk instanceof LastHttpContent) {
                writeResponse(ctx.channel(), readFileUploadData());
                reset();
            }
        }
    }
}
Also used : HttpRequest(io.netty.handler.codec.http.HttpRequest) IncompatibleDataDecoderException(io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.IncompatibleDataDecoderException) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) URI(java.net.URI) HttpPostRequestDecoder(io.netty.handler.codec.http.multipart.HttpPostRequestDecoder) QueryStringDecoder(io.netty.handler.codec.http.QueryStringDecoder) UploadEntity(org.apache.cloudstack.storage.template.UploadEntity) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) List(java.util.List) ErrorDataDecoderException(io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.ErrorDataDecoderException) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) HttpContent(io.netty.handler.codec.http.HttpContent)

Example 2 with UploadEntity

use of org.apache.cloudstack.storage.template.UploadEntity in project cloudstack by apache.

the class NfsSecondaryStorageResource method execute.

private UploadStatusAnswer execute(UploadStatusCommand cmd) {
    String entityUuid = cmd.getEntityUuid();
    if (uploadEntityStateMap.containsKey(entityUuid)) {
        UploadEntity uploadEntity = uploadEntityStateMap.get(entityUuid);
        if (uploadEntity.getUploadState() == UploadEntity.Status.ERROR) {
            uploadEntityStateMap.remove(entityUuid);
            return new UploadStatusAnswer(cmd, UploadStatus.ERROR, uploadEntity.getErrorMessage());
        } else if (uploadEntity.getUploadState() == UploadEntity.Status.COMPLETED) {
            UploadStatusAnswer answer = new UploadStatusAnswer(cmd, UploadStatus.COMPLETED);
            answer.setVirtualSize(uploadEntity.getVirtualSize());
            answer.setInstallPath(uploadEntity.getTmpltPath());
            answer.setPhysicalSize(uploadEntity.getPhysicalSize());
            answer.setDownloadPercent(100);
            uploadEntityStateMap.remove(entityUuid);
            return answer;
        } else if (uploadEntity.getUploadState() == UploadEntity.Status.IN_PROGRESS) {
            UploadStatusAnswer answer = new UploadStatusAnswer(cmd, UploadStatus.IN_PROGRESS);
            long downloadedSize = FileUtils.sizeOfDirectory(new File(uploadEntity.getInstallPathPrefix()));
            int downloadPercent = (int) (100 * downloadedSize / uploadEntity.getContentLength());
            answer.setDownloadPercent(Math.min(downloadPercent, 100));
            return answer;
        }
    }
    return new UploadStatusAnswer(cmd, UploadStatus.UNKNOWN);
}
Also used : UploadEntity(org.apache.cloudstack.storage.template.UploadEntity) UploadStatusAnswer(org.apache.cloudstack.storage.command.UploadStatusAnswer) File(java.io.File) S3Utils.putFile(com.cloud.utils.storage.S3.S3Utils.putFile)

Example 3 with UploadEntity

use of org.apache.cloudstack.storage.template.UploadEntity in project cloudstack by apache.

the class NfsSecondaryStorageResource method postUpload.

public String postUpload(String uuid, String filename) {
    UploadEntity uploadEntity = uploadEntityStateMap.get(uuid);
    int installTimeoutPerGig = 180 * 60 * 1000;
    String resourcePath = uploadEntity.getInstallPathPrefix();
    // template download
    String finalResourcePath = uploadEntity.getTmpltPath();
    UploadEntity.ResourceType resourceType = uploadEntity.getResourceType();
    String fileSavedTempLocation = uploadEntity.getInstallPathPrefix() + "/" + filename;
    String uploadedFileExtension = FilenameUtils.getExtension(filename);
    String userSelectedFormat = uploadEntity.getFormat().toString();
    if (uploadedFileExtension.equals("zip") || uploadedFileExtension.equals("bz2") || uploadedFileExtension.equals("gz")) {
        userSelectedFormat += "." + uploadedFileExtension;
    }
    String formatError = ImageStoreUtil.checkTemplateFormat(fileSavedTempLocation, userSelectedFormat);
    if (StringUtils.isNotBlank(formatError)) {
        String errorString = "File type mismatch between uploaded file and selected format. Selected file format: " + userSelectedFormat + ". Received: " + formatError;
        s_logger.error(errorString);
        return errorString;
    }
    int imgSizeGigs = getSizeInGB(_storage.getSize(fileSavedTempLocation));
    int maxSize = uploadEntity.getMaxSizeInGB();
    if (imgSizeGigs > maxSize) {
        String errorMessage = "Maximum file upload size exceeded. Physical file size: " + imgSizeGigs + "GB. Maximum allowed size: " + maxSize + "GB.";
        s_logger.error(errorMessage);
        return errorMessage;
    }
    // add one just in case
    imgSizeGigs++;
    long timeout = (long) imgSizeGigs * installTimeoutPerGig;
    Script scr = new Script(getScriptLocation(resourceType), timeout, s_logger);
    scr.add("-s", Integer.toString(imgSizeGigs));
    scr.add("-S", Long.toString(UploadEntity.s_maxTemplateSize));
    if (uploadEntity.getDescription() != null && uploadEntity.getDescription().length() > 1) {
        scr.add("-d", uploadEntity.getDescription());
    }
    if (uploadEntity.isHvm()) {
        scr.add("-h");
    }
    String checkSum = uploadEntity.getChksum();
    if (StringUtils.isNotBlank(checkSum)) {
        scr.add("-c", checkSum);
    }
    // add options common to ISO and template
    String extension = uploadEntity.getFormat().getFileExtension();
    String templateName = "";
    if (extension.equals("iso")) {
        templateName = uploadEntity.getUuid().trim().replace(" ", "_");
    } else {
        try {
            templateName = UUID.nameUUIDFromBytes((uploadEntity.getFilename() + System.currentTimeMillis()).getBytes("UTF-8")).toString();
        } catch (UnsupportedEncodingException e) {
            templateName = uploadEntity.getUuid().trim().replace(" ", "_");
        }
    }
    // run script to mv the temporary template file to the final template
    // file
    String templateFilename = templateName + "." + extension;
    uploadEntity.setTemplatePath(finalResourcePath + "/" + templateFilename);
    scr.add("-n", templateFilename);
    scr.add("-t", resourcePath);
    // this is the temporary
    scr.add("-f", fileSavedTempLocation);
    // template file downloaded
    if (uploadEntity.getChksum() != null && uploadEntity.getChksum().length() > 1) {
        scr.add("-c", uploadEntity.getChksum());
    }
    // cleanup
    scr.add("-u");
    String result;
    result = scr.execute();
    if (result != null) {
        return result;
    }
    // Set permissions for the downloaded template
    File downloadedTemplate = new File(resourcePath + "/" + templateFilename);
    _storage.setWorldReadableAndWriteable(downloadedTemplate);
    // Set permissions for template/volume.properties
    String propertiesFile = resourcePath;
    if (resourceType == UploadEntity.ResourceType.TEMPLATE) {
        propertiesFile += "/template.properties";
    } else {
        propertiesFile += "/volume.properties";
    }
    File templateProperties = new File(propertiesFile);
    _storage.setWorldReadableAndWriteable(templateProperties);
    TemplateLocation loc = new TemplateLocation(_storage, resourcePath);
    try {
        loc.create(uploadEntity.getEntityId(), true, uploadEntity.getFilename());
    } catch (IOException e) {
        s_logger.warn("Something is wrong with template location " + resourcePath, e);
        loc.purge();
        return "Unable to upload due to " + e.getMessage();
    }
    Map<String, Processor> processors = _dlMgr.getProcessors();
    for (Processor processor : processors.values()) {
        FormatInfo info = null;
        try {
            info = processor.process(resourcePath, null, templateName);
        } catch (InternalErrorException e) {
            s_logger.error("Template process exception ", e);
            return e.toString();
        }
        if (info != null) {
            loc.addFormat(info);
            uploadEntity.setVirtualSize(info.virtualSize);
            uploadEntity.setPhysicalSize(info.size);
            break;
        }
    }
    if (!loc.save()) {
        s_logger.warn("Cleaning up because we're unable to save the formats");
        loc.purge();
    }
    uploadEntity.setStatus(UploadEntity.Status.COMPLETED);
    uploadEntityStateMap.put(uploadEntity.getUuid(), uploadEntity);
    return null;
}
Also used : Script(com.cloud.utils.script.Script) OVAProcessor(com.cloud.storage.template.OVAProcessor) VhdProcessor(com.cloud.storage.template.VhdProcessor) QCOW2Processor(com.cloud.storage.template.QCOW2Processor) TARProcessor(com.cloud.storage.template.TARProcessor) Processor(com.cloud.storage.template.Processor) VmdkProcessor(com.cloud.storage.template.VmdkProcessor) RawImageProcessor(com.cloud.storage.template.RawImageProcessor) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) InternalErrorException(com.cloud.exception.InternalErrorException) UploadEntity(org.apache.cloudstack.storage.template.UploadEntity) TemplateLocation(com.cloud.storage.template.TemplateLocation) FormatInfo(com.cloud.storage.template.Processor.FormatInfo) File(java.io.File) S3Utils.putFile(com.cloud.utils.storage.S3.S3Utils.putFile)

Example 4 with UploadEntity

use of org.apache.cloudstack.storage.template.UploadEntity in project cloudstack by apache.

the class NfsSecondaryStorageResource method createUploadEntity.

public UploadEntity createUploadEntity(String uuid, String metadata, long contentLength) {
    TemplateOrVolumePostUploadCommand cmd = getTemplateOrVolumePostUploadCmd(metadata);
    UploadEntity uploadEntity = null;
    if (cmd == null) {
        String errorMessage = "unable decode and deserialize metadata.";
        updateStateMapWithError(uuid, errorMessage);
        throw new InvalidParameterValueException(errorMessage);
    } else {
        uuid = cmd.getEntityUUID();
        if (isOneTimePostUrlUsed(cmd)) {
            uploadEntity = uploadEntityStateMap.get(uuid);
            StringBuilder errorMessage = new StringBuilder("The one time post url is already used");
            if (uploadEntity != null) {
                errorMessage.append(" and the upload is in ").append(uploadEntity.getUploadState()).append(" state.");
            }
            throw new InvalidParameterValueException(errorMessage.toString());
        }
        int maxSizeInGB = Integer.parseInt(cmd.getMaxUploadSize());
        int contentLengthInGB = getSizeInGB(contentLength);
        if (contentLengthInGB > maxSizeInGB) {
            String errorMessage = "Maximum file upload size exceeded. Content Length received: " + contentLengthInGB + "GB. Maximum allowed size: " + maxSizeInGB + "GB.";
            updateStateMapWithError(uuid, errorMessage);
            throw new InvalidParameterValueException(errorMessage);
        }
        checkSecondaryStorageResourceLimit(cmd, contentLengthInGB);
        try {
            String absolutePath = cmd.getAbsolutePath();
            uploadEntity = new UploadEntity(uuid, cmd.getEntityId(), UploadEntity.Status.IN_PROGRESS, cmd.getName(), absolutePath);
            uploadEntity.setMetaDataPopulated(true);
            uploadEntity.setResourceType(UploadEntity.ResourceType.valueOf(cmd.getType()));
            uploadEntity.setFormat(Storage.ImageFormat.valueOf(cmd.getImageFormat()));
            //relative path with out ssvm mount info.
            uploadEntity.setTemplatePath(absolutePath);
            String dataStoreUrl = cmd.getDataTo();
            String installPathPrefix = this.getRootDir(dataStoreUrl, cmd.getNfsVersion()) + File.separator + absolutePath;
            uploadEntity.setInstallPathPrefix(installPathPrefix);
            uploadEntity.setHvm(cmd.getRequiresHvm());
            uploadEntity.setChksum(cmd.getChecksum());
            uploadEntity.setMaxSizeInGB(maxSizeInGB);
            uploadEntity.setDescription(cmd.getDescription());
            uploadEntity.setContentLength(contentLength);
            // create a install dir
            if (!_storage.exists(installPathPrefix)) {
                _storage.mkdir(installPathPrefix);
            }
            uploadEntityStateMap.put(uuid, uploadEntity);
        } catch (Exception e) {
            //upload entity will be null incase an exception occurs and the handler will not proceed.
            s_logger.error("exception occurred while creating upload entity ", e);
            updateStateMapWithError(uuid, e.getMessage());
        }
    }
    return uploadEntity;
}
Also used : UploadEntity(org.apache.cloudstack.storage.template.UploadEntity) TemplateOrVolumePostUploadCommand(org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InternalErrorException(com.cloud.exception.InternalErrorException) ConfigurationException(javax.naming.ConfigurationException)

Example 5 with UploadEntity

use of org.apache.cloudstack.storage.template.UploadEntity in project cloudstack by apache.

the class NfsSecondaryStorageResource method updateStateMapWithError.

public void updateStateMapWithError(String uuid, String errorMessage) {
    UploadEntity uploadEntity = null;
    if (uploadEntityStateMap.get(uuid) != null) {
        uploadEntity = uploadEntityStateMap.get(uuid);
    } else {
        uploadEntity = new UploadEntity();
    }
    uploadEntity.setStatus(UploadEntity.Status.ERROR);
    uploadEntity.setErrorMessage(errorMessage);
    uploadEntityStateMap.put(uuid, uploadEntity);
}
Also used : UploadEntity(org.apache.cloudstack.storage.template.UploadEntity)

Aggregations

UploadEntity (org.apache.cloudstack.storage.template.UploadEntity)5 InternalErrorException (com.cloud.exception.InternalErrorException)2 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)2 S3Utils.putFile (com.cloud.utils.storage.S3.S3Utils.putFile)2 File (java.io.File)2 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 OVAProcessor (com.cloud.storage.template.OVAProcessor)1 Processor (com.cloud.storage.template.Processor)1 FormatInfo (com.cloud.storage.template.Processor.FormatInfo)1 QCOW2Processor (com.cloud.storage.template.QCOW2Processor)1 RawImageProcessor (com.cloud.storage.template.RawImageProcessor)1 TARProcessor (com.cloud.storage.template.TARProcessor)1 TemplateLocation (com.cloud.storage.template.TemplateLocation)1 VhdProcessor (com.cloud.storage.template.VhdProcessor)1 VmdkProcessor (com.cloud.storage.template.VmdkProcessor)1 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)1 Script (com.cloud.utils.script.Script)1 HttpContent (io.netty.handler.codec.http.HttpContent)1 HttpRequest (io.netty.handler.codec.http.HttpRequest)1