<commit_before>// Copyright 2016 Stig Bakken (based on the works of Markus Lindenberg)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bufio"
	"flag"
	"fmt"
	"net/http"
	"os"
	"os/exec"
	"os/signal"
	"regexp"
	"strings"
	"syscall"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
)

const (
	namespace = "varnish_request"
)

type str_mapping struct {
	Pattern     *regexp.Regexp
	Replacement string
}

func main() {
	// TODO: add support for multiple Varnish instances (-S)
	var (
		listenAddress = flag.String("http.port", ":9169", "Host/port for HTTP server")
		metricsPath   = flag.String("http.metricsurl", "/metrics", "Prometheus metrics path")
		httpHost      = flag.String("varnish.host", "", "Virtual host to look for in Varnish logs (defaults to all hosts)")
		mappings      = flag.String("varnish.path-mappings", "", "Path mappings formatted like this: 'regexp->replace regex2->replace2'")
	)
	flag.Parse()

	// Listen to signals
	sigchan := make(chan os.Signal, 1)
	signal.Notify(sigchan, syscall.SIGTERM, syscall.SIGINT)

	// Set up 'varnishncsa' pipe
	cmdName := "varnishncsa"
	cmdArgs := buildVarnishncsaArgs(*httpHost)
	log.Infof("Running command: %v %v\n", cmdName, cmdArgs)
	cmd := exec.Command(cmdName, cmdArgs...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	scanner := bufio.NewScanner(cmdReader)

	path_mappings, err := parseMappings(*mappings)
	if err != nil {
		log.Fatal(err)
	}

	// Setup metrics
	varnishMessages := prometheus.NewCounter(prometheus.CounterOpts{
		Namespace: namespace,
		Name:      "exporter_log_messages",
		Help:      "Current total log messages received.",
	})
	err = prometheus.Register(varnishMessages)
	if err != nil {
		log.Fatal(err)
	}
	varnishParseFailures := prometheus.NewCounter(prometheus.CounterOpts{
		Namespace: namespace,
		Name:      "exporter_log_parse_failure",
		Help:      "Number of errors while parsing log messages.",
	})
	err = prometheus.Register(varnishParseFailures)
	if err != nil {
		log.Fatal(err)
	}
	var msgs int64

	go func() {
		for scanner.Scan() {
			varnishMessages.Inc()
			content := scanner.Text()
			msgs++
			metrics, labels, err := parseMessage(content, path_mappings)
			if err != nil {
				log.Error(err)
				continue
			}
			for _, metric := range metrics {
				var collector prometheus.Collector
				collector, err = prometheus.RegisterOrGet(prometheus.NewHistogramVec(prometheus.HistogramOpts{
					Namespace: namespace,
					Name:      metric.Name,
					Help:      fmt.Sprintf("Varnish request log value for %s", metric.Name),
				}, labels.Names))
				if err != nil {
					log.Error(err)
					continue
				}
				collector.(*prometheus.HistogramVec).WithLabelValues(labels.Values...).Observe(metric.Value)
			}
		}
	}()

	// Setup HTTP server
	http.Handle(*metricsPath, prometheus.Handler())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
             <title>Varnish Request Exporter</title>

Varnish Request Exporter

<a href='` + *metricsPath + `'>Metrics

             `))
	})

	go func() {
		log.Infof("Starting Server: %s", *listenAddress)
		log.Fatal(http.ListenAndServe(*listenAddress, nil))
	}()

	go func() {
		err = cmd.Start()
		if err != nil {
			log.Fatal(err)
		}
		err = cmd.Wait()
		if err != nil {
			log.Fatal(err)
		}
		log.Infof("varnishncsa command exited")
		log.Infof("Messages received: %d", msgs)
		os.Exit(0)
	}()

	s := <-sigchan
	log.Infof("Received %v, terminating", s)
	log.Infof("Messages received: %d", msgs)

	os.Exit(0)
}

func parseMappings(input string) (mappings []str_mapping, err error) {
	mappings = make([]str_mapping, 0)
	str_mappings := strings.Split(input, " ")
	for i := range str_mappings {
		onemapping := str_mappings[i]
		if len(onemapping) == 0 {
			continue
		}
		parts := strings.Split(onemapping, "->")
		if len(parts) != 2 {
			err = fmt.Errorf("URL mapping must have two elements separated by \"->\", got \"%s\"", onemapping)
			return
		}
		mappings = append(mappings, str_mapping{ regexp.MustCompile(parts[0]), parts[1] })
	}
	return
}

func buildVarnishncsaArgs(httpHost string) (args []string) {
	args = make([]string, 2, 4)
	args = append(args, "-F")
	if len(httpHost) == 0 {
		args = append(args, "time:%D method=\"%m\" status=%s path=\"%U\" host=\"%{host}i\"")
	} else {
		args = append(args, "time:%D method=\"%m\" status=%s path=\"%U\"")
		args = append(args, "-q")
		args = append(args, "ReqHeader:host eq \"" + httpHost + "\"")
	}
	return
}
<commit_msg>Change default port to 9151 (registered in the Prometheus wiki)<commit_after>// Copyright 2016 Stig Bakken (based on the works of Markus Lindenberg)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bufio"
	"flag"
	"fmt"
	"net/http"
	"os"
	"os/exec"
	"os/signal"
	"regexp"
	"strings"
	"syscall"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
)

const (
	namespace = "varnish_request"
)

type str_mapping struct {
	Pattern     *regexp.Regexp
	Replacement string
}

func main() {
	// TODO: add support for multiple Varnish instances (-S)
	var (
		listenAddress = flag.String("http.port", ":9151", "Host/port for HTTP server")
		metricsPath   = flag.String("http.metricsurl", "/metrics", "Prometheus metrics path")
		httpHost      = flag.String("varnish.host", "", "Virtual host to look for in Varnish logs (defaults to all hosts)")
		mappings      = flag.String("varnish.path-mappings", "", "Path mappings formatted like this: 'regexp->replace regex2->replace2'")
	)
	flag.Parse()

	// Listen to signals
	sigchan := make(chan os.Signal, 1)
	signal.Notify(sigchan, syscall.SIGTERM, syscall.SIGINT)

	// Set up 'varnishncsa' pipe
	cmdName := "varnishncsa"
	cmdArgs := buildVarnishncsaArgs(*httpHost)
	log.Infof("Running command: %v %v\n", cmdName, cmdArgs)
	cmd := exec.Command(cmdName, cmdArgs...)
	cmdReader, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	scanner := bufio.NewScanner(cmdReader)

	path_mappings, err := parseMappings(*mappings)
	if err != nil {
		log.Fatal(err)
	}

	// Setup metrics
	varnishMessages := prometheus.NewCounter(prometheus.CounterOpts{
		Namespace: namespace,
		Name:      "exporter_log_messages",
		Help:      "Current total log messages received.",
	})
	err = prometheus.Register(varnishMessages)
	if err != nil {
		log.Fatal(err)
	}
	varnishParseFailures := prometheus.NewCounter(prometheus.CounterOpts{
		Namespace: namespace,
		Name:      "exporter_log_parse_failure",
		Help:      "Number of errors while parsing log messages.",
	})
	err = prometheus.Register(varnishParseFailures)
	if err != nil {
		log.Fatal(err)
	}
	var msgs int64

	go func() {
		for scanner.Scan() {
			varnishMessages.Inc()
			content := scanner.Text()
			msgs++
			metrics, labels, err := parseMessage(content, path_mappings)
			if err != nil {
				log.Error(err)
				continue
			}
			for _, metric := range metrics {
				var collector prometheus.Collector
				collector, err = prometheus.RegisterOrGet(prometheus.NewHistogramVec(prometheus.HistogramOpts{
					Namespace: namespace,
					Name:      metric.Name,
					Help:      fmt.Sprintf("Varnish request log value for %s", metric.Name),
				}, labels.Names))
				if err != nil {
					log.Error(err)
					continue
				}
				collector.(*prometheus.HistogramVec).WithLabelValues(labels.Values...).Observe(metric.Value)
			}
		}
	}()

	// Setup HTTP server
	http.Handle(*metricsPath, prometheus.Handler())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
             <title>Varnish Request Exporter</title>

Varnish Request Exporter

<a href='` + *metricsPath + `'>Metrics

             `))
	})

	go func() {
		log.Infof("Starting Server: %s", *listenAddress)
		log.Fatal(http.ListenAndServe(*listenAddress, nil))
	}()

	go func() {
		err = cmd.Start()
		if err != nil {
			log.Fatal(err)
		}
		err = cmd.Wait()
		if err != nil {
			log.Fatal(err)
		}
		log.Infof("varnishncsa command exited")
		log.Infof("Messages received: %d", msgs)
		os.Exit(0)
	}()

	s := <-sigchan
	log.Infof("Received %v, terminating", s)
	log.Infof("Messages received: %d", msgs)

	os.Exit(0)
}

func parseMappings(input string) (mappings []str_mapping, err error) {
	mappings = make([]str_mapping, 0)
	str_mappings := strings.Split(input, " ")
	for i := range str_mappings {
		onemapping := str_mappings[i]
		if len(onemapping) == 0 {
			continue
		}
		parts := strings.Split(onemapping, "->")
		if len(parts) != 2 {
			err = fmt.Errorf("URL mapping must have two elements separated by \"->\", got \"%s\"", onemapping)
			return
		}
		mappings = append(mappings, str_mapping{ regexp.MustCompile(parts[0]), parts[1] })
	}
	return
}

func buildVarnishncsaArgs(httpHost string) (args []string) {
	args = make([]string, 2, 4)
	args = append(args, "-F")
	if len(httpHost) == 0 {
		args = append(args, "time:%D method=\"%m\" status=%s path=\"%U\" host=\"%{host}i\"")
	} else {
		args = append(args, "time:%D method=\"%m\" status=%s path=\"%U\"")
		args = append(args, "-q")
		args = append(args, "ReqHeader:host eq \"" + httpHost + "\"")
	}
	return
}
<|endoftext|>


<commit_before>/**
 * (C) Copyright 2014, Deft Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dlshared

import "testing"
import "fmt"

const (
	EmailTestAccessKeyId = "HUH?"
	EmailTestSecretAccessKey = "WHAT?"
	EmailTestFrom = "Me <noreply@someplace.com>"
	EmailTestTo = "you@someplace.com"
)

// These tests are difficult to run in an open source repo because they require aws credentials.
func TestAwsTextEmail(t *testing.T) {
	/*
	logger := Logger { Prefix: "test", Appenders: []Appender{ LevelFilter(Debug, StdErrAppender()) } }

	emailDs := NewAwsEmailDs(EmailTestAccessKeyId, EmailTestSecretAccessKey, NewDefaultHttpRequestClient(), logger)

	response, err := emailDs.SendTextEmailToOneAddress(EmailTestFrom, EmailTestTo, "test subject", "this is a test text body")

	if err != nil {
		t.Errorf("TestAwsTextEmail is broken: %v")
		return
	}

	fmt.Println("message id:", response.(*AwsEmailResponse).MessageId)
	fmt.Println("request id:", response.(*AwsEmailResponse).RequestId)
	fmt.Println("status code:", response.(*AwsEmailResponse).HttpStatusCode)
	*/
}

func TestAwsHtmlEmail(t *testing.T) {
	/*
	bodyHtml := `

Test Link

	`
	logger := Logger { Prefix: "test", Appenders: []Appender{ LevelFilter(Debug, StdErrAppender()) } }

	emailDs := NewAwsEmailDs(EmailTestAccessKeyId, EmailTestSecretAccessKey, NewDefaultHttpRequestClient(), logger)

	response, err := emailDs.SendHtmlEmailToOneAddress(EmailTestFrom, EmailTestTo, "test subject", bodyHtml, "Test Link: http://deftlabs.com")

	if err != nil {
		t.Errorf("TestAwsHtmlEmail is broken: %v")
		return
	}

	fmt.Println("message id:", response.(*AwsEmailResponse).MessageId)
	fmt.Println("request id:", response.(*AwsEmailResponse).RequestId)
	fmt.Println("status code:", response.(*AwsEmailResponse).HttpStatusCode)
	*/
}

<commit_msg>fixed build<commit_after>/**
 * (C) Copyright 2014, Deft Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dlshared

import (
	// "fmt"
	"testing"
)

const (
	EmailTestAccessKeyId = "HUH?"
	EmailTestSecretAccessKey = "WHAT?"
	EmailTestFrom = "Me <noreply@someplace.com>"
	EmailTestTo = "you@someplace.com"
)

// These tests are difficult to run in an open source repo because they require aws credentials.
func TestAwsTextEmail(t *testing.T) {
	/*
	logger := Logger { Prefix: "test", Appenders: []Appender{ LevelFilter(Debug, StdErrAppender()) } }

	emailDs := NewAwsEmailDs(EmailTestAccessKeyId, EmailTestSecretAccessKey, NewDefaultHttpRequestClient(), logger)

	response, err := emailDs.SendTextEmailToOneAddress(EmailTestFrom, EmailTestTo, "test subject", "this is a test text body")

	if err != nil {
		t.Errorf("TestAwsTextEmail is broken: %v")
		return
	}

	fmt.Println("message id:", response.(*AwsEmailResponse).MessageId)
	fmt.Println("request id:", response.(*AwsEmailResponse).RequestId)
	fmt.Println("status code:", response.(*AwsEmailResponse).HttpStatusCode)
	*/
}

func TestAwsHtmlEmail(t *testing.T) {
	/*
	bodyHtml := `

Test Link

	`
	logger := Logger { Prefix: "test", Appenders: []Appender{ LevelFilter(Debug, StdErrAppender()) } }

	emailDs := NewAwsEmailDs(EmailTestAccessKeyId, EmailTestSecretAccessKey, NewDefaultHttpRequestClient(), logger)

	response, err := emailDs.SendHtmlEmailToOneAddress(EmailTestFrom, EmailTestTo, "test subject", bodyHtml, "Test Link: http://deftlabs.com")

	if err != nil {
		t.Errorf("TestAwsHtmlEmail is broken: %v")
		return
	}

	fmt.Println("message id:", response.(*AwsEmailResponse).MessageId)
	fmt.Println("request id:", response.(*AwsEmailResponse).RequestId)
	fmt.Println("status code:", response.(*AwsEmailResponse).HttpStatusCode)
	*/
}

<|endoftext|>


<commit_before>package walking

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"time"

	"github.com/containerd/containerd/archive"
	"github.com/containerd/containerd/archive/compression"
	"github.com/containerd/containerd/content"
	"github.com/containerd/containerd/diff"
	"github.com/containerd/containerd/errdefs"
	"github.com/containerd/containerd/images"
	"github.com/containerd/containerd/log"
	"github.com/containerd/containerd/metadata"
	"github.com/containerd/containerd/mount"
	"github.com/containerd/containerd/platforms"
	"github.com/containerd/containerd/plugin"
	digest "github.com/opencontainers/go-digest"
	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"golang.org/x/net/context"
)

func init() {
	plugin.Register(&plugin.Registration{
		Type: plugin.DiffPlugin,
		ID:   "walking",
		Requires: []plugin.Type{
			plugin.MetadataPlugin,
		},
		InitFn: func(ic *plugin.InitContext) (interface{}, error) {
			md, err := ic.Get(plugin.MetadataPlugin)
			if err != nil {
				return nil, err
			}

			ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec())
			return NewWalkingDiff(md.(*metadata.DB).ContentStore())
		},
	})
}

type walkingDiff struct {
	store content.Store
}

var emptyDesc = ocispec.Descriptor{}

// NewWalkingDiff is a generic implementation of diff.Differ.
// NewWalkingDiff is expected to work with any filesystem.
func NewWalkingDiff(store content.Store) (diff.Differ, error) {
	return &walkingDiff{
		store: store,
	}, nil
}

// Apply applies the content associated with the provided digests onto the
// provided mounts. Archive content will be extracted and decompressed if
// necessary.
func (s *walkingDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount) (d ocispec.Descriptor, err error) {
	t1 := time.Now()
	defer func() {
		if err == nil {
			log.G(ctx).WithFields(logrus.Fields{
				"d":     time.Now().Sub(t1),
				"dgst":  desc.Digest,
				"size":  desc.Size,
				"media": desc.MediaType,
			}).Debugf("diff applied")
		}
	}()
	var isCompressed bool
	switch desc.MediaType {
	case ocispec.MediaTypeImageLayer, images.MediaTypeDockerSchema2Layer:
	case ocispec.MediaTypeImageLayerGzip, images.MediaTypeDockerSchema2LayerGzip:
		isCompressed = true
	default:
		// Still apply all generic media types *.tar[.+]gzip and *.tar
		if strings.HasSuffix(desc.MediaType, ".tar.gzip") || strings.HasSuffix(desc.MediaType, ".tar+gzip") {
			isCompressed = true
		} else if !strings.HasSuffix(desc.MediaType, ".tar") {
			return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", desc.MediaType)
		}
	}

	dir, err := ioutil.TempDir("", "extract-")
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to create temporary directory")
	}
	defer os.Remove(dir)

	if err := mount.All(mounts, dir); err != nil {
		return emptyDesc, errors.Wrap(err, "failed to mount")
	}
	defer mount.Unmount(dir, 0)

	ra, err := s.store.ReaderAt(ctx, desc.Digest)
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to get reader from content store")
	}
	defer ra.Close()

	r := content.NewReader(ra)
	if isCompressed {
		ds, err := compression.DecompressStream(r)
		if err != nil {
			return emptyDesc, err
		}
		defer ds.Close()
		r = ds
	}

	digester := digest.Canonical.Digester()
	rc := &readCounter{
		r: io.TeeReader(r, digester.Hash()),
	}

	if _, err := archive.Apply(ctx, dir, rc); err != nil {
		return emptyDesc, err
	}

	// Read any trailing data
	if _, err := io.Copy(ioutil.Discard, rc); err != nil {
		return emptyDesc, err
	}

	return ocispec.Descriptor{
		MediaType: ocispec.MediaTypeImageLayer,
		Size:      rc.c,
		Digest:    digester.Digest(),
	}, nil
}

// DiffMounts creates a diff between the given mounts and uploads the result
// to the content store.
func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt) (d ocispec.Descriptor, err error) {
	var config diff.Config
	for _, opt := range opts {
		if err := opt(&config); err != nil {
			return emptyDesc, err
		}
	}

	if config.MediaType == "" {
		config.MediaType = ocispec.MediaTypeImageLayerGzip
	}

	var isCompressed bool
	switch config.MediaType {
	case ocispec.MediaTypeImageLayer:
	case ocispec.MediaTypeImageLayerGzip:
		isCompressed = true
	default:
		return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", config.MediaType)
	}
	aDir, err := ioutil.TempDir("", "left-")
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to create temporary directory")
	}
	defer os.Remove(aDir)

	bDir, err := ioutil.TempDir("", "right-")
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to create temporary directory")
	}
	defer os.Remove(bDir)

	if err := mount.All(lower, aDir); err != nil {
		return emptyDesc, errors.Wrap(err, "failed to mount")
	}
	defer mount.Unmount(aDir, 0)

	if err := mount.All(upper, bDir); err != nil {
		return emptyDesc, errors.Wrap(err, "failed to mount")
	}
	defer mount.Unmount(bDir, 0)

	var newReference bool
	if config.Reference == "" {
		newReference = true
		config.Reference = uniqueRef()
	}

	cw, err := s.store.Writer(ctx, config.Reference, 0, "")
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to open writer")
	}
	defer func() {
		if err != nil {
			cw.Close()
			if newReference {
				if err := s.store.Abort(ctx, config.Reference); err != nil {
					log.G(ctx).WithField("ref", config.Reference).Warnf("failed to delete diff upload")
				}
			}
		}
	}()
	if !newReference {
		if err := cw.Truncate(0); err != nil {
			return emptyDesc, err
		}
	}

	if isCompressed {
		dgstr := digest.SHA256.Digester()
		compressed, err := compression.CompressStream(cw, compression.Gzip)
		if err != nil {
			return emptyDesc, errors.Wrap(err, "failed to get compressed stream")
		}
		err = archive.WriteDiff(ctx, io.MultiWriter(compressed, dgstr.Hash()), aDir, bDir)
		compressed.Close()
		if err != nil {
			return emptyDesc, errors.Wrap(err, "failed to write compressed diff")
		}

		if config.Labels == nil {
			config.Labels = map[string]string{}
		}
		config.Labels["containerd.io/uncompressed"] = dgstr.Digest().String()
	} else {
		if err = archive.WriteDiff(ctx, cw, aDir, bDir); err != nil {
			return emptyDesc, errors.Wrap(err, "failed to write diff")
		}
	}

	var commitopts []content.Opt
	if config.Labels != nil {
		commitopts = append(commitopts, content.WithLabels(config.Labels))
	}

	dgst := cw.Digest()
	if err := cw.Commit(ctx, 0, dgst, commitopts...); err != nil {
		return emptyDesc, errors.Wrap(err, "failed to commit")
	}

	info, err := s.store.Info(ctx, dgst)
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to get info from content store")
	}

	return ocispec.Descriptor{
		MediaType: config.MediaType,
		Size:      info.Size,
		Digest:    info.Digest,
	}, nil
}

type readCounter struct {
	r io.Reader
	c int64
}

func (rc *readCounter) Read(p []byte) (n int, err error) {
	n, err = rc.r.Read(p)
	rc.c += int64(n)
	return
}

func uniqueRef() string {
	t := time.Now()
	var b [3]byte
	// Ignore read failures, just decreases uniqueness
	rand.Read(b[:])
	return fmt.Sprintf("%d-%s", t.UnixNano(), base64.URLEncoding.EncodeToString(b[:]))
}
<commit_msg>output error when unmount fail in diff.Apply<commit_after>package walking

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"time"

	"github.com/containerd/containerd/archive"
	"github.com/containerd/containerd/archive/compression"
	"github.com/containerd/containerd/content"
	"github.com/containerd/containerd/diff"
	"github.com/containerd/containerd/errdefs"
	"github.com/containerd/containerd/images"
	"github.com/containerd/containerd/log"
	"github.com/containerd/containerd/metadata"
	"github.com/containerd/containerd/mount"
	"github.com/containerd/containerd/platforms"
	"github.com/containerd/containerd/plugin"
	digest "github.com/opencontainers/go-digest"
	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"golang.org/x/net/context"
)

func init() {
	plugin.Register(&plugin.Registration{
		Type: plugin.DiffPlugin,
		ID:   "walking",
		Requires: []plugin.Type{
			plugin.MetadataPlugin,
		},
		InitFn: func(ic *plugin.InitContext) (interface{}, error) {
			md, err := ic.Get(plugin.MetadataPlugin)
			if err != nil {
				return nil, err
			}

			ic.Meta.Platforms = append(ic.Meta.Platforms, platforms.DefaultSpec())
			return NewWalkingDiff(md.(*metadata.DB).ContentStore())
		},
	})
}

type walkingDiff struct {
	store content.Store
}

var emptyDesc = ocispec.Descriptor{}

// NewWalkingDiff is a generic implementation of diff.Differ.
// NewWalkingDiff is expected to work with any filesystem.
func NewWalkingDiff(store content.Store) (diff.Differ, error) {
	return &walkingDiff{
		store: store,
	}, nil
}

// Apply applies the content associated with the provided digests onto the
// provided mounts. Archive content will be extracted and decompressed if
// necessary.
func (s *walkingDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount) (d ocispec.Descriptor, err error) {
	t1 := time.Now()
	defer func() {
		if err == nil {
			log.G(ctx).WithFields(logrus.Fields{
				"d":     time.Now().Sub(t1),
				"dgst":  desc.Digest,
				"size":  desc.Size,
				"media": desc.MediaType,
			}).Debugf("diff applied")
		}
	}()
	var isCompressed bool
	switch desc.MediaType {
	case ocispec.MediaTypeImageLayer, images.MediaTypeDockerSchema2Layer:
	case ocispec.MediaTypeImageLayerGzip, images.MediaTypeDockerSchema2LayerGzip:
		isCompressed = true
	default:
		// Still apply all generic media types *.tar[.+]gzip and *.tar
		if strings.HasSuffix(desc.MediaType, ".tar.gzip") || strings.HasSuffix(desc.MediaType, ".tar+gzip") {
			isCompressed = true
		} else if !strings.HasSuffix(desc.MediaType, ".tar") {
			return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", desc.MediaType)
		}
	}

	dir, err := ioutil.TempDir("", "extract-")
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to create temporary directory")
	}
	// We change RemoveAll to Remove so that we either leak a temp dir
	// if it fails but not RM snapshot data. refer to #1868 #1785
	defer os.Remove(dir)

	if err := mount.All(mounts, dir); err != nil {
		return emptyDesc, errors.Wrap(err, "failed to mount")
	}
	defer func() {
		if uerr := mount.Unmount(dir, 0); uerr != nil {
			if err == nil {
				err = uerr
			}
		}
	}()

	ra, err := s.store.ReaderAt(ctx, desc.Digest)
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to get reader from content store")
	}
	defer ra.Close()

	r := content.NewReader(ra)
	if isCompressed {
		ds, err := compression.DecompressStream(r)
		if err != nil {
			return emptyDesc, err
		}
		defer ds.Close()
		r = ds
	}

	digester := digest.Canonical.Digester()
	rc := &readCounter{
		r: io.TeeReader(r, digester.Hash()),
	}

	if _, err := archive.Apply(ctx, dir, rc); err != nil {
		return emptyDesc, err
	}

	// Read any trailing data
	if _, err := io.Copy(ioutil.Discard, rc); err != nil {
		return emptyDesc, err
	}

	return ocispec.Descriptor{
		MediaType: ocispec.MediaTypeImageLayer,
		Size:      rc.c,
		Digest:    digester.Digest(),
	}, nil
}

// DiffMounts creates a diff between the given mounts and uploads the result
// to the content store.
func (s *walkingDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt) (d ocispec.Descriptor, err error) {
	var config diff.Config
	for _, opt := range opts {
		if err := opt(&config); err != nil {
			return emptyDesc, err
		}
	}

	if config.MediaType == "" {
		config.MediaType = ocispec.MediaTypeImageLayerGzip
	}

	var isCompressed bool
	switch config.MediaType {
	case ocispec.MediaTypeImageLayer:
	case ocispec.MediaTypeImageLayerGzip:
		isCompressed = true
	default:
		return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", config.MediaType)
	}
	aDir, err := ioutil.TempDir("", "left-")
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to create temporary directory")
	}
	defer os.Remove(aDir)

	bDir, err := ioutil.TempDir("", "right-")
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to create temporary directory")
	}
	defer os.Remove(bDir)

	if err := mount.All(lower, aDir); err != nil {
		return emptyDesc, errors.Wrap(err, "failed to mount")
	}
	defer func() {
		if uerr := mount.Unmount(aDir, 0); uerr != nil {
			if err == nil {
				err = uerr
			}
		}
	}()

	if err := mount.All(upper, bDir); err != nil {
		return emptyDesc, errors.Wrap(err, "failed to mount")
	}
	defer func() {
		if uerr := mount.Unmount(bDir, 0); uerr != nil {
			if err == nil {
				err = uerr
			}
		}
	}()

	var newReference bool
	if config.Reference == "" {
		newReference = true
		config.Reference = uniqueRef()
	}

	cw, err := s.store.Writer(ctx, config.Reference, 0, "")
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to open writer")
	}
	defer func() {
		if err != nil {
			cw.Close()
			if newReference {
				if err := s.store.Abort(ctx, config.Reference); err != nil {
					log.G(ctx).WithField("ref", config.Reference).Warnf("failed to delete diff upload")
				}
			}
		}
	}()
	if !newReference {
		if err := cw.Truncate(0); err != nil {
			return emptyDesc, err
		}
	}

	if isCompressed {
		dgstr := digest.SHA256.Digester()
		compressed, err := compression.CompressStream(cw, compression.Gzip)
		if err != nil {
			return emptyDesc, errors.Wrap(err, "failed to get compressed stream")
		}
		err = archive.WriteDiff(ctx, io.MultiWriter(compressed, dgstr.Hash()), aDir, bDir)
		compressed.Close()
		if err != nil {
			return emptyDesc, errors.Wrap(err, "failed to write compressed diff")
		}

		if config.Labels == nil {
			config.Labels = map[string]string{}
		}
		config.Labels["containerd.io/uncompressed"] = dgstr.Digest().String()
	} else {
		if err = archive.WriteDiff(ctx, cw, aDir, bDir); err != nil {
			return emptyDesc, errors.Wrap(err, "failed to write diff")
		}
	}

	var commitopts []content.Opt
	if config.Labels != nil {
		commitopts = append(commitopts, content.WithLabels(config.Labels))
	}

	dgst := cw.Digest()
	if err := cw.Commit(ctx, 0, dgst, commitopts...); err != nil {
		return emptyDesc, errors.Wrap(err, "failed to commit")
	}

	info, err := s.store.Info(ctx, dgst)
	if err != nil {
		return emptyDesc, errors.Wrap(err, "failed to get info from content store")
	}

	return ocispec.Descriptor{
		MediaType: config.MediaType,
		Size:      info.Size,
		Digest:    info.Digest,
	}, nil
}

type readCounter struct {
	r io.Reader
	c int64
}

func (rc *readCounter) Read(p []byte) (n int, err error) {
	n, err = rc.r.Read(p)
	rc.c += int64(n)
	return
}

func uniqueRef() string {
	t := time.Now()
	var b [3]byte
	// Ignore read failures, just decreases uniqueness
	rand.Read(b[:])
	return fmt.Sprintf("%d-%s", t.UnixNano(), base64.URLEncoding.EncodeToString(b[:]))
}
<|endoftext|>


<commit_before>package algoliasearch

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"errors"
"time"
"reflect"
)

type Client struct {
  transport *Transport
}

func NewClient(appID, apiKey string) *Client {
  client := new(Client)
  client.transport = NewTransport(appID, apiKey)
  return client
}

func NewClientWithHosts(appID, apiKey string, hosts []string) *Client {
  client := new(Client)
  client.transport = NewTransportWithHosts(appID, apiKey, hosts)
  return client
}

func (c *Client) SetExtraHeader(key string, value string) {
  c.transport.setExtraHeader(key, value)
}

func (c *Client) SetTimeout(connectTimeout int, readTimeout int) {
  c.transport.setTimeout(time.Duration(connectTimeout) * time.Millisecond, time.Duration(readTimeout) * time.Millisecond)
}

func (c *Client) ListIndexes() (interface{}, error) {
     return c.transport.request("GET", "/1/indexes", nil, read)
}

func (c *Client) InitIndex(indexName string) *Index {
  return NewIndex(indexName, c)
}

func (c *Client) ListKeys() (interface{}, error) {
  return c.transport.request("GET", "/1/keys", nil, read)
}

func (c *Client) AddKey(acl, indexes []string, validity int, maxQueriesPerIPPerHour int, maxHitsPerQuery int) (interface{}, error) {
  body := make(map[string]interface{})
  body["acl"] = acl
  body["maxHitsPerQuery"] = maxHitsPerQuery
  body["maxQueriesPerIPPerHour"] = maxQueriesPerIPPerHour
  body["validity"] = validity
  body["indexes"] = indexes
  return c.AddKeyWithParam(body)
}

func (c *Client) AddKeyWithParam(params interface{}) (interface{}, error) {
  return c.transport.request("POST", "/1/keys/", params, read)
}

func (c *Client) UpdateKey(key string, acl, indexes []string, validity int, maxQueriesPerIPPerHour int, maxHitsPerQuery int) (interface{}, error) {
  body := make(map[string]interface{})
  body["acl"] = acl
  body["maxHitsPerQuery"] = maxHitsPerQuery
  body["maxQueriesPerIPPerHour"] = maxQueriesPerIPPerHour
  body["validity"] = validity
  body["indexes"] = indexes
  return c.UpdateKeyWithParam(key, body)
}

func (c *Client) UpdateKeyWithParam(key string, params interface{}) (interface{}, error) {
  return c.transport.request("PUT", "/1/keys/" + key, params, write)
}

func (c *Client) GetKey(key string) (interface{}, error) {
  return c.transport.request("GET", "/1/keys/" + key, nil, read)
}

func (c *Client) DeleteKey(key string) (interface{}, error) {
  return c.transport.request("DELETE", "/1/keys/" + key, nil, write)
}

func (c *Client) GetLogs(offset, length int, logType string) (interface{}, error) {
  body := make(map[string]interface{})
  body["offset"] = offset
  body["length"] = length
  body["type"] = logType
  return c.transport.request("GET", "/1/logs", body, write)
}

func (c *Client) GenerateSecuredApiKey(apiKey string, public interface{}, userToken ...string) (string, error) {
  if len(userToken) > 1 {
    return "", errors.New("Too many parameters")
  }
  key := []byte(apiKey)
  h := hmac.New(sha256.New, key)
  var userTokenStr string
  if len(userToken) == 1 {
    userTokenStr = userToken[0]
  } else {
    userTokenStr = ""
  }
  if reflect.TypeOf(public).Name() != "string" {
    public = c.transport.EncodeParams(public)
  }

  message := public.(string) + userTokenStr
  h.Write([]byte(message))
  return hex.EncodeToString(h.Sum(nil)), nil
}

func (c *Client) MultipleQueries(queries []interface{}, optionals ...string) (interface{}, error) {
  if len(optionals) > 2 {
    return "", errors.New("Too many parametters")
  }
  var nameKey string
  if len(optionals) >= 1 {
    nameKey = optionals[0]
  } else {
    nameKey = "indexName"
  }
  var strategy string = "none"
  if len(optionals) == 2 {
    strategy = optionals[1]
  }
  requests := make([]map[string]interface{}, len(queries))
  for i := range queries {
    requests[i] = make(map[string]interface{})
    requests[i]["indexName"] = queries[i].(map[string]interface{})[nameKey].(string)
    delete(queries[i].(map[string]interface{}), nameKey)
    requests[i]["params"] = c.transport.EncodeParams(queries[i])
  }
  body := make(map[string]interface{})
  body["requests"] = requests
  return c.transport.request("POST", "/1/indexes/*/queries?strategy=" + strategy, body, search)
}
<commit_msg>Expose the custom batch to allow batch on multiple indexes<commit_after>package algoliasearch

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"errors"
"time"
"reflect"
)

type Client struct {
  transport *Transport
}

func NewClient(appID, apiKey string) *Client {
  client := new(Client)
  client.transport = NewTransport(appID, apiKey)
  return client
}

func NewClientWithHosts(appID, apiKey string, hosts []string) *Client {
  client := new(Client)
  client.transport = NewTransportWithHosts(appID, apiKey, hosts)
  return client
}

func (c *Client) SetExtraHeader(key string, value string) {
  c.transport.setExtraHeader(key, value)
}

func (c *Client) SetTimeout(connectTimeout int, readTimeout int) {
  c.transport.setTimeout(time.Duration(connectTimeout) * time.Millisecond, time.Duration(readTimeout) * time.Millisecond)
}

func (c *Client) ListIndexes() (interface{}, error) {
     return c.transport.request("GET", "/1/indexes", nil, read)
}

func (c *Client) InitIndex(indexName string) *Index {
  return NewIndex(indexName, c)
}

func (c *Client) ListKeys() (interface{}, error) {
  return c.transport.request("GET", "/1/keys", nil, read)
}

func (c *Client) AddKey(acl, indexes []string, validity int, maxQueriesPerIPPerHour int, maxHitsPerQuery int) (interface{}, error) {
  body := make(map[string]interface{})
  body["acl"] = acl
  body["maxHitsPerQuery"] = maxHitsPerQuery
  body["maxQueriesPerIPPerHour"] = maxQueriesPerIPPerHour
  body["validity"] = validity
  body["indexes"] = indexes
  return c.AddKeyWithParam(body)
}

func (c *Client) AddKeyWithParam(params interface{}) (interface{}, error) {
  return c.transport.request("POST", "/1/keys/", params, read)
}

func (c *Client) UpdateKey(key string, acl, indexes []string, validity int, maxQueriesPerIPPerHour int, maxHitsPerQuery int) (interface{}, error) {
  body := make(map[string]interface{})
  body["acl"] = acl
  body["maxHitsPerQuery"] = maxHitsPerQuery
  body["maxQueriesPerIPPerHour"] = maxQueriesPerIPPerHour
  body["validity"] = validity
  body["indexes"] = indexes
  return c.UpdateKeyWithParam(key, body)
}

func (c *Client) UpdateKeyWithParam(key string, params interface{}) (interface{}, error) {
  return c.transport.request("PUT", "/1/keys/" + key, params, write)
}

func (c *Client) GetKey(key string) (interface{}, error) {
  return c.transport.request("GET", "/1/keys/" + key, nil, read)
}

func (c *Client) DeleteKey(key string) (interface{}, error) {
  return c.transport.request("DELETE", "/1/keys/" + key, nil, write)
}

func (c *Client) GetLogs(offset, length int, logType string) (interface{}, error) {
  body := make(map[string]interface{})
  body["offset"] = offset
  body["length"] = length
  body["type"] = logType
  return c.transport.request("GET", "/1/logs", body, write)
}

func (c *Client) GenerateSecuredApiKey(apiKey string, public interface{}, userToken ...string) (string, error) {
  if len(userToken) > 1 {
    return "", errors.New("Too many parameters")
  }
  key := []byte(apiKey)
  h := hmac.New(sha256.New, key)
  var userTokenStr string
  if len(userToken) == 1 {
    userTokenStr = userToken[0]
  } else {
    userTokenStr = ""
  }
  if reflect.TypeOf(public).Name() != "string" {
    public = c.transport.EncodeParams(public)
  }

  message := public.(string) + userTokenStr
  h.Write([]byte(message))
  return hex.EncodeToString(h.Sum(nil)), nil
}

func (c *Client) MultipleQueries(queries []interface{}, optionals ...string) (interface{}, error) {
  if len(optionals) > 2 {
    return "", errors.New("Too many parametters")
  }
  var nameKey string
  if len(optionals) >= 1 {
    nameKey = optionals[0]
  } else {
    nameKey = "indexName"
  }
  var strategy string = "none"
  if len(optionals) == 2 {
    strategy = optionals[1]
  }
  requests := make([]map[string]interface{}, len(queries))
  for i := range queries {
    requests[i] = make(map[string]interface{})
    requests[i]["indexName"] = queries[i].(map[string]interface{})[nameKey].(string)
    delete(queries[i].(map[string]interface{}), nameKey)
    requests[i]["params"] = c.transport.EncodeParams(queries[i])
  }
  body := make(map[string]interface{})
  body["requests"] = requests
  return c.transport.request("POST", "/1/indexes/*/queries?strategy=" + strategy, body, search)
}

func (i *Index) CustomBatch(queries interface{}) (interface{}, error) {
  request :=  make(map[string]interface{})
  request["requests"] = queries
  return i.client.transport.request("POST", "/1/indexes/*/batch", request, write)
}
<|endoftext|>


<commit_before>package apiserver

import (
	"context"
	"fmt"
	"github.com/openshift/origin/test/extended/operators"
	"io/ioutil"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/client-go/kubernetes"
	"net/http"
	"strings"
	"time"

	"github.com/onsi/ginkgo"
	"github.com/onsi/gomega"
	configv1 "github.com/openshift/api/config/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	types "k8s.io/apimachinery/pkg/types"
	"k8s.io/apimachinery/pkg/util/uuid"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/rest"
	"k8s.io/kubernetes/test/e2e/framework"
	e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"

	"github.com/openshift/origin/test/extended/scheme"
	"github.com/openshift/origin/test/extended/single_node"
	exutil "github.com/openshift/origin/test/extended/util"
	e2e "k8s.io/kubernetes/test/e2e/framework"
)

var _ = ginkgo.Describe("[Conformance][sig-sno][Serial] Cluster", func() {
	f := framework.NewDefaultFramework("cluster-resiliency")
	f.SkipNamespaceCreation = true
	f.SkipPrivilegedPSPBinding = true

	oc := exutil.NewCLIWithoutNamespace("cluster-resiliency")

	ginkgo.It("should allow a fast rollout of kube-apiserver with no pods restarts during API disruption", func() {
		controlPlaneTopology, _ := single_node.GetTopologies(f)

		if controlPlaneTopology != configv1.SingleReplicaTopologyMode {
			e2eskipper.Skipf("Test is only relevant for single replica topologies")
		}

		config, err := framework.LoadConfig()
		framework.ExpectNoError(err)

		setRESTConfigDefaults(config)
		restClient, err := rest.RESTClientFor(config)
		framework.ExpectNoError(err)

		httpClient := restClient.Client

		ginkgo.By("Making sure no previous rollout is in progress")
		clusterApiServer, err := oc.AdminOperatorClient().OperatorV1().KubeAPIServers().Get(context.Background(), "cluster", metav1.GetOptions{})
		framework.ExpectNoError(err)
		gomega.Expect(clusterApiServer.Status.NodeStatuses[0].TargetRevision).To(gomega.Equal(int32(0)))

		ginkgo.By("Initialize pods restart count")
		restartingContainers := make(map[operators.ContainerName]int)
		c, err := e2e.LoadClientset()
		gomega.Expect(err).NotTo(gomega.HaveOccurred())
		// This will just load the restartingContainers map with the current restart count
		// The current restart count is the baseline for validating that there was no restarts during the API rollout
		_ = GetRestartedPods(c, restartingContainers)

		ginkgo.By("Forcing API rollout")
		forceApiRollout(oc)

		ginkgo.By("Expecting API to become unavailable")
		wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
			ready, _, err := isApiReady(config, httpClient)
			return !ready, err
		})

		start := time.Now()

		ginkgo.By("Expecting API to become ready")
		wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
			ready, _, _ := isApiReady(config, httpClient)
			return ready, nil
		})

		end := time.Now()

		ginkgo.By("Measuring disruption duration time")
		disruptionDuration := end.Sub(start)
		// For more information: https://github.com/openshift/origin/pull/26337/files#r698435488
		gomega.Expect(disruptionDuration).To(gomega.BeNumerically("<", 40*time.Second),
			fmt.Sprintf("Total time of disruption is %v which is more than 40 seconds. ", disruptionDuration)+
				"Actual SLO for this is 60 seconds, yet we want to be notified about major regressions")

		ginkgo.By("with no pods restarts during API disruption")
		names := GetRestartedPods(c, restartingContainers)
		gomega.Expect(len(names)).To(gomega.Equal(0), "Some pods in got restarted during kube-apiserver rollout: %s", strings.Join(names, ", "))

		// Workaround for issues identified in https://bugzilla.redhat.com/show_bug.cgi?id=2059581
		// TODO: Remove this sleep once that bug is resolved
		time.Sleep(60 * time.Second)
	})

})

func GetRestartedPods(c *kubernetes.Clientset, restartingContainers map[operators.ContainerName]int) (names []string) {
	pods := operators.GetPodsWithFilter(c, []operators.PodFilter{operators.InCoreNamespaces, ignoreNamespaces})
	for _, pod := range pods {
		if pod.Status.Phase == corev1.PodSucceeded {
			continue
		}
		// This will just load the restartingContainers map with the current restart count
		if operators.HasExcessiveRestarts(pod, 1, restartingContainers) {
			key := fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
			names = append(names, key)
		}
	}
	return names
}

func setRESTConfigDefaults(config *rest.Config) {
	if config.GroupVersion == nil {
		config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"}
	}

	if config.NegotiatedSerializer == nil {
		config.NegotiatedSerializer = scheme.Codecs
	}
}

func forceApiRollout(oc *exutil.CLI) {
	redeploymentReason := fmt.Sprintf(`{"spec":{"forceRedeploymentReason":"resiliency-test-%v"}}`, uuid.NewUUID())

	_, err := oc.AdminOperatorClient().OperatorV1().KubeAPIServers().Patch(context.Background(), "cluster", types.MergePatchType,
		[]byte(redeploymentReason), metav1.PatchOptions{})
	gomega.Expect(err).NotTo(gomega.HaveOccurred())
}

func isApiReady(clusterConfig *rest.Config, httpClient *http.Client) (ready bool, reason string, err error) {
	resp, err := httpClient.Get(clusterConfig.Host + "/readyz")
	if resp != nil && resp.Body != nil {
		defer resp.Body.Close()
	}

	if err != nil {
		return false, "client failed to make the request", err
	}

	if resp.StatusCode < 200 || resp.StatusCode >= 400 {
		body, err := ioutil.ReadAll(resp.Body)
		if err == nil {
			return false, fmt.Sprintf("got status code %v from the server: %v", resp.Status, body), nil
		}

		return false, fmt.Sprintf("got status code %v from the server", resp.Status), err
	}

	return true, "kube-apiserver is ready", nil
}

func ignoreNamespaces(pod *corev1.Pod) bool {
	return !(strings.HasPrefix(pod.Namespace, "openshift-kube-apiserver") ||
		strings.HasPrefix(pod.Namespace, "openshift-kube-controller-manager")) // remove this once https://bugzilla.redhat.com/show_bug.cgi?id=2001330 is fixed
}
<commit_msg>MGMT-9440: Fix single node serial tests API crash<commit_after>package apiserver

import (
	"context"
	"fmt"
	"github.com/openshift/origin/test/extended/operators"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/client-go/kubernetes"
	"net/http"
	"strings"
	"time"

	"github.com/onsi/ginkgo"
	"github.com/onsi/gomega"
	configv1 "github.com/openshift/api/config/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	types "k8s.io/apimachinery/pkg/types"
	"k8s.io/apimachinery/pkg/util/uuid"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/rest"
	"k8s.io/kubernetes/test/e2e/framework"
	e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"

	"github.com/openshift/origin/test/extended/scheme"
	"github.com/openshift/origin/test/extended/single_node"
	exutil "github.com/openshift/origin/test/extended/util"
	e2e "k8s.io/kubernetes/test/e2e/framework"
)

var _ = ginkgo.Describe("[Conformance][sig-sno][Serial] Cluster", func() {
	f := framework.NewDefaultFramework("cluster-resiliency")
	f.SkipNamespaceCreation = true
	f.SkipPrivilegedPSPBinding = true

	oc := exutil.NewCLIWithoutNamespace("cluster-resiliency")

	ginkgo.It("should allow a fast rollout of kube-apiserver with no pods restarts during API disruption", func() {
		controlPlaneTopology, _ := single_node.GetTopologies(f)

		if controlPlaneTopology != configv1.SingleReplicaTopologyMode {
			e2eskipper.Skipf("Test is only relevant for single replica topologies")
		}

		config, err := framework.LoadConfig()
		framework.ExpectNoError(err)

		setRESTConfigDefaults(config)
		restClient, err := rest.RESTClientFor(config)
		framework.ExpectNoError(err)

		httpClient := restClient.Client

		ginkgo.By("Making sure no previous rollout is in progress")
		clusterApiServer, err := oc.AdminOperatorClient().OperatorV1().KubeAPIServers().Get(context.Background(), "cluster", metav1.GetOptions{})
		framework.ExpectNoError(err)
		gomega.Expect(clusterApiServer.Status.NodeStatuses[0].TargetRevision).To(gomega.Equal(int32(0)))

		ginkgo.By("Initialize pods restart count")
		restartingContainers := make(map[operators.ContainerName]int)
		c, err := e2e.LoadClientset()
		gomega.Expect(err).NotTo(gomega.HaveOccurred())
		// This will just load the restartingContainers map with the current restart count
		// The current restart count is the baseline for validating that there was no restarts during the API rollout
		_ = GetRestartedPods(c, restartingContainers)

		ginkgo.By("Forcing API rollout")
		forceApiRollout(oc)

		// We are taking the API down, this can often take more than a minute so we have provided a reasonably generous timeout.
		ginkgo.By("Expecting API to become unavailable")
		err = wait.PollImmediate(time.Second, 5*time.Minute, func() (bool, error) {
			ready := isApiReady(config, httpClient)
			return !ready, nil
		})

		gomega.Expect(err).NotTo(gomega.HaveOccurred(), "The API failed to become unavailable within the desired timeout")

		start := time.Now()

		ginkgo.By("Expecting API to become ready")
		err = wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
			ready := isApiReady(config, httpClient)
			return ready, nil
		})

		gomega.Expect(err).NotTo(gomega.HaveOccurred(), "The API failed to become available again within the desired timeout")

		end := time.Now()

		ginkgo.By("Measuring disruption duration time")
		disruptionDuration := end.Sub(start)
		// For more information: https://github.com/openshift/origin/pull/26337/files#r698435488
		gomega.Expect(disruptionDuration).To(gomega.BeNumerically("<", 40*time.Second),
			fmt.Sprintf("Total time of disruption is %v which is more than 40 seconds. ", disruptionDuration)+
				"Actual SLO for this is 60 seconds, yet we want to be notified about major regressions")

		ginkgo.By("with no pods restarts during API disruption")
		names := GetRestartedPods(c, restartingContainers)
		gomega.Expect(len(names)).To(gomega.Equal(0), "Some pods in got restarted during kube-apiserver rollout: %s", strings.Join(names, ", "))
	})

})

func GetRestartedPods(c *kubernetes.Clientset, restartingContainers map[operators.ContainerName]int) (names []string) {
	pods := operators.GetPodsWithFilter(c, []operators.PodFilter{operators.InCoreNamespaces, ignoreNamespaces})
	for _, pod := range pods {
		if pod.Status.Phase == corev1.PodSucceeded {
			continue
		}
		// This will just load the restartingContainers map with the current restart count
		if operators.HasExcessiveRestarts(pod, 1, restartingContainers) {
			key := fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
			names = append(names, key)
		}
	}
	return names
}

func setRESTConfigDefaults(config *rest.Config) {
	if config.GroupVersion == nil {
		config.GroupVersion = &schema.GroupVersion{Group: "", Version: "v1"}
	}

	if config.NegotiatedSerializer == nil {
		config.NegotiatedSerializer = scheme.Codecs
	}
}

func forceApiRollout(oc *exutil.CLI) {
	redeploymentReason := fmt.Sprintf(`{"spec":{"forceRedeploymentReason":"resiliency-test-%v"}}`, uuid.NewUUID())

	_, err := oc.AdminOperatorClient().OperatorV1().KubeAPIServers().Patch(context.Background(), "cluster", types.MergePatchType,
		[]byte(redeploymentReason), metav1.PatchOptions{})
	gomega.Expect(err).NotTo(gomega.HaveOccurred())
}

func isApiReady(clusterConfig *rest.Config, httpClient *http.Client) (ready bool) {
	resp, err := httpClient.Get(clusterConfig.Host + "/readyz")
	if resp != nil && resp.Body != nil {
		defer resp.Body.Close()
	}
	if err != nil || resp.StatusCode < 200 || resp.StatusCode >= 400 {
		return false
	}
	return true
}

func ignoreNamespaces(pod *corev1.Pod) bool {
	return !(strings.HasPrefix(pod.Namespace, "openshift-kube-apiserver") ||
		strings.HasPrefix(pod.Namespace, "openshift-kube-controller-manager")) // remove this once https://bugzilla.redhat.com/show_bug.cgi?id=2001330 is fixed
}
<|endoftext|>


<commit_before>package api

import (
	"encoding/json"
	"fmt"
	"github.com/olekukonko/tablewriter"
	"io/ioutil"
	"net/url"
	"os"
	"strconv"
	"time"
)

type Projects struct{}

// New creates a new project
func (projects *Projects) New(name string, language string, source string, script string) {

	image := &Image{}
	image.Name = name
	image.Language = language
	image.MakeBin = true
	image.Source = source
	image.SystemVolumes = true
	image.Buildable = true

	data, err := ioutil.ReadFile(script)
	if err == nil {
		image.Script = string(data)
	}

	b, err := json.Marshal(image)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	response, err := Cli.Postit(b, APIBase+"/image/new")
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}
}

// Delete deletes a project
func (projects *Projects) Delete(name string) {

	image := &Image{}
	image.Name = name
	b, err := json.Marshal(image)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	response, err := Cli.Postit(b, APIBase+"/image/remove")
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}
}

// NewFromImage creates a new project from an image
func (projects *Projects) NewFromImage(name string, imagePath string) {
	data, err := ioutil.ReadFile(imagePath)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	response, err := Cli.Postit(data, putURL+"/"+url.QueryEscape(name))
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}

}

type Project struct {
	ID          int
	Name        string
	Buildable   string
	Language    string
	Source      string
	BuildStatus string
	Filename    string
	Addon       string
	CreatedAt   time.Time
}

type ProjectsResponse struct {
	Title    string
	Error    string
	Projects []Project
}

// List lists all your projects
func (projects *Projects) List() {
	pr := ProjectsResponse{}
	err := Cli.GetJSON(APIBase+"/image/display", &pr)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
	} else {
		fmt.Println(GreenBold(pr.Title))

		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)

		table.SetHeader([]string{GreenBold("ID"), GreenBold("Name"),
			GreenBold("Buildable"), GreenBold("Language"), GreenBold("Source"),
			GreenBold("BuildStatus"), GreenBold("Filename"), GreenBold("Addon")})

		for i := 0; i < len(pr.Projects); i++ {
			sid := strconv.Itoa(pr.Projects[i].ID)

			table.Append([]string{sid,
				pr.Projects[i].Name,
				pr.Projects[i].Buildable,
				pr.Projects[i].Language,
				pr.Projects[i].Source,
				pr.Projects[i].BuildStatus,
				pr.Projects[i].Filename,
				pr.Projects[i].Addon,
			})
		}

		table.Render()
	}

}

// Log shows the log output for your project
func (projects *Projects) Log(name string) {
	image := &Image{}

	image.Name = name
	b, err := json.Marshal(image)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	response, err := Cli.Postit(b, APIBase+"/image/makelog")
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}

}

// Download a project root image
func (projects *Projects) Download(name string) {

	image := &Image{}
	image.Name = name
	b, err := json.Marshal(image)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	err = Cli.GrabFile(b, imageURL+"/get", name)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
	} else {
		fmt.Println(GreenBold("file saved"))
	}

}

// Upload uploads a project
func (projects *Projects) Upload(name string, binary string) {
	data, err := ioutil.ReadFile(binary)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	response, err := Cli.Postit(data, putURL+"/"+url.QueryEscape(name))
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}

}

type ManifestVolume struct {
	Id    int
	File  string
	Mount string
}

type ManifestProcess struct {
	Memory  int
	Kernel  string
	Hash    string
	Cmdline string
	Env     string
	Volumes []ManifestVolume
}

type Manifest struct {
	Processes []ManifestProcess
}

// Manifest is a json representation for your project
// useful for running things locally
func (projects *Projects) Manifest(name string) {
	m := Manifest{}
	err := Cli.GetJSON(APIBase+"/projects/manifest/"+name, &m)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
		return
	}

	// dupey-dupe
	js, err := json.Marshal(m)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
		return
	}

	err = ioutil.WriteFile(name+".manifest", js, 0644)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
	}

}
<commit_msg>multiboot<commit_after>package api

import (
	"encoding/json"
	"fmt"
	"github.com/olekukonko/tablewriter"
	"io/ioutil"
	"net/url"
	"os"
	"strconv"
	"time"
)

type Projects struct{}

// New creates a new project
func (projects *Projects) New(name string, language string, source string, script string) {

	image := &Image{}
	image.Name = name
	image.Language = language
	image.MakeBin = true
	image.Source = source
	image.SystemVolumes = true
	image.Buildable = true

	data, err := ioutil.ReadFile(script)
	if err == nil {
		image.Script = string(data)
	}

	b, err := json.Marshal(image)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	response, err := Cli.Postit(b, APIBase+"/image/new")
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}
}

// Delete deletes a project
func (projects *Projects) Delete(name string) {

	image := &Image{}
	image.Name = name
	b, err := json.Marshal(image)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	response, err := Cli.Postit(b, APIBase+"/image/remove")
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}
}

// NewFromImage creates a new project from an image
func (projects *Projects) NewFromImage(name string, imagePath string) {
	data, err := ioutil.ReadFile(imagePath)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	response, err := Cli.Postit(data, putURL+"/"+url.QueryEscape(name))
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}

}

type Project struct {
	ID          int
	Name        string
	Buildable   string
	Language    string
	Source      string
	BuildStatus string
	Filename    string
	Addon       string
	CreatedAt   time.Time
}

type ProjectsResponse struct {
	Title    string
	Error    string
	Projects []Project
}

// List lists all your projects
func (projects *Projects) List() {
	pr := ProjectsResponse{}
	err := Cli.GetJSON(APIBase+"/image/display", &pr)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
	} else {
		fmt.Println(GreenBold(pr.Title))

		table := tablewriter.NewWriter(os.Stdout)
		table.SetAutoFormatHeaders(false)

		table.SetHeader([]string{GreenBold("ID"), GreenBold("Name"),
			GreenBold("Buildable"), GreenBold("Language"), GreenBold("Source"),
			GreenBold("BuildStatus"), GreenBold("Filename"), GreenBold("Addon")})

		for i := 0; i < len(pr.Projects); i++ {
			sid := strconv.Itoa(pr.Projects[i].ID)

			table.Append([]string{sid,
				pr.Projects[i].Name,
				pr.Projects[i].Buildable,
				pr.Projects[i].Language,
				pr.Projects[i].Source,
				pr.Projects[i].BuildStatus,
				pr.Projects[i].Filename,
				pr.Projects[i].Addon,
			})
		}

		table.Render()
	}

}

// Log shows the log output for your project
func (projects *Projects) Log(name string) {
	image := &Image{}

	image.Name = name
	b, err := json.Marshal(image)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	response, err := Cli.Postit(b, APIBase+"/image/makelog")
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}

}

// Download a project root image
func (projects *Projects) Download(name string) {

	image := &Image{}
	image.Name = name
	b, err := json.Marshal(image)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	err = Cli.GrabFile(b, imageURL+"/get", name)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
	} else {
		fmt.Println(GreenBold("file saved"))
	}

}

// Upload uploads a project
func (projects *Projects) Upload(name string, binary string) {
	data, err := ioutil.ReadFile(binary)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	response, err := Cli.Postit(data, putURL+"/"+url.QueryEscape(name))
	if err != nil {
		fmt.Println(RedBold(response))
	} else {
		fmt.Println(GreenBold(response))
	}

}

type ManifestVolume struct {
	Id    int
	File  string
	Mount string
}

type ManifestProcess struct {
	Memory    int
	Kernel    string
	Multiboot bool
	Hash      string
	Cmdline   string
	Env       string
	Volumes   []ManifestVolume
}

type Manifest struct {
	Processes []ManifestProcess
}

// Manifest is a json representation for your project
// useful for running things locally
func (projects *Projects) Manifest(name string) {
	m := Manifest{}
	err := Cli.GetJSON(APIBase+"/projects/manifest/"+name, &m)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
		return
	}

	// dupey-dupe
	js, err := json.Marshal(m)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
		return
	}

	err = ioutil.WriteFile(name+".manifest", js, 0644)
	if err != nil {
		fmt.Println(RedBold(err.Error()))
	}

}
<|endoftext|>


<commit_before>package univedo

import (
	"bytes"
	"errors"

	"code.google.com/p/go.net/websocket"
	// TODO remove
	_ "fmt"
	"net/url"
)

// registeredRemoteObjects is a map from RO name to factory function
var registeredRemoteObjects = make(map[string]func(id uint64, s sender) RemoteObject)

// RegisterRemoteObject adds a remote object factory for a RO name
func RegisterRemoteObject(name string, factory func(id uint64, session sender) RemoteObject) {
	registeredRemoteObjects[name] = factory
}

// A Connection with an univedo server
type Connection struct {
	ws            *websocket.Conn
	urologin      RemoteObject
	remoteObjects map[uint64]RemoteObject
}

// originForURL returns an origin matching the given URL
func originForURL(s string) (string, error) {
	u, err := url.Parse(s)
	if err != nil {
		return "", err
	}
	origin := &url.URL{Scheme: "http", Host: u.Host}
	return origin.String(), nil
}

// Dial opens a new connection with an univedo server
func Dial(url string) (*Connection, error) {
	// Extract the origin from the URL
	origin, err := originForURL(url)
	if err != nil {
		return nil, err
	}

	// Dial the websocket
	url += "v1"
	ws, err := websocket.Dial(url, "", origin)
	if err != nil {
		return nil, err
	}

	c := &Connection{ws: ws, remoteObjects: make(map[uint64]RemoteObject)}
	go func() {
		// TODO error handling
		err := c.handleWebsocket()
		/*		fmt.Printf("%s\n", err.Error())*/
		_ = err
	}()

	// Login
	c.urologin = NewBasicRO(0, c)
	c.remoteObjects[0] = c.urologin

	return c, nil
}

// Close the connection
func (c *Connection) Close() {
	c.ws.Close()
}

// GetSession connects to a bucket with credentials
func (c *Connection) GetSession(bucket string, creds map[string]interface{}) (*Session, error) {
	iSession, err := c.urologin.CallROM("getSession", bucket, creds)
	if err != nil {
		return nil, err
	}
	session, ok := iSession.(*Session)
	if !ok {
		return nil, errors.New("getSession did not return a remote object")
	}
	return session, nil
}

func (c *Connection) sendMessage(data ...interface{}) error {
	m := &message{buffer: &bytes.Buffer{}}
	for _, v := range data {
		m.send(v)
	}
	return websocket.Message.Send(c.ws, m.buffer.Bytes())
}

func (c *Connection) handleWebsocket() error {
	for {
		var buffer []byte
		err := websocket.Message.Receive(c.ws, &buffer)

		if err != nil {
			return err
		}

		msg := &message{buffer: bytes.NewBuffer(buffer), createRO: c.receiveRO}

		iRoID, err := msg.read()
		if err != nil {
			return err
		}
		roID, ok := iRoID.(uint64)
		if !ok {
			return errors.New("ro id should be int")
		}

		ro := c.remoteObjects[roID]
		if ro == nil {
			return errors.New("ro not known")
		}

		var data []interface{}
		for !msg.empty() {
			v, err := msg.read()
			if err != nil {
				return err
			}
			data = append(data, v)
		}

		err = ro.receive(data)
		if err != nil {
			return err
		}
	}
}

func (c *Connection) receiveRO(id uint64, name string) interface{} {
	var ro RemoteObject
	factory := registeredRemoteObjects[name]
	if factory != nil {
		ro = factory(id, c)
	} else {
		ro = NewBasicRO(id, c)
	}
	c.remoteObjects[id] = ro
	return ro
}
<commit_msg>This commit allows univedo uri's w/o trailing /<commit_after>package univedo

import (
	"bytes"
	"errors"
	"strings"

	"code.google.com/p/go.net/websocket"
	// TODO remove
	_ "fmt"
	"net/url"
)

// registeredRemoteObjects is a map from RO name to factory function
var registeredRemoteObjects = make(map[string]func(id uint64, s sender) RemoteObject)

// RegisterRemoteObject adds a remote object factory for a RO name
func RegisterRemoteObject(name string, factory func(id uint64, session sender) RemoteObject) {
	registeredRemoteObjects[name] = factory
}

// A Connection with an univedo server
type Connection struct {
	ws            *websocket.Conn
	urologin      RemoteObject
	remoteObjects map[uint64]RemoteObject
}

// originForURL returns an origin matching the given URL
func originForURL(s string) (string, error) {
	u, err := url.Parse(s)
	if err != nil {
		return "", err
	}
	origin := &url.URL{Scheme: "http", Host: u.Host}
	return origin.String(), nil
}

// Dial opens a new connection with an univedo server
func Dial(url string) (*Connection, error) {
	// Extract the origin from the URL
	origin, err := originForURL(url)
	if err != nil {
		return nil, err
	}

	// Dial the websocket
	if !strings.HasSuffix(url, "/") {
		url += "/"
	}

	url += "v1"
	ws, err := websocket.Dial(url, "", origin)
	if err != nil {
		return nil, err
	}

	c := &Connection{ws: ws, remoteObjects: make(map[uint64]RemoteObject)}
	go func() {
		// TODO error handling
		err := c.handleWebsocket()
		/*		fmt.Printf("%s\n", err.Error())*/
		_ = err
	}()

	// Login
	c.urologin = NewBasicRO(0, c)
	c.remoteObjects[0] = c.urologin

	return c, nil
}

// Close the connection
func (c *Connection) Close() {
	c.ws.Close()
}

// GetSession connects to a bucket with credentials
func (c *Connection) GetSession(bucket string, creds map[string]interface{}) (*Session, error) {
	iSession, err := c.urologin.CallROM("getSession", bucket, creds)
	if err != nil {
		return nil, err
	}
	session, ok := iSession.(*Session)
	if !ok {
		return nil, errors.New("getSession did not return a remote object")
	}
	return session, nil
}

func (c *Connection) sendMessage(data ...interface{}) error {
	m := &message{buffer: &bytes.Buffer{}}
	for _, v := range data {
		m.send(v)
	}
	return websocket.Message.Send(c.ws, m.buffer.Bytes())
}

func (c *Connection) handleWebsocket() error {
	for {
		var buffer []byte
		err := websocket.Message.Receive(c.ws, &buffer)

		if err != nil {
			return err
		}

		msg := &message{buffer: bytes.NewBuffer(buffer), createRO: c.receiveRO}

		iRoID, err := msg.read()
		if err != nil {
			return err
		}
		roID, ok := iRoID.(uint64)
		if !ok {
			return errors.New("ro id should be int")
		}

		ro := c.remoteObjects[roID]
		if ro == nil {
			return errors.New("ro not known")
		}

		var data []interface{}
		for !msg.empty() {
			v, err := msg.read()
			if err != nil {
				return err
			}
			data = append(data, v)
		}

		err = ro.receive(data)
		if err != nil {
			return err
		}
	}
}

func (c *Connection) receiveRO(id uint64, name string) interface{} {
	var ro RemoteObject
	factory := registeredRemoteObjects[name]
	if factory != nil {
		ro = factory(id, c)
	} else {
		ro = NewBasicRO(id, c)
	}
	c.remoteObjects[id] = ro
	return ro
}
<|endoftext|>


<commit_before>// +build !ignore_autogenerated

/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// This file was autogenerated by conversion-gen. Do not edit it manually!

package v1beta1

import (
	federation "k8s.io/kubernetes/federation/apis/federation"
	api "k8s.io/kubernetes/pkg/api"
	v1 "k8s.io/kubernetes/pkg/api/v1"
	conversion "k8s.io/kubernetes/pkg/conversion"
	runtime "k8s.io/kubernetes/pkg/runtime"
)

func init() {
	SchemeBuilder.Register(RegisterConversions)
}

// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
	return scheme.AddGeneratedConversionFuncs(
		Convert_v1beta1_Cluster_To_federation_Cluster,
		Convert_federation_Cluster_To_v1beta1_Cluster,
		Convert_v1beta1_ClusterCondition_To_federation_ClusterCondition,
		Convert_federation_ClusterCondition_To_v1beta1_ClusterCondition,
		Convert_v1beta1_ClusterList_To_federation_ClusterList,
		Convert_federation_ClusterList_To_v1beta1_ClusterList,
		Convert_v1beta1_ClusterSpec_To_federation_ClusterSpec,
		Convert_federation_ClusterSpec_To_v1beta1_ClusterSpec,
		Convert_v1beta1_ClusterStatus_To_federation_ClusterStatus,
		Convert_federation_ClusterStatus_To_v1beta1_ClusterStatus,
		Convert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR,
		Convert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR,
	)
}

func autoConvert_v1beta1_Cluster_To_federation_Cluster(in *Cluster, out *federation.Cluster, s conversion.Scope) error {
	if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
		return err
	}
	// TODO: Inefficient conversion - can we improve it?
	if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
		return err
	}
	if err := Convert_v1beta1_ClusterSpec_To_federation_ClusterSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	if err := Convert_v1beta1_ClusterStatus_To_federation_ClusterStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

func Convert_v1beta1_Cluster_To_federation_Cluster(in *Cluster, out *federation.Cluster, s conversion.Scope) error {
	return autoConvert_v1beta1_Cluster_To_federation_Cluster(in, out, s)
}

func autoConvert_federation_Cluster_To_v1beta1_Cluster(in *federation.Cluster, out *Cluster, s conversion.Scope) error {
	if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
		return err
	}
	// TODO: Inefficient conversion - can we improve it?
	if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
		return err
	}
	if err := Convert_federation_ClusterSpec_To_v1beta1_ClusterSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	if err := Convert_federation_ClusterStatus_To_v1beta1_ClusterStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

func Convert_federation_Cluster_To_v1beta1_Cluster(in *federation.Cluster, out *Cluster, s conversion.Scope) error {
	return autoConvert_federation_Cluster_To_v1beta1_Cluster(in, out, s)
}

func autoConvert_v1beta1_ClusterCondition_To_federation_ClusterCondition(in *ClusterCondition, out *federation.ClusterCondition, s conversion.Scope) error {
	out.Type = federation.ClusterConditionType(in.Type)
	out.Status = api.ConditionStatus(in.Status)
	if err := api.Convert_unversioned_Time_To_unversioned_Time(&in.LastProbeTime, &out.LastProbeTime, s); err != nil {
		return err
	}
	if err := api.Convert_unversioned_Time_To_unversioned_Time(&in.LastTransitionTime, &out.LastTransitionTime, s); err != nil {
		return err
	}
	out.Reason = in.Reason
	out.Message = in.Message
	return nil
}

func Convert_v1beta1_ClusterCondition_To_federation_ClusterCondition(in *ClusterCondition, out *federation.ClusterCondition, s conversion.Scope) error {
	return autoConvert_v1beta1_ClusterCondition_To_federation_ClusterCondition(in, out, s)
}

func autoConvert_federation_ClusterCondition_To_v1beta1_ClusterCondition(in *federation.ClusterCondition, out *ClusterCondition, s conversion.Scope) error {
	out.Type = ClusterConditionType(in.Type)
	out.Status = v1.ConditionStatus(in.Status)
	if err := api.Convert_unversioned_Time_To_unversioned_Time(&in.LastProbeTime, &out.LastProbeTime, s); err != nil {
		return err
	}
	if err := api.Convert_unversioned_Time_To_unversioned_Time(&in.LastTransitionTime, &out.LastTransitionTime, s); err != nil {
		return err
	}
	out.Reason = in.Reason
	out.Message = in.Message
	return nil
}

func Convert_federation_ClusterCondition_To_v1beta1_ClusterCondition(in *federation.ClusterCondition, out *ClusterCondition, s conversion.Scope) error {
	return autoConvert_federation_ClusterCondition_To_v1beta1_ClusterCondition(in, out, s)
}

func autoConvert_v1beta1_ClusterList_To_federation_ClusterList(in *ClusterList, out *federation.ClusterList, s conversion.Scope) error {
	if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
		return err
	}
	if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil {
		return err
	}
	if in.Items != nil {
		in, out := &in.Items, &out.Items
		*out = make([]federation.Cluster, len(*in))
		for i := range *in {
			if err := Convert_v1beta1_Cluster_To_federation_Cluster(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Items = nil
	}
	return nil
}

func Convert_v1beta1_ClusterList_To_federation_ClusterList(in *ClusterList, out *federation.ClusterList, s conversion.Scope) error {
	return autoConvert_v1beta1_ClusterList_To_federation_ClusterList(in, out, s)
}

func autoConvert_federation_ClusterList_To_v1beta1_ClusterList(in *federation.ClusterList, out *ClusterList, s conversion.Scope) error {
	if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
		return err
	}
	if err := api.Convert_unversioned_ListMeta_To_unversioned_ListMeta(&in.ListMeta, &out.ListMeta, s); err != nil {
		return err
	}
	if in.Items != nil {
		in, out := &in.Items, &out.Items
		*out = make([]Cluster, len(*in))
		for i := range *in {
			if err := Convert_federation_Cluster_To_v1beta1_Cluster(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Items = nil
	}
	return nil
}

func Convert_federation_ClusterList_To_v1beta1_ClusterList(in *federation.ClusterList, out *ClusterList, s conversion.Scope) error {
	return autoConvert_federation_ClusterList_To_v1beta1_ClusterList(in, out, s)
}

func autoConvert_v1beta1_ClusterSpec_To_federation_ClusterSpec(in *ClusterSpec, out *federation.ClusterSpec, s conversion.Scope) error {
	if in.ServerAddressByClientCIDRs != nil {
		in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
		*out = make([]federation.ServerAddressByClientCIDR, len(*in))
		for i := range *in {
			if err := Convert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.ServerAddressByClientCIDRs = nil
	}
	if in.SecretRef != nil {
		in, out := &in.SecretRef, &out.SecretRef
		*out = new(api.LocalObjectReference)
		// TODO: Inefficient conversion - can we improve it?
		if err := s.Convert(*in, *out, 0); err != nil {
			return err
		}
	} else {
		out.SecretRef = nil
	}
	return nil
}

func Convert_v1beta1_ClusterSpec_To_federation_ClusterSpec(in *ClusterSpec, out *federation.ClusterSpec, s conversion.Scope) error {
	return autoConvert_v1beta1_ClusterSpec_To_federation_ClusterSpec(in, out, s)
}

func autoConvert_federation_ClusterSpec_To_v1beta1_ClusterSpec(in *federation.ClusterSpec, out *ClusterSpec, s conversion.Scope) error {
	if in.ServerAddressByClientCIDRs != nil {
		in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
		*out = make([]ServerAddressByClientCIDR, len(*in))
		for i := range *in {
			if err := Convert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.ServerAddressByClientCIDRs = nil
	}
	if in.SecretRef != nil {
		in, out := &in.SecretRef, &out.SecretRef
		*out = new(v1.LocalObjectReference)
		// TODO: Inefficient conversion - can we improve it?
		if err := s.Convert(*in, *out, 0); err != nil {
			return err
		}
	} else {
		out.SecretRef = nil
	}
	return nil
}

func Convert_federation_ClusterSpec_To_v1beta1_ClusterSpec(in *federation.ClusterSpec, out *ClusterSpec, s conversion.Scope) error {
	return autoConvert_federation_ClusterSpec_To_v1beta1_ClusterSpec(in, out, s)
}

func autoConvert_v1beta1_ClusterStatus_To_federation_ClusterStatus(in *ClusterStatus, out *federation.ClusterStatus, s conversion.Scope) error {
	if in.Conditions != nil {
		in, out := &in.Conditions, &out.Conditions
		*out = make([]federation.ClusterCondition, len(*in))
		for i := range *in {
			if err := Convert_v1beta1_ClusterCondition_To_federation_ClusterCondition(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Conditions = nil
	}
	out.Zones = in.Zones
	out.Region = in.Region
	return nil
}

func Convert_v1beta1_ClusterStatus_To_federation_ClusterStatus(in *ClusterStatus, out *federation.ClusterStatus, s conversion.Scope) error {
	return autoConvert_v1beta1_ClusterStatus_To_federation_ClusterStatus(in, out, s)
}

func autoConvert_federation_ClusterStatus_To_v1beta1_ClusterStatus(in *federation.ClusterStatus, out *ClusterStatus, s conversion.Scope) error {
	if in.Conditions != nil {
		in, out := &in.Conditions, &out.Conditions
		*out = make([]ClusterCondition, len(*in))
		for i := range *in {
			if err := Convert_federation_ClusterCondition_To_v1beta1_ClusterCondition(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Conditions = nil
	}
	out.Zones = in.Zones
	out.Region = in.Region
	return nil
}

func Convert_federation_ClusterStatus_To_v1beta1_ClusterStatus(in *federation.ClusterStatus, out *ClusterStatus, s conversion.Scope) error {
	return autoConvert_federation_ClusterStatus_To_v1beta1_ClusterStatus(in, out, s)
}

func autoConvert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR(in *ServerAddressByClientCIDR, out *federation.ServerAddressByClientCIDR, s conversion.Scope) error {
	out.ClientCIDR = in.ClientCIDR
	out.ServerAddress = in.ServerAddress
	return nil
}

func Convert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR(in *ServerAddressByClientCIDR, out *federation.ServerAddressByClientCIDR, s conversion.Scope) error {
	return autoConvert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR(in, out, s)
}

func autoConvert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR(in *federation.ServerAddressByClientCIDR, out *ServerAddressByClientCIDR, s conversion.Scope) error {
	out.ClientCIDR = in.ClientCIDR
	out.ServerAddress = in.ServerAddress
	return nil
}

func Convert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR(in *federation.ServerAddressByClientCIDR, out *ServerAddressByClientCIDR, s conversion.Scope) error {
	return autoConvert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR(in, out, s)
}
<commit_msg>generated: conversions<commit_after>// +build !ignore_autogenerated

/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// This file was autogenerated by conversion-gen. Do not edit it manually!

package v1beta1

import (
	federation "k8s.io/kubernetes/federation/apis/federation"
	api "k8s.io/kubernetes/pkg/api"
	v1 "k8s.io/kubernetes/pkg/api/v1"
	conversion "k8s.io/kubernetes/pkg/conversion"
	runtime "k8s.io/kubernetes/pkg/runtime"
)

func init() {
	SchemeBuilder.Register(RegisterConversions)
}

// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
	return scheme.AddGeneratedConversionFuncs(
		Convert_v1beta1_Cluster_To_federation_Cluster,
		Convert_federation_Cluster_To_v1beta1_Cluster,
		Convert_v1beta1_ClusterCondition_To_federation_ClusterCondition,
		Convert_federation_ClusterCondition_To_v1beta1_ClusterCondition,
		Convert_v1beta1_ClusterList_To_federation_ClusterList,
		Convert_federation_ClusterList_To_v1beta1_ClusterList,
		Convert_v1beta1_ClusterSpec_To_federation_ClusterSpec,
		Convert_federation_ClusterSpec_To_v1beta1_ClusterSpec,
		Convert_v1beta1_ClusterStatus_To_federation_ClusterStatus,
		Convert_federation_ClusterStatus_To_v1beta1_ClusterStatus,
		Convert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR,
		Convert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR,
	)
}

func autoConvert_v1beta1_Cluster_To_federation_Cluster(in *Cluster, out *federation.Cluster, s conversion.Scope) error {
	// TODO: Inefficient conversion - can we improve it?
	if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
		return err
	}
	if err := Convert_v1beta1_ClusterSpec_To_federation_ClusterSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	if err := Convert_v1beta1_ClusterStatus_To_federation_ClusterStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

func Convert_v1beta1_Cluster_To_federation_Cluster(in *Cluster, out *federation.Cluster, s conversion.Scope) error {
	return autoConvert_v1beta1_Cluster_To_federation_Cluster(in, out, s)
}

func autoConvert_federation_Cluster_To_v1beta1_Cluster(in *federation.Cluster, out *Cluster, s conversion.Scope) error {
	// TODO: Inefficient conversion - can we improve it?
	if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
		return err
	}
	if err := Convert_federation_ClusterSpec_To_v1beta1_ClusterSpec(&in.Spec, &out.Spec, s); err != nil {
		return err
	}
	if err := Convert_federation_ClusterStatus_To_v1beta1_ClusterStatus(&in.Status, &out.Status, s); err != nil {
		return err
	}
	return nil
}

func Convert_federation_Cluster_To_v1beta1_Cluster(in *federation.Cluster, out *Cluster, s conversion.Scope) error {
	return autoConvert_federation_Cluster_To_v1beta1_Cluster(in, out, s)
}

func autoConvert_v1beta1_ClusterCondition_To_federation_ClusterCondition(in *ClusterCondition, out *federation.ClusterCondition, s conversion.Scope) error {
	out.Type = federation.ClusterConditionType(in.Type)
	out.Status = api.ConditionStatus(in.Status)
	out.LastProbeTime = in.LastProbeTime
	out.LastTransitionTime = in.LastTransitionTime
	out.Reason = in.Reason
	out.Message = in.Message
	return nil
}

func Convert_v1beta1_ClusterCondition_To_federation_ClusterCondition(in *ClusterCondition, out *federation.ClusterCondition, s conversion.Scope) error {
	return autoConvert_v1beta1_ClusterCondition_To_federation_ClusterCondition(in, out, s)
}

func autoConvert_federation_ClusterCondition_To_v1beta1_ClusterCondition(in *federation.ClusterCondition, out *ClusterCondition, s conversion.Scope) error {
	out.Type = ClusterConditionType(in.Type)
	out.Status = v1.ConditionStatus(in.Status)
	out.LastProbeTime = in.LastProbeTime
	out.LastTransitionTime = in.LastTransitionTime
	out.Reason = in.Reason
	out.Message = in.Message
	return nil
}

func Convert_federation_ClusterCondition_To_v1beta1_ClusterCondition(in *federation.ClusterCondition, out *ClusterCondition, s conversion.Scope) error {
	return autoConvert_federation_ClusterCondition_To_v1beta1_ClusterCondition(in, out, s)
}

func autoConvert_v1beta1_ClusterList_To_federation_ClusterList(in *ClusterList, out *federation.ClusterList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	if in.Items != nil {
		in, out := &in.Items, &out.Items
		*out = make([]federation.Cluster, len(*in))
		for i := range *in {
			if err := Convert_v1beta1_Cluster_To_federation_Cluster(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Items = nil
	}
	return nil
}

func Convert_v1beta1_ClusterList_To_federation_ClusterList(in *ClusterList, out *federation.ClusterList, s conversion.Scope) error {
	return autoConvert_v1beta1_ClusterList_To_federation_ClusterList(in, out, s)
}

func autoConvert_federation_ClusterList_To_v1beta1_ClusterList(in *federation.ClusterList, out *ClusterList, s conversion.Scope) error {
	out.ListMeta = in.ListMeta
	if in.Items != nil {
		in, out := &in.Items, &out.Items
		*out = make([]Cluster, len(*in))
		for i := range *in {
			if err := Convert_federation_Cluster_To_v1beta1_Cluster(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Items = nil
	}
	return nil
}

func Convert_federation_ClusterList_To_v1beta1_ClusterList(in *federation.ClusterList, out *ClusterList, s conversion.Scope) error {
	return autoConvert_federation_ClusterList_To_v1beta1_ClusterList(in, out, s)
}

func autoConvert_v1beta1_ClusterSpec_To_federation_ClusterSpec(in *ClusterSpec, out *federation.ClusterSpec, s conversion.Scope) error {
	if in.ServerAddressByClientCIDRs != nil {
		in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
		*out = make([]federation.ServerAddressByClientCIDR, len(*in))
		for i := range *in {
			if err := Convert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.ServerAddressByClientCIDRs = nil
	}
	if in.SecretRef != nil {
		in, out := &in.SecretRef, &out.SecretRef
		*out = new(api.LocalObjectReference)
		// TODO: Inefficient conversion - can we improve it?
		if err := s.Convert(*in, *out, 0); err != nil {
			return err
		}
	} else {
		out.SecretRef = nil
	}
	return nil
}

func Convert_v1beta1_ClusterSpec_To_federation_ClusterSpec(in *ClusterSpec, out *federation.ClusterSpec, s conversion.Scope) error {
	return autoConvert_v1beta1_ClusterSpec_To_federation_ClusterSpec(in, out, s)
}

func autoConvert_federation_ClusterSpec_To_v1beta1_ClusterSpec(in *federation.ClusterSpec, out *ClusterSpec, s conversion.Scope) error {
	if in.ServerAddressByClientCIDRs != nil {
		in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
		*out = make([]ServerAddressByClientCIDR, len(*in))
		for i := range *in {
			if err := Convert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.ServerAddressByClientCIDRs = nil
	}
	if in.SecretRef != nil {
		in, out := &in.SecretRef, &out.SecretRef
		*out = new(v1.LocalObjectReference)
		// TODO: Inefficient conversion - can we improve it?
		if err := s.Convert(*in, *out, 0); err != nil {
			return err
		}
	} else {
		out.SecretRef = nil
	}
	return nil
}

func Convert_federation_ClusterSpec_To_v1beta1_ClusterSpec(in *federation.ClusterSpec, out *ClusterSpec, s conversion.Scope) error {
	return autoConvert_federation_ClusterSpec_To_v1beta1_ClusterSpec(in, out, s)
}

func autoConvert_v1beta1_ClusterStatus_To_federation_ClusterStatus(in *ClusterStatus, out *federation.ClusterStatus, s conversion.Scope) error {
	if in.Conditions != nil {
		in, out := &in.Conditions, &out.Conditions
		*out = make([]federation.ClusterCondition, len(*in))
		for i := range *in {
			if err := Convert_v1beta1_ClusterCondition_To_federation_ClusterCondition(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Conditions = nil
	}
	out.Zones = in.Zones
	out.Region = in.Region
	return nil
}

func Convert_v1beta1_ClusterStatus_To_federation_ClusterStatus(in *ClusterStatus, out *federation.ClusterStatus, s conversion.Scope) error {
	return autoConvert_v1beta1_ClusterStatus_To_federation_ClusterStatus(in, out, s)
}

func autoConvert_federation_ClusterStatus_To_v1beta1_ClusterStatus(in *federation.ClusterStatus, out *ClusterStatus, s conversion.Scope) error {
	if in.Conditions != nil {
		in, out := &in.Conditions, &out.Conditions
		*out = make([]ClusterCondition, len(*in))
		for i := range *in {
			if err := Convert_federation_ClusterCondition_To_v1beta1_ClusterCondition(&(*in)[i], &(*out)[i], s); err != nil {
				return err
			}
		}
	} else {
		out.Conditions = nil
	}
	out.Zones = in.Zones
	out.Region = in.Region
	return nil
}

func Convert_federation_ClusterStatus_To_v1beta1_ClusterStatus(in *federation.ClusterStatus, out *ClusterStatus, s conversion.Scope) error {
	return autoConvert_federation_ClusterStatus_To_v1beta1_ClusterStatus(in, out, s)
}

func autoConvert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR(in *ServerAddressByClientCIDR, out *federation.ServerAddressByClientCIDR, s conversion.Scope) error {
	out.ClientCIDR = in.ClientCIDR
	out.ServerAddress = in.ServerAddress
	return nil
}

func Convert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR(in *ServerAddressByClientCIDR, out *federation.ServerAddressByClientCIDR, s conversion.Scope) error {
	return autoConvert_v1beta1_ServerAddressByClientCIDR_To_federation_ServerAddressByClientCIDR(in, out, s)
}

func autoConvert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR(in *federation.ServerAddressByClientCIDR, out *ServerAddressByClientCIDR, s conversion.Scope) error {
	out.ClientCIDR = in.ClientCIDR
	out.ServerAddress = in.ServerAddress
	return nil
}

func Convert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR(in *federation.ServerAddressByClientCIDR, out *ServerAddressByClientCIDR, s conversion.Scope) error {
	return autoConvert_federation_ServerAddressByClientCIDR_To_v1beta1_ServerAddressByClientCIDR(in, out, s)
}
<|endoftext|>