Skip to content
Merged
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
7 changes: 6 additions & 1 deletion cmd/nerdctl/system_prune.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"fmt"
"strings"

"github.com/containerd/nerdctl/pkg/api/types"
"github.com/containerd/nerdctl/pkg/clientutil"
"github.com/containerd/nerdctl/pkg/cmd/volume"
buildkitclient "github.com/moby/buildkit/client"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -102,7 +104,10 @@ func systemPruneAction(cmd *cobra.Command, args []string) error {
return err
}
if vFlag {
if err := volumePrune(ctx, cmd, client, globalOptions); err != nil {
if err := volume.Prune(ctx, &types.VolumePruneCommandOptions{
GOptions: globalOptions,
Force: true,
}, cmd.InOrStdin(), cmd.OutOrStdout()); err != nil {
return err
}
}
Expand Down
26 changes: 7 additions & 19 deletions cmd/nerdctl/volume_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@
package main

import (
"fmt"

"github.com/containerd/containerd/identifiers"
"github.com/containerd/nerdctl/pkg/strutil"
"github.com/containerd/nerdctl/pkg/api/types"
"github.com/containerd/nerdctl/pkg/cmd/volume"

"github.com/spf13/cobra"
)
Expand All @@ -43,23 +41,13 @@ func volumeCreateAction(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
name := args[0]
if err := identifiers.Validate(name); err != nil {
return fmt.Errorf("malformed name %s: %w", name, err)
}

volStore, err := getVolumeStore(globalOptions)
if err != nil {
return err
}
labels, err := cmd.Flags().GetStringArray("label")
if err != nil {
return err
}
labels = strutil.DedupeStrSlice(labels)
if _, err := volStore.Create(name, labels); err != nil {
return err
}
fmt.Fprintf(cmd.OutOrStdout(), "%s\n", name)
return nil
return volume.Create(&types.VolumeCreateCommandOptions{
GOptions: globalOptions,
Name: args[0],
Labels: labels,
}, cmd.OutOrStdout())
}
25 changes: 8 additions & 17 deletions cmd/nerdctl/volume_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
package main

import (
"github.com/containerd/nerdctl/pkg/formatter"
"github.com/containerd/nerdctl/pkg/api/types"
"github.com/containerd/nerdctl/pkg/cmd/volume"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -48,26 +49,16 @@ func volumeInspectAction(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}

volStore, err := getVolumeStore(globalOptions)
if err != nil {
return err
}
result := make([]interface{}, len(args))

for i, name := range args {
var vol, err = volStore.Get(name, volumeSize)
if err != nil {
return err
}
result[i] = vol
}
format, err := cmd.Flags().GetString("format")
if err != nil {
return err
}

return formatter.FormatSlice(format, cmd.OutOrStdout(), result)
return volume.Inspect(&types.VolumeInspectCommandOptions{
GOptions: globalOptions,
Format: format,
Size: volumeSize,
Volumes: args,
}, cmd.OutOrStdout())
}

func volumeInspectShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
Expand Down
18 changes: 7 additions & 11 deletions cmd/nerdctl/volume_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,33 +50,29 @@ func volumeLsAction(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}

options := &types.VolumeLsCommandOptions{}
options.Writer = cmd.OutOrStdout()
quiet, err := cmd.Flags().GetBool("quiet")
if err != nil {
return err
}
options.Quiet = quiet
format, err := cmd.Flags().GetString("format")
if err != nil {
return err
}
options.Format = format
size, err := cmd.Flags().GetBool("size")
if err != nil {
return err
}
options.Size = size
filters, err := cmd.Flags().GetStringSlice("filter")
if err != nil {
return err
}
options.Filters = filters
options.Namespace = globalOptions.Namespace
options.DataRoot = globalOptions.DataRoot
options.Address = globalOptions.Address
return volume.Ls(options)
return volume.Ls(&types.VolumeLsCommandOptions{
GOptions: globalOptions,
Quiet: quiet,
Format: format,
Size: size,
Filters: filters,
}, cmd.OutOrStdout())
}

func getVolumes(cmd *cobra.Command, globalOptions *types.GlobalCommandOptions) (map[string]native.Volume, error) {
Expand Down
68 changes: 5 additions & 63 deletions cmd/nerdctl/volume_prune.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@
package main

import (
"context"
"fmt"
"strings"

"github.com/containerd/containerd"
"github.com/containerd/nerdctl/pkg/api/types"
"github.com/containerd/nerdctl/pkg/clientutil"
"github.com/containerd/nerdctl/pkg/cmd/volume"
"github.com/spf13/cobra"
)

Expand All @@ -49,61 +44,8 @@ func volumePruneAction(cmd *cobra.Command, _ []string) error {
if err != nil {
return err
}

if !force {
var confirm string
msg := "This will remove all local volumes not used by at least one container."
msg += "\nAre you sure you want to continue? [y/N] "
fmt.Fprintf(cmd.OutOrStdout(), "WARNING! %s", msg)
fmt.Fscanf(cmd.InOrStdin(), "%s", &confirm)

if strings.ToLower(confirm) != "y" {
return nil
}
}
client, ctx, cancel, err := clientutil.NewClient(cmd.Context(), globalOptions.Namespace, globalOptions.Address)
if err != nil {
return err
}
defer cancel()

return volumePrune(ctx, cmd, client, globalOptions)
}

func volumePrune(ctx context.Context, cmd *cobra.Command, client *containerd.Client, globalOptions *types.GlobalCommandOptions) error {
volStore, err := getVolumeStore(globalOptions)
if err != nil {
return err
}
volumes, err := volStore.List(false)
if err != nil {
return err
}
containers, err := client.Containers(ctx)
if err != nil {
return err
}
usedVolumes, err := usedVolumes(ctx, containers)
if err != nil {
return err
}
var removeNames []string // nolint: prealloc
for _, volume := range volumes {
if _, ok := usedVolumes[volume.Name]; ok {
continue
}
removeNames = append(removeNames, volume.Name)
}
removedNames, err := volStore.Remove(removeNames)
if err != nil {
return err
}
if len(removedNames) > 0 {
fmt.Fprintln(cmd.OutOrStdout(), "Deleted Volumes:")
for _, name := range removedNames {
fmt.Fprintln(cmd.OutOrStdout(), name)
}
fmt.Fprintln(cmd.OutOrStdout(), "")
}
return nil
return volume.Prune(cmd.Context(), &types.VolumePruneCommandOptions{
GOptions: globalOptions,
Force: force,
}, cmd.InOrStdin(), cmd.OutOrStdout())
}
79 changes: 6 additions & 73 deletions cmd/nerdctl/volume_rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,8 @@
package main

import (
"context"
"encoding/json"
"fmt"

"github.com/containerd/containerd"
"github.com/containerd/nerdctl/pkg/clientutil"
"github.com/containerd/nerdctl/pkg/inspecttypes/dockercompat"
"github.com/containerd/nerdctl/pkg/labels"
"github.com/containerd/nerdctl/pkg/mountutil"
"github.com/containerd/nerdctl/pkg/api/types"
"github.com/containerd/nerdctl/pkg/cmd/volume"
"github.com/spf13/cobra"
)

Expand All @@ -50,73 +43,13 @@ func volumeRmAction(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
client, ctx, cancel, err := clientutil.NewClient(cmd.Context(), globalOptions.Namespace, globalOptions.Address)
if err != nil {
return err
}
defer cancel()
containers, err := client.Containers(ctx)
if err != nil {
return err
}
volStore, err := getVolumeStore(globalOptions)
if err != nil {
return err
}
names := args
usedVolumes, err := usedVolumes(ctx, containers)
if err != nil {
return err
}

var volumenames []string // nolint: prealloc
for _, name := range names {
volume, err := volStore.Get(name, false)
if err != nil {
return err
}
if _, ok := usedVolumes[volume.Name]; ok {
return fmt.Errorf("volume %q is in use", name)
}
volumenames = append(volumenames, name)
}
removedNames, err := volStore.Remove(volumenames)
if err != nil {
return err
}
for _, name := range removedNames {
fmt.Fprintln(cmd.OutOrStdout(), name)
}
return err
return volume.Rm(cmd.Context(), &types.VolumeRmCommandOptions{
GOptions: globalOptions,
Volumes: args,
}, cmd.OutOrStdout())
}

func volumeRmShellComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// show volume names
return shellCompleteVolumeNames(cmd)
}

func usedVolumes(ctx context.Context, containers []containerd.Container) (map[string]struct{}, error) {
usedVolumes := make(map[string]struct{})
for _, c := range containers {
l, err := c.Labels(ctx)
if err != nil {
return nil, err
}
mountsJSON, ok := l[labels.Mounts]
if !ok {
continue
}

var mounts []dockercompat.MountPoint
err = json.Unmarshal([]byte(mountsJSON), &mounts)
if err != nil {
return nil, err
}
for _, m := range mounts {
if m.Type == mountutil.Volume {
usedVolumes[m.Name] = struct{}{}
}
}
}
return usedVolumes, nil
}
39 changes: 30 additions & 9 deletions pkg/api/types/volume_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,26 @@

package types

import "io"
type VolumeCreateCommandOptions struct {
GOptions *GlobalCommandOptions
// Name is the volume name
Name string
// Labels are the volume labels
Labels []string
}

type VolumeInspectCommandOptions struct {
GOptions *GlobalCommandOptions
// Format the output using the given go template
Format string
// Display the disk usage of volumes. Can be slow with volumes having loads of directories.
Size bool
// Volumes are the volumes to be inspected
Volumes []string
}

type VolumeLsCommandOptions struct {
// Writer is the output writer
Writer io.Writer
GOptions *GlobalCommandOptions
// Only display volume names
Quiet bool
// Format the output using the given go template
Expand All @@ -29,10 +44,16 @@ type VolumeLsCommandOptions struct {
Size bool
// Filter matches volumes based on given conditions
Filters []string
// containerd namespace
Namespace string
// Root directory of persistent nerdctl state
DataRoot string
// containerd address
Address string
}

type VolumePruneCommandOptions struct {
GOptions *GlobalCommandOptions
// Do not prompt for confirmation
Force bool
}

type VolumeRmCommandOptions struct {
GOptions *GlobalCommandOptions
// Volumes are the volumes to be removed
Volumes []string
}
Loading