-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DAOS-14698 crtl: Create container with attributes #15300
base: master
Are you sure you want to change the base?
Changes from 10 commits
5fcd159
315f440
865f2e5
4dd51bd
819b856
b922f70
825512d
2e9afbd
2d26f4d
055c3a0
a3d0a02
7f26733
5e72550
5dca3b4
98bd3c2
a390e8a
9af9320
d2ee639
90186bc
0561a5b
263168f
436436f
f30184d
b1aaa8f
af54e76
d230c87
e3f510d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -251,6 +251,7 @@ type containerCreateCmd struct { | |
Mode ConsModeFlag `long:"mode" short:"M" description:"DFS consistency mode"` | ||
ACLFile string `long:"acl-file" short:"A" description:"input file containing ACL"` | ||
Group ui.ACLPrincipalFlag `long:"group" short:"g" description:"group who will own the container (group@[domain])"` | ||
Attrs ui.SetPropertiesFlag `long:"attrs" short:"a" description:"user-defined attributes (key:val[,key:val...])"` | ||
Args struct { | ||
Label string `positional-arg-name:"label"` | ||
} `positional-args:"yes"` | ||
|
@@ -305,11 +306,7 @@ func (cmd *containerCreateCmd) Execute(_ []string) (err error) { | |
defer disconnectPool() | ||
|
||
var contID string | ||
if cmd.Path != "" { | ||
contID, err = cmd.contCreateUNS() | ||
} else { | ||
contID, err = cmd.contCreate() | ||
} | ||
contID, err = cmd.contCreate() | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -397,77 +394,51 @@ func (cmd *containerCreateCmd) contCreate() (string, error) { | |
if err != nil { | ||
return "", err | ||
} | ||
contID := cmd.contUUID.String() | ||
cContID := C.CString(contID) | ||
defer freeString(cContID) | ||
|
||
var contID string | ||
if cmd.contUUID == uuid.Nil { | ||
contID = cmd.contLabel | ||
} else { | ||
contID = cmd.contUUID.String() | ||
} | ||
|
||
cmd.Infof("Successfully created container %s", contID) | ||
return contID, nil | ||
} | ||
|
||
func (cmd *containerCreateCmd) contCreateUNS() (string, error) { | ||
var dattr C.struct_duns_attr_t | ||
|
||
props, cleanupProps, err := cmd.getCreateProps() | ||
if err != nil { | ||
return "", err | ||
cleanupContainer := func() { | ||
rc := C.daos_cont_destroy(cmd.cPoolHandle, cContID, goBool2int(true), nil) | ||
if err := daosError(rc); err != nil { | ||
cmd.Noticef("Failed to clean-up container %v", err) | ||
} | ||
} | ||
defer cleanupProps() | ||
dattr.da_props = props | ||
|
||
if !cmd.Type.Set { | ||
return "", errors.New("container type is required for UNS") | ||
} | ||
dattr.da_type = cmd.Type.Type | ||
if len(cmd.Attrs.ParsedProps) != 0 { | ||
kjacque marked this conversation as resolved.
Show resolved
Hide resolved
|
||
attrs := make(attrList, 0, len(cmd.Attrs.ParsedProps)) | ||
for key, val := range cmd.Attrs.ParsedProps { | ||
attrs = append(attrs, &attribute{ | ||
Name: key, | ||
Value: []byte(val), | ||
}) | ||
} | ||
|
||
if cmd.poolUUID != uuid.Nil { | ||
poolUUIDStr := C.CString(cmd.poolUUID.String()) | ||
defer freeString(poolUUIDStr) | ||
C.uuid_parse(poolUUIDStr, &dattr.da_puuid[0]) | ||
} | ||
if cmd.contUUID != uuid.Nil { | ||
contUUIDStr := C.CString(cmd.contUUID.String()) | ||
defer freeString(contUUIDStr) | ||
C.uuid_parse(contUUIDStr, &dattr.da_cuuid[0]) | ||
} | ||
if err := cmd.openContainer(C.DAOS_COO_RW); err != nil { | ||
cleanupContainer() | ||
return "", errors.Wrapf(err, "failed to open new container %s", contID) | ||
} | ||
defer cmd.closeContainer() | ||
|
||
if cmd.ChunkSize.Set { | ||
dattr.da_chunk_size = cmd.ChunkSize.Size | ||
} | ||
if cmd.ObjectClass.Set { | ||
dattr.da_oclass_id = cmd.ObjectClass.Class | ||
} | ||
if cmd.DirObjectClass.Set { | ||
dattr.da_dir_oclass_id = cmd.DirObjectClass.Class | ||
} | ||
if cmd.FileObjectClass.Set { | ||
dattr.da_file_oclass_id = cmd.FileObjectClass.Class | ||
} | ||
if cmd.CHints != "" { | ||
hint := C.CString(cmd.CHints) | ||
defer freeString(hint) | ||
C.strncpy(&dattr.da_hints[0], hint, C.DAOS_CONT_HINT_MAX_LEN-1) | ||
if err := setDaosAttributes(cmd.cContHandle, contAttr, attrs); err != nil { | ||
cleanupContainer() | ||
return "", errors.Wrapf(err, "failed to set user attributes on new container %s", contID) | ||
} | ||
} | ||
|
||
cPath := C.CString(cmd.Path) | ||
defer freeString(cPath) | ||
if cmd.Path != "" { | ||
cPath := C.CString(cmd.Path) | ||
defer freeString(cPath) | ||
|
||
dunsErrno := C.duns_create_path(cmd.cPoolHandle, cPath, &dattr) | ||
rc := C.daos_errno2der(dunsErrno) | ||
if err := daosError(rc); err != nil { | ||
return "", errors.Wrapf(err, "duns_create_path() failed") | ||
dunsErrno := C.duns_link_cont(cmd.cPoolHandle, cContID, cPath) | ||
rc := C.daos_errno2der(dunsErrno) | ||
if err := daosError(rc); err != nil { | ||
cleanupContainer() | ||
return "", errors.Wrapf(err, "duns_link_cont() failed") | ||
} | ||
} | ||
|
||
contID := C.GoString(&dattr.da_cont[0]) | ||
cmd.contUUID, err = uuid.Parse(contID) | ||
if err != nil { | ||
cmd.contLabel = contID | ||
} | ||
cmd.Infof("Successfully created container %s type %s", contID, cmd.Type.String()) | ||
cmd.Infof("Successfully created container %s", contID) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curious - Was the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just keep the message of the main merged function.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Fixed with commit 7f26733 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what is expected here, but this now prints
|
||
return contID, nil | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
""" | ||
(C) Copyright 2020-2024 Intel Corporation. | ||
|
||
SPDX-License-Identifier: BSD-2-Clause-Patent | ||
""" | ||
|
||
import os | ||
import re | ||
|
||
from apricot import TestWithServers | ||
from dfuse_utils import get_dfuse, start_dfuse | ||
|
||
|
||
class DfuseContainerAttrs(TestWithServers): | ||
"""Check if the dfuse attributes of a container are properly managed. | ||
|
||
:avocado: recursive | ||
""" | ||
|
||
def setUp(self): | ||
"""Set up each test case.""" | ||
# obtain separate logs | ||
self.update_log_file_names() | ||
|
||
# Start the servers and agents | ||
super().setUp() | ||
|
||
def _check_attrs(self, dfuse, container_name): | ||
phender marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""Check if the DFuse attributes of a container are loaded | ||
|
||
Check in the log file of the dfuse instance if it contains the DFuse attributes of a given | ||
container. It also checks the value of the attributes found. | ||
|
||
Args: | ||
dfuse (Dfuse): DFuse instance to check | ||
container_name (str): Name of the container | ||
""" | ||
log_file = os.linesep.join(dfuse.get_log_file_data().output[0].stdout) | ||
attrs = self.params.get("attrs", f"/run/{container_name}/*") | ||
for name, value in [attr.split(':') for attr in attrs.split(",")]: | ||
match = re.findall( | ||
fr"^.+\ssetting\s+'{name}'\s+is\s+(\d+)\s+seconds$", | ||
log_file, | ||
re.MULTILINE) | ||
self.assertEqual( | ||
len(match), | ||
1, | ||
f"Unexpected number setting(s) of attribute {name}: want=1, got={len(match)}") | ||
self.assertEqual( | ||
value, | ||
match[0], | ||
f"Unexpected value for attribute {name}: want={value}, got={match[0]}") | ||
|
||
def test_dfuse_container_attrs(self): | ||
"""Jira ID: DAOS-14698. | ||
|
||
Test Description: | ||
Create a container with DFuse attributes | ||
Mount a DFuse mount point | ||
Check the output of the DFuse log | ||
ashleypittman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
:avocado: tags=all,pr | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checking - do these tests really need to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have no opinion on this, and do not fill legitimate to have one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need your input :) Roughly, it's something like
IMO these new tests belong in Related, I think we should add the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Fixed with commit 7f26733 |
||
:avocado: tags=vm | ||
:avocado: tags=dfuse,container | ||
:avocado: tags=DfuseContainerAttrs,test_dfuse_container_attrs | ||
""" | ||
self.log.info("Creating DAOS pool") | ||
pool = self.get_pool() | ||
|
||
self.log_step("Creating DAOS container with Dfuse attributes") | ||
container = self.get_container(pool, namespace="/run/container_01/*") | ||
|
||
self.log_step("Mounting DFuse mount point") | ||
dfuse = get_dfuse(self, self.hostlist_clients) | ||
dfuse.env["D_LOG_FLUSH"] = "INFO" | ||
start_dfuse(self, dfuse, pool, container) | ||
|
||
self.log_step("Checking DFuse log file") | ||
self._check_attrs(dfuse, "container_01") | ||
|
||
self.log_step("Test passed") | ||
|
||
def test_dfuse_subcontainer_attrs(self): | ||
"""Jira ID: DAOS-14698. | ||
|
||
Test Description: | ||
Create a container | ||
Mount a DFuse mount point | ||
Create a sub-container with DFuse attributes | ||
Check the output of the DFuse log | ||
:avocado: tags=all,pr | ||
:avocado: tags=vm | ||
:avocado: tags=dfuse,container | ||
:avocado: tags=DfuseContainerAttrs,test_dfuse_subcontainer_attrs | ||
""" | ||
self.log.info("Creating DAOS pool") | ||
pool = self.get_pool() | ||
|
||
self.log_step("Creating DAOS container") | ||
container = self.get_container(pool, namespace="/run/container_02/*") | ||
|
||
self.log_step("Mounting DFuse mount point") | ||
dfuse = get_dfuse(self, self.hostlist_clients) | ||
dfuse.env["D_LOG_FLUSH"] = "INFO" | ||
start_dfuse(self, dfuse, pool, container) | ||
|
||
self.log_step("Creating DAOS subcontainer with DFuse attributes") | ||
sub_dir = os.path.join(dfuse.mount_dir.value, "foo") | ||
container = self.get_container(pool, namespace="/run/container_03/*", path=sub_dir) | ||
|
||
self.log_step("Checking DFuse log file") | ||
self._check_attrs(dfuse, "container_03") | ||
|
||
self.log_step("Test passed") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
hosts: | ||
test_servers: 1 | ||
test_clients: 1 | ||
|
||
timeout: 200 | ||
|
||
server_config: | ||
name: daos_server | ||
engines_per_host: 1 | ||
engines: | ||
0: | ||
log_file: daos_server0.log | ||
storage: auto | ||
|
||
pool: | ||
scm_size: 80% | ||
|
||
container_01: | ||
type: POSIX | ||
attrs: dfuse-attr-time:666,dfuse-dentry-time:999 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice. This will be useful for some other tests as well. Once this lands I'll write up a ticket to identify those (for the test team to handle) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually it would be an idea to have a way of exporting these from dfuse somehow. For now having a python function in ftest would be useful and then if we have a more direct way of querying it then we can plug it in later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant it's nice to specify There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I see what you mean. My mistake. |
||
control_method: daos | ||
|
||
container_02: | ||
type: POSIX | ||
control_method: daos | ||
|
||
container_03: | ||
type: POSIX | ||
attrs: dfuse-attr-time:42,dfuse-dentry-time:404 | ||
control_method: daos |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is moved, not new code but it would be good to use the correct macros here. The
S
here stands for system, that is it's a errno.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed with commit 0561a5b