func (s *TagStore) recursiveLoad(eng *engine.Engine, address, tmpImageDir string) error { if err := eng.Job("image_get", address).Run(); err != nil { log.Debugf("Loading %s", address) imageJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", address, "json")) if err != nil { log.Debugf("Error reading json", err) return err } layer, err := os.Open(path.Join(tmpImageDir, "repo", address, "layer.tar")) if err != nil { log.Debugf("Error reading embedded tar", err) return err } img, err := image.NewImgJSON(imageJson) if err != nil { log.Debugf("Error unmarshalling json", err) return err } if img.Parent != "" { if !s.graph.Exists(img.Parent) { if err := s.recursiveLoad(eng, img.Parent, tmpImageDir); err != nil { return err } } } if err := s.graph.Register(img, imageJson, layer); err != nil { return err } } log.Debugf("Completed processing %s", address) return nil }
func (r *Repository) restore() error { dir, err := ioutil.ReadDir(r.configPath) if err != nil { return err } for _, v := range dir { id := v.Name() path, err := r.driver.Get(id, "") if err != nil { log.Debugf("Could not find volume for %s: %v", id, err) continue } vol := &Volume{ ID: id, configPath: r.configPath + "/" + id, containers: make(map[string]struct{}), Path: path, } if err := vol.FromDisk(); err != nil { if !os.IsNotExist(err) { log.Debugf("Error restoring volume: %v", err) continue } if err := vol.initialize(); err != nil { log.Debugf("%s", err) continue } } if err := r.add(vol); err != nil { log.Debugf("Error restoring volume: %v", err) } } return nil }
func (devices *DeviceSet) AddDevice(hash, baseHash string) error { baseInfo, err := devices.lookupDevice(baseHash) if err != nil { return err } baseInfo.lock.Lock() defer baseInfo.lock.Unlock() devices.Lock() defer devices.Unlock() if info, _ := devices.lookupDevice(hash); info != nil { return fmt.Errorf("device %s already exists", hash) } deviceId := devices.nextDeviceId if err := createSnapDevice(devices.getPoolDevName(), &deviceId, baseInfo.Name(), baseInfo.DeviceId); err != nil { log.Debugf("Error creating snap device: %s", err) return err } // Ids are 24bit, so wrap around devices.nextDeviceId = (deviceId + 1) & 0xffffff if _, err := devices.registerDevice(deviceId, hash, baseInfo.Size); err != nil { deleteDevice(devices.getPoolDevName(), deviceId) log.Debugf("Error registering device: %s", err) return err } return nil }
func spawnGlobalDaemon() { if globalDaemon != nil { log.Debugf("Global daemon already exists. Skipping.") return } t := std_log.New(os.Stderr, "", 0) eng := NewTestEngine(t) globalEngine = eng globalDaemon = mkDaemonFromEngine(eng, t) // Spawn a Daemon go func() { log.Debugf("Spawning global daemon for integration tests") listenURL := &url.URL{ Scheme: testDaemonProto, Host: testDaemonAddr, } job := eng.Job("serveapi", listenURL.String()) job.SetenvBool("Logging", true) if err := job.Run(); err != nil { log.Fatalf("Unable to spawn the test daemon: %s", err) } }() // Give some time to ListenAndServer to actually start // FIXME: use inmem transports instead of tcp time.Sleep(time.Second) if err := eng.Job("acceptconnections").Run(); err != nil { log.Fatalf("Unable to accept connections for test api: %s", err) } }
func (daemon *Daemon) shutdown() error { group := sync.WaitGroup{} log.Debugf("starting clean shutdown of all containers...") for _, container := range daemon.List() { c := container if c.IsRunning() { log.Debugf("stopping %s", c.ID) group.Add(1) go func() { defer group.Done() if err := c.KillSig(15); err != nil { log.Debugf("kill 15 error for %s - %s", c.ID, err) } if _, err := c.WaitStop(3 * time.Second); err != nil { log.Infof("Container %v failed to exit within %d seconds of SIGTERM - using the force", c.ID, 3) if err := c.Kill(); err != nil { c.WaitStop(-1 * time.Second) } } log.Debugf("container stopped %s", c.ID) }() } } group.Wait() return nil }
// ApplyDiff extracts the changeset from the given diff into the // layer with the specified id and parent, returning the size of the // new layer in bytes. func (gdw *naiveDiffDriver) ApplyDiff(id, parent string, diff archive.ArchiveReader) (bytes int64, err error) { driver := gdw.ProtoDriver // Mount the root filesystem so we can apply the diff/layer. layerFs, err := driver.Get(id, "") if err != nil { return } defer driver.Put(id) start := time.Now().UTC() log.Debugf("Start untar layer") if err = archive.ApplyLayer(layerFs, diff); err != nil { return } log.Debugf("Untar time: %vs", time.Now().UTC().Sub(start).Seconds()) if parent == "" { return utils.TreeSize(layerFs) } parentFs, err := driver.Get(parent, "") if err != nil { err = fmt.Errorf("Driver %s failed to get image parent %s: %s", driver, parent, err) return } defer driver.Put(parent) changes, err := archive.ChangesDirs(layerFs, parentFs) if err != nil { return } return archive.ChangesSize(layerFs, changes), nil }
// waitRemove blocks until either: // a) the device registered at <device_set_prefix>-<hash> is removed, // or b) the 10 second timeout expires. func (devices *DeviceSet) waitRemove(devname string) error { log.Debugf("[deviceset %s] waitRemove(%s)", devices.devicePrefix, devname) defer log.Debugf("[deviceset %s] waitRemove(%s) END", devices.devicePrefix, devname) i := 0 for ; i < 1000; i++ { devinfo, err := getInfo(devname) if err != nil { // If there is an error we assume the device doesn't exist. // The error might actually be something else, but we can't differentiate. return nil } if i%100 == 0 { log.Debugf("Waiting for removal of %s: exists=%d", devname, devinfo.Exists) } if devinfo.Exists == 0 { break } devices.Unlock() time.Sleep(10 * time.Millisecond) devices.Lock() } if i == 1000 { return fmt.Errorf("Timeout while waiting for device %s to be removed", devname) } return nil }
func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc, enableCors bool, dockerVersion version.Version) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // log the request log.Debugf("Calling %s %s", localMethod, localRoute) if logging { log.Infof("%s %s", r.Method, r.RequestURI) } if strings.Contains(r.Header.Get("User-Agent"), "Docker-Client/") { userAgent := strings.Split(r.Header.Get("User-Agent"), "/") if len(userAgent) == 2 && !dockerVersion.Equal(version.Version(userAgent[1])) { log.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], dockerVersion) } } version := version.Version(mux.Vars(r)["version"]) if version == "" { version = api.APIVERSION } if enableCors { writeCorsHeaders(w, r) } if version.GreaterThan(api.APIVERSION) { http.Error(w, fmt.Errorf("client and server don't have same version (client : %s, server: %s)", version, api.APIVERSION).Error(), http.StatusNotFound) return } if err := handlerFunc(eng, version, w, r, mux.Vars(r)); err != nil { log.Errorf("Handler for %s %s returned error: %s", localMethod, localRoute, err) httpError(w, err) } } }
func (e Endpoint) Ping() (RegistryInfo, error) { if e.String() == IndexServerAddress() { // Skip the check, we now this one is valid // (and we never want to fallback to http in case of error) return RegistryInfo{Standalone: false}, nil } req, err := http.NewRequest("GET", e.String()+"_ping", nil) if err != nil { return RegistryInfo{Standalone: false}, err } resp, _, err := doRequest(req, nil, ConnectTimeout, e.secure) if err != nil { return RegistryInfo{Standalone: false}, err } defer resp.Body.Close() jsonString, err := ioutil.ReadAll(resp.Body) if err != nil { return RegistryInfo{Standalone: false}, fmt.Errorf("Error while reading the http response: %s", err) } // If the header is absent, we assume true for compatibility with earlier // versions of the registry. default to true info := RegistryInfo{ Standalone: true, } if err := json.Unmarshal(jsonString, &info); err != nil { log.Debugf("Error unmarshalling the _ping RegistryInfo: %s", err) // don't stop here. Just assume sane defaults } if hdr := resp.Header.Get("X-Docker-Registry-Version"); hdr != "" { log.Debugf("Registry version header: '%s'", hdr) info.Version = hdr } log.Debugf("RegistryInfo.Version: %q", info.Version) standalone := resp.Header.Get("X-Docker-Registry-Standalone") log.Debugf("Registry standalone header: '%s'", standalone) // Accepted values are "true" (case-insensitive) and "1". if strings.EqualFold(standalone, "true") || standalone == "1" { info.Standalone = true } else if len(standalone) > 0 { // there is a header set, and it is not "true" or "1", so assume fails info.Standalone = false } log.Debugf("RegistryInfo.Standalone: %t", info.Standalone) return info, nil }
func (t *TrustStore) reload() error { t.Lock() defer t.Unlock() matches, err := filepath.Glob(filepath.Join(t.path, "*.json")) if err != nil { return err } statements := make([]*trustgraph.Statement, len(matches)) for i, match := range matches { f, err := os.Open(match) if err != nil { return err } statements[i], err = trustgraph.LoadStatement(f, nil) if err != nil { f.Close() return err } f.Close() } if len(statements) == 0 { if t.autofetch { log.Debugf("No grants, fetching") t.fetcher = time.AfterFunc(t.fetchTime, t.fetch) } return nil } grants, expiration, err := trustgraph.CollapseStatements(statements, true) if err != nil { return err } t.expiration = expiration t.graph = trustgraph.NewMemoryGraph(grants) log.Debugf("Reloaded graph with %d grants expiring at %s", len(grants), expiration) if t.autofetch { nextFetch := expiration.Sub(time.Now()) if nextFetch < 0 { nextFetch = defaultFetchtime } else { nextFetch = time.Duration(0.8 * (float64)(nextFetch)) } t.fetcher = time.AfterFunc(nextFetch, t.fetch) } return nil }
func (devices *DeviceSet) deactivatePool() error { log.Debugf("[devmapper] deactivatePool()") defer log.Debugf("[devmapper] deactivatePool END") devname := devices.getPoolDevName() devinfo, err := getInfo(devname) if err != nil { return err } if devinfo.Exists != 0 { return removeDevice(devname) } return nil }
func (devices *DeviceSet) setupBaseImage() error { oldInfo, _ := devices.lookupDevice("") if oldInfo != nil && oldInfo.Initialized { return nil } if oldInfo != nil && !oldInfo.Initialized { log.Debugf("Removing uninitialized base image") if err := devices.deleteDevice(oldInfo); err != nil { return err } } log.Debugf("Initializing base device-manager snapshot") id := devices.nextDeviceId // Create initial device if err := createDevice(devices.getPoolDevName(), &id); err != nil { return err } // Ids are 24bit, so wrap around devices.nextDeviceId = (id + 1) & 0xffffff log.Debugf("Registering base device (id %v) with FS size %v", id, devices.baseFsSize) info, err := devices.registerDevice(id, "", devices.baseFsSize) if err != nil { _ = deleteDevice(devices.getPoolDevName(), id) return err } log.Debugf("Creating filesystem on base device-manager snapshot") if err = devices.activateDeviceIfNeeded(info); err != nil { return err } if err := devices.createFilesystem(info); err != nil { return err } info.Initialized = true if err = devices.saveMetadata(info); err != nil { info.Initialized = false return err } return nil }
func (ts *tarSum) Sum(extra []byte) string { ts.sums.SortBySums() h := sha256.New() if extra != nil { h.Write(extra) } for _, fis := range ts.sums { log.Debugf("-->%s<--", fis.Sum()) h.Write([]byte(fis.Sum())) } checksum := ts.Version().String() + "+sha256:" + hex.EncodeToString(h.Sum(nil)) log.Debugf("checksum processed: %s", checksum) return checksum }
// probeCache checks to see if image-caching is enabled (`b.utilizeCache`) // and if so attempts to look up the current `b.image` and `b.config` pair // in the current server `b.daemon`. If an image is found, probeCache returns // `(true, nil)`. If no image is found, it returns `(false, nil)`. If there // is any error, it returns `(false, err)`. func (b *buildFile) probeCache() (bool, error) { if b.utilizeCache { if cache, err := b.daemon.ImageGetCached(b.image, b.config); err != nil { return false, err } else if cache != nil { fmt.Fprintf(b.outStream, " ---> Using cache\n") log.Debugf("[BUILDER] Use cached version") b.image = cache.ID return true, nil } else { log.Debugf("[BUILDER] Cache miss") } } return false, nil }
func (r *Session) GetRemoteImageLayer(imgID, registry string, token []string, imgSize int64) (io.ReadCloser, error) { var ( retries = 5 statusCode = 0 client *http.Client res *http.Response imageURL = fmt.Sprintf("%simages/%s/layer", registry, imgID) ) req, err := r.reqFactory.NewRequest("GET", imageURL, nil) if err != nil { return nil, fmt.Errorf("Error while getting from the server: %s\n", err) } setTokenAuth(req, token) for i := 1; i <= retries; i++ { statusCode = 0 res, client, err = r.doRequest(req) if err != nil { log.Debugf("Error contacting registry: %s", err) if res != nil { if res.Body != nil { res.Body.Close() } statusCode = res.StatusCode } if i == retries { return nil, fmt.Errorf("Server error: Status %d while fetching image layer (%s)", statusCode, imgID) } time.Sleep(time.Duration(i) * 5 * time.Second) continue } break } if res.StatusCode != 200 { res.Body.Close() return nil, fmt.Errorf("Server error: Status %d while fetching image layer (%s)", res.StatusCode, imgID) } if res.Header.Get("Accept-Ranges") == "bytes" && imgSize > 0 { log.Debugf("server supports resume") return httputils.ResumableRequestReaderWithInitialResponse(client, req, 5, imgSize, res), nil } log.Debugf("server doesn't support resume") return res.Body, nil }
func NewEndpoint(hostname string, insecureRegistries []string) (*Endpoint, error) { endpoint, err := newEndpoint(hostname, insecureRegistries) if err != nil { return nil, err } // Try HTTPS ping to registry endpoint.URL.Scheme = "https" if _, err := endpoint.Ping(); err != nil { //TODO: triggering highland build can be done there without "failing" if endpoint.secure { // If registry is secure and HTTPS failed, show user the error and tell them about `--insecure-registry` // in case that's what they need. DO NOT accept unknown CA certificates, and DO NOT fallback to HTTP. return nil, fmt.Errorf("Invalid registry endpoint %s: %v. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry %s` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/%s/ca.crt", endpoint, err, endpoint.URL.Host, endpoint.URL.Host) } // If registry is insecure and HTTPS failed, fallback to HTTP. log.Debugf("Error from registry %q marked as insecure: %v. Insecurely falling back to HTTP", endpoint, err) endpoint.URL.Scheme = "http" _, err2 := endpoint.Ping() if err2 == nil { return endpoint, nil } return nil, fmt.Errorf("Invalid registry endpoint %q. HTTPS attempt: %v. HTTP attempt: %v", endpoint, err, err2) } return endpoint, nil }
func NewEndpoint(hostname string) (*Endpoint, error) { var ( endpoint Endpoint trimmedHostname string err error ) if !strings.HasPrefix(hostname, "http") { hostname = "https://" + hostname } trimmedHostname, endpoint.Version = scanForApiVersion(hostname) endpoint.URL, err = url.Parse(trimmedHostname) if err != nil { return nil, err } endpoint.URL.Scheme = "https" if _, err := endpoint.Ping(); err != nil { log.Debugf("Registry %s does not work (%s), falling back to http", endpoint, err) // TODO: Check if http fallback is enabled endpoint.URL.Scheme = "http" if _, err = endpoint.Ping(); err != nil { return nil, errors.New("Invalid Registry endpoint: " + err.Error()) } } return &endpoint, nil }
func (container *Container) KillSig(sig int) error { log.Debugf("Sending %d to %s", sig, container.ID) container.Lock() defer container.Unlock() // We could unpause the container for them rather than returning this error if container.State.IsPaused() { return fmt.Errorf("Container %s is paused. Unpause the container before stopping", container.ID) } if !container.State.IsRunning() { return nil } // signal to the monitor that it should not restart the container // after we send the kill signal container.monitor.ExitOnNext() // if the container is currently restarting we do not need to send the signal // to the process. Telling the monitor that it should exit on it's next event // loop is enough if container.State.IsRestarting() { return nil } return container.daemon.Kill(container, sig) }
// Retrieve the history of a given image from the Registry. // Return a list of the parent's json (requested image included) func (r *Session) GetRemoteHistory(imgID, registry string, token []string) ([]string, error) { req, err := r.reqFactory.NewRequest("GET", registry+"images/"+imgID+"/ancestry", nil) if err != nil { return nil, err } setTokenAuth(req, token) res, _, err := r.doRequest(req) if err != nil { return nil, err } defer res.Body.Close() if res.StatusCode != 200 { if res.StatusCode == 401 { return nil, errLoginRequired } return nil, utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to fetch remote history for %s", res.StatusCode, imgID), res) } jsonString, err := ioutil.ReadAll(res.Body) if err != nil { return nil, fmt.Errorf("Error while reading the http response: %s", err) } log.Debugf("Ancestry: %s", jsonString) history := new([]string) if err := json.Unmarshal(jsonString, history); err != nil { return nil, err } return *history, nil }
func (r *Session) SearchRepositories(term string) (*SearchResults, error) { log.Debugf("Index server: %s", r.indexEndpoint) u := r.indexEndpoint + "search?q=" + url.QueryEscape(term) req, err := r.reqFactory.NewRequest("GET", u, nil) if err != nil { return nil, err } if r.authConfig != nil && len(r.authConfig.Username) > 0 { req.SetBasicAuth(r.authConfig.Username, r.authConfig.Password) } req.Header.Set("X-Docker-Token", "true") res, _, err := r.doRequest(req) if err != nil { return nil, err } defer res.Body.Close() if res.StatusCode != 200 { return nil, utils.NewHTTPRequestError(fmt.Sprintf("Unexepected status code %d", res.StatusCode), res) } rawData, err := ioutil.ReadAll(res.Body) if err != nil { return nil, err } result := new(SearchResults) err = json.Unmarshal(rawData, result) return result, err }
// Push a local image to the registry func (r *Session) PushImageJSONRegistry(imgData *ImgData, jsonRaw []byte, registry string, token []string) error { log.Debugf("[registry] Calling PUT %s", registry+"images/"+imgData.ID+"/json") req, err := r.reqFactory.NewRequest("PUT", registry+"images/"+imgData.ID+"/json", bytes.NewReader(jsonRaw)) if err != nil { return err } req.Header.Add("Content-type", "application/json") setTokenAuth(req, token) res, _, err := r.doRequest(req) if err != nil { return fmt.Errorf("Failed to upload metadata: %s", err) } defer res.Body.Close() if res.StatusCode == 401 && strings.HasPrefix(registry, "http://") { return utils.NewHTTPRequestError("HTTP code 401, Docker will not send auth headers over HTTP.", res) } if res.StatusCode != 200 { errBody, err := ioutil.ReadAll(res.Body) if err != nil { return utils.NewHTTPRequestError(fmt.Sprintf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err), res) } var jsonBody map[string]string if err := json.Unmarshal(errBody, &jsonBody); err != nil { errBody = []byte(err.Error()) } else if jsonBody["error"] == "Image already exists" { return ErrAlreadyExists } return utils.NewHTTPRequestError(fmt.Sprintf("HTTP code %d while uploading metadata: %s", res.StatusCode, errBody), res) } return nil }
func (r *Session) PushImageChecksumRegistry(imgData *ImgData, registry string, token []string) error { log.Debugf("[registry] Calling PUT %s", registry+"images/"+imgData.ID+"/checksum") req, err := r.reqFactory.NewRequest("PUT", registry+"images/"+imgData.ID+"/checksum", nil) if err != nil { return err } setTokenAuth(req, token) req.Header.Set("X-Docker-Checksum", imgData.Checksum) req.Header.Set("X-Docker-Checksum-Payload", imgData.ChecksumPayload) res, _, err := r.doRequest(req) if err != nil { return fmt.Errorf("Failed to upload metadata: %s", err) } defer res.Body.Close() if len(res.Cookies()) > 0 { r.jar.SetCookies(req.URL, res.Cookies()) } if res.StatusCode != 200 { errBody, err := ioutil.ReadAll(res.Body) if err != nil { return fmt.Errorf("HTTP code %d while uploading metadata and error when trying to parse response body: %s", res.StatusCode, err) } var jsonBody map[string]string if err := json.Unmarshal(errBody, &jsonBody); err != nil { errBody = []byte(err.Error()) } else if jsonBody["error"] == "Image already exists" { return ErrAlreadyExists } return fmt.Errorf("HTTP code %d while uploading metadata: %s", res.StatusCode, errBody) } return nil }
func NewSession(authConfig *AuthConfig, factory *utils.HTTPRequestFactory, indexEndpoint string, timeout bool) (r *Session, err error) { r = &Session{ authConfig: authConfig, indexEndpoint: indexEndpoint, } if timeout { r.timeout = ReceiveTimeout } r.jar, err = cookiejar.New(nil) if err != nil { return nil, err } // If we're working with a standalone private registry over HTTPS, send Basic Auth headers // alongside our requests. if indexEndpoint != IndexServerAddress() && strings.HasPrefix(indexEndpoint, "https://") { info, err := pingRegistryEndpoint(indexEndpoint) if err != nil { return nil, err } if info.Standalone { log.Debugf("Endpoint %s is eligible for private registry registry. Enabling decorator.", indexEndpoint) dec := utils.NewHTTPAuthDecorator(authConfig.Username, authConfig.Password) factory.AddDecorator(dec) } } r.reqFactory = factory return r, nil }
// - Succeeded to mount for this image scope // - Failed with no error (So continue to Push the Blob) // - Failed with error func (r *Session) PostV2ImageMountBlob(imageName, sumType, sum string, token []string) (bool, error) { vars := map[string]string{ "imagename": imageName, "sumtype": sumType, "sum": sum, } routeURL, err := getV2URL(r.indexEndpoint, "mountBlob", vars) if err != nil { return false, err } method := "POST" log.Debugf("[registry] Calling %q %s", method, routeURL.String()) req, err := r.reqFactory.NewRequest(method, routeURL.String(), nil) if err != nil { return false, err } setTokenAuth(req, token) res, _, err := r.doRequest(req) if err != nil { return false, err } res.Body.Close() // close early, since we're not needing a body on this call .. yet? switch res.StatusCode { case 200: // return something indicating no push needed return true, nil case 300: // return something indicating blob push needed return false, nil } return false, fmt.Errorf("Failed to mount %q - %s:%s : %d", imageName, sumType, sum, res.StatusCode) }
func (r *Session) GetV2ImageBlob(imageName, sumType, sum string, blobWrtr io.Writer, token []string) error { vars := map[string]string{ "imagename": imageName, "sumtype": sumType, "sum": sum, } routeURL, err := getV2URL(r.indexEndpoint, "downloadBlob", vars) if err != nil { return err } method := "GET" log.Debugf("[registry] Calling %q %s", method, routeURL.String()) req, err := r.reqFactory.NewRequest(method, routeURL.String(), nil) if err != nil { return err } setTokenAuth(req, token) res, _, err := r.doRequest(req) if err != nil { return err } defer res.Body.Close() if res.StatusCode != 200 { if res.StatusCode == 401 { return errLoginRequired } return utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to pull %s blob", res.StatusCode, imageName), res) } _, err = io.Copy(blobWrtr, res.Body) return err }
// Finally Push the (signed) manifest of the blobs we've just pushed func (r *Session) PutV2ImageManifest(imageName, tagName string, manifestRdr io.Reader, token []string) error { vars := map[string]string{ "imagename": imageName, "tagname": tagName, } routeURL, err := getV2URL(r.indexEndpoint, "manifests", vars) if err != nil { return err } method := "PUT" log.Debugf("[registry] Calling %q %s", method, routeURL.String()) req, err := r.reqFactory.NewRequest(method, routeURL.String(), manifestRdr) if err != nil { return err } setTokenAuth(req, token) res, _, err := r.doRequest(req) if err != nil { return err } res.Body.Close() if res.StatusCode != 201 { if res.StatusCode == 401 { return errLoginRequired } return utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to push %s:%s manifest", res.StatusCode, imageName, tagName), res) } return nil }
func handlerAccessLog(handler http.Handler) http.Handler { logHandler := func(w http.ResponseWriter, r *http.Request) { log.Debugf("%s \"%s %s\"", r.RemoteAddr, r.Method, r.URL) handler.ServeHTTP(w, r) } return http.HandlerFunc(logHandler) }
func (r *Session) GetV2Version(token []string) (*RegistryInfo, error) { routeURL, err := getV2URL(r.indexEndpoint, "version", nil) if err != nil { return nil, err } method := "GET" log.Debugf("[registry] Calling %q %s", method, routeURL.String()) req, err := r.reqFactory.NewRequest(method, routeURL.String(), nil) if err != nil { return nil, err } setTokenAuth(req, token) res, _, err := r.doRequest(req) if err != nil { return nil, err } defer res.Body.Close() if res.StatusCode != 200 { return nil, utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d fetching Version", res.StatusCode), res) } decoder := json.NewDecoder(res.Body) versionInfo := new(RegistryInfo) err = decoder.Decode(versionInfo) if err != nil { return nil, fmt.Errorf("unable to decode GetV2Version JSON response: %s", err) } return versionInfo, nil }
func (archiver *Archiver) CopyWithTar(src, dst string) error { srcSt, err := os.Stat(src) if err != nil { return err } if !srcSt.IsDir() { return archiver.CopyFileWithTar(src, dst) } // Create dst, copy src's content into it log.Debugf("Creating dest directory: %s", dst) if err := os.MkdirAll(dst, 0755); err != nil && !os.IsExist(err) { return err } log.Debugf("Calling TarUntar(%s, %s)", src, dst) return archiver.TarUntar(src, dst) }
func (s *TagStore) pullV2Repository(eng *engine.Engine, r *registry.Session, out io.Writer, localName, remoteName, tag string, sf *utils.StreamFormatter, parallel bool) error { var layersDownloaded bool if tag == "" { log.Debugf("Pulling tag list from V2 registry for %s", remoteName) tags, err := r.GetV2RemoteTags(remoteName, nil) if err != nil { return err } for _, t := range tags { if downloaded, err := s.pullV2Tag(eng, r, out, localName, remoteName, t, sf, parallel); err != nil { return err } else if downloaded { layersDownloaded = true } } } else { if downloaded, err := s.pullV2Tag(eng, r, out, localName, remoteName, tag, sf, parallel); err != nil { return err } else if downloaded { layersDownloaded = true } } requestedTag := localName if len(tag) > 0 { requestedTag = localName + ":" + tag } WriteStatus(requestedTag, out, sf, layersDownloaded) return nil }