mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
Merge branch 'master' into joakimr-axis_noawk
This commit is contained in:
commit
6d07cb47b7
40
install.sh
40
install.sh
@ -167,7 +167,7 @@ setup_env() {
|
||||
|
||||
# --- use sudo if we are not already root ---
|
||||
SUDO=sudo
|
||||
if [ `id -u` = 0 ]; then
|
||||
if [ $(id -u) -eq 0 ]; then
|
||||
SUDO=
|
||||
fi
|
||||
|
||||
@ -207,7 +207,7 @@ setup_env() {
|
||||
fi
|
||||
|
||||
# --- get hash of config & exec for currently installed k3s ---
|
||||
PRE_INSTALL_HASHES=`get_installed_hashes`
|
||||
PRE_INSTALL_HASHES=$(get_installed_hashes)
|
||||
|
||||
# --- if bin directory is read only skip download ---
|
||||
if [ "${INSTALL_K3S_BIN_DIR_READ_ONLY}" = "true" ]; then
|
||||
@ -232,7 +232,7 @@ verify_k3s_is_executable() {
|
||||
# --- set arch and suffix, fatal if architecture not supported ---
|
||||
setup_verify_arch() {
|
||||
if [ -z "$ARCH" ]; then
|
||||
ARCH=`uname -m`
|
||||
ARCH=$(uname -m)
|
||||
fi
|
||||
case $ARCH in
|
||||
amd64)
|
||||
@ -262,14 +262,14 @@ setup_verify_arch() {
|
||||
|
||||
# --- fatal if no curl ---
|
||||
verify_curl() {
|
||||
if [ -z `which curl || true` ]; then
|
||||
if [ -z $(which curl || true) ]; then
|
||||
fatal "Can not find curl for downloading files"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- create tempory directory and cleanup when done ---
|
||||
setup_tmp() {
|
||||
TMP_DIR=`mktemp -d -t k3s-install.XXXXXXXXXX`
|
||||
TMP_DIR=$(mktemp -d -t k3s-install.XXXXXXXXXX)
|
||||
TMP_HASH=${TMP_DIR}/k3s.hash
|
||||
TMP_BIN=${TMP_DIR}/k3s.bin
|
||||
cleanup() {
|
||||
@ -288,7 +288,7 @@ get_release_version() {
|
||||
VERSION_K3S="${INSTALL_K3S_VERSION}"
|
||||
else
|
||||
info "Finding latest release"
|
||||
VERSION_K3S=`curl -w "%{url_effective}" -I -L -s -S ${GITHUB_URL}/latest -o /dev/null | sed -e 's|.*/||'`
|
||||
VERSION_K3S=$(curl -w "%{url_effective}" -I -L -s -S ${GITHUB_URL}/latest -o /dev/null | sed -e 's|.*/||')
|
||||
fi
|
||||
info "Using ${VERSION_K3S} as release"
|
||||
}
|
||||
@ -298,14 +298,14 @@ download_hash() {
|
||||
HASH_URL=${GITHUB_URL}/download/${VERSION_K3S}/sha256sum-${ARCH}.txt
|
||||
info "Downloading hash ${HASH_URL}"
|
||||
curl -o ${TMP_HASH} -sfL ${HASH_URL} || fatal "Hash download failed"
|
||||
HASH_EXPECTED=`grep " k3s${SUFFIX}$" ${TMP_HASH}`
|
||||
HASH_EXPECTED=$(grep " k3s${SUFFIX}$" ${TMP_HASH})
|
||||
HASH_EXPECTED=${HASH_EXPECTED%%[[:blank:]]*}
|
||||
}
|
||||
|
||||
# --- check hash against installed version ---
|
||||
installed_hash_matches() {
|
||||
if [ -x ${BIN_DIR}/k3s ]; then
|
||||
HASH_INSTALLED=`sha256sum ${BIN_DIR}/k3s`
|
||||
HASH_INSTALLED=$(sha256sum ${BIN_DIR}/k3s)
|
||||
HASH_INSTALLED=${HASH_INSTALLED%%[[:blank:]]*}
|
||||
if [ "${HASH_EXPECTED}" = "${HASH_INSTALLED}" ]; then
|
||||
return
|
||||
@ -324,7 +324,7 @@ download_binary() {
|
||||
# --- verify downloaded binary hash ---
|
||||
verify_binary() {
|
||||
info "Verifying binary download"
|
||||
HASH_BIN=`sha256sum ${TMP_BIN}`
|
||||
HASH_BIN=$(sha256sum ${TMP_BIN})
|
||||
HASH_BIN=${HASH_BIN%%[[:blank:]]*}
|
||||
if [ "${HASH_EXPECTED}" != "${HASH_BIN}" ]; then
|
||||
fatal "Download sha256 does not match ${HASH_EXPECTED}, got ${HASH_BIN}"
|
||||
@ -339,12 +339,16 @@ setup_binary() {
|
||||
$SUDO mv -f ${TMP_BIN} ${BIN_DIR}/k3s
|
||||
|
||||
if command -v getenforce > /dev/null 2>&1; then
|
||||
if [ "Disabled" != `getenforce` ]; then
|
||||
info "SeLinux is enabled, setting permissions"
|
||||
if ! $SUDO semanage fcontext -l | grep "${BIN_DIR}/k3s" > /dev/null 2>&1; then
|
||||
$SUDO semanage fcontext -a -t bin_t "${BIN_DIR}/k3s"
|
||||
if [ "Disabled" != $(getenforce) ]; then
|
||||
if command -v semanage > /dev/null 2>&1; then
|
||||
info "SELinux is enabled, setting permissions"
|
||||
if ! $SUDO semanage fcontext -l | grep "${BIN_DIR}/k3s" > /dev/null 2>&1; then
|
||||
$SUDO semanage fcontext -a -t bin_t "${BIN_DIR}/k3s"
|
||||
fi
|
||||
$SUDO restorecon -v ${BIN_DIR}/k3s > /dev/null
|
||||
else
|
||||
error 'SELinux is enabled but semanage is not found'
|
||||
fi
|
||||
$SUDO restorecon -v ${BIN_DIR}/k3s > /dev/null
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@ -400,7 +404,7 @@ create_killall() {
|
||||
$SUDO tee ${BIN_DIR}/${KILLALL_K3S_SH} >/dev/null << \EOF
|
||||
#!/bin/sh
|
||||
set -x
|
||||
[ `id -u` = 0 ] || exec sudo $0 $@
|
||||
[ $(id -u) -eq 0 ] || exec sudo $0 $@
|
||||
|
||||
for bin in /var/lib/rancher/k3s/data/**/bin/; do
|
||||
[ -d $bin ] && export PATH=$bin:$PATH
|
||||
@ -468,7 +472,7 @@ create_uninstall() {
|
||||
$SUDO tee ${BIN_DIR}/${UNINSTALL_K3S_SH} >/dev/null << EOF
|
||||
#!/bin/sh
|
||||
set -x
|
||||
[ \`id -u\` = 0 ] || exec sudo \$0 \$@
|
||||
[ \$(id -u) -eq 0 ] || exec sudo \$0 \$@
|
||||
|
||||
${BIN_DIR}/${KILLALL_K3S_SH}
|
||||
|
||||
@ -519,7 +523,7 @@ systemd_disable() {
|
||||
# --- capture current env and create file containing k3s_ variables ---
|
||||
create_env_file() {
|
||||
info "env: Creating environment file ${FILE_K3S_ENV}"
|
||||
UMASK=`umask`
|
||||
UMASK=$(umask)
|
||||
umask 0377
|
||||
env | grep '^K3S_' | $SUDO tee ${FILE_K3S_ENV} >/dev/null
|
||||
umask $UMASK
|
||||
@ -644,7 +648,7 @@ service_enable_and_start() {
|
||||
|
||||
[ "${INSTALL_K3S_SKIP_START}" = "true" ] && return
|
||||
|
||||
POST_INSTALL_HASHES=`get_installed_hashes`
|
||||
POST_INSTALL_HASHES=$(get_installed_hashes)
|
||||
if [ "${PRE_INSTALL_HASHES}" = "${POST_INSTALL_HASHES}" ]; then
|
||||
info "No change detected so skipping service start"
|
||||
return
|
||||
|
@ -396,19 +396,3 @@ func getConfig(info *clientaccess.Info) (*config.Control, error) {
|
||||
controlControl := &config.Control{}
|
||||
return controlControl, json.Unmarshal(data, controlControl)
|
||||
}
|
||||
|
||||
func HostnameCheck(cfg cmds.Agent) error {
|
||||
hostname, _, err := getHostnameAndIP(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
_, err = sysnet.LookupHost(hostname)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
logrus.Infof("Waiting for hostname %s to be resolvable: %v", hostname, err)
|
||||
time.Sleep(time.Second * 3)
|
||||
}
|
||||
return fmt.Errorf("Timed out waiting for hostname %s to be resolvable: %v", hostname, err)
|
||||
}
|
||||
|
@ -25,10 +25,6 @@ import (
|
||||
func run(ctx context.Context, cfg cmds.Agent, lb *loadbalancer.LoadBalancer) error {
|
||||
nodeConfig := config.Get(ctx, cfg)
|
||||
|
||||
if err := config.HostnameCheck(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !nodeConfig.NoFlannel {
|
||||
if err := flannel.Prepare(ctx, nodeConfig); err != nil {
|
||||
return err
|
||||
|
@ -17,7 +17,7 @@ const ContainerdConfigTemplate = `
|
||||
path = "{{ .NodeConfig.Containerd.Opt }}"
|
||||
|
||||
[plugins.cri]
|
||||
stream_server_address = "{{ .NodeConfig.AgentConfig.NodeName }}"
|
||||
stream_server_address = "127.0.0.1"
|
||||
stream_server_port = "10010"
|
||||
|
||||
{{- if .IsRunningInUserNS }}
|
||||
|
@ -22,8 +22,7 @@ type Server struct {
|
||||
ExtraSchedulerArgs cli.StringSlice
|
||||
ExtraControllerArgs cli.StringSlice
|
||||
Rootless bool
|
||||
BootstrapType string
|
||||
StorageBackend string
|
||||
StoreBootstrap bool
|
||||
StorageEndpoint string
|
||||
StorageCAFile string
|
||||
StorageCertFile string
|
||||
@ -144,16 +143,11 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
|
||||
Usage: "(experimental) Run rootless",
|
||||
Destination: &ServerConfig.Rootless,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "bootstrap",
|
||||
Usage: "(experimental) Specify data bootstrap behavior (one of: none, read, write, or full), etcd3 only",
|
||||
Destination: &ServerConfig.BootstrapType,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "storage-backend",
|
||||
Usage: "Specify storage type etcd3 or kvsql",
|
||||
Destination: &ServerConfig.StorageBackend,
|
||||
EnvVar: "K3S_STORAGE_BACKEND",
|
||||
cli.BoolFlag{
|
||||
Name: "bootstrap-save",
|
||||
Usage: "(experimental) Save bootstrap information in the storage endpoint",
|
||||
Hidden: true,
|
||||
Destination: &ServerConfig.StoreBootstrap,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "storage-endpoint",
|
||||
|
@ -8,13 +8,12 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/k3s/pkg/netutil"
|
||||
|
||||
systemd "github.com/coreos/go-systemd/daemon"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rancher/k3s/pkg/agent"
|
||||
"github.com/rancher/k3s/pkg/cli/cmds"
|
||||
"github.com/rancher/k3s/pkg/datadir"
|
||||
"github.com/rancher/k3s/pkg/netutil"
|
||||
"github.com/rancher/k3s/pkg/rootless"
|
||||
"github.com/rancher/k3s/pkg/server"
|
||||
"github.com/rancher/wrangler/pkg/signals"
|
||||
@ -82,14 +81,13 @@ func run(app *cli.Context, cfg *cmds.Server) error {
|
||||
serverConfig.ControlConfig.ExtraControllerArgs = cfg.ExtraControllerArgs
|
||||
serverConfig.ControlConfig.ExtraSchedulerAPIArgs = cfg.ExtraSchedulerArgs
|
||||
serverConfig.ControlConfig.ClusterDomain = cfg.ClusterDomain
|
||||
serverConfig.ControlConfig.StorageEndpoint = cfg.StorageEndpoint
|
||||
serverConfig.ControlConfig.StorageBackend = cfg.StorageBackend
|
||||
serverConfig.ControlConfig.StorageCAFile = cfg.StorageCAFile
|
||||
serverConfig.ControlConfig.StorageCertFile = cfg.StorageCertFile
|
||||
serverConfig.ControlConfig.StorageKeyFile = cfg.StorageKeyFile
|
||||
serverConfig.ControlConfig.Storage.Endpoint = cfg.StorageEndpoint
|
||||
serverConfig.ControlConfig.Storage.CAFile = cfg.StorageCAFile
|
||||
serverConfig.ControlConfig.Storage.CertFile = cfg.StorageCertFile
|
||||
serverConfig.ControlConfig.Storage.KeyFile = cfg.StorageKeyFile
|
||||
serverConfig.ControlConfig.AdvertiseIP = cfg.AdvertiseIP
|
||||
serverConfig.ControlConfig.AdvertisePort = cfg.AdvertisePort
|
||||
serverConfig.ControlConfig.BootstrapType = cfg.BootstrapType
|
||||
serverConfig.ControlConfig.BootstrapReadOnly = !cfg.StoreBootstrap
|
||||
|
||||
if cmds.AgentConfig.FlannelIface != "" && cmds.AgentConfig.NodeIP == "" {
|
||||
cmds.AgentConfig.NodeIP = netutil.GetIPFromInterface(cmds.AgentConfig.FlannelIface)
|
||||
@ -127,10 +125,6 @@ func run(app *cli.Context, cfg *cmds.Server) error {
|
||||
serverConfig.ControlConfig.ClusterDNS = net2.ParseIP(cfg.ClusterDNS)
|
||||
}
|
||||
|
||||
if serverConfig.ControlConfig.StorageBackend != "etcd3" {
|
||||
serverConfig.ControlConfig.NoLeaderElect = true
|
||||
}
|
||||
|
||||
for _, noDeploy := range app.StringSlice("no-deploy") {
|
||||
if noDeploy == "servicelb" {
|
||||
serverConfig.DisableServiceLB = true
|
||||
@ -165,7 +159,7 @@ func run(app *cli.Context, cfg *cmds.Server) error {
|
||||
}
|
||||
ip := serverConfig.TLSConfig.BindAddress
|
||||
if ip == "" {
|
||||
ip = "localhost"
|
||||
ip = "127.0.0.1"
|
||||
}
|
||||
url := fmt.Sprintf("https://%s:%d", ip, serverConfig.TLSConfig.HTTPSPort)
|
||||
token := server.FormatToken(serverConfig.ControlConfig.Runtime.NodeToken, certs)
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/kine/pkg/endpoint"
|
||||
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
)
|
||||
|
||||
@ -80,12 +82,8 @@ type Control struct {
|
||||
KubeConfigMode string
|
||||
DataDir string
|
||||
Skips []string
|
||||
BootstrapType string
|
||||
StorageBackend string
|
||||
StorageEndpoint string
|
||||
StorageCAFile string
|
||||
StorageCertFile string
|
||||
StorageKeyFile string
|
||||
BootstrapReadOnly bool
|
||||
Storage endpoint.Config
|
||||
NoScheduler bool
|
||||
ExtraAPIArgs []string
|
||||
ExtraControllerArgs []string
|
||||
@ -95,15 +93,25 @@ type Control struct {
|
||||
Runtime *ControlRuntime `json:"-"`
|
||||
}
|
||||
|
||||
type ControlRuntimeBootstrap struct {
|
||||
ServerCA string
|
||||
ServerCAKey string
|
||||
ClientCA string
|
||||
ClientCAKey string
|
||||
ServiceKey string
|
||||
PasswdFile string
|
||||
RequestHeaderCA string
|
||||
RequestHeaderCAKey string
|
||||
ClientKubeletKey string
|
||||
ClientKubeProxyKey string
|
||||
ServingKubeletKey string
|
||||
}
|
||||
|
||||
type ControlRuntime struct {
|
||||
ControlRuntimeBootstrap
|
||||
|
||||
ClientKubeAPICert string
|
||||
ClientKubeAPIKey string
|
||||
ClientCA string
|
||||
ClientCAKey string
|
||||
ServerCA string
|
||||
ServerCAKey string
|
||||
ServiceKey string
|
||||
PasswdFile string
|
||||
NodePasswdFile string
|
||||
|
||||
KubeConfigAdmin string
|
||||
@ -119,8 +127,6 @@ type ControlRuntime struct {
|
||||
Tunnel http.Handler
|
||||
Authenticator authenticator.Request
|
||||
|
||||
RequestHeaderCA string
|
||||
RequestHeaderCAKey string
|
||||
ClientAuthProxyCert string
|
||||
ClientAuthProxyKey string
|
||||
|
||||
@ -131,10 +137,6 @@ type ControlRuntime struct {
|
||||
ClientSchedulerCert string
|
||||
ClientSchedulerKey string
|
||||
ClientKubeProxyCert string
|
||||
ClientKubeProxyKey string
|
||||
|
||||
ServingKubeletKey string
|
||||
ClientKubeletKey string
|
||||
}
|
||||
|
||||
type ArgString []string
|
||||
|
@ -2,264 +2,99 @@ package control
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"encoding/base64"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rancher/k3s/pkg/daemons/config"
|
||||
"github.com/rancher/kine/pkg/client"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.etcd.io/etcd/clientv3"
|
||||
)
|
||||
|
||||
const (
|
||||
etcdDialTimeout = 5 * time.Second
|
||||
k3sRuntimeEtcdPath = "/k3s/runtime"
|
||||
bootstrapTypeNone = "none"
|
||||
bootstrapTypeRead = "read"
|
||||
bootstrapTypeWrite = "write"
|
||||
bootstrapTypeFull = "full"
|
||||
)
|
||||
|
||||
type serverBootstrap struct {
|
||||
ServerCAData string `json:"serverCAData,omitempty"`
|
||||
ServerCAKeyData string `json:"serverCAKeyData,omitempty"`
|
||||
ClientCAData string `json:"clientCAData,omitempty"`
|
||||
ClientCAKeyData string `json:"clientCAKeyData,omitempty"`
|
||||
ServiceKeyData string `json:"serviceKeyData,omitempty"`
|
||||
PasswdFileData string `json:"passwdFileData,omitempty"`
|
||||
RequestHeaderCAData string `json:"requestHeaderCAData,omitempty"`
|
||||
RequestHeaderCAKeyData string `json:"requestHeaderCAKeyData,omitempty"`
|
||||
ClientKubeletKey string `json:"clientKubeletKey,omitempty"`
|
||||
ClientKubeProxyKey string `json:"clientKubeProxyKey,omitempty"`
|
||||
ServingKubeletKey string `json:"servingKubeletKey,omitempty"`
|
||||
}
|
||||
|
||||
var validBootstrapTypes = map[string]bool{
|
||||
bootstrapTypeRead: true,
|
||||
bootstrapTypeWrite: true,
|
||||
bootstrapTypeFull: true,
|
||||
}
|
||||
|
||||
// fetchBootstrapData copies the bootstrap data (certs, keys, passwords)
|
||||
// from etcd to inidividual files specified by cfg.Runtime.
|
||||
func fetchBootstrapData(cfg *config.Control) error {
|
||||
if valid, err := checkBootstrapArgs(cfg, map[string]bool{
|
||||
bootstrapTypeFull: true,
|
||||
bootstrapTypeRead: true,
|
||||
}); !valid {
|
||||
if err != nil {
|
||||
logrus.Warnf("Not fetching bootstrap data: %v", err)
|
||||
}
|
||||
// from etcd to individual files specified by cfg.Runtime.
|
||||
func fetchBootstrapData(ctx context.Context, cfg *config.Control, c client.Client) error {
|
||||
logrus.Info("Fetching bootstrap data from etcd")
|
||||
gr, err := c.Get(ctx, k3sRuntimeEtcdPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if gr.Modified == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
tlsConfig, err := genBootstrapTLSConfig(cfg)
|
||||
paths, err := objToMap(&cfg.Runtime.ControlRuntimeBootstrap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
endpoints := strings.Split(cfg.StorageEndpoint, ",")
|
||||
cli, err := clientv3.New(clientv3.Config{
|
||||
Endpoints: endpoints,
|
||||
DialTimeout: etcdDialTimeout,
|
||||
TLS: tlsConfig,
|
||||
})
|
||||
if err != nil {
|
||||
files := map[string][]byte{}
|
||||
if err := json.Unmarshal(gr.Data, &files); err != nil {
|
||||
return err
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
logrus.Info("Fetching bootstrap data from etcd")
|
||||
gr, err := cli.Get(context.TODO(), k3sRuntimeEtcdPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(gr.Kvs) == 0 {
|
||||
if cfg.BootstrapType != bootstrapTypeRead {
|
||||
return nil
|
||||
for pathKey, data := range files {
|
||||
path, ok := paths[pathKey]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
|
||||
return errors.Wrapf(err, "failed to mkdir %s", filepath.Dir(path))
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(path, data, 0700); err != nil {
|
||||
return errors.Wrapf(err, "failed to write to %s", path)
|
||||
}
|
||||
return errors.New("Unable to read bootstrap data from server")
|
||||
}
|
||||
|
||||
runtimeJSON, err := base64.URLEncoding.DecodeString(string(gr.Kvs[0].Value))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serverRuntime := &serverBootstrap{}
|
||||
if err := json.Unmarshal(runtimeJSON, serverRuntime); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeRuntimeBootstrapData(cfg.Runtime, serverRuntime)
|
||||
return nil
|
||||
}
|
||||
|
||||
// storeBootstrapData copies the bootstrap data in the opposite direction to
|
||||
// fetchBootstrapData.
|
||||
func storeBootstrapData(cfg *config.Control) error {
|
||||
if valid, err := checkBootstrapArgs(cfg, map[string]bool{
|
||||
bootstrapTypeFull: true,
|
||||
bootstrapTypeWrite: true,
|
||||
}); !valid {
|
||||
if err != nil {
|
||||
logrus.Warnf("Not storing boostrap data: %v", err)
|
||||
}
|
||||
func storeBootstrapData(ctx context.Context, cfg *config.Control, client client.Client) error {
|
||||
if cfg.BootstrapReadOnly {
|
||||
return nil
|
||||
}
|
||||
|
||||
tlsConfig, err := genBootstrapTLSConfig(cfg)
|
||||
paths, err := objToMap(&cfg.Runtime.ControlRuntimeBootstrap)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
dataMap := map[string][]byte{}
|
||||
for pathKey, path := range paths {
|
||||
if path == "" {
|
||||
continue
|
||||
}
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to read %s", path)
|
||||
}
|
||||
|
||||
dataMap[pathKey] = data
|
||||
}
|
||||
|
||||
bytes, err := json.Marshal(dataMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
endpoints := strings.Split(cfg.StorageEndpoint, ",")
|
||||
cli, err := clientv3.New(clientv3.Config{
|
||||
Endpoints: endpoints,
|
||||
DialTimeout: etcdDialTimeout,
|
||||
TLS: tlsConfig,
|
||||
})
|
||||
return client.Put(ctx, k3sRuntimeEtcdPath, bytes)
|
||||
}
|
||||
|
||||
func objToMap(obj interface{}) (map[string]string, error) {
|
||||
bytes, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
if cfg.BootstrapType != bootstrapTypeWrite {
|
||||
gr, err := cli.Get(context.TODO(), k3sRuntimeEtcdPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(gr.Kvs) > 0 && string(gr.Kvs[0].Value) != "" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
certData, err := readRuntimeBootstrapData(cfg.Runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Info("Storing bootstrap data to etcd")
|
||||
runtimeBase64 := base64.StdEncoding.EncodeToString(certData)
|
||||
_, err = cli.Put(context.TODO(), k3sRuntimeEtcdPath, runtimeBase64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkBootstrapArgs(cfg *config.Control, accepted map[string]bool) (bool, error) {
|
||||
if cfg.BootstrapType == "" || cfg.BootstrapType == bootstrapTypeNone {
|
||||
return false, nil
|
||||
}
|
||||
if !validBootstrapTypes[cfg.BootstrapType] {
|
||||
return false, fmt.Errorf("unsupported bootstrap type [%s]", cfg.BootstrapType)
|
||||
}
|
||||
if cfg.StorageBackend != "etcd3" {
|
||||
return false, errors.New("bootstrap only supported with etcd3 as storage backend")
|
||||
}
|
||||
if !accepted[cfg.BootstrapType] {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func genBootstrapTLSConfig(cfg *config.Control) (*tls.Config, error) {
|
||||
secureTLSConfig := &tls.Config{}
|
||||
// Note: clientv3 excepts nil for non-tls
|
||||
var tlsConfig *tls.Config
|
||||
if cfg.StorageCertFile != "" && cfg.StorageKeyFile != "" {
|
||||
certPem, err := ioutil.ReadFile(cfg.StorageCertFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyPem, err := ioutil.ReadFile(cfg.StorageKeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsCert, err := tls.X509KeyPair(certPem, keyPem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig = secureTLSConfig
|
||||
tlsConfig.Certificates = []tls.Certificate{tlsCert}
|
||||
}
|
||||
if cfg.StorageCAFile != "" {
|
||||
caData, err := ioutil.ReadFile(cfg.StorageCAFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certPool := x509.NewCertPool()
|
||||
certPool.AppendCertsFromPEM(caData)
|
||||
tlsConfig = secureTLSConfig
|
||||
tlsConfig.RootCAs = certPool
|
||||
}
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
func readRuntimeBootstrapData(runtime *config.ControlRuntime) ([]byte, error) {
|
||||
serverBootstrapFiles := map[string]string{
|
||||
runtime.ServerCA: "",
|
||||
runtime.ServerCAKey: "",
|
||||
runtime.ClientCA: "",
|
||||
runtime.ClientCAKey: "",
|
||||
runtime.ServiceKey: "",
|
||||
runtime.PasswdFile: "",
|
||||
runtime.RequestHeaderCA: "",
|
||||
runtime.RequestHeaderCAKey: "",
|
||||
runtime.ClientKubeletKey: "",
|
||||
runtime.ClientKubeProxyKey: "",
|
||||
runtime.ServingKubeletKey: "",
|
||||
}
|
||||
for k := range serverBootstrapFiles {
|
||||
data, err := ioutil.ReadFile(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
serverBootstrapFiles[k] = string(data)
|
||||
}
|
||||
serverBootstrapFileData := &serverBootstrap{
|
||||
ServerCAData: serverBootstrapFiles[runtime.ServerCA],
|
||||
ServerCAKeyData: serverBootstrapFiles[runtime.ServerCAKey],
|
||||
ClientCAData: serverBootstrapFiles[runtime.ClientCA],
|
||||
ClientCAKeyData: serverBootstrapFiles[runtime.ClientCAKey],
|
||||
ServiceKeyData: serverBootstrapFiles[runtime.ServiceKey],
|
||||
PasswdFileData: serverBootstrapFiles[runtime.PasswdFile],
|
||||
RequestHeaderCAData: serverBootstrapFiles[runtime.RequestHeaderCA],
|
||||
RequestHeaderCAKeyData: serverBootstrapFiles[runtime.RequestHeaderCAKey],
|
||||
ClientKubeletKey: serverBootstrapFiles[runtime.ClientKubeletKey],
|
||||
ClientKubeProxyKey: serverBootstrapFiles[runtime.ClientKubeProxyKey],
|
||||
ServingKubeletKey: serverBootstrapFiles[runtime.ServingKubeletKey],
|
||||
}
|
||||
return json.Marshal(serverBootstrapFileData)
|
||||
}
|
||||
|
||||
func writeRuntimeBootstrapData(runtime *config.ControlRuntime, runtimeData *serverBootstrap) error {
|
||||
runtimePathValue := map[string]string{
|
||||
runtime.ServerCA: runtimeData.ServerCAData,
|
||||
runtime.ServerCAKey: runtimeData.ServerCAKeyData,
|
||||
runtime.ClientCA: runtimeData.ClientCAData,
|
||||
runtime.ClientCAKey: runtimeData.ClientCAKeyData,
|
||||
runtime.ServiceKey: runtimeData.ServiceKeyData,
|
||||
runtime.PasswdFile: runtimeData.PasswdFileData,
|
||||
runtime.RequestHeaderCA: runtimeData.RequestHeaderCAData,
|
||||
runtime.RequestHeaderCAKey: runtimeData.RequestHeaderCAKeyData,
|
||||
runtime.ClientKubeletKey: runtimeData.ClientKubeletKey,
|
||||
runtime.ClientKubeProxyKey: runtimeData.ClientKubeProxyKey,
|
||||
runtime.ServingKubeletKey: runtimeData.ServingKubeletKey,
|
||||
}
|
||||
for k, v := range runtimePathValue {
|
||||
if _, err := os.Stat(k); os.IsNotExist(err) {
|
||||
if err := ioutil.WriteFile(k, []byte(v), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
data := map[string]string{}
|
||||
return data, json.Unmarshal(bytes, &data)
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/kine/pkg/client"
|
||||
"github.com/rancher/kine/pkg/endpoint"
|
||||
|
||||
certutil "github.com/rancher/dynamiclistener/cert"
|
||||
"github.com/rancher/k3s/pkg/daemons/config"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -69,7 +72,7 @@ func Server(ctx context.Context, cfg *config.Control) error {
|
||||
runtime := &config.ControlRuntime{}
|
||||
cfg.Runtime = runtime
|
||||
|
||||
if err := prepare(cfg, runtime); err != nil {
|
||||
if err := prepare(ctx, cfg, runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -147,9 +150,6 @@ func apiServer(ctx context.Context, cfg *config.Control, runtime *config.Control
|
||||
argsMap := make(map[string]string)
|
||||
|
||||
setupStorageBackend(argsMap, cfg)
|
||||
if len(cfg.StorageEndpoint) > 0 {
|
||||
argsMap["etcd-servers"] = cfg.StorageEndpoint
|
||||
}
|
||||
|
||||
certDir := filepath.Join(cfg.DataDir, "tls/temporary-certs")
|
||||
os.MkdirAll(certDir, 0700)
|
||||
@ -227,16 +227,12 @@ func defaults(config *config.Control) {
|
||||
}
|
||||
}
|
||||
|
||||
func prepare(config *config.Control, runtime *config.ControlRuntime) error {
|
||||
func prepare(ctx context.Context, config *config.Control, runtime *config.ControlRuntime) error {
|
||||
var err error
|
||||
|
||||
defaults(config)
|
||||
|
||||
if _, err := os.Stat(config.DataDir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(config.DataDir, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err != nil {
|
||||
if err := os.MkdirAll(config.DataDir, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -284,7 +280,13 @@ func prepare(config *config.Control, runtime *config.ControlRuntime) error {
|
||||
runtime.ClientAuthProxyCert = path.Join(config.DataDir, "tls", "client-auth-proxy.crt")
|
||||
runtime.ClientAuthProxyKey = path.Join(config.DataDir, "tls", "client-auth-proxy.key")
|
||||
|
||||
if err := fetchBootstrapData(config); err != nil {
|
||||
etcdClient, err := prepareStorageBackend(ctx, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer etcdClient.Close()
|
||||
|
||||
if err := fetchBootstrapData(ctx, config, etcdClient); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -300,13 +302,25 @@ func prepare(config *config.Control, runtime *config.ControlRuntime) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := storeBootstrapData(config); err != nil {
|
||||
if err := storeBootstrapData(ctx, config, etcdClient); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return readTokens(runtime)
|
||||
}
|
||||
|
||||
func prepareStorageBackend(ctx context.Context, config *config.Control) (client.Client, error) {
|
||||
etcdConfig, err := endpoint.Listen(ctx, config.Storage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config.Storage.Config = etcdConfig.TLSConfig
|
||||
config.Storage.Endpoint = strings.Join(etcdConfig.Endpoints, ",")
|
||||
config.NoLeaderElect = !etcdConfig.LeaderElect
|
||||
return client.New(etcdConfig)
|
||||
}
|
||||
|
||||
func readTokenFile(passwdFile string) (map[string]string, error) {
|
||||
f, err := os.Open(passwdFile)
|
||||
if err != nil {
|
||||
@ -474,7 +488,7 @@ func genClientCerts(config *config.Control, runtime *config.ControlRuntime) erro
|
||||
factory := getSigningCertFactory(regen, nil, []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, runtime.ClientCA, runtime.ClientCAKey)
|
||||
|
||||
var certGen bool
|
||||
apiEndpoint := fmt.Sprintf("https://localhost:%d", config.ListenPort)
|
||||
apiEndpoint := fmt.Sprintf("https://127.0.0.1:%d", config.ListenPort)
|
||||
|
||||
certGen, err = factory("system:admin", []string{"system:masters"}, runtime.ClientAdminCert, runtime.ClientAdminKey)
|
||||
if err != nil {
|
||||
@ -717,22 +731,19 @@ func KubeConfig(dest, url, caCert, clientCert, clientKey string) error {
|
||||
}
|
||||
|
||||
func setupStorageBackend(argsMap map[string]string, cfg *config.Control) {
|
||||
// setup the storage backend
|
||||
if len(cfg.StorageBackend) > 0 {
|
||||
argsMap["storage-backend"] = cfg.StorageBackend
|
||||
}
|
||||
argsMap["storage-backend"] = "etcd3"
|
||||
// specify the endpoints
|
||||
if len(cfg.StorageEndpoint) > 0 {
|
||||
argsMap["etcd-servers"] = cfg.StorageEndpoint
|
||||
if len(cfg.Storage.Endpoint) > 0 {
|
||||
argsMap["etcd-servers"] = cfg.Storage.Endpoint
|
||||
}
|
||||
// storage backend tls configuration
|
||||
if len(cfg.StorageCAFile) > 0 {
|
||||
argsMap["etcd-cafile"] = cfg.StorageCAFile
|
||||
if len(cfg.Storage.CAFile) > 0 {
|
||||
argsMap["etcd-cafile"] = cfg.Storage.CAFile
|
||||
}
|
||||
if len(cfg.StorageCertFile) > 0 {
|
||||
argsMap["etcd-certfile"] = cfg.StorageCertFile
|
||||
if len(cfg.Storage.CertFile) > 0 {
|
||||
argsMap["etcd-certfile"] = cfg.Storage.CertFile
|
||||
}
|
||||
if len(cfg.StorageKeyFile) > 0 {
|
||||
argsMap["etcd-keyfile"] = cfg.StorageKeyFile
|
||||
if len(cfg.Storage.KeyFile) > 0 {
|
||||
argsMap["etcd-keyfile"] = cfg.Storage.KeyFile
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ func printTokens(certs, advertiseIP string, tlsConfig *dynamiclistener.UserConfi
|
||||
)
|
||||
|
||||
if advertiseIP == "" {
|
||||
advertiseIP = "localhost"
|
||||
advertiseIP = "127.0.0.1"
|
||||
}
|
||||
|
||||
if len(config.Runtime.NodeToken) > 0 {
|
||||
@ -213,7 +213,7 @@ func writeKubeConfig(certs string, tlsConfig *dynamiclistener.UserConfig, config
|
||||
clientToken := FormatToken(config.ControlConfig.Runtime.ClientToken, certs)
|
||||
ip := tlsConfig.BindAddress
|
||||
if ip == "" {
|
||||
ip = "localhost"
|
||||
ip = "127.0.0.1"
|
||||
}
|
||||
url := fmt.Sprintf("https://%s:%d", ip, tlsConfig.HTTPSPort)
|
||||
kubeConfig, err := HomeKubeConfig(true, config.Rootless)
|
||||
|
12
trash.lock
12
trash.lock
@ -146,8 +146,7 @@ import:
|
||||
- package: github.com/hashicorp/golang-lru
|
||||
version: v0.5.0
|
||||
- package: github.com/ibuildthecloud/kvsql
|
||||
version: 9f00ccc82235f0433c736306d091abd2939b7449
|
||||
repo: https://github.com/erikwilson/rancher-kvsql.git
|
||||
version: 0e798b1475327aadf3b8da5d2d1f99bb93dfd667
|
||||
- package: github.com/imdario/mergo
|
||||
version: v0.3.5
|
||||
- package: github.com/inconshreveable/mousetrap
|
||||
@ -175,7 +174,7 @@ import:
|
||||
- package: github.com/mattn/go-shellwords
|
||||
version: v1.0.3-20-gf8471b0a71ded0
|
||||
- package: github.com/mattn/go-sqlite3
|
||||
version: v1.9.0
|
||||
version: v1.10.0
|
||||
- package: github.com/matttproud/golang_protobuf_extensions
|
||||
version: v1.0.0
|
||||
- package: github.com/miekg/dns
|
||||
@ -231,6 +230,9 @@ import:
|
||||
repo: https://github.com/erikwilson/rancher-dynamiclistener.git
|
||||
- package: github.com/rancher/helm-controller
|
||||
version: v0.2.2
|
||||
- package: github.com/rancher/kine
|
||||
version: c308515dee837fd00d480e482f763d76e7572df5
|
||||
repo: https://github.com/ibuildthecloud/kine.git
|
||||
- package: github.com/rancher/remotedialer
|
||||
version: 7c71ffa8f5d7a181704d92bb8a33b0c7d07dccaa
|
||||
repo: https://github.com/erikwilson/rancher-remotedialer.git
|
||||
@ -251,7 +253,7 @@ import:
|
||||
- package: github.com/sigma/go-inotify
|
||||
version: c87b6cf5033d2c6486046f045eeebdc3d910fd38
|
||||
- package: github.com/sirupsen/logrus
|
||||
version: v1.0.3
|
||||
version: v1.4.1
|
||||
- package: github.com/spf13/cobra
|
||||
version: v0.0.1-34-gc439c4fa093711
|
||||
- package: github.com/spf13/pflag
|
||||
@ -278,8 +280,6 @@ import:
|
||||
version: 1d523034197ff1f222f6429836dd36a2457a1874
|
||||
- package: go.etcd.io/bbolt
|
||||
version: v1.3.1-etcd.8
|
||||
- package: go.etcd.io/etcd
|
||||
version: v3.3.11
|
||||
- package: golang.org/x/crypto
|
||||
version: a49355c7e3f8fe157a85be2f77e6e269a0f89602
|
||||
- package: golang.org/x/net
|
||||
|
@ -22,7 +22,7 @@ github.com/coreos/flannel 823afe66b2266bf71f5bec24e6e28b26d70cfc7c ht
|
||||
github.com/natefinch/lumberjack aee4629129445bbdfb69aa565537dcfa16544311
|
||||
github.com/gorilla/mux v1.6.2
|
||||
github.com/gorilla/websocket v1.2.0
|
||||
github.com/mattn/go-sqlite3 v1.9.0
|
||||
github.com/mattn/go-sqlite3 v1.10.0
|
||||
github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/lib/pq v1.1.1
|
||||
go.etcd.io/etcd v3.3.11
|
||||
@ -71,7 +71,7 @@ github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
||||
github.com/golang/protobuf v1.1.0
|
||||
#github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
|
||||
github.com/opencontainers/runc v1.0.0-rc8
|
||||
github.com/sirupsen/logrus v1.0.3
|
||||
github.com/sirupsen/logrus v1.4.1
|
||||
#github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||
golang.org/x/net cdfb69ac37fc6fa907650654115ebebb3aae2087
|
||||
google.golang.org/grpc v1.12.0
|
||||
@ -126,7 +126,8 @@ golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4
|
||||
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
||||
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
||||
gopkg.in/yaml.v2 v2.2.1
|
||||
github.com/ibuildthecloud/kvsql 9f00ccc82235f0433c736306d091abd2939b7449 https://github.com/erikwilson/rancher-kvsql.git
|
||||
github.com/rancher/kine c308515dee837fd00d480e482f763d76e7572df5 https://github.com/ibuildthecloud/kine.git
|
||||
google.golang.org/grpc v1.20.1
|
||||
|
||||
# rootless
|
||||
github.com/rootless-containers/rootlesskit v0.4.1
|
||||
|
3
vendor/github.com/ibuildthecloud/kvsql/clientv3/config.go
generated
vendored
3
vendor/github.com/ibuildthecloud/kvsql/clientv3/config.go
generated
vendored
@ -18,7 +18,6 @@ import (
|
||||
"crypto/tls"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@ -40,6 +39,4 @@ type Config struct {
|
||||
DialTimeout time.Duration
|
||||
|
||||
DialOptions []grpc.DialOption
|
||||
|
||||
TLSInfo *transport.TLSInfo
|
||||
}
|
||||
|
6
vendor/github.com/ibuildthecloud/kvsql/clientv3/driver/generic.go
generated
vendored
6
vendor/github.com/ibuildthecloud/kvsql/clientv3/driver/generic.go
generated
vendored
@ -16,7 +16,7 @@ import (
|
||||
|
||||
type Generic struct {
|
||||
// revision must be first to ensure that this is properly aligned for atomic.LoadInt64
|
||||
revision int64
|
||||
revision int64
|
||||
|
||||
db *sql.DB
|
||||
|
||||
@ -64,7 +64,7 @@ func (g *Generic) Start(ctx context.Context, db *sql.DB) error {
|
||||
|
||||
err = g.cleanup(ctx)
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to cleanup duplicate entries: %v", err)
|
||||
logrus.Errorf("Failed to cleanup duplicate entries")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -209,12 +209,14 @@ func (g *Generic) Update(ctx context.Context, key string, value []byte, revision
|
||||
func (g *Generic) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
|
||||
trace := utiltrace.New(fmt.Sprintf("SQL DB ExecContext query: %s keys: %v", query, args))
|
||||
defer trace.LogIfLong(500 * time.Millisecond)
|
||||
|
||||
return g.db.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (g *Generic) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
|
||||
trace := utiltrace.New(fmt.Sprintf("SQL DB QueryContext query: %s keys: %v", query, args))
|
||||
defer trace.LogIfLong(500 * time.Millisecond)
|
||||
|
||||
return g.db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
|
180
vendor/github.com/ibuildthecloud/kvsql/clientv3/driver/mysql/mysql.go
generated
vendored
180
vendor/github.com/ibuildthecloud/kvsql/clientv3/driver/mysql/mysql.go
generated
vendored
@ -1,180 +0,0 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"database/sql"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/ibuildthecloud/kvsql/clientv3/driver"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultUnixDSN = "root@unix(/var/run/mysqld/mysqld.sock)/"
|
||||
defaultHostDSN = "root@tcp(127.0.0.1)/"
|
||||
)
|
||||
|
||||
var (
|
||||
fieldList = "name, value, old_value, old_revision, create_revision, revision, ttl, version, del"
|
||||
baseList = `
|
||||
SELECT kv.id, kv.name, kv.value, kv.old_value, kv.old_revision, kv.create_revision, kv.revision, kv.ttl, kv.version, kv.del
|
||||
FROM key_value kv
|
||||
INNER JOIN
|
||||
(
|
||||
SELECT MAX(revision) revision, kvi.name
|
||||
FROM key_value kvi
|
||||
%REV%
|
||||
GROUP BY kvi.name
|
||||
) AS r
|
||||
ON r.name = kv.name AND r.revision = kv.revision
|
||||
WHERE kv.name like ? %RES% ORDER BY kv.name ASC limit ?
|
||||
`
|
||||
insertSQL = `
|
||||
INSERT INTO key_value(` + fieldList + `)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
|
||||
schema = []string{
|
||||
`create table if not exists key_value
|
||||
(
|
||||
name TEXT,
|
||||
value BLOB,
|
||||
create_revision INTEGER,
|
||||
revision INTEGER,
|
||||
ttl INTEGER,
|
||||
version INTEGER,
|
||||
del INTEGER,
|
||||
old_value BLOB,
|
||||
old_revision INTEGER,
|
||||
id INTEGER AUTO_INCREMENT,
|
||||
PRIMARY KEY (id)
|
||||
)`,
|
||||
}
|
||||
nameIdx = "create index name_idx on key_value (name(100))"
|
||||
revisionIdx = "create index revision_idx on key_value (revision)"
|
||||
createDB = "create database if not exists "
|
||||
)
|
||||
|
||||
func NewMySQL() *driver.Generic {
|
||||
return &driver.Generic{
|
||||
CleanupSQL: "DELETE FROM key_value WHERE ttl > 0 AND ttl < ?",
|
||||
GetSQL: "SELECT id, " + fieldList + " FROM key_value WHERE name = ? ORDER BY revision DESC limit ?",
|
||||
ListSQL: strings.Replace(strings.Replace(baseList, "%REV%", "", -1), "%RES%", "", -1),
|
||||
ListRevisionSQL: strings.Replace(strings.Replace(baseList, "%REV%", "WHERE kvi.revision >= ?", -1), "%RES%", "", -1),
|
||||
ListResumeSQL: strings.Replace(strings.Replace(baseList, "%REV%", "WHERE kvi.revision <= ?", -1),
|
||||
"%RES%", "and kv.name > ? ", -1),
|
||||
InsertSQL: insertSQL,
|
||||
ReplaySQL: "SELECT id, " + fieldList + " FROM key_value WHERE name like ? and revision >= ? ORDER BY revision ASC",
|
||||
GetRevisionSQL: "SELECT MAX(revision) FROM key_value",
|
||||
ToDeleteSQL: "SELECT count(*), name, max(revision) FROM key_value GROUP BY name,del HAVING count(*) > 1 or (count(*)=1 and del=1)",
|
||||
DeleteOldSQL: "DELETE FROM key_value WHERE name = ? AND (revision < ? OR (revision = ? AND del = 1))",
|
||||
}
|
||||
}
|
||||
|
||||
func Open(dataSourceName string, tlsInfo *transport.TLSInfo) (*sql.DB, error) {
|
||||
tlsConfig, err := tlsInfo.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig.MinVersion = tls.VersionTLS11
|
||||
if len(tlsInfo.CertFile) == 0 && len(tlsInfo.KeyFile) == 0 && len(tlsInfo.CAFile) == 0 {
|
||||
tlsConfig = nil
|
||||
}
|
||||
parsedDSN, err := prepareDSN(dataSourceName, tlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := createDBIfNotExist(parsedDSN); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db, err := sql.Open("mysql", parsedDSN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, stmt := range schema {
|
||||
_, err := db.Exec(stmt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// check if duplicate indexes
|
||||
indexes := []string{
|
||||
nameIdx,
|
||||
revisionIdx}
|
||||
|
||||
for _, idx := range indexes {
|
||||
err := createIndex(db, idx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func createDBIfNotExist(dataSourceName string) error {
|
||||
config, err := mysql.ParseDSN(dataSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dbName := config.DBName
|
||||
|
||||
db, err := sql.Open("mysql", dataSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Exec(createDB + dbName)
|
||||
if err != nil {
|
||||
if mysqlError, ok := err.(*mysql.MySQLError); !ok || mysqlError.Number != 1049 {
|
||||
return err
|
||||
}
|
||||
config.DBName = ""
|
||||
db, err = sql.Open("mysql", config.FormatDSN())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Exec(createDB + dbName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createIndex(db *sql.DB, indexStmt string) error {
|
||||
_, err := db.Exec(indexStmt)
|
||||
if err != nil {
|
||||
if mysqlError, ok := err.(*mysql.MySQLError); !ok || mysqlError.Number != 1061 {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func prepareDSN(dataSourceName string, tlsConfig *tls.Config) (string, error) {
|
||||
if len(dataSourceName) == 0 {
|
||||
dataSourceName = defaultUnixDSN
|
||||
if tlsConfig != nil {
|
||||
dataSourceName = defaultHostDSN
|
||||
}
|
||||
}
|
||||
config, err := mysql.ParseDSN(dataSourceName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// setting up tlsConfig
|
||||
if tlsConfig != nil {
|
||||
mysql.RegisterTLSConfig("custom", tlsConfig)
|
||||
config.TLSConfig = "custom"
|
||||
}
|
||||
dbName := "kubernetes"
|
||||
if len(config.DBName) > 0 {
|
||||
dbName = config.DBName
|
||||
}
|
||||
config.DBName = dbName
|
||||
parsedDSN := config.FormatDSN()
|
||||
|
||||
return parsedDSN, nil
|
||||
}
|
6
vendor/github.com/ibuildthecloud/kvsql/clientv3/driver/watcher.go
generated
vendored
6
vendor/github.com/ibuildthecloud/kvsql/clientv3/driver/watcher.go
generated
vendored
@ -2,6 +2,7 @@ package driver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -93,9 +94,10 @@ func start(watchResponses chan Event) {
|
||||
}
|
||||
|
||||
func sendErrorAndClose(watchResponses chan Event, err error) {
|
||||
if err != nil {
|
||||
watchResponses <- Event{Err: err}
|
||||
if err == nil {
|
||||
err = io.EOF
|
||||
}
|
||||
watchResponses <- Event{Err: err}
|
||||
close(watchResponses)
|
||||
}
|
||||
|
||||
|
32
vendor/github.com/ibuildthecloud/kvsql/clientv3/kv.go
generated
vendored
32
vendor/github.com/ibuildthecloud/kvsql/clientv3/kv.go
generated
vendored
@ -21,13 +21,11 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/ibuildthecloud/kvsql/clientv3/driver"
|
||||
"github.com/ibuildthecloud/kvsql/clientv3/driver/sqlite"
|
||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/mvcc/mvccpb"
|
||||
"github.com/docker/docker/pkg/locker"
|
||||
"github.com/ibuildthecloud/kvsql/clientv3/driver"
|
||||
"github.com/ibuildthecloud/kvsql/clientv3/driver/mysql"
|
||||
"github.com/ibuildthecloud/kvsql/clientv3/driver/pgsql"
|
||||
"github.com/ibuildthecloud/kvsql/clientv3/driver/sqlite"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
@ -40,9 +38,9 @@ type (
|
||||
)
|
||||
|
||||
var (
|
||||
connections map[string]*kv
|
||||
connectionsCtx context.Context
|
||||
CloseDB func()
|
||||
connections map[string]*kv
|
||||
connectionsCtx context.Context
|
||||
CloseDB func()
|
||||
connectionsLock sync.Mutex
|
||||
)
|
||||
|
||||
@ -103,9 +101,9 @@ func newKV(cfg Config) (*kv, error) {
|
||||
}
|
||||
|
||||
var (
|
||||
db *sql.DB
|
||||
db *sql.DB
|
||||
driver *driver.Generic
|
||||
err error
|
||||
err error
|
||||
)
|
||||
|
||||
switch parts[0] {
|
||||
@ -114,18 +112,6 @@ func newKV(cfg Config) (*kv, error) {
|
||||
return nil, err
|
||||
}
|
||||
driver = sqlite.NewSQLite()
|
||||
case "mysql":
|
||||
if db, err = mysql.Open(parts[1], cfg.TLSInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
driver = mysql.NewMySQL()
|
||||
case "postgres":
|
||||
if db, err = pgsql.Open(parts[1], cfg.TLSInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
driver = pgsql.NewPGSQL()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown driver type [%s]", parts[0])
|
||||
}
|
||||
|
||||
if err := driver.Start(context.TODO(), db); err != nil {
|
||||
@ -134,11 +120,11 @@ func newKV(cfg Config) (*kv, error) {
|
||||
}
|
||||
|
||||
kv := &kv{
|
||||
d: driver,
|
||||
d:driver,
|
||||
}
|
||||
connections[key] = kv
|
||||
|
||||
return kv, nil
|
||||
return kv, nil
|
||||
}
|
||||
|
||||
func (k *kv) Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) {
|
||||
|
9
vendor/github.com/ibuildthecloud/kvsql/factory.go
generated
vendored
9
vendor/github.com/ibuildthecloud/kvsql/factory.go
generated
vendored
@ -22,9 +22,8 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"github.com/ibuildthecloud/kvsql/clientv3"
|
||||
etcd3 "github.com/ibuildthecloud/kvsql/storage"
|
||||
"github.com/ibuildthecloud/kvsql/storage"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
@ -66,14 +65,8 @@ func NewKVSQLHealthCheck(c storagebackend.Config) (func() error, error) {
|
||||
}
|
||||
|
||||
func newETCD3Client(c storagebackend.Config) (*clientv3.Client, error) {
|
||||
tlsInfo := &transport.TLSInfo{
|
||||
CertFile: c.Transport.CertFile,
|
||||
KeyFile: c.Transport.KeyFile,
|
||||
CAFile: c.Transport.CAFile,
|
||||
}
|
||||
cfg := clientv3.Config{
|
||||
Endpoints: c.Transport.ServerList,
|
||||
TLSInfo: tlsInfo,
|
||||
}
|
||||
|
||||
if len(cfg.Endpoints) == 0 {
|
||||
|
4
vendor/github.com/mattn/go-sqlite3/.travis.yml
generated
vendored
4
vendor/github.com/mattn/go-sqlite3/.travis.yml
generated
vendored
@ -12,18 +12,18 @@ env:
|
||||
matrix:
|
||||
- GOTAGS=
|
||||
- GOTAGS=libsqlite3
|
||||
- GOTAGS="sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable"
|
||||
- GOTAGS="sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify"
|
||||
- GOTAGS=sqlite_vacuum_full
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
brew update
|
||||
brew upgrade icu4c
|
||||
fi
|
||||
- |
|
||||
go get github.com/smartystreets/goconvey
|
||||
|
7
vendor/github.com/mattn/go-sqlite3/README.md
generated
vendored
7
vendor/github.com/mattn/go-sqlite3/README.md
generated
vendored
@ -67,6 +67,7 @@ This is also known as a DSN string. (Data Source Name).
|
||||
|
||||
Options are append after the filename of the SQLite database.
|
||||
The database filename and options are seperated by an `?` (Question Mark).
|
||||
Options should be URL-encoded (see [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)).
|
||||
|
||||
This also applies when using an in-memory database instead of a file.
|
||||
|
||||
@ -198,7 +199,7 @@ Additional information:
|
||||
|
||||
# Google Cloud Platform
|
||||
|
||||
Building on GCP is not possible because `Google Cloud Platform does not allow `gcc` to be executed.
|
||||
Building on GCP is not possible because Google Cloud Platform does not allow `gcc` to be executed.
|
||||
|
||||
Please work only with compiled final binaries.
|
||||
|
||||
@ -290,7 +291,7 @@ For example the TDM-GCC Toolchain can be found [here](ttps://sourceforge.net/pro
|
||||
When receiving a compile time error referencing recompile with `-FPIC` then you
|
||||
are probably using a hardend system.
|
||||
|
||||
You can copile the library on a hardend system with the following command.
|
||||
You can compile the library on a hardend system with the following command.
|
||||
|
||||
```bash
|
||||
go build -ldflags '-extldflags=-fno-PIC'
|
||||
@ -473,7 +474,7 @@ For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatial
|
||||
|
||||
For more information see [#289](https://github.com/mattn/go-sqlite3/issues/289)
|
||||
|
||||
- Trying to execure a `.` (dot) command throws an error.
|
||||
- Trying to execute a `.` (dot) command throws an error.
|
||||
|
||||
Error: `Error: near ".": syntax error`
|
||||
Dot command are part of SQLite3 CLI not of this library.
|
||||
|
6
vendor/github.com/mattn/go-sqlite3/callback.go
generated
vendored
6
vendor/github.com/mattn/go-sqlite3/callback.go
generated
vendored
@ -77,6 +77,12 @@ func updateHookTrampoline(handle uintptr, op int, db *C.char, table *C.char, row
|
||||
callback(op, C.GoString(db), C.GoString(table), rowid)
|
||||
}
|
||||
|
||||
//export authorizerTrampoline
|
||||
func authorizerTrampoline(handle uintptr, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int {
|
||||
callback := lookupHandle(handle).(func(int, string, string, string) int)
|
||||
return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3))
|
||||
}
|
||||
|
||||
// Use handles to avoid passing Go pointers to C.
|
||||
|
||||
type handleVal struct {
|
||||
|
21393
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
generated
vendored
21393
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
generated
vendored
File diff suppressed because it is too large
Load Diff
293
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
generated
vendored
293
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
generated
vendored
@ -124,9 +124,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.24.0"
|
||||
#define SQLITE_VERSION_NUMBER 3024000
|
||||
#define SQLITE_SOURCE_ID "2018-06-04 19:24:41 c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca"
|
||||
#define SQLITE_VERSION "3.25.2"
|
||||
#define SQLITE_VERSION_NUMBER 3025002
|
||||
#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@ -473,6 +473,7 @@ SQLITE_API int sqlite3_exec(
|
||||
*/
|
||||
#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
|
||||
#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
|
||||
#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8))
|
||||
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
|
||||
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
|
||||
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
|
||||
@ -512,6 +513,7 @@ SQLITE_API int sqlite3_exec(
|
||||
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
|
||||
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
|
||||
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
|
||||
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
|
||||
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
||||
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
|
||||
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
||||
@ -887,7 +889,8 @@ struct sqlite3_io_methods {
|
||||
** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
|
||||
** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
|
||||
** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary
|
||||
** write ahead log and shared memory files used for transaction control
|
||||
** write ahead log ([WAL file]) and shared memory
|
||||
** files used for transaction control
|
||||
** are automatically deleted when the latest connection to the database
|
||||
** closes. Setting persistent WAL mode causes those files to persist after
|
||||
** close. Persisting the files is useful when other processes that do not
|
||||
@ -1073,6 +1076,26 @@ struct sqlite3_io_methods {
|
||||
** a file lock using the xLock or xShmLock methods of the VFS to wait
|
||||
** for up to M milliseconds before failing, where M is the single
|
||||
** unsigned integer parameter.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
|
||||
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
|
||||
** a database file. The argument is a pointer to a 32-bit unsigned integer.
|
||||
** The "data version" for the pager is written into the pointer. The
|
||||
** "data version" changes whenever any change occurs to the corresponding
|
||||
** database file, either through SQL statements on the same database
|
||||
** connection or through transactions committed by separate database
|
||||
** connections possibly in other processes. The [sqlite3_total_changes()]
|
||||
** interface can be used to find if any database on the connection has changed,
|
||||
** but that interface responds to changes on TEMP as well as MAIN and does
|
||||
** not provide a mechanism to detect changes to MAIN only. Also, the
|
||||
** [sqlite3_total_changes()] interface responds to internal changes only and
|
||||
** omits changes made by other database connections. The
|
||||
** [PRAGMA data_version] command provide a mechanism to detect changes to
|
||||
** a single attached database that occur due to other database connections,
|
||||
** but omits changes implemented by the database connection on which it is
|
||||
** called. This file control is the only mechanism to detect changes that
|
||||
** happen either internally or externally and that are associated with
|
||||
** a particular attached database.
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
@ -1108,6 +1131,7 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
|
||||
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
|
||||
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
|
||||
#define SQLITE_FCNTL_DATA_VERSION 35
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
@ -2122,6 +2146,12 @@ struct sqlite3_mem_methods {
|
||||
** with no schema and no content. The following process works even for
|
||||
** a badly corrupted database file:
|
||||
** <ol>
|
||||
** <li> If the database connection is newly opened, make sure it has read the
|
||||
** database schema by preparing then discarding some query against the
|
||||
** database, or calling sqlite3_table_column_metadata(), ignoring any
|
||||
** errors. This step is only necessary if the application desires to keep
|
||||
** the database in WAL mode after the reset if it was in WAL mode before
|
||||
** the reset.
|
||||
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
|
||||
** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
|
||||
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
|
||||
@ -2270,12 +2300,17 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
|
||||
** program, the value returned reflects the number of rows modified by the
|
||||
** previous INSERT, UPDATE or DELETE statement within the same trigger.
|
||||
**
|
||||
** See also the [sqlite3_total_changes()] interface, the
|
||||
** [count_changes pragma], and the [changes() SQL function].
|
||||
**
|
||||
** If a separate thread makes changes on the same database connection
|
||||
** while [sqlite3_changes()] is running then the value returned
|
||||
** is unpredictable and not meaningful.
|
||||
**
|
||||
** See also:
|
||||
** <ul>
|
||||
** <li> the [sqlite3_total_changes()] interface
|
||||
** <li> the [count_changes pragma]
|
||||
** <li> the [changes() SQL function]
|
||||
** <li> the [data_version pragma]
|
||||
** </ul>
|
||||
*/
|
||||
SQLITE_API int sqlite3_changes(sqlite3*);
|
||||
|
||||
@ -2293,13 +2328,26 @@ SQLITE_API int sqlite3_changes(sqlite3*);
|
||||
** count, but those made as part of REPLACE constraint resolution are
|
||||
** not. ^Changes to a view that are intercepted by INSTEAD OF triggers
|
||||
** are not counted.
|
||||
**
|
||||
** See also the [sqlite3_changes()] interface, the
|
||||
** [count_changes pragma], and the [total_changes() SQL function].
|
||||
**
|
||||
** This the [sqlite3_total_changes(D)] interface only reports the number
|
||||
** of rows that changed due to SQL statement run against database
|
||||
** connection D. Any changes by other database connections are ignored.
|
||||
** To detect changes against a database file from other database
|
||||
** connections use the [PRAGMA data_version] command or the
|
||||
** [SQLITE_FCNTL_DATA_VERSION] [file control].
|
||||
**
|
||||
** If a separate thread makes changes on the same database connection
|
||||
** while [sqlite3_total_changes()] is running then the value
|
||||
** returned is unpredictable and not meaningful.
|
||||
**
|
||||
** See also:
|
||||
** <ul>
|
||||
** <li> the [sqlite3_changes()] interface
|
||||
** <li> the [count_changes pragma]
|
||||
** <li> the [changes() SQL function]
|
||||
** <li> the [data_version pragma]
|
||||
** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
|
||||
** </ul>
|
||||
*/
|
||||
SQLITE_API int sqlite3_total_changes(sqlite3*);
|
||||
|
||||
@ -3355,13 +3403,24 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
|
||||
** [database connection] D failed, then the sqlite3_errcode(D) interface
|
||||
** returns the numeric [result code] or [extended result code] for that
|
||||
** API call.
|
||||
** If the most recent API call was successful,
|
||||
** then the return value from sqlite3_errcode() is undefined.
|
||||
** ^The sqlite3_extended_errcode()
|
||||
** interface is the same except that it always returns the
|
||||
** [extended result code] even when extended result codes are
|
||||
** disabled.
|
||||
**
|
||||
** The values returned by sqlite3_errcode() and/or
|
||||
** sqlite3_extended_errcode() might change with each API call.
|
||||
** Except, there are some interfaces that are guaranteed to never
|
||||
** change the value of the error code. The error-code preserving
|
||||
** interfaces are:
|
||||
**
|
||||
** <ul>
|
||||
** <li> sqlite3_errcode()
|
||||
** <li> sqlite3_extended_errcode()
|
||||
** <li> sqlite3_errmsg()
|
||||
** <li> sqlite3_errmsg16()
|
||||
** </ul>
|
||||
**
|
||||
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
|
||||
** text that describes the error, as either UTF-8 or UTF-16 respectively.
|
||||
** ^(Memory to hold the error message string is managed internally.
|
||||
@ -4515,11 +4574,25 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
|
||||
** [sqlite3_free()].
|
||||
**
|
||||
** ^(If a memory allocation error occurs during the evaluation of any
|
||||
** of these routines, a default value is returned. The default value
|
||||
** is either the integer 0, the floating point number 0.0, or a NULL
|
||||
** pointer. Subsequent calls to [sqlite3_errcode()] will return
|
||||
** [SQLITE_NOMEM].)^
|
||||
** As long as the input parameters are correct, these routines will only
|
||||
** fail if an out-of-memory error occurs during a format conversion.
|
||||
** Only the following subset of interfaces are subject to out-of-memory
|
||||
** errors:
|
||||
**
|
||||
** <ul>
|
||||
** <li> sqlite3_column_blob()
|
||||
** <li> sqlite3_column_text()
|
||||
** <li> sqlite3_column_text16()
|
||||
** <li> sqlite3_column_bytes()
|
||||
** <li> sqlite3_column_bytes16()
|
||||
** </ul>
|
||||
**
|
||||
** If an out-of-memory error occurs, then the return value from these
|
||||
** routines is the same as if the column had contained an SQL NULL value.
|
||||
** Valid SQL NULL returns can be distinguished from out-of-memory errors
|
||||
** by invoking the [sqlite3_errcode()] immediately after the suspect
|
||||
** return value is obtained and before any
|
||||
** other SQLite interface is called on the same [database connection].
|
||||
*/
|
||||
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
|
||||
SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
|
||||
@ -4596,11 +4669,13 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
**
|
||||
** ^These functions (collectively known as "function creation routines")
|
||||
** are used to add SQL functions or aggregates or to redefine the behavior
|
||||
** of existing SQL functions or aggregates. The only differences between
|
||||
** these routines are the text encoding expected for
|
||||
** the second parameter (the name of the function being created)
|
||||
** and the presence or absence of a destructor callback for
|
||||
** the application data pointer.
|
||||
** of existing SQL functions or aggregates. The only differences between
|
||||
** the three "sqlite3_create_function*" routines are the text encoding
|
||||
** expected for the second parameter (the name of the function being
|
||||
** created) and the presence or absence of a destructor callback for
|
||||
** the application data pointer. Function sqlite3_create_window_function()
|
||||
** is similar, but allows the user to supply the extra callback functions
|
||||
** needed by [aggregate window functions].
|
||||
**
|
||||
** ^The first parameter is the [database connection] to which the SQL
|
||||
** function is to be added. ^If an application uses more than one database
|
||||
@ -4646,7 +4721,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
|
||||
** function can gain access to this pointer using [sqlite3_user_data()].)^
|
||||
**
|
||||
** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
|
||||
** ^The sixth, seventh and eighth parameters passed to the three
|
||||
** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
|
||||
** pointers to C-language functions that implement the SQL function or
|
||||
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
|
||||
** callback only; NULL pointers must be passed as the xStep and xFinal
|
||||
@ -4655,15 +4731,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||
** SQL function or aggregate, pass NULL pointers for all three function
|
||||
** callbacks.
|
||||
**
|
||||
** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
|
||||
** then it is destructor for the application data pointer.
|
||||
** The destructor is invoked when the function is deleted, either by being
|
||||
** overloaded or when the database connection closes.)^
|
||||
** ^The destructor is also invoked if the call to
|
||||
** sqlite3_create_function_v2() fails.
|
||||
** ^When the destructor callback of the tenth parameter is invoked, it
|
||||
** is passed a single argument which is a copy of the application data
|
||||
** pointer which was the fifth parameter to sqlite3_create_function_v2().
|
||||
** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue
|
||||
** and xInverse) passed to sqlite3_create_window_function are pointers to
|
||||
** C-language callbacks that implement the new function. xStep and xFinal
|
||||
** must both be non-NULL. xValue and xInverse may either both be NULL, in
|
||||
** which case a regular aggregate function is created, or must both be
|
||||
** non-NULL, in which case the new function may be used as either an aggregate
|
||||
** or aggregate window function. More details regarding the implementation
|
||||
** of aggregate window functions are
|
||||
** [user-defined window functions|available here].
|
||||
**
|
||||
** ^(If the final parameter to sqlite3_create_function_v2() or
|
||||
** sqlite3_create_window_function() is not NULL, then it is destructor for
|
||||
** the application data pointer. The destructor is invoked when the function
|
||||
** is deleted, either by being overloaded or when the database connection
|
||||
** closes.)^ ^The destructor is also invoked if the call to
|
||||
** sqlite3_create_function_v2() fails. ^When the destructor callback is
|
||||
** invoked, it is passed a single argument which is a copy of the application
|
||||
** data pointer which was the fifth parameter to sqlite3_create_function_v2().
|
||||
**
|
||||
** ^It is permitted to register multiple implementations of the same
|
||||
** functions with the same name but with either differing numbers of
|
||||
@ -4716,6 +4801,18 @@ SQLITE_API int sqlite3_create_function_v2(
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void(*xDestroy)(void*)
|
||||
);
|
||||
SQLITE_API int sqlite3_create_window_function(
|
||||
sqlite3 *db,
|
||||
const char *zFunctionName,
|
||||
int nArg,
|
||||
int eTextRep,
|
||||
void *pApp,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*)
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Text Encodings
|
||||
@ -4858,6 +4955,28 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
|
||||
**
|
||||
** These routines must be called from the same thread as
|
||||
** the SQL function that supplied the [sqlite3_value*] parameters.
|
||||
**
|
||||
** As long as the input parameter is correct, these routines can only
|
||||
** fail if an out-of-memory error occurs during a format conversion.
|
||||
** Only the following subset of interfaces are subject to out-of-memory
|
||||
** errors:
|
||||
**
|
||||
** <ul>
|
||||
** <li> sqlite3_value_blob()
|
||||
** <li> sqlite3_value_text()
|
||||
** <li> sqlite3_value_text16()
|
||||
** <li> sqlite3_value_text16le()
|
||||
** <li> sqlite3_value_text16be()
|
||||
** <li> sqlite3_value_bytes()
|
||||
** <li> sqlite3_value_bytes16()
|
||||
** </ul>
|
||||
**
|
||||
** If an out-of-memory error occurs, then the return value from these
|
||||
** routines is the same as if the column had contained an SQL NULL value.
|
||||
** Valid SQL NULL returns can be distinguished from out-of-memory errors
|
||||
** by invoking the [sqlite3_errcode()] immediately after the suspect
|
||||
** return value is obtained and before any
|
||||
** other SQLite interface is called on the same [database connection].
|
||||
*/
|
||||
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
|
||||
SQLITE_API double sqlite3_value_double(sqlite3_value*);
|
||||
@ -6324,6 +6443,7 @@ struct sqlite3_index_info {
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
|
||||
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
|
||||
#define SQLITE_INDEX_CONSTRAINT_IS 72
|
||||
#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
|
||||
|
||||
/*
|
||||
** CAPI3REF: Register A Virtual Table Implementation
|
||||
@ -7000,6 +7120,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
|
||||
/*
|
||||
** CAPI3REF: Low-Level Control Of Database Files
|
||||
** METHOD: sqlite3
|
||||
** KEYWORDS: {file control}
|
||||
**
|
||||
** ^The [sqlite3_file_control()] interface makes a direct call to the
|
||||
** xFileControl method for the [sqlite3_io_methods] object associated
|
||||
@ -7014,11 +7135,18 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
|
||||
** the xFileControl method. ^The return value of the xFileControl
|
||||
** method becomes the return value of this routine.
|
||||
**
|
||||
** A few opcodes for [sqlite3_file_control()] are handled directly
|
||||
** by the SQLite core and never invoke the
|
||||
** sqlite3_io_methods.xFileControl method.
|
||||
** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
|
||||
** a pointer to the underlying [sqlite3_file] object to be written into
|
||||
** the space pointed to by the 4th parameter. ^The [SQLITE_FCNTL_FILE_POINTER]
|
||||
** case is a short-circuit path which does not actually invoke the
|
||||
** underlying sqlite3_io_methods.xFileControl method.
|
||||
** the space pointed to by the 4th parameter. The
|
||||
** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
|
||||
** the [sqlite3_file] object associated with the journal file instead of
|
||||
** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns
|
||||
** a pointer to the underlying [sqlite3_vfs] object for the file.
|
||||
** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
|
||||
** from the pager.
|
||||
**
|
||||
** ^If the second parameter (zDbName) does not match the name of any
|
||||
** open database file, then SQLITE_ERROR is returned. ^This error
|
||||
@ -8837,7 +8965,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*);
|
||||
/*
|
||||
** CAPI3REF: Database Snapshot
|
||||
** KEYWORDS: {snapshot} {sqlite3_snapshot}
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** An instance of the snapshot object records the state of a [WAL mode]
|
||||
** database for some specific point in history.
|
||||
@ -8854,11 +8981,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*);
|
||||
** version of the database file so that it is possible to later open a new read
|
||||
** transaction that sees that historical version of the database rather than
|
||||
** the most recent version.
|
||||
**
|
||||
** The constructor for this object is [sqlite3_snapshot_get()]. The
|
||||
** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
|
||||
** to an historical snapshot (if possible). The destructor for
|
||||
** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
|
||||
*/
|
||||
typedef struct sqlite3_snapshot {
|
||||
unsigned char hidden[48];
|
||||
@ -8866,7 +8988,7 @@ typedef struct sqlite3_snapshot {
|
||||
|
||||
/*
|
||||
** CAPI3REF: Record A Database Snapshot
|
||||
** EXPERIMENTAL
|
||||
** CONSTRUCTOR: sqlite3_snapshot
|
||||
**
|
||||
** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
|
||||
** new [sqlite3_snapshot] object that records the current state of
|
||||
@ -8882,7 +9004,7 @@ typedef struct sqlite3_snapshot {
|
||||
** in this case.
|
||||
**
|
||||
** <ul>
|
||||
** <li> The database handle must be in [autocommit mode].
|
||||
** <li> The database handle must not be in [autocommit mode].
|
||||
**
|
||||
** <li> Schema S of [database connection] D must be a [WAL mode] database.
|
||||
**
|
||||
@ -8905,7 +9027,7 @@ typedef struct sqlite3_snapshot {
|
||||
** to avoid a memory leak.
|
||||
**
|
||||
** The [sqlite3_snapshot_get()] interface is only available when the
|
||||
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
|
||||
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
|
||||
*/
|
||||
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
||||
sqlite3 *db,
|
||||
@ -8915,24 +9037,35 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Start a read transaction on an historical snapshot
|
||||
** EXPERIMENTAL
|
||||
** METHOD: sqlite3_snapshot
|
||||
**
|
||||
** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
|
||||
** read transaction for schema S of
|
||||
** [database connection] D such that the read transaction
|
||||
** refers to historical [snapshot] P, rather than the most
|
||||
** recent change to the database.
|
||||
** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
|
||||
** or an appropriate [error code] if it fails.
|
||||
** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read
|
||||
** transaction or upgrades an existing one for schema S of
|
||||
** [database connection] D such that the read transaction refers to
|
||||
** historical [snapshot] P, rather than the most recent change to the
|
||||
** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK
|
||||
** on success or an appropriate [error code] if it fails.
|
||||
**
|
||||
** ^In order to succeed, the database connection must not be in
|
||||
** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
|
||||
** is already a read transaction open on schema S, then the database handle
|
||||
** must have no active statements (SELECT statements that have been passed
|
||||
** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()).
|
||||
** SQLITE_ERROR is returned if either of these conditions is violated, or
|
||||
** if schema S does not exist, or if the snapshot object is invalid.
|
||||
**
|
||||
** ^A call to sqlite3_snapshot_open() will fail to open if the specified
|
||||
** snapshot has been overwritten by a [checkpoint]. In this case
|
||||
** SQLITE_ERROR_SNAPSHOT is returned.
|
||||
**
|
||||
** If there is already a read transaction open when this function is
|
||||
** invoked, then the same read transaction remains open (on the same
|
||||
** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
|
||||
** is returned. If another error code - for example SQLITE_PROTOCOL or an
|
||||
** SQLITE_IOERR error code - is returned, then the final state of the
|
||||
** read transaction is undefined. If SQLITE_OK is returned, then the
|
||||
** read transaction is now open on database snapshot P.
|
||||
**
|
||||
** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
|
||||
** the first operation following the [BEGIN] that takes the schema S
|
||||
** out of [autocommit mode].
|
||||
** ^In other words, schema S must not currently be in
|
||||
** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
|
||||
** database connection D must be out of [autocommit mode].
|
||||
** ^A [snapshot] will fail to open if it has been overwritten by a
|
||||
** [checkpoint].
|
||||
** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
|
||||
** database connection D does not know that the database file for
|
||||
** schema S is in [WAL mode]. A database connection might not know
|
||||
@ -8943,7 +9076,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
||||
** database connection in order to make it ready to use snapshots.)
|
||||
**
|
||||
** The [sqlite3_snapshot_open()] interface is only available when the
|
||||
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
|
||||
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
|
||||
*/
|
||||
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
|
||||
sqlite3 *db,
|
||||
@ -8953,20 +9086,20 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Destroy a snapshot
|
||||
** EXPERIMENTAL
|
||||
** DESTRUCTOR: sqlite3_snapshot
|
||||
**
|
||||
** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
|
||||
** The application must eventually free every [sqlite3_snapshot] object
|
||||
** using this routine to avoid a memory leak.
|
||||
**
|
||||
** The [sqlite3_snapshot_free()] interface is only available when the
|
||||
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
|
||||
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
|
||||
*/
|
||||
SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Compare the ages of two snapshot handles.
|
||||
** EXPERIMENTAL
|
||||
** METHOD: sqlite3_snapshot
|
||||
**
|
||||
** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
|
||||
** of two valid snapshot handles.
|
||||
@ -8985,6 +9118,9 @@ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
|
||||
** Otherwise, this API returns a negative value if P1 refers to an older
|
||||
** snapshot than P2, zero if the two handles refer to the same database
|
||||
** snapshot, and a positive value if P1 is a newer snapshot than P2.
|
||||
**
|
||||
** This interface is only available if SQLite is compiled with the
|
||||
** [SQLITE_ENABLE_SNAPSHOT] option.
|
||||
*/
|
||||
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
||||
sqlite3_snapshot *p1,
|
||||
@ -8993,23 +9129,26 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
||||
|
||||
/*
|
||||
** CAPI3REF: Recover snapshots from a wal file
|
||||
** EXPERIMENTAL
|
||||
** METHOD: sqlite3_snapshot
|
||||
**
|
||||
** If all connections disconnect from a database file but do not perform
|
||||
** a checkpoint, the existing wal file is opened along with the database
|
||||
** file the next time the database is opened. At this point it is only
|
||||
** possible to successfully call sqlite3_snapshot_open() to open the most
|
||||
** recent snapshot of the database (the one at the head of the wal file),
|
||||
** even though the wal file may contain other valid snapshots for which
|
||||
** clients have sqlite3_snapshot handles.
|
||||
** If a [WAL file] remains on disk after all database connections close
|
||||
** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
|
||||
** or because the last process to have the database opened exited without
|
||||
** calling [sqlite3_close()]) and a new connection is subsequently opened
|
||||
** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
|
||||
** will only be able to open the last transaction added to the WAL file
|
||||
** even though the WAL file contains other valid transactions.
|
||||
**
|
||||
** This function attempts to scan the wal file associated with database zDb
|
||||
** This function attempts to scan the WAL file associated with database zDb
|
||||
** of database handle db and make all valid snapshots available to
|
||||
** sqlite3_snapshot_open(). It is an error if there is already a read
|
||||
** transaction open on the database, or if the database is not a wal mode
|
||||
** transaction open on the database, or if the database is not a WAL mode
|
||||
** database.
|
||||
**
|
||||
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
|
||||
**
|
||||
** This interface is only available if SQLite is compiled with the
|
||||
** [SQLITE_ENABLE_SNAPSHOT] option.
|
||||
*/
|
||||
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
|
||||
|
||||
@ -9120,7 +9259,7 @@ SQLITE_API int sqlite3_deserialize(
|
||||
** in the P argument is held in memory obtained from [sqlite3_malloc64()]
|
||||
** and that SQLite should take ownership of this memory and automatically
|
||||
** free it when it has finished using it. Without this flag, the caller
|
||||
** is resposible for freeing any dynamically allocated memory.
|
||||
** is responsible for freeing any dynamically allocated memory.
|
||||
**
|
||||
** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
|
||||
** grow the size of the database using calls to [sqlite3_realloc64()]. This
|
||||
@ -11298,7 +11437,7 @@ struct Fts5ExtensionApi {
|
||||
** This way, even if the tokenizer does not provide synonyms
|
||||
** when tokenizing query text (it should not - to do would be
|
||||
** inefficient), it doesn't matter if the user queries for
|
||||
** 'first + place' or '1st + place', as there are entires in the
|
||||
** 'first + place' or '1st + place', as there are entries in the
|
||||
** FTS index corresponding to both forms of the first token.
|
||||
** </ol>
|
||||
**
|
||||
@ -11326,7 +11465,7 @@ struct Fts5ExtensionApi {
|
||||
** extra data to the FTS index or require FTS5 to query for multiple terms,
|
||||
** so it is efficient in terms of disk space and query speed. However, it
|
||||
** does not support prefix queries very well. If, as suggested above, the
|
||||
** token "first" is subsituted for "1st" by the tokenizer, then the query:
|
||||
** token "first" is substituted for "1st" by the tokenizer, then the query:
|
||||
**
|
||||
** <codeblock>
|
||||
** ... MATCH '1s*'</codeblock>
|
||||
|
116
vendor/github.com/mattn/go-sqlite3/sqlite3.go
generated
vendored
116
vendor/github.com/mattn/go-sqlite3/sqlite3.go
generated
vendored
@ -78,8 +78,38 @@ _sqlite3_exec(sqlite3* db, const char* pcmd, long long* rowid, long long* change
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
extern int _sqlite3_step_blocking(sqlite3_stmt *stmt);
|
||||
extern int _sqlite3_step_row_blocking(sqlite3_stmt* stmt, long long* rowid, long long* changes);
|
||||
extern int _sqlite3_prepare_v2_blocking(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail);
|
||||
|
||||
static int
|
||||
_sqlite3_step(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||
_sqlite3_step_internal(sqlite3_stmt *stmt)
|
||||
{
|
||||
return _sqlite3_step_blocking(stmt);
|
||||
}
|
||||
|
||||
static int
|
||||
_sqlite3_step_row_internal(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||
{
|
||||
return _sqlite3_step_row_blocking(stmt, rowid, changes);
|
||||
}
|
||||
|
||||
static int
|
||||
_sqlite3_prepare_v2_internal(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
|
||||
{
|
||||
return _sqlite3_prepare_v2_blocking(db, zSql, nBytes, ppStmt, pzTail);
|
||||
}
|
||||
|
||||
#else
|
||||
static int
|
||||
_sqlite3_step_internal(sqlite3_stmt *stmt)
|
||||
{
|
||||
return sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
static int
|
||||
_sqlite3_step_row_internal(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||
{
|
||||
int rv = sqlite3_step(stmt);
|
||||
sqlite3* db = sqlite3_db_handle(stmt);
|
||||
@ -88,6 +118,13 @@ _sqlite3_step(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int
|
||||
_sqlite3_prepare_v2_internal(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
|
||||
{
|
||||
return sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);
|
||||
}
|
||||
#endif
|
||||
|
||||
void _sqlite3_result_text(sqlite3_context* ctx, const char* s) {
|
||||
sqlite3_result_text(ctx, s, -1, &free);
|
||||
}
|
||||
@ -119,6 +156,8 @@ int commitHookTrampoline(void*);
|
||||
void rollbackHookTrampoline(void*);
|
||||
void updateHookTrampoline(void*, int, char*, char*, sqlite3_int64);
|
||||
|
||||
int authorizerTrampoline(void*, int, char*, char*, char*, char*);
|
||||
|
||||
#ifdef SQLITE_LIMIT_WORKER_THREADS
|
||||
# define _SQLITE_HAS_LIMIT
|
||||
# define SQLITE_LIMIT_LENGTH 0
|
||||
@ -200,18 +239,57 @@ func Version() (libVersion string, libVersionNumber int, sourceID string) {
|
||||
}
|
||||
|
||||
const (
|
||||
// used by authorizer and pre_update_hook
|
||||
SQLITE_DELETE = C.SQLITE_DELETE
|
||||
SQLITE_INSERT = C.SQLITE_INSERT
|
||||
SQLITE_UPDATE = C.SQLITE_UPDATE
|
||||
|
||||
// used by authorzier - as return value
|
||||
SQLITE_OK = C.SQLITE_OK
|
||||
SQLITE_IGNORE = C.SQLITE_IGNORE
|
||||
SQLITE_DENY = C.SQLITE_DENY
|
||||
|
||||
// different actions query tries to do - passed as argument to authorizer
|
||||
SQLITE_CREATE_INDEX = C.SQLITE_CREATE_INDEX
|
||||
SQLITE_CREATE_TABLE = C.SQLITE_CREATE_TABLE
|
||||
SQLITE_CREATE_TEMP_INDEX = C.SQLITE_CREATE_TEMP_INDEX
|
||||
SQLITE_CREATE_TEMP_TABLE = C.SQLITE_CREATE_TEMP_TABLE
|
||||
SQLITE_CREATE_TEMP_TRIGGER = C.SQLITE_CREATE_TEMP_TRIGGER
|
||||
SQLITE_CREATE_TEMP_VIEW = C.SQLITE_CREATE_TEMP_VIEW
|
||||
SQLITE_CREATE_TRIGGER = C.SQLITE_CREATE_TRIGGER
|
||||
SQLITE_CREATE_VIEW = C.SQLITE_CREATE_VIEW
|
||||
SQLITE_CREATE_VTABLE = C.SQLITE_CREATE_VTABLE
|
||||
SQLITE_DROP_INDEX = C.SQLITE_DROP_INDEX
|
||||
SQLITE_DROP_TABLE = C.SQLITE_DROP_TABLE
|
||||
SQLITE_DROP_TEMP_INDEX = C.SQLITE_DROP_TEMP_INDEX
|
||||
SQLITE_DROP_TEMP_TABLE = C.SQLITE_DROP_TEMP_TABLE
|
||||
SQLITE_DROP_TEMP_TRIGGER = C.SQLITE_DROP_TEMP_TRIGGER
|
||||
SQLITE_DROP_TEMP_VIEW = C.SQLITE_DROP_TEMP_VIEW
|
||||
SQLITE_DROP_TRIGGER = C.SQLITE_DROP_TRIGGER
|
||||
SQLITE_DROP_VIEW = C.SQLITE_DROP_VIEW
|
||||
SQLITE_DROP_VTABLE = C.SQLITE_DROP_VTABLE
|
||||
SQLITE_PRAGMA = C.SQLITE_PRAGMA
|
||||
SQLITE_READ = C.SQLITE_READ
|
||||
SQLITE_SELECT = C.SQLITE_SELECT
|
||||
SQLITE_TRANSACTION = C.SQLITE_TRANSACTION
|
||||
SQLITE_ATTACH = C.SQLITE_ATTACH
|
||||
SQLITE_DETACH = C.SQLITE_DETACH
|
||||
SQLITE_ALTER_TABLE = C.SQLITE_ALTER_TABLE
|
||||
SQLITE_REINDEX = C.SQLITE_REINDEX
|
||||
SQLITE_ANALYZE = C.SQLITE_ANALYZE
|
||||
SQLITE_FUNCTION = C.SQLITE_FUNCTION
|
||||
SQLITE_SAVEPOINT = C.SQLITE_SAVEPOINT
|
||||
SQLITE_COPY = C.SQLITE_COPY
|
||||
/*SQLITE_RECURSIVE = C.SQLITE_RECURSIVE*/
|
||||
)
|
||||
|
||||
// SQLiteDriver implement sql.Driver.
|
||||
// SQLiteDriver implements driver.Driver.
|
||||
type SQLiteDriver struct {
|
||||
Extensions []string
|
||||
ConnectHook func(*SQLiteConn) error
|
||||
}
|
||||
|
||||
// SQLiteConn implement sql.Conn.
|
||||
// SQLiteConn implements driver.Conn.
|
||||
type SQLiteConn struct {
|
||||
mu sync.Mutex
|
||||
db *C.sqlite3
|
||||
@ -221,12 +299,12 @@ type SQLiteConn struct {
|
||||
aggregators []*aggInfo
|
||||
}
|
||||
|
||||
// SQLiteTx implemen sql.Tx.
|
||||
// SQLiteTx implements driver.Tx.
|
||||
type SQLiteTx struct {
|
||||
c *SQLiteConn
|
||||
}
|
||||
|
||||
// SQLiteStmt implement sql.Stmt.
|
||||
// SQLiteStmt implements driver.Stmt.
|
||||
type SQLiteStmt struct {
|
||||
mu sync.Mutex
|
||||
c *SQLiteConn
|
||||
@ -236,13 +314,13 @@ type SQLiteStmt struct {
|
||||
cls bool
|
||||
}
|
||||
|
||||
// SQLiteResult implement sql.Result.
|
||||
// SQLiteResult implements sql.Result.
|
||||
type SQLiteResult struct {
|
||||
id int64
|
||||
changes int64
|
||||
}
|
||||
|
||||
// SQLiteRows implement sql.Rows.
|
||||
// SQLiteRows implements driver.Rows.
|
||||
type SQLiteRows struct {
|
||||
s *SQLiteStmt
|
||||
nc int
|
||||
@ -440,6 +518,20 @@ func (c *SQLiteConn) RegisterUpdateHook(callback func(int, string, string, int64
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterAuthorizer sets the authorizer for connection.
|
||||
//
|
||||
// The parameters to the callback are the operation (one of the constants
|
||||
// SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE), and 1 to 3 arguments,
|
||||
// depending on operation. More details see:
|
||||
// https://www.sqlite.org/c3ref/c_alter_table.html
|
||||
func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, string) int) {
|
||||
if callback == nil {
|
||||
C.sqlite3_set_authorizer(c.db, nil, nil)
|
||||
} else {
|
||||
C.sqlite3_set_authorizer(c.db, (*[0]byte)(C.authorizerTrampoline), unsafe.Pointer(newHandle(c, callback)))
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterFunc makes a Go function available as a SQLite function.
|
||||
//
|
||||
// The Go function can have arguments of the following types: any
|
||||
@ -1582,7 +1674,7 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
|
||||
defer C.free(unsafe.Pointer(pquery))
|
||||
var s *C.sqlite3_stmt
|
||||
var tail *C.char
|
||||
rv := C.sqlite3_prepare_v2(c.db, pquery, -1, &s, &tail)
|
||||
rv := C._sqlite3_prepare_v2_internal(c.db, pquery, -1, &s, &tail)
|
||||
if rv != C.SQLITE_OK {
|
||||
return nil, c.lastError()
|
||||
}
|
||||
@ -1816,7 +1908,7 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
|
||||
}
|
||||
|
||||
var rowid, changes C.longlong
|
||||
rv := C._sqlite3_step(s.s, &rowid, &changes)
|
||||
rv := C._sqlite3_step_row_internal(s.s, &rowid, &changes)
|
||||
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
|
||||
err := s.c.lastError()
|
||||
C.sqlite3_reset(s.s)
|
||||
@ -1883,12 +1975,12 @@ func (rc *SQLiteRows) DeclTypes() []string {
|
||||
|
||||
// Next move cursor to next.
|
||||
func (rc *SQLiteRows) Next(dest []driver.Value) error {
|
||||
rc.s.mu.Lock()
|
||||
defer rc.s.mu.Unlock()
|
||||
if rc.s.closed {
|
||||
return io.EOF
|
||||
}
|
||||
rc.s.mu.Lock()
|
||||
defer rc.s.mu.Unlock()
|
||||
rv := C.sqlite3_step(rc.s.s)
|
||||
rv := C._sqlite3_step_internal(rc.s.s)
|
||||
if rv == C.SQLITE_DONE {
|
||||
return io.EOF
|
||||
}
|
||||
|
8
vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go
generated
vendored
8
vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go
generated
vendored
@ -83,13 +83,13 @@ func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte
|
||||
}
|
||||
}
|
||||
|
||||
// CryptEncoderSHA384 encodes a password with SHA256
|
||||
// CryptEncoderSHA384 encodes a password with SHA384
|
||||
func CryptEncoderSHA384(pass []byte, hash interface{}) []byte {
|
||||
h := sha512.Sum384(pass)
|
||||
return h[:]
|
||||
}
|
||||
|
||||
// CryptEncoderSSHA384 encodes a password with SHA256
|
||||
// CryptEncoderSSHA384 encodes a password with SHA384
|
||||
// with the configured salt
|
||||
func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte {
|
||||
return func(pass []byte, hash interface{}) []byte {
|
||||
@ -100,13 +100,13 @@ func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte
|
||||
}
|
||||
}
|
||||
|
||||
// CryptEncoderSHA512 encodes a password with SHA256
|
||||
// CryptEncoderSHA512 encodes a password with SHA512
|
||||
func CryptEncoderSHA512(pass []byte, hash interface{}) []byte {
|
||||
h := sha512.Sum512(pass)
|
||||
return h[:]
|
||||
}
|
||||
|
||||
// CryptEncoderSSHA512 encodes a password with SHA256
|
||||
// CryptEncoderSSHA512 encodes a password with SHA512
|
||||
// with the configured salt
|
||||
func CryptEncoderSSHA512(salt string) func(pass []byte, hash interface{}) []byte {
|
||||
return func(pass []byte, hash interface{}) []byte {
|
||||
|
85
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.c
generated
vendored
Normal file
85
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.c
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
// Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
|
||||
//
|
||||
// Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
#include <stdio.h>
|
||||
#include <sqlite3-binding.h>
|
||||
|
||||
extern int unlock_notify_wait(sqlite3 *db);
|
||||
|
||||
int
|
||||
_sqlite3_step_blocking(sqlite3_stmt *stmt)
|
||||
{
|
||||
int rv;
|
||||
sqlite3* db;
|
||||
|
||||
db = sqlite3_db_handle(stmt);
|
||||
for (;;) {
|
||||
rv = sqlite3_step(stmt);
|
||||
if (rv != SQLITE_LOCKED) {
|
||||
break;
|
||||
}
|
||||
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
|
||||
break;
|
||||
}
|
||||
rv = unlock_notify_wait(db);
|
||||
if (rv != SQLITE_OK) {
|
||||
break;
|
||||
}
|
||||
sqlite3_reset(stmt);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
_sqlite3_step_row_blocking(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||
{
|
||||
int rv;
|
||||
sqlite3* db;
|
||||
|
||||
db = sqlite3_db_handle(stmt);
|
||||
for (;;) {
|
||||
rv = sqlite3_step(stmt);
|
||||
if (rv!=SQLITE_LOCKED) {
|
||||
break;
|
||||
}
|
||||
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
|
||||
break;
|
||||
}
|
||||
rv = unlock_notify_wait(db);
|
||||
if (rv != SQLITE_OK) {
|
||||
break;
|
||||
}
|
||||
sqlite3_reset(stmt);
|
||||
}
|
||||
|
||||
*rowid = (long long) sqlite3_last_insert_rowid(db);
|
||||
*changes = (long long) sqlite3_changes(db);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
_sqlite3_prepare_v2_blocking(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
|
||||
{
|
||||
int rv;
|
||||
|
||||
for (;;) {
|
||||
rv = sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);
|
||||
if (rv!=SQLITE_LOCKED) {
|
||||
break;
|
||||
}
|
||||
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
|
||||
break;
|
||||
}
|
||||
rv = unlock_notify_wait(db);
|
||||
if (rv != SQLITE_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
93
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go
generated
vendored
Normal file
93
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
|
||||
//
|
||||
// Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build cgo
|
||||
// +build sqlite_unlock_notify
|
||||
|
||||
package sqlite3
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sqlite3-binding.h>
|
||||
|
||||
extern void unlock_notify_callback(void *arg, int argc);
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type unlock_notify_table struct {
|
||||
sync.Mutex
|
||||
seqnum uint
|
||||
table map[uint]chan struct{}
|
||||
}
|
||||
|
||||
var unt unlock_notify_table = unlock_notify_table{table: make(map[uint]chan struct{})}
|
||||
|
||||
func (t *unlock_notify_table) add(c chan struct{}) uint {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
h := t.seqnum
|
||||
t.table[h] = c
|
||||
t.seqnum++
|
||||
return h
|
||||
}
|
||||
|
||||
func (t *unlock_notify_table) remove(h uint) {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
delete(t.table, h)
|
||||
}
|
||||
|
||||
func (t *unlock_notify_table) get(h uint) chan struct{} {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
c, ok := t.table[h]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Non-existent key for unlcok-notify channel: %d", h))
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
//export unlock_notify_callback
|
||||
func unlock_notify_callback(argv unsafe.Pointer, argc C.int) {
|
||||
for i := 0; i < int(argc); i++ {
|
||||
parg := ((*(*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.uint)(nil))]*[1]uint)(argv))[i])
|
||||
arg := *parg
|
||||
h := arg[0]
|
||||
c := unt.get(h)
|
||||
c <- struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
//export unlock_notify_wait
|
||||
func unlock_notify_wait(db *C.sqlite3) C.int {
|
||||
// It has to be a bufferred channel to not block in sqlite_unlock_notify
|
||||
// as sqlite_unlock_notify could invoke the callback before it returns.
|
||||
c := make(chan struct{}, 1)
|
||||
defer close(c)
|
||||
|
||||
h := unt.add(c)
|
||||
defer unt.remove(h)
|
||||
|
||||
pargv := C.malloc(C.sizeof_uint)
|
||||
defer C.free(pargv)
|
||||
|
||||
argv := (*[1]uint)(pargv)
|
||||
argv[0] = h
|
||||
if rv := C.sqlite3_unlock_notify(db, (*[0]byte)(C.unlock_notify_callback), unsafe.Pointer(pargv)); rv != C.SQLITE_OK {
|
||||
return rv
|
||||
}
|
||||
|
||||
<-c
|
||||
|
||||
return C.SQLITE_OK
|
||||
}
|
3
vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
generated
vendored
3
vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
generated
vendored
@ -10,5 +10,8 @@ package sqlite3
|
||||
/*
|
||||
#cgo CFLAGS: -I.
|
||||
#cgo linux LDFLAGS: -ldl
|
||||
#cgo linux,ppc LDFLAGS: -lpthread
|
||||
#cgo linux,ppc64 LDFLAGS: -lpthread
|
||||
#cgo linux,ppc64le LDFLAGS: -lpthread
|
||||
*/
|
||||
import "C"
|
||||
|
8
vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
generated
vendored
8
vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
generated
vendored
@ -311,6 +311,12 @@ struct sqlite3_api_routines {
|
||||
int (*str_errcode)(sqlite3_str*);
|
||||
int (*str_length)(sqlite3_str*);
|
||||
char *(*str_value)(sqlite3_str*);
|
||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*));
|
||||
};
|
||||
|
||||
/*
|
||||
@ -596,6 +602,8 @@ typedef int (*sqlite3_loadext_entry)(
|
||||
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
||||
#define sqlite3_str_length sqlite3_api->str_length
|
||||
#define sqlite3_str_value sqlite3_api->str_value
|
||||
/* Version 3.25.0 and later */
|
||||
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
24
vendor/go.etcd.io/etcd/LICENSE → vendor/github.com/rancher/kine/LICENSE
generated
vendored
24
vendor/go.etcd.io/etcd/LICENSE → vendor/github.com/rancher/kine/LICENSE
generated
vendored
@ -176,27 +176,3 @@
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
16
vendor/github.com/rancher/kine/go.mod
generated
vendored
Normal file
16
vendor/github.com/rancher/kine/go.mod
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
module github.com/rancher/kine
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/coreos/etcd v3.3.13+incompatible
|
||||
github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/gogo/protobuf v1.2.1 // indirect
|
||||
github.com/lib/pq v1.1.1
|
||||
github.com/mattn/go-sqlite3 v1.10.0
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/rancher/wrangler v0.0.0-20190512193419-40fa298578b9
|
||||
github.com/sirupsen/logrus v1.4.1
|
||||
github.com/urfave/cli v1.21.0
|
||||
google.golang.org/grpc v1.20.1
|
||||
)
|
159
vendor/github.com/rancher/kine/go.sum
generated
vendored
Normal file
159
vendor/github.com/rancher/kine/go.sum
generated
vendored
Normal file
@ -0,0 +1,159 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rancher/wrangler v0.0.0-20190512193419-40fa298578b9 h1:Bw3iaHfGqJNXx/j1XvFMxQVIzE0LCVX8iJ7UOcWy2ck=
|
||||
github.com/rancher/wrangler v0.0.0-20190512193419-40fa298578b9/go.mod h1:HM0BuhAugqM5cGtQn2hrMwpbExuLQe7NCUTD+crAxV0=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/urfave/cli v1.21.0 h1:wYSSj06510qPIzGSua9ZqsncMmWE3Zr55KBERygyrxE=
|
||||
github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE=
|
||||
k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
k8s.io/code-generator v0.0.0-20190419212335-ff26e7842f9d/go.mod h1:rVrFWfTVftGH7bb972nWC6N4QkJ4LU7FOXu8GH2UkJo=
|
||||
k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0 h1:0VPpR+sizsiivjIfIAQH/rl8tan6jvWkS7lU+0di3lE=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/kube-openapi v0.0.0-20190502190224-411b2483e503/go.mod h1:iU+ZGYsNlvU9XKUSso6SQfKTCCw7lFduMZy26Mgr2Fw=
|
||||
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5 h1:VBM/0P5TWxwk+Nw6Z+lAw3DKgO76g90ETOiA6rfLV1Y=
|
||||
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
|
||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
83
vendor/github.com/rancher/kine/pkg/broadcaster/broadcaster.go
generated
vendored
Normal file
83
vendor/github.com/rancher/kine/pkg/broadcaster/broadcaster.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
package broadcaster
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type ConnectFunc func() (chan interface{}, error)
|
||||
|
||||
type Broadcaster struct {
|
||||
sync.Mutex
|
||||
running bool
|
||||
subs map[chan interface{}]struct{}
|
||||
}
|
||||
|
||||
func (b *Broadcaster) Subscribe(ctx context.Context, connect ConnectFunc) (<-chan interface{}, error) {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
|
||||
if !b.running {
|
||||
if err := b.start(connect); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
sub := make(chan interface{}, 100)
|
||||
if b.subs == nil {
|
||||
b.subs = map[chan interface{}]struct{}{}
|
||||
}
|
||||
b.subs[sub] = struct{}{}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
b.unsub(sub, true)
|
||||
}()
|
||||
|
||||
return sub, nil
|
||||
}
|
||||
|
||||
func (b *Broadcaster) unsub(sub chan interface{}, lock bool) {
|
||||
if lock {
|
||||
b.Lock()
|
||||
}
|
||||
if _, ok := b.subs[sub]; ok {
|
||||
close(sub)
|
||||
delete(b.subs, sub)
|
||||
}
|
||||
if lock {
|
||||
b.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Broadcaster) start(connect ConnectFunc) error {
|
||||
c, err := connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go b.stream(c)
|
||||
b.running = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Broadcaster) stream(input chan interface{}) {
|
||||
for item := range input {
|
||||
b.Lock()
|
||||
for sub := range b.subs {
|
||||
select {
|
||||
case sub <- item:
|
||||
default:
|
||||
// Slow consumer, drop
|
||||
go b.unsub(sub, true)
|
||||
}
|
||||
}
|
||||
b.Unlock()
|
||||
}
|
||||
|
||||
b.Lock()
|
||||
for sub := range b.subs {
|
||||
b.unsub(sub, false)
|
||||
}
|
||||
b.running = false
|
||||
b.Unlock()
|
||||
}
|
107
vendor/github.com/rancher/kine/pkg/client/client.go
generated
vendored
Normal file
107
vendor/github.com/rancher/kine/pkg/client/client.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/clientv3"
|
||||
"github.com/rancher/kine/pkg/endpoint"
|
||||
)
|
||||
|
||||
type Value struct {
|
||||
Data []byte
|
||||
Modified int64
|
||||
}
|
||||
|
||||
type Client interface {
|
||||
Get(ctx context.Context, key string) (Value, error)
|
||||
Put(ctx context.Context, key string, value []byte) error
|
||||
Create(ctx context.Context, key string, value []byte) error
|
||||
Update(ctx context.Context, key string, revision int64, value []byte) error
|
||||
Close() error
|
||||
}
|
||||
|
||||
type client struct {
|
||||
c *clientv3.Client
|
||||
}
|
||||
|
||||
func New(config endpoint.ETCDConfig) (Client, error) {
|
||||
tlsConfig, err := config.TLSConfig.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := clientv3.New(clientv3.Config{
|
||||
Endpoints: config.Endpoints,
|
||||
DialTimeout: 5 * time.Second,
|
||||
TLS: tlsConfig,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &client{
|
||||
c: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *client) Get(ctx context.Context, key string) (Value, error) {
|
||||
resp, err := c.c.Get(ctx, key)
|
||||
if err != nil {
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
if len(resp.Kvs) == 1 {
|
||||
return Value{
|
||||
Data: resp.Kvs[0].Value,
|
||||
Modified: resp.Kvs[0].ModRevision,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return Value{}, nil
|
||||
}
|
||||
|
||||
func (c *client) Put(ctx context.Context, key string, value []byte) error {
|
||||
val, err := c.Get(ctx, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if val.Modified == 0 {
|
||||
return c.Create(ctx, key, value)
|
||||
}
|
||||
return c.Update(ctx, key, val.Modified, value)
|
||||
}
|
||||
|
||||
func (c *client) Create(ctx context.Context, key string, value []byte) error {
|
||||
resp, err := c.c.Txn(ctx).
|
||||
If(clientv3.Compare(clientv3.ModRevision(key), "=", 0)).
|
||||
Then(clientv3.OpPut(key, string(value))).
|
||||
Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !resp.Succeeded {
|
||||
return fmt.Errorf("key exists")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *client) Update(ctx context.Context, key string, revision int64, value []byte) error {
|
||||
resp, err := c.c.Txn(ctx).
|
||||
If(clientv3.Compare(clientv3.ModRevision(key), "=", revision)).
|
||||
Then(clientv3.OpPut(key, string(value))).
|
||||
Else(clientv3.OpGet(key)).
|
||||
Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !resp.Succeeded {
|
||||
return fmt.Errorf("revision %d doesnt match", revision)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *client) Close() error {
|
||||
return c.c.Close()
|
||||
}
|
289
vendor/github.com/rancher/kine/pkg/drivers/generic/generic.go
generated
vendored
Normal file
289
vendor/github.com/rancher/kine/pkg/drivers/generic/generic.go
generated
vendored
Normal file
@ -0,0 +1,289 @@
|
||||
package generic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
columns = "kv.id as theid, kv.name, kv.created, kv.deleted, kv.create_revision, kv.prev_revision, kv.lease, kv.value, kv.old_value"
|
||||
revSQL = `
|
||||
SELECT rkv.id
|
||||
FROM kine rkv
|
||||
ORDER BY rkv.id
|
||||
DESC LIMIT 1`
|
||||
|
||||
compactRevSQL = `
|
||||
SELECT crkv.prev_revision
|
||||
FROM kine crkv
|
||||
WHERE crkv.name = 'compact_rev_key'
|
||||
ORDER BY crkv.id DESC LIMIT 1`
|
||||
|
||||
idOfKey = `
|
||||
AND mkv.id <= ? AND mkv.id > (
|
||||
SELECT ikv.id
|
||||
FROM kine ikv
|
||||
WHERE
|
||||
ikv.name = ? AND
|
||||
ikv.id <= ?
|
||||
ORDER BY ikv.id DESC LIMIT 1)`
|
||||
|
||||
listSQL = fmt.Sprintf(`SELECT (%s), (%s), %s
|
||||
FROM kine kv
|
||||
JOIN (
|
||||
SELECT MAX(mkv.id) as id
|
||||
FROM kine mkv
|
||||
WHERE
|
||||
mkv.name LIKE ?
|
||||
%%s
|
||||
GROUP BY mkv.name) maxkv
|
||||
ON maxkv.id = kv.id
|
||||
WHERE
|
||||
(kv.deleted = 0 OR ?)
|
||||
ORDER BY kv.id ASC
|
||||
`, revSQL, compactRevSQL, columns)
|
||||
)
|
||||
|
||||
type Stripped string
|
||||
|
||||
func (s Stripped) String() string {
|
||||
str := strings.ReplaceAll(string(s), "\n", "")
|
||||
return regexp.MustCompile("[\t ]+").ReplaceAllString(str, " ")
|
||||
}
|
||||
|
||||
type Generic struct {
|
||||
LastInsertID bool
|
||||
DB *sql.DB
|
||||
GetCurrentSQL string
|
||||
GetRevisionSQL string
|
||||
RevisionSQL string
|
||||
ListRevisionStartSQL string
|
||||
GetRevisionAfterSQL string
|
||||
CountSQL string
|
||||
AfterSQL string
|
||||
DeleteSQL string
|
||||
UpdateCompactSQL string
|
||||
InsertSQL string
|
||||
InsertLastInsertIDSQL string
|
||||
}
|
||||
|
||||
func q(sql, param string, numbered bool) string {
|
||||
if param == "?" && !numbered {
|
||||
return sql
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(`\?`)
|
||||
n := 0
|
||||
return regex.ReplaceAllStringFunc(sql, func(string) string {
|
||||
if numbered {
|
||||
n++
|
||||
return param + strconv.Itoa(n)
|
||||
}
|
||||
return param
|
||||
})
|
||||
}
|
||||
|
||||
func (d *Generic) Migrate(ctx context.Context) {
|
||||
var (
|
||||
count = 0
|
||||
countKV = d.queryRow(ctx, "SELECT COUNT(*) FROM key_value")
|
||||
countKine = d.queryRow(ctx, "SELECT COUNT(*) FROM kine")
|
||||
)
|
||||
|
||||
if err := countKV.Scan(&count); err != nil || count == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if err := countKine.Scan(&count); err != nil || count != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
logrus.Infof("Migrating content from old table")
|
||||
_, err := d.execute(ctx,
|
||||
`INSERT INTO kine(deleted, create_revision, prev_revision, name, value, created, lease)
|
||||
SELECT 0, 0, 0, kv.name, kv.value, 1, CASE WHEN kv.ttl > 0 THEN 15 ELSE 0 END
|
||||
FROM key_value kv
|
||||
WHERE kv.id IN (SELECT MAX(kvd.id) FROM key_value kvd GROUP BY kvd.name)`)
|
||||
if err != nil {
|
||||
logrus.Errorf("Migration failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func Open(driverName, dataSourceName string, paramCharacter string, numbered bool) (*Generic, error) {
|
||||
db, err := sql.Open(driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Generic{
|
||||
DB: db,
|
||||
|
||||
GetRevisionSQL: q(fmt.Sprintf(`
|
||||
SELECT
|
||||
0, 0, %s
|
||||
FROM kine kv
|
||||
WHERE kv.id = ?`, columns), paramCharacter, numbered),
|
||||
|
||||
GetCurrentSQL: q(fmt.Sprintf(listSQL, ""), paramCharacter, numbered),
|
||||
ListRevisionStartSQL: q(fmt.Sprintf(listSQL, "AND mkv.id <= ?"), paramCharacter, numbered),
|
||||
GetRevisionAfterSQL: q(fmt.Sprintf(listSQL, idOfKey), paramCharacter, numbered),
|
||||
|
||||
CountSQL: q(fmt.Sprintf(`
|
||||
SELECT (%s), COUNT(c.theid)
|
||||
FROM (
|
||||
%s
|
||||
) c`, revSQL, fmt.Sprintf(listSQL, "")), paramCharacter, numbered),
|
||||
|
||||
AfterSQL: q(fmt.Sprintf(`
|
||||
SELECT (%s), (%s), %s
|
||||
FROM kine kv
|
||||
WHERE
|
||||
kv.name LIKE ? AND
|
||||
kv.id > ?
|
||||
ORDER BY kv.id ASC`, revSQL, compactRevSQL, columns), paramCharacter, numbered),
|
||||
|
||||
DeleteSQL: q(`
|
||||
DELETE FROM kine
|
||||
WHERE id = ?`, paramCharacter, numbered),
|
||||
|
||||
UpdateCompactSQL: q(`
|
||||
UPDATE kine
|
||||
SET prev_revision = ?
|
||||
WHERE name = 'compact_rev_key'`, paramCharacter, numbered),
|
||||
|
||||
InsertLastInsertIDSQL: q(`INSERT INTO kine(name, created, deleted, create_revision, prev_revision, lease, value, old_value)
|
||||
values(?, ?, ?, ?, ?, ?, ?, ?)`, paramCharacter, numbered),
|
||||
|
||||
InsertSQL: q(`INSERT INTO kine(name, created, deleted, create_revision, prev_revision, lease, value, old_value)
|
||||
values(?, ?, ?, ?, ?, ?, ?, ?) RETURNING id`, paramCharacter, numbered),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Generic) query(ctx context.Context, sql string, args ...interface{}) (*sql.Rows, error) {
|
||||
logrus.Tracef("QUERY %v : %s", args, Stripped(sql))
|
||||
return d.DB.QueryContext(ctx, sql, args...)
|
||||
}
|
||||
|
||||
func (d *Generic) queryRow(ctx context.Context, sql string, args ...interface{}) *sql.Row {
|
||||
logrus.Tracef("QUERY ROW %v : %s", args, Stripped(sql))
|
||||
return d.DB.QueryRowContext(ctx, sql, args...)
|
||||
}
|
||||
|
||||
func (d *Generic) execute(ctx context.Context, sql string, args ...interface{}) (sql.Result, error) {
|
||||
logrus.Tracef("EXEC %v : %s", args, Stripped(sql))
|
||||
return d.DB.ExecContext(ctx, sql, args...)
|
||||
}
|
||||
|
||||
func (d *Generic) GetCompactRevision(ctx context.Context) (int64, error) {
|
||||
var id int64
|
||||
row := d.queryRow(ctx, compactRevSQL)
|
||||
err := row.Scan(&id)
|
||||
if err == sql.ErrNoRows {
|
||||
return 0, nil
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
|
||||
func (d *Generic) SetCompactRevision(ctx context.Context, revision int64) error {
|
||||
result, err := d.execute(ctx, d.UpdateCompactSQL, revision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
num, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if num != 0 {
|
||||
return nil
|
||||
}
|
||||
_, err = d.Insert(ctx, "compact_rev_key", false, false, 0, revision, 0, []byte(""), nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Generic) GetRevision(ctx context.Context, revision int64) (*sql.Rows, error) {
|
||||
return d.query(ctx, d.GetRevisionSQL, revision)
|
||||
}
|
||||
|
||||
func (d *Generic) DeleteRevision(ctx context.Context, revision int64) error {
|
||||
_, err := d.execute(ctx, d.DeleteSQL, revision)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Generic) ListCurrent(ctx context.Context, prefix string, limit int64, includeDeleted bool) (*sql.Rows, error) {
|
||||
sql := d.GetCurrentSQL
|
||||
if limit > 0 {
|
||||
sql = fmt.Sprintf("%s LIMIT %d", sql, limit)
|
||||
}
|
||||
return d.query(ctx, sql, prefix, includeDeleted)
|
||||
}
|
||||
|
||||
func (d *Generic) List(ctx context.Context, prefix, startKey string, limit, revision int64, includeDeleted bool) (*sql.Rows, error) {
|
||||
if startKey == "" {
|
||||
sql := d.ListRevisionStartSQL
|
||||
if limit > 0 {
|
||||
sql = fmt.Sprintf("%s LIMIT %d", sql, limit)
|
||||
}
|
||||
return d.query(ctx, sql, prefix, revision, includeDeleted)
|
||||
}
|
||||
|
||||
sql := d.GetRevisionAfterSQL
|
||||
if limit > 0 {
|
||||
sql = fmt.Sprintf("%s LIMIT %d", sql, limit)
|
||||
}
|
||||
return d.query(ctx, sql, prefix, revision, startKey, revision, includeDeleted)
|
||||
}
|
||||
|
||||
func (d *Generic) Count(ctx context.Context, prefix string) (int64, int64, error) {
|
||||
var (
|
||||
rev sql.NullInt64
|
||||
id int64
|
||||
)
|
||||
|
||||
row := d.queryRow(ctx, d.CountSQL, prefix, false)
|
||||
err := row.Scan(&rev, &id)
|
||||
return rev.Int64, id, err
|
||||
}
|
||||
|
||||
func (d *Generic) CurrentRevision(ctx context.Context) (int64, error) {
|
||||
var id int64
|
||||
row := d.queryRow(ctx, revSQL)
|
||||
err := row.Scan(&id)
|
||||
if err == sql.ErrNoRows {
|
||||
return 0, nil
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
|
||||
func (d *Generic) After(ctx context.Context, prefix string, rev int64) (*sql.Rows, error) {
|
||||
sql := d.AfterSQL
|
||||
return d.query(ctx, sql, prefix, rev)
|
||||
}
|
||||
|
||||
func (d *Generic) Insert(ctx context.Context, key string, create, delete bool, createRevision, previousRevision int64, ttl int64, value, prevValue []byte) (id int64, err error) {
|
||||
cVal := 0
|
||||
dVal := 0
|
||||
if create {
|
||||
cVal = 1
|
||||
}
|
||||
if delete {
|
||||
dVal = 1
|
||||
}
|
||||
|
||||
if d.LastInsertID {
|
||||
row, err := d.execute(ctx, d.InsertLastInsertIDSQL, key, cVal, dVal, createRevision, previousRevision, ttl, value, prevValue)
|
||||
if err != nil {
|
||||
return 00, err
|
||||
}
|
||||
return row.LastInsertId()
|
||||
}
|
||||
|
||||
row := d.queryRow(ctx, d.InsertSQL, key, cVal, dVal, createRevision, previousRevision, ttl, value, prevValue)
|
||||
err = row.Scan(&id)
|
||||
return id, err
|
||||
}
|
160
vendor/github.com/rancher/kine/pkg/drivers/mysql/mysql.go
generated
vendored
Normal file
160
vendor/github.com/rancher/kine/pkg/drivers/mysql/mysql.go
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
cryptotls "crypto/tls"
|
||||
"database/sql"
|
||||
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/rancher/kine/pkg/drivers/generic"
|
||||
"github.com/rancher/kine/pkg/logstructured"
|
||||
"github.com/rancher/kine/pkg/logstructured/sqllog"
|
||||
"github.com/rancher/kine/pkg/server"
|
||||
"github.com/rancher/kine/pkg/tls"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultUnixDSN = "root@unix(/var/run/mysqld/mysqld.sock)/"
|
||||
defaultHostDSN = "root@tcp(127.0.0.1)/"
|
||||
)
|
||||
|
||||
var (
|
||||
schema = []string{
|
||||
`create table if not exists kine
|
||||
(
|
||||
id INTEGER AUTO_INCREMENT,
|
||||
name TEXT,
|
||||
created INTEGER,
|
||||
deleted INTEGER,
|
||||
create_revision INTEGER,
|
||||
prev_revision INTEGER,
|
||||
lease INTEGER,
|
||||
value BLOB,
|
||||
old_value BLOB,
|
||||
PRIMARY KEY (id)
|
||||
);`,
|
||||
}
|
||||
nameIdx = "create index kine_name_index on kine (name(100))"
|
||||
revisionIdx = "create index kine_name_prev_revision_uindex on kine (name(100), prev_revision)"
|
||||
createDB = "create database if not exists "
|
||||
)
|
||||
|
||||
func New(dataSourceName string, tlsInfo tls.Config) (server.Backend, error) {
|
||||
tlsConfig, err := tlsInfo.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tlsConfig != nil {
|
||||
tlsConfig.MinVersion = cryptotls.VersionTLS11
|
||||
}
|
||||
|
||||
parsedDSN, err := prepareDSN(dataSourceName, tlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := createDBIfNotExist(parsedDSN); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dialect, err := generic.Open("mysql", parsedDSN, "?", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dialect.LastInsertID = true
|
||||
if err := setup(dialect.DB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dialect.Migrate(context.Background())
|
||||
return logstructured.New(sqllog.New(dialect)), nil
|
||||
}
|
||||
|
||||
func setup(db *sql.DB) error {
|
||||
for _, stmt := range schema {
|
||||
_, err := db.Exec(stmt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// check if duplicate indexes
|
||||
indexes := []string{
|
||||
nameIdx,
|
||||
revisionIdx}
|
||||
|
||||
for _, idx := range indexes {
|
||||
err := createIndex(db, idx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDBIfNotExist(dataSourceName string) error {
|
||||
config, err := mysql.ParseDSN(dataSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dbName := config.DBName
|
||||
|
||||
db, err := sql.Open("mysql", dataSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Exec(createDB + dbName)
|
||||
if err != nil {
|
||||
if mysqlError, ok := err.(*mysql.MySQLError); !ok || mysqlError.Number != 1049 {
|
||||
return err
|
||||
}
|
||||
config.DBName = ""
|
||||
db, err = sql.Open("mysql", config.FormatDSN())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Exec(createDB + dbName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func prepareDSN(dataSourceName string, tlsConfig *cryptotls.Config) (string, error) {
|
||||
if len(dataSourceName) == 0 {
|
||||
dataSourceName = defaultUnixDSN
|
||||
if tlsConfig != nil {
|
||||
dataSourceName = defaultHostDSN
|
||||
}
|
||||
}
|
||||
config, err := mysql.ParseDSN(dataSourceName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// setting up tlsConfig
|
||||
if tlsConfig != nil {
|
||||
if err := mysql.RegisterTLSConfig("kine", tlsConfig); err != nil {
|
||||
return "", err
|
||||
}
|
||||
config.TLSConfig = "kine"
|
||||
}
|
||||
dbName := "kubernetes"
|
||||
if len(config.DBName) > 0 {
|
||||
dbName = config.DBName
|
||||
}
|
||||
config.DBName = dbName
|
||||
parsedDSN := config.FormatDSN()
|
||||
|
||||
return parsedDSN, nil
|
||||
}
|
||||
|
||||
func createIndex(db *sql.DB, indexStmt string) error {
|
||||
_, err := db.Exec(indexStmt)
|
||||
if err != nil {
|
||||
if mysqlError, ok := err.(*mysql.MySQLError); !ok || mysqlError.Number != 1061 {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,15 +1,19 @@
|
||||
package pgsql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
"github.com/ibuildthecloud/kvsql/clientv3/driver"
|
||||
"github.com/lib/pq"
|
||||
"github.com/rancher/kine/pkg/drivers/generic"
|
||||
"github.com/rancher/kine/pkg/logstructured"
|
||||
"github.com/rancher/kine/pkg/logstructured/sqllog"
|
||||
"github.com/rancher/kine/pkg/server"
|
||||
"github.com/rancher/kine/pkg/tls"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -17,82 +21,57 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
fieldList = "name, value, old_value, old_revision, create_revision, revision, ttl, version, del"
|
||||
baseList = `
|
||||
SELECT kv.id, kv.name, kv.value, kv.old_value, kv.old_revision, kv.create_revision, kv.revision, kv.ttl, kv.version, kv.del
|
||||
FROM key_value kv
|
||||
INNER JOIN
|
||||
(
|
||||
SELECT MAX(revision) revision, kvi.name
|
||||
FROM key_value kvi
|
||||
%REV%
|
||||
GROUP BY kvi.name
|
||||
) AS r
|
||||
ON r.name = kv.name AND r.revision = kv.revision
|
||||
WHERE kv.name like ? %RES% ORDER BY kv.name ASC limit ?
|
||||
`
|
||||
insertSQL = `
|
||||
INSERT INTO key_value(` + fieldList + `)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
|
||||
schema = []string{
|
||||
`create table if not exists key_value
|
||||
`create table if not exists kine
|
||||
(
|
||||
name TEXT,
|
||||
value TEXT,
|
||||
create_revision INTEGER,
|
||||
revision INTEGER,
|
||||
ttl INTEGER,
|
||||
version INTEGER,
|
||||
del INTEGER,
|
||||
old_value TEXT,
|
||||
id SERIAL PRIMARY KEY,
|
||||
old_revision INTEGER
|
||||
name TEXT,
|
||||
created INTEGER,
|
||||
deleted INTEGER,
|
||||
create_revision INTEGER,
|
||||
prev_revision INTEGER,
|
||||
lease INTEGER,
|
||||
value bytea,
|
||||
old_value bytea
|
||||
);`,
|
||||
`create index if not exists name_idx on key_value (name)`,
|
||||
`create index if not exists revision_idx on key_value (revision)`,
|
||||
`CREATE INDEX IF NOT EXISTS kine_name_index ON kine (name)`,
|
||||
`CREATE UNIQUE INDEX IF NOT EXISTS kine_name_prev_revision_uindex ON kine (name, prev_revision)`,
|
||||
}
|
||||
createDB = "create database "
|
||||
)
|
||||
|
||||
func NewPGSQL() *driver.Generic {
|
||||
return &driver.Generic{
|
||||
CleanupSQL: q("DELETE FROM key_value WHERE ttl > 0 AND ttl < ?"),
|
||||
GetSQL: q("SELECT id, " + fieldList + " FROM key_value WHERE name=? ORDER BY revision DESC limit ?"),
|
||||
ListSQL: q(strings.Replace(strings.Replace(baseList, "%REV%", "", -1), "%RES%", "", -1)),
|
||||
ListRevisionSQL: q(strings.Replace(strings.Replace(baseList, "%REV%", "WHERE kvi.revision>=?", -1), "%RES%", "", -1)),
|
||||
ListResumeSQL: q(strings.Replace(strings.Replace(baseList, "%REV%", "WHERE kvi.revision<=?", -1),
|
||||
"%RES%", "and kv.name > ? ", -1)),
|
||||
InsertSQL: q(insertSQL),
|
||||
ReplaySQL: q("SELECT id, " + fieldList + " FROM key_value WHERE name like ? and revision>=? ORDER BY revision ASC"),
|
||||
GetRevisionSQL: q("SELECT MAX(revision) FROM key_value"),
|
||||
ToDeleteSQL: q("SELECT count(*), name, max(revision) FROM key_value GROUP BY name,del HAVING count(*) > 1 or (count(*)=1 and del=1)"),
|
||||
DeleteOldSQL: q("DELETE FROM key_value WHERE name=? AND (revision<? OR (revision=? AND del=1))"),
|
||||
}
|
||||
}
|
||||
|
||||
func Open(dataSourceName string, tlsInfo *transport.TLSInfo) (*sql.DB, error) {
|
||||
func New(dataSourceName string, tlsInfo tls.Config) (server.Backend, error) {
|
||||
parsedDSN, err := prepareDSN(dataSourceName, tlsInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// get database name
|
||||
|
||||
if err := createDBIfNotExist(parsedDSN); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db, err := sql.Open("postgres", parsedDSN)
|
||||
|
||||
dialect, err := generic.Open("postgres", parsedDSN, "$", true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := setup(dialect.DB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dialect.Migrate(context.Background())
|
||||
return logstructured.New(sqllog.New(dialect)), nil
|
||||
}
|
||||
|
||||
func setup(db *sql.DB) error {
|
||||
for _, stmt := range schema {
|
||||
_, err := db.Exec(stmt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return db, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDBIfNotExist(dataSourceName string) error {
|
||||
@ -100,11 +79,14 @@ func createDBIfNotExist(dataSourceName string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dbName := strings.SplitN(u.Path, "/", 2)[1]
|
||||
db, err := sql.Open("postgres", dataSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
err = db.Ping()
|
||||
// check if database already exists
|
||||
if _, ok := err.(*pq.Error); !ok {
|
||||
@ -120,6 +102,7 @@ func createDBIfNotExist(dataSourceName string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
_, err = db.Exec(createDB + dbName + ";")
|
||||
if err != nil {
|
||||
return err
|
||||
@ -138,7 +121,7 @@ func q(sql string) string {
|
||||
})
|
||||
}
|
||||
|
||||
func prepareDSN(dataSourceName string, tlsInfo *transport.TLSInfo) (string, error) {
|
||||
func prepareDSN(dataSourceName string, tlsInfo tls.Config) (string, error) {
|
||||
if len(dataSourceName) == 0 {
|
||||
dataSourceName = defaultDSN
|
||||
} else {
|
||||
@ -158,7 +141,7 @@ func prepareDSN(dataSourceName string, tlsInfo *transport.TLSInfo) (string, erro
|
||||
}
|
||||
// set up tls dsn
|
||||
params := url.Values{}
|
||||
sslmode := "require"
|
||||
sslmode := ""
|
||||
if _, ok := queryMap["sslcert"]; tlsInfo.CertFile != "" && !ok {
|
||||
params.Add("sslcert", tlsInfo.CertFile)
|
||||
sslmode = "verify-full"
|
||||
@ -171,7 +154,7 @@ func prepareDSN(dataSourceName string, tlsInfo *transport.TLSInfo) (string, erro
|
||||
params.Add("sslrootcert", tlsInfo.CAFile)
|
||||
sslmode = "verify-full"
|
||||
}
|
||||
if _, ok := queryMap["sslmode"]; !ok {
|
||||
if _, ok := queryMap["sslmode"]; !ok && sslmode != "" {
|
||||
params.Add("sslmode", sslmode)
|
||||
}
|
||||
for k, v := range queryMap {
|
67
vendor/github.com/rancher/kine/pkg/drivers/sqlite/sqlite.go
generated
vendored
Normal file
67
vendor/github.com/rancher/kine/pkg/drivers/sqlite/sqlite.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"os"
|
||||
|
||||
"github.com/rancher/kine/pkg/drivers/generic"
|
||||
"github.com/rancher/kine/pkg/logstructured"
|
||||
"github.com/rancher/kine/pkg/logstructured/sqllog"
|
||||
"github.com/rancher/kine/pkg/server"
|
||||
|
||||
// sqlite db driver
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
var (
|
||||
schema = []string{
|
||||
`CREATE TABLE IF NOT EXISTS kine
|
||||
(
|
||||
id INTEGER primary key autoincrement,
|
||||
name INTEGER,
|
||||
created INTEGER,
|
||||
deleted INTEGER,
|
||||
create_revision INTEGER,
|
||||
prev_revision INTEGER,
|
||||
lease INTEGER,
|
||||
value BLOB,
|
||||
old_value BLOB
|
||||
)`,
|
||||
`CREATE INDEX IF NOT EXISTS kine_name_index ON kine (name)`,
|
||||
`CREATE UNIQUE INDEX IF NOT EXISTS kine_name_prev_revision_uindex ON kine (name, prev_revision)`,
|
||||
}
|
||||
)
|
||||
|
||||
func New(dataSourceName string) (server.Backend, error) {
|
||||
if dataSourceName == "" {
|
||||
if err := os.MkdirAll("./db", 0700); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dataSourceName = "./db/state.db?_journal=WAL&cache=shared"
|
||||
}
|
||||
|
||||
dialect, err := generic.Open("sqlite3", dataSourceName, "?", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dialect.LastInsertID = true
|
||||
|
||||
if err := setup(dialect.DB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dialect.Migrate(context.Background())
|
||||
return logstructured.New(sqllog.New(dialect)), nil
|
||||
}
|
||||
|
||||
func setup(db *sql.DB) error {
|
||||
for _, stmt := range schema {
|
||||
_, err := db.Exec(stmt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
155
vendor/github.com/rancher/kine/pkg/endpoint/endpoint.go
generated
vendored
Normal file
155
vendor/github.com/rancher/kine/pkg/endpoint/endpoint.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
package endpoint
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/kine/pkg/drivers/mysql"
|
||||
"github.com/rancher/kine/pkg/drivers/pgsql"
|
||||
"github.com/rancher/kine/pkg/drivers/sqlite"
|
||||
"github.com/rancher/kine/pkg/server"
|
||||
"github.com/rancher/kine/pkg/tls"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const (
|
||||
KineSocket = "unix://kine.sock"
|
||||
SQLiteBackend = "sqlite"
|
||||
ETCDBackend = "etcd3"
|
||||
MySQLBackend = "mysql"
|
||||
PostgresBackend = "postgres"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
GRPCServer *grpc.Server
|
||||
Listener string
|
||||
Endpoint string
|
||||
|
||||
tls.Config
|
||||
}
|
||||
|
||||
type ETCDConfig struct {
|
||||
Endpoints []string
|
||||
TLSConfig tls.Config
|
||||
LeaderElect bool
|
||||
}
|
||||
|
||||
func Listen(ctx context.Context, config Config) (ETCDConfig, error) {
|
||||
driver, dsn := ParseStorageEndpoint(config.Endpoint)
|
||||
if driver == ETCDBackend {
|
||||
return ETCDConfig{
|
||||
Endpoints: strings.Split(config.Endpoint, ","),
|
||||
TLSConfig: config.Config,
|
||||
LeaderElect: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
leaderelect, backend, err := getKineStorageBackend(driver, dsn, config)
|
||||
if err != nil {
|
||||
return ETCDConfig{}, err
|
||||
}
|
||||
|
||||
if err := backend.Start(ctx); err != nil {
|
||||
return ETCDConfig{}, err
|
||||
}
|
||||
|
||||
listen := config.Listener
|
||||
if listen == "" {
|
||||
listen = KineSocket
|
||||
}
|
||||
|
||||
b := server.New(backend)
|
||||
grpcServer := grpcServer(config)
|
||||
b.Register(grpcServer)
|
||||
|
||||
listener, err := createListener(listen)
|
||||
if err != nil {
|
||||
return ETCDConfig{}, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := grpcServer.Serve(listener); err != nil {
|
||||
logrus.Errorf("Kine server shutdown: %v", err)
|
||||
}
|
||||
<-ctx.Done()
|
||||
grpcServer.Stop()
|
||||
listener.Close()
|
||||
}()
|
||||
|
||||
return ETCDConfig{
|
||||
LeaderElect: leaderelect,
|
||||
Endpoints: []string{listen},
|
||||
TLSConfig: tls.Config{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func createListener(listen string) (ret net.Listener, rerr error) {
|
||||
network, address := networkAndAddress(listen)
|
||||
|
||||
if network == "unix" {
|
||||
if err := os.Remove(address); err != nil && !os.IsNotExist(err) {
|
||||
logrus.Warnf("failed to remove socket %s: %v", address, err)
|
||||
}
|
||||
defer func() {
|
||||
if err := os.Chmod(address, 0600); err != nil {
|
||||
rerr = err
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
logrus.Infof("Kine listening on %s://%s", network, address)
|
||||
return net.Listen(network, address)
|
||||
}
|
||||
|
||||
func grpcServer(config Config) *grpc.Server {
|
||||
if config.GRPCServer != nil {
|
||||
return config.GRPCServer
|
||||
}
|
||||
return grpc.NewServer()
|
||||
}
|
||||
|
||||
func getKineStorageBackend(driver, dsn string, cfg Config) (bool, server.Backend, error) {
|
||||
var (
|
||||
backend server.Backend
|
||||
leaderElect = true
|
||||
err error
|
||||
)
|
||||
switch driver {
|
||||
case SQLiteBackend:
|
||||
leaderElect = false
|
||||
backend, err = sqlite.New(dsn)
|
||||
case PostgresBackend:
|
||||
backend, err = pgsql.New(dsn, cfg.Config)
|
||||
case MySQLBackend:
|
||||
backend, err = mysql.New(dsn, cfg.Config)
|
||||
default:
|
||||
return false, nil, fmt.Errorf("storage backend is not defined")
|
||||
}
|
||||
|
||||
return leaderElect, backend, err
|
||||
}
|
||||
|
||||
func ParseStorageEndpoint(storageEndpoint string) (string, string) {
|
||||
network, address := networkAndAddress(storageEndpoint)
|
||||
switch network {
|
||||
case "":
|
||||
return SQLiteBackend, ""
|
||||
case "http":
|
||||
fallthrough
|
||||
case "https":
|
||||
return ETCDBackend, address
|
||||
}
|
||||
return network, address
|
||||
}
|
||||
|
||||
func networkAndAddress(str string) (string, string) {
|
||||
parts := strings.SplitN(str, "://", 2)
|
||||
if len(parts) > 1 {
|
||||
return parts[0], parts[1]
|
||||
}
|
||||
return "", parts[0]
|
||||
}
|
284
vendor/github.com/rancher/kine/pkg/logstructured/logstructured.go
generated
vendored
Normal file
284
vendor/github.com/rancher/kine/pkg/logstructured/logstructured.go
generated
vendored
Normal file
@ -0,0 +1,284 @@
|
||||
package logstructured
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/kine/pkg/server"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Log interface {
|
||||
Start(ctx context.Context) error
|
||||
CurrentRevision(ctx context.Context) (int64, error)
|
||||
List(ctx context.Context, prefix, startKey string, limit, revision int64, includeDeletes bool) (int64, []*server.Event, error)
|
||||
After(ctx context.Context, prefix string, revision int64) (int64, []*server.Event, error)
|
||||
Watch(ctx context.Context, prefix string) <-chan []*server.Event
|
||||
Count(ctx context.Context, prefix string) (int64, int64, error)
|
||||
Append(ctx context.Context, event *server.Event) (int64, error)
|
||||
}
|
||||
|
||||
type LogStructured struct {
|
||||
log Log
|
||||
}
|
||||
|
||||
func New(log Log) *LogStructured {
|
||||
return &LogStructured{
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LogStructured) Start(ctx context.Context) error {
|
||||
if err := l.log.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
l.Create(ctx, "/registry/health", []byte(`{"health":"true"}`), 0)
|
||||
go l.ttl(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *LogStructured) Get(ctx context.Context, key string, revision int64) (revRet int64, kvRet *server.KeyValue, errRet error) {
|
||||
defer func() {
|
||||
l.adjustRevision(ctx, &revRet)
|
||||
logrus.Debugf("GET %s, rev=%d => rev=%d, kv=%v, err=%v", key, revision, revRet, kvRet != nil, errRet)
|
||||
}()
|
||||
|
||||
rev, event, err := l.get(ctx, key, revision, false)
|
||||
if event == nil {
|
||||
return rev, nil, err
|
||||
}
|
||||
return rev, event.KV, err
|
||||
}
|
||||
|
||||
func (l *LogStructured) get(ctx context.Context, key string, revision int64, includeDeletes bool) (int64, *server.Event, error) {
|
||||
rev, events, err := l.log.List(ctx, key, "", 1, revision, includeDeletes)
|
||||
if err == server.ErrCompacted {
|
||||
// ignore compacted when getting by revision
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if revision != 0 {
|
||||
rev = revision
|
||||
}
|
||||
if len(events) == 0 {
|
||||
return rev, nil, nil
|
||||
}
|
||||
return rev, events[0], nil
|
||||
}
|
||||
|
||||
func (l *LogStructured) adjustRevision(ctx context.Context, rev *int64) {
|
||||
if *rev != 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if newRev, err := l.log.CurrentRevision(ctx); err == nil {
|
||||
*rev = newRev
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LogStructured) Create(ctx context.Context, key string, value []byte, lease int64) (revRet int64, errRet error) {
|
||||
defer func() {
|
||||
l.adjustRevision(ctx, &revRet)
|
||||
logrus.Debugf("CREATE %s, size=%d, lease=%d => rev=%d, err=%v", key, len(value), lease, revRet, errRet)
|
||||
}()
|
||||
|
||||
rev, prevEvent, err := l.get(ctx, key, 0, true)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
createEvent := &server.Event{
|
||||
Create: true,
|
||||
KV: &server.KeyValue{
|
||||
Key: key,
|
||||
Value: value,
|
||||
Lease: lease,
|
||||
},
|
||||
PrevKV: &server.KeyValue{
|
||||
ModRevision: rev,
|
||||
},
|
||||
}
|
||||
if prevEvent != nil {
|
||||
if !prevEvent.Delete {
|
||||
return 0, server.ErrKeyExists
|
||||
}
|
||||
createEvent.PrevKV = prevEvent.KV
|
||||
}
|
||||
|
||||
return l.log.Append(ctx, createEvent)
|
||||
}
|
||||
|
||||
func (l *LogStructured) Delete(ctx context.Context, key string, revision int64) (revRet int64, kvRet *server.KeyValue, deletedRet bool, errRet error) {
|
||||
defer func() {
|
||||
l.adjustRevision(ctx, &revRet)
|
||||
logrus.Debugf("DELETE %s, rev=%d => rev=%d, kv=%v, deleted=%v, err=%v", key, revision, revRet, kvRet != nil, deletedRet, errRet)
|
||||
}()
|
||||
|
||||
rev, event, err := l.get(ctx, key, 0, true)
|
||||
if err != nil {
|
||||
return 0, nil, false, err
|
||||
}
|
||||
|
||||
if event == nil {
|
||||
return rev, nil, true, nil
|
||||
}
|
||||
|
||||
if event.Delete {
|
||||
return rev, event.KV, true, nil
|
||||
}
|
||||
|
||||
if revision != 0 && event.KV.ModRevision != revision {
|
||||
return rev, event.KV, false, nil
|
||||
}
|
||||
|
||||
deleteEvent := &server.Event{
|
||||
Delete: true,
|
||||
KV: event.KV,
|
||||
PrevKV: event.KV,
|
||||
}
|
||||
|
||||
rev, err = l.log.Append(ctx, deleteEvent)
|
||||
return rev, event.KV, true, err
|
||||
}
|
||||
|
||||
func (l *LogStructured) List(ctx context.Context, prefix, startKey string, limit, revision int64) (revRet int64, kvRet []*server.KeyValue, errRet error) {
|
||||
defer func() {
|
||||
l.adjustRevision(ctx, &revRet)
|
||||
logrus.Debugf("LIST %s, start=%s, limit=%d, rev=%d => rev=%d, kvs=%d, err=%v", prefix, startKey, limit, revision, revRet, len(kvRet), errRet)
|
||||
}()
|
||||
|
||||
rev, events, err := l.log.List(ctx, prefix, startKey, limit, revision, false)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if revision != 0 {
|
||||
rev = revision
|
||||
}
|
||||
|
||||
kvs := make([]*server.KeyValue, 0, len(events))
|
||||
for _, event := range events {
|
||||
kvs = append(kvs, event.KV)
|
||||
}
|
||||
return rev, kvs, nil
|
||||
}
|
||||
|
||||
func (l *LogStructured) Count(ctx context.Context, prefix string) (revRet int64, count int64, err error) {
|
||||
defer func() {
|
||||
l.adjustRevision(ctx, &revRet)
|
||||
logrus.Debugf("COUNT %s => rev=%d, count=%d, err=%v", prefix, revRet, count, err)
|
||||
}()
|
||||
return l.log.Count(ctx, prefix)
|
||||
}
|
||||
|
||||
func (l *LogStructured) Update(ctx context.Context, key string, value []byte, revision, lease int64) (revRet int64, kvRet *server.KeyValue, updateRet bool, errRet error) {
|
||||
defer func() {
|
||||
l.adjustRevision(ctx, &revRet)
|
||||
logrus.Debugf("UPDATE %s, value=%d, rev=%d, lease=%v => rev=%d, kv=%v, updated=%v, err=%v", key, len(value), revision, lease, revRet, kvRet != nil, updateRet, errRet)
|
||||
}()
|
||||
|
||||
rev, event, err := l.get(ctx, key, revision, false)
|
||||
if err != nil {
|
||||
return 0, nil, false, err
|
||||
}
|
||||
|
||||
if event == nil {
|
||||
return 0, nil, false, nil
|
||||
}
|
||||
|
||||
if event.KV.ModRevision != revision {
|
||||
return rev, event.KV, false, nil
|
||||
}
|
||||
|
||||
updateEvent := &server.Event{
|
||||
KV: &server.KeyValue{
|
||||
Key: key,
|
||||
CreateRevision: event.KV.CreateRevision,
|
||||
Value: value,
|
||||
Lease: lease,
|
||||
},
|
||||
PrevKV: event.KV,
|
||||
}
|
||||
|
||||
rev, err = l.log.Append(ctx, updateEvent)
|
||||
if err != nil {
|
||||
rev, event, err := l.get(ctx, key, 0, false)
|
||||
if event == nil {
|
||||
return rev, nil, false, err
|
||||
}
|
||||
return rev, event.KV, false, err
|
||||
}
|
||||
|
||||
updateEvent.KV.ModRevision = rev
|
||||
return rev, updateEvent.KV, true, err
|
||||
}
|
||||
|
||||
func (l *LogStructured) ttl(ctx context.Context) {
|
||||
// very naive TTL support
|
||||
for events := range l.log.Watch(ctx, "/") {
|
||||
for _, event := range events {
|
||||
if event.KV.Lease <= 0 {
|
||||
continue
|
||||
}
|
||||
go func(event *server.Event) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(time.Duration(event.KV.Lease) * time.Second):
|
||||
}
|
||||
l.Delete(ctx, event.KV.Key, event.KV.ModRevision)
|
||||
}(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LogStructured) Watch(ctx context.Context, prefix string, revision int64) <-chan []*server.Event {
|
||||
logrus.Debugf("WATCH %s, revision=%d", prefix, revision)
|
||||
|
||||
// starting watching right away so we don't miss anything
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
readChan := l.log.Watch(ctx, prefix)
|
||||
|
||||
// include the current revision in list
|
||||
if revision > 0 {
|
||||
revision -= 1
|
||||
}
|
||||
|
||||
result := make(chan []*server.Event)
|
||||
|
||||
rev, kvs, err := l.log.After(ctx, prefix, revision)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to list %s for revision %d", prefix, revision)
|
||||
cancel()
|
||||
}
|
||||
|
||||
logrus.Debugf("WATCH LIST key=%s rev=%d => rev=%d kvs=%d", prefix, revision, rev, len(kvs))
|
||||
|
||||
go func() {
|
||||
lastRevision := revision
|
||||
if len(kvs) > 0 {
|
||||
lastRevision = rev
|
||||
}
|
||||
|
||||
if len(kvs) > 0 {
|
||||
result <- kvs
|
||||
}
|
||||
|
||||
// always ensure we fully read the channel
|
||||
for i := range readChan {
|
||||
result <- filter(i, lastRevision)
|
||||
}
|
||||
close(result)
|
||||
cancel()
|
||||
}()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func filter(events []*server.Event, rev int64) []*server.Event {
|
||||
for len(events) > 0 && events[0].KV.ModRevision <= rev {
|
||||
events = events[1:]
|
||||
}
|
||||
|
||||
return events
|
||||
}
|
377
vendor/github.com/rancher/kine/pkg/logstructured/sqllog/sql.go
generated
vendored
Normal file
377
vendor/github.com/rancher/kine/pkg/logstructured/sqllog/sql.go
generated
vendored
Normal file
@ -0,0 +1,377 @@
|
||||
package sqllog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/kine/pkg/broadcaster"
|
||||
"github.com/rancher/kine/pkg/server"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type SQLLog struct {
|
||||
d Dialect
|
||||
broadcaster broadcaster.Broadcaster
|
||||
ctx context.Context
|
||||
notify chan int64
|
||||
}
|
||||
|
||||
func New(d Dialect) *SQLLog {
|
||||
l := &SQLLog{
|
||||
d: d,
|
||||
notify: make(chan int64, 1024),
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
type Dialect interface {
|
||||
ListCurrent(ctx context.Context, prefix string, limit int64, includeDeleted bool) (*sql.Rows, error)
|
||||
List(ctx context.Context, prefix, startKey string, limit, revision int64, includeDeleted bool) (*sql.Rows, error)
|
||||
Count(ctx context.Context, prefix string) (int64, int64, error)
|
||||
CurrentRevision(ctx context.Context) (int64, error)
|
||||
After(ctx context.Context, prefix string, rev int64) (*sql.Rows, error)
|
||||
Insert(ctx context.Context, key string, create, delete bool, createRevision, previousRevision int64, ttl int64, value, prevValue []byte) (int64, error)
|
||||
GetRevision(ctx context.Context, revision int64) (*sql.Rows, error)
|
||||
DeleteRevision(ctx context.Context, revision int64) error
|
||||
GetCompactRevision(ctx context.Context) (int64, error)
|
||||
SetCompactRevision(ctx context.Context, revision int64) error
|
||||
}
|
||||
|
||||
func (s *SQLLog) Start(ctx context.Context) error {
|
||||
s.ctx = ctx
|
||||
go s.compact()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SQLLog) compact() {
|
||||
t := time.NewTicker(2 * time.Second)
|
||||
|
||||
outer:
|
||||
for {
|
||||
select {
|
||||
case <-s.ctx.Done():
|
||||
return
|
||||
case <-t.C:
|
||||
}
|
||||
|
||||
end, err := s.d.CurrentRevision(s.ctx)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to get current revision: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
cursor, err := s.d.GetCompactRevision(s.ctx)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to get compact revision: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if end-cursor < 100 {
|
||||
// Only run if we have at least 100 rows to process
|
||||
continue
|
||||
}
|
||||
|
||||
savedCursor := cursor
|
||||
// Purposefully start at the current and redo the current as
|
||||
// it could have failed before actually compacting
|
||||
for ; cursor <= end; cursor++ {
|
||||
rows, err := s.d.GetRevision(s.ctx, cursor)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to get revision %d: %v", cursor, err)
|
||||
continue outer
|
||||
}
|
||||
|
||||
_, _, events, err := RowsToEvents(rows)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to convert to events: %v", err)
|
||||
continue outer
|
||||
}
|
||||
|
||||
if len(events) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
event := events[0]
|
||||
|
||||
if event.KV.Key == "compact_rev_key" {
|
||||
// don't compact the compact key
|
||||
continue
|
||||
}
|
||||
|
||||
setRev := false
|
||||
if event.PrevKV != nil && event.PrevKV.ModRevision != 0 {
|
||||
if savedCursor != cursor {
|
||||
if err := s.d.SetCompactRevision(s.ctx, cursor); err != nil {
|
||||
logrus.Errorf("failed to record compact revision: %v", err)
|
||||
continue outer
|
||||
}
|
||||
savedCursor = cursor
|
||||
setRev = true
|
||||
}
|
||||
|
||||
if err := s.d.DeleteRevision(s.ctx, event.PrevKV.ModRevision); err != nil {
|
||||
logrus.Errorf("failed to delete revision %d: %v", event.PrevKV.ModRevision, err)
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
|
||||
if event.Delete {
|
||||
if !setRev && savedCursor != cursor {
|
||||
if err := s.d.SetCompactRevision(s.ctx, cursor); err != nil {
|
||||
logrus.Errorf("failed to record compact revision: %v", err)
|
||||
continue outer
|
||||
}
|
||||
savedCursor = cursor
|
||||
}
|
||||
|
||||
if err := s.d.DeleteRevision(s.ctx, cursor); err != nil {
|
||||
logrus.Errorf("failed to delete current revision %d: %v", cursor, err)
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if savedCursor != cursor {
|
||||
if err := s.d.SetCompactRevision(s.ctx, cursor); err != nil {
|
||||
logrus.Errorf("failed to record compact revision: %v", err)
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SQLLog) CurrentRevision(ctx context.Context) (int64, error) {
|
||||
return s.d.CurrentRevision(ctx)
|
||||
}
|
||||
|
||||
func (s *SQLLog) After(ctx context.Context, prefix string, revision int64) (int64, []*server.Event, error) {
|
||||
if strings.HasSuffix(prefix, "/") {
|
||||
prefix += "%"
|
||||
}
|
||||
|
||||
rows, err := s.d.After(ctx, prefix, revision)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
rev, _, result, err := RowsToEvents(rows)
|
||||
return rev, result, err
|
||||
}
|
||||
|
||||
func (s *SQLLog) List(ctx context.Context, prefix, startKey string, limit, revision int64, includeDeleted bool) (int64, []*server.Event, error) {
|
||||
var (
|
||||
rows *sql.Rows
|
||||
err error
|
||||
)
|
||||
|
||||
if strings.HasSuffix(prefix, "/") {
|
||||
prefix += "%"
|
||||
}
|
||||
|
||||
if revision == 0 {
|
||||
rows, err = s.d.ListCurrent(ctx, prefix, limit, includeDeleted)
|
||||
} else {
|
||||
rows, err = s.d.List(ctx, prefix, startKey, limit, revision, includeDeleted)
|
||||
}
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
rev, compact, result, err := RowsToEvents(rows)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
if revision > 0 && len(result) == 0 {
|
||||
// a zero length result won't have the compact revision so get it manually
|
||||
compact, err = s.d.GetCompactRevision(ctx)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if revision > 0 && revision < compact {
|
||||
return rev, result, server.ErrCompacted
|
||||
}
|
||||
|
||||
select {
|
||||
case s.notify <- rev:
|
||||
default:
|
||||
}
|
||||
|
||||
return rev, result, err
|
||||
}
|
||||
|
||||
func RowsToEvents(rows *sql.Rows) (int64, int64, []*server.Event, error) {
|
||||
var (
|
||||
result []*server.Event
|
||||
rev int64
|
||||
compact int64
|
||||
)
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
event := &server.Event{}
|
||||
if err := scan(rows, &rev, &compact, event); err != nil {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
result = append(result, event)
|
||||
}
|
||||
|
||||
return rev, compact, result, nil
|
||||
}
|
||||
|
||||
func (s *SQLLog) Watch(ctx context.Context, prefix string) <-chan []*server.Event {
|
||||
res := make(chan []*server.Event)
|
||||
values, err := s.broadcaster.Subscribe(ctx, s.startWatch)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
checkPrefix := strings.HasSuffix(prefix, "/")
|
||||
|
||||
go func() {
|
||||
defer close(res)
|
||||
for i := range values {
|
||||
events, ok := filter(i, checkPrefix, prefix)
|
||||
if ok {
|
||||
res <- events
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func filter(events interface{}, checkPrefix bool, prefix string) ([]*server.Event, bool) {
|
||||
eventList := events.([]*server.Event)
|
||||
filteredEventList := make([]*server.Event, 0, len(eventList))
|
||||
|
||||
for _, event := range eventList {
|
||||
if (checkPrefix && strings.HasPrefix(event.KV.Key, prefix)) || event.KV.Key == prefix {
|
||||
filteredEventList = append(filteredEventList, event)
|
||||
}
|
||||
}
|
||||
|
||||
return filteredEventList, len(filteredEventList) > 0
|
||||
}
|
||||
|
||||
func (s *SQLLog) startWatch() (chan interface{}, error) {
|
||||
c := make(chan interface{})
|
||||
go s.poll(c)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (s *SQLLog) poll(result chan interface{}) {
|
||||
var (
|
||||
last int64
|
||||
)
|
||||
|
||||
wait := time.NewTicker(120 * time.Second)
|
||||
defer wait.Stop()
|
||||
defer close(result)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.ctx.Done():
|
||||
return
|
||||
case check := <-s.notify:
|
||||
if check <= last {
|
||||
continue
|
||||
}
|
||||
case <-wait.C:
|
||||
}
|
||||
|
||||
rows, err := s.d.After(s.ctx, "%", last)
|
||||
if err != nil {
|
||||
logrus.Errorf("fail to list latest changes: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
rev, _, events, err := RowsToEvents(rows)
|
||||
if err != nil {
|
||||
logrus.Errorf("fail to convert rows changes: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(events) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, event := range events {
|
||||
logrus.Debugf("TRIGGERED %s, revision=%d, delete=%v", event.KV.Key, event.KV.ModRevision, event.Delete)
|
||||
}
|
||||
|
||||
result <- events
|
||||
last = rev
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SQLLog) Count(ctx context.Context, prefix string) (int64, int64, error) {
|
||||
if strings.HasSuffix(prefix, "/") {
|
||||
prefix += "%"
|
||||
}
|
||||
return s.d.Count(ctx, prefix)
|
||||
}
|
||||
|
||||
func (s *SQLLog) Append(ctx context.Context, event *server.Event) (int64, error) {
|
||||
e := *event
|
||||
if e.KV == nil {
|
||||
e.KV = &server.KeyValue{}
|
||||
}
|
||||
if e.PrevKV == nil {
|
||||
e.PrevKV = &server.KeyValue{}
|
||||
}
|
||||
|
||||
rev, err := s.d.Insert(ctx, e.KV.Key,
|
||||
e.Create,
|
||||
e.Delete,
|
||||
e.KV.CreateRevision,
|
||||
e.PrevKV.ModRevision,
|
||||
e.KV.Lease,
|
||||
e.KV.Value,
|
||||
e.PrevKV.Value,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
select {
|
||||
case s.notify <- rev:
|
||||
default:
|
||||
}
|
||||
return rev, nil
|
||||
}
|
||||
|
||||
func scan(rows *sql.Rows, rev *int64, compact *int64, event *server.Event) error {
|
||||
event.KV = &server.KeyValue{}
|
||||
event.PrevKV = &server.KeyValue{}
|
||||
|
||||
c := &sql.NullInt64{}
|
||||
|
||||
err := rows.Scan(
|
||||
rev,
|
||||
c,
|
||||
&event.KV.ModRevision,
|
||||
&event.KV.Key,
|
||||
&event.Create,
|
||||
&event.Delete,
|
||||
&event.KV.CreateRevision,
|
||||
&event.PrevKV.ModRevision,
|
||||
&event.KV.Lease,
|
||||
&event.KV.Value,
|
||||
&event.PrevKV.Value,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if event.Create {
|
||||
event.KV.CreateRevision = event.KV.ModRevision
|
||||
event.PrevKV = nil
|
||||
}
|
||||
|
||||
*compact = c.Int64
|
||||
return nil
|
||||
}
|
34
vendor/github.com/rancher/kine/pkg/server/compact.go
generated
vendored
Normal file
34
vendor/github.com/rancher/kine/pkg/server/compact.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
)
|
||||
|
||||
func isCompact(txn *etcdserverpb.TxnRequest) bool {
|
||||
return len(txn.Compare) == 1 &&
|
||||
txn.Compare[0].Target == etcdserverpb.Compare_VERSION &&
|
||||
txn.Compare[0].Result == etcdserverpb.Compare_EQUAL &&
|
||||
len(txn.Success) == 1 &&
|
||||
txn.Success[0].GetRequestPut() != nil &&
|
||||
len(txn.Failure) == 1 &&
|
||||
txn.Failure[0].GetRequestRange() != nil &&
|
||||
string(txn.Compare[0].Key) == "compact_rev_key"
|
||||
}
|
||||
|
||||
func (l *LimitedServer) compact(ctx context.Context) (*etcdserverpb.TxnResponse, error) {
|
||||
return &etcdserverpb.TxnResponse{
|
||||
Header: &etcdserverpb.ResponseHeader{},
|
||||
Succeeded: true,
|
||||
Responses: []*etcdserverpb.ResponseOp{
|
||||
{
|
||||
Response: &etcdserverpb.ResponseOp_ResponsePut{
|
||||
ResponsePut: &etcdserverpb.PutResponse{
|
||||
Header: &etcdserverpb.ResponseHeader{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
54
vendor/github.com/rancher/kine/pkg/server/create.go
generated
vendored
Normal file
54
vendor/github.com/rancher/kine/pkg/server/create.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
)
|
||||
|
||||
func isCreate(txn *etcdserverpb.TxnRequest) *etcdserverpb.PutRequest {
|
||||
if len(txn.Compare) == 1 &&
|
||||
txn.Compare[0].Target == etcdserverpb.Compare_MOD &&
|
||||
txn.Compare[0].Result == etcdserverpb.Compare_EQUAL &&
|
||||
txn.Compare[0].GetModRevision() == 0 &&
|
||||
len(txn.Failure) == 0 &&
|
||||
len(txn.Success) == 1 &&
|
||||
txn.Success[0].GetRequestPut() != nil {
|
||||
return txn.Success[0].GetRequestPut()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *LimitedServer) create(ctx context.Context, put *etcdserverpb.PutRequest, txn *etcdserverpb.TxnRequest) (*etcdserverpb.TxnResponse, error) {
|
||||
if put.IgnoreLease {
|
||||
return nil, unsupported("ignoreLease")
|
||||
} else if put.IgnoreValue {
|
||||
return nil, unsupported("ignoreValue")
|
||||
} else if put.PrevKv {
|
||||
return nil, unsupported("prevKv")
|
||||
}
|
||||
|
||||
rev, err := l.backend.Create(ctx, string(put.Key), put.Value, put.Lease)
|
||||
if err == ErrKeyExists {
|
||||
return &etcdserverpb.TxnResponse{
|
||||
Header: txnHeader(rev),
|
||||
Succeeded: false,
|
||||
}, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &etcdserverpb.TxnResponse{
|
||||
Header: txnHeader(rev),
|
||||
Responses: []*etcdserverpb.ResponseOp{
|
||||
{
|
||||
Response: &etcdserverpb.ResponseOp_ResponsePut{
|
||||
ResponsePut: &etcdserverpb.PutResponse{
|
||||
Header: txnHeader(rev),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Succeeded: true,
|
||||
}, nil
|
||||
}
|
50
vendor/github.com/rancher/kine/pkg/server/delete.go
generated
vendored
Normal file
50
vendor/github.com/rancher/kine/pkg/server/delete.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
)
|
||||
|
||||
func isDelete(txn *etcdserverpb.TxnRequest) (int64, string, bool) {
|
||||
if len(txn.Compare) == 0 &&
|
||||
len(txn.Failure) == 0 &&
|
||||
len(txn.Success) == 2 &&
|
||||
txn.Success[0].GetRequestRange() != nil &&
|
||||
txn.Success[1].GetRequestDeleteRange() != nil {
|
||||
rng := txn.Success[1].GetRequestDeleteRange()
|
||||
return 0, string(rng.Key), true
|
||||
}
|
||||
if len(txn.Compare) == 1 &&
|
||||
txn.Compare[0].Target == etcdserverpb.Compare_MOD &&
|
||||
txn.Compare[0].Result == etcdserverpb.Compare_EQUAL &&
|
||||
len(txn.Failure) == 1 &&
|
||||
txn.Failure[0].GetRequestRange() != nil &&
|
||||
len(txn.Success) == 1 &&
|
||||
txn.Success[0].GetRequestDeleteRange() != nil {
|
||||
return txn.Compare[0].GetModRevision(), string(txn.Success[0].GetRequestDeleteRange().Key), true
|
||||
}
|
||||
return 0, "", false
|
||||
}
|
||||
|
||||
func (l *LimitedServer) delete(ctx context.Context, key string, revision int64) (*etcdserverpb.TxnResponse, error) {
|
||||
rev, kv, ok, err := l.backend.Delete(ctx, key, revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &etcdserverpb.TxnResponse{
|
||||
Header: txnHeader(rev),
|
||||
Responses: []*etcdserverpb.ResponseOp{
|
||||
{
|
||||
Response: &etcdserverpb.ResponseOp_ResponseRange{
|
||||
ResponseRange: &etcdserverpb.RangeResponse{
|
||||
Header: txnHeader(rev),
|
||||
Kvs: toKVs(kv),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Succeeded: ok,
|
||||
}, nil
|
||||
}
|
27
vendor/github.com/rancher/kine/pkg/server/get.go
generated
vendored
Normal file
27
vendor/github.com/rancher/kine/pkg/server/get.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
)
|
||||
|
||||
func (l *LimitedServer) get(ctx context.Context, r *etcdserverpb.RangeRequest) (*RangeResponse, error) {
|
||||
if r.Limit != 0 {
|
||||
return nil, fmt.Errorf("invalid combination of rangeEnd and limit, limit should be 0 got %d", r.Limit)
|
||||
}
|
||||
|
||||
rev, kv, err := l.backend.Get(ctx, string(r.Key), r.Revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := &RangeResponse{
|
||||
Header: txnHeader(rev),
|
||||
}
|
||||
if kv != nil {
|
||||
resp.Kvs = []*KeyValue{kv}
|
||||
}
|
||||
return resp, nil
|
||||
}
|
32
vendor/github.com/rancher/kine/pkg/server/lease.go
generated
vendored
Normal file
32
vendor/github.com/rancher/kine/pkg/server/lease.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
)
|
||||
|
||||
func (s *KVServerBridge) LeaseGrant(ctx context.Context, req *etcdserverpb.LeaseGrantRequest) (*etcdserverpb.LeaseGrantResponse, error) {
|
||||
return &etcdserverpb.LeaseGrantResponse{
|
||||
Header: &etcdserverpb.ResponseHeader{},
|
||||
ID: req.TTL,
|
||||
TTL: req.TTL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *KVServerBridge) LeaseRevoke(context.Context, *etcdserverpb.LeaseRevokeRequest) (*etcdserverpb.LeaseRevokeResponse, error) {
|
||||
return nil, fmt.Errorf("lease revoke is not supported")
|
||||
}
|
||||
|
||||
func (s *KVServerBridge) LeaseKeepAlive(etcdserverpb.Lease_LeaseKeepAliveServer) error {
|
||||
return fmt.Errorf("lease keep alive is not supported")
|
||||
}
|
||||
|
||||
func (s *KVServerBridge) LeaseTimeToLive(context.Context, *etcdserverpb.LeaseTimeToLiveRequest) (*etcdserverpb.LeaseTimeToLiveResponse, error) {
|
||||
return nil, fmt.Errorf("lease time to live is not supported")
|
||||
}
|
||||
|
||||
func (s *KVServerBridge) LeaseLeases(context.Context, *etcdserverpb.LeaseLeasesRequest) (*etcdserverpb.LeaseLeasesResponse, error) {
|
||||
return nil, fmt.Errorf("lease leases is not supported")
|
||||
}
|
52
vendor/github.com/rancher/kine/pkg/server/limited.go
generated
vendored
Normal file
52
vendor/github.com/rancher/kine/pkg/server/limited.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
)
|
||||
|
||||
type LimitedServer struct {
|
||||
backend Backend
|
||||
}
|
||||
|
||||
func (l *LimitedServer) Range(ctx context.Context, r *etcdserverpb.RangeRequest) (*RangeResponse, error) {
|
||||
if len(r.RangeEnd) == 0 {
|
||||
return l.get(ctx, r)
|
||||
}
|
||||
return l.list(ctx, r)
|
||||
}
|
||||
|
||||
func txnHeader(rev int64) *etcdserverpb.ResponseHeader {
|
||||
return &etcdserverpb.ResponseHeader{
|
||||
Revision: rev,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LimitedServer) Txn(ctx context.Context, txn *etcdserverpb.TxnRequest) (*etcdserverpb.TxnResponse, error) {
|
||||
if put := isCreate(txn); put != nil {
|
||||
return l.create(ctx, put, txn)
|
||||
}
|
||||
if rev, key, ok := isDelete(txn); ok {
|
||||
return l.delete(ctx, key, rev)
|
||||
}
|
||||
if rev, key, value, lease, ok := isUpdate(txn); ok {
|
||||
return l.update(ctx, rev, key, value, lease)
|
||||
}
|
||||
if isCompact(txn) {
|
||||
return l.compact(ctx)
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported transaction: %v", txn)
|
||||
}
|
||||
|
||||
type ResponseHeader struct {
|
||||
Revision int64
|
||||
}
|
||||
|
||||
type RangeResponse struct {
|
||||
Header *etcdserverpb.ResponseHeader
|
||||
Kvs []*KeyValue
|
||||
More bool
|
||||
Count int64
|
||||
}
|
56
vendor/github.com/rancher/kine/pkg/server/list.go
generated
vendored
Normal file
56
vendor/github.com/rancher/kine/pkg/server/list.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
)
|
||||
|
||||
func (l *LimitedServer) list(ctx context.Context, r *etcdserverpb.RangeRequest) (*RangeResponse, error) {
|
||||
if len(r.RangeEnd) == 0 {
|
||||
return nil, fmt.Errorf("invalid range end length of 0")
|
||||
}
|
||||
|
||||
prefix := string(append(r.RangeEnd[:len(r.RangeEnd)-1], r.RangeEnd[len(r.RangeEnd)-1]-1))
|
||||
if !strings.HasSuffix(prefix, "/") {
|
||||
prefix = prefix + "/"
|
||||
}
|
||||
start := string(bytes.TrimRight(r.Key, "\x00"))
|
||||
|
||||
if r.CountOnly {
|
||||
rev, count, err := l.backend.Count(ctx, prefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RangeResponse{
|
||||
Header: txnHeader(rev),
|
||||
Count: count,
|
||||
}, nil
|
||||
}
|
||||
|
||||
limit := r.Limit
|
||||
if limit > 0 {
|
||||
limit++
|
||||
}
|
||||
|
||||
rev, kvs, err := l.backend.List(ctx, prefix, start, limit, r.Revision)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := &RangeResponse{
|
||||
Header: txnHeader(rev),
|
||||
Count: int64(len(kvs)),
|
||||
Kvs: kvs,
|
||||
}
|
||||
|
||||
if limit > 0 && resp.Count > limit {
|
||||
resp.More = true
|
||||
resp.Kvs = kvs[0 : limit-1]
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
155
vendor/github.com/rancher/kine/pkg/server/server.go
generated
vendored
Normal file
155
vendor/github.com/rancher/kine/pkg/server/server.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/mvcc/mvccpb"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/health"
|
||||
healthpb "google.golang.org/grpc/health/grpc_health_v1"
|
||||
)
|
||||
|
||||
var (
|
||||
_ etcdserverpb.KVServer = (*KVServerBridge)(nil)
|
||||
_ etcdserverpb.WatchServer = (*KVServerBridge)(nil)
|
||||
)
|
||||
|
||||
type KVServerBridge struct {
|
||||
limited *LimitedServer
|
||||
}
|
||||
|
||||
func New(backend Backend) *KVServerBridge {
|
||||
return &KVServerBridge{
|
||||
limited: &LimitedServer{
|
||||
backend: backend,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (k *KVServerBridge) Register(server *grpc.Server) {
|
||||
etcdserverpb.RegisterLeaseServer(server, k)
|
||||
etcdserverpb.RegisterWatchServer(server, k)
|
||||
etcdserverpb.RegisterKVServer(server, k)
|
||||
|
||||
hsrv := health.NewServer()
|
||||
hsrv.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
|
||||
healthpb.RegisterHealthServer(server, hsrv)
|
||||
}
|
||||
|
||||
func (k *KVServerBridge) Range(ctx context.Context, r *etcdserverpb.RangeRequest) (*etcdserverpb.RangeResponse, error) {
|
||||
if r.KeysOnly {
|
||||
return nil, unsupported("keysOnly")
|
||||
}
|
||||
|
||||
if r.MaxCreateRevision != 0 {
|
||||
return nil, unsupported("maxCreateRevision")
|
||||
}
|
||||
|
||||
if r.SortOrder != 0 {
|
||||
return nil, unsupported("sortOrder")
|
||||
}
|
||||
|
||||
if r.SortTarget != 0 {
|
||||
return nil, unsupported("sortTarget")
|
||||
}
|
||||
|
||||
if r.Serializable {
|
||||
return nil, unsupported("serializable")
|
||||
}
|
||||
|
||||
if r.KeysOnly {
|
||||
return nil, unsupported("keysOnly")
|
||||
}
|
||||
|
||||
if r.MinModRevision != 0 {
|
||||
return nil, unsupported("minModRevision")
|
||||
}
|
||||
|
||||
if r.MinCreateRevision != 0 {
|
||||
return nil, unsupported("minCreateRevision")
|
||||
}
|
||||
|
||||
if r.MaxCreateRevision != 0 {
|
||||
return nil, unsupported("maxCreateRevision")
|
||||
}
|
||||
|
||||
if r.MaxModRevision != 0 {
|
||||
return nil, unsupported("maxModRevision")
|
||||
}
|
||||
|
||||
resp, err := k.limited.Range(ctx, r)
|
||||
if err != nil {
|
||||
logrus.Errorf("error while range on %s %s: %v", r.Key, r.RangeEnd, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rangeResponse := &etcdserverpb.RangeResponse{
|
||||
More: resp.More,
|
||||
Count: resp.Count,
|
||||
Header: resp.Header,
|
||||
Kvs: toKVs(resp.Kvs...),
|
||||
}
|
||||
|
||||
return rangeResponse, nil
|
||||
}
|
||||
|
||||
func toKVs(kvs ...*KeyValue) []*mvccpb.KeyValue {
|
||||
if len(kvs) == 0 || kvs[0] == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ret := make([]*mvccpb.KeyValue, 0, len(kvs))
|
||||
for _, kv := range kvs {
|
||||
newKV := toKV(kv)
|
||||
if newKV == nil {
|
||||
fmt.Println("HIHIHIH")
|
||||
} else {
|
||||
ret = append(ret, toKV(kv))
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func toKV(kv *KeyValue) *mvccpb.KeyValue {
|
||||
if kv == nil {
|
||||
return nil
|
||||
}
|
||||
return &mvccpb.KeyValue{
|
||||
Key: []byte(kv.Key),
|
||||
Value: kv.Value,
|
||||
Lease: kv.Lease,
|
||||
CreateRevision: kv.CreateRevision,
|
||||
ModRevision: kv.ModRevision,
|
||||
}
|
||||
}
|
||||
|
||||
func (k *KVServerBridge) Put(ctx context.Context, r *etcdserverpb.PutRequest) (*etcdserverpb.PutResponse, error) {
|
||||
return nil, fmt.Errorf("put is not supported")
|
||||
}
|
||||
|
||||
func (k *KVServerBridge) DeleteRange(ctx context.Context, r *etcdserverpb.DeleteRangeRequest) (*etcdserverpb.DeleteRangeResponse, error) {
|
||||
return nil, fmt.Errorf("delete is not supported")
|
||||
}
|
||||
|
||||
func (k *KVServerBridge) Txn(ctx context.Context, r *etcdserverpb.TxnRequest) (*etcdserverpb.TxnResponse, error) {
|
||||
res, err := k.limited.Txn(ctx, r)
|
||||
if err != nil {
|
||||
logrus.Errorf("error in txn: %v", err)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (k *KVServerBridge) Compact(ctx context.Context, r *etcdserverpb.CompactionRequest) (*etcdserverpb.CompactionResponse, error) {
|
||||
return &etcdserverpb.CompactionResponse{
|
||||
Header: &etcdserverpb.ResponseHeader{
|
||||
Revision: r.Revision,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func unsupported(field string) error {
|
||||
return fmt.Errorf("%s is unsupported", field)
|
||||
}
|
38
vendor/github.com/rancher/kine/pkg/server/types.go
generated
vendored
Normal file
38
vendor/github.com/rancher/kine/pkg/server/types.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrKeyExists = errors.New("key exists")
|
||||
ErrCompacted = errors.New("revision has been compact")
|
||||
)
|
||||
|
||||
type Backend interface {
|
||||
Start(ctx context.Context) error
|
||||
Get(ctx context.Context, key string, revision int64) (int64, *KeyValue, error)
|
||||
Create(ctx context.Context, key string, value []byte, lease int64) (int64, error)
|
||||
Delete(ctx context.Context, key string, revision int64) (int64, *KeyValue, bool, error)
|
||||
List(ctx context.Context, prefix, startKey string, limit, revision int64) (int64, []*KeyValue, error)
|
||||
Count(ctx context.Context, prefix string) (int64, int64, error)
|
||||
Update(ctx context.Context, key string, value []byte, revision, lease int64) (int64, *KeyValue, bool, error)
|
||||
Watch(ctx context.Context, key string, revision int64) <-chan []*Event
|
||||
}
|
||||
|
||||
type KeyValue struct {
|
||||
Key string
|
||||
CreateRevision int64
|
||||
ModRevision int64
|
||||
Value []byte
|
||||
Lease int64
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Delete bool
|
||||
Create bool
|
||||
KV *KeyValue
|
||||
PrevKV *KeyValue
|
||||
}
|
72
vendor/github.com/rancher/kine/pkg/server/update.go
generated
vendored
Normal file
72
vendor/github.com/rancher/kine/pkg/server/update.go
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
)
|
||||
|
||||
func isUpdate(txn *etcdserverpb.TxnRequest) (int64, string, []byte, int64, bool) {
|
||||
if len(txn.Compare) == 1 &&
|
||||
txn.Compare[0].Target == etcdserverpb.Compare_MOD &&
|
||||
txn.Compare[0].Result == etcdserverpb.Compare_EQUAL &&
|
||||
len(txn.Success) == 1 &&
|
||||
txn.Success[0].GetRequestPut() != nil &&
|
||||
len(txn.Failure) == 1 &&
|
||||
txn.Failure[0].GetRequestRange() != nil {
|
||||
return txn.Compare[0].GetModRevision(),
|
||||
string(txn.Compare[0].Key),
|
||||
txn.Success[0].GetRequestPut().Value,
|
||||
txn.Success[0].GetRequestPut().Lease,
|
||||
true
|
||||
}
|
||||
return 0, "", nil, 0, false
|
||||
}
|
||||
|
||||
func (l *LimitedServer) update(ctx context.Context, rev int64, key string, value []byte, lease int64) (*etcdserverpb.TxnResponse, error) {
|
||||
var (
|
||||
kv *KeyValue
|
||||
ok bool
|
||||
err error
|
||||
)
|
||||
|
||||
if rev == 0 {
|
||||
rev, err = l.backend.Create(ctx, key, value, lease)
|
||||
ok = true
|
||||
} else {
|
||||
rev, kv, ok, err = l.backend.Update(ctx, key, value, rev, lease)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := &etcdserverpb.TxnResponse{
|
||||
Header: txnHeader(rev),
|
||||
Succeeded: ok,
|
||||
}
|
||||
|
||||
if ok {
|
||||
resp.Responses = []*etcdserverpb.ResponseOp{
|
||||
{
|
||||
Response: &etcdserverpb.ResponseOp_ResponsePut{
|
||||
ResponsePut: &etcdserverpb.PutResponse{
|
||||
Header: txnHeader(rev),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
resp.Responses = []*etcdserverpb.ResponseOp{
|
||||
{
|
||||
Response: &etcdserverpb.ResponseOp_ResponseRange{
|
||||
ResponseRange: &etcdserverpb.RangeResponse{
|
||||
Header: txnHeader(rev),
|
||||
Kvs: toKVs(kv),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
143
vendor/github.com/rancher/kine/pkg/server/watch.go
generated
vendored
Normal file
143
vendor/github.com/rancher/kine/pkg/server/watch.go
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||
"github.com/coreos/etcd/mvcc/mvccpb"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
watchID int64
|
||||
)
|
||||
|
||||
func (s *KVServerBridge) Watch(ws etcdserverpb.Watch_WatchServer) error {
|
||||
w := watcher{
|
||||
server: ws,
|
||||
backend: s.limited.backend,
|
||||
watches: map[int64]func(){},
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
for {
|
||||
msg, err := ws.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if msg.GetCreateRequest() != nil {
|
||||
w.Start(msg.GetCreateRequest())
|
||||
} else if msg.GetCancelRequest() != nil {
|
||||
w.Cancel(msg.GetCancelRequest().WatchId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type watcher struct {
|
||||
sync.Mutex
|
||||
|
||||
wg sync.WaitGroup
|
||||
backend Backend
|
||||
server etcdserverpb.Watch_WatchServer
|
||||
watches map[int64]func()
|
||||
}
|
||||
|
||||
func (w *watcher) Start(r *etcdserverpb.WatchCreateRequest) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
id := atomic.AddInt64(&watchID, 1)
|
||||
w.watches[id] = cancel
|
||||
w.wg.Add(1)
|
||||
|
||||
key := string(r.Key)
|
||||
|
||||
logrus.Debugf("WATCH START id=%d, key=%s, revision=%d", id, key, r.StartRevision)
|
||||
|
||||
go func() {
|
||||
defer w.wg.Done()
|
||||
if err := w.server.Send(&etcdserverpb.WatchResponse{
|
||||
Header: &etcdserverpb.ResponseHeader{},
|
||||
Created: true,
|
||||
WatchId: id,
|
||||
}); err != nil {
|
||||
w.Cancel(id)
|
||||
return
|
||||
}
|
||||
|
||||
for events := range w.backend.Watch(ctx, key, r.StartRevision) {
|
||||
if len(events) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if logrus.IsLevelEnabled(logrus.DebugLevel) {
|
||||
for _, event := range events {
|
||||
logrus.Debugf("WATCH READ id=%d, key=%s, revision=%d", id, event.KV.Key, event.KV.ModRevision)
|
||||
}
|
||||
}
|
||||
|
||||
if err := w.server.Send(&etcdserverpb.WatchResponse{
|
||||
Header: txnHeader(events[len(events)-1].KV.ModRevision),
|
||||
WatchId: id,
|
||||
Events: toEvents(events...),
|
||||
}); err != nil {
|
||||
w.Cancel(id)
|
||||
return
|
||||
}
|
||||
}
|
||||
logrus.Debugf("WATCH CLOSE id=%d, key=%s", id, key)
|
||||
}()
|
||||
}
|
||||
|
||||
func toEvents(events ...*Event) []*mvccpb.Event {
|
||||
ret := make([]*mvccpb.Event, 0, len(events))
|
||||
for _, e := range events {
|
||||
ret = append(ret, toEvent(e))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func toEvent(event *Event) *mvccpb.Event {
|
||||
e := &mvccpb.Event{
|
||||
Kv: toKV(event.KV),
|
||||
PrevKv: toKV(event.PrevKV),
|
||||
}
|
||||
if event.Delete {
|
||||
e.Type = mvccpb.DELETE
|
||||
} else {
|
||||
e.Type = mvccpb.PUT
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func (w *watcher) Cancel(watchID int64) {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
if cancel, ok := w.watches[watchID]; ok {
|
||||
cancel()
|
||||
delete(w.watches, watchID)
|
||||
}
|
||||
err := w.server.Send(&etcdserverpb.WatchResponse{
|
||||
Header: &etcdserverpb.ResponseHeader{},
|
||||
Canceled: true,
|
||||
WatchId: watchID,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Errorf("Failed to send cancel response for watchID %d: %v", watchID, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *watcher) Close() {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
for _, v := range w.watches {
|
||||
v()
|
||||
}
|
||||
w.wg.Wait()
|
||||
}
|
31
vendor/github.com/rancher/kine/pkg/tls/config.go
generated
vendored
Normal file
31
vendor/github.com/rancher/kine/pkg/tls/config.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
package tls
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
|
||||
"github.com/coreos/etcd/pkg/transport"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
CAFile string
|
||||
CertFile string
|
||||
KeyFile string
|
||||
}
|
||||
|
||||
func (c Config) ClientConfig() (*tls.Config, error) {
|
||||
if c.CertFile == "" && c.KeyFile == "" && c.CAFile == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
info := &transport.TLSInfo{
|
||||
CertFile: c.CertFile,
|
||||
KeyFile: c.KeyFile,
|
||||
CAFile: c.CAFile,
|
||||
}
|
||||
tlsConfig, err := info.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tlsConfig, nil
|
||||
}
|
1
vendor/github.com/sirupsen/logrus/.gitignore
generated
vendored
1
vendor/github.com/sirupsen/logrus/.gitignore
generated
vendored
@ -1 +1,2 @@
|
||||
logrus
|
||||
vendor
|
||||
|
26
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
26
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
@ -1,15 +1,21 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- tip
|
||||
go_import_path: github.com/sirupsen/logrus
|
||||
git:
|
||||
depth: 1
|
||||
env:
|
||||
- GOMAXPROCS=4 GORACE=halt_on_error=1
|
||||
- GO111MODULE=on
|
||||
- GO111MODULE=off
|
||||
go: [ 1.10.x, 1.11.x, 1.12.x ]
|
||||
os: [ linux, osx, windows ]
|
||||
matrix:
|
||||
exclude:
|
||||
- env: GO111MODULE=on
|
||||
go: 1.10.x
|
||||
install:
|
||||
- go get github.com/stretchr/testify/assert
|
||||
- go get gopkg.in/gemnasium/logrus-airbrake-hook.v2
|
||||
- go get golang.org/x/sys/unix
|
||||
- go get golang.org/x/sys/windows
|
||||
- if [[ "$GO111MODULE" == "on" ]]; then go mod download; fi
|
||||
- if [[ "$GO111MODULE" == "off" ]]; then go get github.com/stretchr/testify/assert golang.org/x/sys/unix github.com/konsorten/go-windows-terminal-sequences; fi
|
||||
script:
|
||||
- export GOMAXPROCS=4
|
||||
- export GORACE=halt_on_error=1
|
||||
- go test -race -v ./...
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then go test -race -v -tags appengine ./... ; fi
|
||||
|
85
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
85
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
@ -1,3 +1,88 @@
|
||||
# 1.4.1
|
||||
This new release introduces:
|
||||
* Enhance TextFormatter to not print caller information when they are empty (#944)
|
||||
* Remove dependency on golang.org/x/crypto (#932, #943)
|
||||
|
||||
Fixes:
|
||||
* Fix Entry.WithContext method to return a copy of the initial entry (#941)
|
||||
|
||||
# 1.4.0
|
||||
This new release introduces:
|
||||
* Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848).
|
||||
* Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter (#909, #911)
|
||||
* Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919).
|
||||
|
||||
Fixes:
|
||||
* Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893).
|
||||
* Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903)
|
||||
* Fix infinite recursion on unknown `Level.String()` (#907)
|
||||
* Fix race condition in `getCaller` (#916).
|
||||
|
||||
|
||||
# 1.3.0
|
||||
This new release introduces:
|
||||
* Log, Logf, Logln functions for Logger and Entry that take a Level
|
||||
|
||||
Fixes:
|
||||
* Building prometheus node_exporter on AIX (#840)
|
||||
* Race condition in TextFormatter (#468)
|
||||
* Travis CI import path (#868)
|
||||
* Remove coloured output on Windows (#862)
|
||||
* Pointer to func as field in JSONFormatter (#870)
|
||||
* Properly marshal Levels (#873)
|
||||
|
||||
# 1.2.0
|
||||
This new release introduces:
|
||||
* A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued
|
||||
* A new trace level named `Trace` whose level is below `Debug`
|
||||
* A configurable exit function to be called upon a Fatal trace
|
||||
* The `Level` object now implements `encoding.TextUnmarshaler` interface
|
||||
|
||||
# 1.1.1
|
||||
This is a bug fix release.
|
||||
* fix the build break on Solaris
|
||||
* don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized
|
||||
|
||||
# 1.1.0
|
||||
This new release introduces:
|
||||
* several fixes:
|
||||
* a fix for a race condition on entry formatting
|
||||
* proper cleanup of previously used entries before putting them back in the pool
|
||||
* the extra new line at the end of message in text formatter has been removed
|
||||
* a new global public API to check if a level is activated: IsLevelEnabled
|
||||
* the following methods have been added to the Logger object
|
||||
* IsLevelEnabled
|
||||
* SetFormatter
|
||||
* SetOutput
|
||||
* ReplaceHooks
|
||||
* introduction of go module
|
||||
* an indent configuration for the json formatter
|
||||
* output colour support for windows
|
||||
* the field sort function is now configurable for text formatter
|
||||
* the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater
|
||||
|
||||
# 1.0.6
|
||||
|
||||
This new release introduces:
|
||||
* a new api WithTime which allows to easily force the time of the log entry
|
||||
which is mostly useful for logger wrapper
|
||||
* a fix reverting the immutability of the entry given as parameter to the hooks
|
||||
a new configuration field of the json formatter in order to put all the fields
|
||||
in a nested dictionnary
|
||||
* a new SetOutput method in the Logger
|
||||
* a new configuration of the textformatter to configure the name of the default keys
|
||||
* a new configuration of the text formatter to disable the level truncation
|
||||
|
||||
# 1.0.5
|
||||
|
||||
* Fix hooks race (#707)
|
||||
* Fix panic deadlock (#695)
|
||||
|
||||
# 1.0.4
|
||||
|
||||
* Fix race when adding hooks (#612)
|
||||
* Fix terminal check in AppEngine (#635)
|
||||
|
||||
# 1.0.3
|
||||
|
||||
* Replace example files with testable examples
|
||||
|
96
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
96
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
@ -56,8 +56,39 @@ time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased
|
||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
|
||||
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
|
||||
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
|
||||
exit status 1
|
||||
```
|
||||
To ensure this behaviour even if a TTY is attached, set your formatter as follows:
|
||||
|
||||
```go
|
||||
log.SetFormatter(&log.TextFormatter{
|
||||
DisableColors: true,
|
||||
FullTimestamp: true,
|
||||
})
|
||||
```
|
||||
|
||||
#### Logging Method Name
|
||||
|
||||
If you wish to add the calling method as a field, instruct the logger via:
|
||||
```go
|
||||
log.SetReportCaller(true)
|
||||
```
|
||||
This adds the caller as 'method' like so:
|
||||
|
||||
```json
|
||||
{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by",
|
||||
"time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
|
||||
```
|
||||
|
||||
```text
|
||||
time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin
|
||||
```
|
||||
Note that this does add measurable overhead - the cost will depend on the version of Go, but is
|
||||
between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your
|
||||
environment via benchmarks:
|
||||
```
|
||||
go test -bench=.*CallerTracing
|
||||
```
|
||||
|
||||
|
||||
#### Case-sensitivity
|
||||
|
||||
@ -220,7 +251,7 @@ Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
|
||||
```go
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
|
||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
|
||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||
"log/syslog"
|
||||
)
|
||||
@ -241,60 +272,15 @@ func init() {
|
||||
```
|
||||
Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
|
||||
|
||||
| Hook | Description |
|
||||
| ----- | ----------- |
|
||||
| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
|
||||
| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. |
|
||||
| [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) |
|
||||
| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) |
|
||||
| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
|
||||
| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic |
|
||||
| [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) |
|
||||
| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch|
|
||||
| [Firehose](https://github.com/beaubrewer/logrus_firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/)
|
||||
| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
|
||||
| [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) |
|
||||
| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) |
|
||||
| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
|
||||
| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger |
|
||||
| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb |
|
||||
| [Influxus](http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB](http://influxdata.com/) |
|
||||
| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
|
||||
| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka |
|
||||
| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem |
|
||||
| [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) |
|
||||
| [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) |
|
||||
| [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) |
|
||||
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
||||
| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
|
||||
| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
|
||||
| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) |
|
||||
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
||||
| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
|
||||
| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
|
||||
| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. |
|
||||
| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) |
|
||||
| [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) |
|
||||
| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) |
|
||||
| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) |
|
||||
| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar |
|
||||
| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)|
|
||||
| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. |
|
||||
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
||||
| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
|
||||
| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
|
||||
| [Syslog](https://github.com/sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
||||
| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
|
||||
| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
|
||||
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
|
||||
| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash |
|
||||
| [SQS-Hook](https://github.com/tsarpaul/logrus_sqs) | Hook for logging to [Amazon Simple Queue Service (SQS)](https://aws.amazon.com/sqs/) |
|
||||
A list of currently known of service hook can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
|
||||
|
||||
|
||||
#### Level logging
|
||||
|
||||
Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
|
||||
Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic.
|
||||
|
||||
```go
|
||||
log.Trace("Something very low level.")
|
||||
log.Debug("Useful debugging information.")
|
||||
log.Info("Something noteworthy happened!")
|
||||
log.Warn("You should probably take a look at this.")
|
||||
@ -366,16 +352,20 @@ The built-in logging formatters are:
|
||||
field to `true`. To force no colored output even if there is a TTY set the
|
||||
`DisableColors` field to `true`. For Windows, see
|
||||
[github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
|
||||
* When colors are enabled, levels are truncated to 4 characters by default. To disable
|
||||
truncation set the `DisableLevelTruncation` field to `true`.
|
||||
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
|
||||
* `logrus.JSONFormatter`. Logs fields as JSON.
|
||||
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
|
||||
|
||||
Third party logging formatters:
|
||||
|
||||
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can by parsed by Kubernetes and Google Container Engine.
|
||||
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine.
|
||||
* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html).
|
||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
||||
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
|
||||
|
||||
You can define your formatter by implementing the `Formatter` interface,
|
||||
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
|
||||
@ -489,7 +479,7 @@ logrus.RegisterExitHandler(handler)
|
||||
|
||||
#### Thread safety
|
||||
|
||||
By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs.
|
||||
By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs.
|
||||
If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
|
||||
|
||||
Situation when locking is not needed includes:
|
||||
|
18
vendor/github.com/sirupsen/logrus/alt_exit.go
generated
vendored
18
vendor/github.com/sirupsen/logrus/alt_exit.go
generated
vendored
@ -51,9 +51,9 @@ func Exit(code int) {
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
|
||||
// all handlers. The handlers will also be invoked when any Fatal log entry is
|
||||
// made.
|
||||
// RegisterExitHandler appends a Logrus Exit handler to the list of handlers,
|
||||
// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
|
||||
// any Fatal log entry is made.
|
||||
//
|
||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||
// message but also needs to gracefully shutdown. An example usecase could be
|
||||
@ -62,3 +62,15 @@ func Exit(code int) {
|
||||
func RegisterExitHandler(handler func()) {
|
||||
handlers = append(handlers, handler)
|
||||
}
|
||||
|
||||
// DeferExitHandler prepends a Logrus Exit handler to the list of handlers,
|
||||
// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
|
||||
// any Fatal log entry is made.
|
||||
//
|
||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||
// message but also needs to gracefully shutdown. An example usecase could be
|
||||
// closing database connections, or sending a alert that the application is
|
||||
// closing.
|
||||
func DeferExitHandler(handler func()) {
|
||||
handlers = append([]func(){handler}, handlers...)
|
||||
}
|
||||
|
305
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
305
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
@ -2,13 +2,33 @@ package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var bufferPool *sync.Pool
|
||||
var (
|
||||
bufferPool *sync.Pool
|
||||
|
||||
// qualified package name, cached at first use
|
||||
logrusPackage string
|
||||
|
||||
// Positions in the call stack when tracing to report the calling method
|
||||
minimumCallerDepth int
|
||||
|
||||
// Used for caller information initialisation
|
||||
callerInitOnce sync.Once
|
||||
)
|
||||
|
||||
const (
|
||||
maximumCallerDepth int = 25
|
||||
knownLogrusFrames int = 4
|
||||
)
|
||||
|
||||
func init() {
|
||||
bufferPool = &sync.Pool{
|
||||
@ -16,15 +36,18 @@ func init() {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
|
||||
// start at the bottom of the stack before the package-name cache is primed
|
||||
minimumCallerDepth = 1
|
||||
}
|
||||
|
||||
// Defines the key when adding errors using WithError.
|
||||
var ErrorKey = "error"
|
||||
|
||||
// An entry is the final or intermediate Logrus logging entry. It contains all
|
||||
// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
|
||||
// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
|
||||
// passed around as much as you wish to avoid field duplication.
|
||||
// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
|
||||
// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
|
||||
// reused and passed around as much as you wish to avoid field duplication.
|
||||
type Entry struct {
|
||||
Logger *Logger
|
||||
|
||||
@ -34,22 +57,31 @@ type Entry struct {
|
||||
// Time at which the log entry was created
|
||||
Time time.Time
|
||||
|
||||
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
||||
// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
|
||||
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
|
||||
Level Level
|
||||
|
||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||
// Calling method, with package name
|
||||
Caller *runtime.Frame
|
||||
|
||||
// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
|
||||
Message string
|
||||
|
||||
// When formatter is called in entry.log(), an Buffer may be set to entry
|
||||
// When formatter is called in entry.log(), a Buffer may be set to entry
|
||||
Buffer *bytes.Buffer
|
||||
|
||||
// Contains the context set by the user. Useful for hook processing etc.
|
||||
Context context.Context
|
||||
|
||||
// err may contain a field formatting error
|
||||
err string
|
||||
}
|
||||
|
||||
func NewEntry(logger *Logger) *Entry {
|
||||
return &Entry{
|
||||
Logger: logger,
|
||||
// Default is three fields, give a little extra room
|
||||
Data: make(Fields, 5),
|
||||
// Default is three fields, plus one optional. Give a little extra room.
|
||||
Data: make(Fields, 6),
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +101,11 @@ func (entry *Entry) WithError(err error) *Entry {
|
||||
return entry.WithField(ErrorKey, err)
|
||||
}
|
||||
|
||||
// Add a context to the Entry.
|
||||
func (entry *Entry) WithContext(ctx context.Context) *Entry {
|
||||
return &Entry{Logger: entry.Logger, Data: entry.Data, Time: entry.Time, err: entry.err, Context: ctx}
|
||||
}
|
||||
|
||||
// Add a single field to the Entry.
|
||||
func (entry *Entry) WithField(key string, value interface{}) *Entry {
|
||||
return entry.WithFields(Fields{key: value})
|
||||
@ -80,43 +117,120 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
fieldErr := entry.err
|
||||
for k, v := range fields {
|
||||
data[k] = v
|
||||
isErrField := false
|
||||
if t := reflect.TypeOf(v); t != nil {
|
||||
switch t.Kind() {
|
||||
case reflect.Func:
|
||||
isErrField = true
|
||||
case reflect.Ptr:
|
||||
isErrField = t.Elem().Kind() == reflect.Func
|
||||
}
|
||||
}
|
||||
if isErrField {
|
||||
tmp := fmt.Sprintf("can not add field %q", k)
|
||||
if fieldErr != "" {
|
||||
fieldErr = entry.err + ", " + tmp
|
||||
} else {
|
||||
fieldErr = tmp
|
||||
}
|
||||
} else {
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: data}
|
||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context}
|
||||
}
|
||||
|
||||
// Overrides the time of the Entry.
|
||||
func (entry *Entry) WithTime(t time.Time) *Entry {
|
||||
return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err, Context: entry.Context}
|
||||
}
|
||||
|
||||
// getPackageName reduces a fully qualified function name to the package name
|
||||
// There really ought to be to be a better way...
|
||||
func getPackageName(f string) string {
|
||||
for {
|
||||
lastPeriod := strings.LastIndex(f, ".")
|
||||
lastSlash := strings.LastIndex(f, "/")
|
||||
if lastPeriod > lastSlash {
|
||||
f = f[:lastPeriod]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
// getCaller retrieves the name of the first non-logrus calling function
|
||||
func getCaller() *runtime.Frame {
|
||||
|
||||
// cache this package's fully-qualified name
|
||||
callerInitOnce.Do(func() {
|
||||
pcs := make([]uintptr, 2)
|
||||
_ = runtime.Callers(0, pcs)
|
||||
logrusPackage = getPackageName(runtime.FuncForPC(pcs[1]).Name())
|
||||
|
||||
// now that we have the cache, we can skip a minimum count of known-logrus functions
|
||||
// XXX this is dubious, the number of frames may vary
|
||||
minimumCallerDepth = knownLogrusFrames
|
||||
})
|
||||
|
||||
// Restrict the lookback frames to avoid runaway lookups
|
||||
pcs := make([]uintptr, maximumCallerDepth)
|
||||
depth := runtime.Callers(minimumCallerDepth, pcs)
|
||||
frames := runtime.CallersFrames(pcs[:depth])
|
||||
|
||||
for f, again := frames.Next(); again; f, again = frames.Next() {
|
||||
pkg := getPackageName(f.Function)
|
||||
|
||||
// If the caller isn't part of this package, we're done
|
||||
if pkg != logrusPackage {
|
||||
return &f
|
||||
}
|
||||
}
|
||||
|
||||
// if we got here, we failed to find the caller's context
|
||||
return nil
|
||||
}
|
||||
|
||||
func (entry Entry) HasCaller() (has bool) {
|
||||
return entry.Logger != nil &&
|
||||
entry.Logger.ReportCaller &&
|
||||
entry.Caller != nil
|
||||
}
|
||||
|
||||
// This function is not declared with a pointer value because otherwise
|
||||
// race conditions will occur when using multiple goroutines
|
||||
func (entry Entry) log(level Level, msg string) {
|
||||
var buffer *bytes.Buffer
|
||||
entry.Time = time.Now()
|
||||
|
||||
// Default to now, but allow users to override if they want.
|
||||
//
|
||||
// We don't have to worry about polluting future calls to Entry#log()
|
||||
// with this assignment because this function is declared with a
|
||||
// non-pointer receiver.
|
||||
if entry.Time.IsZero() {
|
||||
entry.Time = time.Now()
|
||||
}
|
||||
|
||||
entry.Level = level
|
||||
entry.Message = msg
|
||||
|
||||
if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
if entry.Logger.ReportCaller {
|
||||
entry.Caller = getCaller()
|
||||
}
|
||||
|
||||
entry.fireHooks()
|
||||
|
||||
buffer = bufferPool.Get().(*bytes.Buffer)
|
||||
buffer.Reset()
|
||||
defer bufferPool.Put(buffer)
|
||||
entry.Buffer = buffer
|
||||
serialized, err := entry.Logger.Formatter.Format(&entry)
|
||||
|
||||
entry.write()
|
||||
|
||||
entry.Buffer = nil
|
||||
if err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
} else {
|
||||
entry.Logger.mu.Lock()
|
||||
_, err = entry.Logger.Out.Write(serialized)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
}
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
// To avoid Entry#log() returning a value that only would make sense for
|
||||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
||||
@ -126,26 +240,53 @@ func (entry Entry) log(level Level, msg string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Debug(args ...interface{}) {
|
||||
if entry.Logger.level() >= DebugLevel {
|
||||
entry.log(DebugLevel, fmt.Sprint(args...))
|
||||
func (entry *Entry) fireHooks() {
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
err := entry.Logger.Hooks.Fire(entry.Level, entry)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) write() {
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||
} else {
|
||||
_, err = entry.Logger.Out.Write(serialized)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Log(level Level, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(level) {
|
||||
entry.log(level, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Trace(args ...interface{}) {
|
||||
entry.Log(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debug(args ...interface{}) {
|
||||
entry.Log(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Print(args ...interface{}) {
|
||||
entry.Info(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Info(args ...interface{}) {
|
||||
if entry.Logger.level() >= InfoLevel {
|
||||
entry.log(InfoLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warn(args ...interface{}) {
|
||||
if entry.Logger.level() >= WarnLevel {
|
||||
entry.log(WarnLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warning(args ...interface{}) {
|
||||
@ -153,37 +294,37 @@ func (entry *Entry) Warning(args ...interface{}) {
|
||||
}
|
||||
|
||||
func (entry *Entry) Error(args ...interface{}) {
|
||||
if entry.Logger.level() >= ErrorLevel {
|
||||
entry.log(ErrorLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatal(args ...interface{}) {
|
||||
if entry.Logger.level() >= FatalLevel {
|
||||
entry.log(FatalLevel, fmt.Sprint(args...))
|
||||
}
|
||||
Exit(1)
|
||||
entry.Log(FatalLevel, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panic(args ...interface{}) {
|
||||
if entry.Logger.level() >= PanicLevel {
|
||||
entry.log(PanicLevel, fmt.Sprint(args...))
|
||||
}
|
||||
entry.Log(PanicLevel, args...)
|
||||
panic(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
// Entry Printf family functions
|
||||
|
||||
func (entry *Entry) Debugf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= DebugLevel {
|
||||
entry.Debug(fmt.Sprintf(format, args...))
|
||||
func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(level) {
|
||||
entry.Log(level, fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Tracef(format string, args ...interface{}) {
|
||||
entry.Logf(TraceLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debugf(format string, args ...interface{}) {
|
||||
entry.Logf(DebugLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Infof(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= InfoLevel {
|
||||
entry.Info(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(InfoLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Printf(format string, args ...interface{}) {
|
||||
@ -191,9 +332,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) {
|
||||
}
|
||||
|
||||
func (entry *Entry) Warnf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= WarnLevel {
|
||||
entry.Warn(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(WarnLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningf(format string, args ...interface{}) {
|
||||
@ -201,36 +340,36 @@ func (entry *Entry) Warningf(format string, args ...interface{}) {
|
||||
}
|
||||
|
||||
func (entry *Entry) Errorf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= ErrorLevel {
|
||||
entry.Error(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(ErrorLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= FatalLevel {
|
||||
entry.Fatal(fmt.Sprintf(format, args...))
|
||||
}
|
||||
Exit(1)
|
||||
entry.Logf(FatalLevel, format, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||
if entry.Logger.level() >= PanicLevel {
|
||||
entry.Panic(fmt.Sprintf(format, args...))
|
||||
}
|
||||
entry.Logf(PanicLevel, format, args...)
|
||||
}
|
||||
|
||||
// Entry Println family functions
|
||||
|
||||
func (entry *Entry) Debugln(args ...interface{}) {
|
||||
if entry.Logger.level() >= DebugLevel {
|
||||
entry.Debug(entry.sprintlnn(args...))
|
||||
func (entry *Entry) Logln(level Level, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(level) {
|
||||
entry.Log(level, entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Traceln(args ...interface{}) {
|
||||
entry.Logln(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debugln(args ...interface{}) {
|
||||
entry.Logln(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Infoln(args ...interface{}) {
|
||||
if entry.Logger.level() >= InfoLevel {
|
||||
entry.Info(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Println(args ...interface{}) {
|
||||
@ -238,9 +377,7 @@ func (entry *Entry) Println(args ...interface{}) {
|
||||
}
|
||||
|
||||
func (entry *Entry) Warnln(args ...interface{}) {
|
||||
if entry.Logger.level() >= WarnLevel {
|
||||
entry.Warn(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningln(args ...interface{}) {
|
||||
@ -248,22 +385,16 @@ func (entry *Entry) Warningln(args ...interface{}) {
|
||||
}
|
||||
|
||||
func (entry *Entry) Errorln(args ...interface{}) {
|
||||
if entry.Logger.level() >= ErrorLevel {
|
||||
entry.Error(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalln(args ...interface{}) {
|
||||
if entry.Logger.level() >= FatalLevel {
|
||||
entry.Fatal(entry.sprintlnn(args...))
|
||||
}
|
||||
Exit(1)
|
||||
entry.Logln(FatalLevel, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicln(args ...interface{}) {
|
||||
if entry.Logger.level() >= PanicLevel {
|
||||
entry.Panic(entry.sprintlnn(args...))
|
||||
}
|
||||
entry.Logln(PanicLevel, args...)
|
||||
}
|
||||
|
||||
// Sprintlnn => Sprint no newline. This is to get the behavior of how
|
||||
|
66
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
66
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
@ -1,7 +1,9 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -15,37 +17,38 @@ func StandardLogger() *Logger {
|
||||
|
||||
// SetOutput sets the standard logger output.
|
||||
func SetOutput(out io.Writer) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Out = out
|
||||
std.SetOutput(out)
|
||||
}
|
||||
|
||||
// SetFormatter sets the standard logger formatter.
|
||||
func SetFormatter(formatter Formatter) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Formatter = formatter
|
||||
std.SetFormatter(formatter)
|
||||
}
|
||||
|
||||
// SetReportCaller sets whether the standard logger will include the calling
|
||||
// method as a field.
|
||||
func SetReportCaller(include bool) {
|
||||
std.SetReportCaller(include)
|
||||
}
|
||||
|
||||
// SetLevel sets the standard logger level.
|
||||
func SetLevel(level Level) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.SetLevel(level)
|
||||
}
|
||||
|
||||
// GetLevel returns the standard logger level.
|
||||
func GetLevel() Level {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
return std.level()
|
||||
return std.GetLevel()
|
||||
}
|
||||
|
||||
// IsLevelEnabled checks if the log level of the standard logger is greater than the level param
|
||||
func IsLevelEnabled(level Level) bool {
|
||||
return std.IsLevelEnabled(level)
|
||||
}
|
||||
|
||||
// AddHook adds a hook to the standard logger hooks.
|
||||
func AddHook(hook Hook) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Hooks.Add(hook)
|
||||
std.AddHook(hook)
|
||||
}
|
||||
|
||||
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
|
||||
@ -53,6 +56,11 @@ func WithError(err error) *Entry {
|
||||
return std.WithField(ErrorKey, err)
|
||||
}
|
||||
|
||||
// WithContext creates an entry from the standard logger and adds a context to it.
|
||||
func WithContext(ctx context.Context) *Entry {
|
||||
return std.WithContext(ctx)
|
||||
}
|
||||
|
||||
// WithField creates an entry from the standard logger and adds a field to
|
||||
// it. If you want multiple fields, use `WithFields`.
|
||||
//
|
||||
@ -72,6 +80,20 @@ func WithFields(fields Fields) *Entry {
|
||||
return std.WithFields(fields)
|
||||
}
|
||||
|
||||
// WithTime creats an entry from the standard logger and overrides the time of
|
||||
// logs generated with it.
|
||||
//
|
||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
||||
// or Panic on the Entry it returns.
|
||||
func WithTime(t time.Time) *Entry {
|
||||
return std.WithTime(t)
|
||||
}
|
||||
|
||||
// Trace logs a message at level Trace on the standard logger.
|
||||
func Trace(args ...interface{}) {
|
||||
std.Trace(args...)
|
||||
}
|
||||
|
||||
// Debug logs a message at level Debug on the standard logger.
|
||||
func Debug(args ...interface{}) {
|
||||
std.Debug(args...)
|
||||
@ -107,11 +129,16 @@ func Panic(args ...interface{}) {
|
||||
std.Panic(args...)
|
||||
}
|
||||
|
||||
// Fatal logs a message at level Fatal on the standard logger.
|
||||
// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
||||
func Fatal(args ...interface{}) {
|
||||
std.Fatal(args...)
|
||||
}
|
||||
|
||||
// Tracef logs a message at level Trace on the standard logger.
|
||||
func Tracef(format string, args ...interface{}) {
|
||||
std.Tracef(format, args...)
|
||||
}
|
||||
|
||||
// Debugf logs a message at level Debug on the standard logger.
|
||||
func Debugf(format string, args ...interface{}) {
|
||||
std.Debugf(format, args...)
|
||||
@ -147,11 +174,16 @@ func Panicf(format string, args ...interface{}) {
|
||||
std.Panicf(format, args...)
|
||||
}
|
||||
|
||||
// Fatalf logs a message at level Fatal on the standard logger.
|
||||
// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
||||
func Fatalf(format string, args ...interface{}) {
|
||||
std.Fatalf(format, args...)
|
||||
}
|
||||
|
||||
// Traceln logs a message at level Trace on the standard logger.
|
||||
func Traceln(args ...interface{}) {
|
||||
std.Traceln(args...)
|
||||
}
|
||||
|
||||
// Debugln logs a message at level Debug on the standard logger.
|
||||
func Debugln(args ...interface{}) {
|
||||
std.Debugln(args...)
|
||||
@ -187,7 +219,7 @@ func Panicln(args ...interface{}) {
|
||||
std.Panicln(args...)
|
||||
}
|
||||
|
||||
// Fatalln logs a message at level Fatal on the standard logger.
|
||||
// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
||||
func Fatalln(args ...interface{}) {
|
||||
std.Fatalln(args...)
|
||||
}
|
||||
|
51
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
51
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
@ -2,7 +2,16 @@ package logrus
|
||||
|
||||
import "time"
|
||||
|
||||
const defaultTimestampFormat = time.RFC3339
|
||||
// Default key names for the default fields
|
||||
const (
|
||||
defaultTimestampFormat = time.RFC3339
|
||||
FieldKeyMsg = "msg"
|
||||
FieldKeyLevel = "level"
|
||||
FieldKeyTime = "time"
|
||||
FieldKeyLogrusError = "logrus_error"
|
||||
FieldKeyFunc = "func"
|
||||
FieldKeyFile = "file"
|
||||
)
|
||||
|
||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
||||
// `Entry`. It exposes all the fields, including the default ones:
|
||||
@ -18,7 +27,7 @@ type Formatter interface {
|
||||
Format(*Entry) ([]byte, error)
|
||||
}
|
||||
|
||||
// This is to not silently overwrite `time`, `msg` and `level` fields when
|
||||
// This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
|
||||
// dumping it. If this code wasn't there doing:
|
||||
//
|
||||
// logrus.WithField("level", 1).Info("hello")
|
||||
@ -30,16 +39,40 @@ type Formatter interface {
|
||||
//
|
||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||
// avoid code duplication between the two default formatters.
|
||||
func prefixFieldClashes(data Fields) {
|
||||
if t, ok := data["time"]; ok {
|
||||
data["fields.time"] = t
|
||||
func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
|
||||
timeKey := fieldMap.resolve(FieldKeyTime)
|
||||
if t, ok := data[timeKey]; ok {
|
||||
data["fields."+timeKey] = t
|
||||
delete(data, timeKey)
|
||||
}
|
||||
|
||||
if m, ok := data["msg"]; ok {
|
||||
data["fields.msg"] = m
|
||||
msgKey := fieldMap.resolve(FieldKeyMsg)
|
||||
if m, ok := data[msgKey]; ok {
|
||||
data["fields."+msgKey] = m
|
||||
delete(data, msgKey)
|
||||
}
|
||||
|
||||
if l, ok := data["level"]; ok {
|
||||
data["fields.level"] = l
|
||||
levelKey := fieldMap.resolve(FieldKeyLevel)
|
||||
if l, ok := data[levelKey]; ok {
|
||||
data["fields."+levelKey] = l
|
||||
delete(data, levelKey)
|
||||
}
|
||||
|
||||
logrusErrKey := fieldMap.resolve(FieldKeyLogrusError)
|
||||
if l, ok := data[logrusErrKey]; ok {
|
||||
data["fields."+logrusErrKey] = l
|
||||
delete(data, logrusErrKey)
|
||||
}
|
||||
|
||||
// If reportCaller is not set, 'func' will not conflict.
|
||||
if reportCaller {
|
||||
funcKey := fieldMap.resolve(FieldKeyFunc)
|
||||
if l, ok := data[funcKey]; ok {
|
||||
data["fields."+funcKey] = l
|
||||
}
|
||||
fileKey := fieldMap.resolve(FieldKeyFile)
|
||||
if l, ok := data[fileKey]; ok {
|
||||
data["fields."+fileKey] = l
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
vendor/github.com/sirupsen/logrus/go.mod
generated
vendored
Normal file
10
vendor/github.com/sirupsen/logrus/go.mod
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
module github.com/sirupsen/logrus
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/objx v0.1.1 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33
|
||||
)
|
13
vendor/github.com/sirupsen/logrus/go.sum
generated
vendored
Normal file
13
vendor/github.com/sirupsen/logrus/go.sum
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
74
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
74
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
@ -1,8 +1,10 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type fieldKey string
|
||||
@ -10,13 +12,6 @@ type fieldKey string
|
||||
// FieldMap allows customization of the key names for default fields.
|
||||
type FieldMap map[fieldKey]string
|
||||
|
||||
// Default key names for the default fields
|
||||
const (
|
||||
FieldKeyMsg = "msg"
|
||||
FieldKeyLevel = "level"
|
||||
FieldKeyTime = "time"
|
||||
)
|
||||
|
||||
func (f FieldMap) resolve(key fieldKey) string {
|
||||
if k, ok := f[key]; ok {
|
||||
return k
|
||||
@ -33,21 +28,34 @@ type JSONFormatter struct {
|
||||
// DisableTimestamp allows disabling automatic timestamps in output
|
||||
DisableTimestamp bool
|
||||
|
||||
// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
|
||||
DataKey string
|
||||
|
||||
// FieldMap allows users to customize the names of keys for default fields.
|
||||
// As an example:
|
||||
// formatter := &JSONFormatter{
|
||||
// FieldMap: FieldMap{
|
||||
// FieldKeyTime: "@timestamp",
|
||||
// FieldKeyTime: "@timestamp",
|
||||
// FieldKeyLevel: "@level",
|
||||
// FieldKeyMsg: "@message",
|
||||
// FieldKeyMsg: "@message",
|
||||
// FieldKeyFunc: "@caller",
|
||||
// },
|
||||
// }
|
||||
FieldMap FieldMap
|
||||
|
||||
// CallerPrettyfier can be set by the user to modify the content
|
||||
// of the function and file keys in the json data when ReportCaller is
|
||||
// activated. If any of the returned value is the empty string the
|
||||
// corresponding key will be removed from json fields.
|
||||
CallerPrettyfier func(*runtime.Frame) (function string, file string)
|
||||
|
||||
// PrettyPrint will indent all json logs
|
||||
PrettyPrint bool
|
||||
}
|
||||
|
||||
// Format renders a single log entry
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data := make(Fields, len(entry.Data)+3)
|
||||
data := make(Fields, len(entry.Data)+4)
|
||||
for k, v := range entry.Data {
|
||||
switch v := v.(type) {
|
||||
case error:
|
||||
@ -58,22 +66,56 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
prefixFieldClashes(data)
|
||||
|
||||
if f.DataKey != "" {
|
||||
newData := make(Fields, 4)
|
||||
newData[f.DataKey] = data
|
||||
data = newData
|
||||
}
|
||||
|
||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = defaultTimestampFormat
|
||||
}
|
||||
|
||||
if entry.err != "" {
|
||||
data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err
|
||||
}
|
||||
if !f.DisableTimestamp {
|
||||
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
|
||||
}
|
||||
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
if entry.HasCaller() {
|
||||
funcVal := entry.Caller.Function
|
||||
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
||||
if f.CallerPrettyfier != nil {
|
||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
||||
}
|
||||
if funcVal != "" {
|
||||
data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal
|
||||
}
|
||||
if fileVal != "" {
|
||||
data[f.FieldMap.resolve(FieldKeyFile)] = fileVal
|
||||
}
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
|
||||
var b *bytes.Buffer
|
||||
if entry.Buffer != nil {
|
||||
b = entry.Buffer
|
||||
} else {
|
||||
b = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
encoder := json.NewEncoder(b)
|
||||
if f.PrettyPrint {
|
||||
encoder.SetIndent("", " ")
|
||||
}
|
||||
if err := encoder.Encode(data); err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
246
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
246
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
@ -1,16 +1,18 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
||||
// file, or leave it default which is `os.Stderr`. You can also set this to
|
||||
// something more adventorous, such as logging to Kafka.
|
||||
// something more adventurous, such as logging to Kafka.
|
||||
Out io.Writer
|
||||
// Hooks for the logger instance. These allow firing events based on logging
|
||||
// levels and log entries. For example, to send errors to an error tracking
|
||||
@ -23,6 +25,10 @@ type Logger struct {
|
||||
// own that implements the `Formatter` interface, see the `README` or included
|
||||
// formatters for examples.
|
||||
Formatter Formatter
|
||||
|
||||
// Flag for whether to log caller info (off by default)
|
||||
ReportCaller bool
|
||||
|
||||
// The logging level the logger should log at. This is typically (and defaults
|
||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||
// logged.
|
||||
@ -31,8 +37,12 @@ type Logger struct {
|
||||
mu MutexWrap
|
||||
// Reusable empty entry
|
||||
entryPool sync.Pool
|
||||
// Function to exit the application, defaults to `os.Exit()`
|
||||
ExitFunc exitFunc
|
||||
}
|
||||
|
||||
type exitFunc func(int)
|
||||
|
||||
type MutexWrap struct {
|
||||
lock sync.Mutex
|
||||
disabled bool
|
||||
@ -68,10 +78,12 @@ func (mw *MutexWrap) Disable() {
|
||||
// It's recommended to make this a global instance called `log`.
|
||||
func New() *Logger {
|
||||
return &Logger{
|
||||
Out: os.Stderr,
|
||||
Formatter: new(TextFormatter),
|
||||
Hooks: make(LevelHooks),
|
||||
Level: InfoLevel,
|
||||
Out: os.Stderr,
|
||||
Formatter: new(TextFormatter),
|
||||
Hooks: make(LevelHooks),
|
||||
Level: InfoLevel,
|
||||
ExitFunc: os.Exit,
|
||||
ReportCaller: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,11 +96,12 @@ func (logger *Logger) newEntry() *Entry {
|
||||
}
|
||||
|
||||
func (logger *Logger) releaseEntry(entry *Entry) {
|
||||
entry.Data = map[string]interface{}{}
|
||||
logger.entryPool.Put(entry)
|
||||
}
|
||||
|
||||
// Adds a field to the log entry, note that it doesn't log until you call
|
||||
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
||||
// Debug, Print, Info, Warn, Error, Fatal or Panic. It only creates a log entry.
|
||||
// If you want multiple fields, use `WithFields`.
|
||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
||||
entry := logger.newEntry()
|
||||
@ -112,20 +125,38 @@ func (logger *Logger) WithError(err error) *Entry {
|
||||
return entry.WithError(err)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||
if logger.level() >= DebugLevel {
|
||||
// Add a context to the log entry.
|
||||
func (logger *Logger) WithContext(ctx context.Context) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithContext(ctx)
|
||||
}
|
||||
|
||||
// Overrides the time of the log entry.
|
||||
func (logger *Logger) WithTime(t time.Time) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithTime(t)
|
||||
}
|
||||
|
||||
func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Debugf(format, args...)
|
||||
entry.Logf(level, format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Tracef(format string, args ...interface{}) {
|
||||
logger.Logf(TraceLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||
logger.Logf(DebugLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||
if logger.level() >= InfoLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Infof(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logf(InfoLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||
@ -135,123 +166,91 @@ func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logf(WarnLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Warnf(format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||
if logger.level() >= ErrorLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Errorf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logf(ErrorLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||
if logger.level() >= FatalLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
Exit(1)
|
||||
logger.Logf(FatalLevel, format, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||
if logger.level() >= PanicLevel {
|
||||
logger.Logf(PanicLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Log(level Level, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Panicf(format, args...)
|
||||
entry.Log(level, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Trace(args ...interface{}) {
|
||||
logger.Log(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(args ...interface{}) {
|
||||
if logger.level() >= DebugLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Debug(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(args ...interface{}) {
|
||||
if logger.level() >= InfoLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Print(args ...interface{}) {
|
||||
entry := logger.newEntry()
|
||||
entry.Info(args...)
|
||||
entry.Print(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warn(args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warn(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Warn(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(args ...interface{}) {
|
||||
if logger.level() >= ErrorLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Error(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Log(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(args ...interface{}) {
|
||||
if logger.level() >= FatalLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatal(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
Exit(1)
|
||||
logger.Log(FatalLevel, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panic(args ...interface{}) {
|
||||
if logger.level() >= PanicLevel {
|
||||
logger.Log(PanicLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Logln(level Level, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Panic(args...)
|
||||
entry.Logln(level, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Traceln(args ...interface{}) {
|
||||
logger.Logln(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugln(args ...interface{}) {
|
||||
if logger.level() >= DebugLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Debugln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Infoln(args ...interface{}) {
|
||||
if logger.level() >= InfoLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Infoln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Println(args ...interface{}) {
|
||||
@ -261,44 +260,32 @@ func (logger *Logger) Println(args ...interface{}) {
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnln(args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningln(args ...interface{}) {
|
||||
if logger.level() >= WarnLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Warnln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Warnln(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorln(args ...interface{}) {
|
||||
if logger.level() >= ErrorLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Errorln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
logger.Logln(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||
if logger.level() >= FatalLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Fatalln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
Exit(1)
|
||||
logger.Logln(FatalLevel, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicln(args ...interface{}) {
|
||||
if logger.level() >= PanicLevel {
|
||||
entry := logger.newEntry()
|
||||
entry.Panicln(args...)
|
||||
logger.releaseEntry(entry)
|
||||
logger.Logln(PanicLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Exit(code int) {
|
||||
runHandlers()
|
||||
if logger.ExitFunc == nil {
|
||||
logger.ExitFunc = os.Exit
|
||||
}
|
||||
logger.ExitFunc(code)
|
||||
}
|
||||
|
||||
//When file is opened with appending mode, it's safe to
|
||||
@ -312,6 +299,53 @@ func (logger *Logger) level() Level {
|
||||
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
||||
}
|
||||
|
||||
// SetLevel sets the logger level.
|
||||
func (logger *Logger) SetLevel(level Level) {
|
||||
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
||||
}
|
||||
|
||||
// GetLevel returns the logger level.
|
||||
func (logger *Logger) GetLevel() Level {
|
||||
return logger.level()
|
||||
}
|
||||
|
||||
// AddHook adds a hook to the logger hooks.
|
||||
func (logger *Logger) AddHook(hook Hook) {
|
||||
logger.mu.Lock()
|
||||
defer logger.mu.Unlock()
|
||||
logger.Hooks.Add(hook)
|
||||
}
|
||||
|
||||
// IsLevelEnabled checks if the log level of the logger is greater than the level param
|
||||
func (logger *Logger) IsLevelEnabled(level Level) bool {
|
||||
return logger.level() >= level
|
||||
}
|
||||
|
||||
// SetFormatter sets the logger formatter.
|
||||
func (logger *Logger) SetFormatter(formatter Formatter) {
|
||||
logger.mu.Lock()
|
||||
defer logger.mu.Unlock()
|
||||
logger.Formatter = formatter
|
||||
}
|
||||
|
||||
// SetOutput sets the logger output.
|
||||
func (logger *Logger) SetOutput(output io.Writer) {
|
||||
logger.mu.Lock()
|
||||
defer logger.mu.Unlock()
|
||||
logger.Out = output
|
||||
}
|
||||
|
||||
func (logger *Logger) SetReportCaller(reportCaller bool) {
|
||||
logger.mu.Lock()
|
||||
defer logger.mu.Unlock()
|
||||
logger.ReportCaller = reportCaller
|
||||
}
|
||||
|
||||
// ReplaceHooks replaces the logger hooks and returns the old ones
|
||||
func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
|
||||
logger.mu.Lock()
|
||||
oldHooks := logger.Hooks
|
||||
logger.Hooks = hooks
|
||||
logger.mu.Unlock()
|
||||
return oldHooks
|
||||
}
|
||||
|
75
vendor/github.com/sirupsen/logrus/logrus.go
generated
vendored
75
vendor/github.com/sirupsen/logrus/logrus.go
generated
vendored
@ -14,22 +14,11 @@ type Level uint32
|
||||
|
||||
// Convert the Level to a string. E.g. PanicLevel becomes "panic".
|
||||
func (level Level) String() string {
|
||||
switch level {
|
||||
case DebugLevel:
|
||||
return "debug"
|
||||
case InfoLevel:
|
||||
return "info"
|
||||
case WarnLevel:
|
||||
return "warning"
|
||||
case ErrorLevel:
|
||||
return "error"
|
||||
case FatalLevel:
|
||||
return "fatal"
|
||||
case PanicLevel:
|
||||
return "panic"
|
||||
if b, err := level.MarshalText(); err == nil {
|
||||
return string(b)
|
||||
} else {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// ParseLevel takes a string level and returns the Logrus log level constant.
|
||||
@ -47,12 +36,47 @@ func ParseLevel(lvl string) (Level, error) {
|
||||
return InfoLevel, nil
|
||||
case "debug":
|
||||
return DebugLevel, nil
|
||||
case "trace":
|
||||
return TraceLevel, nil
|
||||
}
|
||||
|
||||
var l Level
|
||||
return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (level *Level) UnmarshalText(text []byte) error {
|
||||
l, err := ParseLevel(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*level = Level(l)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (level Level) MarshalText() ([]byte, error) {
|
||||
switch level {
|
||||
case TraceLevel:
|
||||
return []byte("trace"), nil
|
||||
case DebugLevel:
|
||||
return []byte("debug"), nil
|
||||
case InfoLevel:
|
||||
return []byte("info"), nil
|
||||
case WarnLevel:
|
||||
return []byte("warning"), nil
|
||||
case ErrorLevel:
|
||||
return []byte("error"), nil
|
||||
case FatalLevel:
|
||||
return []byte("fatal"), nil
|
||||
case PanicLevel:
|
||||
return []byte("panic"), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("not a valid logrus level %d", level)
|
||||
}
|
||||
|
||||
// A constant exposing all logging levels
|
||||
var AllLevels = []Level{
|
||||
PanicLevel,
|
||||
@ -61,6 +85,7 @@ var AllLevels = []Level{
|
||||
WarnLevel,
|
||||
InfoLevel,
|
||||
DebugLevel,
|
||||
TraceLevel,
|
||||
}
|
||||
|
||||
// These are the different logging levels. You can set the logging level to log
|
||||
@ -69,7 +94,7 @@ const (
|
||||
// PanicLevel level, highest level of severity. Logs and then calls panic with the
|
||||
// message passed to Debug, Info, ...
|
||||
PanicLevel Level = iota
|
||||
// FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
|
||||
// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
|
||||
// logging level is set to Panic.
|
||||
FatalLevel
|
||||
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
|
||||
@ -82,6 +107,8 @@ const (
|
||||
InfoLevel
|
||||
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
|
||||
DebugLevel
|
||||
// TraceLevel level. Designates finer-grained informational events than the Debug.
|
||||
TraceLevel
|
||||
)
|
||||
|
||||
// Won't compile if StdLogger can't be realized by a log.Logger
|
||||
@ -140,4 +167,20 @@ type FieldLogger interface {
|
||||
Errorln(args ...interface{})
|
||||
Fatalln(args ...interface{})
|
||||
Panicln(args ...interface{})
|
||||
|
||||
// IsDebugEnabled() bool
|
||||
// IsInfoEnabled() bool
|
||||
// IsWarnEnabled() bool
|
||||
// IsErrorEnabled() bool
|
||||
// IsFatalEnabled() bool
|
||||
// IsPanicEnabled() bool
|
||||
}
|
||||
|
||||
// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is
|
||||
// here for consistancy. Do not use. Use Logger or Entry instead.
|
||||
type Ext1FieldLogger interface {
|
||||
FieldLogger
|
||||
Tracef(format string, args ...interface{})
|
||||
Trace(args ...interface{})
|
||||
Traceln(args ...interface{})
|
||||
}
|
||||
|
10
vendor/github.com/sirupsen/logrus/terminal_bsd.go
generated
vendored
10
vendor/github.com/sirupsen/logrus/terminal_bsd.go
generated
vendored
@ -1,10 +0,0 @@
|
||||
// +build darwin freebsd openbsd netbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const ioctlReadTermios = unix.TIOCGETA
|
||||
|
||||
type Termios unix.Termios
|
11
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
generated
vendored
Normal file
11
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// +build appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
return true
|
||||
}
|
13
vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
Normal file
13
vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
|
||||
package logrus
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const ioctlReadTermios = unix.TIOCGETA
|
||||
|
||||
func isTerminal(fd int) bool {
|
||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
return err == nil
|
||||
}
|
||||
|
11
vendor/github.com/sirupsen/logrus/terminal_check_js.go
generated
vendored
Normal file
11
vendor/github.com/sirupsen/logrus/terminal_check_js.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// +build js
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
return false
|
||||
}
|
17
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
generated
vendored
Normal file
17
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// +build !appengine,!js,!windows
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
switch v := w.(type) {
|
||||
case *os.File:
|
||||
return isTerminal(int(v.Fd()))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
13
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
Normal file
13
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// +build linux aix
|
||||
|
||||
package logrus
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const ioctlReadTermios = unix.TCGETS
|
||||
|
||||
func isTerminal(fd int) bool {
|
||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
return err == nil
|
||||
}
|
||||
|
20
vendor/github.com/sirupsen/logrus/terminal_check_windows.go
generated
vendored
Normal file
20
vendor/github.com/sirupsen/logrus/terminal_check_windows.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// +build !appengine,!js,windows
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
switch v := w.(type) {
|
||||
case *os.File:
|
||||
var mode uint32
|
||||
err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode)
|
||||
return err == nil
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
14
vendor/github.com/sirupsen/logrus/terminal_linux.go
generated
vendored
14
vendor/github.com/sirupsen/logrus/terminal_linux.go
generated
vendored
@ -1,14 +0,0 @@
|
||||
// Based on ssh/terminal:
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const ioctlReadTermios = unix.TCGETS
|
||||
|
||||
type Termios unix.Termios
|
8
vendor/github.com/sirupsen/logrus/terminal_notwindows.go
generated
vendored
Normal file
8
vendor/github.com/sirupsen/logrus/terminal_notwindows.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// +build !windows
|
||||
|
||||
package logrus
|
||||
|
||||
import "io"
|
||||
|
||||
func initTerminal(w io.Writer) {
|
||||
}
|
18
vendor/github.com/sirupsen/logrus/terminal_windows.go
generated
vendored
Normal file
18
vendor/github.com/sirupsen/logrus/terminal_windows.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// +build !appengine,!js,windows
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
sequences "github.com/konsorten/go-windows-terminal-sequences"
|
||||
)
|
||||
|
||||
func initTerminal(w io.Writer) {
|
||||
switch v := w.(type) {
|
||||
case *os.File:
|
||||
sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true)
|
||||
}
|
||||
}
|
204
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
204
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
@ -3,28 +3,22 @@ package logrus
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
const (
|
||||
nocolor = 0
|
||||
red = 31
|
||||
green = 32
|
||||
yellow = 33
|
||||
blue = 36
|
||||
gray = 37
|
||||
red = 31
|
||||
yellow = 33
|
||||
blue = 36
|
||||
gray = 37
|
||||
)
|
||||
|
||||
var (
|
||||
baseTimestamp time.Time
|
||||
)
|
||||
var baseTimestamp time.Time
|
||||
|
||||
func init() {
|
||||
baseTimestamp = time.Now()
|
||||
@ -38,6 +32,9 @@ type TextFormatter struct {
|
||||
// Force disabling colors.
|
||||
DisableColors bool
|
||||
|
||||
// Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/
|
||||
EnvironmentOverrideColors bool
|
||||
|
||||
// Disable timestamp logging. useful when output is redirected to logging
|
||||
// system that already adds timestamps.
|
||||
DisableTimestamp bool
|
||||
@ -54,69 +51,155 @@ type TextFormatter struct {
|
||||
// be desired.
|
||||
DisableSorting bool
|
||||
|
||||
// The keys sorting function, when uninitialized it uses sort.Strings.
|
||||
SortingFunc func([]string)
|
||||
|
||||
// Disables the truncation of the level text to 4 characters.
|
||||
DisableLevelTruncation bool
|
||||
|
||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||
QuoteEmptyFields bool
|
||||
|
||||
// Whether the logger's out is to a terminal
|
||||
isTerminal bool
|
||||
|
||||
sync.Once
|
||||
// FieldMap allows users to customize the names of keys for default fields.
|
||||
// As an example:
|
||||
// formatter := &TextFormatter{
|
||||
// FieldMap: FieldMap{
|
||||
// FieldKeyTime: "@timestamp",
|
||||
// FieldKeyLevel: "@level",
|
||||
// FieldKeyMsg: "@message"}}
|
||||
FieldMap FieldMap
|
||||
|
||||
// CallerPrettyfier can be set by the user to modify the content
|
||||
// of the function and file keys in the data when ReportCaller is
|
||||
// activated. If any of the returned value is the empty string the
|
||||
// corresponding key will be removed from fields.
|
||||
CallerPrettyfier func(*runtime.Frame) (function string, file string)
|
||||
|
||||
terminalInitOnce sync.Once
|
||||
}
|
||||
|
||||
func (f *TextFormatter) init(entry *Entry) {
|
||||
if entry.Logger != nil {
|
||||
f.isTerminal = f.checkIfTerminal(entry.Logger.Out)
|
||||
f.isTerminal = checkIfTerminal(entry.Logger.Out)
|
||||
|
||||
if f.isTerminal {
|
||||
initTerminal(entry.Logger.Out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) checkIfTerminal(w io.Writer) bool {
|
||||
switch v := w.(type) {
|
||||
case *os.File:
|
||||
return terminal.IsTerminal(int(v.Fd()))
|
||||
default:
|
||||
return false
|
||||
func (f *TextFormatter) isColored() bool {
|
||||
isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows"))
|
||||
|
||||
if f.EnvironmentOverrideColors {
|
||||
if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" {
|
||||
isColored = true
|
||||
} else if ok && force == "0" {
|
||||
isColored = false
|
||||
} else if os.Getenv("CLICOLOR") == "0" {
|
||||
isColored = false
|
||||
}
|
||||
}
|
||||
|
||||
return isColored && !f.DisableColors
|
||||
}
|
||||
|
||||
// Format renders a single log entry
|
||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
var b *bytes.Buffer
|
||||
keys := make([]string, 0, len(entry.Data))
|
||||
for k := range entry.Data {
|
||||
data := make(Fields)
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
||||
keys := make([]string, 0, len(data))
|
||||
for k := range data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
if !f.DisableSorting {
|
||||
sort.Strings(keys)
|
||||
var funcVal, fileVal string
|
||||
|
||||
fixedKeys := make([]string, 0, 4+len(data))
|
||||
if !f.DisableTimestamp {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
|
||||
}
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLevel))
|
||||
if entry.Message != "" {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyMsg))
|
||||
}
|
||||
if entry.err != "" {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
|
||||
}
|
||||
if entry.HasCaller() {
|
||||
if f.CallerPrettyfier != nil {
|
||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
||||
} else {
|
||||
funcVal = entry.Caller.Function
|
||||
fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
||||
}
|
||||
|
||||
if funcVal != "" {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFunc))
|
||||
}
|
||||
if fileVal != "" {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFile))
|
||||
}
|
||||
}
|
||||
|
||||
if !f.DisableSorting {
|
||||
if f.SortingFunc == nil {
|
||||
sort.Strings(keys)
|
||||
fixedKeys = append(fixedKeys, keys...)
|
||||
} else {
|
||||
if !f.isColored() {
|
||||
fixedKeys = append(fixedKeys, keys...)
|
||||
f.SortingFunc(fixedKeys)
|
||||
} else {
|
||||
f.SortingFunc(keys)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fixedKeys = append(fixedKeys, keys...)
|
||||
}
|
||||
|
||||
var b *bytes.Buffer
|
||||
if entry.Buffer != nil {
|
||||
b = entry.Buffer
|
||||
} else {
|
||||
b = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
prefixFieldClashes(entry.Data)
|
||||
|
||||
f.Do(func() { f.init(entry) })
|
||||
|
||||
isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
|
||||
f.terminalInitOnce.Do(func() { f.init(entry) })
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = defaultTimestampFormat
|
||||
}
|
||||
if isColored {
|
||||
f.printColored(b, entry, keys, timestampFormat)
|
||||
if f.isColored() {
|
||||
f.printColored(b, entry, keys, data, timestampFormat)
|
||||
} else {
|
||||
if !f.DisableTimestamp {
|
||||
f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat))
|
||||
}
|
||||
f.appendKeyValue(b, "level", entry.Level.String())
|
||||
if entry.Message != "" {
|
||||
f.appendKeyValue(b, "msg", entry.Message)
|
||||
}
|
||||
for _, key := range keys {
|
||||
f.appendKeyValue(b, key, entry.Data[key])
|
||||
|
||||
for _, key := range fixedKeys {
|
||||
var value interface{}
|
||||
switch {
|
||||
case key == f.FieldMap.resolve(FieldKeyTime):
|
||||
value = entry.Time.Format(timestampFormat)
|
||||
case key == f.FieldMap.resolve(FieldKeyLevel):
|
||||
value = entry.Level.String()
|
||||
case key == f.FieldMap.resolve(FieldKeyMsg):
|
||||
value = entry.Message
|
||||
case key == f.FieldMap.resolve(FieldKeyLogrusError):
|
||||
value = entry.err
|
||||
case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller():
|
||||
value = funcVal
|
||||
case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
|
||||
value = fileVal
|
||||
default:
|
||||
value = data[key]
|
||||
}
|
||||
f.appendKeyValue(b, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,10 +207,10 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) {
|
||||
var levelColor int
|
||||
switch entry.Level {
|
||||
case DebugLevel:
|
||||
case DebugLevel, TraceLevel:
|
||||
levelColor = gray
|
||||
case WarnLevel:
|
||||
levelColor = yellow
|
||||
@ -137,17 +220,42 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
|
||||
levelColor = blue
|
||||
}
|
||||
|
||||
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
||||
levelText := strings.ToUpper(entry.Level.String())
|
||||
if !f.DisableLevelTruncation {
|
||||
levelText = levelText[0:4]
|
||||
}
|
||||
|
||||
// Remove a single newline if it already exists in the message to keep
|
||||
// the behavior of logrus text_formatter the same as the stdlib log package
|
||||
entry.Message = strings.TrimSuffix(entry.Message, "\n")
|
||||
|
||||
caller := ""
|
||||
if entry.HasCaller() {
|
||||
funcVal := fmt.Sprintf("%s()", entry.Caller.Function)
|
||||
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
||||
|
||||
if f.CallerPrettyfier != nil {
|
||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
||||
}
|
||||
|
||||
if fileVal == "" {
|
||||
caller = funcVal
|
||||
} else if funcVal == "" {
|
||||
caller = fileVal
|
||||
} else {
|
||||
caller = fileVal + " " + funcVal
|
||||
}
|
||||
}
|
||||
|
||||
if f.DisableTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message)
|
||||
} else if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message)
|
||||
} else {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := entry.Data[k]
|
||||
v := data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
||||
f.appendValue(b, v)
|
||||
}
|
||||
|
2
vendor/github.com/sirupsen/logrus/writer.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/writer.go
generated
vendored
@ -24,6 +24,8 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
||||
var printFunc func(args ...interface{})
|
||||
|
||||
switch level {
|
||||
case TraceLevel:
|
||||
printFunc = entry.Trace
|
||||
case DebugLevel:
|
||||
printFunc = entry.Debug
|
||||
case InfoLevel:
|
||||
|
1
vendor/go.etcd.io/etcd/.dockerignore
generated
vendored
1
vendor/go.etcd.io/etcd/.dockerignore
generated
vendored
@ -1 +0,0 @@
|
||||
.git
|
21
vendor/go.etcd.io/etcd/.gitignore
generated
vendored
21
vendor/go.etcd.io/etcd/.gitignore
generated
vendored
@ -1,21 +0,0 @@
|
||||
/agent-*
|
||||
/coverage
|
||||
/covdir
|
||||
/docs
|
||||
/vendor
|
||||
/gopath
|
||||
/gopath.proto
|
||||
/go-bindata
|
||||
/release
|
||||
/machine*
|
||||
/bin
|
||||
.vagrant
|
||||
*.etcd
|
||||
*.log
|
||||
/etcd
|
||||
*.swp
|
||||
/hack/insta-discovery/.env
|
||||
*.test
|
||||
hack/tls-setup/certs
|
||||
.idea
|
||||
*.bak
|
1
vendor/go.etcd.io/etcd/.godir
generated
vendored
1
vendor/go.etcd.io/etcd/.godir
generated
vendored
@ -1 +0,0 @@
|
||||
github.com/coreos/etcd
|
13
vendor/go.etcd.io/etcd/.header
generated
vendored
13
vendor/go.etcd.io/etcd/.header
generated
vendored
@ -1,13 +0,0 @@
|
||||
// Copyright 2016 The etcd 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.
|
73
vendor/go.etcd.io/etcd/.travis.yml
generated
vendored
73
vendor/go.etcd.io/etcd/.travis.yml
generated
vendored
@ -1,73 +0,0 @@
|
||||
language: go
|
||||
go_import_path: github.com/coreos/etcd
|
||||
|
||||
sudo: required
|
||||
|
||||
services: docker
|
||||
|
||||
go:
|
||||
- 1.10.7
|
||||
|
||||
notifications:
|
||||
on_success: never
|
||||
on_failure: never
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- TARGET=linux-amd64-integration
|
||||
- TARGET=linux-amd64-functional
|
||||
- TARGET=linux-amd64-unit
|
||||
- TARGET=all-build
|
||||
- TARGET=linux-386-unit
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- go: 1.10.7
|
||||
env: TARGET=linux-386-unit
|
||||
exclude:
|
||||
- go: tip
|
||||
env: TARGET=linux-386-unit
|
||||
|
||||
before_install:
|
||||
- if [[ $TRAVIS_GO_VERSION == 1.* ]]; then docker pull gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION}; fi
|
||||
|
||||
install:
|
||||
- pushd cmd/etcd && go get -t -v ./... && popd
|
||||
|
||||
script:
|
||||
- echo "TRAVIS_GO_VERSION=${TRAVIS_GO_VERSION}"
|
||||
- >
|
||||
case "${TARGET}" in
|
||||
linux-amd64-integration)
|
||||
docker run --rm \
|
||||
--volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
|
||||
/bin/bash -c "GOARCH=amd64 PASSES='integration' ./test"
|
||||
;;
|
||||
linux-amd64-functional)
|
||||
docker run --rm \
|
||||
--volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
|
||||
/bin/bash -c "./build && GOARCH=amd64 PASSES='functional' ./test"
|
||||
;;
|
||||
linux-amd64-unit)
|
||||
docker run --rm \
|
||||
--volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
|
||||
/bin/bash -c "GOARCH=amd64 PASSES='unit' ./test"
|
||||
;;
|
||||
all-build)
|
||||
docker run --rm \
|
||||
--volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
|
||||
/bin/bash -c "GOARCH=amd64 PASSES='build' ./test \
|
||||
&& GOARCH=386 PASSES='build' ./test \
|
||||
&& GO_BUILD_FLAGS='-v' GOOS=darwin GOARCH=amd64 ./build \
|
||||
&& GO_BUILD_FLAGS='-v' GOOS=windows GOARCH=amd64 ./build \
|
||||
&& GO_BUILD_FLAGS='-v' GOARCH=arm ./build \
|
||||
&& GO_BUILD_FLAGS='-v' GOARCH=arm64 ./build \
|
||||
&& GO_BUILD_FLAGS='-v' GOARCH=ppc64le ./build"
|
||||
;;
|
||||
linux-386-unit)
|
||||
docker run --rm \
|
||||
--volume=`pwd`:/go/src/github.com/coreos/etcd gcr.io/etcd-development/etcd-test:go${TRAVIS_GO_VERSION} \
|
||||
/bin/bash -c "GOARCH=386 PASSES='unit' ./test"
|
||||
;;
|
||||
esac
|
44
vendor/go.etcd.io/etcd/.words
generated
vendored
44
vendor/go.etcd.io/etcd/.words
generated
vendored
@ -1,44 +0,0 @@
|
||||
DefaultMaxRequestBytes
|
||||
ErrCodeEnhanceYourCalm
|
||||
ErrTimeout
|
||||
GoAway
|
||||
KeepAlive
|
||||
Keepalive
|
||||
MiB
|
||||
ResourceExhausted
|
||||
RPC
|
||||
RPCs
|
||||
TODO
|
||||
backoff
|
||||
blackhole
|
||||
blackholed
|
||||
cancelable
|
||||
cancelation
|
||||
cluster_proxy
|
||||
defragment
|
||||
defragmenting
|
||||
etcd
|
||||
gRPC
|
||||
goroutine
|
||||
goroutines
|
||||
healthcheck
|
||||
iff
|
||||
inflight
|
||||
keepalive
|
||||
keepalives
|
||||
keyspace
|
||||
linearization
|
||||
localhost
|
||||
mutex
|
||||
prefetching
|
||||
protobuf
|
||||
prometheus
|
||||
rafthttp
|
||||
repin
|
||||
serializable
|
||||
teardown
|
||||
too_many_pings
|
||||
uncontended
|
||||
unprefixed
|
||||
unlisting
|
||||
|
746
vendor/go.etcd.io/etcd/CHANGELOG.md
generated
vendored
746
vendor/go.etcd.io/etcd/CHANGELOG.md
generated
vendored
@ -1,746 +0,0 @@
|
||||
## [v3.3.0](https://github.com/coreos/etcd/releases/tag/v3.3.0)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.0...v3.3.0) and [v3.3 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_3.md) for any breaking changes.
|
||||
|
||||
### Improved
|
||||
|
||||
- Use [`coreos/bbolt`](https://github.com/coreos/bbolt/releases) to replace [`boltdb/bolt`](https://github.com/boltdb/bolt#project-status).
|
||||
- Fix [etcd database size grows until `mvcc: database space exceeded`](https://github.com/coreos/etcd/issues/8009).
|
||||
- [Reduce memory allocation](https://github.com/coreos/etcd/pull/8428) on [Range operations](https://github.com/coreos/etcd/pull/8475).
|
||||
- [Rate limit](https://github.com/coreos/etcd/pull/8099) and [randomize](https://github.com/coreos/etcd/pull/8101) lease revoke on restart or leader elections.
|
||||
- Prevent [spikes in Raft proposal rate](https://github.com/coreos/etcd/issues/8096).
|
||||
- Support `clientv3` balancer failover under [network faults/partitions](https://github.com/coreos/etcd/issues/8711).
|
||||
- Better warning on [mismatched `--initial-cluster`](https://github.com/coreos/etcd/pull/8083) flag.
|
||||
|
||||
### Changed(Breaking Changes)
|
||||
|
||||
- Require [Go 1.9+](https://github.com/coreos/etcd/issues/6174).
|
||||
- Compile with *Go 1.9.2*.
|
||||
- Deprecate [`golang.org/x/net/context`](https://github.com/coreos/etcd/pull/8511).
|
||||
- Require [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) [**`v1.7.4`**](https://github.com/grpc/grpc-go/releases/tag/v1.7.4) or [**`v1.7.5+`**](https://github.com/grpc/grpc-go/releases/tag/v1.7.5):
|
||||
- Deprecate [`metadata.Incoming/OutgoingContext`](https://github.com/coreos/etcd/pull/7896).
|
||||
- Deprecate `grpclog.Logger`, upgrade to [`grpclog.LoggerV2`](https://github.com/coreos/etcd/pull/8533).
|
||||
- Deprecate [`grpc.ErrClientConnTimeout`](https://github.com/coreos/etcd/pull/8505) errors in `clientv3`.
|
||||
- Use [`MaxRecvMsgSize` and `MaxSendMsgSize`](https://github.com/coreos/etcd/pull/8437) to limit message size, in etcd server.
|
||||
- Upgrade [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) `v1.2.2` to `v1.3.0`.
|
||||
- Translate [gRPC status error in v3 client `Snapshot` API](https://github.com/coreos/etcd/pull/9038).
|
||||
- Upgrade [`github.com/ugorji/go/codec`](https://github.com/ugorji/go) for v2 `client`.
|
||||
- [Regenerated](https://github.com/coreos/etcd/pull/8721) v2 `client` source code with latest `ugorji/go/codec`.
|
||||
- Fix [`/health` endpoint JSON output](https://github.com/coreos/etcd/pull/8312).
|
||||
- v3 `etcdctl` [`lease timetolive LEASE_ID`](https://github.com/coreos/etcd/issues/9028) on expired lease now prints [`lease LEASE_ID already expired`](https://github.com/coreos/etcd/pull/9047).
|
||||
- <=3.2 prints `lease LEASE_ID granted with TTL(0s), remaining(-1s)`.
|
||||
|
||||
### Added(`etcd`)
|
||||
|
||||
- Add [`--experimental-enable-v2v3`](https://github.com/coreos/etcd/pull/8407) flag to [emulate v2 API with v3](https://github.com/coreos/etcd/issues/6925).
|
||||
- Add [`--experimental-corrupt-check-time`](https://github.com/coreos/etcd/pull/8420) flag to [raise corrupt alarm monitoring](https://github.com/coreos/etcd/issues/7125).
|
||||
- Add [`--experimental-initial-corrupt-check`](https://github.com/coreos/etcd/pull/8554) flag to [check database hash before serving client/peer traffic](https://github.com/coreos/etcd/issues/8313).
|
||||
- Add [`--max-txn-ops`](https://github.com/coreos/etcd/pull/7976) flag to [configure maximum number operations in transaction](https://github.com/coreos/etcd/issues/7826).
|
||||
- Add [`--max-request-bytes`](https://github.com/coreos/etcd/pull/7968) flag to [configure maximum client request size](https://github.com/coreos/etcd/issues/7923).
|
||||
- If not configured, it defaults to 1.5 MiB.
|
||||
- Add [`--client-crl-file`, `--peer-crl-file`](https://github.com/coreos/etcd/pull/8124) flags for [Certificate revocation list](https://github.com/coreos/etcd/issues/4034).
|
||||
- Add [`--peer-require-cn`](https://github.com/coreos/etcd/pull/8616) flag to support [CN-based auth for inter-peer connection](https://github.com/coreos/etcd/issues/8262).
|
||||
- Add [`--listen-metrics-urls`](https://github.com/coreos/etcd/pull/8242) flag for additional `/metrics` endpoints.
|
||||
- Support [additional (non) TLS `/metrics` endpoints for a TLS-enabled cluster](https://github.com/coreos/etcd/pull/8282).
|
||||
- e.g. `--listen-metrics-urls=https://localhost:2378,http://localhost:9379` to serve `/metrics` in secure port 2378 and insecure port 9379.
|
||||
- Useful for [bypassing critical APIs when monitoring etcd](https://github.com/coreos/etcd/issues/8060).
|
||||
- Add [`--auto-compaction-mode`](https://github.com/coreos/etcd/pull/8123) flag to [support revision-based compaction](https://github.com/coreos/etcd/issues/8098).
|
||||
- Change `--auto-compaction-retention` flag to [accept string values](https://github.com/coreos/etcd/pull/8563) with [finer granularity](https://github.com/coreos/etcd/issues/8503).
|
||||
- Add [`--grpc-keepalive-min-time`, `--grpc-keepalive-interval`, `--grpc-keepalive-timeout`](https://github.com/coreos/etcd/pull/8535) flags to configure server-side keepalive policies.
|
||||
- Serve [`/health` endpoint as unhealthy](https://github.com/coreos/etcd/pull/8272) when [alarm is raised](https://github.com/coreos/etcd/issues/8207).
|
||||
- Provide [error information in `/health`](https://github.com/coreos/etcd/pull/8312).
|
||||
- e.g. `{"health":false,"errors":["NOSPACE"]}`.
|
||||
- Move [logging setup to embed package](https://github.com/coreos/etcd/pull/8810)
|
||||
- Disable gRPC server log by default.
|
||||
- Use [monotonic time in Go 1.9](https://github.com/coreos/etcd/pull/8507) for `lease` package.
|
||||
- Warn on [empty hosts in advertise URLs](https://github.com/coreos/etcd/pull/8384).
|
||||
- Address [advertise client URLs accepts empty hosts](https://github.com/coreos/etcd/issues/8379).
|
||||
- etcd `v3.4` will exit on this error.
|
||||
- e.g. `--advertise-client-urls=http://:2379`.
|
||||
- Warn on [shadowed environment variables](https://github.com/coreos/etcd/pull/8385).
|
||||
- Address [error on shadowed environment variables](https://github.com/coreos/etcd/issues/8380).
|
||||
- etcd `v3.4` will exit on this error.
|
||||
|
||||
### Added(API)
|
||||
|
||||
- Support [ranges in transaction comparisons](https://github.com/coreos/etcd/pull/8025) for [disconnected linearized reads](https://github.com/coreos/etcd/issues/7924).
|
||||
- Add [nested transactions](https://github.com/coreos/etcd/pull/8102) to extend [proxy use cases](https://github.com/coreos/etcd/issues/7857).
|
||||
- Add [lease comparison target in transaction](https://github.com/coreos/etcd/pull/8324).
|
||||
- Add [lease list](https://github.com/coreos/etcd/pull/8358).
|
||||
- Add [hash by revision](https://github.com/coreos/etcd/pull/8263) for [better corruption checking against boltdb](https://github.com/coreos/etcd/issues/8016).
|
||||
|
||||
### Added(`etcd/clientv3`)
|
||||
|
||||
- Add [health balancer](https://github.com/coreos/etcd/pull/8545) to fix [watch API hangs](https://github.com/coreos/etcd/issues/7247), improve [endpoint switch under network faults](https://github.com/coreos/etcd/issues/7941).
|
||||
- [Refactor balancer](https://github.com/coreos/etcd/pull/8840) and add [client-side keepalive pings](https://github.com/coreos/etcd/pull/8199) to handle [network partitions](https://github.com/coreos/etcd/issues/8711).
|
||||
- Add [`MaxCallSendMsgSize` and `MaxCallRecvMsgSize`](https://github.com/coreos/etcd/pull/9047) fields to [`clientv3.Config`](https://godoc.org/github.com/coreos/etcd/clientv3#Config).
|
||||
- Fix [exceeded response size limit error in client-side](https://github.com/coreos/etcd/issues/9043).
|
||||
- Address [kubernetes#51099](https://github.com/kubernetes/kubernetes/issues/51099).
|
||||
- `MaxCallSendMsgSize` default value is 2 MiB, if not configured.
|
||||
- `MaxCallRecvMsgSize` default value is `math.MaxInt32`, if not configured.
|
||||
- Accept [`Compare_LEASE`](https://github.com/coreos/etcd/pull/8324) in [`clientv3.Compare`](https://godoc.org/github.com/coreos/etcd/clientv3#Compare).
|
||||
- Add [`LeaseValue` helper](https://github.com/coreos/etcd/pull/8488) to `Cmp` `LeaseID` values in `Txn`.
|
||||
- Add [`MoveLeader`](https://github.com/coreos/etcd/pull/8153) to `Maintenance`.
|
||||
- Add [`HashKV`](https://github.com/coreos/etcd/pull/8351) to `Maintenance`.
|
||||
- Add [`Leases`](https://github.com/coreos/etcd/pull/8358) to `Lease`.
|
||||
- Add [`clientv3/ordering`](https://github.com/coreos/etcd/pull/8092) for enforce [ordering in serialized requests](https://github.com/coreos/etcd/issues/7623).
|
||||
|
||||
### Added(v2 `etcdctl`)
|
||||
|
||||
- Add [`backup --with-v3`](https://github.com/coreos/etcd/pull/8479) flag.
|
||||
|
||||
### Added(v3 `etcdctl`)
|
||||
|
||||
- Add [`--discovery-srv`](https://github.com/coreos/etcd/pull/8462) flag.
|
||||
- Add [`--keepalive-time`, `--keepalive-timeout`](https://github.com/coreos/etcd/pull/8663) flags.
|
||||
- Add [`lease list`](https://github.com/coreos/etcd/pull/8358) command.
|
||||
- Add [`lease keep-alive --once`](https://github.com/coreos/etcd/pull/8775) flag.
|
||||
- Make [`lease timetolive LEASE_ID`](https://github.com/coreos/etcd/issues/9028) on expired lease print [`lease LEASE_ID already expired`](https://github.com/coreos/etcd/pull/9047).
|
||||
- <=3.2 prints `lease LEASE_ID granted with TTL(0s), remaining(-1s)`.
|
||||
- Add [`defrag --data-dir`](https://github.com/coreos/etcd/pull/8367) flag.
|
||||
- Add [`move-leader`](https://github.com/coreos/etcd/pull/8153) command.
|
||||
- Add [`endpoint hashkv`](https://github.com/coreos/etcd/pull/8351) command.
|
||||
- Add [`endpoint --cluster`](https://github.com/coreos/etcd/pull/8143) flag, equivalent to [v2 `etcdctl cluster-health`](https://github.com/coreos/etcd/issues/8117).
|
||||
- Make `endpoint health` command terminate with [non-zero exit code on unhealthy status](https://github.com/coreos/etcd/pull/8342).
|
||||
- Add [`lock --ttl`](https://github.com/coreos/etcd/pull/8370) flag.
|
||||
- Support [`watch [key] [range_end] -- [exec-command…]`](https://github.com/coreos/etcd/pull/8919), equivalent to [v2 `etcdctl exec-watch`](https://github.com/coreos/etcd/issues/8814).
|
||||
- Enable [`clientv3.WithRequireLeader(context.Context)` for `watch`](https://github.com/coreos/etcd/pull/8672) command.
|
||||
- Print [`"del"` instead of `"delete"`](https://github.com/coreos/etcd/pull/8297) in `txn` interactive mode.
|
||||
- Print [`ETCD_INITIAL_ADVERTISE_PEER_URLS` in `member add`](https://github.com/coreos/etcd/pull/8332).
|
||||
|
||||
### Added(metrics)
|
||||
|
||||
- Add [`etcd --listen-metrics-urls`](https://github.com/coreos/etcd/pull/8242) flag for additional `/metrics` endpoints.
|
||||
- Useful for [bypassing critical APIs when monitoring etcd](https://github.com/coreos/etcd/issues/8060).
|
||||
- Add [`etcd_server_version`](https://github.com/coreos/etcd/pull/8960) Prometheus metric.
|
||||
- To replace [Kubernetes `etcd-version-monitor`](https://github.com/coreos/etcd/issues/8948).
|
||||
- Add [`etcd_debugging_mvcc_db_compaction_keys_total`](https://github.com/coreos/etcd/pull/8280) Prometheus metric.
|
||||
- Add [`etcd_debugging_server_lease_expired_total`](https://github.com/coreos/etcd/pull/8064) Prometheus metric.
|
||||
- To improve [lease revoke monitoring](https://github.com/coreos/etcd/issues/8050).
|
||||
- Document [Prometheus 2.0 rules](https://github.com/coreos/etcd/pull/8879).
|
||||
- Initialize gRPC server [metrics with zero values](https://github.com/coreos/etcd/pull/8878).
|
||||
|
||||
### Added(`grpc-proxy`)
|
||||
|
||||
- Add [`grpc-proxy start --experimental-leasing-prefix`](https://github.com/coreos/etcd/pull/8341) flag:
|
||||
- For disconnected linearized reads.
|
||||
- Based on [V system leasing](https://github.com/coreos/etcd/issues/6065).
|
||||
- See ["Disconnected consistent reads with etcd" blog post](https://coreos.com/blog/coreos-labs-disconnected-consistent-reads-with-etcd).
|
||||
- Add [`grpc-proxy start --experimental-serializable-ordering`](https://github.com/coreos/etcd/pull/8315) flag.
|
||||
- To ensure serializable reads have monotonically increasing store revisions across endpoints.
|
||||
- Add [`grpc-proxy start --metrics-addr`](https://github.com/coreos/etcd/pull/8242) flag for an additional `/metrics` endpoint.
|
||||
- Set `--metrics-addr=http://[HOST]:9379` to serve `/metrics` in insecure port 9379.
|
||||
- Serve [`/health` endpoint in grpc-proxy](https://github.com/coreos/etcd/pull/8322).
|
||||
- Add [`grpc-proxy start --debug`](https://github.com/coreos/etcd/pull/8994) flag.
|
||||
|
||||
### Added(gRPC gateway)
|
||||
|
||||
- Replace [gRPC gateway](https://github.com/grpc-ecosystem/grpc-gateway) endpoint with [`/v3beta`](https://github.com/coreos/etcd/pull/8880).
|
||||
- To deprecate [`/v3alpha`](https://github.com/coreos/etcd/issues/8125) in `v3.4`.
|
||||
- Support ["authorization" token](https://github.com/coreos/etcd/pull/7999).
|
||||
- Support [websocket for bi-directional streams](https://github.com/coreos/etcd/pull/8257).
|
||||
- Fix [`Watch` API with gRPC gateway](https://github.com/coreos/etcd/issues/8237).
|
||||
- Upgrade gRPC gateway to [v1.3.0](https://github.com/coreos/etcd/issues/8838).
|
||||
|
||||
### Added(`etcd/raft`)
|
||||
|
||||
- Add [non-voting member](https://github.com/coreos/etcd/pull/8751).
|
||||
- To implement [Raft thesis 4.2.1 Catching up new servers](https://github.com/coreos/etcd/issues/8568).
|
||||
- `Learner` node does not vote or promote itself.
|
||||
|
||||
### Added/Fixed(Security/Auth)
|
||||
|
||||
- Add [CRL based connection rejection](https://github.com/coreos/etcd/pull/8124) to manage [revoked certs](https://github.com/coreos/etcd/issues/4034).
|
||||
- Document [TLS authentication changes](https://github.com/coreos/etcd/pull/8895):
|
||||
- [Server accepts connections if IP matches, without checking DNS entries](https://github.com/coreos/etcd/pull/8223). For instance, if peer cert contains IP addresses and DNS names in Subject Alternative Name (SAN) field, and the remote IP address matches one of those IP addresses, server just accepts connection without further checking the DNS names.
|
||||
- [Server supports reverse-lookup on wildcard DNS `SAN`](https://github.com/coreos/etcd/pull/8281). For instance, if peer cert contains only DNS names (no IP addresses) in Subject Alternative Name (SAN) field, server first reverse-lookups the remote IP address to get a list of names mapping to that address (e.g. `nslookup IPADDR`). Then accepts the connection if those names have a matching name with peer cert's DNS names (either by exact or wildcard match). If none is matched, server forward-lookups each DNS entry in peer cert (e.g. look up `example.default.svc` when the entry is `*.example.default.svc`), and accepts connection only when the host's resolved addresses have the matching IP address with the peer's remote IP address.
|
||||
- Add [`etcd --peer-require-cn`](https://github.com/coreos/etcd/pull/8616) flag.
|
||||
- To support [CommonName(CN) based auth](https://github.com/coreos/etcd/issues/8262) for inter peer connection.
|
||||
- [Swap priority](https://github.com/coreos/etcd/pull/8594) of cert CommonName(CN) and username + password.
|
||||
- To address ["username and password specified in the request should take priority over CN in the cert"](https://github.com/coreos/etcd/issues/8584).
|
||||
- Protect [lease revoke with auth](https://github.com/coreos/etcd/pull/8031).
|
||||
- Provide user's role on [auth permission error](https://github.com/coreos/etcd/pull/8164).
|
||||
- Fix [auth store panic with disabled token](https://github.com/coreos/etcd/pull/8695).
|
||||
- Update `golang.org/x/crypto/bcrypt` (see [golang/crypto@6c586e1](https://github.com/golang/crypto/commit/6c586e17d90a7d08bbbc4069984180dce3b04117)).
|
||||
|
||||
### Fixed(v2)
|
||||
|
||||
- [Fail-over v2 client](https://github.com/coreos/etcd/pull/8519) to next endpoint on [oneshot failure](https://github.com/coreos/etcd/issues/8515).
|
||||
- [Put back `/v2/machines`](https://github.com/coreos/etcd/pull/8062) endpoint for python-etcd wrapper.
|
||||
|
||||
### Fixed(v3)
|
||||
|
||||
- Fix [range/put/delete operation metrics](https://github.com/coreos/etcd/pull/8054) with transaction:
|
||||
- `etcd_debugging_mvcc_range_total`
|
||||
- `etcd_debugging_mvcc_put_total`
|
||||
- `etcd_debugging_mvcc_delete_total`
|
||||
- `etcd_debugging_mvcc_txn_total`
|
||||
- Fix [`etcd_debugging_mvcc_keys_total`](https://github.com/coreos/etcd/pull/8390) on restore.
|
||||
- Fix [`etcd_debugging_mvcc_db_total_size_in_bytes`](https://github.com/coreos/etcd/pull/8120) on restore.
|
||||
- Also change to [`prometheus.NewGaugeFunc`](https://github.com/coreos/etcd/pull/8150).
|
||||
- Fix [backend database in-memory index corruption](https://github.com/coreos/etcd/pull/8127) issue on restore (only 3.2.0 is affected).
|
||||
- Fix [watch restore from snapshot](https://github.com/coreos/etcd/pull/8427).
|
||||
- Fix ["put at-most-once" in `clientv3`](https://github.com/coreos/etcd/pull/8335).
|
||||
- Handle [empty key permission](https://github.com/coreos/etcd/pull/8514) in `etcdctl`.
|
||||
- [Fix server crash](https://github.com/coreos/etcd/pull/8010) on [invalid transaction request from gRPC gateway](https://github.com/coreos/etcd/issues/7889).
|
||||
- Fix [`clientv3.WatchResponse.Canceled`](https://github.com/coreos/etcd/pull/8283) on [compacted watch request](https://github.com/coreos/etcd/issues/8231).
|
||||
- Handle [WAL renaming failure on Windows](https://github.com/coreos/etcd/pull/8286).
|
||||
- Make [peer dial timeout longer](https://github.com/coreos/etcd/pull/8599).
|
||||
- See [coreos/etcd-operator#1300](https://github.com/coreos/etcd-operator/issues/1300) for more detail.
|
||||
- Make server [wait up to request time-out](https://github.com/coreos/etcd/pull/8267) with [pending RPCs](https://github.com/coreos/etcd/issues/8224).
|
||||
- Fix [`grpc.Server` panic on `GracefulStop`](https://github.com/coreos/etcd/pull/8987) with [TLS-enabled server](https://github.com/coreos/etcd/issues/8916).
|
||||
- Fix ["multiple peer URLs cannot start" issue](https://github.com/coreos/etcd/issues/8383).
|
||||
- Fix server-side auth so [concurrent auth operations do not return old revision error](https://github.com/coreos/etcd/pull/8442).
|
||||
- Fix [`concurrency/stm` `Put` with serializable snapshot](https://github.com/coreos/etcd/pull/8439).
|
||||
- Use store revision from first fetch to resolve write conflicts instead of modified revision.
|
||||
- Fix [`grpc-proxy` Snapshot API error handling](https://github.com/coreos/etcd/commit/dbd16d52fbf81e5fd806d21ff5e9148d5bf203ab).
|
||||
- Fix [`grpc-proxy` KV API `PrevKv` flag handling](https://github.com/coreos/etcd/pull/8366).
|
||||
- Fix [`grpc-proxy` KV API `KeysOnly` flag handling](https://github.com/coreos/etcd/pull/8552).
|
||||
- Upgrade [`coreos/go-systemd`](https://github.com/coreos/go-systemd/releases) to `v15` (see https://github.com/coreos/go-systemd/releases/tag/v15).
|
||||
|
||||
### Other
|
||||
|
||||
- Support previous two minor versions (see our [new release policy](https://github.com/coreos/etcd/pull/8805)).
|
||||
- `v3.3.x` is the last release cycle that supports `ACI`:
|
||||
- AppC was [officially suspended](https://github.com/appc/spec#-disclaimer-), as of late 2016.
|
||||
- [`acbuild`](https://github.com/containers/build#this-project-is-currently-unmaintained) is not maintained anymore.
|
||||
- `*.aci` files won't be available from etcd `v3.4` release.
|
||||
- Add container registry [`gcr.io/etcd-development/etcd`](https://gcr.io/etcd-development/etcd).
|
||||
- [quay.io/coreos/etcd](https://quay.io/coreos/etcd) is still supported as secondary.
|
||||
|
||||
|
||||
## [v3.2.12](https://github.com/coreos/etcd/releases/tag/v3.2.12) (2017-12-20)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.11...v3.2.12) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix [error message of `Revision` compactor](https://github.com/coreos/etcd/pull/8999) in server-side.
|
||||
|
||||
### Added(`etcd/clientv3`,`etcdctl/v3`)
|
||||
|
||||
- Add [`MaxCallSendMsgSize` and `MaxCallRecvMsgSize`](https://github.com/coreos/etcd/pull/9047) fields to [`clientv3.Config`](https://godoc.org/github.com/coreos/etcd/clientv3#Config).
|
||||
- Fix [exceeded response size limit error in client-side](https://github.com/coreos/etcd/issues/9043).
|
||||
- Address [kubernetes#51099](https://github.com/kubernetes/kubernetes/issues/51099).
|
||||
- `MaxCallSendMsgSize` default value is 2 MiB, if not configured.
|
||||
- `MaxCallRecvMsgSize` default value is `math.MaxInt32`, if not configured.
|
||||
|
||||
### Other
|
||||
|
||||
- Pin [grpc v1.7.5](https://github.com/grpc/grpc-go/releases/tag/v1.7.5), [grpc-gateway v1.3.0](https://github.com/grpc-ecosystem/grpc-gateway/releases/tag/v1.3.0).
|
||||
- No code change, just to be explicit about recommended versions.
|
||||
|
||||
|
||||
## [v3.2.11](https://github.com/coreos/etcd/releases/tag/v3.2.11) (2017-12-05)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.10...v3.2.11) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix racey grpc-go's server handler transport `WriteStatus` call to prevent [TLS-enabled etcd server crash](https://github.com/coreos/etcd/issues/8904):
|
||||
- Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) `v1.7.3` to `v1.7.4`.
|
||||
- Add [gRPC RPC failure warnings](https://github.com/coreos/etcd/pull/8939) to help debug such issues in the future.
|
||||
- Remove `--listen-metrics-urls` flag in monitoring document (non-released in `v3.2.x`, planned for `v3.3.x`).
|
||||
|
||||
### Added
|
||||
|
||||
- Provide [more cert details](https://github.com/coreos/etcd/pull/8952/files) on TLS handshake failures.
|
||||
|
||||
|
||||
## [v3.1.11](https://github.com/coreos/etcd/releases/tag/v3.1.11) (2017-11-28)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.10...v3.1.11) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- [#8411](https://github.com/coreos/etcd/issues/8411),[#8806](https://github.com/coreos/etcd/pull/8806) mvcc: fix watch restore from snapshot
|
||||
- [#8009](https://github.com/coreos/etcd/issues/8009),[#8902](https://github.com/coreos/etcd/pull/8902) backport coreos/bbolt v1.3.1-coreos.5
|
||||
|
||||
|
||||
## [v3.2.10](https://github.com/coreos/etcd/releases/tag/v3.2.10) (2017-11-16)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.9...v3.2.10) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Replace backend key-value database `boltdb/bolt` with [`coreos/bbolt`](https://github.com/coreos/bbolt/releases) to address [backend database size issue](https://github.com/coreos/etcd/issues/8009).
|
||||
- Fix `clientv3` balancer to handle [network partitions](https://github.com/coreos/etcd/issues/8711):
|
||||
- Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) `v1.2.1` to `v1.7.3`.
|
||||
- Upgrade [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) `v1.2` to `v1.3`.
|
||||
- Revert [discovery SRV auth `ServerName` with `*.{ROOT_DOMAIN}`](https://github.com/coreos/etcd/pull/8651) to support non-wildcard subject alternative names in the certs (see [issue #8445](https://github.com/coreos/etcd/issues/8445) for more contexts).
|
||||
- For instance, `etcd --discovery-srv=etcd.local` will only authenticate peers/clients when the provided certs have root domain `etcd.local` (**not `*.etcd.local`**) as an entry in Subject Alternative Name (SAN) field.
|
||||
|
||||
|
||||
## [v3.2.9](https://github.com/coreos/etcd/releases/tag/v3.2.9) (2017-10-06)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.8...v3.2.9) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed(Security)
|
||||
|
||||
- Compile with [Go 1.8.4](https://groups.google.com/d/msg/golang-nuts/sHfMg4gZNps/a-HDgDDDAAAJ).
|
||||
- Update `golang.org/x/crypto/bcrypt` (see [golang/crypto@6c586e1](https://github.com/golang/crypto/commit/6c586e17d90a7d08bbbc4069984180dce3b04117)).
|
||||
- Fix discovery SRV bootstrapping to [authenticate `ServerName` with `*.{ROOT_DOMAIN}`](https://github.com/coreos/etcd/pull/8651), in order to support sub-domain wildcard matching (see [issue #8445](https://github.com/coreos/etcd/issues/8445) for more contexts).
|
||||
- For instance, `etcd --discovery-srv=etcd.local` will only authenticate peers/clients when the provided certs have root domain `*.etcd.local` as an entry in Subject Alternative Name (SAN) field.
|
||||
|
||||
|
||||
## [v3.2.8](https://github.com/coreos/etcd/releases/tag/v3.2.8) (2017-09-29)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.7...v3.2.8) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix v2 client failover to next endpoint on mutable operation.
|
||||
- Fix grpc-proxy to respect `KeysOnly` flag.
|
||||
|
||||
|
||||
## [v3.2.7](https://github.com/coreos/etcd/releases/tag/v3.2.7) (2017-09-01)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.6...v3.2.7) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix server-side auth so concurrent auth operations do not return old revision error.
|
||||
- Fix concurrency/stm Put with serializable snapshot
|
||||
- Use store revision from first fetch to resolve write conflicts instead of modified revision.
|
||||
|
||||
|
||||
## [v3.2.6](https://github.com/coreos/etcd/releases/tag/v3.2.6) (2017-08-21)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.5...v3.2.6).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix watch restore from snapshot.
|
||||
- Fix `etcd_debugging_mvcc_keys_total` inconsistency.
|
||||
- Fix multiple URLs for `--listen-peer-urls` flag.
|
||||
- Add `--enable-pprof` flag to etcd configuration file format.
|
||||
|
||||
|
||||
## [v3.2.5](https://github.com/coreos/etcd/releases/tag/v3.2.5) (2017-08-04)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.4...v3.2.5) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Use reverse lookup to match wildcard DNS SAN.
|
||||
- Return non-zero exit code on unhealthy `endpoint health`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix unreachable /metrics endpoint when `--enable-v2=false`.
|
||||
- Fix grpc-proxy to respect `PrevKv` flag.
|
||||
|
||||
### Added
|
||||
|
||||
- Add container registry `gcr.io/etcd-development/etcd`.
|
||||
|
||||
|
||||
## [v3.2.4](https://github.com/coreos/etcd/releases/tag/v3.2.4) (2017-07-19)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.3...v3.2.4) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Do not block on active client stream when stopping server
|
||||
- Fix gRPC proxy Snapshot RPC error handling
|
||||
|
||||
|
||||
## [v3.2.3](https://github.com/coreos/etcd/releases/tag/v3.2.3) (2017-07-14)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.2...v3.2.3) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Let clients establish unlimited streams
|
||||
|
||||
### Added
|
||||
|
||||
- Tag docker images with minor versions
|
||||
- e.g. `docker pull quay.io/coreos/etcd:v3.2` to fetch latest v3.2 versions
|
||||
|
||||
|
||||
## [v3.1.10](https://github.com/coreos/etcd/releases/tag/v3.1.10) (2017-07-14)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.9...v3.1.10) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Compile with Go 1.8.3 to fix panic on `net/http.CloseNotify`
|
||||
|
||||
### Added
|
||||
|
||||
- Tag docker images with minor versions.
|
||||
- e.g. `docker pull quay.io/coreos/etcd:v3.1` to fetch latest v3.1 versions.
|
||||
|
||||
|
||||
## [v3.2.2](https://github.com/coreos/etcd/releases/tag/v3.2.2) (2017-07-07)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.1...v3.2.2) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Improved
|
||||
|
||||
- Rate-limit lease revoke on expiration.
|
||||
- Extend leases on promote to avoid queueing effect on lease expiration.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Use user-provided listen address to connect to gRPC gateway:
|
||||
- `net.Listener` rewrites IPv4 0.0.0.0 to IPv6 [::], breaking IPv6 disabled hosts.
|
||||
- Only v3.2.0, v3.2.1 are affected.
|
||||
- Accept connection with matched IP SAN but no DNS match.
|
||||
- Don't check DNS entries in certs if there's a matching IP.
|
||||
- Fix 'tools/benchmark' watch command.
|
||||
|
||||
|
||||
## [v3.2.1](https://github.com/coreos/etcd/releases/tag/v3.2.1) (2017-06-23)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.2.0...v3.2.1) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix backend database in-memory index corruption issue on restore (only 3.2.0 is affected).
|
||||
- Fix gRPC gateway Txn marshaling issue.
|
||||
- Fix backend database size debugging metrics.
|
||||
|
||||
|
||||
## [v3.2.0](https://github.com/coreos/etcd/releases/tag/v3.2.0) (2017-06-09)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.0...v3.2.0) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes.
|
||||
|
||||
### Improved
|
||||
|
||||
- Improve backend read concurrency.
|
||||
|
||||
### Added
|
||||
|
||||
- Embedded etcd
|
||||
- `Etcd.Peers` field is now `[]*peerListener`.
|
||||
- RPCs
|
||||
- Add Election, Lock service.
|
||||
- Native client etcdserver/api/v3client
|
||||
- client "embedded" in the server.
|
||||
- gRPC proxy
|
||||
- Proxy endpoint discovery.
|
||||
- Namespaces.
|
||||
- Coalesce lease requests.
|
||||
- v3 client
|
||||
- STM prefetching.
|
||||
- Add namespace feature.
|
||||
- Add `ErrOldCluster` with server version checking.
|
||||
- Translate `WithPrefix()` into `WithFromKey()` for empty key.
|
||||
- v3 etcdctl
|
||||
- Add `check perf` command.
|
||||
- Add `--from-key` flag to role grant-permission command.
|
||||
- `lock` command takes an optional command to execute.
|
||||
- etcd flags
|
||||
- Add `--enable-v2` flag to configure v2 backend (enabled by default).
|
||||
- Add `--auth-token` flag.
|
||||
- `etcd gateway`
|
||||
- Support DNS SRV priority.
|
||||
- Auth
|
||||
- Support Watch API.
|
||||
- JWT tokens.
|
||||
- Logging, monitoring
|
||||
- Server warns large snapshot operations.
|
||||
- Add `etcd_debugging_server_lease_expired_total` metrics.
|
||||
- Security
|
||||
- Deny incoming peer certs with wrong IP SAN.
|
||||
- Resolve TLS `DNSNames` when SAN checking.
|
||||
- Reload TLS certificates on every client connection.
|
||||
- Release
|
||||
- Annotate acbuild with supports-systemd-notify.
|
||||
- Add `nsswitch.conf` to Docker container image.
|
||||
- Add ppc64le, arm64(experimental) builds.
|
||||
- Compile with `Go 1.8.3`.
|
||||
|
||||
### Changed
|
||||
|
||||
- v3 client
|
||||
- `LeaseTimeToLive` returns TTL=-1 resp on lease not found.
|
||||
- `clientv3.NewFromConfigFile` is moved to `clientv3/yaml.NewConfig`.
|
||||
- concurrency package's elections updated to match RPC interfaces.
|
||||
- let client dial endpoints not in the balancer.
|
||||
- Dependencies
|
||||
- Update [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) to `v1.2.1`.
|
||||
- Update [`github.com/grpc-ecosystem/grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway/releases) to `v1.2.0`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Allow v2 snapshot over 512MB.
|
||||
|
||||
|
||||
## [v3.1.9](https://github.com/coreos/etcd/releases/tag/v3.1.9) (2017-06-09)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.8...v3.1.9) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Allow v2 snapshot over 512MB.
|
||||
|
||||
|
||||
## [v3.1.8](https://github.com/coreos/etcd/releases/tag/v3.1.8) (2017-05-19)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.7...v3.1.8) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.1.7](https://github.com/coreos/etcd/releases/tag/v3.1.7) (2017-04-28)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.6...v3.1.7) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.1.6](https://github.com/coreos/etcd/releases/tag/v3.1.6) (2017-04-19)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.5...v3.1.6) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Remove auth check in Status API.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fill in Auth API response header.
|
||||
|
||||
|
||||
## [v3.1.5](https://github.com/coreos/etcd/releases/tag/v3.1.5) (2017-03-27)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.4...v3.1.5) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
### Added
|
||||
|
||||
- Add `/etc/nsswitch.conf` file to alpine-based Docker image.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix raft memory leak issue.
|
||||
- Fix Windows file path issues.
|
||||
|
||||
|
||||
## [v3.1.4](https://github.com/coreos/etcd/releases/tag/v3.1.4) (2017-03-22)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.3...v3.1.4) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.1.3](https://github.com/coreos/etcd/releases/tag/v3.1.3) (2017-03-10)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.2...v3.1.3) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Use machine default host when advertise URLs are default values(`localhost:2379,2380`) AND if listen URL is `0.0.0.0`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `etcd gateway` schema handling in DNS discovery.
|
||||
- Fix sd_notify behaviors in `gateway`, `grpc-proxy`.
|
||||
|
||||
|
||||
## [v3.1.2](https://github.com/coreos/etcd/releases/tag/v3.1.2) (2017-02-24)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.1...v3.1.2) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Use IPv4 default host, by default (when IPv4 and IPv6 are available).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `etcd gateway` with multiple endpoints.
|
||||
|
||||
|
||||
## [v3.1.1](https://github.com/coreos/etcd/releases/tag/v3.1.1) (2017-02-17)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.1.0...v3.1.1) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Compile with `Go 1.7.5`.
|
||||
|
||||
|
||||
## [v2.3.8](https://github.com/coreos/etcd/releases/tag/v2.3.8) (2017-02-17)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v2.3.7...v2.3.8).
|
||||
|
||||
### Changed
|
||||
|
||||
- Compile with `Go 1.7.5`.
|
||||
|
||||
|
||||
## [v3.1.0](https://github.com/coreos/etcd/releases/tag/v3.1.0) (2017-01-20)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.0...v3.1.0) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes.
|
||||
|
||||
### Improved
|
||||
|
||||
- Faster linearizable reads (implements Raft read-index).
|
||||
- v3 authentication API is now stable.
|
||||
|
||||
### Added
|
||||
|
||||
- Automatic leadership transfer when leader steps down.
|
||||
- etcd flags
|
||||
- `--strict-reconfig-check` flag is set by default.
|
||||
- Add `--log-output` flag.
|
||||
- Add `--metrics` flag.
|
||||
- v3 client
|
||||
- Add `SetEndpoints` method; update endpoints at runtime.
|
||||
- Add `Sync` method; auto-update endpoints at runtime.
|
||||
- Add `Lease TimeToLive` API; fetch lease information.
|
||||
- replace Config.Logger field with global logger.
|
||||
- Get API responses are sorted in ascending order by default.
|
||||
- v3 etcdctl
|
||||
- Add `lease timetolive` command.
|
||||
- Add `--print-value-only` flag to get command.
|
||||
- Add `--dest-prefix` flag to make-mirror command.
|
||||
- `get` command responses are sorted in ascending order by default.
|
||||
- `recipes` now conform to sessions defined in `clientv3/concurrency`.
|
||||
- ACI has symlinks to `/usr/local/bin/etcd*`.
|
||||
- Experimental gRPC proxy feature.
|
||||
|
||||
### Changed
|
||||
|
||||
- Deprecated following gRPC metrics in favor of [go-grpc-prometheus](https://github.com/grpc-ecosystem/go-grpc-prometheus):
|
||||
- `etcd_grpc_requests_total`
|
||||
- `etcd_grpc_requests_failed_total`
|
||||
- `etcd_grpc_active_streams`
|
||||
- `etcd_grpc_unary_requests_duration_seconds`
|
||||
- etcd uses default route IP if advertise URL is not given.
|
||||
- Cluster rejects removing members if quorum will be lost.
|
||||
- SRV records (e.g., infra1.example.com) must match the discovery domain (i.e., example.com) if no custom certificate authority is given.
|
||||
- `TLSConfig.ServerName` is ignored with user-provided certificates for backwards compatibility; to be deprecated.
|
||||
- For example, `etcd --discovery-srv=example.com` will only authenticate peers/clients when the provided certs have root domain `example.com` as an entry in Subject Alternative Name (SAN) field.
|
||||
- Discovery now has upper limit for waiting on retries.
|
||||
- Warn on binding listeners through domain names; to be deprecated.
|
||||
|
||||
|
||||
## [v3.0.16](https://github.com/coreos/etcd/releases/tag/v3.0.16) (2016-11-13)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.15...v3.0.16) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.0.15](https://github.com/coreos/etcd/releases/tag/v3.0.15) (2016-11-11)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.14...v3.0.15) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix cancel watch request with wrong range end.
|
||||
|
||||
|
||||
## [v3.0.14](https://github.com/coreos/etcd/releases/tag/v3.0.14) (2016-11-04)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.13...v3.0.14) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Added
|
||||
|
||||
- v3 `etcdctl migrate` command now supports `--no-ttl` flag to discard keys on transform.
|
||||
|
||||
|
||||
## [v3.0.13](https://github.com/coreos/etcd/releases/tag/v3.0.13) (2016-10-24)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.12...v3.0.13) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.0.12](https://github.com/coreos/etcd/releases/tag/v3.0.12) (2016-10-07)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.11...v3.0.12) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.0.11](https://github.com/coreos/etcd/releases/tag/v3.0.11) (2016-10-07)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.10...v3.0.11) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Added
|
||||
|
||||
- Server returns previous key-value (optional)
|
||||
- `clientv3.WithPrevKV` option
|
||||
- v3 etcdctl `put,watch,del --prev-kv` flag
|
||||
|
||||
|
||||
## [v3.0.10](https://github.com/coreos/etcd/releases/tag/v3.0.10) (2016-09-23)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.9...v3.0.10) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.0.9](https://github.com/coreos/etcd/releases/tag/v3.0.9) (2016-09-15)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.8...v3.0.9) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Added
|
||||
|
||||
- Warn on domain names on listen URLs (v3.2 will reject domain names).
|
||||
|
||||
|
||||
## [v3.0.8](https://github.com/coreos/etcd/releases/tag/v3.0.8) (2016-09-09)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.7...v3.0.8) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Allow only IP addresses in listen URLs (domain names are rejected).
|
||||
|
||||
|
||||
## [v3.0.7](https://github.com/coreos/etcd/releases/tag/v3.0.7) (2016-08-31)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.6...v3.0.7) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- SRV records only allow A records (RFC 2052).
|
||||
|
||||
|
||||
## [v3.0.6](https://github.com/coreos/etcd/releases/tag/v3.0.6) (2016-08-19)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.5...v3.0.6) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.0.5](https://github.com/coreos/etcd/releases/tag/v3.0.5) (2016-08-19)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.4...v3.0.5) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- SRV records (e.g., infra1.example.com) must match the discovery domain (i.e., example.com) if no custom certificate authority is given.
|
||||
|
||||
|
||||
## [v3.0.4](https://github.com/coreos/etcd/releases/tag/v3.0.4) (2016-07-27)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.3...v3.0.4) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- v2 auth can now use common name from TLS certificate when `--client-cert-auth` is enabled.
|
||||
|
||||
### Added
|
||||
|
||||
- v2 `etcdctl ls` command now supports `--output=json`.
|
||||
- Add /var/lib/etcd directory to etcd official Docker image.
|
||||
|
||||
|
||||
## [v3.0.3](https://github.com/coreos/etcd/releases/tag/v3.0.3) (2016-07-15)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.2...v3.0.3) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Revert Dockerfile to use `CMD`, instead of `ENTRYPOINT`, to support `etcdctl` run.
|
||||
- Docker commands for v3.0.2 won't work without specifying executable binary paths.
|
||||
- v3 etcdctl default endpoints are now `127.0.0.1:2379`.
|
||||
|
||||
|
||||
## [v3.0.2](https://github.com/coreos/etcd/releases/tag/v3.0.2) (2016-07-08)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.1...v3.0.2) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
### Changed
|
||||
|
||||
- Dockerfile uses `ENTRYPOINT`, instead of `CMD`, to run etcd without binary path specified.
|
||||
|
||||
|
||||
## [v3.0.1](https://github.com/coreos/etcd/releases/tag/v3.0.1) (2016-07-01)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v3.0.0...v3.0.1) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
||||
|
||||
|
||||
## [v3.0.0](https://github.com/coreos/etcd/releases/tag/v3.0.0) (2016-06-30)
|
||||
|
||||
See [code changes](https://github.com/coreos/etcd/compare/v2.3.0...v3.0.0) and [v3.0 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md) for any breaking changes.
|
63
vendor/go.etcd.io/etcd/CODE_OF_CONDUCT.md
generated
vendored
63
vendor/go.etcd.io/etcd/CODE_OF_CONDUCT.md
generated
vendored
@ -1,63 +0,0 @@
|
||||
## CoreOS Community Code of Conduct
|
||||
|
||||
### Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of
|
||||
fostering an open and welcoming community, we pledge to respect all people who
|
||||
contribute through reporting issues, posting feature requests, updating
|
||||
documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free
|
||||
experience for everyone, regardless of level of experience, gender, gender
|
||||
identity and expression, sexual orientation, disability, personal appearance,
|
||||
body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as physical or electronic addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct. By adopting this Code of Conduct,
|
||||
project maintainers commit themselves to fairly and consistently applying these
|
||||
principles to every aspect of managing this project. Project maintainers who do
|
||||
not follow or enforce the Code of Conduct may be permanently removed from the
|
||||
project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting a project maintainer, Brandon Philips
|
||||
<brandon.philips@coreos.com>, and/or Meghan Schofield
|
||||
<meghan.schofield@coreos.com>.
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant
|
||||
(http://contributor-covenant.org), version 1.2.0, available at
|
||||
http://contributor-covenant.org/version/1/2/0/
|
||||
|
||||
### CoreOS Events Code of Conduct
|
||||
|
||||
CoreOS events are working conferences intended for professional networking and
|
||||
collaboration in the CoreOS community. Attendees are expected to behave
|
||||
according to professional standards and in accordance with their employer’s
|
||||
policies on appropriate workplace behavior.
|
||||
|
||||
While at CoreOS events or related social networking opportunities, attendees
|
||||
should not engage in discriminatory or offensive speech or actions including
|
||||
but not limited to gender, sexuality, race, age, disability, or religion.
|
||||
Speakers should be especially aware of these concerns.
|
||||
|
||||
CoreOS does not condone any statements by speakers contrary to these standards.
|
||||
CoreOS reserves the right to deny entrance and/or eject from an event (without
|
||||
refund) any individual found to be engaging in discriminatory or offensive
|
||||
speech or actions.
|
||||
|
||||
Please bring any concerns to the immediate attention of designated on-site
|
||||
staff, Brandon Philips <brandon.philips@coreos.com>, and/or Meghan Schofield
|
||||
<meghan.schofield@coreos.com>.
|
62
vendor/go.etcd.io/etcd/CONTRIBUTING.md
generated
vendored
62
vendor/go.etcd.io/etcd/CONTRIBUTING.md
generated
vendored
@ -1,62 +0,0 @@
|
||||
# How to contribute
|
||||
|
||||
etcd is Apache 2.0 licensed and accepts contributions via GitHub pull requests. This document outlines some of the conventions on commit message formatting, contact points for developers, and other resources to help get contributions into etcd.
|
||||
|
||||
# Email and chat
|
||||
|
||||
- Email: [etcd-dev](https://groups.google.com/forum/?hl=en#!forum/etcd-dev)
|
||||
- IRC: #[etcd](irc://irc.freenode.org:6667/#etcd) IRC channel on freenode.org
|
||||
|
||||
## Getting started
|
||||
|
||||
- Fork the repository on GitHub
|
||||
- Read the README.md for build instructions
|
||||
|
||||
## Reporting bugs and creating issues
|
||||
|
||||
Reporting bugs is one of the best ways to contribute. However, a good bug report has some very specific qualities, so please read over our short document on [reporting bugs](https://github.com/coreos/etcd/blob/master/Documentation/reporting_bugs.md) before submitting a bug report. This document might contain links to known issues, another good reason to take a look there before reporting a bug.
|
||||
|
||||
## Contribution flow
|
||||
|
||||
This is a rough outline of what a contributor's workflow looks like:
|
||||
|
||||
- Create a topic branch from where to base the contribution. This is usually master.
|
||||
- Make commits of logical units.
|
||||
- Make sure commit messages are in the proper format (see below).
|
||||
- Push changes in a topic branch to a personal fork of the repository.
|
||||
- Submit a pull request to coreos/etcd.
|
||||
- The PR must receive a LGTM from two maintainers found in the MAINTAINERS file.
|
||||
|
||||
Thanks for contributing!
|
||||
|
||||
### Code style
|
||||
|
||||
The coding style suggested by the Golang community is used in etcd. See the [style doc](https://github.com/golang/go/wiki/CodeReviewComments) for details.
|
||||
|
||||
Please follow this style to make etcd easy to review, maintain and develop.
|
||||
|
||||
### Format of the commit message
|
||||
|
||||
We follow a rough convention for commit messages that is designed to answer two
|
||||
questions: what changed and why. The subject line should feature the what and
|
||||
the body of the commit should describe the why.
|
||||
|
||||
```
|
||||
scripts: add the test-cluster command
|
||||
|
||||
this uses tmux to setup a test cluster that can easily be killed and started for debugging.
|
||||
|
||||
Fixes #38
|
||||
```
|
||||
|
||||
The format can be described more formally as follows:
|
||||
|
||||
```
|
||||
<subsystem>: <what changed>
|
||||
<BLANK LINE>
|
||||
<why this change was made>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The first line is the subject and should be no longer than 70 characters, the second line is always blank, and other lines should be wrapped at 80 characters. This allows the message to be easier to read on GitHub as well as in various git tools.
|
36
vendor/go.etcd.io/etcd/DCO
generated
vendored
36
vendor/go.etcd.io/etcd/DCO
generated
vendored
@ -1,36 +0,0 @@
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
6
vendor/go.etcd.io/etcd/Dockerfile
generated
vendored
6
vendor/go.etcd.io/etcd/Dockerfile
generated
vendored
@ -1,6 +0,0 @@
|
||||
FROM golang
|
||||
ADD . /go/src/github.com/coreos/etcd
|
||||
ADD cmd/vendor /go/src/github.com/coreos/etcd/vendor
|
||||
RUN go install github.com/coreos/etcd
|
||||
EXPOSE 2379 2380
|
||||
ENTRYPOINT ["etcd"]
|
53
vendor/go.etcd.io/etcd/Dockerfile-functional-tester
generated
vendored
53
vendor/go.etcd.io/etcd/Dockerfile-functional-tester
generated
vendored
@ -1,53 +0,0 @@
|
||||
FROM ubuntu:17.10
|
||||
|
||||
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
|
||||
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
|
||||
|
||||
RUN apt-get -y update \
|
||||
&& apt-get -y install \
|
||||
build-essential \
|
||||
gcc \
|
||||
apt-utils \
|
||||
pkg-config \
|
||||
software-properties-common \
|
||||
apt-transport-https \
|
||||
libssl-dev \
|
||||
sudo \
|
||||
bash \
|
||||
curl \
|
||||
wget \
|
||||
tar \
|
||||
git \
|
||||
&& apt-get -y update \
|
||||
&& apt-get -y upgrade \
|
||||
&& apt-get -y autoremove \
|
||||
&& apt-get -y autoclean
|
||||
|
||||
ENV GOROOT /usr/local/go
|
||||
ENV GOPATH /go
|
||||
ENV PATH ${GOPATH}/bin:${GOROOT}/bin:${PATH}
|
||||
ENV GO_VERSION REPLACE_ME_GO_VERSION
|
||||
ENV GO_DOWNLOAD_URL https://storage.googleapis.com/golang
|
||||
RUN rm -rf ${GOROOT} \
|
||||
&& curl -s ${GO_DOWNLOAD_URL}/go${GO_VERSION}.linux-amd64.tar.gz | tar -v -C /usr/local/ -xz \
|
||||
&& mkdir -p ${GOPATH}/src ${GOPATH}/bin \
|
||||
&& go version
|
||||
|
||||
RUN mkdir -p ${GOPATH}/src/github.com/coreos/etcd
|
||||
ADD . ${GOPATH}/src/github.com/coreos/etcd
|
||||
|
||||
RUN go get -v github.com/coreos/gofail \
|
||||
&& pushd ${GOPATH}/src/github.com/coreos/etcd \
|
||||
&& GO_BUILD_FLAGS="-v" ./build \
|
||||
&& cp ./bin/etcd /etcd \
|
||||
&& cp ./bin/etcdctl /etcdctl \
|
||||
&& GO_BUILD_FLAGS="-v" FAILPOINTS=1 ./build \
|
||||
&& cp ./bin/etcd /etcd-failpoints \
|
||||
&& ./tools/functional-tester/build \
|
||||
&& cp ./bin/etcd-agent /etcd-agent \
|
||||
&& cp ./bin/etcd-tester /etcd-tester \
|
||||
&& cp ./bin/etcd-runner /etcd-runner \
|
||||
&& go build -v -o /benchmark ./cmd/tools/benchmark \
|
||||
&& go build -v -o /etcd-test-proxy ./cmd/tools/etcd-test-proxy \
|
||||
&& popd \
|
||||
&& rm -rf ${GOPATH}/src/github.com/coreos/etcd
|
17
vendor/go.etcd.io/etcd/Dockerfile-release
generated
vendored
17
vendor/go.etcd.io/etcd/Dockerfile-release
generated
vendored
@ -1,17 +0,0 @@
|
||||
FROM alpine:latest
|
||||
|
||||
ADD etcd /usr/local/bin/
|
||||
ADD etcdctl /usr/local/bin/
|
||||
RUN mkdir -p /var/etcd/
|
||||
RUN mkdir -p /var/lib/etcd/
|
||||
|
||||
# Alpine Linux doesn't use pam, which means that there is no /etc/nsswitch.conf,
|
||||
# but Golang relies on /etc/nsswitch.conf to check the order of DNS resolving
|
||||
# (see https://github.com/golang/go/commit/9dee7771f561cf6aee081c0af6658cc81fac3918)
|
||||
# To fix this we just create /etc/nsswitch.conf and add the following line:
|
||||
RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
|
||||
|
||||
EXPOSE 2379 2380
|
||||
|
||||
# Define default command.
|
||||
CMD ["/usr/local/bin/etcd"]
|
11
vendor/go.etcd.io/etcd/Dockerfile-release.arm64
generated
vendored
11
vendor/go.etcd.io/etcd/Dockerfile-release.arm64
generated
vendored
@ -1,11 +0,0 @@
|
||||
FROM aarch64/ubuntu:16.04
|
||||
|
||||
ADD etcd /usr/local/bin/
|
||||
ADD etcdctl /usr/local/bin/
|
||||
ADD var/etcd /var/etcd
|
||||
ADD var/lib/etcd /var/lib/etcd
|
||||
|
||||
EXPOSE 2379 2380
|
||||
|
||||
# Define default command.
|
||||
CMD ["/usr/local/bin/etcd"]
|
11
vendor/go.etcd.io/etcd/Dockerfile-release.ppc64le
generated
vendored
11
vendor/go.etcd.io/etcd/Dockerfile-release.ppc64le
generated
vendored
@ -1,11 +0,0 @@
|
||||
FROM ppc64le/ubuntu:16.04
|
||||
|
||||
ADD etcd /usr/local/bin/
|
||||
ADD etcdctl /usr/local/bin/
|
||||
ADD var/etcd /var/etcd
|
||||
ADD var/lib/etcd /var/lib/etcd
|
||||
|
||||
EXPOSE 2379 2380
|
||||
|
||||
# Define default command.
|
||||
CMD ["/usr/local/bin/etcd"]
|
58
vendor/go.etcd.io/etcd/Dockerfile-test
generated
vendored
58
vendor/go.etcd.io/etcd/Dockerfile-test
generated
vendored
@ -1,58 +0,0 @@
|
||||
FROM ubuntu:16.10
|
||||
|
||||
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
|
||||
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
|
||||
|
||||
RUN apt-get -y update \
|
||||
&& apt-get -y install \
|
||||
build-essential \
|
||||
gcc \
|
||||
apt-utils \
|
||||
pkg-config \
|
||||
software-properties-common \
|
||||
apt-transport-https \
|
||||
libssl-dev \
|
||||
sudo \
|
||||
bash \
|
||||
curl \
|
||||
wget \
|
||||
tar \
|
||||
git \
|
||||
netcat \
|
||||
libaspell-dev \
|
||||
libhunspell-dev \
|
||||
hunspell-en-us \
|
||||
aspell-en \
|
||||
shellcheck \
|
||||
&& apt-get -y update \
|
||||
&& apt-get -y upgrade \
|
||||
&& apt-get -y autoremove \
|
||||
&& apt-get -y autoclean
|
||||
|
||||
ENV GOROOT /usr/local/go
|
||||
ENV GOPATH /go
|
||||
ENV PATH ${GOPATH}/bin:${GOROOT}/bin:${PATH}
|
||||
ENV GO_VERSION REPLACE_ME_GO_VERSION
|
||||
ENV GO_DOWNLOAD_URL https://storage.googleapis.com/golang
|
||||
RUN rm -rf ${GOROOT} \
|
||||
&& curl -s ${GO_DOWNLOAD_URL}/go${GO_VERSION}.linux-amd64.tar.gz | tar -v -C /usr/local/ -xz \
|
||||
&& mkdir -p ${GOPATH}/src ${GOPATH}/bin \
|
||||
&& go version
|
||||
|
||||
RUN mkdir -p ${GOPATH}/src/github.com/coreos/etcd
|
||||
WORKDIR ${GOPATH}/src/github.com/coreos/etcd
|
||||
|
||||
ADD ./scripts/install-marker.sh /tmp/install-marker.sh
|
||||
|
||||
RUN go get -v -u -tags spell github.com/chzchzchz/goword \
|
||||
&& go get -v -u github.com/coreos/license-bill-of-materials \
|
||||
&& go get -v -u honnef.co/go/tools/cmd/gosimple \
|
||||
&& go get -v -u honnef.co/go/tools/cmd/unused \
|
||||
&& go get -v -u honnef.co/go/tools/cmd/staticcheck \
|
||||
&& go get -v -u github.com/gyuho/gocovmerge \
|
||||
&& go get -v -u github.com/gordonklaus/ineffassign \
|
||||
&& go get -v -u github.com/alexkohler/nakedret \
|
||||
&& /tmp/install-marker.sh amd64 \
|
||||
&& rm -f /tmp/install-marker.sh \
|
||||
&& curl -s https://codecov.io/bash >/codecov \
|
||||
&& chmod 700 /codecov
|
8
vendor/go.etcd.io/etcd/MAINTAINERS
generated
vendored
8
vendor/go.etcd.io/etcd/MAINTAINERS
generated
vendored
@ -1,8 +0,0 @@
|
||||
Anthony Romano <anthony.romano@coreos.com> (@heyitsanthony) pkg:*
|
||||
Brandon Philips <brandon.philips@coreos.com> (@philips) pkg:*
|
||||
Fanmin Shi <fanmin.shi@coreos.com> (@fanminshi) pkg:*
|
||||
Gyu-Ho Lee <gyu_ho.lee@coreos.com> (@gyuho) pkg:*
|
||||
Xiang Li <xiang.li@coreos.com> (@xiang90) pkg:*
|
||||
|
||||
Ben Darnell <ben@cockroachlabs.com> (@bdarnell) pkg:github.com/coreos/etcd/raft
|
||||
Hitoshi Mitake <mitake.hitoshi@lab.ntt.co.jp> (@mitake) pkg:github.com/coreos/etcd/auth
|
517
vendor/go.etcd.io/etcd/Makefile
generated
vendored
517
vendor/go.etcd.io/etcd/Makefile
generated
vendored
@ -1,517 +0,0 @@
|
||||
# run from repository root
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
# make build
|
||||
# make clean
|
||||
# make docker-clean
|
||||
# make docker-start
|
||||
# make docker-kill
|
||||
# make docker-remove
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
GO_BUILD_FLAGS="-v" ./build
|
||||
./bin/etcd --version
|
||||
ETCDCTL_API=3 ./bin/etcdctl version
|
||||
|
||||
clean:
|
||||
rm -f ./codecov
|
||||
rm -rf ./agent-*
|
||||
rm -rf ./covdir
|
||||
rm -f ./*.coverprofile
|
||||
rm -f ./*.log
|
||||
rm -f ./bin/Dockerfile-release
|
||||
rm -rf ./bin/*.etcd
|
||||
rm -rf ./default.etcd
|
||||
rm -rf ./tests/e2e/default.etcd
|
||||
rm -rf ./gopath
|
||||
rm -rf ./gopath.proto
|
||||
rm -rf ./release
|
||||
rm -f ./snapshot/localhost:*
|
||||
rm -f ./integration/127.0.0.1:* ./integration/localhost:*
|
||||
rm -f ./clientv3/integration/127.0.0.1:* ./clientv3/integration/localhost:*
|
||||
rm -f ./clientv3/ordering/127.0.0.1:* ./clientv3/ordering/localhost:*
|
||||
|
||||
docker-clean:
|
||||
docker images
|
||||
docker image prune --force
|
||||
|
||||
docker-start:
|
||||
service docker restart
|
||||
|
||||
docker-kill:
|
||||
docker kill `docker ps -q` || true
|
||||
|
||||
docker-remove:
|
||||
docker rm --force `docker ps -a -q` || true
|
||||
docker rmi --force `docker images -q` || true
|
||||
|
||||
|
||||
|
||||
GO_VERSION ?= 1.10.3
|
||||
ETCD_VERSION ?= $(shell git rev-parse --short HEAD || echo "GitNotFound")
|
||||
|
||||
TEST_SUFFIX = $(shell date +%s | base64 | head -c 15)
|
||||
TEST_OPTS ?= PASSES='unit'
|
||||
|
||||
TMP_DIR_MOUNT_FLAG = --mount type=tmpfs,destination=/tmp
|
||||
ifdef HOST_TMP_DIR
|
||||
TMP_DIR_MOUNT_FLAG = --mount type=bind,source=$(HOST_TMP_DIR),destination=/tmp
|
||||
endif
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
# GO_VERSION=1.8.7 make build-docker-test
|
||||
# make build-docker-test
|
||||
#
|
||||
# gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io
|
||||
# GO_VERSION=1.8.7 make push-docker-test
|
||||
# make push-docker-test
|
||||
#
|
||||
# gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
|
||||
# make pull-docker-test
|
||||
|
||||
build-docker-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./tests/Dockerfile
|
||||
docker build \
|
||||
--tag gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
|
||||
--file ./tests/Dockerfile .
|
||||
@mv ./tests/Dockerfile.bak ./tests/Dockerfile
|
||||
|
||||
push-docker-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
gcloud docker -- push gcr.io/etcd-development/etcd-test:go$(GO_VERSION)
|
||||
|
||||
pull-docker-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
docker pull gcr.io/etcd-development/etcd-test:go$(GO_VERSION)
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
# make build-docker-test
|
||||
# make compile-with-docker-test
|
||||
# make compile-setup-gopath-with-docker-test
|
||||
|
||||
compile-with-docker-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
docker run \
|
||||
--rm \
|
||||
--mount type=bind,source=`pwd`,destination=/go/src/github.com/coreos/etcd \
|
||||
gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "GO_BUILD_FLAGS=-v ./build && ./bin/etcd --version"
|
||||
|
||||
compile-setup-gopath-with-docker-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
docker run \
|
||||
--rm \
|
||||
--mount type=bind,source=`pwd`,destination=/etcd \
|
||||
gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && ETCD_SETUP_GOPATH=1 GO_BUILD_FLAGS=-v ./build && ./bin/etcd --version && rm -rf ./gopath"
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
#
|
||||
# Local machine:
|
||||
# TEST_OPTS="PASSES='fmt'" make test
|
||||
# TEST_OPTS="PASSES='fmt bom dep build unit'" make test
|
||||
# TEST_OPTS="PASSES='build unit release integration_e2e functional'" make test
|
||||
# TEST_OPTS="PASSES='build grpcproxy'" make test
|
||||
#
|
||||
# Example (test with docker):
|
||||
# make pull-docker-test
|
||||
# TEST_OPTS="PASSES='fmt'" make docker-test
|
||||
# TEST_OPTS="VERBOSE=2 PASSES='unit'" make docker-test
|
||||
#
|
||||
# Travis CI (test with docker):
|
||||
# TEST_OPTS="PASSES='fmt bom dep build unit'" make docker-test
|
||||
#
|
||||
# Semaphore CI (test with docker):
|
||||
# TEST_OPTS="PASSES='build unit release integration_e2e functional'" make docker-test
|
||||
# HOST_TMP_DIR=/tmp TEST_OPTS="PASSES='build unit release integration_e2e functional'" make docker-test
|
||||
# TEST_OPTS="GOARCH=386 PASSES='build unit integration_e2e'" make docker-test
|
||||
#
|
||||
# grpc-proxy tests (test with docker):
|
||||
# TEST_OPTS="PASSES='build grpcproxy'" make docker-test
|
||||
# HOST_TMP_DIR=/tmp TEST_OPTS="PASSES='build grpcproxy'" make docker-test
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
$(info TEST_OPTS: $(TEST_OPTS))
|
||||
$(info log-file: test-$(TEST_SUFFIX).log)
|
||||
$(TEST_OPTS) ./test 2>&1 | tee test-$(TEST_SUFFIX).log
|
||||
! egrep "(--- FAIL:|panic: test timed out|appears to have leaked)" -B50 -A10 test-$(TEST_SUFFIX).log
|
||||
|
||||
docker-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info ETCD_VERSION: $(ETCD_VERSION))
|
||||
$(info TEST_OPTS: $(TEST_OPTS))
|
||||
$(info log-file: test-$(TEST_SUFFIX).log)
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`,destination=/go/src/github.com/coreos/etcd \
|
||||
gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "$(TEST_OPTS) ./test 2>&1 | tee test-$(TEST_SUFFIX).log"
|
||||
! egrep "(--- FAIL:|panic: test timed out|appears to have leaked)" -B50 -A10 test-$(TEST_SUFFIX).log
|
||||
|
||||
docker-test-coverage:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info ETCD_VERSION: $(ETCD_VERSION))
|
||||
$(info log-file: docker-test-coverage-$(TEST_SUFFIX).log)
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`,destination=/go/src/github.com/coreos/etcd \
|
||||
gcr.io/etcd-development/etcd-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "COVERDIR=covdir PASSES='build build_cov cov' ./test 2>&1 | tee docker-test-coverage-$(TEST_SUFFIX).log && /codecov -t 6040de41-c073-4d6f-bbf8-d89256ef31e1"
|
||||
! egrep "(--- FAIL:|panic: test timed out|appears to have leaked)" -B50 -A10 docker-test-coverage-$(TEST_SUFFIX).log
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
# make compile-with-docker-test
|
||||
# ETCD_VERSION=v3-test make build-docker-release-master
|
||||
# ETCD_VERSION=v3-test make push-docker-release-master
|
||||
# gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
|
||||
|
||||
build-docker-release-master:
|
||||
$(info ETCD_VERSION: $(ETCD_VERSION))
|
||||
cp ./Dockerfile-release ./bin/Dockerfile-release
|
||||
docker build \
|
||||
--tag gcr.io/etcd-development/etcd:$(ETCD_VERSION) \
|
||||
--file ./bin/Dockerfile-release \
|
||||
./bin
|
||||
rm -f ./bin/Dockerfile-release
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
gcr.io/etcd-development/etcd:$(ETCD_VERSION) \
|
||||
/bin/sh -c "/usr/local/bin/etcd --version && ETCDCTL_API=3 /usr/local/bin/etcdctl version"
|
||||
|
||||
push-docker-release-master:
|
||||
$(info ETCD_VERSION: $(ETCD_VERSION))
|
||||
gcloud docker -- push gcr.io/etcd-development/etcd:$(ETCD_VERSION)
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
# make build-docker-test
|
||||
# make compile-with-docker-test
|
||||
# make build-docker-static-ip-test
|
||||
#
|
||||
# gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io
|
||||
# make push-docker-static-ip-test
|
||||
#
|
||||
# gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
|
||||
# make pull-docker-static-ip-test
|
||||
#
|
||||
# make docker-static-ip-test-certs-run
|
||||
# make docker-static-ip-test-certs-metrics-proxy-run
|
||||
|
||||
build-docker-static-ip-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./tests/docker-static-ip/Dockerfile
|
||||
docker build \
|
||||
--tag gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION) \
|
||||
--file ./tests/docker-static-ip/Dockerfile \
|
||||
./tests/docker-static-ip
|
||||
@mv ./tests/docker-static-ip/Dockerfile.bak ./tests/docker-static-ip/Dockerfile
|
||||
|
||||
push-docker-static-ip-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
gcloud docker -- push gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION)
|
||||
|
||||
pull-docker-static-ip-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
docker pull gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION)
|
||||
|
||||
docker-static-ip-test-certs-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-static-ip/certs,destination=/certs \
|
||||
gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs/run.sh && rm -rf m*.etcd"
|
||||
|
||||
docker-static-ip-test-certs-metrics-proxy-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-static-ip/certs-metrics-proxy,destination=/certs-metrics-proxy \
|
||||
gcr.io/etcd-development/etcd-static-ip-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs-metrics-proxy/run.sh && rm -rf m*.etcd"
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
# make build-docker-test
|
||||
# make compile-with-docker-test
|
||||
# make build-docker-dns-test
|
||||
#
|
||||
# gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io
|
||||
# make push-docker-dns-test
|
||||
#
|
||||
# gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
|
||||
# make pull-docker-dns-test
|
||||
#
|
||||
# make docker-dns-test-insecure-run
|
||||
# make docker-dns-test-certs-run
|
||||
# make docker-dns-test-certs-gateway-run
|
||||
# make docker-dns-test-certs-wildcard-run
|
||||
# make docker-dns-test-certs-common-name-auth-run
|
||||
# make docker-dns-test-certs-common-name-multi-run
|
||||
|
||||
build-docker-dns-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./tests/docker-dns/Dockerfile
|
||||
docker build \
|
||||
--tag gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
|
||||
--file ./tests/docker-dns/Dockerfile \
|
||||
./tests/docker-dns
|
||||
@mv ./tests/docker-dns/Dockerfile.bak ./tests/docker-dns/Dockerfile
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
--dns 127.0.0.1 \
|
||||
gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "/etc/init.d/bind9 start && cat /dev/null >/etc/hosts && dig etcd.local"
|
||||
|
||||
push-docker-dns-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
gcloud docker -- push gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION)
|
||||
|
||||
pull-docker-dns-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
docker pull gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION)
|
||||
|
||||
docker-dns-test-insecure-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns/insecure,destination=/insecure \
|
||||
gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /insecure/run.sh && rm -rf m*.etcd"
|
||||
|
||||
docker-dns-test-certs-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns/certs,destination=/certs \
|
||||
gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs/run.sh && rm -rf m*.etcd"
|
||||
|
||||
docker-dns-test-certs-gateway-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns/certs-gateway,destination=/certs-gateway \
|
||||
gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs-gateway/run.sh && rm -rf m*.etcd"
|
||||
|
||||
docker-dns-test-certs-wildcard-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns/certs-wildcard,destination=/certs-wildcard \
|
||||
gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs-wildcard/run.sh && rm -rf m*.etcd"
|
||||
|
||||
docker-dns-test-certs-common-name-auth-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns/certs-common-name-auth,destination=/certs-common-name-auth \
|
||||
gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs-common-name-auth/run.sh && rm -rf m*.etcd"
|
||||
|
||||
docker-dns-test-certs-common-name-multi-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns/certs-common-name-multi,destination=/certs-common-name-multi \
|
||||
gcr.io/etcd-development/etcd-dns-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs-common-name-multi/run.sh && rm -rf m*.etcd"
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
# make build-docker-test
|
||||
# make compile-with-docker-test
|
||||
# make build-docker-dns-srv-test
|
||||
# gcloud docker -- login -u _json_key -p "$(cat /etc/gcp-key-etcd-development.json)" https://gcr.io
|
||||
# make push-docker-dns-srv-test
|
||||
# gsutil -m acl ch -u allUsers:R -r gs://artifacts.etcd-development.appspot.com
|
||||
# make pull-docker-dns-srv-test
|
||||
# make docker-dns-srv-test-certs-run
|
||||
# make docker-dns-srv-test-certs-gateway-run
|
||||
# make docker-dns-srv-test-certs-wildcard-run
|
||||
|
||||
build-docker-dns-srv-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./tests/docker-dns-srv/Dockerfile
|
||||
docker build \
|
||||
--tag gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
|
||||
--file ./tests/docker-dns-srv/Dockerfile \
|
||||
./tests/docker-dns-srv
|
||||
@mv ./tests/docker-dns-srv/Dockerfile.bak ./tests/docker-dns-srv/Dockerfile
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
--dns 127.0.0.1 \
|
||||
gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "/etc/init.d/bind9 start && cat /dev/null >/etc/hosts && dig +noall +answer SRV _etcd-client-ssl._tcp.etcd.local && dig +noall +answer SRV _etcd-server-ssl._tcp.etcd.local && dig +noall +answer m1.etcd.local m2.etcd.local m3.etcd.local"
|
||||
|
||||
push-docker-dns-srv-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
gcloud docker -- push gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION)
|
||||
|
||||
pull-docker-dns-srv-test:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
docker pull gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION)
|
||||
|
||||
docker-dns-srv-test-certs-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns-srv/certs,destination=/certs \
|
||||
gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs/run.sh && rm -rf m*.etcd"
|
||||
|
||||
docker-dns-srv-test-certs-gateway-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns-srv/certs-gateway,destination=/certs-gateway \
|
||||
gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs-gateway/run.sh && rm -rf m*.etcd"
|
||||
|
||||
docker-dns-srv-test-certs-wildcard-run:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info HOST_TMP_DIR: $(HOST_TMP_DIR))
|
||||
$(info TMP_DIR_MOUNT_FLAG: $(TMP_DIR_MOUNT_FLAG))
|
||||
docker run \
|
||||
--rm \
|
||||
--tty \
|
||||
--dns 127.0.0.1 \
|
||||
$(TMP_DIR_MOUNT_FLAG) \
|
||||
--mount type=bind,source=`pwd`/bin,destination=/etcd \
|
||||
--mount type=bind,source=`pwd`/tests/docker-dns-srv/certs-wildcard,destination=/certs-wildcard \
|
||||
gcr.io/etcd-development/etcd-dns-srv-test:go$(GO_VERSION) \
|
||||
/bin/bash -c "cd /etcd && /certs-wildcard/run.sh && rm -rf m*.etcd"
|
||||
|
||||
|
||||
|
||||
# Example:
|
||||
# make build-functional
|
||||
# make build-docker-functional
|
||||
# make push-docker-functional
|
||||
# make pull-docker-functional
|
||||
|
||||
build-functional:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info ETCD_VERSION: $(ETCD_VERSION))
|
||||
./functional/build
|
||||
./bin/etcd-agent -help || true && \
|
||||
./bin/etcd-proxy -help || true && \
|
||||
./bin/etcd-runner --help || true && \
|
||||
./bin/etcd-tester -help || true
|
||||
|
||||
build-docker-functional:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info ETCD_VERSION: $(ETCD_VERSION))
|
||||
@sed -i.bak 's|REPLACE_ME_GO_VERSION|$(GO_VERSION)|g' ./functional/Dockerfile
|
||||
docker build \
|
||||
--tag gcr.io/etcd-development/etcd-functional:go$(GO_VERSION) \
|
||||
--file ./functional/Dockerfile \
|
||||
.
|
||||
@mv ./functional/Dockerfile.bak ./functional/Dockerfile
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
gcr.io/etcd-development/etcd-functional:go$(GO_VERSION) \
|
||||
/bin/bash -c "./bin/etcd --version && \
|
||||
./bin/etcd-failpoints --version && \
|
||||
ETCDCTL_API=3 ./bin/etcdctl version && \
|
||||
./bin/etcd-agent -help || true && \
|
||||
./bin/etcd-proxy -help || true && \
|
||||
./bin/etcd-runner --help || true && \
|
||||
./bin/etcd-tester -help || true && \
|
||||
./bin/benchmark --help || true"
|
||||
|
||||
push-docker-functional:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info ETCD_VERSION: $(ETCD_VERSION))
|
||||
gcloud docker -- push gcr.io/etcd-development/etcd-functional:go$(GO_VERSION)
|
||||
|
||||
pull-docker-functional:
|
||||
$(info GO_VERSION: $(GO_VERSION))
|
||||
$(info ETCD_VERSION: $(ETCD_VERSION))
|
||||
docker pull gcr.io/etcd-development/etcd-functional:go$(GO_VERSION)
|
5
vendor/go.etcd.io/etcd/NOTICE
generated
vendored
5
vendor/go.etcd.io/etcd/NOTICE
generated
vendored
@ -1,5 +0,0 @@
|
||||
CoreOS Project
|
||||
Copyright 2014 CoreOS, Inc
|
||||
|
||||
This product includes software developed at CoreOS, Inc.
|
||||
(http://www.coreos.com/).
|
5
vendor/go.etcd.io/etcd/Procfile
generated
vendored
5
vendor/go.etcd.io/etcd/Procfile
generated
vendored
@ -1,5 +0,0 @@
|
||||
# Use goreman to run `go get github.com/mattn/goreman`
|
||||
etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
#proxy: bin/etcd grpc-proxy start --endpoints=127.0.0.1:2379,127.0.0.1:22379,127.0.0.1:32379 --listen-addr=127.0.0.1:23790 --advertise-client-url=127.0.0.1:23790 --enable-pprof
|
6
vendor/go.etcd.io/etcd/Procfile.v2
generated
vendored
6
vendor/go.etcd.io/etcd/Procfile.v2
generated
vendored
@ -1,6 +0,0 @@
|
||||
# Use goreman to run `go get github.com/mattn/goreman`
|
||||
etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof
|
||||
# in future, use proxy to listen on 2379
|
||||
#proxy: bin/etcd --name infra-proxy1 --proxy=on --listen-client-urls http://127.0.0.1:2378 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --enable-pprof
|
161
vendor/go.etcd.io/etcd/README.md
generated
vendored
161
vendor/go.etcd.io/etcd/README.md
generated
vendored
@ -1,161 +0,0 @@
|
||||
# etcd
|
||||
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/coreos/etcd?style=flat-square)](https://goreportcard.com/report/github.com/coreos/etcd)
|
||||
[![Coverage](https://codecov.io/gh/coreos/etcd/branch/master/graph/badge.svg)](https://codecov.io/gh/coreos/etcd)
|
||||
[![Build Status Travis](https://img.shields.io/travis/coreos/etcdlabs.svg?style=flat-square&&branch=master)](https://travis-ci.org/coreos/etcd)
|
||||
[![Build Status Semaphore](https://semaphoreci.com/api/v1/coreos/etcd/branches/master/shields_badge.svg)](https://semaphoreci.com/coreos/etcd)
|
||||
[![Godoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/github.com/coreos/etcd)
|
||||
[![Releases](https://img.shields.io/github/release/coreos/etcd/all.svg?style=flat-square)](https://github.com/coreos/etcd/releases)
|
||||
[![LICENSE](https://img.shields.io/github/license/coreos/etcd.svg?style=flat-square)](https://github.com/coreos/etcd/blob/master/LICENSE)
|
||||
|
||||
**Note**: The `master` branch may be in an *unstable or even broken state* during development. Please use [releases][github-release] instead of the `master` branch in order to get stable binaries.
|
||||
|
||||
*the etcd v2 [documentation](Documentation/v2/README.md) has moved*
|
||||
|
||||
![etcd Logo](logos/etcd-horizontal-color.png)
|
||||
|
||||
etcd is a distributed reliable key-value store for the most critical data of a distributed system, with a focus on being:
|
||||
|
||||
* *Simple*: well-defined, user-facing API (gRPC)
|
||||
* *Secure*: automatic TLS with optional client cert authentication
|
||||
* *Fast*: benchmarked 10,000 writes/sec
|
||||
* *Reliable*: properly distributed using Raft
|
||||
|
||||
etcd is written in Go and uses the [Raft][raft] consensus algorithm to manage a highly-available replicated log.
|
||||
|
||||
etcd is used [in production by many companies](./Documentation/production-users.md), and the development team stands behind it in critical deployment scenarios, where etcd is frequently teamed with applications such as [Kubernetes][k8s], [fleet][fleet], [locksmith][locksmith], [vulcand][vulcand], [Doorman][doorman], and many others. Reliability is further ensured by rigorous [testing][etcd-tests].
|
||||
|
||||
See [etcdctl][etcdctl] for a simple command line client.
|
||||
|
||||
[raft]: https://raft.github.io/
|
||||
[k8s]: http://kubernetes.io/
|
||||
[doorman]: https://github.com/youtube/doorman
|
||||
[fleet]: https://github.com/coreos/fleet
|
||||
[locksmith]: https://github.com/coreos/locksmith
|
||||
[vulcand]: https://github.com/vulcand/vulcand
|
||||
[etcdctl]: https://github.com/coreos/etcd/tree/master/etcdctl
|
||||
[etcd-tests]: http://dash.etcd.io
|
||||
|
||||
## Community meetings
|
||||
|
||||
etcd contributors and maintainers have bi-weekly meetings at 11:00 AM (USA Pacific) on Tuesdays. There is an [iCalendar][rfc5545] format for the meetings [here](meeting.ics). Anyone is welcome to join via [Zoom][zoom] or audio-only: +1 669 900 6833. An initial agenda will be posted to the [shared Google docs][shared-meeting-notes] a day before each meeting, and everyone is welcome to suggest additional topics or other agendas.
|
||||
|
||||
[rfc5545]: https://tools.ietf.org/html/rfc5545
|
||||
[zoom]: https://coreos.zoom.us/j/854793406
|
||||
[shared-meeting-notes]: https://docs.google.com/document/d/1DbVXOHvd9scFsSmL2oNg4YGOHJdXqtx583DmeVWrB_M/edit#
|
||||
|
||||
## Getting started
|
||||
|
||||
### Getting etcd
|
||||
|
||||
The easiest way to get etcd is to use one of the pre-built release binaries which are available for OSX, Linux, Windows, [rkt][rkt], and Docker. Instructions for using these binaries are on the [GitHub releases page][github-release].
|
||||
|
||||
For those wanting to try the very latest version, [build the latest version of etcd][dl-build] from the `master` branch. This first needs [*Go*](https://golang.org/) installed (version 1.9+ is required). All development occurs on `master`, including new features and bug fixes. Bug fixes are first targeted at `master` and subsequently ported to release branches, as described in the [branch management][branch-management] guide.
|
||||
|
||||
[rkt]: https://github.com/rkt/rkt/releases/
|
||||
[github-release]: https://github.com/coreos/etcd/releases/
|
||||
[branch-management]: ./Documentation/branch_management.md
|
||||
[dl-build]: ./Documentation/dl_build.md#build-the-latest-version
|
||||
|
||||
### Running etcd
|
||||
|
||||
First start a single-member cluster of etcd.
|
||||
|
||||
If etcd is installed using the [pre-built release binaries][github-release], run it from the installation location as below:
|
||||
|
||||
```sh
|
||||
/tmp/etcd-download-test/etcd
|
||||
```
|
||||
The etcd command can be simply run as such if it is moved to the system path as below:
|
||||
|
||||
```sh
|
||||
mv /tmp/etcd-download-test/etcd /usr/locale/bin/
|
||||
|
||||
etcd
|
||||
```
|
||||
|
||||
If etcd is [build from the master branch][dl-build], run it as below:
|
||||
|
||||
```sh
|
||||
./bin/etcd
|
||||
```
|
||||
|
||||
This will bring up etcd listening on port 2379 for client communication and on port 2380 for server-to-server communication.
|
||||
|
||||
Next, let's set a single key, and then retrieve it:
|
||||
|
||||
```
|
||||
ETCDCTL_API=3 etcdctl put mykey "this is awesome"
|
||||
ETCDCTL_API=3 etcdctl get mykey
|
||||
```
|
||||
|
||||
That's it! etcd is now running and serving client requests. For more
|
||||
|
||||
- [Animated quick demo][demo-gif]
|
||||
- [Interactive etcd playground][etcd-play]
|
||||
|
||||
[demo-gif]: ./Documentation/demo.md
|
||||
[etcd-play]: http://play.etcd.io/
|
||||
|
||||
### etcd TCP ports
|
||||
|
||||
The [official etcd ports][iana-ports] are 2379 for client requests, and 2380 for peer communication.
|
||||
|
||||
[iana-ports]: http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
|
||||
|
||||
### Running a local etcd cluster
|
||||
|
||||
First install [goreman](https://github.com/mattn/goreman), which manages Procfile-based applications.
|
||||
|
||||
Our [Procfile script](./Procfile) will set up a local example cluster. Start it with:
|
||||
|
||||
```sh
|
||||
goreman start
|
||||
```
|
||||
|
||||
This will bring up 3 etcd members `infra1`, `infra2` and `infra3` and etcd `grpc-proxy`, which runs locally and composes a cluster.
|
||||
|
||||
Every cluster member and proxy accepts key value reads and key value writes.
|
||||
|
||||
### Running etcd on Kubernetes
|
||||
|
||||
To run an etcd cluster on Kubernetes, try [etcd operator](https://github.com/coreos/etcd-operator).
|
||||
|
||||
### Next steps
|
||||
|
||||
Now it's time to dig into the full etcd API and other guides.
|
||||
|
||||
- Read the full [documentation][fulldoc].
|
||||
- Explore the full gRPC [API][api].
|
||||
- Set up a [multi-machine cluster][clustering].
|
||||
- Learn the [config format, env variables and flags][configuration].
|
||||
- Find [language bindings and tools][integrations].
|
||||
- Use TLS to [secure an etcd cluster][security].
|
||||
- [Tune etcd][tuning].
|
||||
|
||||
[fulldoc]: ./Documentation/docs.md
|
||||
[api]: ./Documentation/dev-guide/api_reference_v3.md
|
||||
[clustering]: ./Documentation/op-guide/clustering.md
|
||||
[configuration]: ./Documentation/op-guide/configuration.md
|
||||
[integrations]: ./Documentation/integrations.md
|
||||
[security]: ./Documentation/op-guide/security.md
|
||||
[tuning]: ./Documentation/tuning.md
|
||||
|
||||
## Contact
|
||||
|
||||
- Mailing list: [etcd-dev](https://groups.google.com/forum/?hl=en#!forum/etcd-dev)
|
||||
- IRC: #[etcd](irc://irc.freenode.org:6667/#etcd) on freenode.org
|
||||
- Planning/Roadmap: [milestones](https://github.com/coreos/etcd/milestones), [roadmap](./ROADMAP.md)
|
||||
- Bugs: [issues](https://github.com/coreos/etcd/issues)
|
||||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING](CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
See [reporting bugs](Documentation/reporting_bugs.md) for details about reporting any issues.
|
||||
|
||||
### License
|
||||
|
||||
etcd is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user