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  }