Skip to content

Commit

Permalink
Allow label and labels when creating volumes
Browse files Browse the repository at this point in the history
JSON payload may have either key. Labels will override any values set
via Label.

Fixes containers#12102

Signed-off-by: Jhon Honce <[email protected]>
  • Loading branch information
jwhonce committed Oct 28, 2021
1 parent f7ca045 commit 98506c9
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 5 deletions.
17 changes: 14 additions & 3 deletions pkg/api/handlers/libpod/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
}{
// override any golang type defaults
}
input := entities.VolumeCreateOptions{}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError,
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}

input := entities.VolumeCreateOptions{}
// decode params from body
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
Expand All @@ -47,9 +48,19 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
if len(input.Driver) > 0 {
volumeOptions = append(volumeOptions, libpod.WithVolumeDriver(input.Driver))
}
if len(input.Label) > 0 {
volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(input.Label))

// Label provided for compatibility.
labels := make(map[string]string, len(input.Label)+len(input.Labels))
for k, v := range input.Label {
labels[k] = v
}
for k, v := range input.Labels {
labels[k] = v
}
if len(labels) > 0 {
volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(labels))
}

if len(input.Options) > 0 {
parsedOptions, err := parse.VolumeOptions(input.Options)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion pkg/domain/entities/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ type VolumeCreateOptions struct {
Name string `schema:"name"`
// Volume driver to use
Driver string `schema:"driver"`
// User-defined key/value metadata.
// User-defined key/value metadata. Provided for compatibility
Label map[string]string `schema:"label"`
// User-defined key/value metadata. Preferred field, will override Label
Labels map[string]string `schema:"labels"`
// Mapping of driver options and values.
Options map[string]string `schema:"opts"`
}
Expand Down
67 changes: 66 additions & 1 deletion test/apiv2/python/rest_api/test_v2_0_0_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


class VolumeTestCase(APITestCase):
def test_volume(self):
def test_volume_crud(self):
name = f"Volume_{random.getrandbits(160):x}"

ls = requests.get(self.podman_url + "/v1.40/volumes")
Expand Down Expand Up @@ -70,6 +70,71 @@ def test_volume(self):
self.assertIn(name, payload["VolumesDeleted"])
self.assertGreater(payload["SpaceReclaimed"], 0)

def test_volume_label(self):
name = f"Volume_{random.getrandbits(160):x}"
expected = {
"Production": "False",
"Database": "Foxbase",
}

create = requests.post(
self.podman_url + "/v4.0.0/libpod/volumes/create",
json={"name": name, "label": expected},
)
self.assertEqual(create.status_code, 201, create.text)

inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
self.assertEqual(inspect.status_code, 200, inspect.text)

volume = inspect.json()
self.assertIn("Labels", volume)
self.assertNotIn("Label", volume)
self.assertDictEqual(expected, volume["Labels"])

def test_volume_labels(self):
name = f"Volume_{random.getrandbits(160):x}"
expected = {
"Production": "False",
"Database": "Foxbase",
}

create = requests.post(
self.podman_url + "/v4.0.0/libpod/volumes/create",
json={"name": name, "labels": expected},
)
self.assertEqual(create.status_code, 201, create.text)

inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
self.assertEqual(inspect.status_code, 200, inspect.text)

volume = inspect.json()
self.assertIn("Labels", volume)
self.assertDictEqual(expected, volume["Labels"])

def test_volume_label_override(self):
name = f"Volume_{random.getrandbits(160):x}"
create = requests.post(
self.podman_url + "/v4.0.0/libpod/volumes/create",
json={
"Name": name,
"Label": {
"Database": "dbase",
},
"Labels": {
"Database": "sqlserver",
},
},
)
self.assertEqual(create.status_code, 201, create.text)

inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
self.assertEqual(inspect.status_code, 200, inspect.text)

volume = inspect.json()
self.assertIn("Labels", volume)
self.assertNotIn("Label", volume)
self.assertDictEqual({"Database": "sqlserver"}, volume["Labels"])


if __name__ == "__main__":
unittest.main()

0 comments on commit 98506c9

Please sign in to comment.