// TODO(vmarmol): Deprecate over time as old Dockers are phased out. func ReadConfig(dockerRoot, dockerRun, containerID string) (*configs.Config, error) { // Try using the new config if it is available. configPath := configPath(dockerRun, containerID) if utils.FileExists(configPath) { out, err := ioutil.ReadFile(configPath) if err != nil { return nil, err } var state libcontainer.State err = json.Unmarshal(out, &state) if err != nil { glog.Errorf("Unmarshal failure for: \n\n%v\n", string(out)) return nil, err } return &state.Config, nil } // Fallback to reading the old config which is comprised of the state and config files. oldConfigPath := oldConfigPath(dockerRoot, containerID) out, err := ioutil.ReadFile(oldConfigPath) if err != nil { glog.Errorf("Unmarshal failure for: \n\n%v\n", string(out)) return nil, err } // Try reading the preAPIConfig. var config preAPIConfig err = json.Unmarshal(out, &config) if err != nil { // Try to parse the old pre-API config. The main difference is that namespaces used to be a map, now it is a slice of structs. // The JSON marshaler will use the non-nested field before the nested one. type oldLibcontainerConfig struct { preAPIConfig OldNamespaces map[string]bool `json:"namespaces,omitempty"` } var oldConfig oldLibcontainerConfig err2 := json.Unmarshal(out, &oldConfig) if err2 != nil { // Use original error. return nil, err } // Translate the old pre-API config into the new config. config = oldConfig.preAPIConfig for ns := range oldConfig.OldNamespaces { config.Namespaces = append(config.Namespaces, configs.Namespace{ Type: configs.NamespaceType(ns), }) } } // Read the old state file as well. state, err := readState(dockerRoot, containerID) if err != nil { return nil, err } // Convert preAPIConfig + old state file to Config. // This only converts some of the fields, the ones we use. // You may need to add fields if the one you're interested in is not available. var result configs.Config result.Cgroups = new(configs.Cgroup) result.Rootfs = config.RootFs result.Hostname = config.Hostname result.Namespaces = config.Namespaces result.Capabilities = config.Capabilities for _, net := range config.Networks { n := &configs.Network{ Name: state.NetworkState.VethChild, Bridge: net.Bridge, MacAddress: net.MacAddress, Address: net.Address, Gateway: net.Gateway, IPv6Address: net.IPv6Address, IPv6Gateway: net.IPv6Gateway, HostInterfaceName: state.NetworkState.VethHost, } result.Networks = append(result.Networks, n) } result.Routes = config.Routes if config.Cgroups != nil { result.Cgroups = config.Cgroups } return &result, nil }