2013-03-22 00:47:23 +00:00
|
|
|
package docker
|
2013-03-21 19:18:47 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2013-03-22 03:06:20 +00:00
|
|
|
"fmt"
|
2013-03-21 19:18:47 +00:00
|
|
|
"io/ioutil"
|
2013-03-22 02:00:43 +00:00
|
|
|
"os"
|
2013-03-21 19:18:47 +00:00
|
|
|
"path/filepath"
|
2013-03-22 03:06:20 +00:00
|
|
|
"strings"
|
2013-03-21 19:18:47 +00:00
|
|
|
)
|
|
|
|
|
2013-03-22 00:35:49 +00:00
|
|
|
type TagStore struct {
|
2013-03-21 19:18:47 +00:00
|
|
|
path string
|
|
|
|
graph *Graph
|
2013-03-22 00:35:49 +00:00
|
|
|
Repositories map[string]Repository
|
2013-03-21 19:18:47 +00:00
|
|
|
}
|
|
|
|
|
2013-03-22 00:35:49 +00:00
|
|
|
type Repository map[string]string
|
2013-03-21 19:18:47 +00:00
|
|
|
|
2013-03-22 00:35:49 +00:00
|
|
|
func NewTagStore(path string, graph *Graph) (*TagStore, error) {
|
2013-03-21 19:18:47 +00:00
|
|
|
abspath, err := filepath.Abs(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2013-03-22 00:35:49 +00:00
|
|
|
store := &TagStore{
|
2013-03-21 19:18:47 +00:00
|
|
|
path: abspath,
|
|
|
|
graph: graph,
|
2013-03-22 00:35:49 +00:00
|
|
|
Repositories: make(map[string]Repository),
|
2013-03-21 19:18:47 +00:00
|
|
|
}
|
2013-03-22 02:00:43 +00:00
|
|
|
// Load the json file if it exists, otherwise create it.
|
|
|
|
if err := store.Reload(); os.IsNotExist(err) {
|
|
|
|
if err := store.Save(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
} else if err != nil {
|
2013-03-21 19:18:47 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return store, nil
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:35:49 +00:00
|
|
|
func (store *TagStore) Save() error {
|
2013-03-21 19:18:47 +00:00
|
|
|
// Store the json ball
|
|
|
|
jsonData, err := json.Marshal(store)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := ioutil.WriteFile(store.path, jsonData, 0600); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:35:49 +00:00
|
|
|
func (store *TagStore) Reload() error {
|
2013-03-21 19:18:47 +00:00
|
|
|
jsonData, err := ioutil.ReadFile(store.path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := json.Unmarshal(jsonData, store); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:35:49 +00:00
|
|
|
func (store *TagStore) Set(repoName, tag, revision string) error {
|
2013-03-22 03:06:20 +00:00
|
|
|
if strings.Contains(repoName, ":") {
|
|
|
|
return fmt.Errorf("Illegal repository name: %s", repoName)
|
|
|
|
}
|
|
|
|
if strings.Contains(repoName, ":") {
|
|
|
|
return fmt.Errorf("Illegal tag name: %s", tag)
|
|
|
|
}
|
2013-03-21 19:18:47 +00:00
|
|
|
if err := store.Reload(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2013-03-22 00:35:49 +00:00
|
|
|
var repo Repository
|
2013-03-21 19:18:47 +00:00
|
|
|
if r, exists := store.Repositories[repoName]; exists {
|
|
|
|
repo = r
|
|
|
|
} else {
|
2013-03-22 00:35:49 +00:00
|
|
|
repo = make(map[string]string)
|
2013-03-21 19:18:47 +00:00
|
|
|
store.Repositories[repoName] = repo
|
|
|
|
}
|
2013-03-22 00:35:49 +00:00
|
|
|
repo[tag] = revision
|
2013-03-21 19:18:47 +00:00
|
|
|
return store.Save()
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:35:49 +00:00
|
|
|
func (store *TagStore) Get(repoName string) (Repository, error) {
|
2013-03-21 19:18:47 +00:00
|
|
|
if err := store.Reload(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if r, exists := store.Repositories[repoName]; exists {
|
|
|
|
return r, nil
|
|
|
|
}
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:35:49 +00:00
|
|
|
func (store *TagStore) GetImage(repoName, tag string) (*Image, error) {
|
2013-03-21 19:18:47 +00:00
|
|
|
repo, err := store.Get(repoName)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
} else if repo == nil {
|
|
|
|
return nil, nil
|
|
|
|
}
|
2013-03-22 00:35:49 +00:00
|
|
|
if revision, exists := repo[tag]; exists {
|
2013-03-21 19:18:47 +00:00
|
|
|
return store.graph.Get(revision)
|
|
|
|
}
|
|
|
|
return nil, nil
|
|
|
|
}
|