1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package random
16
17 import (
18 "archive/tar"
19 "bytes"
20 "crypto"
21 "encoding/hex"
22 "fmt"
23 "io"
24 "math/rand"
25
26 v1 "github.com/google/go-containerregistry/pkg/v1"
27 "github.com/google/go-containerregistry/pkg/v1/empty"
28 "github.com/google/go-containerregistry/pkg/v1/mutate"
29 "github.com/google/go-containerregistry/pkg/v1/partial"
30 "github.com/google/go-containerregistry/pkg/v1/types"
31 )
32
33
34 type uncompressedLayer struct {
35 diffID v1.Hash
36 mediaType types.MediaType
37 content []byte
38 }
39
40
41 func (ul *uncompressedLayer) DiffID() (v1.Hash, error) {
42 return ul.diffID, nil
43 }
44
45
46 func (ul *uncompressedLayer) Uncompressed() (io.ReadCloser, error) {
47 return io.NopCloser(bytes.NewBuffer(ul.content)), nil
48 }
49
50
51 func (ul *uncompressedLayer) MediaType() (types.MediaType, error) {
52 return ul.mediaType, nil
53 }
54
55 var _ partial.UncompressedLayer = (*uncompressedLayer)(nil)
56
57
58 func Image(byteSize, layers int64, options ...Option) (v1.Image, error) {
59 adds := make([]mutate.Addendum, 0, 5)
60 for i := int64(0); i < layers; i++ {
61 layer, err := Layer(byteSize, types.DockerLayer, options...)
62 if err != nil {
63 return nil, err
64 }
65 adds = append(adds, mutate.Addendum{
66 Layer: layer,
67 History: v1.History{
68 Author: "random.Image",
69 Comment: fmt.Sprintf("this is a random history %d of %d", i, layers),
70 CreatedBy: "random",
71 },
72 })
73 }
74
75 return mutate.Append(empty.Image, adds...)
76 }
77
78
79 func Layer(byteSize int64, mt types.MediaType, options ...Option) (v1.Layer, error) {
80 o := getOptions(options)
81 rng := rand.New(o.source)
82
83 fileName := fmt.Sprintf("random_file_%d.txt", rng.Int())
84
85
86 var b bytes.Buffer
87 hasher := crypto.SHA256.New()
88 mw := io.MultiWriter(&b, hasher)
89
90
91 tw := tar.NewWriter(mw)
92 if err := tw.WriteHeader(&tar.Header{
93 Name: fileName,
94 Size: byteSize,
95 Typeflag: tar.TypeReg,
96 }); err != nil {
97 return nil, err
98 }
99 if _, err := io.CopyN(tw, rng, byteSize); err != nil {
100 return nil, err
101 }
102 if err := tw.Close(); err != nil {
103 return nil, err
104 }
105
106 h := v1.Hash{
107 Algorithm: "sha256",
108 Hex: hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))),
109 }
110
111 return partial.UncompressedToLayer(&uncompressedLayer{
112 diffID: h,
113 mediaType: mt,
114 content: b.Bytes(),
115 })
116 }
117
View as plain text