github.com/ggreg80/ketos@v0.0.0-20171109040536-049616f51ddb/pkg/metadata/metadata.go (about) 1 package metadata 2 3 import ( 4 "encoding/json" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "strings" 9 10 manifestV1 "github.com/docker/distribution/manifest/schema1" 11 "github.com/opencontainers/go-digest" 12 "github.com/pkg/errors" 13 "github.com/setekhid/ketos/pkg/registry" 14 "gopkg.in/yaml.v2" 15 ) 16 17 type Metadatas struct { 18 folders MetaFolders 19 } 20 21 func NewMetadata(path string, image string) (*Metadatas, error) { 22 23 path, err := filepath.Abs(path) 24 if err != nil { 25 return nil, errors.Wrap(err, "calc absolute path of ketos folder") 26 } 27 28 data := &Metadatas{MetaFolders(path)} 29 err = data.init(image) 30 31 return data, err 32 } 33 34 func ConnMetadata(path string) (*Metadatas, error) { 35 36 path, err := filepath.Abs(path) 37 if err != nil { 38 return nil, errors.Wrap(err, "calc absolute path of ketos folder") 39 } 40 41 data := &Metadatas{MetaFolders(path)} 42 inited, err := data.hasInited() 43 if err != nil { 44 return nil, err 45 } 46 if !inited { 47 return nil, errors.New("ketos metadata folder hasn't been initialized") 48 } 49 50 return data, err 51 } 52 53 func (d *Metadatas) init(image string) error { 54 55 inited, err := d.hasInited() 56 if err != nil { 57 return err 58 } 59 if inited { 60 return nil 61 } 62 63 err = d.folders.InitFolders() 64 if err != nil { 65 return err 66 } 67 68 err = d.folders.InitConfig(image) 69 if err != nil { 70 return err 71 } 72 73 return nil 74 } 75 76 func (d *Metadatas) hasInited() (bool, error) { 77 78 _, err := os.Stat(d.folders.Config()) 79 if err != nil && !os.IsNotExist(err) { 80 return false, errors.Wrap(err, "check ketos config file") 81 } 82 83 return err == nil, nil 84 } 85 86 type KetosConfig struct { 87 InitImageName string `yaml:"init_image_name"` 88 89 Repository struct { 90 Name string `yaml:"name"` 91 Registry string `yaml:"registry"` 92 } 93 } 94 95 func (d *Metadatas) GetConfig() (*KetosConfig, error) { 96 97 content, err := ioutil.ReadFile(d.folders.Config()) 98 if err != nil { 99 return nil, errors.Wrap(err, "reading ketos config") 100 } 101 102 config := &KetosConfig{} 103 err = yaml.Unmarshal(content, config) 104 if err != nil { 105 return nil, errors.Wrap(err, "unmarshal ketos config") 106 } 107 108 return config, nil 109 } 110 111 func (d *Metadatas) ConnectRegistry() (*registry.Repository, error) { 112 113 conf, err := d.GetConfig() 114 if err != nil { 115 return nil, err 116 } 117 118 imageName := conf.Repository.Registry + "/" + conf.Repository.Name 119 repo, _, err := registry.DockerImage(imageName).Connect() 120 return repo, err 121 } 122 123 func (d *Metadatas) ListTags() ([]string, error) { 124 125 infos, err := ioutil.ReadDir(d.folders.Manifests()) 126 if err != nil { 127 return nil, errors.Wrap(err, "reading manifest directory") 128 } 129 130 tags := []string{} 131 for _, info := range infos { 132 133 name := info.Name() 134 if strings.HasSuffix(name, ".json") { 135 tag := name[:len(name)-len(".json")] 136 tags = append(tags, tag) 137 } 138 } 139 140 return tags, nil 141 } 142 143 func (d *Metadatas) GetManifest(tag string) (*manifestV1.Manifest, error) { 144 145 content, err := ioutil.ReadFile(d.folders.Manifest(tag)) 146 if err != nil { 147 return nil, errors.Wrap(err, "reading manifest file") 148 } 149 150 manifest := &manifestV1.Manifest{} 151 err = json.Unmarshal(content, manifest) 152 if err != nil { 153 return nil, errors.Wrap(err, "unmarshal manifest file") 154 } 155 156 return manifest, nil 157 } 158 159 func (d *Metadatas) PutManifest( 160 tag string, manifest *manifestV1.Manifest) error { 161 162 content, err := json.Marshal(manifest) 163 if err != nil { 164 return errors.Wrap(err, "marshal manifest json") 165 } 166 167 err = ioutil.WriteFile(d.folders.Manifest(tag), content, os.ModePerm) 168 if err != nil { 169 return errors.Wrap(err, "write down manifest") 170 } 171 172 return nil 173 } 174 175 func (d *Metadatas) LayerPath(digest digest.Digest) string { 176 return d.folders.Layer(digest) 177 } 178 179 func (d *Metadatas) PackFile(digest digest.Digest) string { 180 return d.folders.Pack(digest) 181 } 182 183 func (d *Metadatas) ContainerPath() string { 184 return d.folders.Container() 185 } 186 187 func (d *Metadatas) MetaFolderPath() string { 188 return string(d.folders) 189 } 190 191 var ( 192 metaFolders = map[string]*Metadatas{} 193 ) 194 195 func GetMetadatas(path string) (*Metadatas, error) { 196 197 path, err := SeekKetosFolder(path) 198 if err != nil { 199 return nil, err 200 } 201 202 meta, ok := metaFolders[path] 203 if ok { 204 return meta, nil 205 } 206 207 meta, err = ConnMetadata(path) 208 if err != nil { 209 return nil, err 210 } 211 212 metaFolders[path] = meta 213 214 return meta, nil 215 } 216 217 func CurrentMetadatas() (*Metadatas, error) { 218 219 wd, err := os.Getwd() 220 if err != nil { 221 return nil, errors.Wrap(err, "get working directory") 222 } 223 224 return GetMetadatas(wd) 225 }