Skip to content

Commit

Permalink
restful: provide functionality to remove or add labels of a file
Browse files Browse the repository at this point in the history
Motivation

Allow any dCache service to modify and remove labels
attributes.

Modification:

Add set-label and rm-label fucntions to restful Api.
Additional Message subclasses has been added  to allow dCache services to
request that PnfsManager updates (remove) a file's label.
Implement support for these  new message in PnfsManager.

The following curl command will be used to modify file's label.

Result:

 user- or admin can mdify  remove file labels.

Target: master
Require-book: yes
Require-notes: yes
Patch: https://rb.dcache.org/r/13079/
Acked-by: Lea Morschel, Tigran Mkrtchyan
Commited
  • Loading branch information
mksahakyan committed Sep 3, 2021
1 parent 84b45e6 commit 2fc1f8d
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,8 @@ public FileAttributes setFileAttributes(Subject subject, PnfsId pnfsId,
break;
case XATTR:
break;
case LABELS:
break;
default:
throw new UnsupportedOperationException("Attribute " + attribute + " not supported yet.");
}
Expand Down Expand Up @@ -1794,4 +1796,42 @@ public void removeExtendedAttribute(Subject subject, FsPath path, String name)
+ Exceptions.messageOrClassName(e), e);
}
}

/**@param subject The user making the request.
* Remove a label from a file.
*
* @param path The file from which the label is deleted.
* @param label The name of the label to remove.
* @throws FileNotFoundCacheException if the path does not exist.
* @throws PermissionDeniedCacheException if the user is not allowed to
* remove the label.
* @throws CacheException a generic failure in removing the labe.
**/
public void removeLabel(Subject subject, FsPath path, String label) throws CacheException {
try {
ExtendedInode target = pathToInode(subject, path.toString());

if (!Subjects.isRoot(subject)) {

FileAttributes attributes = getFileAttributesForPermissionHandler(target);

if (target.isDirectory()) {

throw new NotFileCacheException("Directory object cannot have a label.");

} else {
if (_permissionHandler.canWriteFile(subject, attributes) != ACCESS_ALLOWED) {
throw new PermissionDeniedCacheException("Access denied");
}
} }
_fs.removeLabel(target, label);

} catch (FileNotFoundChimeraFsException e) {
throw new FileNotFoundCacheException("No such file " + path);
} catch (ChimeraFsException e) {
throw new CacheException("Failed to remove the label: "
+ Exceptions.messageOrClassName(e), e);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,15 @@ public Response cmrResources(@ApiParam(value="Path of file or directory to be mo
+ "corresponding JSON Object's "
+ "value is this attribute's value."
+ "\n"
+ "If action is 'set-label' then "
+ "a label is added to the"
+ "given file object."
+ "'label' item value is a String."
+ "\n"
+ "If action is 'rm-label' then the corresponding"
+ "label of a file is removed."
+ "The 'label' value is either a string."
+ "\n"
+ "If action is 'chgrp' then the "
+ "command requests the change of "
+ "group-owner of the target file "
Expand Down Expand Up @@ -356,6 +365,18 @@ public Response cmrResources(@ApiParam(value="Path of file or directory to be mo
+ " \"attr-2\"\n"
+ " ]\n"
+ "}"),

@ExampleProperty(mediaType = "SET-LABEL",
value = "{\n"
+ " \"action\" : \"set-label\",\n"
+ " \"label\" : : \"label\",\n"
+ "}"),

@ExampleProperty(mediaType = "RM-LABEL",
value = "{\n"
+ " \"action\" : \"rm-label\",\n"
+ " \"label\" : \"label\",\n"
+ "}"),
@ExampleProperty(mediaType = "CHGRP",
value = "{\n"
+ " \"action\" : \"chgrp\",\n"
Expand Down Expand Up @@ -421,6 +442,14 @@ public Response cmrResources(@ApiParam(value="Path of file or directory to be mo
}
pnfsHandler.writeExtendedAttribute(path, attributes, xattrSetMode);
break;
case "set-label":
String label = reqPayload.getString("label");
pnfsHandler.setFileAttributes(path,FileAttributes.ofLabel(label)) ;
break;
case "rm-label":
String labelsArgument = reqPayload.getString("label");
pnfsHandler.removeLabel(path, labelsArgument);
break;
case "chgrp":
int gid = reqPayload.getInt("gid");
pnfsHandler.setFileAttributes(path, FileAttributes.ofGid(gid));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* dCache - http://www.dcache.org/
*
* Copyright (C) 2021 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package diskCacheV111.vehicles;

import java.util.HashSet;
import java.util.Set;

import diskCacheV111.util.PnfsId;

/**
* Remove a label of a file object.
*/
public class PnfsRemoveLabelsMessage extends PnfsMessage
{
private static final long serialVersionUID = -3390360138874265448L;

private final Set<String> _labels = new HashSet<>();

public PnfsRemoveLabelsMessage(PnfsId id)
{
super(id);
}

public PnfsRemoveLabelsMessage(String path)
{
setPnfsPath(path);
}

public void addLabel(String label)
{
_labels.add(label);
}

public Set<String> getLabels()
{
return _labels;
}

public void clearLabel()
{
_labels.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,10 @@ public static FileAttributes ofLocations(Collection<String> pools)
return of().locations(pools).build();
}

public static FileAttributes ofLabel(String label) {
return of().label(label).build();
}

public static FileAttributes ofHsm(String hsm)
{
return of().hsm(hsm).build();
Expand Down Expand Up @@ -1087,5 +1091,13 @@ public Builder xattrs(Map<String, String> xattrs) {
getXattrs().putAll(xattrs);
return this;
}

public Builder label(String label) {
if (!isDefined(LABELS)) {
setLabels(new HashSet());
}
getLabels().add(label);
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import diskCacheV111.util.PnfsId;
import diskCacheV111.util.RetentionPolicy;


import org.dcache.namespace.CreateOption;
import org.dcache.namespace.FileAttribute;
import org.dcache.namespace.FileType;
Expand Down Expand Up @@ -235,4 +236,10 @@ public void updateFsStat() throws CacheException {
delegate().updateFsStat();
}

@Override
public void removeLabel(Subject subject, FsPath path, String name) throws CacheException
{
delegate().removeLabel(subject, path, name);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -424,4 +424,17 @@ void removeExtendedAttribute(Subject subject, FsPath path, String name)
*/
void updateFsStat() throws CacheException;

/**
* Remove a label from a file.
* @param subject The user making the request.
* @param path The file from which the label is deleted.
* @param label The labelto remove.
* @throws FileNotFoundCacheException if the path does not exist.
* @throws PermissionDeniedCacheException if the user is not allowed to
* remove the label.
* @throws CacheException a generic failure in removing the attribute.
*/
void removeLabel(Subject subject, FsPath path, String label) throws CacheException;


}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import diskCacheV111.vehicles.PnfsReadExtendedAttributesMessage;
import diskCacheV111.vehicles.PnfsRemoveExtendedAttributesMessage;
import diskCacheV111.vehicles.PnfsRenameMessage;
import diskCacheV111.vehicles.PnfsRemoveLabelsMessage;
import diskCacheV111.vehicles.PnfsWriteExtendedAttributesMessage;
import diskCacheV111.vehicles.PoolFileFlushedMessage;
import diskCacheV111.vehicles.StorageInfo;
Expand Down Expand Up @@ -268,6 +269,7 @@ private void populateRequestMap()
_gauges.addGauge(PnfsReadExtendedAttributesMessage.class);
_gauges.addGauge(PnfsWriteExtendedAttributesMessage.class);
_gauges.addGauge(PnfsRemoveExtendedAttributesMessage.class);
_gauges.addGauge(PnfsRemoveLabelsMessage.class);
}

public PnfsManagerV3()
Expand Down Expand Up @@ -2644,6 +2646,8 @@ private boolean processMessageTransactionally(CellMessage message, PnfsMessage p
writeExtendedAttributes((PnfsWriteExtendedAttributesMessage) pnfsMessage);
} else if (pnfsMessage instanceof PnfsRemoveExtendedAttributesMessage) {
removeExtendedAttributes((PnfsRemoveExtendedAttributesMessage) pnfsMessage);
} else if (pnfsMessage instanceof PnfsRemoveLabelsMessage) {
removeLabel((PnfsRemoveLabelsMessage) pnfsMessage);
} else {
LOGGER.warn("Unexpected message class [{}] from source [{}]",
pnfsMessage.getClass(), message.getSourcePath());
Expand Down Expand Up @@ -3039,6 +3043,33 @@ private void removeExtendedAttributes(PnfsRemoveExtendedAttributesMessage messag
}
}

private void removeLabel(PnfsRemoveLabelsMessage message)
{
try {
if (message.getFsPath() == null) {
throw new CacheException("PNFS-ID based label removal is not supported");
}

populatePnfsId(message);

checkMask(message);
checkRestriction(message, UPDATE_METADATA);
FsPath path = message.getFsPath();

for (String name : message.getLabels()) {
_nameSpaceProvider.removeLabel(message.getSubject(),
path, name);

}
message.clearLabel();
message.setSucceeded();

} catch (CacheException e) {
message.clearLabel();
message.setFailed(e.getRc(), e);
}

}
private PnfsId populatePnfsId(PnfsMessage message)
throws CacheException
{
Expand Down
21 changes: 21 additions & 0 deletions modules/dcache/src/main/java/diskCacheV111/util/PnfsHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import diskCacheV111.vehicles.PnfsMessage;
import diskCacheV111.vehicles.PnfsReadExtendedAttributesMessage;
import diskCacheV111.vehicles.PnfsRemoveExtendedAttributesMessage;
import diskCacheV111.vehicles.PnfsRemoveLabelsMessage;
import diskCacheV111.vehicles.PnfsRenameMessage;
import diskCacheV111.vehicles.PnfsWriteExtendedAttributesMessage;
import diskCacheV111.vehicles.PnfsWriteExtendedAttributesMessage.Mode;
Expand Down Expand Up @@ -761,4 +762,24 @@ public void removeExtendedAttribute(FsPath path, Collection<String> names)
names.forEach(message::addName);
request(message);
}

/**
* Remove a label attribute from a file.
* @param path The file from which the label is deleted.
* @param label The name of the label to remove.
* @throws FileNotFoundCacheException if the path does not exist.
* @throws PermissionDeniedCacheException if the user is not allowed to
* remove the label.
* @throws CacheException if the label does not exist or the object is a directory.
* @throws CacheException a generic failure in removing the label.
*/

public void removeLabel(FsPath path, String label) throws CacheException
{

PnfsRemoveLabelsMessage message =
new PnfsRemoveLabelsMessage(path.toString());
message.addLabel(label);
request(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import javax.security.auth.Subject;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

Expand All @@ -26,6 +25,7 @@
import diskCacheV111.vehicles.PnfsListExtendedAttributesMessage;
import diskCacheV111.vehicles.PnfsReadExtendedAttributesMessage;
import diskCacheV111.vehicles.PnfsRemoveExtendedAttributesMessage;
import diskCacheV111.vehicles.PnfsRemoveLabelsMessage;
import diskCacheV111.vehicles.PnfsWriteExtendedAttributesMessage;

import org.dcache.auth.attributes.Restrictions;
Expand Down Expand Up @@ -315,4 +315,23 @@ public void removeExtendedAttribute(Subject subject, FsPath path, String name)
message.setRestriction(Restrictions.none());
_pnfs.request(message);
}


/**
* Remove a label attribute from a file.
* @param subject The user making the request.
* @param path The file from which the label is deleted.
* @param label The name of the label to be remove.
* @throws CacheException a generic failure in removing the label.
*/
public void removeLabel(Subject subject, FsPath path, String label) throws CacheException
{
PnfsRemoveLabelsMessage message =
new PnfsRemoveLabelsMessage(path.toString());
message.addLabel(label);
message.setSubject(subject);
message.setRestriction(Restrictions.none());
_pnfs.request(message);

}
}

0 comments on commit 2fc1f8d

Please sign in to comment.