1// Copyright 2013 go-dockerclient authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package docker
6
7import (
8	"encoding/json"
9	"net"
10	"strings"
11
12)
13
14// Version returns version information about the docker server.
15//
16// See https://goo.gl/mU7yje for more details.
17func (c *Client) Version() (*Env, error) {
18	resp, err := c.do("GET", "/version", doOptions{})
19	if err != nil {
20		return nil, err
21	}
22	defer resp.Body.Close()
23	var env Env
24	if err := env.Decode(resp.Body); err != nil {
25		return nil, err
26	}
27	return &env, nil
28}
29
30// DockerInfo contains information about the Docker server
31//
32// See https://goo.gl/bHUoz9 for more details.
33type DockerInfo struct {
34	ID                 string
35	Containers         int
36	ContainersRunning  int
37	ContainersPaused   int
38	ContainersStopped  int
39	Images             int
40	Driver             string
41	DriverStatus       [][2]string
42	SystemStatus       [][2]string
43	Plugins            PluginsInfo
44	MemoryLimit        bool
45	SwapLimit          bool
46	KernelMemory       bool
47	CPUCfsPeriod       bool `json:"CpuCfsPeriod"`
48	CPUCfsQuota        bool `json:"CpuCfsQuota"`
49	CPUShares          bool
50	CPUSet             bool
51	IPv4Forwarding     bool
52	BridgeNfIptables   bool
53	BridgeNfIP6tables  bool `json:"BridgeNfIp6tables"`
54	Debug              bool
55	OomKillDisable     bool
56	ExperimentalBuild  bool
57	NFd                int
58	NGoroutines        int
59	SystemTime         string
60	ExecutionDriver    string
61	LoggingDriver      string
62	CgroupDriver       string
63	NEventsListener    int
64	KernelVersion      string
65	OperatingSystem    string
66	OSType             string
67	Architecture       string
68	IndexServerAddress string
69	RegistryConfig     *ServiceConfig
70	SecurityOptions    []string
71	NCPU               int
72	MemTotal           int64
73	DockerRootDir      string
74	HTTPProxy          string `json:"HttpProxy"`
75	HTTPSProxy         string `json:"HttpsProxy"`
76	NoProxy            string
77	Name               string
78	Labels             []string
79	ServerVersion      string
80	ClusterStore       string
81	ClusterAdvertise   string
82	Isolation          string
83	InitBinary         string
84	DefaultRuntime     string
85	LiveRestoreEnabled bool
86	//Swarm              swarm.Info
87}
88
89// PluginsInfo is a struct with the plugins registered with the docker daemon
90//
91// for more information, see: https://goo.gl/bHUoz9
92type PluginsInfo struct {
93	// List of Volume plugins registered
94	Volume []string
95	// List of Network plugins registered
96	Network []string
97	// List of Authorization plugins registered
98	Authorization []string
99}
100
101// ServiceConfig stores daemon registry services configuration.
102//
103// for more information, see: https://goo.gl/7iFFDz
104type ServiceConfig struct {
105	InsecureRegistryCIDRs []*NetIPNet
106	IndexConfigs          map[string]*IndexInfo
107	Mirrors               []string
108}
109
110// NetIPNet is the net.IPNet type, which can be marshalled and
111// unmarshalled to JSON.
112//
113// for more information, see: https://goo.gl/7iFFDz
114type NetIPNet net.IPNet
115
116// MarshalJSON returns the JSON representation of the IPNet.
117//
118func (ipnet *NetIPNet) MarshalJSON() ([]byte, error) {
119	return json.Marshal((*net.IPNet)(ipnet).String())
120}
121
122// UnmarshalJSON sets the IPNet from a byte array of JSON.
123//
124func (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) {
125	var ipnetStr string
126	if err = json.Unmarshal(b, &ipnetStr); err == nil {
127		var cidr *net.IPNet
128		if _, cidr, err = net.ParseCIDR(ipnetStr); err == nil {
129			*ipnet = NetIPNet(*cidr)
130		}
131	}
132	return
133}
134
135// IndexInfo contains information about a registry.
136//
137// for more information, see: https://goo.gl/7iFFDz
138type IndexInfo struct {
139	Name     string
140	Mirrors  []string
141	Secure   bool
142	Official bool
143}
144
145// Info returns system-wide information about the Docker server.
146//
147// See https://goo.gl/ElTHi2 for more details.
148func (c *Client) Info() (*DockerInfo, error) {
149	resp, err := c.do("GET", "/info", doOptions{})
150	if err != nil {
151		return nil, err
152	}
153	defer resp.Body.Close()
154	var info DockerInfo
155	if err := json.NewDecoder(resp.Body).Decode(&info); err != nil {
156		return nil, err
157	}
158	return &info, nil
159}
160
161// ParseRepositoryTag gets the name of the repository and returns it splitted
162// in two parts: the repository and the tag. It ignores the digest when it is
163// present.
164//
165// Some examples:
166//
167//     localhost.localdomain:5000/samalba/hipache:latest -> localhost.localdomain:5000/samalba/hipache, latest
168//     localhost.localdomain:5000/samalba/hipache -> localhost.localdomain:5000/samalba/hipache, ""
169//     busybox:latest@sha256:4a731fb46adc5cefe3ae374a8b6020fc1b6ad667a279647766e9a3cd89f6fa92 -> busybox, latest
170func ParseRepositoryTag(repoTag string) (repository string, tag string) {
171	parts := strings.SplitN(repoTag, "@", 2)
172	repoTag = parts[0]
173	n := strings.LastIndex(repoTag, ":")
174	if n < 0 {
175		return repoTag, ""
176	}
177	if tag := repoTag[n+1:]; !strings.Contains(tag, "/") {
178		return repoTag[:n], tag
179	}
180	return repoTag, ""
181}
182