Skip to content

Commit dc8e17c

Browse files
authored
update readme example
1 parent 0cd4f4a commit dc8e17c

1 file changed

Lines changed: 105 additions & 72 deletions

File tree

README.md

Lines changed: 105 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -70,78 +70,6 @@ Below is a table of all of the possible URI parameter substitutions and associat
7070
| `<reference>` | Tag or digest | `WithReference` (`Request`) |
7171
| `<session_id>` | Session ID for upload | `WithSessionID` (`Request`) |
7272

73-
## Example
74-
75-
The following is an example of a resumable blob upload and subsequent manifest upload:
76-
77-
```go
78-
package main
79-
80-
import (
81-
"github.com/bloodorangeio/reggie"
82-
godigest "github.com/opencontainers/go-digest"
83-
84-
)
85-
86-
func main() {
87-
client := reggie.NewClient("http://localhost:5000",
88-
WithDefaultName("my/repo"),
89-
WithDebug(true))
90-
91-
// get the session URL
92-
req := client.NewRequest(reggie.POST, "/v2/<name>/blobs/uploads")
93-
resp, err := client.Do(req)
94-
if err != nil {
95-
// handle error
96-
}
97-
98-
blob := []byte("{}\n")
99-
blobChunk1 := blob[:1]
100-
blobChunk1Range := fmt.Sprintf("0-%d", len(blobChunk1)-1)
101-
blobChunk2 := blob[1:]
102-
blobChunk2Range := fmt.Sprintf("0-%d", len(blobChunk2)-1)
103-
blobDigest := godigest.FromBytes(blob).String()
104-
105-
// upload the first chunk
106-
req = client.NewRequest(reggie.PATCH, resp.GetRelativeLocation())
107-
req.SetHeader("Content-Type", "application/octet-stream")
108-
req.SetHeader("Content-Length", fmt.Sprintf("%d", len(blobChunk1)))
109-
req.SetHeader("Content-Range", blobChunk1Range)
110-
req.SetBody(blobChunk1)
111-
resp, err = client.Do(req)
112-
if err != nil {
113-
//handle error
114-
}
115-
116-
// upload the final chunk and close the session
117-
req = client.NewRequest(reggie.PUT, resp.GetRelativeLocation())
118-
req.SetHeader("Content-Length", fmt.Sprintf("%d", len(blobChunk2)))
119-
req.SetHeader("Content-Range", blobChunk2Range)
120-
req.SetHeader("Content-Type", "application/octet-stream")
121-
req.SetQueryParam("digest", blobDigest)
122-
req.SetBody(blobChunk2)
123-
resp, err = client.Do(req)
124-
if err != nil {
125-
//handle error
126-
}
127-
128-
//upload the manifest
129-
manifest = []byte(fmt.Sprintf(
130-
"{ \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\", \"config\": { \"digest\": \"%s\", "+
131-
"\"mediaType\": \"application/vnd.oci.image.config.v1+json\","+" \"size\": %d }, \"layers\": [], "+
132-
"\"schemaVersion\": 2 }",
133-
blobDigest, len(blob)))
134-
req = client.NewRequest(reggie.PUT, "/v2/<name>/manifests/<reference>", reggie.WithReference("test"))
135-
req.SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json")
136-
req.SetBody(manifest)
137-
resp, err = client.Do(req)
138-
if err != nil {
139-
// handle error
140-
}
141-
}
142-
143-
```
144-
14573
## Other Features
14674

14775
### Error Parsing
@@ -184,3 +112,108 @@ Requests made by Reggie will use a custom value by default for the `User-Agent`
184112
```
185113
User-Agent: reggie/0.1.1 (https://github.com/bloodorangeio/reggie)
186114
```
115+
116+
## Example
117+
118+
The following is an example of a resumable blob upload and subsequent manifest upload:
119+
120+
```go
121+
package main
122+
123+
import (
124+
"fmt"
125+
126+
"github.com/bloodorangeio/reggie"
127+
godigest "github.com/opencontainers/go-digest"
128+
)
129+
130+
func main() {
131+
// construct client pointing to your registry
132+
client, err := reggie.NewClient("http://localhost:5000",
133+
reggie.WithDefaultName("my/repo"),
134+
reggie.WithDebug(true))
135+
if err != nil {
136+
panic(err)
137+
}
138+
139+
// get the session URL
140+
req := client.NewRequest(reggie.POST, "/v2/<name>/blobs/uploads/")
141+
resp, err := client.Do(req)
142+
if err != nil {
143+
panic(err)
144+
}
145+
146+
// a blob for an empty manifest config, separated into 2 chunks ("{" and "}")
147+
blob := []byte("{}")
148+
blobChunk1 := blob[:1]
149+
blobChunk1Range := fmt.Sprintf("0-%d", len(blobChunk1)-1)
150+
blobChunk2 := blob[1:]
151+
blobChunk2Range := fmt.Sprintf("%d-%d", len(blobChunk1), len(blob)-1)
152+
blobDigest := godigest.FromBytes(blob).String()
153+
154+
// upload the first chunk
155+
req = client.NewRequest(reggie.PATCH, resp.GetRelativeLocation())
156+
req.SetHeader("Content-Type", "application/octet-stream").
157+
SetHeader("Content-Length", fmt.Sprintf("%d", len(blobChunk1))).
158+
SetHeader("Content-Range", blobChunk1Range).
159+
SetBody(blobChunk1)
160+
resp, err = client.Do(req)
161+
if err != nil {
162+
panic(err)
163+
}
164+
165+
// upload the final chunk and close the session
166+
req = client.NewRequest(reggie.PUT, resp.GetRelativeLocation())
167+
req.SetHeader("Content-Length", fmt.Sprintf("%d", len(blobChunk2))).
168+
SetHeader("Content-Range", blobChunk2Range).
169+
SetHeader("Content-Type", "application/octet-stream").
170+
SetQueryParam("digest", blobDigest).
171+
SetBody(blobChunk2)
172+
resp, err = client.Do(req)
173+
if err != nil {
174+
panic(err)
175+
}
176+
177+
// validate the uploaded blob content
178+
req = client.NewRequest(reggie.GET, "/v2/<name>/blobs/<digest>",
179+
reggie.WithDigest(blobDigest))
180+
resp, err = client.Do(req)
181+
if err != nil {
182+
panic(err)
183+
}
184+
fmt.Printf("Blob content:\n%s\n", resp.String())
185+
186+
// upload the manifest (referencing the uploaded blob)
187+
ref := "test"
188+
manifest := []byte(fmt.Sprintf(
189+
`{
190+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
191+
"config": {
192+
"digest": "%s",
193+
"mediaType": "application/vnd.oci.image.config.v1+json",
194+
"size": %d
195+
},
196+
"layers": [],
197+
"schemaVersion": 2
198+
}`, blobDigest, len(blob)))
199+
req = client.NewRequest(reggie.PUT, "/v2/<name>/manifests/<reference>",
200+
reggie.WithReference(ref))
201+
req.SetHeader("Content-Type", "application/vnd.oci.image.manifest.v1+json").
202+
SetBody(manifest)
203+
resp, err = client.Do(req)
204+
if err != nil {
205+
panic(err)
206+
}
207+
208+
// validate the uploaded manifest content
209+
req = client.NewRequest(reggie.GET, "/v2/<name>/manifests/<reference>",
210+
reggie.WithReference(ref))
211+
req.SetHeader("Accept", "application/vnd.oci.image.manifest.v1+json")
212+
resp, err = client.Do(req)
213+
if err != nil {
214+
panic(err)
215+
}
216+
fmt.Printf("Manifest content:\n%s\n", resp.String())
217+
}
218+
219+
```

0 commit comments

Comments
 (0)