<commit_before>package pxemgr

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"path"
	"strconv"
	"strings"

	"github.com/golang/glog"
	"github.com/gorilla/mux"
	"crypto/x509"
	"crypto/tls"
)

type EtcdNode struct {
	Key   string      `json:"key"`
	Value string      `json:"value,omitempty"`
	Nodes []*EtcdNode `json:"nodes,omitempty"`
	Dir   bool        `json:"dir,omitempty"`
}

type EtcdResponse struct {
	Action string    `json:"action"`
	Node   *EtcdNode `json:"node,omitempty"`
}

type EtcdResponseError struct {
	ErrorCode int    `json:"errorCode"`
	Message   string `json:"message"`
	Cause     string `json:"cause"`
}

func (mgr *pxeManagerT) defineEtcdDiscoveryRoutes(etcdRouter *mux.Router) {
	etcdRouter.PathPrefix("/new").Methods("PUT").HandlerFunc(mgr.etcdDiscoveryNewCluster)

	tokenRouter := etcdRouter.PathPrefix("/{token:[a-f0-9]{32}}").Subrouter()
	tokenRouter.PathPrefix("/_config/size").Methods("GET").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.PathPrefix("/_config/size").Methods("PUT").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.PathPrefix("/{machine}").Methods("PUT").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.PathPrefix("/{machine}").Methods("GET").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.PathPrefix("/{machine}").Methods("DELETE").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.Methods("GET").HandlerFunc(mgr.etcdDiscoveryProxyHandler)

	etcdRouter.Methods("GET").HandlerFunc(mgr.etcdDiscoveryHandler)
}

func (mgr *pxeManagerT) etcdDiscoveryHandler(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r,
		"https://github.com/giantswarm/mayu/blob/master/docs/etcd-discovery.md",
		http.StatusMovedPermanently,
	)
}

func (mgr *pxeManagerT) etcdDiscoveryNewCluster(w http.ResponseWriter, r *http.Request) {
	var err error
	size := mgr.defaultEtcdQuorumSize
	s := r.FormValue("size")
	if s != "" {
		size, err = strconv.Atoi(s)
		if err != nil {
			httpError(w, err.Error(), http.StatusBadRequest)
			return
		}
	}

	token, err := mgr.cluster.GenerateEtcdDiscoveryToken()
	if err != nil {
		httpError(w, fmt.Sprintf("Unable to generate token '%v'", err), 400)
		return
	}

	err = mgr.cluster.StoreEtcdDiscoveryToken(mgr.etcdEndpoint, mgr.etcdCAFile, token, size)
	if err != nil {
		httpError(w, fmt.Sprintf("Unable to store token in etcd '%v'", err), 400)
		return
	}

	glog.V(2).Infof("New cluster created '%s'", token)

	fmt.Fprintf(w, "%s/%s", mgr.etcdDiscoveryBaseURL(), token)
}

func (mgr *pxeManagerT) etcdDiscoveryBaseURL() string {
	return fmt.Sprintf("%s/etcd", mgr.thisHost())
}

func (mgr *pxeManagerT) etcdDiscoveryProxyHandler(w http.ResponseWriter, r *http.Request) {
	resp, err := mgr.etcdDiscoveryProxyRequest(r)
	if err != nil {
		httpError(w, fmt.Sprintf("Error proxying request to etcd '%v'", err), 500)
	}

	copyHeader(w.Header(), resp.Header)
	w.WriteHeader(resp.StatusCode)
	io.Copy(w, resp.Body)
}

func (mgr *pxeManagerT) etcdDiscoveryProxyRequest(r *http.Request) (*http.Response, error) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return nil, err
	}
	var transport = http.DefaultTransport

	if strings.HasPrefix(mgr.etcdEndpoint, "https") && mgr.etcdCAFile != "" {
		customCA := x509.NewCertPool()

		pemData, err := ioutil.ReadFile(mgr.etcdCAFile)
		if err != nil {
			return nil, errors.New("unable to read custom CA file: "+err.Error())
		}
		customCA.AppendCertsFromPEM(pemData)
		transport = &http.Transport{
			TLSClientConfig: &tls.Config{RootCAs:customCA},
		}
	}

	u, err := url.Parse(mgr.etcdEndpoint)
	if err != nil {
		nil, errors.New("invalid etcd-endpoint: "+err.Error())
	}
	u.Path = path.Join("v2", "keys", "_etcd", "registry", strings.TrimPrefix(r.URL.Path, "/etcd"))
	u.RawQuery = r.URL.RawQuery

	for i := 0; i <= 10; i++ {

		buf := bytes.NewBuffer(body)
		glog.V(2).Infof("Body '%s'", body)

		outreq, err := http.NewRequest(r.Method, u.String(), buf)
		if err != nil {
			return nil, err
		}

		copyHeader(outreq.Header, r.Header)

		client := http.Client{Transport:transport}
		resp, err := client.Do(outreq)
		if err != nil {
			return nil, err
		}

		return resp, nil
	}

	return nil, errors.New("All attempts at proxying to etcd failed")
}

// copyHeader copies all of the headers from dst to src.
func copyHeader(dst, src http.Header) {
	for k, v := range src {
		for _, q := range v {
			dst.Add(k, q)
		}
	}
}
<commit_msg>scheme condition simplified<commit_after>package pxemgr

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"path"
	"strconv"
	"strings"

	"github.com/golang/glog"
	"github.com/gorilla/mux"
	"crypto/x509"
	"crypto/tls"
)

type EtcdNode struct {
	Key   string      `json:"key"`
	Value string      `json:"value,omitempty"`
	Nodes []*EtcdNode `json:"nodes,omitempty"`
	Dir   bool        `json:"dir,omitempty"`
}

type EtcdResponse struct {
	Action string    `json:"action"`
	Node   *EtcdNode `json:"node,omitempty"`
}

type EtcdResponseError struct {
	ErrorCode int    `json:"errorCode"`
	Message   string `json:"message"`
	Cause     string `json:"cause"`
}

func (mgr *pxeManagerT) defineEtcdDiscoveryRoutes(etcdRouter *mux.Router) {
	etcdRouter.PathPrefix("/new").Methods("PUT").HandlerFunc(mgr.etcdDiscoveryNewCluster)

	tokenRouter := etcdRouter.PathPrefix("/{token:[a-f0-9]{32}}").Subrouter()
	tokenRouter.PathPrefix("/_config/size").Methods("GET").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.PathPrefix("/_config/size").Methods("PUT").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.PathPrefix("/{machine}").Methods("PUT").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.PathPrefix("/{machine}").Methods("GET").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.PathPrefix("/{machine}").Methods("DELETE").HandlerFunc(mgr.etcdDiscoveryProxyHandler)
	tokenRouter.Methods("GET").HandlerFunc(mgr.etcdDiscoveryProxyHandler)

	etcdRouter.Methods("GET").HandlerFunc(mgr.etcdDiscoveryHandler)
}

func (mgr *pxeManagerT) etcdDiscoveryHandler(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r,
		"https://github.com/giantswarm/mayu/blob/master/docs/etcd-discovery.md",
		http.StatusMovedPermanently,
	)
}

func (mgr *pxeManagerT) etcdDiscoveryNewCluster(w http.ResponseWriter, r *http.Request) {
	var err error
	size := mgr.defaultEtcdQuorumSize
	s := r.FormValue("size")
	if s != "" {
		size, err = strconv.Atoi(s)
		if err != nil {
			httpError(w, err.Error(), http.StatusBadRequest)
			return
		}
	}

	token, err := mgr.cluster.GenerateEtcdDiscoveryToken()
	if err != nil {
		httpError(w, fmt.Sprintf("Unable to generate token '%v'", err), 400)
		return
	}

	err = mgr.cluster.StoreEtcdDiscoveryToken(mgr.etcdEndpoint, mgr.etcdCAFile, token, size)
	if err != nil {
		httpError(w, fmt.Sprintf("Unable to store token in etcd '%v'", err), 400)
		return
	}

	glog.V(2).Infof("New cluster created '%s'", token)

	fmt.Fprintf(w, "%s/%s", mgr.etcdDiscoveryBaseURL(), token)
}

func (mgr *pxeManagerT) etcdDiscoveryBaseURL() string {
	return fmt.Sprintf("%s/etcd", mgr.thisHost())
}

func (mgr *pxeManagerT) etcdDiscoveryProxyHandler(w http.ResponseWriter, r *http.Request) {
	resp, err := mgr.etcdDiscoveryProxyRequest(r)
	if err != nil {
		httpError(w, fmt.Sprintf("Error proxying request to etcd '%v'", err), 500)
	}

	copyHeader(w.Header(), resp.Header)
	w.WriteHeader(resp.StatusCode)
	io.Copy(w, resp.Body)
}

func (mgr *pxeManagerT) etcdDiscoveryProxyRequest(r *http.Request) (*http.Response, error) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return nil, err
	}

	u, err := url.Parse(mgr.etcdEndpoint)
	if err != nil {
		nil, errors.New("invalid etcd-endpoint: "+err.Error())
	}
	u.Path = path.Join("v2", "keys", "_etcd", "registry", strings.TrimPrefix(r.URL.Path, "/etcd"))
	u.RawQuery = r.URL.RawQuery
	var transport = http.DefaultTransport

	if u.Scheme == "https" && mgr.etcdCAFile != "" {
		customCA := x509.NewCertPool()

		pemData, err := ioutil.ReadFile(mgr.etcdCAFile)
		if err != nil {
			return nil, errors.New("unable to read custom CA file: "+err.Error())
		}
		customCA.AppendCertsFromPEM(pemData)
		transport = &http.Transport{
			TLSClientConfig: &tls.Config{RootCAs:customCA},
		}
	}

	for i := 0; i <= 10; i++ {

		buf := bytes.NewBuffer(body)
		glog.V(2).Infof("Body '%s'", body)

		outreq, err := http.NewRequest(r.Method, u.String(), buf)
		if err != nil {
			return nil, err
		}

		copyHeader(outreq.Header, r.Header)

		client := http.Client{Transport:transport}
		resp, err := client.Do(outreq)
		if err != nil {
			return nil, err
		}

		return resp, nil
	}

	return nil, errors.New("All attempts at proxying to etcd failed")
}

// copyHeader copies all of the headers from dst to src.
func copyHeader(dst, src http.Header) {
	for k, v := range src {
		for _, q := range v {
			dst.Add(k, q)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"time"

	"github.com/animenotifier/arn"
	"github.com/fatih/color"

	"github.com/aerogo/crawler"
)

const (
	// The maximum age of files we accept until we force a refresh.
	maxAge    = 30 * 24 * time.Hour
	userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.166 Safari/537.36"
)

func main() {
	defer arn.Node.Close()

	// Filter anime with MAL ID
	animes := []*arn.Anime{}

	for anime := range arn.StreamAnime() {
		malID := anime.GetMapping("myanimelist/anime")

		if malID == "" {
			continue
		}

		animes = append(animes, anime)
	}

	color.Yellow("Found %d anime", len(animes))

	// Create crawler
	malCrawler := crawler.New(
		map[string]string{
			"User-Agent":      userAgent,
			"Accept-Encoding": "gzip",
		},
		1500*time.Millisecond,
		len(animes),
	)

	// Sort so that we download the most important ones first
	arn.SortAnimeByQuality(animes, "")

	// Queue up URLs
	count := 0

	for _, anime := range animes {
		malID := anime.GetMapping("myanimelist/anime")
		url := "https://myanimelist.net/anime/" + malID
		filePath := fmt.Sprintf("files/anime-%s.html", malID)
		fileInfo, err := os.Stat(filePath)

		if err == nil && time.Since(fileInfo.ModTime()) <= maxAge {
			// fmt.Println(color.YellowString(url), "skip")
			continue
		}

		malCrawler.Queue(&crawler.Task{
			URL:         url,
			Destination: filePath,
		})

		count++
	}

	color.Yellow("Queued up %d links", count)
	malCrawler.Wait()
}
<commit_msg>Updated crawler settings<commit_after>package main

import (
	"fmt"
	"os"
	"time"

	"github.com/animenotifier/arn"
	"github.com/fatih/color"

	"github.com/aerogo/crawler"
)

const (
	// The maximum age of files we accept until we force a refresh.
	maxAge               = 30 * 24 * time.Hour
	delayBetweenRequests = 1000 * time.Millisecond
	userAgent            = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.166 Safari/537.36"
)

func main() {
	defer arn.Node.Close()

	// Filter anime with MAL ID
	animes := []*arn.Anime{}

	for anime := range arn.StreamAnime() {
		malID := anime.GetMapping("myanimelist/anime")

		if malID == "" {
			continue
		}

		animes = append(animes, anime)
	}

	color.Yellow("Found %d anime", len(animes))

	// Create crawler
	malCrawler := crawler.New(
		map[string]string{
			"User-Agent":      userAgent,
			"Accept-Encoding": "gzip",
		},
		delayBetweenRequests,
		len(animes),
	)

	// Sort so that we download the most important ones first
	arn.SortAnimeByQuality(animes, "")

	// Queue up URLs
	count := 0

	for _, anime := range animes {
		malID := anime.GetMapping("myanimelist/anime")
		url := "https://myanimelist.net/anime/" + malID
		filePath := fmt.Sprintf("files/anime-%s.html", malID)
		fileInfo, err := os.Stat(filePath)

		if err == nil && time.Since(fileInfo.ModTime()) <= maxAge {
			// fmt.Println(color.YellowString(url), "skip")
			continue
		}

		malCrawler.Queue(&crawler.Task{
			URL:         url,
			Destination: filePath,
		})

		count++
	}

	color.Yellow("Queued up %d links", count)
	malCrawler.Wait()
}
<|endoftext|>


<commit_before><commit_msg>gofmt<commit_after><|endoftext|>


<commit_before>package daemon

import (
	"encoding/json"
	"net/http"

	"github.com/gorilla/mux"
	"github.com/pkg/errors"
	stdprometheus "github.com/prometheus/client_golang/prometheus"
	"github.com/weaveworks/common/middleware"
	"github.com/weaveworks/flux"

	"github.com/weaveworks/flux/api"
	transport "github.com/weaveworks/flux/http"
	"github.com/weaveworks/flux/job"
	fluxmetrics "github.com/weaveworks/flux/metrics"
	"github.com/weaveworks/flux/policy"
	"github.com/weaveworks/flux/update"
)

var (
	requestDuration = stdprometheus.NewHistogramVec(stdprometheus.HistogramOpts{
		Namespace: "flux",
		Name:      "request_duration_seconds",
		Help:      "Time (in seconds) spent serving HTTP requests.",
		Buckets:   stdprometheus.DefBuckets,
	}, []string{fluxmetrics.LabelMethod, fluxmetrics.LabelRoute, "status_code", "ws"})
)

// An API server for the daemon
func NewRouter() *mux.Router {
	r := transport.NewAPIRouter()

	// All old versions are deprecated in the daemon. Use an up to
	// date client!
	transport.DeprecateVersions(r, "v1", "v2", "v3", "v4", "v5")
	// We assume every request that doesn't match a route is a client
	// calling an old or hitherto unsupported API.
	r.NewRoute().Name("NotFound").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		transport.WriteError(w, r, http.StatusNotFound, transport.MakeAPINotFound(r.URL.Path))
	})

	return r
}

func NewHandler(s api.Server, r *mux.Router) http.Handler {
	handle := HTTPServer{s}
	r.Get("JobStatus").HandlerFunc(handle.JobStatus)
	r.Get("SyncStatus").HandlerFunc(handle.SyncStatus)
	r.Get("UpdateManifests").HandlerFunc(handle.UpdateManifests)
	r.Get("ListServices").HandlerFunc(handle.ListServices)
	r.Get("ListImages").HandlerFunc(handle.ListImages)
	r.Get("Export").HandlerFunc(handle.Export)
	r.Get("GitRepoConfig").HandlerFunc(handle.GitRepoConfig)

	// These handlers persist to support requests from older fluxctls. In general we
	// should avoid adding references to them so that they can eventually be removed.
	r.Get("UpdateImages").HandlerFunc(handle.UpdateImages)
	r.Get("UpdatePolicies").HandlerFunc(handle.UpdatePolicies)
	r.Get("GetPublicSSHKey").HandlerFunc(handle.GetPublicSSHKey)
	r.Get("RegeneratePublicSSHKey").HandlerFunc(handle.RegeneratePublicSSHKey)

	return middleware.Instrument{
		RouteMatcher: r,
		Duration:     requestDuration,
	}.Wrap(r)
}

type HTTPServer struct {
	server api.Server
}

func (s HTTPServer) JobStatus(w http.ResponseWriter, r *http.Request) {
	id := job.ID(mux.Vars(r)["id"])
	status, err := s.server.JobStatus(r.Context(), id)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, status)
}

func (s HTTPServer) SyncStatus(w http.ResponseWriter, r *http.Request) {
	ref := mux.Vars(r)["ref"]
	commits, err := s.server.SyncStatus(r.Context(), ref)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, commits)
}

func (s HTTPServer) ListImages(w http.ResponseWriter, r *http.Request) {
	service := mux.Vars(r)["service"]
	spec, err := update.ParseResourceSpec(service)
	if err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing service spec %q", service))
		return
	}

	d, err := s.server.ListImages(r.Context(), spec)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, d)
}

func (s HTTPServer) UpdateManifests(w http.ResponseWriter, r *http.Request) {
	var spec update.Spec
	if err := json.NewDecoder(r.Body).Decode(&spec); err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, err)
		return
	}

	jobID, err := s.server.UpdateManifests(r.Context(), spec)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, jobID)
}

func (s HTTPServer) ListServices(w http.ResponseWriter, r *http.Request) {
	namespace := mux.Vars(r)["namespace"]
	res, err := s.server.ListServices(r.Context(), namespace)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, res)
}

func (s HTTPServer) Export(w http.ResponseWriter, r *http.Request) {
	status, err := s.server.Export(r.Context())
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}

	transport.JSONResponse(w, r, status)
}

func (s HTTPServer) GitRepoConfig(w http.ResponseWriter, r *http.Request) {
	var regenerate bool
	if err := json.NewDecoder(r.Body).Decode(&regenerate); err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, err)
	}
	res, err := s.server.GitRepoConfig(r.Context(), regenerate)
	if err != nil {
		transport.ErrorResponse(w, r, err)
	}
	transport.JSONResponse(w, r, res)
}

// --- handlers supporting deprecated requests

func (s HTTPServer) UpdateImages(w http.ResponseWriter, r *http.Request) {
	var (
		vars  = mux.Vars(r)
		image = vars["image"]
		kind  = vars["kind"]
	)
	if err := r.ParseForm(); err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing form"))
		return
	}
	var serviceSpecs []update.ResourceSpec
	for _, service := range r.Form["service"] {
		serviceSpec, err := update.ParseResourceSpec(service)
		if err != nil {
			transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing service spec %q", service))
			return
		}
		serviceSpecs = append(serviceSpecs, serviceSpec)
	}
	imageSpec, err := update.ParseImageSpec(image)
	if err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing image spec %q", image))
		return
	}
	releaseKind, err := update.ParseReleaseKind(kind)
	if err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing release kind %q", kind))
		return
	}

	var excludes []flux.ResourceID
	for _, ex := range r.URL.Query()["exclude"] {
		s, err := flux.ParseResourceID(ex)
		if err != nil {
			transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing excluded service %q", ex))
			return
		}
		excludes = append(excludes, s)
	}

	spec := update.ReleaseSpec{
		ServiceSpecs: serviceSpecs,
		ImageSpec:    imageSpec,
		Kind:         releaseKind,
		Excludes:     excludes,
	}
	cause := update.Cause{
		User:    r.FormValue("user"),
		Message: r.FormValue("message"),
	}
	result, err := s.server.UpdateManifests(r.Context(), update.Spec{Type: update.Images, Cause: cause, Spec: spec})
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, result)
}

func (s HTTPServer) UpdatePolicies(w http.ResponseWriter, r *http.Request) {
	var updates policy.Updates
	if err := json.NewDecoder(r.Body).Decode(&updates); err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, err)
		return
	}

	cause := update.Cause{
		User:    r.FormValue("user"),
		Message: r.FormValue("message"),
	}

	jobID, err := s.server.UpdateManifests(r.Context(), update.Spec{Type: update.Policy, Cause: cause, Spec: updates})
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}

	transport.JSONResponse(w, r, jobID)
}

func (s HTTPServer) GetPublicSSHKey(w http.ResponseWriter, r *http.Request) {
	res, err := s.server.GitRepoConfig(r.Context(), false)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, res.PublicSSHKey)
}

func (s HTTPServer) RegeneratePublicSSHKey(w http.ResponseWriter, r *http.Request) {
	_, err := s.server.GitRepoConfig(r.Context(), true)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	w.WriteHeader(http.StatusNoContent)
	return
}
<commit_msg>Use route constants instead of magic strings in HTTP handler<commit_after>package daemon

import (
	"encoding/json"
	"net/http"

	"github.com/gorilla/mux"
	"github.com/pkg/errors"
	stdprometheus "github.com/prometheus/client_golang/prometheus"
	"github.com/weaveworks/common/middleware"
	"github.com/weaveworks/flux"

	"github.com/weaveworks/flux/api"
	transport "github.com/weaveworks/flux/http"
	"github.com/weaveworks/flux/job"
	fluxmetrics "github.com/weaveworks/flux/metrics"
	"github.com/weaveworks/flux/policy"
	"github.com/weaveworks/flux/update"
)

var (
	requestDuration = stdprometheus.NewHistogramVec(stdprometheus.HistogramOpts{
		Namespace: "flux",
		Name:      "request_duration_seconds",
		Help:      "Time (in seconds) spent serving HTTP requests.",
		Buckets:   stdprometheus.DefBuckets,
	}, []string{fluxmetrics.LabelMethod, fluxmetrics.LabelRoute, "status_code", "ws"})
)

// An API server for the daemon
func NewRouter() *mux.Router {
	r := transport.NewAPIRouter()

	// All old versions are deprecated in the daemon. Use an up to
	// date client!
	transport.DeprecateVersions(r, "v1", "v2", "v3", "v4", "v5")
	// We assume every request that doesn't match a route is a client
	// calling an old or hitherto unsupported API.
	r.NewRoute().Name("NotFound").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		transport.WriteError(w, r, http.StatusNotFound, transport.MakeAPINotFound(r.URL.Path))
	})

	return r
}

func NewHandler(s api.Server, r *mux.Router) http.Handler {
	handle := HTTPServer{s}
	r.Get(transport.ListServices).HandlerFunc(handle.ListServices)
	r.Get(transport.ListImages).HandlerFunc(handle.ListImages)
	r.Get(transport.UpdateManifests).HandlerFunc(handle.UpdateManifests)
	r.Get(transport.JobStatus).HandlerFunc(handle.JobStatus)
	r.Get(transport.SyncStatus).HandlerFunc(handle.SyncStatus)
	r.Get(transport.Export).HandlerFunc(handle.Export)
	r.Get(transport.GitRepoConfig).HandlerFunc(handle.GitRepoConfig)

	// These handlers persist to support requests from older fluxctls. In general we
	// should avoid adding references to them so that they can eventually be removed.
	r.Get(transport.UpdateImages).HandlerFunc(handle.UpdateImages)
	r.Get(transport.UpdatePolicies).HandlerFunc(handle.UpdatePolicies)
	r.Get(transport.GetPublicSSHKey).HandlerFunc(handle.GetPublicSSHKey)
	r.Get(transport.RegeneratePublicSSHKey).HandlerFunc(handle.RegeneratePublicSSHKey)

	return middleware.Instrument{
		RouteMatcher: r,
		Duration:     requestDuration,
	}.Wrap(r)
}

type HTTPServer struct {
	server api.Server
}

func (s HTTPServer) JobStatus(w http.ResponseWriter, r *http.Request) {
	id := job.ID(mux.Vars(r)["id"])
	status, err := s.server.JobStatus(r.Context(), id)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, status)
}

func (s HTTPServer) SyncStatus(w http.ResponseWriter, r *http.Request) {
	ref := mux.Vars(r)["ref"]
	commits, err := s.server.SyncStatus(r.Context(), ref)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, commits)
}

func (s HTTPServer) ListImages(w http.ResponseWriter, r *http.Request) {
	service := mux.Vars(r)["service"]
	spec, err := update.ParseResourceSpec(service)
	if err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing service spec %q", service))
		return
	}

	d, err := s.server.ListImages(r.Context(), spec)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, d)
}

func (s HTTPServer) UpdateManifests(w http.ResponseWriter, r *http.Request) {
	var spec update.Spec
	if err := json.NewDecoder(r.Body).Decode(&spec); err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, err)
		return
	}

	jobID, err := s.server.UpdateManifests(r.Context(), spec)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, jobID)
}

func (s HTTPServer) ListServices(w http.ResponseWriter, r *http.Request) {
	namespace := mux.Vars(r)["namespace"]
	res, err := s.server.ListServices(r.Context(), namespace)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, res)
}

func (s HTTPServer) Export(w http.ResponseWriter, r *http.Request) {
	status, err := s.server.Export(r.Context())
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}

	transport.JSONResponse(w, r, status)
}

func (s HTTPServer) GitRepoConfig(w http.ResponseWriter, r *http.Request) {
	var regenerate bool
	if err := json.NewDecoder(r.Body).Decode(&regenerate); err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, err)
	}
	res, err := s.server.GitRepoConfig(r.Context(), regenerate)
	if err != nil {
		transport.ErrorResponse(w, r, err)
	}
	transport.JSONResponse(w, r, res)
}

// --- handlers supporting deprecated requests

func (s HTTPServer) UpdateImages(w http.ResponseWriter, r *http.Request) {
	var (
		vars  = mux.Vars(r)
		image = vars["image"]
		kind  = vars["kind"]
	)
	if err := r.ParseForm(); err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing form"))
		return
	}
	var serviceSpecs []update.ResourceSpec
	for _, service := range r.Form["service"] {
		serviceSpec, err := update.ParseResourceSpec(service)
		if err != nil {
			transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing service spec %q", service))
			return
		}
		serviceSpecs = append(serviceSpecs, serviceSpec)
	}
	imageSpec, err := update.ParseImageSpec(image)
	if err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing image spec %q", image))
		return
	}
	releaseKind, err := update.ParseReleaseKind(kind)
	if err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing release kind %q", kind))
		return
	}

	var excludes []flux.ResourceID
	for _, ex := range r.URL.Query()["exclude"] {
		s, err := flux.ParseResourceID(ex)
		if err != nil {
			transport.WriteError(w, r, http.StatusBadRequest, errors.Wrapf(err, "parsing excluded service %q", ex))
			return
		}
		excludes = append(excludes, s)
	}

	spec := update.ReleaseSpec{
		ServiceSpecs: serviceSpecs,
		ImageSpec:    imageSpec,
		Kind:         releaseKind,
		Excludes:     excludes,
	}
	cause := update.Cause{
		User:    r.FormValue("user"),
		Message: r.FormValue("message"),
	}
	result, err := s.server.UpdateManifests(r.Context(), update.Spec{Type: update.Images, Cause: cause, Spec: spec})
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, result)
}

func (s HTTPServer) UpdatePolicies(w http.ResponseWriter, r *http.Request) {
	var updates policy.Updates
	if err := json.NewDecoder(r.Body).Decode(&updates); err != nil {
		transport.WriteError(w, r, http.StatusBadRequest, err)
		return
	}

	cause := update.Cause{
		User:    r.FormValue("user"),
		Message: r.FormValue("message"),
	}

	jobID, err := s.server.UpdateManifests(r.Context(), update.Spec{Type: update.Policy, Cause: cause, Spec: updates})
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}

	transport.JSONResponse(w, r, jobID)
}

func (s HTTPServer) GetPublicSSHKey(w http.ResponseWriter, r *http.Request) {
	res, err := s.server.GitRepoConfig(r.Context(), false)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	transport.JSONResponse(w, r, res.PublicSSHKey)
}

func (s HTTPServer) RegeneratePublicSSHKey(w http.ResponseWriter, r *http.Request) {
	_, err := s.server.GitRepoConfig(r.Context(), true)
	if err != nil {
		transport.ErrorResponse(w, r, err)
		return
	}
	w.WriteHeader(http.StatusNoContent)
	return
}
<|endoftext|>


<commit_before>package template

import (
	"bufio"
	"encoding/json"
	"github.com/leekchan/gtf"
	"io"
	"os"
	"path"
	"reflect"
	"strings"
	txttmpl "text/template"
	"time"
	"sort"
)

type Templating struct {
	template  *txttmpl.Template
	name      string
	content   string
	functions map[string]interface{}
}

const EXT_CFG = ".cfg"

var TemplateFunctions map[string]interface{}

func NewTemplating(partials *txttmpl.Template, filePath, content string) (*Templating, error) {
	t := Templating{
		name:      filePath,
		content:   CleanupOfTemplate(content),
		functions: TemplateFunctions,
	}
	if partials == nil {
		partials = txttmpl.New(t.name)
	}

	tmpl, err := partials.New(t.name).Funcs(t.functions).Funcs(map[string]interface{}(gtf.GtfFuncMap)).Parse(t.content)
	t.template = tmpl
	return &t, err
}

func CleanupOfTemplate(content string) string {
	var lines []string
	var currentLine string
	scanner := bufio.NewScanner(strings.NewReader(string(content)))
	for scanner.Scan() {
		part := strings.TrimRight(scanner.Text(), " ")
		leftTrim := strings.TrimLeft(part, " ")
		if strings.HasPrefix(leftTrim, "{{-") {
			part = "{{" + leftTrim[3:]
		}
		currentLine += part
		if strings.HasSuffix(currentLine, "-}}") {
			currentLine = currentLine[0:len(currentLine)-3] + "}}"
		} else {
			lines = append(lines, currentLine)
			currentLine = ""
		}
	}
	if currentLine != "" {
		lines = append(lines, currentLine)
	}
	return strings.Join(lines, "\n")
}

func (t *Templating) Execute(wr io.Writer, data interface{}) error {
	return t.template.Execute(wr, data)
}

func (t *Templating) AddFunction(name string, fn interface{}) {
	t.functions[name] = fn
}

func (t *Templating) AddFunctions(fs map[string]interface{}) {
	addFuncs(t.functions, fs)
}

///////////////////////////////////

func ifOrDef(eif interface{}, yes interface{}, no interface{}) interface{} {
	if eif != nil {
		return yes
	}
	return no
}

func orDef(val interface{}, def interface{}) interface{} {
	if val != nil {
		return val
	}
	return def
}

func orDefs(val []interface{}, def interface{}) interface{} {
	if val != nil && len(val) != 0 {
		return val
	}
	return []interface{}{def}
}

func addFuncs(out, in map[string]interface{}) {
	for name, fn := range in {
		out[name] = fn
	}
}

func UnmarshalJsonObject(data string) (map[string]interface{}, error) {
	var ret map[string]interface{}
	err := json.Unmarshal([]byte(data), &ret)
	return ret, err
}

func UnmarshalJsonArray(data string) ([]interface{}, error) {
	var ret []interface{}
	err := json.Unmarshal([]byte(data), &ret)
	return ret, err
}

func IsType(data interface{}, t string) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.String() == t {
		return true
	}
	return false
}

func IsKind(data interface{}, t string) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.Kind().String() == t {
		return true
	}
	return false
}

func IsMap(data interface{}) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.Kind() == reflect.Map {
		return true
	}
	return false
}

func IsArray(data interface{}) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.Kind() == reflect.Array || dataType.Kind() == reflect.Slice {
		return true
	}
	return false
}

func IsString(data interface{}) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.Kind() == reflect.String {
		return true
	}
	return false
}

func IsMapFirst(data interface{},element interface{}) bool {
	switch reflect.TypeOf(data).Kind() {
		case reflect.Map :
				mapItem := reflect.ValueOf(data).MapKeys()

			  var keys []string
				for _,k := range mapItem {
				    keys = append(keys,k.String())
				}
				sort.Strings(keys)
				mapItemType := keys[0]
				return (mapItemType == element)
	}
	return false
}

func IsMapLast(data interface{},element interface{}) bool {
	switch reflect.TypeOf(data).Kind() {
		case reflect.Map :
			mapItem := reflect.ValueOf(data).MapKeys()
			mapLen := reflect.ValueOf(data).Len()
			mapItemType := mapItem[mapLen - 1].String()
			return (mapItemType == element)
	}
	return false
}

func HowDeep(data interface{},element interface{}) int{
 	return HowDeepIsIt(data,element,0)
}

func HowDeepIsIt(data interface{},element interface{},deep int) int{
	//elemType := reflect.TypeOf(element).Kind()
	// dataType := reflect.TypeOf(data).Kind()
	mapItem := reflect.ValueOf(data)
	elemItem := reflect.ValueOf(element)
	switch elemType {
		case reflect.String:
		//	fmt.Println("1Bis: Type:",elemType,"Value",elemItem,"ValueData",mapItem)
		// 	fmt.Println("Type:",dataType,"Value",mapItem)
		// 	for _, b := range reflect.ValueOf(data).MapKeys() {
		// 		//fmt.Println("Reflect:",elemItem , "Value:",b,"MapValue",mapItem.MapIndex(b),"Equal",reflect.DeepEqual(mapItem.MapIndex(b).Interface(), elemItem.Interface()))
		// 		//fmt.Println("Reflect:",IsMap(mapItem.MapIndex(b).Interface()),"b",mapItem.MapIndex(b).Interface())
		// 		// fmt.Println("Reflect:",(elemItem.Interface()) ,mapItem.MapIndex(b).Interface())
		// 		if reflect.DeepEqual(mapItem.MapIndex(b).Interface(), elemItem.Interface()) {
		// 			return deep + 1
		// 		}
		// 	}
		case reflect.Map :
			//fmt.Println("1: Key:",elemType , "Value:",element ,"Reflect",elemItem)
			//fmt.Println("Key:",data , "Value:",dataType,"Reflect",mapItem)
			for _, b := range reflect.ValueOf(data).MapKeys() {
				//fmt.Println("Reflect:",elemItem , "Value:",b,"MapValue",mapItem.MapIndex(b),"Equal",reflect.DeepEqual(mapItem.MapIndex(b).Interface(), elemItem.Interface()))
				//fmt.Println("Reflect:",IsMap(mapItem.MapIndex(b).Interface()),"b",mapItem.MapIndex(b).Interface())
				//fmt.Println("2: Reflect:",(elemItem.Interface()) ,mapItem.MapIndex(b).Interface())
				if reflect.DeepEqual(mapItem.MapIndex(b).Interface(), elemItem.Interface()) {
					return deep + 1
				}
				// if IsMap(mapItem.MapIndex(b).Interface()) {
				// 	fmt.Println("3: IsMap:",mapItem.MapIndex(b).Interface())
				// 	index := HowDeepIsIt(mapItem.MapIndex(b).Interface(),element,deep + 1 )
				// 	if index == deep + 2 {
				// 		fmt.Println("4: Key:",mapItem.MapIndex(b).Interface() ,"Deepness",index)
				// 		return index
				// 	}
				// }
			}
	}

	return deep
}

func add(x, y int) int {
	return x + y
}

func mul(x, y int) int {
	return x * y
}

func div(x, y int) int {
	return x / y
}

func mod(x, y int) int {
	return x % y
}

func sub(x, y int) int {
	return x - y
}

func init() {
	TemplateFunctions = make(map[string]interface{})
	TemplateFunctions["base"] = path.Base
	TemplateFunctions["split"] = strings.Split
	TemplateFunctions["json"] = UnmarshalJsonObject
	TemplateFunctions["jsonArray"] = UnmarshalJsonArray
	TemplateFunctions["dir"] = path.Dir
	TemplateFunctions["getenv"] = os.Getenv
	TemplateFunctions["join"] = strings.Join
	TemplateFunctions["datetime"] = time.Now
	TemplateFunctions["toUpper"] = strings.ToUpper
	TemplateFunctions["toLower"] = strings.ToLower
	TemplateFunctions["contains"] = strings.Contains
	TemplateFunctions["replace"] = strings.Replace
	TemplateFunctions["repeat"] = strings.Repeat
	TemplateFunctions["orDef"] = orDef
	TemplateFunctions["orDefs"] = orDefs
	TemplateFunctions["ifOrDef"] = ifOrDef
	TemplateFunctions["isType"] = IsType
	TemplateFunctions["isMap"] = IsMap
	TemplateFunctions["isArray"] = IsArray
	TemplateFunctions["isKind"] = IsKind
	TemplateFunctions["isString"] = IsString
	TemplateFunctions["IsMapFirst"] = IsMapFirst
	TemplateFunctions["IsMapLast"] = IsMapLast
	TemplateFunctions["HowDeep"] = HowDeep
	TemplateFunctions["add"] = add
	TemplateFunctions["mul"] = mul
	TemplateFunctions["div"] = div
	TemplateFunctions["sub"] = sub
	TemplateFunctions["mod"] = mod
}
<commit_msg>Add IsMapFirst and IsMapLast and HowDeep in templater<commit_after>package template

import (
	"bufio"
	"encoding/json"
	"github.com/leekchan/gtf"
	"io"
	"os"
	"path"
	"reflect"
	"strings"
	txttmpl "text/template"
	"time"
	"sort"
)

type Templating struct {
	template  *txttmpl.Template
	name      string
	content   string
	functions map[string]interface{}
}

const EXT_CFG = ".cfg"

var TemplateFunctions map[string]interface{}

func NewTemplating(partials *txttmpl.Template, filePath, content string) (*Templating, error) {
	t := Templating{
		name:      filePath,
		content:   CleanupOfTemplate(content),
		functions: TemplateFunctions,
	}
	if partials == nil {
		partials = txttmpl.New(t.name)
	}

	tmpl, err := partials.New(t.name).Funcs(t.functions).Funcs(map[string]interface{}(gtf.GtfFuncMap)).Parse(t.content)
	t.template = tmpl
	return &t, err
}

func CleanupOfTemplate(content string) string {
	var lines []string
	var currentLine string
	scanner := bufio.NewScanner(strings.NewReader(string(content)))
	for scanner.Scan() {
		part := strings.TrimRight(scanner.Text(), " ")
		leftTrim := strings.TrimLeft(part, " ")
		if strings.HasPrefix(leftTrim, "{{-") {
			part = "{{" + leftTrim[3:]
		}
		currentLine += part
		if strings.HasSuffix(currentLine, "-}}") {
			currentLine = currentLine[0:len(currentLine)-3] + "}}"
		} else {
			lines = append(lines, currentLine)
			currentLine = ""
		}
	}
	if currentLine != "" {
		lines = append(lines, currentLine)
	}
	return strings.Join(lines, "\n")
}

func (t *Templating) Execute(wr io.Writer, data interface{}) error {
	return t.template.Execute(wr, data)
}

func (t *Templating) AddFunction(name string, fn interface{}) {
	t.functions[name] = fn
}

func (t *Templating) AddFunctions(fs map[string]interface{}) {
	addFuncs(t.functions, fs)
}

///////////////////////////////////

func ifOrDef(eif interface{}, yes interface{}, no interface{}) interface{} {
	if eif != nil {
		return yes
	}
	return no
}

func orDef(val interface{}, def interface{}) interface{} {
	if val != nil {
		return val
	}
	return def
}

func orDefs(val []interface{}, def interface{}) interface{} {
	if val != nil && len(val) != 0 {
		return val
	}
	return []interface{}{def}
}

func addFuncs(out, in map[string]interface{}) {
	for name, fn := range in {
		out[name] = fn
	}
}

func UnmarshalJsonObject(data string) (map[string]interface{}, error) {
	var ret map[string]interface{}
	err := json.Unmarshal([]byte(data), &ret)
	return ret, err
}

func UnmarshalJsonArray(data string) ([]interface{}, error) {
	var ret []interface{}
	err := json.Unmarshal([]byte(data), &ret)
	return ret, err
}

func IsType(data interface{}, t string) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.String() == t {
		return true
	}
	return false
}

func IsKind(data interface{}, t string) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.Kind().String() == t {
		return true
	}
	return false
}

func IsMap(data interface{}) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.Kind() == reflect.Map {
		return true
	}
	return false
}

func IsArray(data interface{}) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.Kind() == reflect.Array || dataType.Kind() == reflect.Slice {
		return true
	}
	return false
}

func IsString(data interface{}) bool {
	dataType := reflect.TypeOf(data)
	if dataType == nil {
		return false
	}
	if dataType.Kind() == reflect.String {
		return true
	}
	return false
}

func IsMapFirst(data interface{},element interface{}) bool {
	switch reflect.TypeOf(data).Kind() {
		case reflect.Map :
				mapItem := reflect.ValueOf(data).MapKeys()

			  var keys []string
				for _,k := range mapItem {
				    keys = append(keys,k.String())
				}
				sort.Strings(keys)
				mapItemType := keys[0]
				return (mapItemType == element)
	}
	return false
}

func IsMapLast(data interface{},element interface{}) bool {
	switch reflect.TypeOf(data).Kind() {
		case reflect.Map :
			mapItem := reflect.ValueOf(data).MapKeys()
			mapLen := reflect.ValueOf(data).Len()
			mapItemType := mapItem[mapLen - 1].String()
			return (mapItemType == element)
	}
	return false
}

func HowDeep(data interface{},element interface{}) int{
 	return HowDeepIsIt(data,element,0)
}

func HowDeepIsIt(data interface{},element interface{},deep int) int{
	//elemType := reflect.TypeOf(element).Kind()
	// dataType := reflect.TypeOf(data).Kind()
	mapItem := reflect.ValueOf(data)
	elemItem := reflect.ValueOf(element)
	switch elemType {
		case reflect.String:
		//	fmt.Println("1Bis: Type:",elemType,"Value",elemItem,"ValueData",mapItem)
		// 	fmt.Println("Type:",dataType,"Value",mapItem)
		// 	for _, b := range reflect.ValueOf(data).MapKeys() {cd ~g
		// 		//fmt.Println("Reflect:",elemItem , "Value:",b,"MapValue",mapItem.MapIndex(b),"Equal",reflect.DeepEqual(mapItem.MapIndex(b).Interface(), elemItem.Interface()))
		// 		//fmt.Println("Reflect:",IsMap(mapItem.MapIndex(b).Interface()),"b",mapItem.MapIndex(b).Interface())
		// 		// fmt.Println("Reflect:",(elemItem.Interface()) ,mapItem.MapIndex(b).Interface())
		// 		if reflect.DeepEqual(mapItem.MapIndex(b).Interface(), elemItem.Interface()) {
		// 			return deep + 1
		// 		}
		// 	}
		case reflect.Map :
			//fmt.Println("1: Key:",elemType , "Value:",element ,"Reflect",elemItem)
			//fmt.Println("Key:",data , "Value:",dataType,"Reflect",mapItem)
			for _, b := range reflect.ValueOf(data).MapKeys() {
				//fmt.Println("Reflect:",elemItem , "Value:",b,"MapValue",mapItem.MapIndex(b),"Equal",reflect.DeepEqual(mapItem.MapIndex(b).Interface(), elemItem.Interface()))
				//fmt.Println("Reflect:",IsMap(mapItem.MapIndex(b).Interface()),"b",mapItem.MapIndex(b).Interface())
				//fmt.Println("2: Reflect:",(elemItem.Interface()) ,mapItem.MapIndex(b).Interface())
				if reflect.DeepEqual(mapItem.MapIndex(b).Interface(), elemItem.Interface()) {
					return deep + 1
				}
				// if IsMap(mapItem.MapIndex(b).Interface()) {
				// 	fmt.Println("3: IsMap:",mapItem.MapIndex(b).Interface())
				// 	index := HowDeepIsIt(mapItem.MapIndex(b).Interface(),element,deep + 1 )
				// 	if index == deep + 2 {
				// 		fmt.Println("4: Key:",mapItem.MapIndex(b).Interface() ,"Deepness",index)
				// 		return index
				// 	}
				// }
			}
	}

	return deep
}

func add(x, y int) int {
	return x + y
}

func mul(x, y int) int {
	return x * y
}

func div(x, y int) int {
	return x / y
}

func mod(x, y int) int {
	return x % y
}

func sub(x, y int) int {
	return x - y
}

func init() {
	TemplateFunctions = make(map[string]interface{})
	TemplateFunctions["base"] = path.Base
	TemplateFunctions["split"] = strings.Split
	TemplateFunctions["json"] = UnmarshalJsonObject
	TemplateFunctions["jsonArray"] = UnmarshalJsonArray
	TemplateFunctions["dir"] = path.Dir
	TemplateFunctions["getenv"] = os.Getenv
	TemplateFunctions["join"] = strings.Join
	TemplateFunctions["datetime"] = time.Now
	TemplateFunctions["toUpper"] = strings.ToUpper
	TemplateFunctions["toLower"] = strings.ToLower
	TemplateFunctions["contains"] = strings.Contains
	TemplateFunctions["replace"] = strings.Replace
	TemplateFunctions["repeat"] = strings.Repeat
	TemplateFunctions["orDef"] = orDef
	TemplateFunctions["orDefs"] = orDefs
	TemplateFunctions["ifOrDef"] = ifOrDef
	TemplateFunctions["isType"] = IsType
	TemplateFunctions["isMap"] = IsMap
	TemplateFunctions["isArray"] = IsArray
	TemplateFunctions["isKind"] = IsKind
	TemplateFunctions["isString"] = IsString
	TemplateFunctions["IsMapFirst"] = IsMapFirst
	TemplateFunctions["IsMapLast"] = IsMapLast
	TemplateFunctions["HowDeep"] = HowDeep
	TemplateFunctions["add"] = add
	TemplateFunctions["mul"] = mul
	TemplateFunctions["div"] = div
	TemplateFunctions["sub"] = sub
	TemplateFunctions["mod"] = mod
}
<|endoftext|>


<commit_before>package btctimestamper

import (
	"flag"

	"github.com/stratumn/sdk/blockchain/btc"

	log "github.com/sirupsen/logrus"
)

var (
	fee int64
)

// RegisterFlags registers the flags used by InitializeWithFlags.
func RegisterFlags() {
	flag.Int64Var(&fee, "fee", DefaultFee, "transaction fee (satoshis)")

}

// InitializeWithFlags should be called after RegisterFlags and flag.Parse to initialize
// a bcbatchfossilizer using flag values.
func InitializeWithFlags(version, commit string, key string, unspentFinder btc.UnspentFinder, broadcaster btc.Broadcaster) *Timestamper {
	ts, err := New(&Config{
		UnspentFinder: unspentFinder,
		Broadcaster:   broadcaster,
		WIF:           key,
		Fee:           fee,
	})
	if err != nil {
		log.WithField("error", err).Fatal("Failed to create Bitcoin timestamper")
	}
	return ts
}
<commit_msg>blockchain: fix formatting<commit_after>package btctimestamper

import (
	"flag"

	"github.com/stratumn/sdk/blockchain/btc"

	log "github.com/sirupsen/logrus"
)

var (
	fee int64
)

// RegisterFlags registers the flags used by InitializeWithFlags.
func RegisterFlags() {
	flag.Int64Var(&fee, "fee", DefaultFee, "transaction fee (satoshis)")
}

// InitializeWithFlags should be called after RegisterFlags and flag.Parse to initialize
// a bcbatchfossilizer using flag values.
func InitializeWithFlags(version, commit string, key string, unspentFinder btc.UnspentFinder, broadcaster btc.Broadcaster) *Timestamper {
	ts, err := New(&Config{
		UnspentFinder: unspentFinder,
		Broadcaster:   broadcaster,
		WIF:           key,
		Fee:           fee,
	})
	if err != nil {
		log.WithField("error", err).Fatal("Failed to create Bitcoin timestamper")
	}
	return ts
}
<|endoftext|>


<commit_before>package rtnetlink

import "syscall"

type Family uint8

const (
  AF_UNSPEC Family = syscall.AF_UNSPEC
  AF_INET   Family = syscall.AF_INET
  AF_INET6  Family = syscall.AF_INET6
)

<commit_msg>add Family/String() method<commit_after>package rtnetlink

import "syscall"

type Family uint8

const (
  AF_UNSPEC Family = syscall.AF_UNSPEC
  AF_INET   Family = syscall.AF_INET
  AF_INET6  Family = syscall.AF_INET6
)

func (self Family)String()(out string){
  switch self {
    default: out = "Unknown"
    case AF_UNSPEC: out = "AF_UNSPEC"
    case AF_INET: out = "AF_INET"
    case AF_INET6: out = "AF_INET6"
  }
  return
}
<|endoftext|>


<commit_before>package registry

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/registry/v2"
	"github.com/docker/docker/utils"
)

const DockerDigestHeader = "Docker-Content-Digest"

func getV2Builder(e *Endpoint) *v2.URLBuilder {
	if e.URLBuilder == nil {
		e.URLBuilder = v2.NewURLBuilder(e.URL)
	}
	return e.URLBuilder
}

func (r *Session) V2RegistryEndpoint(index *IndexInfo) (ep *Endpoint, err error) {
	// TODO check if should use Mirror
	if index.Official {
		ep, err = newEndpoint(REGISTRYSERVER, true)
		if err != nil {
			return
		}
		err = validateEndpoint(ep)
		if err != nil {
			return
		}
	} else if r.indexEndpoint.String() == index.GetAuthConfigKey() {
		ep = r.indexEndpoint
	} else {
		ep, err = NewEndpoint(index)
		if err != nil {
			return
		}
	}

	ep.URLBuilder = v2.NewURLBuilder(ep.URL)
	return
}

// GetV2Authorization gets the authorization needed to the given image
// If readonly access is requested, then only the authorization may
// only be used for Get operations.
func (r *Session) GetV2Authorization(ep *Endpoint, imageName string, readOnly bool) (auth *RequestAuthorization, err error) {
	scopes := []string{"pull"}
	if !readOnly {
		scopes = append(scopes, "push")
	}

	log.Debugf("Getting authorization for %s %s", imageName, scopes)
	return NewRequestAuthorization(r.GetAuthConfig(true), ep, "repository", imageName, scopes), nil
}

//
// 1) Check if TarSum of each layer exists /v2/
//  1.a) if 200, continue
//  1.b) if 300, then push the
//  1.c) if anything else, err
// 2) PUT the created/signed manifest
//
func (r *Session) GetV2ImageManifest(ep *Endpoint, imageName, tagName string, auth *RequestAuthorization) ([]byte, string, error) {
	routeURL, err := getV2Builder(ep).BuildManifestURL(imageName, tagName)
	if err != nil {
		return nil, "", err
	}

	method := "GET"
	log.Debugf("[registry] Calling %q %s", method, routeURL)

	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return nil, "", err
	}
	if err := auth.Authorize(req); err != nil {
		return nil, "", err
	}
	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
		} else if res.StatusCode == 404 {
			return nil, "", ErrDoesNotExist
		}
		return nil, "", utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to fetch for %s:%s", res.StatusCode, imageName, tagName), res)
	}

	buf, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, "", fmt.Errorf("Error while reading the http response: %s", err)
	}
	return buf, res.Header.Get(DockerDigestHeader), nil
}

// - Succeeded to head image blob (already exists)
// - Failed with no error (continue to Push the Blob)
// - Failed with error
func (r *Session) HeadV2ImageBlob(ep *Endpoint, imageName, sumType, sum string, auth *RequestAuthorization) (bool, error) {
	routeURL, err := getV2Builder(ep).BuildBlobURL(imageName, sumType+":"+sum)
	if err != nil {
		return false, err
	}

	method := "HEAD"
	log.Debugf("[registry] Calling %q %s", method, routeURL)

	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return false, err
	}
	if err := auth.Authorize(req); err != nil {
		return false, err
	}
	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 {
	case res.StatusCode >= 200 && res.StatusCode < 400:
		// return something indicating no push needed
		return true, nil
	case res.StatusCode == 401:
		return false, errLoginRequired
	case res.StatusCode == 404:
		// return something indicating blob push needed
		return false, nil
	}

	return false, utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying head request for %s - %s:%s", res.StatusCode, imageName, sumType, sum), res)
}

func (r *Session) GetV2ImageBlob(ep *Endpoint, imageName, sumType, sum string, blobWrtr io.Writer, auth *RequestAuthorization) error {
	routeURL, err := getV2Builder(ep).BuildBlobURL(imageName, sumType+":"+sum)
	if err != nil {
		return err
	}

	method := "GET"
	log.Debugf("[registry] Calling %q %s", method, routeURL)
	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return err
	}
	if err := auth.Authorize(req); err != nil {
		return err
	}
	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
}

func (r *Session) GetV2ImageBlobReader(ep *Endpoint, imageName, sumType, sum string, auth *RequestAuthorization) (io.ReadCloser, int64, error) {
	routeURL, err := getV2Builder(ep).BuildBlobURL(imageName, sumType+":"+sum)
	if err != nil {
		return nil, 0, err
	}

	method := "GET"
	log.Debugf("[registry] Calling %q %s", method, routeURL)
	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return nil, 0, err
	}
	if err := auth.Authorize(req); err != nil {
		return nil, 0, err
	}
	res, _, err := r.doRequest(req)
	if err != nil {
		return nil, 0, err
	}
	if res.StatusCode != 200 {
		if res.StatusCode == 401 {
			return nil, 0, errLoginRequired
		}
		return nil, 0, utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to pull %s blob - %s:%s", res.StatusCode, imageName, sumType, sum), res)
	}
	lenStr := res.Header.Get("Content-Length")
	l, err := strconv.ParseInt(lenStr, 10, 64)
	if err != nil {
		return nil, 0, err
	}

	return res.Body, l, err
}

// Push the image to the server for storage.
// 'layer' is an uncompressed reader of the blob to be pushed.
// The server will generate it's own checksum calculation.
func (r *Session) PutV2ImageBlob(ep *Endpoint, imageName, sumType, sumStr string, blobRdr io.Reader, auth *RequestAuthorization) error {
	routeURL, err := getV2Builder(ep).BuildBlobUploadURL(imageName)
	if err != nil {
		return err
	}

	log.Debugf("[registry] Calling %q %s", "POST", routeURL)
	req, err := r.reqFactory.NewRequest("POST", routeURL, nil)
	if err != nil {
		return err
	}

	if err := auth.Authorize(req); err != nil {
		return err
	}
	res, _, err := r.doRequest(req)
	if err != nil {
		return err
	}
	location := res.Header.Get("Location")

	method := "PUT"
	log.Debugf("[registry] Calling %q %s", method, location)
	req, err = r.reqFactory.NewRequest(method, location, ioutil.NopCloser(blobRdr))
	if err != nil {
		return err
	}
	queryParams := req.URL.Query()
	queryParams.Add("digest", sumType+":"+sumStr)
	req.URL.RawQuery = queryParams.Encode()
	if err := auth.Authorize(req); err != nil {
		return err
	}
	res, _, err = r.doRequest(req)
	if err != nil {
		return err
	}
	defer res.Body.Close()

	if res.StatusCode != 201 {
		if res.StatusCode == 401 {
			return errLoginRequired
		}
		errBody, err := ioutil.ReadAll(res.Body)
		if err != nil {
			return err
		}
		log.Debugf("Unexpected response from server: %q %#v", errBody, res.Header)
		return utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to push %s blob - %s:%s", res.StatusCode, imageName, sumType, sumStr), res)
	}

	return nil
}

// Finally Push the (signed) manifest of the blobs we've just pushed
func (r *Session) PutV2ImageManifest(ep *Endpoint, imageName, tagName string, manifestRdr io.Reader, auth *RequestAuthorization) (string, error) {
	routeURL, err := getV2Builder(ep).BuildManifestURL(imageName, tagName)
	if err != nil {
		return "", err
	}

	method := "PUT"
	log.Debugf("[registry] Calling %q %s", method, routeURL)
	req, err := r.reqFactory.NewRequest(method, routeURL, manifestRdr)
	if err != nil {
		return "", err
	}
	if err := auth.Authorize(req); err != nil {
		return "", err
	}
	res, _, err := r.doRequest(req)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()

	// All 2xx and 3xx responses can be accepted for a put.
	if res.StatusCode >= 400 {
		if res.StatusCode == 401 {
			return "", errLoginRequired
		}
		errBody, err := ioutil.ReadAll(res.Body)
		if err != nil {
			return "", err
		}
		log.Debugf("Unexpected response from server: %q %#v", errBody, res.Header)
		return "", utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to push %s:%s manifest", res.StatusCode, imageName, tagName), res)
	}

	return res.Header.Get(DockerDigestHeader), nil
}

type remoteTags struct {
	name string
	tags []string
}

// Given a repository name, returns a json array of string tags
func (r *Session) GetV2RemoteTags(ep *Endpoint, imageName string, auth *RequestAuthorization) ([]string, error) {
	routeURL, err := getV2Builder(ep).BuildTagsURL(imageName)
	if err != nil {
		return nil, err
	}

	method := "GET"
	log.Debugf("[registry] Calling %q %s", method, routeURL)

	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return nil, err
	}
	if err := auth.Authorize(req); err != nil {
		return nil, err
	}
	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
		} else if res.StatusCode == 404 {
			return nil, ErrDoesNotExist
		}
		return nil, utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to fetch for %s", res.StatusCode, imageName), res)
	}

	decoder := json.NewDecoder(res.Body)
	var remote remoteTags
	err = decoder.Decode(&remote)
	if err != nil {
		return nil, fmt.Errorf("Error while decoding the http response: %s", err)
	}
	return remote.tags, nil
}
<commit_msg>Separate init blob upload<commit_after>package registry

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/registry/v2"
	"github.com/docker/docker/utils"
)

const DockerDigestHeader = "Docker-Content-Digest"

func getV2Builder(e *Endpoint) *v2.URLBuilder {
	if e.URLBuilder == nil {
		e.URLBuilder = v2.NewURLBuilder(e.URL)
	}
	return e.URLBuilder
}

func (r *Session) V2RegistryEndpoint(index *IndexInfo) (ep *Endpoint, err error) {
	// TODO check if should use Mirror
	if index.Official {
		ep, err = newEndpoint(REGISTRYSERVER, true)
		if err != nil {
			return
		}
		err = validateEndpoint(ep)
		if err != nil {
			return
		}
	} else if r.indexEndpoint.String() == index.GetAuthConfigKey() {
		ep = r.indexEndpoint
	} else {
		ep, err = NewEndpoint(index)
		if err != nil {
			return
		}
	}

	ep.URLBuilder = v2.NewURLBuilder(ep.URL)
	return
}

// GetV2Authorization gets the authorization needed to the given image
// If readonly access is requested, then only the authorization may
// only be used for Get operations.
func (r *Session) GetV2Authorization(ep *Endpoint, imageName string, readOnly bool) (auth *RequestAuthorization, err error) {
	scopes := []string{"pull"}
	if !readOnly {
		scopes = append(scopes, "push")
	}

	log.Debugf("Getting authorization for %s %s", imageName, scopes)
	return NewRequestAuthorization(r.GetAuthConfig(true), ep, "repository", imageName, scopes), nil
}

//
// 1) Check if TarSum of each layer exists /v2/
//  1.a) if 200, continue
//  1.b) if 300, then push the
//  1.c) if anything else, err
// 2) PUT the created/signed manifest
//
func (r *Session) GetV2ImageManifest(ep *Endpoint, imageName, tagName string, auth *RequestAuthorization) ([]byte, string, error) {
	routeURL, err := getV2Builder(ep).BuildManifestURL(imageName, tagName)
	if err != nil {
		return nil, "", err
	}

	method := "GET"
	log.Debugf("[registry] Calling %q %s", method, routeURL)

	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return nil, "", err
	}
	if err := auth.Authorize(req); err != nil {
		return nil, "", err
	}
	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
		} else if res.StatusCode == 404 {
			return nil, "", ErrDoesNotExist
		}
		return nil, "", utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to fetch for %s:%s", res.StatusCode, imageName, tagName), res)
	}

	buf, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, "", fmt.Errorf("Error while reading the http response: %s", err)
	}
	return buf, res.Header.Get(DockerDigestHeader), nil
}

// - Succeeded to head image blob (already exists)
// - Failed with no error (continue to Push the Blob)
// - Failed with error
func (r *Session) HeadV2ImageBlob(ep *Endpoint, imageName, sumType, sum string, auth *RequestAuthorization) (bool, error) {
	routeURL, err := getV2Builder(ep).BuildBlobURL(imageName, sumType+":"+sum)
	if err != nil {
		return false, err
	}

	method := "HEAD"
	log.Debugf("[registry] Calling %q %s", method, routeURL)

	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return false, err
	}
	if err := auth.Authorize(req); err != nil {
		return false, err
	}
	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 {
	case res.StatusCode >= 200 && res.StatusCode < 400:
		// return something indicating no push needed
		return true, nil
	case res.StatusCode == 401:
		return false, errLoginRequired
	case res.StatusCode == 404:
		// return something indicating blob push needed
		return false, nil
	}

	return false, utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying head request for %s - %s:%s", res.StatusCode, imageName, sumType, sum), res)
}

func (r *Session) GetV2ImageBlob(ep *Endpoint, imageName, sumType, sum string, blobWrtr io.Writer, auth *RequestAuthorization) error {
	routeURL, err := getV2Builder(ep).BuildBlobURL(imageName, sumType+":"+sum)
	if err != nil {
		return err
	}

	method := "GET"
	log.Debugf("[registry] Calling %q %s", method, routeURL)
	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return err
	}
	if err := auth.Authorize(req); err != nil {
		return err
	}
	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
}

func (r *Session) GetV2ImageBlobReader(ep *Endpoint, imageName, sumType, sum string, auth *RequestAuthorization) (io.ReadCloser, int64, error) {
	routeURL, err := getV2Builder(ep).BuildBlobURL(imageName, sumType+":"+sum)
	if err != nil {
		return nil, 0, err
	}

	method := "GET"
	log.Debugf("[registry] Calling %q %s", method, routeURL)
	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return nil, 0, err
	}
	if err := auth.Authorize(req); err != nil {
		return nil, 0, err
	}
	res, _, err := r.doRequest(req)
	if err != nil {
		return nil, 0, err
	}
	if res.StatusCode != 200 {
		if res.StatusCode == 401 {
			return nil, 0, errLoginRequired
		}
		return nil, 0, utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to pull %s blob - %s:%s", res.StatusCode, imageName, sumType, sum), res)
	}
	lenStr := res.Header.Get("Content-Length")
	l, err := strconv.ParseInt(lenStr, 10, 64)
	if err != nil {
		return nil, 0, err
	}

	return res.Body, l, err
}

// Push the image to the server for storage.
// 'layer' is an uncompressed reader of the blob to be pushed.
// The server will generate it's own checksum calculation.
func (r *Session) PutV2ImageBlob(ep *Endpoint, imageName, sumType, sumStr string, blobRdr io.Reader, auth *RequestAuthorization) error {
	location, err := r.initiateBlobUpload(ep, imageName, auth)
	if err != nil {
		return err
	}

	method := "PUT"
	log.Debugf("[registry] Calling %q %s", method, location)
	req, err := r.reqFactory.NewRequest(method, location, ioutil.NopCloser(blobRdr))
	if err != nil {
		return err
	}
	queryParams := req.URL.Query()
	queryParams.Add("digest", sumType+":"+sumStr)
	req.URL.RawQuery = queryParams.Encode()
	if err := auth.Authorize(req); err != nil {
		return err
	}
	res, _, err := r.doRequest(req)
	if err != nil {
		return err
	}
	defer res.Body.Close()

	if res.StatusCode != 201 {
		if res.StatusCode == 401 {
			return errLoginRequired
		}
		errBody, err := ioutil.ReadAll(res.Body)
		if err != nil {
			return err
		}
		log.Debugf("Unexpected response from server: %q %#v", errBody, res.Header)
		return utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to push %s blob - %s:%s", res.StatusCode, imageName, sumType, sumStr), res)
	}

	return nil
}

// initiateBlobUpload gets the blob upload location for the given image name.
func (r *Session) initiateBlobUpload(ep *Endpoint, imageName string, auth *RequestAuthorization) (location string, err error) {
	routeURL, err := getV2Builder(ep).BuildBlobUploadURL(imageName)
	if err != nil {
		return "", err
	}

	log.Debugf("[registry] Calling %q %s", "POST", routeURL)
	req, err := r.reqFactory.NewRequest("POST", routeURL, nil)
	if err != nil {
		return "", err
	}

	if err := auth.Authorize(req); err != nil {
		return "", err
	}
	res, _, err := r.doRequest(req)
	if err != nil {
		return "", err
	}

	if res.StatusCode != http.StatusAccepted {
		if res.StatusCode == http.StatusUnauthorized {
			return "", errLoginRequired
		}
		if res.StatusCode == http.StatusNotFound {
			return "", ErrDoesNotExist
		}

		errBody, err := ioutil.ReadAll(res.Body)
		if err != nil {
			return "", err
		}

		log.Debugf("Unexpected response from server: %q %#v", errBody, res.Header)
		return "", utils.NewHTTPRequestError(fmt.Sprintf("Server error: unexpected %d response status trying to initiate upload of %s", res.StatusCode, imageName), res)
	}

	if location = res.Header.Get("Location"); location == "" {
		return "", fmt.Errorf("registry did not return a Location header for resumable blob upload for image %s", imageName)
	}

	return
}

// Finally Push the (signed) manifest of the blobs we've just pushed
func (r *Session) PutV2ImageManifest(ep *Endpoint, imageName, tagName string, manifestRdr io.Reader, auth *RequestAuthorization) (string, error) {
	routeURL, err := getV2Builder(ep).BuildManifestURL(imageName, tagName)
	if err != nil {
		return "", err
	}

	method := "PUT"
	log.Debugf("[registry] Calling %q %s", method, routeURL)
	req, err := r.reqFactory.NewRequest(method, routeURL, manifestRdr)
	if err != nil {
		return "", err
	}
	if err := auth.Authorize(req); err != nil {
		return "", err
	}
	res, _, err := r.doRequest(req)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()

	// All 2xx and 3xx responses can be accepted for a put.
	if res.StatusCode >= 400 {
		if res.StatusCode == 401 {
			return "", errLoginRequired
		}
		errBody, err := ioutil.ReadAll(res.Body)
		if err != nil {
			return "", err
		}
		log.Debugf("Unexpected response from server: %q %#v", errBody, res.Header)
		return "", utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to push %s:%s manifest", res.StatusCode, imageName, tagName), res)
	}

	return res.Header.Get(DockerDigestHeader), nil
}

type remoteTags struct {
	name string
	tags []string
}

// Given a repository name, returns a json array of string tags
func (r *Session) GetV2RemoteTags(ep *Endpoint, imageName string, auth *RequestAuthorization) ([]string, error) {
	routeURL, err := getV2Builder(ep).BuildTagsURL(imageName)
	if err != nil {
		return nil, err
	}

	method := "GET"
	log.Debugf("[registry] Calling %q %s", method, routeURL)

	req, err := r.reqFactory.NewRequest(method, routeURL, nil)
	if err != nil {
		return nil, err
	}
	if err := auth.Authorize(req); err != nil {
		return nil, err
	}
	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
		} else if res.StatusCode == 404 {
			return nil, ErrDoesNotExist
		}
		return nil, utils.NewHTTPRequestError(fmt.Sprintf("Server error: %d trying to fetch for %s", res.StatusCode, imageName), res)
	}

	decoder := json.NewDecoder(res.Body)
	var remote remoteTags
	err = decoder.Decode(&remote)
	if err != nil {
		return nil, fmt.Errorf("Error while decoding the http response: %s", err)
	}
	return remote.tags, nil
}
<|endoftext|>


<commit_before>// Copyright 2017 The go-python Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package bind

import (
	"go/token"
)

const (
	// FIXME(corona10): ffibuilder.cdef should be written this way.
	// ffi.cdef("""
	//       //header exported from 'go tool cgo'
	//      #include "%[3]s.h"
	//       """)
	// discuss: https://github.com/go-python/gopy/pull/93#discussion_r119652220
	cffiPreamble = `%[1]s
from __future__ import unicode_literals
import collections
import os
import sys
import cffi as _cffi_backend

_PY3 = sys.version_info[0] == 3

ffi = _cffi_backend.FFI()
ffi.cdef("""
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef size_t GoUintptr;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef float GoFloat32;
typedef double GoFloat64;
typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
typedef struct { GoFloat32 real; GoFloat32 imag; } GoComplex64;
typedef struct { GoFloat64 real; GoFloat64 imag; } GoComplex128;

extern GoComplex64 _cgopy_GoComplex64(GoFloat32 p0, GoFloat32 p1);
extern GoComplex128 _cgopy_GoComplex128(GoFloat64 p0, GoFloat64 p1);
extern GoString _cgopy_GoString(char* p0);
extern char* _cgopy_CString(GoString p0);
extern void _cgopy_FreeCString(char* p0);
extern GoUint8 _cgopy_ErrorIsNil(GoInterface p0);
extern char* _cgopy_ErrorString(GoInterface p0);
extern void cgopy_incref(void* p0);
extern void cgopy_decref(void* p0);

extern void cgo_pkg_%[2]s_init();

`
	cffiHelperPreamble = `""")

# python <--> cffi helper.
class _cffi_helper(object):

    here = os.path.dirname(os.path.abspath(__file__))
    lib = ffi.dlopen(os.path.join(here, "_%[1]s%[2]s"))

    @staticmethod
    def cffi_cgopy_cnv_py2c_bool(o):
        return ffi.cast('_Bool', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_complex64(o):
        real = o.real
        imag = o.imag
        complex64 = _cffi_helper.lib._cgopy_GoComplex64(real, imag)
        return complex64

    @staticmethod
    def cffi_cgopy_cnv_py2c_complex128(o):
        real = o.real
        imag = o.imag
        complex128 = _cffi_helper.lib._cgopy_GoComplex128(real, imag)
        return complex128

    @staticmethod
    def cffi_cgopy_cnv_py2c_string(o):
        if (_PY3 and isinstance(o, str)) or (not _PY3 and isinstance(o, unicode)):
            o = o.encode('utf8')
        s = ffi.new("char[]", o)
        return _cffi_helper.lib._cgopy_GoString(s)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int(o):
        return ffi.cast('int', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int8(o):
        return ffi.cast('int8_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int16(o):
        return ffi.cast('int16_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int32(o):
        return ffi.cast('int32_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int64(o):
        return ffi.cast('int64_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_float32(o):
        return ffi.cast('float', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_float64(o):
        return ffi.cast('double', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint(o):
        return ffi.cast('uint', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint8(o):
        return ffi.cast('uint8_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint16(o):
        return ffi.cast('uint16_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint32(o):
        return ffi.cast('uint32_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint64(o):
        return ffi.cast('uint64_t', o)

    @staticmethod
    def cffi_cgopy_cnv_c2py_bool(c):
        return bool(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_complex64(c):
         return complex(c.real, c.imag)

    @staticmethod
    def cffi_cgopy_cnv_c2py_complex128(c):
         return complex(c.real, c.imag)

    @staticmethod
    def cffi_cgopy_cnv_c2py_string(c):
        s = _cffi_helper.lib._cgopy_CString(c)
        pystr = ffi.string(s)
        _cffi_helper.lib._cgopy_FreeCString(s)
        pystr = pystr.decode('utf8')
        return pystr

    @staticmethod
    def cffi_cgopy_cnv_c2py_errstring(c):
        s = _cffi_helper.lib._cgopy_ErrorString(c)
        pystr = ffi.string(s)
        _cffi_helper.lib._cgopy_FreeCString(s)
        pystr = pystr.decode('utf8')
        return pystr

    @staticmethod
    def cffi_cgopy_cnv_c2py_int(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_int8(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_int16(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_int32(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_int64(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_float32(c):
        return float(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_float64(c):
        return float(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint8(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint16(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint32(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint64(c):
        return int(c)

`
)

type cffiGen struct {
	wrapper *printer

	fset *token.FileSet
	pkg  *Package
	err  ErrorList

	vm   string // python interpreter
	lang int    // c-python api version (2,3)
}

func (g *cffiGen) gen() error {
	// Write preamble for CFFI library wrapper.
	g.genCffiPreamble()
	g.genCffiCdef()
	g.genWrappedPy()
	return nil
}

func (g *cffiGen) genCffiPreamble() {
	n := g.pkg.pkg.Name()
	pkgDoc := g.pkg.doc.Doc
	if pkgDoc != "" {
		g.wrapper.Printf(cffiPreamble, `"""`+pkgDoc+`"""`, n)
	} else {
		g.wrapper.Printf(cffiPreamble, "", n)
	}
}

func (g *cffiGen) genCffiCdef() {

	// first, process slices, arrays
	{
		names := g.pkg.syms.names()
		for _, n := range names {
			sym := g.pkg.syms.sym(n)
			if !sym.isType() {
				continue
			}
			g.genCdefType(sym)
		}
	}

	// Register struct type defintions
	for _, s := range g.pkg.structs {
		g.genCdefStruct(s)
	}

	for _, s := range g.pkg.structs {
		for _, ctor := range s.ctors {
			g.genCdefFunc(ctor)
		}
	}

	for _, s := range g.pkg.structs {
		for _, m := range s.meths {
			g.genCdefMethod(m)
		}

		typ := s.Struct()
		for i := 0; i < typ.NumFields(); i++ {
			f := typ.Field(i)
			if !f.Exported() {
				continue
			}
			g.genCdefStructMemberGetter(s, i, f)
			g.genCdefStructMemberSetter(s, i, f)
		}

		g.genCdefStructTPStr(s)
	}

	for _, f := range g.pkg.funcs {
		g.genCdefFunc(f)
	}

	for _, c := range g.pkg.consts {
		g.genCdefConst(c)
	}

	for _, v := range g.pkg.vars {
		g.genCdefVar(v)
	}
}

func (g *cffiGen) genWrappedPy() {
	n := g.pkg.pkg.Name()
	g.wrapper.Printf(cffiHelperPreamble, n, shlibExt)
	g.wrapper.Indent()

	// first, process slices, arrays
	names := g.pkg.syms.names()
	for _, n := range names {
		sym := g.pkg.syms.sym(n)
		if !sym.isType() {
			continue
		}
		if sym.isPointer() {
			continue
		}
		g.genTypeConverter(sym)
	}

	for _, s := range g.pkg.structs {
		g.genStructConversion(s)
	}
	g.wrapper.Outdent()

	// After generating all of the stuff for the preamble (includes struct, interface.. etc)
	// then call a function which checks Cgo is successfully loaded and initialized.
	g.wrapper.Printf("# make sure Cgo is loaded and initialized\n")
	g.wrapper.Printf("_cffi_helper.lib.cgo_pkg_%[1]s_init()\n", n)

	for _, n := range names {
		sym := g.pkg.syms.sym(n)
		if !sym.isType() {
			continue
		}
		g.genType(sym)
	}

	for _, s := range g.pkg.structs {
		g.genStruct(s)
	}

	for _, s := range g.pkg.structs {
		for _, ctor := range s.ctors {
			g.genFunc(ctor)
		}
	}

	for _, f := range g.pkg.funcs {
		g.genFunc(f)
	}

	for _, c := range g.pkg.consts {
		g.genConst(c)
	}

	for _, v := range g.pkg.vars {
		g.genVar(v)
	}
}

func (g *cffiGen) genConst(c Const) {
	g.genGetFunc(c.f)
}

func (g *cffiGen) genVar(v Var) {
	id := g.pkg.Name() + "_" + v.Name()
	get := "returns " + g.pkg.Name() + "." + v.Name()
	set := "sets " + g.pkg.Name() + "." + v.Name()
	if v.doc != "" {
		// if the Go variable had some documentation attached,
		// put it there as well.
		get += "\n\n" + v.doc
		set += "\n\n" + v.doc
	}
	doc := v.doc
	{
		res := []*Var{newVar(g.pkg, v.GoType(), "ret", v.Name(), doc)}
		sig := newSignature(g.pkg, nil, nil, res)
		fget := Func{
			pkg:  g.pkg,
			sig:  sig,
			typ:  nil,
			name: v.Name(),
			id:   id + "_get",
			doc:  get,
			ret:  v.GoType(),
			err:  false,
		}
		g.genGetFunc(fget)
	}
	{
		params := []*Var{newVar(g.pkg, v.GoType(), "arg", v.Name(), doc)}
		sig := newSignature(g.pkg, nil, params, nil)
		fset := Func{
			pkg:  g.pkg,
			sig:  sig,
			typ:  nil,
			name: v.Name(),
			id:   id + "_set",
			doc:  set,
			ret:  nil,
			err:  false,
		}
		g.genSetFunc(fset)
	}
}

func (g *cffiGen) genCdefConst(c Const) {
	g.genCdefFunc(c.f)
}

func (g *cffiGen) genCdefVar(v Var) {
	id := g.pkg.Name() + "_" + v.Name()
	doc := v.doc
	{
		res := []*Var{newVar(g.pkg, v.GoType(), "ret", v.Name(), doc)}
		sig := newSignature(g.pkg, nil, nil, res)
		fget := Func{
			pkg:  g.pkg,
			sig:  sig,
			typ:  nil,
			name: v.Name(),
			id:   id + "_get",
			doc:  "returns " + g.pkg.Name() + "." + v.Name(),
			ret:  v.GoType(),
			err:  false,
		}
		g.genCdefFunc(fget)
	}
	{
		params := []*Var{newVar(g.pkg, v.GoType(), "arg", v.Name(), doc)}
		sig := newSignature(g.pkg, nil, params, nil)
		fset := Func{
			pkg:  g.pkg,
			sig:  sig,
			typ:  nil,
			name: v.Name(),
			id:   id + "_set",
			doc:  "sets " + g.pkg.Name() + "." + v.Name(),
			ret:  nil,
			err:  false,
		}
		g.genCdefFunc(fset)
	}
}
<commit_msg>bind: use uintXX_t types<commit_after>// Copyright 2017 The go-python Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package bind

import (
	"go/token"
)

const (
	// FIXME(corona10): ffibuilder.cdef should be written this way.
	// ffi.cdef("""
	//       //header exported from 'go tool cgo'
	//      #include "%[3]s.h"
	//       """)
	// discuss: https://github.com/go-python/gopy/pull/93#discussion_r119652220
	cffiPreamble = `%[1]s
from __future__ import unicode_literals
import collections
import os
import sys
import cffi as _cffi_backend

_PY3 = sys.version_info[0] == 3

ffi = _cffi_backend.FFI()
ffi.cdef("""
typedef  int8_t  GoInt8;
typedef uint8_t  GoUint8;
typedef  int16_t GoInt16;
typedef uint16_t GoUint16;
typedef  int32_t GoInt32;
typedef uint32_t GoUint32;
typedef  int64_t GoInt64;
typedef uintptr_t GoUintptr;
typedef uint64_t  GoUint64;
typedef GoInt64   GoInt;
typedef GoUint64  GoUint;
typedef float     GoFloat32;
typedef double    GoFloat64;
typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
typedef struct { GoFloat32 real; GoFloat32 imag; } GoComplex64;
typedef struct { GoFloat64 real; GoFloat64 imag; } GoComplex128;

extern GoComplex64 _cgopy_GoComplex64(GoFloat32 p0, GoFloat32 p1);
extern GoComplex128 _cgopy_GoComplex128(GoFloat64 p0, GoFloat64 p1);
extern GoString _cgopy_GoString(char* p0);
extern char* _cgopy_CString(GoString p0);
extern void _cgopy_FreeCString(char* p0);
extern GoUint8 _cgopy_ErrorIsNil(GoInterface p0);
extern char* _cgopy_ErrorString(GoInterface p0);
extern void cgopy_incref(void* p0);
extern void cgopy_decref(void* p0);

extern void cgo_pkg_%[2]s_init();

`
	cffiHelperPreamble = `""")

# python <--> cffi helper.
class _cffi_helper(object):

    here = os.path.dirname(os.path.abspath(__file__))
    lib = ffi.dlopen(os.path.join(here, "_%[1]s%[2]s"))

    @staticmethod
    def cffi_cgopy_cnv_py2c_bool(o):
        return ffi.cast('_Bool', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_complex64(o):
        real = o.real
        imag = o.imag
        complex64 = _cffi_helper.lib._cgopy_GoComplex64(real, imag)
        return complex64

    @staticmethod
    def cffi_cgopy_cnv_py2c_complex128(o):
        real = o.real
        imag = o.imag
        complex128 = _cffi_helper.lib._cgopy_GoComplex128(real, imag)
        return complex128

    @staticmethod
    def cffi_cgopy_cnv_py2c_string(o):
        if (_PY3 and isinstance(o, str)) or (not _PY3 and isinstance(o, unicode)):
            o = o.encode('utf8')
        s = ffi.new("char[]", o)
        return _cffi_helper.lib._cgopy_GoString(s)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int(o):
        return ffi.cast('int', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int8(o):
        return ffi.cast('int8_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int16(o):
        return ffi.cast('int16_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int32(o):
        return ffi.cast('int32_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_int64(o):
        return ffi.cast('int64_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_float32(o):
        return ffi.cast('float', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_float64(o):
        return ffi.cast('double', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint(o):
        return ffi.cast('uint', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint8(o):
        return ffi.cast('uint8_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint16(o):
        return ffi.cast('uint16_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint32(o):
        return ffi.cast('uint32_t', o)

    @staticmethod
    def cffi_cgopy_cnv_py2c_uint64(o):
        return ffi.cast('uint64_t', o)

    @staticmethod
    def cffi_cgopy_cnv_c2py_bool(c):
        return bool(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_complex64(c):
         return complex(c.real, c.imag)

    @staticmethod
    def cffi_cgopy_cnv_c2py_complex128(c):
         return complex(c.real, c.imag)

    @staticmethod
    def cffi_cgopy_cnv_c2py_string(c):
        s = _cffi_helper.lib._cgopy_CString(c)
        pystr = ffi.string(s)
        _cffi_helper.lib._cgopy_FreeCString(s)
        pystr = pystr.decode('utf8')
        return pystr

    @staticmethod
    def cffi_cgopy_cnv_c2py_errstring(c):
        s = _cffi_helper.lib._cgopy_ErrorString(c)
        pystr = ffi.string(s)
        _cffi_helper.lib._cgopy_FreeCString(s)
        pystr = pystr.decode('utf8')
        return pystr

    @staticmethod
    def cffi_cgopy_cnv_c2py_int(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_int8(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_int16(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_int32(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_int64(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_float32(c):
        return float(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_float64(c):
        return float(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint8(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint16(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint32(c):
        return int(c)

    @staticmethod
    def cffi_cgopy_cnv_c2py_uint64(c):
        return int(c)

`
)

type cffiGen struct {
	wrapper *printer

	fset *token.FileSet
	pkg  *Package
	err  ErrorList

	vm   string // python interpreter
	lang int    // c-python api version (2,3)
}

func (g *cffiGen) gen() error {
	// Write preamble for CFFI library wrapper.
	g.genCffiPreamble()
	g.genCffiCdef()
	g.genWrappedPy()
	return nil
}

func (g *cffiGen) genCffiPreamble() {
	n := g.pkg.pkg.Name()
	pkgDoc := g.pkg.doc.Doc
	if pkgDoc != "" {
		g.wrapper.Printf(cffiPreamble, `"""`+pkgDoc+`"""`, n)
	} else {
		g.wrapper.Printf(cffiPreamble, "", n)
	}
}

func (g *cffiGen) genCffiCdef() {

	// first, process slices, arrays
	{
		names := g.pkg.syms.names()
		for _, n := range names {
			sym := g.pkg.syms.sym(n)
			if !sym.isType() {
				continue
			}
			g.genCdefType(sym)
		}
	}

	// Register struct type defintions
	for _, s := range g.pkg.structs {
		g.genCdefStruct(s)
	}

	for _, s := range g.pkg.structs {
		for _, ctor := range s.ctors {
			g.genCdefFunc(ctor)
		}
	}

	for _, s := range g.pkg.structs {
		for _, m := range s.meths {
			g.genCdefMethod(m)
		}

		typ := s.Struct()
		for i := 0; i < typ.NumFields(); i++ {
			f := typ.Field(i)
			if !f.Exported() {
				continue
			}
			g.genCdefStructMemberGetter(s, i, f)
			g.genCdefStructMemberSetter(s, i, f)
		}

		g.genCdefStructTPStr(s)
	}

	for _, f := range g.pkg.funcs {
		g.genCdefFunc(f)
	}

	for _, c := range g.pkg.consts {
		g.genCdefConst(c)
	}

	for _, v := range g.pkg.vars {
		g.genCdefVar(v)
	}
}

func (g *cffiGen) genWrappedPy() {
	n := g.pkg.pkg.Name()
	g.wrapper.Printf(cffiHelperPreamble, n, shlibExt)
	g.wrapper.Indent()

	// first, process slices, arrays
	names := g.pkg.syms.names()
	for _, n := range names {
		sym := g.pkg.syms.sym(n)
		if !sym.isType() {
			continue
		}
		if sym.isPointer() {
			continue
		}
		g.genTypeConverter(sym)
	}

	for _, s := range g.pkg.structs {
		g.genStructConversion(s)
	}
	g.wrapper.Outdent()

	// After generating all of the stuff for the preamble (includes struct, interface.. etc)
	// then call a function which checks Cgo is successfully loaded and initialized.
	g.wrapper.Printf("# make sure Cgo is loaded and initialized\n")
	g.wrapper.Printf("_cffi_helper.lib.cgo_pkg_%[1]s_init()\n", n)

	for _, n := range names {
		sym := g.pkg.syms.sym(n)
		if !sym.isType() {
			continue
		}
		g.genType(sym)
	}

	for _, s := range g.pkg.structs {
		g.genStruct(s)
	}

	for _, s := range g.pkg.structs {
		for _, ctor := range s.ctors {
			g.genFunc(ctor)
		}
	}

	for _, f := range g.pkg.funcs {
		g.genFunc(f)
	}

	for _, c := range g.pkg.consts {
		g.genConst(c)
	}

	for _, v := range g.pkg.vars {
		g.genVar(v)
	}
}

func (g *cffiGen) genConst(c Const) {
	g.genGetFunc(c.f)
}

func (g *cffiGen) genVar(v Var) {
	id := g.pkg.Name() + "_" + v.Name()
	get := "returns " + g.pkg.Name() + "." + v.Name()
	set := "sets " + g.pkg.Name() + "." + v.Name()
	if v.doc != "" {
		// if the Go variable had some documentation attached,
		// put it there as well.
		get += "\n\n" + v.doc
		set += "\n\n" + v.doc
	}
	doc := v.doc
	{
		res := []*Var{newVar(g.pkg, v.GoType(), "ret", v.Name(), doc)}
		sig := newSignature(g.pkg, nil, nil, res)
		fget := Func{
			pkg:  g.pkg,
			sig:  sig,
			typ:  nil,
			name: v.Name(),
			id:   id + "_get",
			doc:  get,
			ret:  v.GoType(),
			err:  false,
		}
		g.genGetFunc(fget)
	}
	{
		params := []*Var{newVar(g.pkg, v.GoType(), "arg", v.Name(), doc)}
		sig := newSignature(g.pkg, nil, params, nil)
		fset := Func{
			pkg:  g.pkg,
			sig:  sig,
			typ:  nil,
			name: v.Name(),
			id:   id + "_set",
			doc:  set,
			ret:  nil,
			err:  false,
		}
		g.genSetFunc(fset)
	}
}

func (g *cffiGen) genCdefConst(c Const) {
	g.genCdefFunc(c.f)
}

func (g *cffiGen) genCdefVar(v Var) {
	id := g.pkg.Name() + "_" + v.Name()
	doc := v.doc
	{
		res := []*Var{newVar(g.pkg, v.GoType(), "ret", v.Name(), doc)}
		sig := newSignature(g.pkg, nil, nil, res)
		fget := Func{
			pkg:  g.pkg,
			sig:  sig,
			typ:  nil,
			name: v.Name(),
			id:   id + "_get",
			doc:  "returns " + g.pkg.Name() + "." + v.Name(),
			ret:  v.GoType(),
			err:  false,
		}
		g.genCdefFunc(fget)
	}
	{
		params := []*Var{newVar(g.pkg, v.GoType(), "arg", v.Name(), doc)}
		sig := newSignature(g.pkg, nil, params, nil)
		fset := Func{
			pkg:  g.pkg,
			sig:  sig,
			typ:  nil,
			name: v.Name(),
			id:   id + "_set",
			doc:  "sets " + g.pkg.Name() + "." + v.Name(),
			ret:  nil,
			err:  false,
		}
		g.genCdefFunc(fset)
	}
}
<|endoftext|>


<commit_before>package fasthttputil

import (
	"errors"
	"io"
	"net"
	"sync"
	"time"
)

// NewPipeConns returns new bi-directonal connection pipe.
func NewPipeConns() *PipeConns {
	ch1 := acquirePipeChan()
	ch2 := acquirePipeChan()

	pc := &PipeConns{}
	pc.c1.r = ch1
	pc.c1.w = ch2
	pc.c2.r = ch2
	pc.c2.w = ch1
	pc.c1.pc = pc
	pc.c2.pc = pc
	return pc
}

// PipeConns provides bi-directional connection pipe,
// which use in-process memory as a transport.
//
// PipeConns must be created by calling NewPipeConns.
//
// PipeConns have the following additional features comparing to connections
// returned from net.Pipe():
//
//   * It is faster.
//   * It buffers Write calls, so there is no need to have concurrent goroutine
//     calling Read in order to unblock each Write call.
type PipeConns struct {
	c1 pipeConn
	c2 pipeConn
}

// Conn1 returns the first end of bi-directional pipe.
//
// Data written to Conn1 may be read from Conn2.
// Data written to Conn2 may be read from Conn1.
func (pc *PipeConns) Conn1() net.Conn {
	return &pc.c1
}

// Conn2 returns the second end of bi-directional pipe.
//
// Data written to Conn2 may be read from Conn1.
// Data written to Conn1 may be read from Conn2.
func (pc *PipeConns) Conn2() net.Conn {
	return &pc.c2
}

func (pc *PipeConns) release() {
	pc.c1.wlock.Lock()
	pc.c2.wlock.Lock()
	mustRelease := pc.c1.wclosed && pc.c2.wclosed
	pc.c1.wlock.Unlock()
	pc.c2.wlock.Unlock()

	if mustRelease {
		pc.c1.release()
		pc.c2.release()
	}
}

type pipeConn struct {
	r  *pipeChan
	w  *pipeChan
	b  *byteBuffer
	bb []byte

	rlock   sync.Mutex
	rclosed bool

	wlock   sync.Mutex
	wclosed bool

	pc *PipeConns
}

func (c *pipeConn) Write(p []byte) (int, error) {
	b := acquireByteBuffer()
	b.b = append(b.b[:0], p...)

	c.wlock.Lock()
	if c.wclosed {
		c.wlock.Unlock()
		releaseByteBuffer(b)
		return 0, errConnectionClosed
	}
	c.w.ch <- b
	c.wlock.Unlock()

	return len(p), nil
}

func (c *pipeConn) Read(p []byte) (int, error) {
	mayBlock := true
	nn := 0
	for len(p) > 0 {
		n, err := c.read(p, mayBlock)
		nn += n
		if err != nil {
			if !mayBlock && err == errWouldBlock {
				err = nil
			}
			return nn, err
		}
		p = p[n:]
		mayBlock = false
	}

	return nn, nil
}

func (c *pipeConn) read(p []byte, mayBlock bool) (int, error) {
	if len(c.bb) == 0 {
		releaseByteBuffer(c.b)
		c.b = nil

		c.rlock.Lock()
		if c.rclosed {
			c.rlock.Unlock()
			return 0, io.EOF
		}

		if mayBlock {
			c.b = <-c.r.ch
		} else {
			select {
			case c.b = <-c.r.ch:
			default:
				c.rlock.Unlock()
				return 0, errWouldBlock
			}
		}

		if c.b == nil {
			c.rclosed = true
			c.rlock.Unlock()
			return 0, io.EOF
		}
		c.rlock.Unlock()

		c.bb = c.b.b
	}
	n := copy(p, c.bb)
	c.bb = c.bb[n:]

	return n, nil
}

var (
	errWouldBlock       = errors.New("would block")
	errConnectionClosed = errors.New("connection closed")
	errNoDeadlines      = errors.New("deadline not supported")
)

func (c *pipeConn) Close() error {
	c.wlock.Lock()
	if c.wclosed {
		c.wlock.Unlock()
		return errConnectionClosed
	}

	c.wclosed = true
	c.w.ch <- nil
	c.wlock.Unlock()

	c.pc.release()
	return nil
}

func (c *pipeConn) release() {
	c.rlock.Lock()

	releaseByteBuffer(c.b)
	c.b = nil
	c.bb = nil

	if !c.rclosed {
		c.rclosed = true
		for b := range c.r.ch {
			releaseByteBuffer(b)
			if b == nil {
				break
			}
		}
	}
	if c.r != nil {
		releasePipeChan(c.r)
		c.r = nil
		c.w = nil
	}

	c.rlock.Unlock()
}

func (c *pipeConn) LocalAddr() net.Addr {
	return pipeAddr(0)
}

func (c *pipeConn) RemoteAddr() net.Addr {
	return pipeAddr(0)
}

func (c *pipeConn) SetDeadline(t time.Time) error {
	return errNoDeadlines
}

func (c *pipeConn) SetReadDeadline(t time.Time) error {
	return c.SetDeadline(t)
}

func (c *pipeConn) SetWriteDeadline(t time.Time) error {
	return c.SetDeadline(t)
}

type pipeAddr int

func (pipeAddr) Network() string {
	return "pipe"
}

func (pipeAddr) String() string {
	return "pipe"
}

type byteBuffer struct {
	b []byte
}

func acquireByteBuffer() *byteBuffer {
	return byteBufferPool.Get().(*byteBuffer)
}

func releaseByteBuffer(b *byteBuffer) {
	if b != nil {
		byteBufferPool.Put(b)
	}
}

var byteBufferPool = &sync.Pool{
	New: func() interface{} {
		return &byteBuffer{
			b: make([]byte, 1024),
		}
	},
}

func acquirePipeChan() *pipeChan {
	ch := pipeChanPool.Get().(*pipeChan)
	if len(ch.ch) > 0 {
		panic("BUG: non-empty pipeChan acquired")
	}
	return ch
}

func releasePipeChan(ch *pipeChan) {
	if len(ch.ch) > 0 {
		panic("BUG: non-empty pipeChan released")
	}
	pipeChanPool.Put(ch)
}

var pipeChanPool = &sync.Pool{
	New: func() interface{} {
		return &pipeChan{
			ch: make(chan *byteBuffer, 4),
		}
	},
}

type pipeChan struct {
	ch chan *byteBuffer
}
<commit_msg>typo fix<commit_after>package fasthttputil

import (
	"errors"
	"io"
	"net"
	"sync"
	"time"
)

// NewPipeConns returns new bi-directonal connection pipe.
func NewPipeConns() *PipeConns {
	ch1 := acquirePipeChan()
	ch2 := acquirePipeChan()

	pc := &PipeConns{}
	pc.c1.r = ch1
	pc.c1.w = ch2
	pc.c2.r = ch2
	pc.c2.w = ch1
	pc.c1.pc = pc
	pc.c2.pc = pc
	return pc
}

// PipeConns provides bi-directional connection pipe,
// which use in-process memory as a transport.
//
// PipeConns must be created by calling NewPipeConns.
//
// PipeConns has the following additional features comparing to connections
// returned from net.Pipe():
//
//   * It is faster.
//   * It buffers Write calls, so there is no need to have concurrent goroutine
//     calling Read in order to unblock each Write call.
type PipeConns struct {
	c1 pipeConn
	c2 pipeConn
}

// Conn1 returns the first end of bi-directional pipe.
//
// Data written to Conn1 may be read from Conn2.
// Data written to Conn2 may be read from Conn1.
func (pc *PipeConns) Conn1() net.Conn {
	return &pc.c1
}

// Conn2 returns the second end of bi-directional pipe.
//
// Data written to Conn2 may be read from Conn1.
// Data written to Conn1 may be read from Conn2.
func (pc *PipeConns) Conn2() net.Conn {
	return &pc.c2
}

func (pc *PipeConns) release() {
	pc.c1.wlock.Lock()
	pc.c2.wlock.Lock()
	mustRelease := pc.c1.wclosed && pc.c2.wclosed
	pc.c1.wlock.Unlock()
	pc.c2.wlock.Unlock()

	if mustRelease {
		pc.c1.release()
		pc.c2.release()
	}
}

type pipeConn struct {
	r  *pipeChan
	w  *pipeChan
	b  *byteBuffer
	bb []byte

	rlock   sync.Mutex
	rclosed bool

	wlock   sync.Mutex
	wclosed bool

	pc *PipeConns
}

func (c *pipeConn) Write(p []byte) (int, error) {
	b := acquireByteBuffer()
	b.b = append(b.b[:0], p...)

	c.wlock.Lock()
	if c.wclosed {
		c.wlock.Unlock()
		releaseByteBuffer(b)
		return 0, errConnectionClosed
	}
	c.w.ch <- b
	c.wlock.Unlock()

	return len(p), nil
}

func (c *pipeConn) Read(p []byte) (int, error) {
	mayBlock := true
	nn := 0
	for len(p) > 0 {
		n, err := c.read(p, mayBlock)
		nn += n
		if err != nil {
			if !mayBlock && err == errWouldBlock {
				err = nil
			}
			return nn, err
		}
		p = p[n:]
		mayBlock = false
	}

	return nn, nil
}

func (c *pipeConn) read(p []byte, mayBlock bool) (int, error) {
	if len(c.bb) == 0 {
		releaseByteBuffer(c.b)
		c.b = nil

		c.rlock.Lock()
		if c.rclosed {
			c.rlock.Unlock()
			return 0, io.EOF
		}

		if mayBlock {
			c.b = <-c.r.ch
		} else {
			select {
			case c.b = <-c.r.ch:
			default:
				c.rlock.Unlock()
				return 0, errWouldBlock
			}
		}

		if c.b == nil {
			c.rclosed = true
			c.rlock.Unlock()
			return 0, io.EOF
		}
		c.rlock.Unlock()

		c.bb = c.b.b
	}
	n := copy(p, c.bb)
	c.bb = c.bb[n:]

	return n, nil
}

var (
	errWouldBlock       = errors.New("would block")
	errConnectionClosed = errors.New("connection closed")
	errNoDeadlines      = errors.New("deadline not supported")
)

func (c *pipeConn) Close() error {
	c.wlock.Lock()
	if c.wclosed {
		c.wlock.Unlock()
		return errConnectionClosed
	}

	c.wclosed = true
	c.w.ch <- nil
	c.wlock.Unlock()

	c.pc.release()
	return nil
}

func (c *pipeConn) release() {
	c.rlock.Lock()

	releaseByteBuffer(c.b)
	c.b = nil
	c.bb = nil

	if !c.rclosed {
		c.rclosed = true
		for b := range c.r.ch {
			releaseByteBuffer(b)
			if b == nil {
				break
			}
		}
	}
	if c.r != nil {
		releasePipeChan(c.r)
		c.r = nil
		c.w = nil
	}

	c.rlock.Unlock()
}

func (c *pipeConn) LocalAddr() net.Addr {
	return pipeAddr(0)
}

func (c *pipeConn) RemoteAddr() net.Addr {
	return pipeAddr(0)
}

func (c *pipeConn) SetDeadline(t time.Time) error {
	return errNoDeadlines
}

func (c *pipeConn) SetReadDeadline(t time.Time) error {
	return c.SetDeadline(t)
}

func (c *pipeConn) SetWriteDeadline(t time.Time) error {
	return c.SetDeadline(t)
}

type pipeAddr int

func (pipeAddr) Network() string {
	return "pipe"
}

func (pipeAddr) String() string {
	return "pipe"
}

type byteBuffer struct {
	b []byte
}

func acquireByteBuffer() *byteBuffer {
	return byteBufferPool.Get().(*byteBuffer)
}

func releaseByteBuffer(b *byteBuffer) {
	if b != nil {
		byteBufferPool.Put(b)
	}
}

var byteBufferPool = &sync.Pool{
	New: func() interface{} {
		return &byteBuffer{
			b: make([]byte, 1024),
		}
	},
}

func acquirePipeChan() *pipeChan {
	ch := pipeChanPool.Get().(*pipeChan)
	if len(ch.ch) > 0 {
		panic("BUG: non-empty pipeChan acquired")
	}
	return ch
}

func releasePipeChan(ch *pipeChan) {
	if len(ch.ch) > 0 {
		panic("BUG: non-empty pipeChan released")
	}
	pipeChanPool.Put(ch)
}

var pipeChanPool = &sync.Pool{
	New: func() interface{} {
		return &pipeChan{
			ch: make(chan *byteBuffer, 4),
		}
	},
}

type pipeChan struct {
	ch chan *byteBuffer
}
<|endoftext|>


<commit_before>package release

import (
	"sync"
	"time"

	"github.com/weaveworks/fluxy"
)

// InmemStore is an in-memory job store.
type InmemStore struct {
	mtx    sync.RWMutex
	jobs   map[flux.ReleaseID]flux.ReleaseJob
	oldest time.Duration
}

var _ flux.ReleaseJobStore = &InmemStore{}

// NewInmemStore returns a usable in-mem job store.
func NewInmemStore(oldest time.Duration) *InmemStore {
	return &InmemStore{
		jobs:   map[flux.ReleaseID]flux.ReleaseJob{},
		oldest: oldest,
	}
}

// GetJob implements JobStore.
func (s *InmemStore) GetJob(inst flux.InstanceID, id flux.ReleaseID) (flux.ReleaseJob, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()
	job, ok := s.jobs[id]
	if !ok && job.Instance == inst {
		return flux.ReleaseJob{}, flux.ErrNoSuchReleaseJob
	}
	return job, nil
}

// PutJob implements JobStore.
func (s *InmemStore) PutJob(inst flux.InstanceID, spec flux.ReleaseJobSpec) (flux.ReleaseID, error) {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	id := flux.NewReleaseID()
	for _, exists := s.jobs[id]; exists; id = flux.NewReleaseID() {
		// in case of ID collision
	}

	s.jobs[id] = flux.ReleaseJob{
		Instance:  inst,
		Spec:      spec,
		ID:        id,
		Submitted: time.Now().UTC(),
	}
	return id, nil
}

// NextJob implements JobStore.
// It returns immediately. If no job is available, ErrNoJobAvailable is returned.
func (s *InmemStore) NextJob() (flux.ReleaseJob, error) {
	s.mtx.Lock()
	defer s.mtx.Unlock()

	var (
		candidate flux.ReleaseJob
		earliest  = time.Now().UTC()
	)
	for _, job := range s.jobs {
		if job.Claimed.IsZero() && job.Submitted.Before(earliest) {
			candidate = job
		}
	}

	if candidate.ID == "" {
		return flux.ReleaseJob{}, flux.ErrNoReleaseJobAvailable
	}

	candidate.Claimed = time.Now().UTC()
	s.jobs[candidate.ID] = candidate
	return candidate, nil
}

// UpdateJob implements JobStore.
func (s *InmemStore) UpdateJob(job flux.ReleaseJob) error {
	s.mtx.Lock()
	defer s.mtx.Unlock()
	s.jobs[job.ID] = job
	return nil
}

func (s *InmemStore) Heartbeat(id flux.ReleaseID) error {
	s.mtx.Lock()
	defer s.mtx.Unlock()
	job, ok := s.jobs[id]
	if !ok {
		return flux.ErrNoSuchReleaseJob
	}
	job.Heartbeat = time.Now().UTC()
	s.jobs[id] = job
	return nil
}

func (s *InmemStore) GC() error {
	s.mtx.Lock()
	defer s.mtx.Unlock()
	cutoff := time.Now().UTC().Add(-s.oldest)
	for id, job := range s.jobs {
		if job.IsFinished() && job.Finished.Before(cutoff) {
			delete(s.jobs, id)
		}
	}
	return nil
}
<commit_msg>Remove release.InmemStore as it is dead code<commit_after><|endoftext|>