Merge pull request #17969 from offlinehacker/pkgs/etcd/update-3.0.6

Update etcd, improve nixos module, fix nixos tests

authored by

Jaka Hudoklin and committed by
GitHub
c083ab99 095c7aef

+575 -122
+60 -5
nixos/modules/services/misc/etcd.nix
··· 28 28 29 29 listenClientUrls = mkOption { 30 30 description = "Etcd list of URLs to listen on for client traffic."; 31 - default = ["http://localhost:4001"]; 31 + default = ["http://127.0.0.1:2379"]; 32 32 type = types.listOf types.str; 33 33 }; 34 34 35 35 listenPeerUrls = mkOption { 36 36 description = "Etcd list of URLs to listen on for peer traffic."; 37 - default = ["http://localhost:7001"]; 37 + default = ["http://127.0.0.1:2380"]; 38 38 type = types.listOf types.str; 39 39 }; 40 40 ··· 46 46 47 47 initialCluster = mkOption { 48 48 description = "Etcd initial cluster configuration for bootstrapping."; 49 - default = ["${cfg.name}=http://localhost:7001"]; 49 + default = ["${cfg.name}=http://127.0.0.1:2380"]; 50 50 type = types.listOf types.str; 51 51 }; 52 52 ··· 68 68 type = types.str; 69 69 }; 70 70 71 + clientCertAuth = mkOption { 72 + description = "Whether to use certs for client authentication"; 73 + default = false; 74 + type = types.bool; 75 + }; 76 + 77 + trustedCaFile = mkOption { 78 + description = "Certificate authority file to use for clients"; 79 + default = null; 80 + type = types.nullOr types.path; 81 + }; 82 + 83 + certFile = mkOption { 84 + description = "Cert file to use for clients"; 85 + default = null; 86 + type = types.nullOr types.path; 87 + }; 88 + 89 + keyFile = mkOption { 90 + description = "Key file to use for clients"; 91 + default = null; 92 + type = types.nullOr types.path; 93 + }; 94 + 95 + peerCertFile = mkOption { 96 + description = "Cert file to use for peer to peer communication"; 97 + default = cfg.certFile; 98 + type = types.nullOr types.path; 99 + }; 100 + 101 + peerKeyFile = mkOption { 102 + description = "Key file to use for peer to peer communication"; 103 + default = cfg.keyFile; 104 + type = types.nullOr types.path; 105 + }; 106 + 107 + peerTrustedCaFile = mkOption { 108 + description = "Certificate authority file to use for peer to peer communication"; 109 + default = cfg.trustedCaFile; 110 + type = types.nullOr types.path; 111 + }; 112 + 113 + peerClientCertAuth = mkOption { 114 + description = "Whether to check all incoming peer requests from the cluster for valid client certificates signed by the supplied CA"; 115 + default = false; 116 + type = types.bool; 117 + }; 118 + 71 119 extraConf = mkOption { 72 120 description = '' 73 121 Etcd extra configuration. See ··· 99 147 wantedBy = [ "multi-user.target" ]; 100 148 after = [ "network-interfaces.target" ]; 101 149 102 - environment = { 150 + environment = (filterAttrs (n: v: v != null) { 103 151 ETCD_NAME = cfg.name; 104 152 ETCD_DISCOVERY = cfg.discovery; 105 153 ETCD_DATA_DIR = cfg.dataDir; ··· 107 155 ETCD_LISTEN_CLIENT_URLS = concatStringsSep "," cfg.listenClientUrls; 108 156 ETCD_LISTEN_PEER_URLS = concatStringsSep "," cfg.listenPeerUrls; 109 157 ETCD_INITIAL_ADVERTISE_PEER_URLS = concatStringsSep "," cfg.initialAdvertisePeerUrls; 110 - } // (optionalAttrs (cfg.discovery == ""){ 158 + ETCD_PEER_TRUSTED_CA_FILE = cfg.peerTrustedCaFile; 159 + ETCD_PEER_CERT_FILE = cfg.peerCertFile; 160 + ETCD_PEER_KEY_FILE = cfg.peerKeyFile; 161 + ETCD_CLIENT_CERT_AUTH = toString cfg.peerClientCertAuth; 162 + ETCD_TRUSTED_CA_FILE = cfg.trustedCaFile; 163 + ETCD_CERT_FILE = cfg.certFile; 164 + ETCD_KEY_FILE = cfg.keyFile; 165 + }) // (optionalAttrs (cfg.discovery == ""){ 111 166 ETCD_INITIAL_CLUSTER = concatStringsSep "," cfg.initialCluster; 112 167 ETCD_INITIAL_CLUSTER_STATE = cfg.initialClusterState; 113 168 ETCD_INITIAL_CLUSTER_TOKEN = cfg.initialClusterToken;
+157
nixos/tests/etcd-cluster.nix
··· 1 + # This test runs simple etcd cluster 2 + 3 + import ./make-test.nix ({ pkgs, ... } : let 4 + 5 + runWithOpenSSL = file: cmd: pkgs.runCommand file { 6 + buildInputs = [ pkgs.openssl ]; 7 + } cmd; 8 + 9 + ca_key = runWithOpenSSL "ca-key.pem" "openssl genrsa -out $out 2048"; 10 + ca_pem = runWithOpenSSL "ca.pem" '' 11 + openssl req \ 12 + -x509 -new -nodes -key ${ca_key} \ 13 + -days 10000 -out $out -subj "/CN=etcd-ca" 14 + ''; 15 + etcd_key = runWithOpenSSL "etcd-key.pem" "openssl genrsa -out $out 2048"; 16 + etcd_csr = runWithOpenSSL "etcd.csr" '' 17 + openssl req \ 18 + -new -key ${etcd_key} \ 19 + -out $out -subj "/CN=etcd" \ 20 + -config ${openssl_cnf} 21 + ''; 22 + etcd_cert = runWithOpenSSL "etcd.pem" '' 23 + openssl x509 \ 24 + -req -in ${etcd_csr} \ 25 + -CA ${ca_pem} -CAkey ${ca_key} \ 26 + -CAcreateserial -out $out \ 27 + -days 365 -extensions v3_req \ 28 + -extfile ${openssl_cnf} 29 + ''; 30 + 31 + etcd_client_key = runWithOpenSSL "etcd-client-key.pem" 32 + "openssl genrsa -out $out 2048"; 33 + 34 + etcd_client_csr = runWithOpenSSL "etcd-client-key.pem" '' 35 + openssl req \ 36 + -new -key ${etcd_client_key} \ 37 + -out $out -subj "/CN=etcd-client" \ 38 + -config ${client_openssl_cnf} 39 + ''; 40 + 41 + etcd_client_cert = runWithOpenSSL "etcd-client.crt" '' 42 + openssl x509 \ 43 + -req -in ${etcd_client_csr} \ 44 + -CA ${ca_pem} -CAkey ${ca_key} -CAcreateserial \ 45 + -out $out -days 365 -extensions v3_req \ 46 + -extfile ${client_openssl_cnf} 47 + ''; 48 + 49 + openssl_cnf = pkgs.writeText "openssl.cnf" '' 50 + ions = v3_req 51 + distinguished_name = req_distinguished_name 52 + [req_distinguished_name] 53 + [ v3_req ] 54 + basicConstraints = CA:FALSE 55 + keyUsage = digitalSignature, keyEncipherment 56 + extendedKeyUsage = serverAuth 57 + subjectAltName = @alt_names 58 + [alt_names] 59 + DNS.1 = node1 60 + DNS.2 = node2 61 + DNS.3 = node3 62 + IP.1 = 127.0.0.1 63 + ''; 64 + 65 + client_openssl_cnf = pkgs.writeText "client-openssl.cnf" '' 66 + ions = v3_req 67 + distinguished_name = req_distinguished_name 68 + [req_distinguished_name] 69 + [ v3_req ] 70 + basicConstraints = CA:FALSE 71 + keyUsage = digitalSignature, keyEncipherment 72 + extendedKeyUsage = clientAuth 73 + ''; 74 + 75 + nodeConfig = { 76 + services = { 77 + etcd = { 78 + enable = true; 79 + keyFile = etcd_key; 80 + certFile = etcd_cert; 81 + trustedCaFile = ca_pem; 82 + peerClientCertAuth = true; 83 + listenClientUrls = ["https://127.0.0.1:2379"]; 84 + listenPeerUrls = ["https://0.0.0.0:2380"]; 85 + }; 86 + }; 87 + 88 + environment.variables = { 89 + ETCDCTL_CERT_FILE = "${etcd_client_cert}"; 90 + ETCDCTL_KEY_FILE = "${etcd_client_key}"; 91 + ETCDCTL_CA_FILE = "${ca_pem}"; 92 + ETCDCTL_PEERS = "https://127.0.0.1:2379"; 93 + }; 94 + 95 + networking.firewall.allowedTCPPorts = [ 2380 ]; 96 + }; 97 + in { 98 + name = "etcd"; 99 + 100 + meta = with pkgs.stdenv.lib.maintainers; { 101 + maintainers = [ offline ]; 102 + }; 103 + 104 + nodes = { 105 + node1 = { config, pkgs, nodes, ... }: { 106 + require = [nodeConfig]; 107 + services.etcd = { 108 + initialCluster = ["node1=https://node1:2380" "node2=https://node2:2380"]; 109 + initialAdvertisePeerUrls = ["https://node1:2380"]; 110 + }; 111 + }; 112 + 113 + node2 = { config, pkgs, ... }: { 114 + require = [nodeConfig]; 115 + services.etcd = { 116 + initialCluster = ["node1=https://node1:2380" "node2=https://node2:2380"]; 117 + initialAdvertisePeerUrls = ["https://node2:2380"]; 118 + }; 119 + }; 120 + 121 + node3 = { config, pkgs, ... }: { 122 + require = [nodeConfig]; 123 + services.etcd = { 124 + initialCluster = ["node1=https://node1:2380" "node2=https://node2:2380" "node3=https://node3:2380"]; 125 + initialAdvertisePeerUrls = ["https://node3:2380"]; 126 + initialClusterState = "existing"; 127 + }; 128 + }; 129 + }; 130 + 131 + testScript = '' 132 + subtest "should start etcd cluster", sub { 133 + $node1->start(); 134 + $node2->start(); 135 + $node1->waitForUnit("etcd.service"); 136 + $node2->waitForUnit("etcd.service"); 137 + $node2->waitUntilSucceeds("etcdctl cluster-health"); 138 + $node1->succeed("etcdctl set /foo/bar 'Hello world'"); 139 + $node2->succeed("etcdctl get /foo/bar | grep 'Hello world'"); 140 + }; 141 + 142 + subtest "should add another member", sub { 143 + $node1->succeed("etcdctl member add node3 https://node3:2380"); 144 + $node3->start(); 145 + $node3->waitForUnit("etcd.service"); 146 + $node3->waitUntilSucceeds("etcdctl member list | grep 'node3'"); 147 + $node3->succeed("etcdctl cluster-health"); 148 + }; 149 + 150 + subtest "should survive member crash", sub { 151 + $node3->crash; 152 + $node1->succeed("etcdctl cluster-health"); 153 + $node1->succeed("etcdctl set /foo/bar 'Hello degraded world'"); 154 + $node1->succeed("etcdctl get /foo/bar | grep 'Hello degraded world'"); 155 + }; 156 + ''; 157 + })
+12 -96
nixos/tests/etcd.nix
··· 1 - # This test runs etcd as single node, multy node and using discovery 1 + # This test runs simple etcd node 2 2 3 3 import ./make-test.nix ({ pkgs, ... } : { 4 4 name = "etcd"; 5 + 5 6 meta = with pkgs.stdenv.lib.maintainers; { 6 7 maintainers = [ offline ]; 7 8 }; 8 9 9 10 nodes = { 10 - simple = 11 - { config, pkgs, nodes, ... }: 12 - { 13 - services.etcd.enable = true; 14 - services.etcd.listenClientUrls = ["http://0.0.0.0:4001"]; 15 - environment.systemPackages = [ pkgs.curl ]; 16 - networking.firewall.allowedTCPPorts = [ 4001 ]; 17 - }; 18 - 19 - 20 - node1 = 21 - { config, pkgs, nodes, ... }: 22 - { 23 - services = { 24 - etcd = { 25 - enable = true; 26 - listenPeerUrls = ["http://0.0.0.0:7001"]; 27 - initialAdvertisePeerUrls = ["http://node1:7001"]; 28 - initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"]; 29 - }; 30 - }; 31 - 32 - networking.firewall.allowedTCPPorts = [ 7001 ]; 33 - }; 34 - 35 - node2 = 36 - { config, pkgs, ... }: 37 - { 38 - services = { 39 - etcd = { 40 - enable = true; 41 - listenPeerUrls = ["http://0.0.0.0:7001"]; 42 - initialAdvertisePeerUrls = ["http://node2:7001"]; 43 - initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"]; 44 - }; 45 - }; 46 - 47 - networking.firewall.allowedTCPPorts = [ 7001 ]; 48 - }; 49 - 50 - discovery1 = 51 - { config, pkgs, nodes, ... }: 52 - { 53 - services = { 54 - etcd = { 55 - enable = true; 56 - listenPeerUrls = ["http://0.0.0.0:7001"]; 57 - initialAdvertisePeerUrls = ["http://discovery1:7001"]; 58 - discovery = "http://simple:4001/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/"; 59 - }; 60 - }; 61 - 62 - networking.firewall.allowedTCPPorts = [ 7001 ]; 63 - }; 64 - 65 - discovery2 = 66 - { config, pkgs, ... }: 67 - { 68 - services = { 69 - etcd = { 70 - enable = true; 71 - listenPeerUrls = ["http://0.0.0.0:7001"]; 72 - initialAdvertisePeerUrls = ["http://discovery2:7001"]; 73 - discovery = "http://simple:4001/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/"; 74 - }; 75 - }; 76 - 77 - networking.firewall.allowedTCPPorts = [ 7001 ]; 78 - }; 11 + node = { config, pkgs, nodes, ... }: { 12 + services.etcd.enable = true; 79 13 }; 14 + }; 80 15 81 16 testScript = '' 82 - subtest "single node", sub { 83 - $simple->start(); 84 - $simple->waitForUnit("etcd.service"); 85 - $simple->waitUntilSucceeds("etcdctl set /foo/bar 'Hello world'"); 86 - $simple->waitUntilSucceeds("etcdctl get /foo/bar | grep 'Hello world'"); 87 - }; 88 - 89 - subtest "multy node", sub { 90 - $node1->start(); 91 - $node2->start(); 92 - $node1->waitForUnit("etcd.service"); 93 - $node2->waitForUnit("etcd.service"); 94 - $node1->waitUntilSucceeds("etcdctl set /foo/bar 'Hello world'"); 95 - $node2->waitUntilSucceeds("etcdctl get /foo/bar | grep 'Hello world'"); 96 - $node1->shutdown(); 97 - $node2->shutdown(); 17 + subtest "should start etcd node", sub { 18 + $node->start(); 19 + $node->waitForUnit("etcd.service"); 98 20 }; 99 21 100 - subtest "discovery", sub { 101 - $simple->succeed("curl -X PUT http://localhost:4001/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/_config/size -d value=2"); 102 - 103 - $discovery1->start(); 104 - $discovery2->start(); 105 - $discovery1->waitForUnit("etcd.service"); 106 - $discovery2->waitForUnit("etcd.service"); 107 - $discovery1->waitUntilSucceeds("etcdctl set /foo/bar 'Hello world'"); 108 - $discovery2->waitUntilSucceeds("etcdctl get /foo/bar | grep 'Hello world'"); 109 - }; 22 + subtest "should write and read some values to etcd", sub { 23 + $node->succeed("etcdctl set /foo/bar 'Hello world'"); 24 + $node->succeed("etcdctl get /foo/bar | grep 'Hello world'"); 25 + } 110 26 ''; 111 27 })
+13 -3
pkgs/servers/etcd/default.nix
··· 1 1 { stdenv, lib, libpcap, buildGoPackage, fetchFromGitHub }: 2 2 3 + with lib; 4 + 3 5 buildGoPackage rec { 4 6 name = "etcd-${version}"; 5 - version = "2.3.7"; 7 + version = "3.0.6"; # After updating check that nixos tests pass 6 8 rev = "v${version}"; 7 - 9 + 8 10 goPackagePath = "github.com/coreos/etcd"; 9 11 10 12 src = fetchFromGitHub { 11 13 inherit rev; 12 14 owner = "coreos"; 13 15 repo = "etcd"; 14 - sha256 = "07rdnhcpnvnkxj5pqacxz669rzn5vw2i1zmf6dd4nv7wpfscdw9f"; 16 + sha256 = "163qji360y21nr1wnl16nbvvgdgqgbny4c3v3igp87q9p78sdf75"; 15 17 }; 16 18 17 19 goDeps = ./deps.json; 18 20 19 21 buildInputs = [ libpcap ]; 22 + 23 + meta = { 24 + description = "Distributed reliable key-value store for the most critical data of a distributed system"; 25 + license = licenses.asl20; 26 + homepage = https://coreos.com/etcd/; 27 + maintainers = with maintainers; [offline]; 28 + platforms = with platforms; linux; 29 + }; 20 30 }
+333 -18
pkgs/servers/etcd/deps.json
··· 1 1 [ 2 - { 3 - "goPackagePath": "github.com/olekukonko/tablewriter", 4 - "fetch": { 5 - "type": "git", 6 - "url": "https://github.com/olekukonko/tablewriter", 7 - "rev": "cca8bbc0798408af109aaaa239cbd2634846b340", 8 - "sha256": "0f9ph3z7lh6p6gihbl1461j9yq5qiaqxr9mzdkp512n18v89ml48" 9 - } 10 - }, 11 - { 12 - "goPackagePath": "github.com/mattn/go-runewidth", 13 - "fetch": { 14 - "type": "git", 15 - "url": "https://github.com/mattn/go-runewidth", 16 - "rev": "d6bea18f789704b5f83375793155289da36a3c7f", 17 - "sha256": "1hnigpn7rjbwd1ircxkyx9hvi0xmxr32b2jdy2jzw6b3jmcnz1fs" 18 - } 2 + { 3 + "goPackagePath": "github.com/beorn7/perks", 4 + "fetch": { 5 + "type": "git", 6 + "url": "https://github.com/beorn7/perks", 7 + "rev": "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9", 8 + "sha256": "1hrybsql68xw57brzj805xx2mghydpdiysv3gbhr7f5wlxj2514y" 9 + } 10 + }, 11 + { 12 + "goPackagePath": "github.com/boltdb/bolt", 13 + "fetch": { 14 + "type": "git", 15 + "url": "https://github.com/boltdb/bolt", 16 + "rev": "583e8937c61f1af6513608ccc75c97b6abdf4ff9", 17 + "sha256": "0cp5v9iypg9ysiq40k3h3lg7aisxplnmxshha7nama6b170izyay" 18 + } 19 + }, 20 + { 21 + "goPackagePath": "github.com/cloudfoundry-incubator/candiedyaml", 22 + "fetch": { 23 + "type": "git", 24 + "url": "https://github.com/cloudfoundry-incubator/candiedyaml", 25 + "rev": "99c3df83b51532e3615f851d8c2dbb638f5313bf", 26 + "sha256": "106nibg7423642gbkg88c5x2jxfz6nmxbribhwb8cr1rn9vpjaxs" 27 + } 28 + }, 29 + { 30 + "goPackagePath": "github.com/cockroachdb/cmux", 31 + "fetch": { 32 + "type": "git", 33 + "url": "https://github.com/cockroachdb/cmux", 34 + "rev": "b64f5908f4945f4b11ed4a0a9d3cc1e23350866d", 35 + "sha256": "1by4f3x7j3r3z1sdx1v04r494hn6jaag7lc03prrgx455j8i0jlh" 36 + } 37 + }, 38 + { 39 + "goPackagePath": "github.com/coreos/etcd", 40 + "fetch": { 41 + "type": "git", 42 + "url": "https://github.com/coreos/etcd.git", 43 + "rev": "9efa00d1030d4bf62eb8e5ec130023aeb1b8e2d0", 44 + "sha256": "163qji360y21nr1wnl16nbvvgdgqgbny4c3v3igp87q9p78sdf75" 45 + } 46 + }, 47 + { 48 + "goPackagePath": "github.com/coreos/go-semver", 49 + "fetch": { 50 + "type": "git", 51 + "url": "https://github.com/coreos/go-semver", 52 + "rev": "8ab6407b697782a06568d4b7f1db25550ec2e4c6", 53 + "sha256": "1gghi5bnqj50hfxhqc1cxmynqmh2yk9ii7ab9gsm75y5cp94ymk0" 54 + } 55 + }, 56 + { 57 + "goPackagePath": "github.com/coreos/go-systemd", 58 + "fetch": { 59 + "type": "git", 60 + "url": "https://github.com/coreos/go-systemd", 61 + "rev": "5c49e4850c879a0ddc061e8f4adcf307de8a8bc2", 62 + "sha256": "1w16bnrgfjb5rwha7g8rdjhpgjf8bzmlzhrda5bfvc9ymj3qjibk" 63 + } 64 + }, 65 + { 66 + "goPackagePath": "github.com/coreos/pkg", 67 + "fetch": { 68 + "type": "git", 69 + "url": "https://github.com/coreos/pkg", 70 + "rev": "3ac0863d7acf3bc44daf49afef8919af12f704ef", 71 + "sha256": "0l5ans1ls2gknkrnhymgc0zbgg5nqjbjbqc51r611adcr0m6gg8l" 72 + } 73 + }, 74 + { 75 + "goPackagePath": "github.com/ghodss/yaml", 76 + "fetch": { 77 + "type": "git", 78 + "url": "https://github.com/ghodss/yaml", 79 + "rev": "aa0c862057666179de291b67d9f093d12b5a8473", 80 + "sha256": "0cbc78n8l7h1gdzhrvahplcvr4v7n8v23vkgskfp843rcx5h6isr" 81 + } 82 + }, 83 + { 84 + "goPackagePath": "github.com/gogo/protobuf", 85 + "fetch": { 86 + "type": "git", 87 + "url": "https://github.com/gogo/protobuf", 88 + "rev": "f20a1444730c7d9949b880a0309e737d007def25", 89 + "sha256": "12wa3r2cb2v1m65phbkh692ldlklk459z4x6avpc6im0zkr6r73c" 90 + } 91 + }, 92 + { 93 + "goPackagePath": "github.com/golang/protobuf", 94 + "fetch": { 95 + "type": "git", 96 + "url": "https://github.com/golang/protobuf", 97 + "rev": "f592bd283e9ef86337a432eb50e592278c3d534d", 98 + "sha256": "01gxhzn9m6jz6ihwxfycnx39zf5pmkan61l278cnynsb8mibdpvb" 99 + } 100 + }, 101 + { 102 + "goPackagePath": "github.com/google/btree", 103 + "fetch": { 104 + "type": "git", 105 + "url": "https://github.com/google/btree", 106 + "rev": "7d79101e329e5a3adf994758c578dab82b90c017", 107 + "sha256": "1c1hsy5s2pfawg3l9954jmqmy4yc2zp3f7i87m00km2yqgb8xpd0" 108 + } 109 + }, 110 + { 111 + "goPackagePath": "github.com/grpc-ecosystem/grpc-gateway", 112 + "fetch": { 113 + "type": "git", 114 + "url": "https://github.com/grpc-ecosystem/grpc-gateway", 115 + "rev": "5e0e028ba0a015710eaebf6e47af18812c9f2767", 116 + "sha256": "00s4wxzs6lz5al7y2hxi6r4bxhx5b0ajk5rwxrnb4a4mhlaii8pk" 117 + } 118 + }, 119 + { 120 + "goPackagePath": "github.com/jonboulle/clockwork", 121 + "fetch": { 122 + "type": "git", 123 + "url": "https://github.com/jonboulle/clockwork", 124 + "rev": "e3653ace2d63753697e0e5b07b9393971c0bba9d", 125 + "sha256": "1avzqhks12a8x2yzpvjsf3k0gv9cy7zx2z88hn0scacnxkphisvc" 126 + } 127 + }, 128 + { 129 + "goPackagePath": "github.com/matttproud/golang_protobuf_extensions", 130 + "fetch": { 131 + "type": "git", 132 + "url": "https://github.com/matttproud/golang_protobuf_extensions", 133 + "rev": "c12348ce28de40eed0136aa2b644d0ee0650e56c", 134 + "sha256": "1d0c1isd2lk9pnfq2nk0aih356j30k3h1gi2w0ixsivi5csl7jya" 135 + } 136 + }, 137 + { 138 + "goPackagePath": "github.com/prometheus/client_golang", 139 + "fetch": { 140 + "type": "git", 141 + "url": "https://github.com/prometheus/client_golang", 142 + "rev": "c5b7fccd204277076155f10851dad72b76a49317", 143 + "sha256": "1xqny3147g12n4j03kxm8s9mvdbs3ln6i56c655mybrn9jjy48kd" 144 + } 145 + }, 146 + { 147 + "goPackagePath": "github.com/prometheus/client_model", 148 + "fetch": { 149 + "type": "git", 150 + "url": "https://github.com/prometheus/client_model", 151 + "rev": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6", 152 + "sha256": "11a7v1fjzhhwsl128znjcf5v7v6129xjgkdpym2lial4lac1dhm9" 153 + } 154 + }, 155 + { 156 + "goPackagePath": "github.com/prometheus/common", 157 + "fetch": { 158 + "type": "git", 159 + "url": "https://github.com/prometheus/common", 160 + "rev": "ebdfc6da46522d58825777cf1f90490a5b1ef1d8", 161 + "sha256": "0js62pj8600773wx6labpd772yyhz5ivim7dnl7b862wblbmc8mq" 162 + } 163 + }, 164 + { 165 + "goPackagePath": "github.com/prometheus/procfs", 166 + "fetch": { 167 + "type": "git", 168 + "url": "https://github.com/prometheus/procfs", 169 + "rev": "abf152e5f3e97f2fafac028d2cc06c1feb87ffa5", 170 + "sha256": "0cp8lznv1b4zhi3wnbjkfxwzhkqd3wbmiy6mwgjanip8l9l3ykws" 171 + } 172 + }, 173 + { 174 + "goPackagePath": "github.com/spf13/cobra", 175 + "fetch": { 176 + "type": "git", 177 + "url": "https://github.com/spf13/cobra", 178 + "rev": "7c674d9e72017ed25f6d2b5e497a1368086b6a6f", 179 + "sha256": "0an935r7lc11a744mvdrsy56rs2w0ah3gdclvr4gzd5iqr9ap3dr" 180 + } 181 + }, 182 + { 183 + "goPackagePath": "github.com/spf13/pflag", 184 + "fetch": { 185 + "type": "git", 186 + "url": "https://github.com/spf13/pflag", 187 + "rev": "6454a84b6da0ea8b628d5d8a26759f62c6c161b4", 188 + "sha256": "06rfi73jhkncn8gxy6klgmba5947k9gpwdswipdpz680yxczcwna" 189 + } 190 + }, 191 + { 192 + "goPackagePath": "github.com/ugorji/go", 193 + "fetch": { 194 + "type": "git", 195 + "url": "https://github.com/ugorji/go", 196 + "rev": "4a1cb5252a6951f715a85d0e4be334c2a2dbf2a2", 197 + "sha256": "0izpijk3piihl4fnqg8ncnp5ivbq41pg3xf7iagg4fbg5id4pxbx" 198 + } 199 + }, 200 + { 201 + "goPackagePath": "github.com/xiang90/probing", 202 + "fetch": { 203 + "type": "git", 204 + "url": "https://github.com/xiang90/probing", 205 + "rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2", 206 + "sha256": "0r8rq27yigz72mk8z7p61yjfan8id021dnp1v421ln9byzpvabn2" 207 + } 208 + }, 209 + { 210 + "goPackagePath": "golang.org/x/crypto", 211 + "fetch": { 212 + "type": "git", 213 + "url": "https://go.googlesource.com/crypto", 214 + "rev": "88d0005bf4c3ec17306ecaca4281a8d8efd73e91", 215 + "sha256": "1d3x0rwfd4cml06ka8gy74wxrw94m2z7qgz6ky0rgmxcr7p5iikz" 216 + } 217 + }, 218 + { 219 + "goPackagePath": "golang.org/x/net", 220 + "fetch": { 221 + "type": "git", 222 + "url": "https://go.googlesource.com/net", 223 + "rev": "7394c112eae4dba7e96bfcfe738e6373d61772b4", 224 + "sha256": "1p8wsxnbsp2lq6hbza2n0zgv4sgpxzzjjlrmcngkhxj47kp3hin7" 225 + } 226 + }, 227 + { 228 + "goPackagePath": "google.golang.org/grpc", 229 + "fetch": { 230 + "type": "git", 231 + "url": "https://github.com/grpc/grpc-go", 232 + "rev": "0032a855ba5c8a3c8e0d71c2deef354b70af1584", 233 + "sha256": "0qkynp65jwk6jk932k7kwxs5v6fzlfsb1fay71a00dwr36f44s67" 234 + } 235 + }, 236 + { 237 + "goPackagePath": "github.com/urfave/cli", 238 + "fetch": { 239 + "type": "git", 240 + "url": "https://github.com/urfave/cli", 241 + "rev": "168c95418e66e019fe17b8f4f5c45aa62ff80e23", 242 + "sha256": "1gdvvim2f1zigcmbpcgypgn7nvpnlr87grbg7lw13fbpy6fnlw2n" 243 + } 244 + }, 245 + { 246 + "goPackagePath": "github.com/mattn/go-runewidth", 247 + "fetch": { 248 + "type": "git", 249 + "url": "https://github.com/mattn/go-runewidth", 250 + "rev": "d6bea18f789704b5f83375793155289da36a3c7f", 251 + "sha256": "1hnigpn7rjbwd1ircxkyx9hvi0xmxr32b2jdy2jzw6b3jmcnz1fs" 252 + } 253 + }, 254 + { 255 + "goPackagePath": "github.com/olekukonko/tablewriter", 256 + "fetch": { 257 + "type": "git", 258 + "url": "https://github.com/olekukonko/tablewriter", 259 + "rev": "daf2955e742cf123959884fdff4685aa79b63135", 260 + "sha256": "1fvl251ms7qmzfbi853kdgghqkrmyy6n1605mfy50nhgvw03z203" 261 + } 262 + }, 263 + { 264 + "goPackagePath": "github.com/dustin/go-humanize", 265 + "fetch": { 266 + "type": "git", 267 + "url": "https://github.com/dustin/go-humanize", 268 + "rev": "2fcb5204cdc65b4bec9fd0a87606bb0d0e3c54e8", 269 + "sha256": "1m2qgn5vh5m66ggmclgikvwc05np2r7sxgpvlj2jip5d61x29j5k" 270 + } 271 + }, 272 + { 273 + "goPackagePath": "github.com/bgentry/speakeasy", 274 + "fetch": { 275 + "type": "git", 276 + "url": "https://github.com/bgentry/speakeasy", 277 + "rev": "a1ccbf2c40dfc8ce514b5c5c6e6d1429ea6880da", 278 + "sha256": "0xqpc1qhdcs5blp1mkrppfb1x0rcv4a445mj0yzdwshbzkw5di01" 279 + } 280 + }, 281 + { 282 + "goPackagePath": "github.com/kr/pty", 283 + "fetch": { 284 + "type": "git", 285 + "url": "https://github.com/kr/pty", 286 + "rev": "ce7fa45920dc37a92de8377972e52bc55ffa8d57", 287 + "sha256": "0mdlr2mmwjznw2id0l4200xjajq9dh1kxn3z7d3ksn0b5fwinzmk" 288 + } 289 + }, 290 + { 291 + "goPackagePath": "github.com/golang/groupcache", 292 + "fetch": { 293 + "type": "git", 294 + "url": "https://github.com/golang/groupcache", 295 + "rev": "a6b377e3400b08991b80d6805d627f347f983866", 296 + "sha256": "125a6zdaxj916yp2rlrkg8xw00vjf5ga9xwdg4clby8wj4fysma2" 297 + } 298 + }, 299 + { 300 + "goPackagePath": "gopkg.in/cheggaaa/pb.v1", 301 + "fetch": { 302 + "type": "git", 303 + "url": "https://gopkg.in/cheggaaa/pb.v1", 304 + "rev": "9453b2db37f4d8bc63751daca63bbe7049eb5e74", 305 + "sha256": "0py7dxvm3ydxcw260x7r7xbjww1vkil3rhyy3f9njmjydyb303rb" 306 + } 307 + }, 308 + { 309 + "goPackagePath": "github.com/golang/glog", 310 + "fetch": { 311 + "type": "git", 312 + "url": "https://github.com/golang/glog", 313 + "rev": "23def4e6c14b4da8ac2ed8007337bc5eb5007998", 314 + "sha256": "0jb2834rw5sykfr937fxi8hxi2zy80sj2bdn9b3jb4b26ksqng30" 315 + } 316 + }, 317 + { 318 + "goPackagePath": "github.com/spacejam/loghisto", 319 + "fetch": { 320 + "type": "git", 321 + "url": "https://github.com/spacejam/loghisto", 322 + "rev": "9d1d8c1fd2a4ac852bf2e312f2379f553345fda7", 323 + "sha256": "0r31y4ci35pp11wqdyarimdq5a703byk3cf6d67adsa4nw0ysfm1" 324 + } 325 + }, 326 + { 327 + "goPackagePath": "github.com/akrennmair/gopcap", 328 + "fetch": { 329 + "type": "git", 330 + "url": "https://github.com/akrennmair/gopcap", 331 + "rev": "00e11033259acb75598ba416495bb708d864a010", 332 + "sha256": "0xfw7x5a36w0g76imjvgk055360xg0nva42qhmflfvll7ldxq96a" 19 333 } 20 - ] 334 + } 335 + ]