<commit_before>// Copyright 2015 CoreOS, Inc.
//
// 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 oem

import (
	"fmt"

	"github.com/coreos/ignition/config/types"
	"github.com/coreos/ignition/internal/providers"
	"github.com/coreos/ignition/internal/providers/azure"
	"github.com/coreos/ignition/internal/providers/digitalocean"
	"github.com/coreos/ignition/internal/providers/ec2"
	"github.com/coreos/ignition/internal/providers/file"
	"github.com/coreos/ignition/internal/providers/gce"
	"github.com/coreos/ignition/internal/providers/noop"
	"github.com/coreos/ignition/internal/providers/openstack"
	"github.com/coreos/ignition/internal/providers/packet"
	"github.com/coreos/ignition/internal/providers/qemu"
	"github.com/coreos/ignition/internal/providers/vmware"
	"github.com/coreos/ignition/internal/registry"

	"github.com/vincent-petithory/dataurl"
)

// Config represents a set of options that map to a particular OEM.
type Config struct {
	name              string
	fetch             providers.FuncFetchConfig
	baseConfig        types.Config
	defaultUserConfig types.Config
}

func (c Config) Name() string {
	return c.name
}

func (c Config) FetchFunc() providers.FuncFetchConfig {
	return c.fetch
}

func (c Config) BaseConfig() types.Config {
	return c.baseConfig
}

func (c Config) DefaultUserConfig() types.Config {
	return c.defaultUserConfig
}

var configs = registry.Create("oem configs")

func init() {
	configs.Register(Config{
		name:  "azure",
		fetch: azure.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{
					{Enable: true, Name: "waagent.service"},
					{Name: "etcd.service", DropIns: []types.SystemdUnitDropIn{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_PEER_ELECTION_TIMEOUT=1200\n"},
					}},
					{Name: "etcd2.service", DropIns: []types.SystemdUnitDropIn{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_ELECTION_TIMEOUT=1200\n"},
					}},
				},
			},
			Storage: types.Storage{Files: []types.File{serviceFromOem("waagent.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.SystemdUnit{userCloudInit("Azure", "azure")}}},
	})
	configs.Register(Config{
		name:  "cloudsigma",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "cloudstack",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "digitalocean",
		fetch: digitalocean.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{{Enable: true, Name: "coreos-metadata-sshkeys@.service"}},
			},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.SystemdUnit{userCloudInit("DigitalOcean", "digitalocean")}}},
	})
	configs.Register(Config{
		name:  "brightbox",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "openstack",
		fetch: openstack.FetchConfig,
	})
	configs.Register(Config{
		name:  "ec2",
		fetch: ec2.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{
					{Enable: true, Name: "coreos-metadata-sshkeys@.service"},
					{Name: "etcd.service", DropIns: []types.SystemdUnitDropIn{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_PEER_ELECTION_TIMEOUT=1200\n"},
					}},
					{Name: "etcd2.service", DropIns: []types.SystemdUnitDropIn{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_ELECTION_TIMEOUT=1200\n"},
					}},
				},
			},
		},
		defaultUserConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{
					{Mask: true, Name: "user-configdrive.service"},
					{Mask: true, Name: "user-configvirtfs.service"},
					userCloudInit("EC2-style", "ec2-compat"),
				},
			},
		},
	})
	configs.Register(Config{
		name:  "exoscale",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "gce",
		fetch: gce.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{
					{Enable: true, Name: "coreos-metadata-sshkeys@.service"},
					{Enable: true, Name: "oem-gce.service"},
				},
			},
			Storage: types.Storage{
				Files: []types.File{
					serviceFromOem("oem-gce.service"),
					{
						Node: types.Node{
							Filesystem: "root",
							Path:       "/etc/hosts",
							Mode:       0444,
						},
						Contents: contentsFromString("169.254.169.254 metadata\n127.0.0.1 localhost\n"),
					},
					{
						Node: types.Node{
							Filesystem: "root",
							Path:       "/etc/profile.d/google-cloud-sdk.sh",
							Mode:       0444,
						},
						Contents: contentsFromString(`#!/bin/sh
alias gcloud="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/.config -v /var/run/docker.sock:/var/run/doker.sock -v /usr/bin/docker:/usr/bin/docker google/cloud-sdk gcloud"
alias gcutil="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/.config google/cloud-sdk gcutil"
alias gsutil="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/.config google/cloud-sdk gsutil"
`),
					},
				},
			},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.SystemdUnit{userCloudInit("GCE", "gce")}}},
	})
	configs.Register(Config{
		name:  "hyperv",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "niftycloud",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "packet",
		fetch: packet.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{{Enable: true, Name: "coreos-metadata-sshkeys@.service"}},
			},
		},
	})
	configs.Register(Config{
		name:  "pxe",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "rackspace",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "rackspace-onmetal",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "vagrant",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "vmware",
		fetch: vmware.FetchConfig,
	})
	configs.Register(Config{
		name:  "xendom0",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "interoute",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "qemu",
		fetch: qemu.FetchConfig,
	})
	configs.Register(Config{
		name:  "file",
		fetch: file.FetchConfig,
	})
}

func Get(name string) (config Config, ok bool) {
	config, ok = configs.Get(name).(Config)
	return
}

func MustGet(name string) Config {
	if config, ok := Get(name); ok {
		return config
	} else {
		panic(fmt.Sprintf("invalid OEM name %q provided", name))
	}
}

func Names() (names []string) {
	return configs.Names()
}

func contentsFromString(data string) types.FileContents {
	return types.FileContents{
		Source: types.Url{
			Scheme: "data",
			Opaque: "," + dataurl.EscapeString(data),
		},
	}
}

func contentsFromOem(path string) types.FileContents {
	return types.FileContents{
		Source: types.Url{
			Scheme: "oem",
			Path:   path,
		},
	}
}

func userCloudInit(name string, oem string) types.SystemdUnit {
	contents := `[Unit]
Description=Cloudinit from %s metadata

[Service]
Type=oneshot
ExecStart=/usr/bin/coreos-cloudinit --oem=%s

[Install]
WantedBy=multi-user.target
`

	return types.SystemdUnit{
		Name:     "oem-cloudinit.service",
		Enable:   true,
		Contents: fmt.Sprintf(contents, name, oem),
	}
}

func serviceFromOem(unit string) types.File {
	return types.File{
		Node: types.Node{
			Filesystem: "root",
			Path:       types.Path("/etc/systemd/system/" + unit),
			Mode:       0444,
		},
		Contents: contentsFromOem("/units/" + unit),
	}
}
<commit_msg>oem: add configuration for vmware<commit_after>// Copyright 2015 CoreOS, Inc.
//
// 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 oem

import (
	"fmt"

	"github.com/coreos/ignition/config/types"
	"github.com/coreos/ignition/internal/providers"
	"github.com/coreos/ignition/internal/providers/azure"
	"github.com/coreos/ignition/internal/providers/digitalocean"
	"github.com/coreos/ignition/internal/providers/ec2"
	"github.com/coreos/ignition/internal/providers/file"
	"github.com/coreos/ignition/internal/providers/gce"
	"github.com/coreos/ignition/internal/providers/noop"
	"github.com/coreos/ignition/internal/providers/openstack"
	"github.com/coreos/ignition/internal/providers/packet"
	"github.com/coreos/ignition/internal/providers/qemu"
	"github.com/coreos/ignition/internal/providers/vmware"
	"github.com/coreos/ignition/internal/registry"

	"github.com/vincent-petithory/dataurl"
)

// Config represents a set of options that map to a particular OEM.
type Config struct {
	name              string
	fetch             providers.FuncFetchConfig
	baseConfig        types.Config
	defaultUserConfig types.Config
}

func (c Config) Name() string {
	return c.name
}

func (c Config) FetchFunc() providers.FuncFetchConfig {
	return c.fetch
}

func (c Config) BaseConfig() types.Config {
	return c.baseConfig
}

func (c Config) DefaultUserConfig() types.Config {
	return c.defaultUserConfig
}

var configs = registry.Create("oem configs")

func init() {
	configs.Register(Config{
		name:  "azure",
		fetch: azure.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{
					{Enable: true, Name: "waagent.service"},
					{Name: "etcd.service", DropIns: []types.SystemdUnitDropIn{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_PEER_ELECTION_TIMEOUT=1200\n"},
					}},
					{Name: "etcd2.service", DropIns: []types.SystemdUnitDropIn{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_ELECTION_TIMEOUT=1200\n"},
					}},
				},
			},
			Storage: types.Storage{Files: []types.File{serviceFromOem("waagent.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.SystemdUnit{userCloudInit("Azure", "azure")}}},
	})
	configs.Register(Config{
		name:  "cloudsigma",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "cloudstack",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "digitalocean",
		fetch: digitalocean.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{{Enable: true, Name: "coreos-metadata-sshkeys@.service"}},
			},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.SystemdUnit{userCloudInit("DigitalOcean", "digitalocean")}}},
	})
	configs.Register(Config{
		name:  "brightbox",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "openstack",
		fetch: openstack.FetchConfig,
	})
	configs.Register(Config{
		name:  "ec2",
		fetch: ec2.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{
					{Enable: true, Name: "coreos-metadata-sshkeys@.service"},
					{Name: "etcd.service", DropIns: []types.SystemdUnitDropIn{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_PEER_ELECTION_TIMEOUT=1200\n"},
					}},
					{Name: "etcd2.service", DropIns: []types.SystemdUnitDropIn{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_ELECTION_TIMEOUT=1200\n"},
					}},
				},
			},
		},
		defaultUserConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{
					{Mask: true, Name: "user-configdrive.service"},
					{Mask: true, Name: "user-configvirtfs.service"},
					userCloudInit("EC2-style", "ec2-compat"),
				},
			},
		},
	})
	configs.Register(Config{
		name:  "exoscale",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "gce",
		fetch: gce.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{
					{Enable: true, Name: "coreos-metadata-sshkeys@.service"},
					{Enable: true, Name: "oem-gce.service"},
				},
			},
			Storage: types.Storage{
				Files: []types.File{
					serviceFromOem("oem-gce.service"),
					{
						Node: types.Node{
							Filesystem: "root",
							Path:       "/etc/hosts",
							Mode:       0444,
						},
						Contents: contentsFromString("169.254.169.254 metadata\n127.0.0.1 localhost\n"),
					},
					{
						Node: types.Node{
							Filesystem: "root",
							Path:       "/etc/profile.d/google-cloud-sdk.sh",
							Mode:       0444,
						},
						Contents: contentsFromString(`#!/bin/sh
alias gcloud="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/.config -v /var/run/docker.sock:/var/run/doker.sock -v /usr/bin/docker:/usr/bin/docker google/cloud-sdk gcloud"
alias gcutil="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/.config google/cloud-sdk gcutil"
alias gsutil="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/.config google/cloud-sdk gsutil"
`),
					},
				},
			},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.SystemdUnit{userCloudInit("GCE", "gce")}}},
	})
	configs.Register(Config{
		name:  "hyperv",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "niftycloud",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "packet",
		fetch: packet.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.SystemdUnit{{Enable: true, Name: "coreos-metadata-sshkeys@.service"}},
			},
		},
	})
	configs.Register(Config{
		name:  "pxe",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "rackspace",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "rackspace-onmetal",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "vagrant",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "vmware",
		fetch: vmware.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{Units: []types.SystemdUnit{{Enable: true, Name: "vmtoolsd.service"}}},
			Storage: types.Storage{Files: []types.File{serviceFromOem("vmtoolsd.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.SystemdUnit{userCloudInit("VMware", "vmware")}}},
	})
	configs.Register(Config{
		name:  "xendom0",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "interoute",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "qemu",
		fetch: qemu.FetchConfig,
	})
	configs.Register(Config{
		name:  "file",
		fetch: file.FetchConfig,
	})
}

func Get(name string) (config Config, ok bool) {
	config, ok = configs.Get(name).(Config)
	return
}

func MustGet(name string) Config {
	if config, ok := Get(name); ok {
		return config
	} else {
		panic(fmt.Sprintf("invalid OEM name %q provided", name))
	}
}

func Names() (names []string) {
	return configs.Names()
}

func contentsFromString(data string) types.FileContents {
	return types.FileContents{
		Source: types.Url{
			Scheme: "data",
			Opaque: "," + dataurl.EscapeString(data),
		},
	}
}

func contentsFromOem(path string) types.FileContents {
	return types.FileContents{
		Source: types.Url{
			Scheme: "oem",
			Path:   path,
		},
	}
}

func userCloudInit(name string, oem string) types.SystemdUnit {
	contents := `[Unit]
Description=Cloudinit from %s metadata

[Service]
Type=oneshot
ExecStart=/usr/bin/coreos-cloudinit --oem=%s

[Install]
WantedBy=multi-user.target
`

	return types.SystemdUnit{
		Name:     "oem-cloudinit.service",
		Enable:   true,
		Contents: fmt.Sprintf(contents, name, oem),
	}
}

func serviceFromOem(unit string) types.File {
	return types.File{
		Node: types.Node{
			Filesystem: "root",
			Path:       types.Path("/etc/systemd/system/" + unit),
			Mode:       0444,
		},
		Contents: contentsFromOem("/units/" + unit),
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 CoreOS, Inc.
//
// 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 oem

import (
	"fmt"
	"net/url"

	"github.com/coreos/ignition/config/types"
	"github.com/coreos/ignition/internal/log"
	"github.com/coreos/ignition/internal/providers"
	"github.com/coreos/ignition/internal/providers/azure"
	"github.com/coreos/ignition/internal/providers/cloudstack"
	"github.com/coreos/ignition/internal/providers/digitalocean"
	"github.com/coreos/ignition/internal/providers/ec2"
	"github.com/coreos/ignition/internal/providers/file"
	"github.com/coreos/ignition/internal/providers/gce"
	"github.com/coreos/ignition/internal/providers/noop"
	"github.com/coreos/ignition/internal/providers/openstack"
	"github.com/coreos/ignition/internal/providers/oracleoci"
	"github.com/coreos/ignition/internal/providers/packet"
	"github.com/coreos/ignition/internal/providers/qemu"
	"github.com/coreos/ignition/internal/providers/virtualbox"
	"github.com/coreos/ignition/internal/providers/vmware"
	"github.com/coreos/ignition/internal/registry"
	"github.com/coreos/ignition/internal/resource"
	"github.com/coreos/ignition/internal/util"

	"github.com/vincent-petithory/dataurl"
)

// Config represents a set of options that map to a particular OEM.
type Config struct {
	name              string
	fetch             providers.FuncFetchConfig
	newFetcher        providers.FuncNewFetcher
	baseConfig        types.Config
	defaultUserConfig types.Config
}

func (c Config) Name() string {
	return c.name
}

func (c Config) FetchFunc() providers.FuncFetchConfig {
	return c.fetch
}

func (c Config) NewFetcherFunc() providers.FuncNewFetcher {
	if c.newFetcher != nil {
		return c.newFetcher
	}
	return func(l *log.Logger, c *resource.HttpClient) (resource.Fetcher, error) {
		return resource.Fetcher{
			Logger: l,
			Client: c,
		}, nil
	}
}

func (c Config) BaseConfig() types.Config {
	return c.baseConfig
}

func (c Config) DefaultUserConfig() types.Config {
	return c.defaultUserConfig
}

var configs = registry.Create("oem configs")
var yes = util.BoolToPtr(true)

func init() {
	configs.Register(Config{
		name:  "azure",
		fetch: azure.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "waagent.service"},
					{Name: "etcd2.service", Dropins: []types.Dropin{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_ELECTION_TIMEOUT=1200\n"},
					}},
				},
			},
			Storage: types.Storage{Files: []types.File{serviceFromOem("waagent.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("Azure", "azure")}}},
	})
	configs.Register(Config{
		name:  "cloudsigma",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "cloudstack",
		fetch: cloudstack.FetchConfig,
	})
	configs.Register(Config{
		name:  "digitalocean",
		fetch: digitalocean.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"}},
			},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("DigitalOcean", "digitalocean")}}},
	})
	configs.Register(Config{
		name:  "brightbox",
		fetch: openstack.FetchConfig,
		defaultUserConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Mask: true, Name: "user-configdrive.service"},
					{Mask: true, Name: "user-configvirtfs.service"},
					userCloudInit("BrightBox", "ec2-compat"),
				},
			},
		},
	})
	configs.Register(Config{
		name:  "openstack",
		fetch: openstack.FetchConfig,
		defaultUserConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Mask: true, Name: "user-configdrive.service"},
					{Mask: true, Name: "user-configvirtfs.service"},
					userCloudInit("OpenStack", "ec2-compat"),
				},
			},
		},
	})
	configs.Register(Config{
		name:       "ec2",
		fetch:      ec2.FetchConfig,
		newFetcher: ec2.NewFetcher,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"},
					{Name: "etcd2.service", Dropins: []types.Dropin{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_ELECTION_TIMEOUT=1200\n"},
					}},
				},
			},
		},
		defaultUserConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Mask: true, Name: "user-configdrive.service"},
					{Mask: true, Name: "user-configvirtfs.service"},
					userCloudInit("EC2", "ec2-compat"),
				},
			},
		},
	})
	configs.Register(Config{
		name:  "exoscale",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "gce",
		fetch: gce.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"},
					{Enabled: yes, Name: "oem-gce.service"},
				},
			},
			Storage: types.Storage{
				Files: []types.File{
					serviceFromOem("oem-gce.service"),
					{
						Node: types.Node{
							Filesystem: "root",
							Path:       "/etc/hosts",
						},
						FileEmbedded1: types.FileEmbedded1{
							Mode:     0444,
							Contents: contentsFromString("169.254.169.254 metadata\n127.0.0.1 localhost\n"),
						},
					},
					{
						Node: types.Node{
							Filesystem: "root",
							Path:       "/etc/profile.d/google-cloud-sdk.sh",
						},
						FileEmbedded1: types.FileEmbedded1{
							Mode: 0444,
							Contents: contentsFromString(`#!/bin/sh
alias gcloud="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/root/.config -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker google/cloud-sdk gcloud"
alias gcutil="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/root/.config google/cloud-sdk gcutil"
alias gsutil="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/root/.config google/cloud-sdk gsutil"
`),
						},
					},
				},
			},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("GCE", "gce")}}},
	})
	configs.Register(Config{
		name:  "hyperv",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "niftycloud",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "packet",
		fetch: packet.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"},
					{Enabled: yes, Name: "packet-phone-home.service"},
				},
			},
			Storage: types.Storage{Files: []types.File{serviceFromOem("packet-phone-home.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("Packet", "packet")}}},
	})
	configs.Register(Config{
		name:  "pxe",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "rackspace",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "rackspace-onmetal",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "vagrant",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "vagrant-virtualbox",
		fetch: virtualbox.FetchConfig,
	})
	configs.Register(Config{
		name:  "virtualbox",
		fetch: virtualbox.FetchConfig,
	})
	configs.Register(Config{
		name:  "vmware",
		fetch: vmware.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{Units: []types.Unit{{Enabled: yes, Name: "vmtoolsd.service"}}},
			Storage: types.Storage{Files: []types.File{serviceFromOem("vmtoolsd.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("VMware", "vmware")}}},
	})
	configs.Register(Config{
		name:  "interoute",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "qemu",
		fetch: qemu.FetchConfig,
	})
	configs.Register(Config{
		name:  "file",
		fetch: file.FetchConfig,
	})
	configs.Register(Config{
		name:  "oracle-oci",
		fetch: oracleoci.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"},
					{Enabled: yes, Name: "iscsid.service"},
					{Enabled: yes, Name: "oracle-oci-root-setup.service"},
					{Enabled: yes, Name: "oracle-oci-iptables.service"},
				},
			},
			Storage: types.Storage{
				Files: []types.File{
					serviceFromOem("oracle-oci-root-setup.service"),
					serviceFromOem("oracle-oci-iptables.service"),
				},
			},
		},
	})
}

func Get(name string) (config Config, ok bool) {
	config, ok = configs.Get(name).(Config)
	return
}

func MustGet(name string) Config {
	if config, ok := Get(name); ok {
		return config
	} else {
		panic(fmt.Sprintf("invalid OEM name %q provided", name))
	}
}

func Names() (names []string) {
	return configs.Names()
}

func contentsFromString(data string) types.FileContents {
	return types.FileContents{
		Source: (&url.URL{
			Scheme: "data",
			Opaque: "," + dataurl.EscapeString(data),
		}).String(),
	}
}

func contentsFromOem(path string) types.FileContents {
	return types.FileContents{
		Source: (&url.URL{
			Scheme: "oem",
			Path:   path,
		}).String(),
	}
}

func userCloudInit(name string, oem string) types.Unit {
	contents := `[Unit]
Description=Cloudinit from %s metadata

[Service]
Type=oneshot
ExecStart=/usr/bin/coreos-cloudinit --oem=%s

[Install]
WantedBy=multi-user.target
`

	return types.Unit{
		Name:     "oem-cloudinit.service",
		Enabled:  yes,
		Contents: fmt.Sprintf(contents, name, oem),
	}
}

func serviceFromOem(unit string) types.File {
	return types.File{
		Node: types.Node{
			Filesystem: "root",
			Path:       "/etc/systemd/system/" + unit,
		},
		FileEmbedded1: types.FileEmbedded1{
			Mode:     0444,
			Contents: contentsFromOem("/units/" + unit),
		},
	}
}
<commit_msg>oem: drop gcutil alias<commit_after>// Copyright 2015 CoreOS, Inc.
//
// 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 oem

import (
	"fmt"
	"net/url"

	"github.com/coreos/ignition/config/types"
	"github.com/coreos/ignition/internal/log"
	"github.com/coreos/ignition/internal/providers"
	"github.com/coreos/ignition/internal/providers/azure"
	"github.com/coreos/ignition/internal/providers/cloudstack"
	"github.com/coreos/ignition/internal/providers/digitalocean"
	"github.com/coreos/ignition/internal/providers/ec2"
	"github.com/coreos/ignition/internal/providers/file"
	"github.com/coreos/ignition/internal/providers/gce"
	"github.com/coreos/ignition/internal/providers/noop"
	"github.com/coreos/ignition/internal/providers/openstack"
	"github.com/coreos/ignition/internal/providers/oracleoci"
	"github.com/coreos/ignition/internal/providers/packet"
	"github.com/coreos/ignition/internal/providers/qemu"
	"github.com/coreos/ignition/internal/providers/virtualbox"
	"github.com/coreos/ignition/internal/providers/vmware"
	"github.com/coreos/ignition/internal/registry"
	"github.com/coreos/ignition/internal/resource"
	"github.com/coreos/ignition/internal/util"

	"github.com/vincent-petithory/dataurl"
)

// Config represents a set of options that map to a particular OEM.
type Config struct {
	name              string
	fetch             providers.FuncFetchConfig
	newFetcher        providers.FuncNewFetcher
	baseConfig        types.Config
	defaultUserConfig types.Config
}

func (c Config) Name() string {
	return c.name
}

func (c Config) FetchFunc() providers.FuncFetchConfig {
	return c.fetch
}

func (c Config) NewFetcherFunc() providers.FuncNewFetcher {
	if c.newFetcher != nil {
		return c.newFetcher
	}
	return func(l *log.Logger, c *resource.HttpClient) (resource.Fetcher, error) {
		return resource.Fetcher{
			Logger: l,
			Client: c,
		}, nil
	}
}

func (c Config) BaseConfig() types.Config {
	return c.baseConfig
}

func (c Config) DefaultUserConfig() types.Config {
	return c.defaultUserConfig
}

var configs = registry.Create("oem configs")
var yes = util.BoolToPtr(true)

func init() {
	configs.Register(Config{
		name:  "azure",
		fetch: azure.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "waagent.service"},
					{Name: "etcd2.service", Dropins: []types.Dropin{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_ELECTION_TIMEOUT=1200\n"},
					}},
				},
			},
			Storage: types.Storage{Files: []types.File{serviceFromOem("waagent.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("Azure", "azure")}}},
	})
	configs.Register(Config{
		name:  "cloudsigma",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "cloudstack",
		fetch: cloudstack.FetchConfig,
	})
	configs.Register(Config{
		name:  "digitalocean",
		fetch: digitalocean.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"}},
			},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("DigitalOcean", "digitalocean")}}},
	})
	configs.Register(Config{
		name:  "brightbox",
		fetch: openstack.FetchConfig,
		defaultUserConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Mask: true, Name: "user-configdrive.service"},
					{Mask: true, Name: "user-configvirtfs.service"},
					userCloudInit("BrightBox", "ec2-compat"),
				},
			},
		},
	})
	configs.Register(Config{
		name:  "openstack",
		fetch: openstack.FetchConfig,
		defaultUserConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Mask: true, Name: "user-configdrive.service"},
					{Mask: true, Name: "user-configvirtfs.service"},
					userCloudInit("OpenStack", "ec2-compat"),
				},
			},
		},
	})
	configs.Register(Config{
		name:       "ec2",
		fetch:      ec2.FetchConfig,
		newFetcher: ec2.NewFetcher,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"},
					{Name: "etcd2.service", Dropins: []types.Dropin{
						{Name: "10-oem.conf", Contents: "[Service]\nEnvironment=ETCD_ELECTION_TIMEOUT=1200\n"},
					}},
				},
			},
		},
		defaultUserConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Mask: true, Name: "user-configdrive.service"},
					{Mask: true, Name: "user-configvirtfs.service"},
					userCloudInit("EC2", "ec2-compat"),
				},
			},
		},
	})
	configs.Register(Config{
		name:  "exoscale",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "gce",
		fetch: gce.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"},
					{Enabled: yes, Name: "oem-gce.service"},
				},
			},
			Storage: types.Storage{
				Files: []types.File{
					serviceFromOem("oem-gce.service"),
					{
						Node: types.Node{
							Filesystem: "root",
							Path:       "/etc/hosts",
						},
						FileEmbedded1: types.FileEmbedded1{
							Mode:     0444,
							Contents: contentsFromString("169.254.169.254 metadata\n127.0.0.1 localhost\n"),
						},
					},
					{
						Node: types.Node{
							Filesystem: "root",
							Path:       "/etc/profile.d/google-cloud-sdk.sh",
						},
						FileEmbedded1: types.FileEmbedded1{
							Mode: 0444,
							Contents: contentsFromString(`#!/bin/sh
alias gcloud="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/root/.config -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker google/cloud-sdk gcloud"
alias gsutil="(docker images google/cloud-sdk || docker pull google/cloud-sdk) > /dev/null;docker run -t -i --net="host" -v $HOME/.config:/root/.config google/cloud-sdk gsutil"
`),
						},
					},
				},
			},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("GCE", "gce")}}},
	})
	configs.Register(Config{
		name:  "hyperv",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "niftycloud",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "packet",
		fetch: packet.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"},
					{Enabled: yes, Name: "packet-phone-home.service"},
				},
			},
			Storage: types.Storage{Files: []types.File{serviceFromOem("packet-phone-home.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("Packet", "packet")}}},
	})
	configs.Register(Config{
		name:  "pxe",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "rackspace",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "rackspace-onmetal",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "vagrant",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "vagrant-virtualbox",
		fetch: virtualbox.FetchConfig,
	})
	configs.Register(Config{
		name:  "virtualbox",
		fetch: virtualbox.FetchConfig,
	})
	configs.Register(Config{
		name:  "vmware",
		fetch: vmware.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{Units: []types.Unit{{Enabled: yes, Name: "vmtoolsd.service"}}},
			Storage: types.Storage{Files: []types.File{serviceFromOem("vmtoolsd.service")}},
		},
		defaultUserConfig: types.Config{Systemd: types.Systemd{Units: []types.Unit{userCloudInit("VMware", "vmware")}}},
	})
	configs.Register(Config{
		name:  "interoute",
		fetch: noop.FetchConfig,
	})
	configs.Register(Config{
		name:  "qemu",
		fetch: qemu.FetchConfig,
	})
	configs.Register(Config{
		name:  "file",
		fetch: file.FetchConfig,
	})
	configs.Register(Config{
		name:  "oracle-oci",
		fetch: oracleoci.FetchConfig,
		baseConfig: types.Config{
			Systemd: types.Systemd{
				Units: []types.Unit{
					{Enabled: yes, Name: "coreos-metadata-sshkeys@.service"},
					{Enabled: yes, Name: "iscsid.service"},
					{Enabled: yes, Name: "oracle-oci-root-setup.service"},
					{Enabled: yes, Name: "oracle-oci-iptables.service"},
				},
			},
			Storage: types.Storage{
				Files: []types.File{
					serviceFromOem("oracle-oci-root-setup.service"),
					serviceFromOem("oracle-oci-iptables.service"),
				},
			},
		},
	})
}

func Get(name string) (config Config, ok bool) {
	config, ok = configs.Get(name).(Config)
	return
}

func MustGet(name string) Config {
	if config, ok := Get(name); ok {
		return config
	} else {
		panic(fmt.Sprintf("invalid OEM name %q provided", name))
	}
}

func Names() (names []string) {
	return configs.Names()
}

func contentsFromString(data string) types.FileContents {
	return types.FileContents{
		Source: (&url.URL{
			Scheme: "data",
			Opaque: "," + dataurl.EscapeString(data),
		}).String(),
	}
}

func contentsFromOem(path string) types.FileContents {
	return types.FileContents{
		Source: (&url.URL{
			Scheme: "oem",
			Path:   path,
		}).String(),
	}
}

func userCloudInit(name string, oem string) types.Unit {
	contents := `[Unit]
Description=Cloudinit from %s metadata

[Service]
Type=oneshot
ExecStart=/usr/bin/coreos-cloudinit --oem=%s

[Install]
WantedBy=multi-user.target
`

	return types.Unit{
		Name:     "oem-cloudinit.service",
		Enabled:  yes,
		Contents: fmt.Sprintf(contents, name, oem),
	}
}

func serviceFromOem(unit string) types.File {
	return types.File{
		Node: types.Node{
			Filesystem: "root",
			Path:       "/etc/systemd/system/" + unit,
		},
		FileEmbedded1: types.FileEmbedded1{
			Mode:     0444,
			Contents: contentsFromOem("/units/" + unit),
		},
	}
}
<|endoftext|>


<commit_before>package interval

import (
	"encoding/json"
	"errors"
)

// ErrInvalidMessageType defines the message value extracting error
var ErrInvalidMessageType = errors.New(`invalid message type`)

type messageValue interface {
	Value() interface{}
}

type message struct {
	v interface{}
}

// Unical message ID (depends on transport)
func (m *message) ID() string {
	return ""
}

// Body returns message data as bytes
func (m *message) Body() (d []byte) {
	switch v := m.v.(type) {
	case []byte:
		d = v
	case string:
		d = []byte(v)
	default:
		d, _ = json.Marshal(m)
	}
	return d
}

// Acknowledgment of the message processing
func (m *message) Ack() error {
	return nil
}

// Value returns value of the message
func (m *message) Value() interface{} {
	return m.v
}

// MessageValue take the target value from the message
func MessageValue(m interface{}) interface{} {
	switch v := m.(type) {
	case messageValue:
		return v.Value()
	}
	panic(ErrInvalidMessageType)
}
<commit_msg>fix interval message body<commit_after>package interval

import (
	"encoding/json"
	"errors"
)

// ErrInvalidMessageType defines the message value extracting error
var ErrInvalidMessageType = errors.New(`invalid message type`)

type messageValue interface {
	Value() interface{}
}

type message struct {
	v interface{}
}

// Unical message ID (depends on transport)
func (m *message) ID() string {
	return ""
}

// Body returns message data as bytes
func (m *message) Body() (d []byte) {
	switch v := m.v.(type) {
	case []byte:
		d = v
	case string:
		d = []byte(v)
	default:
		d, _ = json.Marshal(m.v)
	}
	return d
}

// Acknowledgment of the message processing
func (m *message) Ack() error {
	return nil
}

// Value returns value of the message
func (m *message) Value() interface{} {
	return m.v
}

// MessageValue take the target value from the message
func MessageValue(m interface{}) interface{} {
	switch v := m.(type) {
	case messageValue:
		return v.Value()
	}
	panic(ErrInvalidMessageType)
}
<|endoftext|>


<commit_before>// Copyright 2020 Martin Holst Swende. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the COPYING file.
//

package uint256

import (
	"bytes"
	"math/big"
	"testing"
)

func TestFromBig(t *testing.T) {
	a := new(big.Int)
	b, o := FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}

	a = big.NewInt(1)
	b, o = FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}

	a = big.NewInt(0x1000000000000000)
	b, o = FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}

	a = big.NewInt(0x1234)
	b, o = FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}

	a = big.NewInt(1)
	a.Lsh(a, 256)

	b, o = FromBig(a)
	if !o {
		t.Fatalf("expected overflow")
	}
	if !b.Eq(new(Int)) {
		t.Fatalf("got %x exp 0", b.Bytes())
	}

	a.Sub(a, big.NewInt(1))
	b, o = FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}
}

func TestFromBigOverflow(t *testing.T) {
	_, o := FromBig(new(big.Int).SetBytes(hex2Bytes("ababee444444444444ffcc333333333333ddaa222222222222bb8811111111111199")))
	if !o {
		t.Errorf("expected overflow, got %v", o)
	}
	_, o = FromBig(new(big.Int).SetBytes(hex2Bytes("ee444444444444ffcc333333333333ddaa222222222222bb8811111111111199")))
	if o {
		t.Errorf("expected no overflow, got %v", o)
	}
	b := new(big.Int).SetBytes(hex2Bytes("ee444444444444ffcc333333333333ddaa222222222222bb8811111111111199"))
	_, o = FromBig(b.Neg(b))
	if o {
		t.Errorf("expected no overflow, got %v", o)
	}
}

func benchmarkSetFromBig(bench *testing.B, b *big.Int) Int {
	var f Int
	for i := 0; i < bench.N; i++ {
		f.SetFromBig(b)
	}
	return f
}

func BenchmarkSetFromBig(bench *testing.B) {
	param1 := big.NewInt(0xff)
	bench.Run("1word", func(bench *testing.B) { benchmarkSetFromBig(bench, param1) })

	param2 := new(big.Int).Lsh(param1, 64)
	bench.Run("2words", func(bench *testing.B) { benchmarkSetFromBig(bench, param2) })

	param3 := new(big.Int).Lsh(param2, 64)
	bench.Run("3words", func(bench *testing.B) { benchmarkSetFromBig(bench, param3) })

	param4 := new(big.Int).Lsh(param3, 64)
	bench.Run("4words", func(bench *testing.B) { benchmarkSetFromBig(bench, param4) })

	param5 := new(big.Int).Lsh(param4, 64)
	bench.Run("overflow", func(bench *testing.B) { benchmarkSetFromBig(bench, param5) })
}<commit_msg>test: Add benchmark for ToBig()<commit_after>// Copyright 2020 Martin Holst Swende. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the COPYING file.
//

package uint256

import (
	"bytes"
	"math/big"
	"testing"
)

func TestFromBig(t *testing.T) {
	a := new(big.Int)
	b, o := FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}

	a = big.NewInt(1)
	b, o = FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}

	a = big.NewInt(0x1000000000000000)
	b, o = FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}

	a = big.NewInt(0x1234)
	b, o = FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}

	a = big.NewInt(1)
	a.Lsh(a, 256)

	b, o = FromBig(a)
	if !o {
		t.Fatalf("expected overflow")
	}
	if !b.Eq(new(Int)) {
		t.Fatalf("got %x exp 0", b.Bytes())
	}

	a.Sub(a, big.NewInt(1))
	b, o = FromBig(a)
	if o {
		t.Fatalf("conversion overflowed! big.Int %x", a.Bytes())
	}
	if exp, got := a.Bytes(), b.Bytes(); !bytes.Equal(got, exp) {
		t.Fatalf("got %x exp %x", got, exp)
	}
}

func TestFromBigOverflow(t *testing.T) {
	_, o := FromBig(new(big.Int).SetBytes(hex2Bytes("ababee444444444444ffcc333333333333ddaa222222222222bb8811111111111199")))
	if !o {
		t.Errorf("expected overflow, got %v", o)
	}
	_, o = FromBig(new(big.Int).SetBytes(hex2Bytes("ee444444444444ffcc333333333333ddaa222222222222bb8811111111111199")))
	if o {
		t.Errorf("expected no overflow, got %v", o)
	}
	b := new(big.Int).SetBytes(hex2Bytes("ee444444444444ffcc333333333333ddaa222222222222bb8811111111111199"))
	_, o = FromBig(b.Neg(b))
	if o {
		t.Errorf("expected no overflow, got %v", o)
	}
}

func benchmarkSetFromBig(bench *testing.B, b *big.Int) Int {
	var f Int
	for i := 0; i < bench.N; i++ {
		f.SetFromBig(b)
	}
	return f
}

func BenchmarkSetFromBig(bench *testing.B) {
	param1 := big.NewInt(0xff)
	bench.Run("1word", func(bench *testing.B) { benchmarkSetFromBig(bench, param1) })

	param2 := new(big.Int).Lsh(param1, 64)
	bench.Run("2words", func(bench *testing.B) { benchmarkSetFromBig(bench, param2) })

	param3 := new(big.Int).Lsh(param2, 64)
	bench.Run("3words", func(bench *testing.B) { benchmarkSetFromBig(bench, param3) })

	param4 := new(big.Int).Lsh(param3, 64)
	bench.Run("4words", func(bench *testing.B) { benchmarkSetFromBig(bench, param4) })

	param5 := new(big.Int).Lsh(param4, 64)
	bench.Run("overflow", func(bench *testing.B) { benchmarkSetFromBig(bench, param5) })
}

func benchmarkToBig(bench *testing.B, f *Int) *big.Int {
	var b *big.Int
	for i := 0; i < bench.N; i++ {
		b = f.ToBig()
	}
	return b
}

func BenchmarkToBig(bench *testing.B) {
	param1 := new(Int).SetUint64(0xff)
	bench.Run("1word", func(bench *testing.B) { benchmarkToBig(bench, param1) })

	param2 := new(Int).Lsh(param1, 64)
	bench.Run("2words", func(bench *testing.B) { benchmarkToBig(bench, param2) })

	param3 := new(Int).Lsh(param2, 64)
	bench.Run("3words", func(bench *testing.B) { benchmarkToBig(bench, param3) })

	param4 := new(Int).Lsh(param3, 64)
	bench.Run("4words", func(bench *testing.B) { benchmarkToBig(bench, param4) })
}
<|endoftext|>


<commit_before>package convert

import (
	"crypto/md5"
	"fmt"
	"strconv"
	"strings"
	"time"
)

func Int(val interface{}) int64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return int64(val.(float64))
		case int64:
			return val.(int64)
		default:
			ret, err := strconv.ParseInt(String(val), 10, 64)
			if err != nil {
				return 0
			} else {
				return ret
			}
		}
	}
	return 0
}

func IntWith(val interface{}, defaultValue int64) int64 {
	if val != nil {
		return Int(val)
	}
	return defaultValue
}

func Float(val interface{}) float64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return val.(float64)
		case int64:
			return float64(val.(int64))
		default:
			ret, err := strconv.ParseFloat(String(val), 64)
			if err != nil {
				return 0
			} else {
				return float64(ret)
			}
		}
	}
	return 0
}

func FloatWith(val interface{}, defaultValue float64) float64 {
	if val != nil {
		return Float(val)
	}
	return defaultValue
}

func String(val interface{}) string {
	switch val.(type) {
	case string:
		return val.(string)
	case []byte:
		return string(val.([]byte))
	case time.Time:
		t := val.(time.Time)
		return fmt.Sprintf("%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
	case nil:
		return ""
	default:
		return fmt.Sprintf("%v", val)
	}
}

func QueryString(val string) string {
	return strings.Join(strings.Split(val, "'"), "''")
}

func MD5(src string) string {
	return fmt.Sprintf("%x", md5.Sum([]byte(src)))
}
<commit_msg>fix bug<commit_after>package convert

import (
	"crypto/md5"
	"fmt"
	"strconv"
	"strings"
	"time"
)

func Int(val interface{}) int64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return int64(val.(float64))
		case int64:
			return val.(int64)
		default:
			ret, err := strconv.ParseInt(String(val), 10, 64)
			if err != nil {
				return 0
			} else {
				return ret
			}
		}
	}
	return 0
}

func IntWith(val interface{}, defaultValue int64) int64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return int64(val.(float64))
		case int64:
			return val.(int64)
		default:
			ret, err := strconv.ParseInt(String(val), 10, 64)
			if err != nil {
				return defaultValue
			} else {
				return ret
			}
		}
	}
	return defaultValue
}

func Float(val interface{}) float64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return val.(float64)
		case int64:
			return float64(val.(int64))
		default:
			ret, err := strconv.ParseFloat(String(val), 64)
			if err != nil {
				return 0
			} else {
				return float64(ret)
			}
		}
	}
	return 0
}

func FloatWith(val interface{}, defaultValue float64) float64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return val.(float64)
		case int64:
			return float64(val.(int64))
		default:
			ret, err := strconv.ParseFloat(String(val), 64)
			if err != nil {
				return defaultValue
			} else {
				return float64(ret)
			}
		}
	}
	return defaultValue
}

func String(val interface{}) string {
	switch val.(type) {
	case string:
		return val.(string)
	case []byte:
		return string(val.([]byte))
	case time.Time:
		t := val.(time.Time)
		return fmt.Sprintf("%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
	case nil:
		return ""
	default:
		return fmt.Sprintf("%v", val)
	}
}

func QueryString(val string) string {
	return strings.Join(strings.Split(val, "'"), "''")
}

func MD5(src string) string {
	return fmt.Sprintf("%x", md5.Sum([]byte(src)))
}
<|endoftext|>


<commit_before>/*
Copyright 2019 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.
*/

package kubelet

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"regexp"
	"strconv"
	"time"

	"k8s.io/apimachinery/pkg/util/wait"
	kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
	kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
	kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/config/scheme"

	"k8s.io/kubernetes/test/e2e/framework"
	e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"
)

// GetCurrentKubeletConfig fetches the current Kubelet Config for the given node
func GetCurrentKubeletConfig(nodeName, namespace string, useProxy bool) (*kubeletconfig.KubeletConfiguration, error) {
	resp := pollConfigz(5*time.Minute, 5*time.Second, nodeName, namespace, useProxy)
	if resp == nil {
		return nil, fmt.Errorf("failed to fetch /configz from %q", nodeName)
	}
	kubeCfg, err := decodeConfigz(resp)
	if err != nil {
		return nil, err
	}
	return kubeCfg, nil
}

// returns a status 200 response from the /configz endpoint or nil if fails
func pollConfigz(timeout time.Duration, pollInterval time.Duration, nodeName, namespace string, useProxy bool) *http.Response {
	endpoint := ""
	if useProxy {
		// start local proxy, so we can send graceful deletion over query string, rather than body parameter
		framework.Logf("Opening proxy to cluster")
		tk := e2ekubectl.NewTestKubeconfig(framework.TestContext.CertDir, framework.TestContext.Host, framework.TestContext.KubeConfig, framework.TestContext.KubeContext, framework.TestContext.KubectlPath, namespace)
		cmd := tk.KubectlCmd("proxy", "-p", "0")
		stdout, stderr, err := framework.StartCmdAndStreamOutput(cmd)
		framework.ExpectNoError(err)
		defer stdout.Close()
		defer stderr.Close()
		defer framework.TryKill(cmd)

		buf := make([]byte, 128)
		var n int
		n, err = stdout.Read(buf)
		framework.ExpectNoError(err)
		output := string(buf[:n])
		proxyRegexp := regexp.MustCompile("Starting to serve on 127.0.0.1:([0-9]+)")
		match := proxyRegexp.FindStringSubmatch(output)
		framework.ExpectEqual(len(match), 2)
		port, err := strconv.Atoi(match[1])
		framework.ExpectNoError(err)
		framework.Logf("http requesting node kubelet /configz")
		endpoint = fmt.Sprintf("http://127.0.0.1:%d/api/v1/nodes/%s/proxy/configz", port, nodeName)
	} else {
		endpoint = fmt.Sprintf("%s/api/v1/nodes/%s/proxy/configz", framework.TestContext.Host, framework.TestContext.NodeName)
	}
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	req, err := http.NewRequest("GET", endpoint, nil)
	framework.ExpectNoError(err)
	if !useProxy {
		req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", framework.TestContext.BearerToken))
	}
	req.Header.Add("Accept", "application/json")

	var resp *http.Response
	err = wait.PollImmediate(pollInterval, timeout, func() (bool, error) {
		resp, err = client.Do(req)
		if err != nil {
			framework.Logf("Failed to get /configz, retrying. Error: %v", err)
			return false, nil
		}
		if resp.StatusCode != 200 {
			framework.Logf("/configz response status not 200, retrying. Response was: %+v", resp)
			return false, nil
		}

		return true, nil
	})
	framework.ExpectNoError(err, "Failed to get successful response from /configz")
	return resp
}

// Decodes the http response from /configz and returns a kubeletconfig.KubeletConfiguration (internal type).
func decodeConfigz(resp *http.Response) (*kubeletconfig.KubeletConfiguration, error) {
	// This hack because /configz reports the following structure:
	// {"kubeletconfig": {the JSON representation of kubeletconfigv1beta1.KubeletConfiguration}}
	type configzWrapper struct {
		ComponentConfig kubeletconfigv1beta1.KubeletConfiguration `json:"kubeletconfig"`
	}

	configz := configzWrapper{}
	kubeCfg := kubeletconfig.KubeletConfiguration{}

	contentsBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	err = json.Unmarshal(contentsBytes, &configz)
	if err != nil {
		return nil, err
	}

	scheme, _, err := kubeletconfigscheme.NewSchemeAndCodecs()
	if err != nil {
		return nil, err
	}
	err = scheme.Convert(&configz.ComponentConfig, &kubeCfg, nil)
	if err != nil {
		return nil, err
	}

	return &kubeCfg, nil
}
<commit_msg>test/e2e: fix GetCurrentKubeletConfig<commit_after>/*
Copyright 2019 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.
*/

package kubelet

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"regexp"
	"strconv"
	"time"

	"k8s.io/apimachinery/pkg/util/wait"
	kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
	kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
	kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/config/scheme"

	"k8s.io/kubernetes/test/e2e/framework"
	e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"
)

// GetCurrentKubeletConfig fetches the current Kubelet Config for the given node
func GetCurrentKubeletConfig(nodeName, namespace string, useProxy bool) (*kubeletconfig.KubeletConfiguration, error) {
	resp := pollConfigz(5*time.Minute, 5*time.Second, nodeName, namespace, useProxy)
	if len(resp) == 0 {
		return nil, fmt.Errorf("failed to fetch /configz from %q", nodeName)
	}
	kubeCfg, err := decodeConfigz(resp)
	if err != nil {
		return nil, err
	}
	return kubeCfg, nil
}

// returns a status 200 response from the /configz endpoint or nil if fails
func pollConfigz(timeout time.Duration, pollInterval time.Duration, nodeName, namespace string, useProxy bool) []byte {
	endpoint := ""
	if useProxy {
		// start local proxy, so we can send graceful deletion over query string, rather than body parameter
		framework.Logf("Opening proxy to cluster")
		tk := e2ekubectl.NewTestKubeconfig(framework.TestContext.CertDir, framework.TestContext.Host, framework.TestContext.KubeConfig, framework.TestContext.KubeContext, framework.TestContext.KubectlPath, namespace)
		cmd := tk.KubectlCmd("proxy", "-p", "0")
		stdout, stderr, err := framework.StartCmdAndStreamOutput(cmd)
		framework.ExpectNoError(err)
		defer stdout.Close()
		defer stderr.Close()
		defer framework.TryKill(cmd)

		buf := make([]byte, 128)
		var n int
		n, err = stdout.Read(buf)
		framework.ExpectNoError(err)
		output := string(buf[:n])
		proxyRegexp := regexp.MustCompile("Starting to serve on 127.0.0.1:([0-9]+)")
		match := proxyRegexp.FindStringSubmatch(output)
		framework.ExpectEqual(len(match), 2)
		port, err := strconv.Atoi(match[1])
		framework.ExpectNoError(err)
		framework.Logf("http requesting node kubelet /configz")
		endpoint = fmt.Sprintf("http://127.0.0.1:%d/api/v1/nodes/%s/proxy/configz", port, nodeName)
	} else {
		endpoint = fmt.Sprintf("%s/api/v1/nodes/%s/proxy/configz", framework.TestContext.Host, framework.TestContext.NodeName)
	}
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{Transport: tr}
	req, err := http.NewRequest("GET", endpoint, nil)
	framework.ExpectNoError(err)
	if !useProxy {
		req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", framework.TestContext.BearerToken))
	}
	req.Header.Add("Accept", "application/json")

	var respBody []byte
	err = wait.PollImmediate(pollInterval, timeout, func() (bool, error) {
		resp, err := client.Do(req)
		if err != nil {
			framework.Logf("Failed to get /configz, retrying. Error: %v", err)
			return false, nil
		}
		defer resp.Body.Close()

		if resp.StatusCode != 200 {
			framework.Logf("/configz response status not 200, retrying. Response was: %+v", resp)
			return false, nil
		}

		respBody, err = io.ReadAll(resp.Body)
		if err != nil {
			framework.Logf("failed to read body from /configz response, retrying. Error: %v", err)
			return false, nil
		}

		return true, nil
	})
	framework.ExpectNoError(err, "Failed to get successful response from /configz")

	return respBody
}

// Decodes the http response from /configz and returns a kubeletconfig.KubeletConfiguration (internal type).
func decodeConfigz(respBody []byte) (*kubeletconfig.KubeletConfiguration, error) {
	// This hack because /configz reports the following structure:
	// {"kubeletconfig": {the JSON representation of kubeletconfigv1beta1.KubeletConfiguration}}
	type configzWrapper struct {
		ComponentConfig kubeletconfigv1beta1.KubeletConfiguration `json:"kubeletconfig"`
	}

	configz := configzWrapper{}
	kubeCfg := kubeletconfig.KubeletConfiguration{}

	err := json.Unmarshal(respBody, &configz)
	if err != nil {
		return nil, err
	}

	scheme, _, err := kubeletconfigscheme.NewSchemeAndCodecs()
	if err != nil {
		return nil, err
	}
	err = scheme.Convert(&configz.ComponentConfig, &kubeCfg, nil)
	if err != nil {
		return nil, err
	}

	return &kubeCfg, nil
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Skaffold 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.
*/

package integration

import (
	"encoding/json"
	"testing"
	"time"

	"github.com/GoogleContainerTools/skaffold/integration/skaffold"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/debug"
	"github.com/GoogleContainerTools/skaffold/proto"
)

func TestDebug(t *testing.T) {
	MarkIntegrationTest(t, CanRunWithoutGcp)

	tests := []struct {
		description string
		config      string
		args        []string
		deployments []string
		pods        []string
	}{
		{
			description: "kubectl",
			deployments: []string{"java"},
			pods:        []string{"nodejs", "npm", "python3", "go"},
		},
		{
			description: "kustomize",
			args:        []string{"--profile", "kustomize"},
			deployments: []string{"java"},
			pods:        []string{"nodejs", "npm", "python3", "go"},
		},
		{
			description: "buildpacks",
			args:        []string{"--profile", "buildpacks"},
			deployments: []string{"java"},
			pods:        []string{"nodejs", "npm", "python3", "go"},
		},
	}
	for _, test := range tests {
		t.Run(test.description, func(t *testing.T) {
			// Run skaffold build first to fail quickly on a build failure
			skaffold.Build(test.args...).InDir("testdata/debug").RunOrFail(t)

			ns, client := SetupNamespace(t)

			skaffold.Debug(test.args...).InDir("testdata/debug").InNs(ns.Name).RunBackground(t)

			verifyDebugAnnotations := func(annotations map[string]string) {
				var configs map[string]debug.ContainerDebugConfiguration
				if anno, found := annotations["debug.cloud.google.com/config"]; !found {
					t.Errorf("deployment missing debug annotation: %v", annotations)
				} else if err := json.Unmarshal([]byte(anno), &configs); err != nil {
					t.Errorf("error unmarshalling debug annotation: %v: %v", anno, err)
				} else {
					for k, config := range configs {
						if config.WorkingDir == "" {
							t.Errorf("debug config for %q missing WorkingDir: %v: %v", k, anno, config)
						}
						if config.Runtime == "" {
							t.Errorf("debug config for %q missing Runtime: %v: %v", k, anno, config)
						}
					}
				}
			}

			for _, depName := range test.deployments {
				deploy := client.GetDeployment(depName)

				annotations := deploy.Spec.Template.GetAnnotations()
				verifyDebugAnnotations(annotations)
			}
			for _, podName := range test.pods {
				pod := client.GetPod(podName)

				annotations := pod.Annotations
				verifyDebugAnnotations(annotations)
			}
		})
	}
}

func TestDebugEventsRPC_StatusCheck(t *testing.T) {
	MarkIntegrationTest(t, CanRunWithoutGcp)

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build().InDir("testdata/jib").RunOrFail(t)

	ns, client := SetupNamespace(t)

	rpcAddr := randomPort()
	skaffold.Debug("--enable-rpc", "--rpc-port", rpcAddr).InDir("testdata/jib").InNs(ns.Name).RunBackground(t)

	waitForDebugEvent(t, client, rpcAddr)
}

func TestDebugEventsRPC_NoStatusCheck(t *testing.T) {
	MarkIntegrationTest(t, CanRunWithoutGcp)

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build().InDir("testdata/jib").RunOrFail(t)

	ns, client := SetupNamespace(t)

	rpcAddr := randomPort()
	skaffold.Debug("--enable-rpc", "--rpc-port", rpcAddr, "--status-check=false").InDir("testdata/jib").InNs(ns.Name).RunBackground(t)

	waitForDebugEvent(t, client, rpcAddr)
}

func waitForDebugEvent(t *testing.T, client *NSKubernetesClient, rpcAddr string) {
	client.WaitForPodsReady()

	_, entries := apiEvents(t, rpcAddr)

	timeout := time.After(1 * time.Minute)
	for {
		select {
		case <-timeout:
			t.Fatalf("timed out waiting for debugging event")
		case entry := <-entries:
			switch entry.Event.GetEventType().(type) {
			case *proto.Event_DebuggingContainerEvent:
				// success!
				return
			default:
			}
		}
	}
}
<commit_msg>check pods before deployments<commit_after>/*
Copyright 2019 The Skaffold 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.
*/

package integration

import (
	"encoding/json"
	"testing"
	"time"

	"github.com/GoogleContainerTools/skaffold/integration/skaffold"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/debug"
	"github.com/GoogleContainerTools/skaffold/proto"
)

func TestDebug(t *testing.T) {
	MarkIntegrationTest(t, CanRunWithoutGcp)

	tests := []struct {
		description string
		config      string
		args        []string
		deployments []string
		pods        []string
	}{
		{
			description: "kubectl",
			deployments: []string{"java"},
			pods:        []string{"nodejs", "npm", "python3", "go"},
		},
		{
			description: "kustomize",
			args:        []string{"--profile", "kustomize"},
			deployments: []string{"java"},
			pods:        []string{"nodejs", "npm", "python3", "go"},
		},
		{
			description: "buildpacks",
			args:        []string{"--profile", "buildpacks"},
			deployments: []string{"java"},
			pods:        []string{"nodejs", "npm", "python3", "go"},
		},
	}
	for _, test := range tests {
		t.Run(test.description, func(t *testing.T) {
			// Run skaffold build first to fail quickly on a build failure
			skaffold.Build(test.args...).InDir("testdata/debug").RunOrFail(t)

			ns, client := SetupNamespace(t)

			skaffold.Debug(test.args...).InDir("testdata/debug").InNs(ns.Name).RunBackground(t)

			verifyDebugAnnotations := func(annotations map[string]string) {
				var configs map[string]debug.ContainerDebugConfiguration
				if anno, found := annotations["debug.cloud.google.com/config"]; !found {
					t.Errorf("deployment missing debug annotation: %v", annotations)
				} else if err := json.Unmarshal([]byte(anno), &configs); err != nil {
					t.Errorf("error unmarshalling debug annotation: %v: %v", anno, err)
				} else {
					for k, config := range configs {
						if config.WorkingDir == "" {
							t.Errorf("debug config for %q missing WorkingDir: %v: %v", k, anno, config)
						}
						if config.Runtime == "" {
							t.Errorf("debug config for %q missing Runtime: %v: %v", k, anno, config)
						}
					}
				}
			}

			for _, podName := range test.pods {
				pod := client.GetPod(podName)

				annotations := pod.Annotations
				verifyDebugAnnotations(annotations)
			}

			for _, depName := range test.deployments {
				deploy := client.GetDeployment(depName)

				annotations := deploy.Spec.Template.GetAnnotations()
				verifyDebugAnnotations(annotations)
			}
		})
	}
}

func TestDebugEventsRPC_StatusCheck(t *testing.T) {
	MarkIntegrationTest(t, CanRunWithoutGcp)

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build().InDir("testdata/jib").RunOrFail(t)

	ns, client := SetupNamespace(t)

	rpcAddr := randomPort()
	skaffold.Debug("--enable-rpc", "--rpc-port", rpcAddr).InDir("testdata/jib").InNs(ns.Name).RunBackground(t)

	waitForDebugEvent(t, client, rpcAddr)
}

func TestDebugEventsRPC_NoStatusCheck(t *testing.T) {
	MarkIntegrationTest(t, CanRunWithoutGcp)

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build().InDir("testdata/jib").RunOrFail(t)

	ns, client := SetupNamespace(t)

	rpcAddr := randomPort()
	skaffold.Debug("--enable-rpc", "--rpc-port", rpcAddr, "--status-check=false").InDir("testdata/jib").InNs(ns.Name).RunBackground(t)

	waitForDebugEvent(t, client, rpcAddr)
}

func waitForDebugEvent(t *testing.T, client *NSKubernetesClient, rpcAddr string) {
	client.WaitForPodsReady()

	_, entries := apiEvents(t, rpcAddr)

	timeout := time.After(1 * time.Minute)
	for {
		select {
		case <-timeout:
			t.Fatalf("timed out waiting for debugging event")
		case entry := <-entries:
			switch entry.Event.GetEventType().(type) {
			case *proto.Event_DebuggingContainerEvent:
				// success!
				return
			default:
			}
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 Politecnico di Torino
//
// 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"
	"os"
	"time"

	"github.com/netgroup-polito/iovisor-ovn/cli"
	"github.com/netgroup-polito/iovisor-ovn/config"
	l "github.com/op/go-logging"

	"github.com/netgroup-polito/iovisor-ovn/common"
	"github.com/netgroup-polito/iovisor-ovn/mainlogic"
	"github.com/netgroup-polito/iovisor-ovn/servicetopology"
)

var log = l.MustGetLogger("iovisor-ovn-daemon")

func init() {

	flag.StringVar(&config.TopologyFile, "topologyFile", "", "path to topology file")

	flag.StringVar(&config.Nb, "nb", config.Nb, "nb db address:port")
	flag.StringVar(&config.Sb, "sb", config.Sb, "sb db address:port")
	flag.StringVar(&config.Ovs, "ovs", config.Ovs, "ovs db address:port")

	flag.StringVar(&config.NbSock, "nbsock", config.NbSock, "nb db local .sock file")
	flag.StringVar(&config.SbSock, "sbsock", config.SbSock, "sb db local .sock file")
	flag.StringVar(&config.OvsSock, "ovssock", config.OvsSock, "ovs db local .sock file")

	flag.BoolVar(&config.Sandbox, "sandbox", false, "connect to sandbox with local .sock files")
	flag.BoolVar(&config.TestEnv, "testenv", false, "enable testenv")

	flag.BoolVar(&config.Debug, "debug", false, "enable DEBUG level in logger")
	flag.BoolVar(&config.Info, "info", true, "enable INFO  level in logger")

	flag.StringVar(&config.Hover, "hover", config.Hover, "hover url")
}

//Start iovisor-ovn Daemon
func main() {

	//Parse Cmdline args
	flag.Parse()
	config.PrintConfig()

	//Init Logger
	common.LogInit()

	if config.TopologyFile != "" {
		// topologyFile has been passed, deploy this without connecting to OVN
		err := servicetopology.DeployTopology(config.TopologyFile)
		if err != nil {
			log.Errorf("Error deploying topology, please verify your topology file");
		}
		log.Infof("Press enter to close");
		bufio.NewReader(os.Stdin).ReadBytes('\n')
		// TODO: defer call to servicetopologyUndeploy
	} else {
		// topologyFile argument was not passed, then connect to OVN
		//Monitors started here!
		mainlogic.MainLogic()

		// Cli start
		time.Sleep(1 * time.Second)
		go cli.Cli(mainlogic.Dataplane)

		quit := make(chan bool)
		<-quit
	}
}
<commit_msg>iovisorovnd: print configuration only in OpensStack/OVN mode<commit_after>// Copyright 2016 Politecnico di Torino
//
// 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"
	"os"
	"time"

	"github.com/netgroup-polito/iovisor-ovn/cli"
	"github.com/netgroup-polito/iovisor-ovn/config"
	l "github.com/op/go-logging"

	"github.com/netgroup-polito/iovisor-ovn/common"
	"github.com/netgroup-polito/iovisor-ovn/mainlogic"
	"github.com/netgroup-polito/iovisor-ovn/servicetopology"
)

var log = l.MustGetLogger("iovisor-ovn-daemon")

func init() {

	flag.StringVar(&config.TopologyFile, "topologyFile", "", "path to topology file")

	flag.StringVar(&config.Nb, "nb", config.Nb, "nb db address:port")
	flag.StringVar(&config.Sb, "sb", config.Sb, "sb db address:port")
	flag.StringVar(&config.Ovs, "ovs", config.Ovs, "ovs db address:port")

	flag.StringVar(&config.NbSock, "nbsock", config.NbSock, "nb db local .sock file")
	flag.StringVar(&config.SbSock, "sbsock", config.SbSock, "sb db local .sock file")
	flag.StringVar(&config.OvsSock, "ovssock", config.OvsSock, "ovs db local .sock file")

	flag.BoolVar(&config.Sandbox, "sandbox", false, "connect to sandbox with local .sock files")
	flag.BoolVar(&config.TestEnv, "testenv", false, "enable testenv")

	flag.BoolVar(&config.Debug, "debug", false, "enable DEBUG level in logger")
	flag.BoolVar(&config.Info, "info", true, "enable INFO  level in logger")

	flag.StringVar(&config.Hover, "hover", config.Hover, "hover url")
}

//Start iovisor-ovn Daemon
func main() {

	//Parse Cmdline args
	flag.Parse()

	//Init Logger
	common.LogInit()

	if config.TopologyFile != "" {
		// topologyFile has been passed, deploy this without connecting to OVN
		err := servicetopology.DeployTopology(config.TopologyFile)
		if err != nil {
			log.Errorf("Error deploying topology, please verify your topology file");
		}
		log.Infof("Press enter to close");
		bufio.NewReader(os.Stdin).ReadBytes('\n')
		// TODO: defer call to servicetopologyUndeploy
	} else {
		// topologyFile argument was not passed, then connect to OVN
		config.PrintConfig()
		//Monitors started here!
		mainlogic.MainLogic()

		// Cli start
		time.Sleep(1 * time.Second)
		go cli.Cli(mainlogic.Dataplane)

		quit := make(chan bool)
		<-quit
	}
}
<|endoftext|>


<commit_before>package loginsight

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"

	"github.com/cloudfoundry-community/firehose-to-syslog/logging"
)

type LogInsight struct {
	LogInsightServer         *string
	LogInsightPort           *int
	LogInsightBatchSize      *int
	LogInsightReservedFields []string
	LogInsightAgentID        *string
	Messages                 Messages
}

//NewLogging - Creates new instance of LogInsight that implments logging.Logging interface
func NewLogging(logInsightServer *string, logInsightPort, logInsightBatchSize *int, logInsightReservedFields *string, logInsightAgentID *string) logging.Logging {
	return &LogInsight{
		LogInsightServer:         logInsightServer,
		LogInsightPort:           logInsightPort,
		LogInsightBatchSize:      logInsightBatchSize,
		LogInsightReservedFields: strings.Split(*logInsightReservedFields, ","),
		LogInsightAgentID:        logInsightAgentID,
		Messages:                 Messages{},
	}
}

func (l *LogInsight) Connect() bool {
	return true
}

func (l *LogInsight) CreateKey(k string) string {
	if contains(l.LogInsightReservedFields, k) {
		return "cf_" + k
	} else {
		return k
	}
}

func contains(s []string, e string) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}
func (l *LogInsight) ShipEvents(eventFields map[string]interface{}, msg string) {
	message := Message{
		Text: msg,
	}
	for k, v := range eventFields {
		if k == "timestamp" {
			message.Timestamp = v.(int64)
		} else {
			message.Fields = append(message.Fields, Field{Name: l.CreateKey(k), Content: fmt.Sprint(v)})
		}
	}
	l.Messages.Messages = append(l.Messages.Messages, message)

	if len(l.Messages.Messages) >= *l.LogInsightBatchSize {
		if jsonstr, err := json.Marshal(l.Messages); err == nil {
			url := fmt.Sprintf("https://%s:%d/api/v1/messages/ingest/%s", *l.LogInsightServer, *l.LogInsightPort, *l.LogInsightAgentID)
			tr := &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
			var req *http.Request
			var resp *http.Response
			if req, err = http.NewRequest("POST", url, bytes.NewBuffer(jsonstr)); err == nil {
				req.Header.Add("Content-Type", "application/json")
				client := &http.Client{Transport: tr}
				if resp, err = client.Do(req); err == nil {
					defer resp.Body.Close()
					if resp.StatusCode != 200 {
						body, _ := ioutil.ReadAll(resp.Body)
						logging.LogError(fmt.Sprintf("Error posting data to log insight with status %d and payload %s", resp.StatusCode, string(jsonstr)), string(body))
						fmt.Println("response Status:", resp.Status)
						fmt.Println("response Headers:", resp.Header)
						fmt.Println("response Body:", string(body))
					} else {
						l.Messages = Messages{}
					}
				} else {
					logging.LogError("Error sending data", err)
				}
			} else {
				logging.LogError("Error creating request", err)
			}
		} else {
			logging.LogError("Error marshalling", err)
		}
	}
}

type Messages struct {
	Messages []Message `json:"messages"`
}

type Message struct {
	Fields    []Field `json:"fields"`
	Text      string  `json:"text"`
	Timestamp int64   `json:"timestamp"`
}

type Field struct {
	Name    string `json:"name"`
	Content string `json:"content"`
}
<commit_msg>Make HTTP calls to LogInsight asynchronous, so that it can unblock websocket ping/pong exchanges<commit_after>package loginsight

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"

	"github.com/cloudfoundry-community/firehose-to-syslog/logging"
)

type LogInsight struct {
	LogInsightServer         *string
	LogInsightPort           *int
	LogInsightBatchSize      *int
	LogInsightReservedFields []string
	LogInsightAgentID        *string
	Messages                 Messages
	LogInsightClient         *http.Client
}

//NewLogging - Creates new instance of LogInsight that implments logging.Logging interface
func NewLogging(logInsightServer *string, logInsightPort, logInsightBatchSize *int, logInsightReservedFields *string, logInsightAgentID *string) logging.Logging {
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}

	baseClient := &http.Client{Transport: tr}

	return &LogInsight{
		LogInsightServer:         logInsightServer,
		LogInsightPort:           logInsightPort,
		LogInsightBatchSize:      logInsightBatchSize,
		LogInsightReservedFields: strings.Split(*logInsightReservedFields, ","),
		LogInsightAgentID:        logInsightAgentID,
		Messages:                 Messages{},
		LogInsightClient:         baseClient,
	}
}

func (l *LogInsight) Connect() bool {
	return true
}

func (l *LogInsight) CreateKey(k string) string {
	if contains(l.LogInsightReservedFields, k) {
		return "cf_" + k
	} else {
		return k
	}
}

func contains(s []string, e string) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}

func (l *LogInsight) ShipEvents(eventFields map[string]interface{}, msg string) {
	message := Message{
		Text: msg,
	}
	for k, v := range eventFields {
		if k == "timestamp" {
			message.Timestamp = v.(int64)
		} else {
			message.Fields = append(message.Fields, Field{Name: l.CreateKey(k), Content: fmt.Sprint(v)})
		}
	}

	l.Messages.Messages = append(l.Messages.Messages, message)
	if len(l.Messages.Messages) >= *l.LogInsightBatchSize {

		jsonBuffer := new(bytes.Buffer)
		encoder := json.NewEncoder(jsonBuffer)

		if err := encoder.Encode(l.Messages); err == nil {
			url := fmt.Sprintf("https://%s:%d/api/v1/messages/ingest/%s", *l.LogInsightServer, *l.LogInsightPort, *l.LogInsightAgentID)

			var req *http.Request
			if req, err = http.NewRequest("POST", url, jsonBuffer); err == nil {
				defer req.Body.Close()

				req.Header.Add("Content-Type", "application/json")
				go l.handleLogInsightResponse(req, jsonBuffer)
			} else {
				logging.LogError("Error creating request", err)
			}
		} else {
			logging.LogError("Error marshalling", err)
		}

		jsonBuffer = nil
		encoder = nil
	}

	message.Fields = nil
	l.Messages.Messages = nil
}

func (l *LogInsight) handleLogInsightResponse(req *http.Request, jsonBuffer *bytes.Buffer) func() {
	return func() {
		if resp, err := l.LogInsightClient.Do(req); err == nil {
			defer resp.Body.Close()

			if resp.StatusCode != 200 {
				body, _ := ioutil.ReadAll(resp.Body)
				logging.LogError(fmt.Sprintf("Error posting data to log insight with status %d and payload %s", resp.StatusCode, jsonBuffer.String()), string(body))
				fmt.Println("response Status:", resp.Status)
				fmt.Println("response Headers:", resp.Header)
				fmt.Println("response Body:", string(body))
			} else {
				l.Messages = Messages{}
			}
		} else {
			logging.LogError("Error sending data", err)
		}
		jsonBuffer = nil
	}
}

type Messages struct {
	Messages []Message `json:"messages"`
}

type Message struct {
	Fields    []Field `json:"fields"`
	Text      string  `json:"text"`
	Timestamp int64   `json:"timestamp"`
}

type Field struct {
	Name    string `json:"name"`
	Content string `json:"content"`
}
<|endoftext|>