Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions api/src/main/java/com/cloud/agent/api/to/FilesystemInfoTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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.
*/
package com.cloud.agent.api.to;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

public class FilesystemInfoTO {
private final String name;
private final String filesystem;
private final long size;
private final long volumeId;

public FilesystemInfoTO(String name, String filesystem, long size, long volumeId) {
this.name = name;
this.filesystem = filesystem;
this.size = size;
this.volumeId = volumeId;
}

public String getName() {
return name;
}

public String getFilesystem() {
return filesystem;
}

public long getSize() {
return size;
}

public long getVolumeId() {
return volumeId;
}

@Override
public String toString() {
return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
}
}
1 change: 1 addition & 0 deletions api/src/main/java/com/cloud/event/EventTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ public class EventTypes {
public static final String EVENT_VM_BACKUP_EDIT = "BACKUP.OFFERING.EDIT";
public static final String EVENT_VM_CREATE_FROM_BACKUP = "VM.CREATE.FROM.BACKUP";
public static final String EVENT_SCREENSHOT_DOWNLOAD = "BACKUP.VALIDATION.SCREENSHOT.DOWNLOAD";
public static final String EVENT_BACKUP_FILE_DOWNLOAD = "BACKUP.FILE.DOWNLOAD";

// external network device events
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
Expand Down
4 changes: 3 additions & 1 deletion api/src/main/java/com/cloud/storage/Storage.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public static enum ImageFormat {
TAR(false, false, false, "tar"),
ZIP(false, false, false, "zip"),
DIR(false, false, false, "dir"),
PNG(false, false, false, "png");
PNG(false, false, false, "png"),
GZIP(false, false, false, "gz"),
TARGZ(false, false, false, "tar.gz");

private final boolean supportThinProvisioning;
private final boolean supportSparse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ public enum ApiArgValidator {
* Validates if the parameter is a valid RFC Compliance domain name.
*/
RFCComplianceDomainName,

/**
* Validates that the parameter does not match the following regex '[$|&*`\@!%'"^;<>!()]'
* Some special characters are allowed, such as '/'. If you need to disallow all special characters, a new validator should be created.
* */
LimitedSpecialCharacters,
}
4 changes: 4 additions & 0 deletions api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,10 @@ public class ApiConstants {
public static final String SCHEDULED = "scheduled";
public static final String SCHEDULED_DATE = "scheduleddate";
public static final String BACKUP_PROVIDER = "backupprovider";
public static final String IS_FILESYSTEM = "isfilesystem";
public static final String IS_SYMLINK = "issymlink";
public static final String BROWSABLE = "browsable";
public static final String CANONICAL_PATH = "canonicalpath";

/**
* This enum specifies IO Drivers, each option controls specific policies on I/O.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// 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.
package org.apache.cloudstack.api.command.user.backup;

import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiArgValidator;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.ExtractResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.backup.Backup;
import org.apache.cloudstack.backup.BackupManager;

import javax.inject.Inject;

@APICommand(name = "downloadBackupFile",
description = "Download a file from a backup",
responseObject = ExtractResponse.class, since = "4.24.0.0")
public class DownloadBackupFileCmd extends BaseAsyncCmd {

@Inject
private BackupManager backupManager;

/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////

@ACL
@Parameter(name = ApiConstants.BACKUP_ID, type = BaseCmd.CommandType.UUID, entityType = BackupResponse.class, required = true,
description = "ID of the backup to download the file.")
private Long backupId;

@ACL
@Parameter(name = ApiConstants.VOLUME_ID, type = BaseCmd.CommandType.UUID, entityType = VolumeResponse.class, required = true,
description = "ID of the volume. If not informed, we will return every filesystem of every volume.")
private Long volumeId;

@Parameter(name = ApiConstants.FILESYSTEM, type = BaseCmd.CommandType.STRING, required = true,
description = "Filesystem to list the files in.", validations = {ApiArgValidator.LimitedSpecialCharacters})
private String filesystem;

@Parameter(name = ApiConstants.PATH, type = BaseCmd.CommandType.STRING, required = true,
description = "Path to the file to be downloaded in the backed-up volume.", validations = {ApiArgValidator.LimitedSpecialCharacters})
private String path;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////

public Long getBackupId() {
return backupId;
}

public Long getVolumeId() {
return volumeId;
}

public String getFilesystem() {
return filesystem.trim();
}

public String getPath() {
return path.trim();
}

/////////////////////////////////////////////////////
/////////////// API Implementation //////////////////
/////////////////////////////////////////////////////

@Override
public String getEventType() {
return EventTypes.EVENT_BACKUP_FILE_DOWNLOAD;
}

@Override
public String getEventDescription() {
Backup backup = _entityMgr.findById(Backup.class, getBackupId());
if (backup == null) {
throw new InvalidParameterValueException(String.format("Unable to find backup with ID [%s].", getBackupId()));
}
return "Downloading a file from backup " + backup.getUuid();
}

@Override
public long getEntityOwnerId() {
Backup backup = _entityMgr.findById(Backup.class, getBackupId());
if (backup != null) {
return backup.getAccountId();
}

return Account.ACCOUNT_ID_SYSTEM;
}

@Override
public void execute() {
ExtractResponse response = backupManager.downloadBackupFile(getBackupId(), getVolumeId(), getFilesystem(), getPath());

response.setResponseName(getCommandName());
response.setObjectName(getCommandName());
this.setResponseObject(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// 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.
package org.apache.cloudstack.api.command.user.backup;

import com.cloud.user.Account;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiArgValidator;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.backup.Backup;
import org.apache.cloudstack.backup.BackupManager;
import org.apache.cloudstack.storage.browser.DataStoreObjectResponse;

import javax.inject.Inject;
import java.util.List;

@APICommand(name = "listBackupFiles",
description = "List a backup inner files",
responseObject = DataStoreObjectResponse.class, since = "4.24.0.0")
public class ListBackupFilesCmd extends BaseListCmd {

@Inject
private BackupManager backupManager;

/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////

@ACL
@Parameter(name = ApiConstants.BACKUP_ID, type = CommandType.UUID, entityType = BackupResponse.class, required = true,
description = "ID of the backup to list the files.")
private Long backupId;

@ACL
@Parameter(name = ApiConstants.VOLUME_ID, type = CommandType.UUID, entityType = VolumeResponse.class, required = true,
description = "ID of the volume.")
private Long volumeId;

@Parameter(name = ApiConstants.FILESYSTEM, type = CommandType.STRING, required = true,
description = "Filesystem to list the files in.", validations = {ApiArgValidator.LimitedSpecialCharacters})
private String filesystem;

@Parameter(name = ApiConstants.PATH, type = CommandType.STRING, required = true,
description = "Path to list files in the backed-up volume.", validations = {ApiArgValidator.LimitedSpecialCharacters})
private String path;

@Parameter(name = ApiConstants.IS_SYMLINK, type = CommandType.BOOLEAN,
description = "Path to list files in the backed-up volume.")
private Boolean isSymlink;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////

public Long getBackupId() {
return backupId;
}

public Long getVolumeId() {
return volumeId;
}

public String getFilesystem() {
return filesystem.trim();
}

public String getPath() {
return path.trim();
}

public Boolean getSymlink() {
return isSymlink;
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

@Override
public long getEntityOwnerId() {
Backup backup = _entityMgr.findById(Backup.class, getBackupId());
if (backup != null) {
return backup.getAccountId();
}

return Account.ACCOUNT_ID_SYSTEM;
}

@Override
public void execute() {
List<DataStoreObjectResponse> responseList = backupManager.listBackupFiles(getBackupId(), getVolumeId(), getFilesystem(), getPath(), getSymlink());

ListResponse<DataStoreObjectResponse> response = new ListResponse<>();
response.setResponses(responseList);
response.setResponseName(getCommandName());
response.setObjectName(getCommandName());
this.setResponseObject(response);
}
}
Loading
Loading