Skip to content

Commit 1dbc99c

Browse files
committed
image: Add image-layout directory based CAS and ref engines
These are much nicer than the tar engines (hooray atomic renames :), so switch the manifest tests tests back to using the directory-backed engines. I also switched the man-page examples over to directory-backed layouts, now that they're what oci-image-init generates by default. And I added command-line wrappers for the delete methods, now that we have a backend that implements it. I do with there was a paginated, callback-based directory lister we could use instead of ioutils.ReadDir. On the other hand, by the time directories get big enough for that to matter we may be sharding them anyway. Signed-off-by: W. Trevor King <[email protected]>
1 parent e9fa3ac commit 1dbc99c

25 files changed

+716
-51
lines changed

cmd/oci-cas/delete.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2016 The Linux Foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"fmt"
19+
"os"
20+
21+
"github.com/opencontainers/image-tools/image/cas/layout"
22+
"github.com/spf13/cobra"
23+
"golang.org/x/net/context"
24+
)
25+
26+
type deleteCmd struct {
27+
path string
28+
digest string
29+
}
30+
31+
func newDeleteCmd() *cobra.Command {
32+
state := &deleteCmd{}
33+
34+
return &cobra.Command{
35+
Use: "delete PATH DIGEST",
36+
Short: "Remove a blob from from the store",
37+
Run: state.Run,
38+
}
39+
}
40+
41+
func (state *deleteCmd) Run(cmd *cobra.Command, args []string) {
42+
if len(args) != 2 {
43+
fmt.Fprintln(os.Stderr, "both PATH and DIGEST must be provided")
44+
if err := cmd.Usage(); err != nil {
45+
fmt.Fprintln(os.Stderr, err)
46+
}
47+
os.Exit(1)
48+
}
49+
50+
state.path = args[0]
51+
state.digest = args[1]
52+
53+
err := state.run()
54+
if err != nil {
55+
fmt.Fprintln(os.Stderr, err)
56+
os.Exit(1)
57+
}
58+
59+
os.Exit(0)
60+
}
61+
62+
func (state *deleteCmd) run() (err error) {
63+
ctx := context.Background()
64+
65+
engine, err := layout.NewEngine(ctx, state.path)
66+
if err != nil {
67+
return err
68+
}
69+
defer engine.Close()
70+
71+
return engine.Delete(ctx, state.digest)
72+
}

cmd/oci-cas/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func main() {
2929

3030
cmd.AddCommand(newGetCmd())
3131
cmd.AddCommand(newPutCmd())
32+
cmd.AddCommand(newDeleteCmd())
3233

3334
err := cmd.Execute()
3435
if err != nil {

cmd/oci-cas/oci-cas-delete.1.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
% OCI(1) OCI-IMAGE-TOOL User Manuals
2+
% OCI Community
3+
% SEPTEMBER 2016
4+
# NAME
5+
6+
oci-cas-get \- Remove a blob from the store
7+
8+
# SYNOPSIS
9+
10+
**oci-cas delete** [OPTIONS] PATH DIGEST
11+
12+
# DESCRIPTION
13+
14+
`oci-cas delete` removes the blob referenced by `DIGEST` from the store at `PATH`.
15+
16+
# OPTIONS
17+
18+
**--help**
19+
Print usage statement
20+
21+
# SEE ALSO
22+
23+
**oci-cas**(1), **oci-cas-get**(1), **oci-cas-put**(1)
24+
25+
# HISTORY
26+
27+
September 2016, Originally compiled by W. Trevor King (wking at tremily dot us)

cmd/oci-cas/oci-cas-get.1.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ oci-cas-get \- Retrieve a blob from the store
2020

2121
# SEE ALSO
2222

23-
**oci-cas**(1), **oci-cas-put**(1)
23+
**oci-cas**(1), **oci-cas-put**(1), **oci-cas-delete**(1)
2424

2525
# HISTORY
2626

cmd/oci-cas/oci-cas-put.1.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ oci-cas-put \- Write a blob to the store
2020

2121
# SEE ALSO
2222

23-
**oci-cas**(1), **oci-cas-get**(1)
23+
**oci-cas**(1), **oci-cas-get**(1), **oci-cas-delete**(1)
2424

2525
# HISTORY
2626

cmd/oci-cas/oci-cas.1.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,24 @@ oci-cas \- Content-addressable storage manipulation
2828
Write a blob to the store.
2929
See **oci-cas-put**(1) for full documentation on the **put** command.
3030

31+
**delete**
32+
Remove a blob from the store.
33+
See **oci-cas-delete**(1) for full documentation on the **delete** command.
34+
3135
# EXAMPLES
3236

3337
```
34-
$ oci-image-init image-layout image.tar
35-
$ echo hello | oci-cas put image.tar
38+
$ oci-image-init image-layout image
39+
$ echo hello | oci-cas put image
3640
sha256:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
37-
$ oci-cas get image.tar sha256:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
41+
$ oci-cas get image sha256:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
3842
hello
43+
$ oci-cas delete image sha256:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
3944
```
4045

4146
# SEE ALSO
4247

43-
**oci-image-tools**(7), **oci-cas-get**(1), **oci-cas-put**(1), **oci-image-init**(1)
48+
**oci-image-tools**(7), **oci-cas-get**(1), **oci-cas-put**(1), **oci-cas-delete**(1), **oci-image-init**(1)
4449

4550
# HISTORY
4651

cmd/oci-image-init/image_layout.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,33 @@ import (
2323
"golang.org/x/net/context"
2424
)
2525

26-
type imageLayout struct{}
26+
type imageLayout struct {
27+
backend string
28+
}
2729

2830
func newImageLayoutCmd() *cobra.Command {
29-
state := &imageLayout{}
31+
state := &imageLayout{
32+
backend: "dir",
33+
}
3034

31-
return &cobra.Command{
35+
cmd := &cobra.Command{
3236
Use: "image-layout PATH",
3337
Short: "Initialize an OCI image-layout repository",
3438
Run: state.Run,
3539
}
40+
41+
cmd.Flags().StringVar(
42+
&state.backend, "type", "dir",
43+
"Select the image-backend. Choices: dir, tar. Defaults to dir.",
44+
)
45+
46+
return cmd
3647
}
3748

3849
func (state *imageLayout) Run(cmd *cobra.Command, args []string) {
50+
var err error
3951
if len(args) != 1 {
40-
if err := cmd.Usage(); err != nil {
52+
if err = cmd.Usage(); err != nil {
4153
fmt.Fprintln(os.Stderr, err)
4254
}
4355
os.Exit(1)
@@ -47,7 +59,14 @@ func (state *imageLayout) Run(cmd *cobra.Command, args []string) {
4759

4860
ctx := context.Background()
4961

50-
err := layout.CreateTarFile(ctx, path)
62+
switch state.backend {
63+
case "dir":
64+
err = layout.CreateDir(ctx, path)
65+
case "tar":
66+
err = layout.CreateTarFile(ctx, path)
67+
default:
68+
err = fmt.Errorf("unrecognized type: %q", state.backend)
69+
}
5170
if err != nil {
5271
fmt.Fprintln(os.Stderr, err)
5372
os.Exit(1)

cmd/oci-image-init/oci-image-init-image-layout.1.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ oci-image-init-image-layout \- Initialize an OCI image-layout repository
1818
**--help**
1919
Print usage statement
2020

21+
**--type**
22+
Select the image-layout backend.
23+
Choices: dir, tar.
24+
Defaults to dir.
25+
2126
# SEE ALSO
2227

2328
**oci-image-init**(1), **oci-cas**(1), ***oci-refs**(1)

cmd/oci-refs/delete.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2016 The Linux Foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"fmt"
19+
"os"
20+
21+
"github.com/opencontainers/image-tools/image/refs/layout"
22+
"github.com/spf13/cobra"
23+
"golang.org/x/net/context"
24+
)
25+
26+
type deleteCmd struct {
27+
path string
28+
name string
29+
}
30+
31+
func newDeleteCmd() *cobra.Command {
32+
state := &deleteCmd{}
33+
34+
return &cobra.Command{
35+
Use: "delete PATH NAME",
36+
Short: "Remove a reference from the store",
37+
Run: state.Run,
38+
}
39+
}
40+
41+
func (state *deleteCmd) Run(cmd *cobra.Command, args []string) {
42+
if len(args) != 2 {
43+
fmt.Fprintln(os.Stderr, "both PATH and NAME must be provided")
44+
if err := cmd.Usage(); err != nil {
45+
fmt.Fprintln(os.Stderr, err)
46+
}
47+
os.Exit(1)
48+
}
49+
50+
state.path = args[0]
51+
state.name = args[1]
52+
53+
err := state.run()
54+
if err != nil {
55+
fmt.Fprintln(os.Stderr, err)
56+
os.Exit(1)
57+
}
58+
59+
os.Exit(0)
60+
}
61+
62+
func (state *deleteCmd) run() (err error) {
63+
ctx := context.Background()
64+
65+
engine, err := layout.NewEngine(ctx, state.path)
66+
if err != nil {
67+
return err
68+
}
69+
defer engine.Close()
70+
71+
return engine.Delete(ctx, state.name)
72+
}

cmd/oci-refs/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func main() {
3030
cmd.AddCommand(newPutCmd())
3131
cmd.AddCommand(newGetCmd())
3232
cmd.AddCommand(newListCmd())
33+
cmd.AddCommand(newDeleteCmd())
3334

3435
err := cmd.Execute()
3536
if err != nil {

0 commit comments

Comments
 (0)