diff --git a/Gopkg.lock b/Gopkg.lock index 76aec16a0..4edbe1b21 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -29,7 +29,7 @@ revision = "d6e3b3328b783f23731bc4d058875b0371ff8109" [[projects]] - digest = "1:11e17f77281a8ab1267c30ca114e934f93e63379d328615b3d3448f0c87f7dc9" + digest = "1:1cd7c78615a24f1f886b7c23d9a1d323dee3c36e76c0a64a348ab72036be90bf" name = "github.com/Azure/go-autorest" packages = [ "autorest", @@ -44,7 +44,7 @@ version = "v11.2.8" [[projects]] - digest = "1:d9b9f8e552b21361f2753af22b298440b06287e6390e7f33f010f27a62d90179" + digest = "1:9f3b30d9f8e0d7040f729b82dcbc8f0dead820a133b3147ce355fc451f32d761" name = "github.com/BurntSushi/toml" packages = ["."] pruneopts = "UT" @@ -91,6 +91,22 @@ revision = "b4f55832432b95a611cf1495272b5c8e24952a1a" version = "v1.13.0" +[[projects]] + digest = "1:f9ae348e1f793dcf9ed930ed47136a67343dbd6809c5c91391322267f4476892" + name = "github.com/Microsoft/go-winio" + packages = ["."] + pruneopts = "UT" + revision = "1a8911d1ed007260465c3bfbbc785ac6915a0bb8" + version = "v0.4.12" + +[[projects]] + branch = "master" + digest = "1:3721a10686511b80c052323423f0de17a8c06d417dbdd3b392b1578432a33aae" + name = "github.com/Nvveen/Gotty" + packages = ["."] + pruneopts = "UT" + revision = "cd527374f1e5bff4938207604a14f2e38a9cf512" + [[projects]] digest = "1:d1665c44bd5db19aaee18d1b6233c99b0b9a986e8bccb24ef54747547a48027f" name = "github.com/PuerkitoBio/purell" @@ -140,7 +156,7 @@ version = "v0.4.1" [[projects]] - digest = "1:0a896acf6dcc0f0228090208b69e70ea681843771c07d5990b6c495baa5f9d91" + digest = "1:a9ef0c82c0459e56e52a374cff03bc7b21a2e76bd957cc368fafd23ca0ba0b45" name = "github.com/bugsnag/bugsnag-go" packages = [ ".", @@ -159,7 +175,7 @@ version = "v1.2.0" [[projects]] - digest = "1:7b69ec1477f4beff10335b7da13a3c0329dfdb3141c5653a249760d1ee177a7c" + digest = "1:65b0d980b428a6ad4425f2df4cd5410edd81f044cf527bd1c345368444649e58" name = "github.com/census-instrumentation/opencensus-proto" packages = [ "gen-go/agent/common/v1", @@ -173,7 +189,7 @@ [[projects]] branch = "master" - digest = "1:1f8ed389b3f7923ed00486d86509f8f859a7b2dcffb5f2f137c7150ddca66dbb" + digest = "1:95e08278c876d185ba67533f045e9e63b3c9d02cbd60beb0f4dbaa2344a13ac2" name = "github.com/chai2010/gettext-go" packages = [ "gettext", @@ -185,7 +201,7 @@ revision = "bf70f2a70fb1b1f36d90d671a72795984eab0fcb" [[projects]] - digest = "1:6248c3bfae5a941cbeb291dac75fb633ca0b18af62c69c6b0ec6b40d7a4844cc" + digest = "1:37f8940c4d3c41536ea882b1ca3498e403c04892dfc34bd0d670ed9eafccda9a" name = "github.com/containerd/containerd" packages = [ "content", @@ -198,8 +214,16 @@ "remotes/docker", ] pruneopts = "UT" - revision = "9b32062dc1f5a7c2564315c269b5059754f12b9d" - version = "v1.2.1" + revision = "894b81a4b802e4eb2a91d1ce216b8817763c29fb" + version = "v1.2.6" + +[[projects]] + branch = "master" + digest = "1:e48c63e818c67fbf3d7afe20bba33134ab1a5bf384847385384fd027652a5a96" + name = "github.com/containerd/continuity" + packages = ["pathdriver"] + pruneopts = "UT" + revision = "004b46473808b3e7a4a3049c20e4376c91eb966d" [[projects]] digest = "1:7cb4fdca4c251b3ef8027c90ea35f70c7b661a593b9eeae34753c65499098bb1" @@ -218,15 +242,17 @@ version = "v1.1.1" [[projects]] - digest = "1:c2b304e9f010d2fdd048b50c8c9eaa3ae947e7c5717be87a379f63980786dcb8" + digest = "1:82158435e282da9b23bb1188487fe1c68b17a54ed9dcd557ab6204782ad3ff92" name = "github.com/deislabs/oras" packages = [ + "pkg/auth", + "pkg/auth/docker", "pkg/content", "pkg/oras", ] pruneopts = "UT" - revision = "e8a1fa6ff9a507b99eedd45745959e8c5b826d9f" - version = "v0.3.3" + revision = "9f7669048990b0d0c186985737e6a6c3bb3f7ecc" + version = "v0.4.0" [[projects]] digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55" @@ -237,7 +263,20 @@ version = "v3.2.0" [[projects]] - digest = "1:ef764aa16c439ecf65aa588d21ad3499c55064f7ea05082b18211468d2ca99be" + digest = "1:f65090e4f60dcd4d2de69e8ebca022d59a8c6463a3a4c122e64cec91a83749ff" + name = "github.com/docker/cli" + packages = [ + "cli/config", + "cli/config/configfile", + "cli/config/credentials", + "opts", + ] + pruneopts = "UT" + revision = "c89750f836c57ce10386e71669e1b08a54c3caeb" + version = "v18.09.5" + +[[projects]] + digest = "1:feaf11ab67fe48ec2712bf9d44e2fb2d4ebdc5da8e5a47bd3ce05bae9f82825b" name = "github.com/docker/distribution" packages = [ ".", @@ -258,6 +297,7 @@ "registry/api/errcode", "registry/api/v2", "registry/auth", + "registry/auth/htpasswd", "registry/client", "registry/client/auth", "registry/client/auth/challenge", @@ -286,15 +326,61 @@ [[projects]] branch = "master" - digest = "1:efacbb3ab555c719a041fb74373aa9a6c46c2579f0bfb9fae9e6c9daf662a4eb" + digest = "1:b5be0d9940d8fa3ff7df4949a8e8c47a7f93ea8251239ad074e1a6b0db55876a" name = "github.com/docker/docker" packages = [ + "api/types", + "api/types/blkiodev", + "api/types/container", + "api/types/filters", + "api/types/mount", + "api/types/network", + "api/types/registry", + "api/types/strslice", + "api/types/swarm", + "api/types/swarm/runtime", + "api/types/versions", + "errdefs", + "pkg/homedir", + "pkg/idtools", + "pkg/ioutils", + "pkg/jsonmessage", + "pkg/longpath", + "pkg/mount", + "pkg/stringid", + "pkg/system", + "pkg/tarsum", "pkg/term", "pkg/term/windows", + "registry", + "registry/resumable", ] pruneopts = "UT" revision = "2cb26cfe9cbf8a64c5046c74d65f4528b22e67f4" +[[projects]] + digest = "1:8866486038791fe65ea1abf660041423954b1f3fb99ea6a0ad8424422e943458" + name = "github.com/docker/docker-credential-helpers" + packages = [ + "client", + "credentials", + ] + pruneopts = "UT" + revision = "5241b46610f2491efdf9d1c85f1ddf5b02f6d962" + version = "v0.6.1" + +[[projects]] + digest = "1:811c86996b1ca46729bad2724d4499014c4b9effd05ef8c71b852aad90deb0ce" + name = "github.com/docker/go-connections" + packages = [ + "nat", + "sockets", + "tlsconfig", + ] + pruneopts = "UT" + revision = "7395e3f8aa162843a74ed6d48e79627d9792ac55" + version = "v0.4.0" + [[projects]] branch = "master" digest = "1:2b126e77be4ab4b92cdb3924c87894dd76bf365ba282f358a13133e848aa0059" @@ -321,7 +407,7 @@ [[projects]] branch = "master" - digest = "1:93a21c82477de8936e5e238bc8f98a1fee607241326abbc812d7e5d5d8649d6b" + digest = "1:ecdc8e0fe3bc7d549af1c9c36acf3820523b707d6c071b6d0c3860882c6f7b42" name = "github.com/docker/spdystream" packages = [ ".", @@ -331,7 +417,7 @@ revision = "6480d4af844c189cf5dd913db24ddd339d3a4f85" [[projects]] - digest = "1:513bf2fb3b6a767c5679569d4b54b2cc634fd7e5df542b4637363189699b1b81" + digest = "1:899234af23e5793c34e06fd397f86ba33af5307b959b6a7afd19b63db065a9d7" name = "github.com/emicklei/go-restful" packages = [ ".", @@ -366,7 +452,7 @@ version = "v1.0.0" [[projects]] - digest = "1:f26133af0db0007ccbd4830a033f7124c38cbab8afecd06452f17c6b7fd4c3a9" + digest = "1:0594af97b2f4cec6554086eeace6597e20a4b69466eb4ada25adf9f4300dddd2" name = "github.com/garyburd/redigo" packages = [ "internal", @@ -417,7 +503,7 @@ version = "v0.17.2" [[projects]] - digest = "1:f50cd3eefda65d741da69224fbfba0d7fea9847bad9b4f462457bae567b198f2" + digest = "1:9ae31ce33b4bab257668963e844d98765b44160be4ee98cafc44637a213e530d" name = "github.com/gobwas/glob" packages = [ ".", @@ -434,7 +520,7 @@ version = "v0.2.3" [[projects]] - digest = "1:3eb221925fcc7f9dcf507ecc2510bf011a1b5abf2869c8da523f72faf85fbbe9" + digest = "1:b402bb9a24d108a9405a6f34675091b036c8b056aac843bf6ef2389a65c5cf48" name = "github.com/gogo/protobuf" packages = [ "proto", @@ -453,7 +539,7 @@ revision = "c65c006176ff7ff98bb916961c7abbc6b0afc0aa" [[projects]] - digest = "1:92a1b6546eab24700568ef2821fd42fccc527361056bbb70837442e14aa32f12" + digest = "1:8f0705fa33e8957018611cc81c65cb373b626c092d39931bb86882489fc4c3f4" name = "github.com/golang/protobuf" packages = [ "proto", @@ -492,7 +578,7 @@ version = "v1.1.0" [[projects]] - digest = "1:a6a3cf96c8f626d50c11f5ab6c6a92e3ccde777aafe091dd305224c85d3c0030" + digest = "1:65c4414eeb350c47b8de71110150d0ea8a281835b1f386eacaa3ad7325929c21" name = "github.com/googleapis/gnostic" packages = [ "OpenAPIv2", @@ -505,7 +591,7 @@ [[projects]] branch = "master" - digest = "1:2d2da032a134b161abb9cbc826fda2c7501fb921662bb9234d5273b711c04a7f" + digest = "1:d47549022c929925679aec031329f59f250d704f69ee44a194998cdb8d873393" name = "github.com/gophercloud/gophercloud" packages = [ ".", @@ -537,7 +623,7 @@ [[projects]] branch = "master" - digest = "1:cfff48546cb55d9bfcb60078c1bb27b0cb8fbf403d8d481d7244a920359c8d7b" + digest = "1:4e08dc2383a46b3107f0b34ca338c4459e8fc8ee90e46a60e728aa8a2b21d558" name = "github.com/gosuri/uitable" packages = [ ".", @@ -549,7 +635,7 @@ [[projects]] branch = "master" - digest = "1:d9221e54176cdc408f6cb9cc35626743e8728fd7e69e5b0df075df15e4bec895" + digest = "1:86c1210529e69d69860f2bb3ee9ccce0b595aa3f9165e7dd1388e5c612915888" name = "github.com/gregjones/httpcache" packages = [ ".", @@ -627,7 +713,7 @@ [[projects]] branch = "master" - digest = "1:ebd709f6c64e850ee37ffd662604b647934ba1b7da39c7ba26381d634a4b6d4d" + digest = "1:84a5a2b67486d5d67060ac393aa255d05d24ed5ee41daecd5635ec22657b6492" name = "github.com/mailru/easyjson" packages = [ "buffer", @@ -701,7 +787,7 @@ version = "v1.0.0-rc1" [[projects]] - digest = "1:7c5c09ec84d18b0dc5ec0de36c1b8d12d3bf1815d04b90dc50ab082f3b8f13f1" + digest = "1:11db38d694c130c800d0aefb502fb02519e514dc53d9804ce51d1ad25ec27db6" name = "github.com/opencontainers/image-spec" packages = [ "specs-go", @@ -711,6 +797,14 @@ revision = "d60099175f88c47cd379c4738d158884749ed235" version = "v1.0.1" +[[projects]] + digest = "1:38ee335aedf4626620f3cf8f605661e71abdcce7b40b38921962beb3980f0a20" + name = "github.com/opencontainers/runc" + packages = ["libcontainer/user"] + pruneopts = "UT" + revision = "baf6536d6259209c3edfa2b22237af82942d3dfa" + version = "v0.1.1" + [[projects]] branch = "master" digest = "1:3bf17a6e6eaa6ad24152148a631d18662f7212e21637c2699bff3369b7f00fa2" @@ -744,7 +838,7 @@ version = "v1.0.0" [[projects]] - digest = "1:32c1cb4c09d4eb89294d52c2df910ad981aa8d47f06fee22f0112702cf5f4e53" + digest = "1:93a746f1060a8acbcf69344862b2ceced80f854170e1caae089b2834c5fbf7f4" name = "github.com/prometheus/client_golang" packages = [ "prometheus", @@ -757,14 +851,14 @@ [[projects]] branch = "master" - digest = "1:0f37e09b3e92aaeda5991581311f8dbf38944b36a3edec61cc2d1991f527554a" + digest = "1:2d5cd61daa5565187e1d96bae64dbbc6080dacf741448e9629c64fd93203b0d4" name = "github.com/prometheus/client_model" packages = ["go"] pruneopts = "UT" revision = "fd36f4220a901265f90734c3183c5f0c91daa0b8" [[projects]] - digest = "1:404f5b09a91546084d2d791b7148df956e7ce42cd75414649ee20aefac288e51" + digest = "1:35cf6bdf68db765988baa9c4f10cc5d7dda1126a54bd62e252dbcd0b1fc8da90" name = "github.com/prometheus/common" packages = [ "expfmt", @@ -777,7 +871,7 @@ [[projects]] branch = "master" - digest = "1:66ab3a15e2472626455c057a3010b54b5ed1e5194517035e1b74d9a620c6bb6a" + digest = "1:5833c61ebbd625a6bad8e5a1ada2b3e13710cf3272046953a2c8915340fe60a3" name = "github.com/prometheus/procfs" packages = [ ".", @@ -805,15 +899,15 @@ version = "v1.2.0" [[projects]] - branch = "master" - digest = "1:bfa8819cf03174788453b572ddef4dfcd7d43fdcbc661c7aa9bd9d15852cdcd8" + digest = "1:e01b05ba901239c783dfe56450bcde607fc858908529868259c9a8765dc176d0" name = "github.com/spf13/cobra" packages = [ ".", "doc", ] pruneopts = "UT" - revision = "67fc4837d267bc9bfd6e47f77783fcc3dffc68de" + revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385" + version = "v0.0.3" [[projects]] digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2" @@ -824,7 +918,7 @@ version = "v1.0.3" [[projects]] - digest = "1:9b3581602b9ee17983e3db9a4695c57fe1143d86bfc1d98600d0f97749027593" + digest = "1:8ff03ccc603abb0d7cce94d34b613f5f6251a9e1931eba1a3f9888a9029b055c" name = "github.com/stretchr/testify" packages = [ "assert", @@ -890,7 +984,7 @@ revision = "b21fdbd4370f3717f3bbd2bf41c223bc273068e6" [[projects]] - digest = "1:996e7a159bad6d51ceffbd64d17998356fbb5601dc6ed4a67d77ace392f9cdce" + digest = "1:2ae8314c44cd413cfdb5b1df082b350116dd8d2fff973e62c01b285b7affd89e" name = "go.opencensus.io" packages = [ ".", @@ -915,9 +1009,11 @@ [[projects]] branch = "master" - digest = "1:64c445cda3e93ef79c10f21aaef5908e3b330729f1e3ca2fb6cb728b9cc775b3" + digest = "1:91e034b0c63a4c747c6e9dc8285f36dc5fe699a78d34de0a663895e52ff673dd" name = "golang.org/x/crypto" packages = [ + "bcrypt", + "blowfish", "cast5", "ed25519", "ed25519/internal/edwards25519", @@ -938,7 +1034,7 @@ [[projects]] branch = "master" - digest = "1:6492d22c047269b7c1000e7794efe28ade2f0e14ce4e89d38cd7a5d25cd31c07" + digest = "1:80c256dfc14840e13293d6404b7774e497187bd15a53f943f99bfaef4bbb2e42" name = "golang.org/x/net" packages = [ "bpf", @@ -950,9 +1046,11 @@ "idna", "internal/iana", "internal/socket", + "internal/socks", "internal/timeseries", "ipv4", "ipv6", + "proxy", "publicsuffix", "trace", ] @@ -961,7 +1059,7 @@ [[projects]] branch = "master" - digest = "1:45e8fd4fd9d1f254a2166bb2d837a34274a9e2b16c23ada2f1f03c421c8ef704" + digest = "1:23443edff0740e348959763085df98400dcfd85528d7771bb0ce9f5f2754ff4a" name = "golang.org/x/oauth2" packages = [ ".", @@ -975,7 +1073,7 @@ [[projects]] branch = "master" - digest = "1:a4b267e58eba4f8efcf35d73d68e142126b0ce508c099d418f56a5f0179f59ef" + digest = "1:04a5b0e4138f98eef79ce12a955a420ee358e9f787044cc3a553ac3c3ade997e" name = "golang.org/x/sync" packages = [ "errgroup", @@ -986,7 +1084,7 @@ [[projects]] branch = "master" - digest = "1:dc09916156071dc2a710631c3f726fc7b3d0dd4996ccddaad79042272f516c2f" + digest = "1:3d5e79e10549fd9119cbefd614b6d351ef5bd0be2f2b103a4199788e784cbc68" name = "golang.org/x/sys" packages = [ "unix", @@ -996,7 +1094,7 @@ revision = "b4a75ba826a64a70990f11a225237acd6ef35c9f" [[projects]] - digest = "1:8e06c0384eb063fd67edc3cbc0be213b7f88a88c2a851a904c4319aaa19e1224" + digest = "1:28756bf526c1af662d24519f2fa7abca7237bebb06e3e02941b2b6e5b6ceb7b9" name = "golang.org/x/text" packages = [ "collate", @@ -1035,14 +1133,14 @@ [[projects]] branch = "master" - digest = "1:55afc21c324dec8966cef5e8e7f0d7662efa943e30dc4d2a8e1699824c8fce5c" + digest = "1:5f003878aabe31d7f6b842d4de32b41c46c214bb629bb485387dbcce1edf5643" name = "google.golang.org/api" packages = ["support/bundler"] pruneopts = "UT" revision = "65a46cafb132eff435c7d1e0f439cc73c8eebb85" [[projects]] - digest = "1:0b4626f7673aa8961ae4d08df0d492a3d902e5f8356a1cab39ea598326c7f573" + digest = "1:fa026a5c59bd2df343ec4a3538e6288dcf4e2ec5281d743ae82c120affe6926a" name = "google.golang.org/appengine" packages = [ ".", @@ -1069,7 +1167,7 @@ revision = "bd9b4fb69e2ffd37621a6caa54dcbead29b546f2" [[projects]] - digest = "1:851ba93ee00a247214f894bb3e85bb00d260a4e536e15539b2b2831a0405162f" + digest = "1:9edd250a3c46675d0679d87540b30c9ed253b19bd1fd1af08f4f5fb3c79fc487" name = "google.golang.org/grpc" packages = [ ".", @@ -1118,7 +1216,7 @@ version = "v0.9.1" [[projects]] - digest = "1:bb0ec423b815fd5b98b33bfae448c77cbe4febe0b344deb8e5cd1ebbc15649a5" + digest = "1:0c9d7630c981ff09c7d297db73b3a94358e6572e8de063853c38d1e2c500272e" name = "gopkg.in/square/go-jose.v1" packages = [ ".", @@ -1131,7 +1229,7 @@ version = "v1.1.2" [[projects]] - digest = "1:2290981a4c5f7bb9d1572fd0ef257fff17ee36d7c42bd5a69cdbdb3b753036dd" + digest = "1:005cbf8b937fcb1694b9dbb845b0aef618627be7faf7bb330eb2490e3f506ef8" name = "gopkg.in/square/go-jose.v2" packages = [ ".", @@ -1155,7 +1253,7 @@ [[projects]] branch = "release-1.14" - digest = "1:afe9083e1570571e0d8639515b577c54fb838fe17ecf9cc23403de3209e5139d" + digest = "1:7b8963a5f5bb45d0b3c18806459c02b2284a4267c8c7e9444606e95b95b51fe3" name = "k8s.io/api" packages = [ "admission/v1beta1", @@ -1210,7 +1308,7 @@ [[projects]] branch = "release-1.14" - digest = "1:c96059b6dbbebcfb60546204e7b4db08c6c663770211f2f6859d04fc8cf381a1" + digest = "1:c10a6fffe98df81cdaaeef73a38e4d669d59d2b46a3fe18565d5eb7264d19255" name = "k8s.io/apimachinery" packages = [ "pkg/api/equality", @@ -1272,7 +1370,7 @@ [[projects]] branch = "release-1.14" - digest = "1:ecb8670ee370bbd8174cc4012f6480171e4738ffa532fa340127ab89328a8094" + digest = "1:71c95d81a294dcee66147ff711896968d512b05df9bf6183cb289c6570c60b4f" name = "k8s.io/apiserver" packages = [ "pkg/authentication/authenticator", @@ -1286,7 +1384,7 @@ [[projects]] branch = "master" - digest = "1:5439c463e465209609af21f7e384fd51cb5a7c839c35619f6acb000343ccc04f" + digest = "1:1617a9d82f05ddcd88c9f3638359de6c12012f61f0fea110a37f5fc1861dc48b" name = "k8s.io/cli-runtime" packages = [ "pkg/genericclioptions", @@ -1306,7 +1404,7 @@ revision = "44a48934c135b31e4f1c0d12e91d384e1cb2304c" [[projects]] - digest = "1:f90ed84da7b41cd354ad9e8980a0d44b0371ff716c25efb157b6008454a23324" + digest = "1:8774c035808c344c148ba5135b282d487561233ee3be10f6115ea9a9da5e1c56" name = "k8s.io/client-go" packages = [ "discovery", @@ -1459,7 +1557,7 @@ [[projects]] branch = "master" - digest = "1:5f615d024e16938abfe73784c156d5da647ef74e8d16ebb1cf2e2087f7b6ddcf" + digest = "1:d8f05387026197d55244f5866ea172e360c3f1602bea51ba90c72a7a43ecdce6" name = "k8s.io/kube-openapi" packages = [ "pkg/common", @@ -1472,7 +1570,7 @@ [[projects]] branch = "release-1.14" - digest = "1:0c96fb4f93ffc4e978e32e5194b98a7078b3387db2991eeaaad8db202c006f46" + digest = "1:3e8a09f07ca1d0163720064d0bcb567fdc85338e02bd63c6d84786be8b24ebdb" name = "k8s.io/kubernetes" packages = [ "pkg/api/legacyscheme", @@ -1597,7 +1695,7 @@ [[projects]] branch = "master" - digest = "1:12092f1fa23f0a229362b8ab287e9acf865599986bfdbd34c2f63912462ee756" + digest = "1:97af0e3995afafd52fc0135efaa3290f1f3326fd184e0ef48060f76fab51c6ef" name = "k8s.io/utils" packages = [ "buffer", @@ -1621,7 +1719,7 @@ source = "https://github.com/dmcgowan/letsencrypt.git" [[projects]] - digest = "1:64e0041f63a38381fcc692dc48af9e7cd38844423f2a8ca86c609f1806547c92" + digest = "1:cb422c75bab66a8339a38b64e837f3b28f3d5a8c06abd7b9048f420363baa18a" name = "sigs.k8s.io/kustomize" packages = [ "pkg/commands/build", @@ -1678,12 +1776,15 @@ "github.com/asaskevich/govalidator", "github.com/containerd/containerd/reference", "github.com/containerd/containerd/remotes", - "github.com/containerd/containerd/remotes/docker", + "github.com/deislabs/oras/pkg/auth", + "github.com/deislabs/oras/pkg/auth/docker", "github.com/deislabs/oras/pkg/content", "github.com/deislabs/oras/pkg/oras", "github.com/docker/distribution/configuration", "github.com/docker/distribution/registry", + "github.com/docker/distribution/registry/auth/htpasswd", "github.com/docker/distribution/registry/storage/driver/inmemory", + "github.com/docker/docker/pkg/term", "github.com/docker/go-units", "github.com/evanphx/json-patch", "github.com/ghodss/yaml", @@ -1701,6 +1802,7 @@ "github.com/stretchr/testify/assert", "github.com/stretchr/testify/suite", "github.com/xeipuuv/gojsonschema", + "golang.org/x/crypto/bcrypt", "golang.org/x/crypto/openpgp", "golang.org/x/crypto/openpgp/clearsign", "golang.org/x/crypto/openpgp/errors", diff --git a/Gopkg.toml b/Gopkg.toml index dc3350f1c..a35ccded0 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -44,7 +44,7 @@ [[constraint]] name = "github.com/deislabs/oras" - version = "~0.3.3" + version = "0.4.0" [[constraint]] name = "github.com/docker/go-units" @@ -76,11 +76,6 @@ branch = "master" source = "https://github.com/dmcgowan/letsencrypt.git" -# https://github.com/bugsnag/bugsnag-go/issues/96 -[[override]] - name = "github.com/bugsnag/bugsnag-go" - version = "=1.3.2" - # gopkg.in is broken # # https://github.com/golang/dep/issues/1760 diff --git a/cmd/helm/chart.go b/cmd/helm/chart.go index dd4af9273..293ab3635 100644 --- a/cmd/helm/chart.go +++ b/cmd/helm/chart.go @@ -18,14 +18,13 @@ package main import ( "io" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" "helm.sh/helm/pkg/action" ) const chartHelp = ` -This command consists of multiple subcommands to interact with charts and registries. +This command consists of multiple subcommands to work with the chart cache. It can be used to push, pull, tag, list, or remove Helm charts. Example usage: @@ -48,8 +47,3 @@ func newChartCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { ) return cmd } - -// TODO remove once WARN lines removed from oras or containerd -func init() { - logrus.SetLevel(logrus.ErrorLevel) -} diff --git a/cmd/helm/history.go b/cmd/helm/history.go index 699cf38ca..7ba4eb7b3 100644 --- a/cmd/helm/history.go +++ b/cmd/helm/history.go @@ -35,11 +35,11 @@ configures the maximum length of the revision list returned. The historical release set is printed as a formatted table, e.g: $ helm history angry-bird --max=4 - REVISION UPDATED STATUS CHART DESCRIPTION - 1 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 Initial install - 2 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 Upgraded successfully - 3 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 Rolled back to 2 - 4 Mon Oct 3 10:15:13 2016 deployed alpine-0.1.0 Upgraded successfully + REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION + 1 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Initial install + 2 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Upgraded successfully + 3 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Rolled back to 2 + 4 Mon Oct 3 10:15:13 2016 deployed alpine-0.1.0 1.0 Upgraded successfully ` func newHistoryCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { diff --git a/cmd/helm/registry.go b/cmd/helm/registry.go new file mode 100644 index 000000000..1ed885c83 --- /dev/null +++ b/cmd/helm/registry.go @@ -0,0 +1,45 @@ +/* +Copyright The Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "io" + + "github.com/spf13/cobra" + + "helm.sh/helm/pkg/action" +) + +const registryHelp = ` +This command consists of multiple subcommands to interact with registries. + +It can be used to login to or logout from a registry. +Example usage: + $ helm registry login [URL] +` + +func newRegistryCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { + cmd := &cobra.Command{ + Use: "registry", + Short: "login to or logout from a registry", + Long: registryHelp, + } + cmd.AddCommand( + newRegistryLoginCmd(cfg, out), + newRegistryLogoutCmd(cfg, out), + ) + return cmd +} diff --git a/cmd/helm/registry_login.go b/cmd/helm/registry_login.go new file mode 100644 index 000000000..d40b1dd44 --- /dev/null +++ b/cmd/helm/registry_login.go @@ -0,0 +1,134 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bufio" + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "strings" + + "github.com/docker/docker/pkg/term" + "github.com/spf13/cobra" + + "helm.sh/helm/cmd/helm/require" + "helm.sh/helm/pkg/action" +) + +const registryLoginDesc = ` +Authenticate to a remote registry. +` + +func newRegistryLoginCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { + var usernameOpt, passwordOpt string + var passwordFromStdinOpt bool + + cmd := &cobra.Command{ + Use: "login [host]", + Short: "login to a registry", + Long: registryLoginDesc, + Args: require.MinimumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + hostname := args[0] + + username, password, err := getUsernamePassword(usernameOpt, passwordOpt, passwordFromStdinOpt) + if err != nil { + return err + } + + return action.NewRegistryLogin(cfg).Run(out, hostname, username, password) + }, + } + + f := cmd.Flags() + f.StringVarP(&usernameOpt, "username", "u", "", "registry username") + f.StringVarP(&passwordOpt, "password", "p", "", "registry password or identity token") + f.BoolVarP(&passwordFromStdinOpt, "password-stdin", "", false, "read password or identity token from stdin") + + return cmd +} + +// Adapted from https://github.com/deislabs/oras +func getUsernamePassword(usernameOpt string, passwordOpt string, passwordFromStdinOpt bool) (string, string, error) { + var err error + username := usernameOpt + password := passwordOpt + + if passwordFromStdinOpt { + passwordFromStdin, err := ioutil.ReadAll(os.Stdin) + if err != nil { + return "", "", err + } + password = strings.TrimSuffix(string(passwordFromStdin), "\n") + password = strings.TrimSuffix(password, "\r") + } else if password == "" { + if username == "" { + username, err = readLine("Username: ", false) + if err != nil { + return "", "", err + } + username = strings.TrimSpace(username) + } + if username == "" { + password, err = readLine("Token: ", true) + if err != nil { + return "", "", err + } else if password == "" { + return "", "", errors.New("token required") + } + } else { + password, err = readLine("Password: ", true) + if err != nil { + return "", "", err + } else if password == "" { + return "", "", errors.New("password required") + } + } + } else { + fmt.Fprintln(os.Stderr, "WARNING! Using --password via the CLI is insecure. Use --password-stdin.") + } + + return username, password, nil +} + +// Copied/adapted from https://github.com/deislabs/oras +func readLine(prompt string, silent bool) (string, error) { + fmt.Print(prompt) + if silent { + fd := os.Stdin.Fd() + state, err := term.SaveState(fd) + if err != nil { + return "", err + } + term.DisableEcho(fd, state) + defer term.RestoreTerminal(fd, state) + } + + reader := bufio.NewReader(os.Stdin) + line, _, err := reader.ReadLine() + if err != nil { + return "", err + } + if silent { + fmt.Println() + } + + return string(line), nil +} diff --git a/cmd/helm/registry_logout.go b/cmd/helm/registry_logout.go new file mode 100644 index 000000000..099f4ee7b --- /dev/null +++ b/cmd/helm/registry_logout.go @@ -0,0 +1,43 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "io" + + "github.com/spf13/cobra" + + "helm.sh/helm/cmd/helm/require" + "helm.sh/helm/pkg/action" +) + +const registryLogoutDesc = ` +Remove credentials stored for a remote registry. +` + +func newRegistryLogoutCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { + return &cobra.Command{ + Use: "logout [host]", + Short: "logout from a registry", + Long: registryLogoutDesc, + Args: require.MinimumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + hostname := args[0] + return action.NewRegistryLogout(cfg).Run(out, hostname) + }, + } +} diff --git a/cmd/helm/root.go b/cmd/helm/root.go index 5a6f43d6e..f2124aba4 100644 --- a/cmd/helm/root.go +++ b/cmd/helm/root.go @@ -17,9 +17,11 @@ limitations under the License. package main // import "helm.sh/helm/cmd/helm" import ( + "context" "io" + "path/filepath" - "github.com/containerd/containerd/remotes/docker" + auth "github.com/deislabs/oras/pkg/auth/docker" "github.com/spf13/cobra" "helm.sh/helm/cmd/helm/require" @@ -68,10 +70,23 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string // Add the registry client based on settings // TODO: Move this elsewhere (first, settings.Init() must move) + // TODO: handle errors, dont panic + credentialsFile := filepath.Join(settings.Home.Registry(), registry.CredentialsFileBasename) + client, err := auth.NewClient(credentialsFile) + if err != nil { + panic(err) + } + resolver, err := client.Resolver(context.Background()) + if err != nil { + panic(err) + } actionConfig.RegistryClient = registry.NewClient(®istry.ClientOptions{ Out: out, + Authorizer: registry.Authorizer{ + Client: client, + }, Resolver: registry.Resolver{ - Resolver: docker.NewResolver(docker.ResolverOptions{}), + Resolver: resolver, }, CacheRootDir: settings.Home.Registry(), }) @@ -87,6 +102,9 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string newRepoCmd(out), newSearchCmd(out), newVerifyCmd(out), + + // registry/chart cache commands + newRegistryCmd(actionConfig, out), newChartCmd(actionConfig, out), // release commands diff --git a/cmd/helm/testdata/output/history-limit.txt b/cmd/helm/testdata/output/history-limit.txt index 48c900c86..92ce86edf 100644 --- a/cmd/helm/testdata/output/history-limit.txt +++ b/cmd/helm/testdata/output/history-limit.txt @@ -1,3 +1,3 @@ -REVISION UPDATED STATUS CHART DESCRIPTION -3 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 Release mock -4 1977-09-02 22:04:05 +0000 UTC deployed foo-0.1.0-beta.1 Release mock +REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION +3 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 1.0 Release mock +4 1977-09-02 22:04:05 +0000 UTC deployed foo-0.1.0-beta.1 1.0 Release mock diff --git a/cmd/helm/testdata/output/history.json b/cmd/helm/testdata/output/history.json index e16b5670e..364007f3c 100644 --- a/cmd/helm/testdata/output/history.json +++ b/cmd/helm/testdata/output/history.json @@ -1 +1 @@ -[{"revision":3,"updated":"1977-09-02 22:04:05 +0000 UTC","status":"superseded","chart":"foo-0.1.0-beta.1","description":"Release mock"},{"revision":4,"updated":"1977-09-02 22:04:05 +0000 UTC","status":"deployed","chart":"foo-0.1.0-beta.1","description":"Release mock"}] +[{"revision":3,"updated":"1977-09-02 22:04:05 +0000 UTC","status":"superseded","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock"},{"revision":4,"updated":"1977-09-02 22:04:05 +0000 UTC","status":"deployed","chart":"foo-0.1.0-beta.1","app_version":"1.0","description":"Release mock"}] diff --git a/cmd/helm/testdata/output/history.txt b/cmd/helm/testdata/output/history.txt index e2379f721..a6161b524 100644 --- a/cmd/helm/testdata/output/history.txt +++ b/cmd/helm/testdata/output/history.txt @@ -1,5 +1,5 @@ -REVISION UPDATED STATUS CHART DESCRIPTION -1 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 Release mock -2 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 Release mock -3 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 Release mock -4 1977-09-02 22:04:05 +0000 UTC deployed foo-0.1.0-beta.1 Release mock +REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION +1 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 1.0 Release mock +2 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 1.0 Release mock +3 1977-09-02 22:04:05 +0000 UTC superseded foo-0.1.0-beta.1 1.0 Release mock +4 1977-09-02 22:04:05 +0000 UTC deployed foo-0.1.0-beta.1 1.0 Release mock diff --git a/cmd/helm/testdata/output/history.yaml b/cmd/helm/testdata/output/history.yaml index 042b87118..fc2887068 100644 --- a/cmd/helm/testdata/output/history.yaml +++ b/cmd/helm/testdata/output/history.yaml @@ -1,9 +1,11 @@ -- chart: foo-0.1.0-beta.1 +- app_version: "1.0" + chart: foo-0.1.0-beta.1 description: Release mock revision: 3 status: superseded updated: 1977-09-02 22:04:05 +0000 UTC -- chart: foo-0.1.0-beta.1 +- app_version: "1.0" + chart: foo-0.1.0-beta.1 description: Release mock revision: 4 status: deployed diff --git a/cmd/helm/testdata/output/uninstall-purge.txt b/cmd/helm/testdata/output/uninstall-keep-history.txt similarity index 100% rename from cmd/helm/testdata/output/uninstall-purge.txt rename to cmd/helm/testdata/output/uninstall-keep-history.txt diff --git a/cmd/helm/uninstall.go b/cmd/helm/uninstall.go index 1117465da..37da40666 100644 --- a/cmd/helm/uninstall.go +++ b/cmd/helm/uninstall.go @@ -27,8 +27,10 @@ import ( ) const uninstallDesc = ` -This command takes a release name, and then uninstalls the release from Kubernetes. -It removes all of the resources associated with the last release of the chart. +This command takes a release name and uninstalls the release. + +It removes all of the resources associated with the last release of the chart +as well as the release history, freeing it up for future use. Use the '--dry-run' flag to see which releases will be uninstalled without actually uninstalling them. @@ -41,7 +43,7 @@ func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { Use: "uninstall RELEASE_NAME [...]", Aliases: []string{"del", "delete", "un"}, SuggestFor: []string{"remove", "rm"}, - Short: "given a release name, uninstall the release from Kubernetes", + Short: "uninstall a release", Long: uninstallDesc, Args: require.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -64,7 +66,7 @@ func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { f := cmd.Flags() f.BoolVar(&client.DryRun, "dry-run", false, "simulate a uninstall") f.BoolVar(&client.DisableHooks, "no-hooks", false, "prevent hooks from running during uninstallation") - f.BoolVar(&client.Purge, "purge", false, "remove the release from the store and make its name free for later use") + f.BoolVar(&client.KeepHistory, "keep-history", false, "remove all associated resources and mark the release as deleted, but retain the release history") f.Int64Var(&client.Timeout, "timeout", 300, "time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks)") return cmd diff --git a/cmd/helm/uninstall_test.go b/cmd/helm/uninstall_test.go index b31928e8f..409019a3c 100644 --- a/cmd/helm/uninstall_test.go +++ b/cmd/helm/uninstall_test.go @@ -52,9 +52,9 @@ func TestUninstall(t *testing.T) { rels: []*release.Release{release.Mock(&release.MockReleaseOptions{Name: "aeneas"})}, }, { - name: "purge", - cmd: "uninstall aeneas --purge", - golden: "output/uninstall-purge.txt", + name: "keep history", + cmd: "uninstall aeneas --keep-history", + golden: "output/uninstall-keep-history.txt", rels: []*release.Release{release.Mock(&release.MockReleaseOptions{Name: "aeneas"})}, }, { diff --git a/docs/faq.md b/docs/faq.md index 4d37e8a24..85bfc5350 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -15,6 +15,16 @@ Here's an exhaustive list of all the major changes introduced in Helm 3. In Helm 3, Helm switched the Go import path over from `k8s.io/helm` to `helm.sh/helm`. If you intend to upgrade to the Helm 3 Go client libraries, make sure to change your import paths. +### Helm delete + +In order to better align the verbiage from other package managers, `helm delete` was re-named to +`helm uninstall`. `helm delete` is still retained as an alias to `helm uninstall`, so either form +can be used. + +In Helm 2, in order to purge the release ledger, the `--purge` flag had to be provided. This +functionality is now enabled by default. To retain the previous behaviour, use +`helm uninstall --keep-history`. + ## Installing diff --git a/docs/install.md b/docs/install.md index 3bd5beeb5..cc684bf45 100755 --- a/docs/install.md +++ b/docs/install.md @@ -82,18 +82,16 @@ You must have a working Go environment with ```console $ cd $GOPATH -$ mkdir -p src/k8s.io -$ cd src/k8s.io +$ mkdir -p src/helm.sh +$ cd src/helm.sh $ git clone https://github.com/helm/helm.git $ cd helm -$ make bootstrap build +$ make ``` -The `bootstrap` target will attempt to install dependencies, rebuild the -`vendor/` tree, and validate configuration. - -The `build` target will compile `helm` and place it in `bin/helm`. - +If required, it will first install dependencies, rebuild the +`vendor/` tree, and validate configuration. It will then compile `helm` and +place it in `bin/helm`. ## Conclusion diff --git a/pkg/action/history.go b/pkg/action/history.go index 290154986..36a11710e 100644 --- a/pkg/action/history.go +++ b/pkg/action/history.go @@ -34,6 +34,7 @@ type releaseInfo struct { Updated string `json:"updated"` Status string `json:"status"` Chart string `json:"chart"` + AppVersion string `json:"app_version"` Description string `json:"description"` } @@ -142,11 +143,13 @@ func getReleaseHistory(rls []*release.Release) (history releaseHistory) { s := r.Info.Status.String() v := r.Version d := r.Info.Description + a := formatAppVersion(r.Chart) rInfo := releaseInfo{ Revision: v, Status: s, Chart: c, + AppVersion: a, Description: d, } if !r.Info.LastDeployed.IsZero() { @@ -162,10 +165,10 @@ func getReleaseHistory(rls []*release.Release) (history releaseHistory) { func formatAsTable(releases releaseHistory) []byte { tbl := uitable.New() - tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "DESCRIPTION") + tbl.AddRow("REVISION", "UPDATED", "STATUS", "CHART", "APP VERSION", "DESCRIPTION") for i := 0; i <= len(releases)-1; i++ { r := releases[i] - tbl.AddRow(r.Revision, r.Updated, r.Status, r.Chart, r.Description) + tbl.AddRow(r.Revision, r.Updated, r.Status, r.Chart, r.AppVersion, r.Description) } return tbl.Bytes() } @@ -178,3 +181,12 @@ func formatChartname(c *chart.Chart) string { } return fmt.Sprintf("%s-%s", c.Name(), c.Metadata.Version) } + +func formatAppVersion(c *chart.Chart) string { + if c == nil || c.Metadata == nil { + // This is an edge case that has happened in prod, though we don't + // know how: https://github.com/helm/helm/issues/1347 + return "MISSING" + } + return c.AppVersion() +} diff --git a/pkg/action/registry_login.go b/pkg/action/registry_login.go new file mode 100644 index 000000000..2192d49e8 --- /dev/null +++ b/pkg/action/registry_login.go @@ -0,0 +1,38 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package action + +import ( + "io" +) + +// RegistryLogin performs a registry login operation. +type RegistryLogin struct { + cfg *Configuration +} + +// NewRegistryLogin creates a new RegistryLogin object with the given configuration. +func NewRegistryLogin(cfg *Configuration) *RegistryLogin { + return &RegistryLogin{ + cfg: cfg, + } +} + +// Run executes the registry login operation +func (a *RegistryLogin) Run(out io.Writer, hostname string, username string, password string) error { + return a.cfg.RegistryClient.Login(hostname, username, password) +} diff --git a/pkg/action/registry_logout.go b/pkg/action/registry_logout.go new file mode 100644 index 000000000..69add4163 --- /dev/null +++ b/pkg/action/registry_logout.go @@ -0,0 +1,38 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package action + +import ( + "io" +) + +// RegistryLogout performs a registry login operation. +type RegistryLogout struct { + cfg *Configuration +} + +// NewRegistryLogout creates a new RegistryLogout object with the given configuration. +func NewRegistryLogout(cfg *Configuration) *RegistryLogout { + return &RegistryLogout{ + cfg: cfg, + } +} + +// Run executes the registry logout operation +func (a *RegistryLogout) Run(out io.Writer, hostname string) error { + return a.cfg.RegistryClient.Logout(hostname) +} diff --git a/pkg/action/uninstall.go b/pkg/action/uninstall.go index e44b15583..11d1b5225 100644 --- a/pkg/action/uninstall.go +++ b/pkg/action/uninstall.go @@ -38,7 +38,7 @@ type Uninstall struct { DisableHooks bool DryRun bool - Purge bool + KeepHistory bool Timeout int64 } @@ -78,7 +78,7 @@ func (u *Uninstall) Run(name string) (*release.UninstallReleaseResponse, error) // TODO: Are there any cases where we want to force a delete even if it's // already marked deleted? if rel.Info.Status == release.StatusUninstalled { - if u.Purge { + if !u.KeepHistory { if err := u.purgeReleases(rels...); err != nil { return nil, errors.Wrap(err, "uninstall: Failed to purge the release") } @@ -119,7 +119,7 @@ func (u *Uninstall) Run(name string) (*release.UninstallReleaseResponse, error) rel.Info.Status = release.StatusUninstalled rel.Info.Description = "Uninstallation complete" - if u.Purge { + if !u.KeepHistory { u.cfg.Log("purge requested for %s", name) err := u.purgeReleases(rels...) return res, errors.Wrap(err, "uninstall: Failed to purge the release") diff --git a/pkg/chart/chart.go b/pkg/chart/chart.go index 92ad68cb1..c016d3e33 100644 --- a/pkg/chart/chart.go +++ b/pkg/chart/chart.go @@ -102,3 +102,11 @@ func (ch *Chart) ChartFullPath() string { func (ch *Chart) Validate() error { return ch.Metadata.Validate() } + +// AppVersion returns the appversion of the chart. +func (ch *Chart) AppVersion() string { + if ch.Metadata == nil { + return "" + } + return ch.Metadata.AppVersion +} diff --git a/pkg/chartutil/create.go b/pkg/chartutil/create.go index e9e5e12e1..8bf0fbf73 100644 --- a/pkg/chartutil/create.go +++ b/pkg/chartutil/create.go @@ -73,7 +73,7 @@ version: 0.1.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 0.1.0 +appVersion: 1.16.0 ` const defaultValues = `# Default values for %s. @@ -211,7 +211,7 @@ spec: spec: containers: - name: {{ .Chart.Name }} - image: "{{ .Values.image.repository }}:{{ .Release.AppVersion }}" + image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http diff --git a/pkg/engine/funcs.go b/pkg/engine/funcs.go index 2b927872f..936f91d3c 100644 --- a/pkg/engine/funcs.go +++ b/pkg/engine/funcs.go @@ -25,7 +25,7 @@ import ( "github.com/BurntSushi/toml" "github.com/Masterminds/sprig" "github.com/pkg/errors" - "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v2" ) // funcMap returns a mapping of all of the functions that Engine has. diff --git a/pkg/registry/authorizer.go b/pkg/registry/authorizer.go new file mode 100644 index 000000000..c601b59d4 --- /dev/null +++ b/pkg/registry/authorizer.go @@ -0,0 +1,28 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package registry // import "helm.sh/helm/pkg/registry" + +import ( + "github.com/deislabs/oras/pkg/auth" +) + +type ( + // Authorizer handles registry auth operations + Authorizer struct { + auth.Client + } +) diff --git a/pkg/registry/cache.go b/pkg/registry/cache.go index 39dec1467..ccedd1e54 100644 --- a/pkg/registry/cache.go +++ b/pkg/registry/cache.go @@ -29,7 +29,7 @@ import ( "time" orascontent "github.com/deislabs/oras/pkg/content" - "github.com/docker/go-units" + units "github.com/docker/go-units" checksum "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" diff --git a/pkg/registry/client.go b/pkg/registry/client.go index a2244f816..588961d02 100644 --- a/pkg/registry/client.go +++ b/pkg/registry/client.go @@ -28,27 +28,34 @@ import ( "helm.sh/helm/pkg/chart" ) +const ( + CredentialsFileBasename = "config.json" +) + type ( // ClientOptions is used to construct a new client ClientOptions struct { Out io.Writer + Authorizer Authorizer Resolver Resolver CacheRootDir string } // Client works with OCI-compliant registries and local Helm chart cache Client struct { - out io.Writer - resolver Resolver - cache *filesystemCache // TODO: something more robust + out io.Writer + authorizer Authorizer + resolver Resolver + cache *filesystemCache // TODO: something more robust } ) // NewClient returns a new registry client with config func NewClient(options *ClientOptions) *Client { return &Client{ - out: options.Out, - resolver: options.Resolver, + out: options.Out, + resolver: options.Resolver, + authorizer: options.Authorizer, cache: &filesystemCache{ out: options.Out, rootDir: options.CacheRootDir, @@ -57,6 +64,26 @@ func NewClient(options *ClientOptions) *Client { } } +// Login logs into a registry +func (c *Client) Login(hostname string, username string, password string) error { + err := c.authorizer.Login(context.Background(), hostname, username, password) + if err != nil { + return err + } + fmt.Fprint(c.out, "Login succeeded\n") + return nil +} + +// Logout logs out of a registry +func (c *Client) Logout(hostname string) error { + err := c.authorizer.Logout(context.Background(), hostname) + if err != nil { + return err + } + fmt.Fprint(c.out, "Logout succeeded\n") + return nil +} + // PushChart uploads a chart to a registry func (c *Client) PushChart(ref *Reference) error { c.setDefaultTag(ref) @@ -65,7 +92,7 @@ func (c *Client) PushChart(ref *Reference) error { if err != nil { return err } - err = oras.Push(context.Background(), c.resolver, ref.String(), c.cache.store, layers) + _, err = oras.Push(context.Background(), c.resolver, ref.String(), c.cache.store, layers) if err != nil { return err } @@ -82,7 +109,7 @@ func (c *Client) PushChart(ref *Reference) error { func (c *Client) PullChart(ref *Reference) error { c.setDefaultTag(ref) fmt.Fprintf(c.out, "%s: Pulling from %s\n", ref.Tag, ref.Repo) - layers, err := oras.Pull(context.Background(), c.resolver, ref.String(), c.cache.store, KnownMediaTypes()...) + _, layers, err := oras.Pull(context.Background(), c.resolver, ref.String(), c.cache.store, oras.WithAllowedMediaTypes(KnownMediaTypes())) if err != nil { return err } diff --git a/pkg/registry/client_test.go b/pkg/registry/client_test.go index fd6285c15..5b2f06eb5 100644 --- a/pkg/registry/client_test.go +++ b/pkg/registry/client_test.go @@ -21,22 +21,29 @@ import ( "context" "fmt" "io" + "io/ioutil" "net" "os" + "path/filepath" "testing" "time" - "github.com/containerd/containerd/remotes/docker" + auth "github.com/deislabs/oras/pkg/auth/docker" "github.com/docker/distribution/configuration" "github.com/docker/distribution/registry" + _ "github.com/docker/distribution/registry/auth/htpasswd" _ "github.com/docker/distribution/registry/storage/driver/inmemory" "github.com/stretchr/testify/suite" + "golang.org/x/crypto/bcrypt" "helm.sh/helm/pkg/chart" ) var ( - testCacheRootDir = "helm-registry-test" + testCacheRootDir = "helm-registry-test" + testHtpasswdFileBasename = "authtest.htpasswd" + testUsername = "myuser" + testPassword = "mypass" ) type RegistryClientTestSuite struct { @@ -49,28 +56,52 @@ type RegistryClientTestSuite struct { func (suite *RegistryClientTestSuite) SetupSuite() { suite.CacheRootDir = testCacheRootDir + os.RemoveAll(suite.CacheRootDir) + os.Mkdir(suite.CacheRootDir, 0700) - // Init test client var out bytes.Buffer suite.Out = &out + credentialsFile := filepath.Join(suite.CacheRootDir, CredentialsFileBasename) + + client, err := auth.NewClient(credentialsFile) + suite.Nil(err, "no error creating auth client") + + resolver, err := client.Resolver(context.Background()) + suite.Nil(err, "no error creating resolver") + + // Init test client suite.RegistryClient = NewClient(&ClientOptions{ Out: suite.Out, + Authorizer: Authorizer{ + Client: client, + }, Resolver: Resolver{ - Resolver: docker.NewResolver(docker.ResolverOptions{}), + Resolver: resolver, }, CacheRootDir: suite.CacheRootDir, }) + // create htpasswd file (w BCrypt, which is required) + pwBytes, err := bcrypt.GenerateFromPassword([]byte(testPassword), bcrypt.DefaultCost) + suite.Nil(err, "no error generating bcrypt password for test htpasswd file") + htpasswdPath := filepath.Join(suite.CacheRootDir, testHtpasswdFileBasename) + err = ioutil.WriteFile(htpasswdPath, []byte(fmt.Sprintf("%s:%s\n", testUsername, string(pwBytes))), 0644) + suite.Nil(err, "no error creating test htpasswd file") + // Registry config config := &configuration.Configuration{} port, err := getFreePort() - if err != nil { - suite.Nil(err, "no error finding free port for test registry") - } + suite.Nil(err, "no error finding free port for test registry") suite.DockerRegistryHost = fmt.Sprintf("localhost:%d", port) config.HTTP.Addr = fmt.Sprintf(":%d", port) config.HTTP.DrainTimeout = time.Duration(10) * time.Second config.Storage = map[string]configuration.Parameters{"inmemory": map[string]interface{}{}} + config.Auth = configuration.Auth{ + "htpasswd": configuration.Parameters{ + "realm": "localhost", + "path": htpasswdPath, + }, + } dockerRegistry, err := registry.NewRegistry(context.Background(), config) suite.Nil(err, "no error creating test registry") @@ -82,7 +113,15 @@ func (suite *RegistryClientTestSuite) TearDownSuite() { os.RemoveAll(suite.CacheRootDir) } -func (suite *RegistryClientTestSuite) Test_0_SaveChart() { +func (suite *RegistryClientTestSuite) Test_0_Login() { + err := suite.RegistryClient.Login(suite.DockerRegistryHost, "badverybad", "ohsobad") + suite.NotNil(err, "error logging into registry with bad credentials") + + err = suite.RegistryClient.Login(suite.DockerRegistryHost, testUsername, testPassword) + suite.Nil(err, "no error logging into registry with good credentials") +} + +func (suite *RegistryClientTestSuite) Test_1_SaveChart() { ref, err := ParseReference(fmt.Sprintf("%s/testrepo/testchart:1.2.3", suite.DockerRegistryHost)) suite.Nil(err) @@ -101,7 +140,7 @@ func (suite *RegistryClientTestSuite) Test_0_SaveChart() { suite.Nil(err) } -func (suite *RegistryClientTestSuite) Test_1_LoadChart() { +func (suite *RegistryClientTestSuite) Test_2_LoadChart() { // non-existent ref ref, err := ParseReference(fmt.Sprintf("%s/testrepo/whodis:9.9.9", suite.DockerRegistryHost)) @@ -118,7 +157,7 @@ func (suite *RegistryClientTestSuite) Test_1_LoadChart() { suite.Equal("1.2.3", ch.Metadata.Version) } -func (suite *RegistryClientTestSuite) Test_2_PushChart() { +func (suite *RegistryClientTestSuite) Test_3_PushChart() { // non-existent ref ref, err := ParseReference(fmt.Sprintf("%s/testrepo/whodis:9.9.9", suite.DockerRegistryHost)) @@ -133,7 +172,7 @@ func (suite *RegistryClientTestSuite) Test_2_PushChart() { suite.Nil(err) } -func (suite *RegistryClientTestSuite) Test_3_PullChart() { +func (suite *RegistryClientTestSuite) Test_4_PullChart() { // non-existent ref ref, err := ParseReference(fmt.Sprintf("%s/testrepo/whodis:9.9.9", suite.DockerRegistryHost)) @@ -148,12 +187,12 @@ func (suite *RegistryClientTestSuite) Test_3_PullChart() { suite.Nil(err) } -func (suite *RegistryClientTestSuite) Test_4_PrintChartTable() { +func (suite *RegistryClientTestSuite) Test_5_PrintChartTable() { err := suite.RegistryClient.PrintChartTable() suite.Nil(err) } -func (suite *RegistryClientTestSuite) Test_5_RemoveChart() { +func (suite *RegistryClientTestSuite) Test_6_RemoveChart() { // non-existent ref ref, err := ParseReference(fmt.Sprintf("%s/testrepo/whodis:9.9.9", suite.DockerRegistryHost)) @@ -168,6 +207,14 @@ func (suite *RegistryClientTestSuite) Test_5_RemoveChart() { suite.Nil(err) } +func (suite *RegistryClientTestSuite) Test_7_Logout() { + err := suite.RegistryClient.Logout("this-host-aint-real:5000") + suite.NotNil(err, "error logging out of registry that has no entry") + + err = suite.RegistryClient.Logout(suite.DockerRegistryHost) + suite.Nil(err, "no error logging out of registry") +} + func TestRegistryClientTestSuite(t *testing.T) { suite.Run(t, new(RegistryClientTestSuite)) } diff --git a/pkg/release/mock.go b/pkg/release/mock.go index 0a3656a3b..3e8a8e361 100644 --- a/pkg/release/mock.go +++ b/pkg/release/mock.go @@ -71,8 +71,9 @@ func Mock(opts *MockReleaseOptions) *Release { if opts.Chart == nil { ch = &chart.Chart{ Metadata: &chart.Metadata{ - Name: "foo", - Version: "0.1.0-beta.1", + Name: "foo", + Version: "0.1.0-beta.1", + AppVersion: "1.0", }, Templates: []*chart.File{ {Name: "templates/foo.tpl", Data: []byte(MockManifest)}, diff --git a/scripts/completions.bash b/scripts/completions.bash index ededbb791..6c05963b4 100644 --- a/scripts/completions.bash +++ b/scripts/completions.bash @@ -287,8 +287,8 @@ _helm_delete() local_nonpersistent_flags+=("--dry-run") flags+=("--no-hooks") local_nonpersistent_flags+=("--no-hooks") - flags+=("--purge") - local_nonpersistent_flags+=("--purge") + flags+=("--keep-history") + local_nonpersistent_flags+=("--keep-history") flags+=("--timeout=") local_nonpersistent_flags+=("--timeout=") flags+=("--tls")