├── .gitignore ├── Goopfile ├── Goopfile.lock ├── LICENSE.md ├── Makefile ├── PATCHES.md ├── README.md ├── bin └── build_ruby ├── bindata.go ├── build_ruby.go ├── build_ruby_test.go └── data ├── Dockerfile-bionic-libssl-yjit.template ├── Dockerfile-bionic-libssl.template ├── Dockerfile-bionic-yjit.template ├── Dockerfile-bionic.template ├── Dockerfile.template ├── Gemfile.bionic ├── Gemfile.bionic.lock ├── Gemfile.template ├── Gemfile.template.lock └── patches ├── 1.0.0 ├── 01_for_tests └── 02_for_tests ├── 1.9.3-p551 └── 01_strict_hostname_checking.patch ├── 2.0.0-p0 └── 01_readline.patch ├── 2.0.0-p195 └── 01_readline.patch ├── 2.0.0-p247 └── 01_readline.patch ├── 2.0.0-p353 └── 01_readline.patch ├── 2.0.0-p451 └── 01_readline.patch ├── 2.1.0 └── 01_readline.patch └── 2.1.1 └── 01_readline.patch /.gitignore: -------------------------------------------------------------------------------- 1 | ruby*deb 2 | ruby*rpm 3 | # bin/build_ruby 4 | *.a 5 | *.o 6 | *.so 7 | .DS_Store 8 | bindata.go 9 | RELEASE.md 10 | .vendor 11 | -------------------------------------------------------------------------------- /Goopfile: -------------------------------------------------------------------------------- 1 | github.com/google/uuid/uuid 2 | github.com/urfave/cli 3 | github.com/fsouza/go-dockerclient -------------------------------------------------------------------------------- /Goopfile.lock: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml #3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 2 | github.com/cpuguy83/go-md2man #eda4fa589184806b8720ea3b9146491209877a10 3 | github.com/docker/docker #6f4fbef82718212e593626419182f31a9f604316 4 | github.com/docker/go-units #519db1ee28dcc9fd2474ae59fca29a810482bfb1 5 | github.com/fsouza/go-dockerclient #a958d2e31b6c581391fe589cf11c2d208ae03e9f 6 | github.com/google/uuid/uuid #c2e93f3ae59f2904160ceaab466009f965df46d6 7 | github.com/gorilla/mux #884b5ffcbd3a11b730f0b75f5c86ac408753c34d 8 | github.com/urfave/cli #a221e662f14fd7404302444a5c4293409a401210 9 | gopkg.in/yaml.v2 #f221b8435cfb71e54062f6c6e99e9ade30b124d5 10 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 by Will Jessop 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: assets 2 | GO111MODULE=off $(GOPATH)/bin/goop go build -o bin/build_ruby 3 | 4 | setup: 5 | brew install go-bindata 6 | go install github.com/karmakaze/goop@latest 7 | 8 | test: assets 9 | $GOPATH/bin/goop go test 10 | 11 | assets: 12 | go-bindata data/... 13 | 14 | clean: 15 | rm -f bin/* 16 | rm -f *deb 17 | 18 | # Break the rules as goop likes to exit 1 for various upstream reasons that 19 | # won't break the build. Less confusing this way. 20 | deps: 21 | $(GOPATH)/bin/goop install || true 22 | mv .vendor/tmp/* .vendor/ || true 23 | echo "This likes to exit 1 - don't be alarmed, try the build." 24 | 25 | update_deps: 26 | $(GOPATH)/bin/goop update 27 | 28 | package: 29 | $(GOPATH)/bin/goop go build -o /tmp/tmp_build 30 | GOOS=linux make 31 | $(eval VERSION = $(shell /tmp/tmp_build -v)) fpm -s dir -t deb -n build_ruby -a amd64 -v ${VERSION} bin 32 | -------------------------------------------------------------------------------- /PATCHES.md: -------------------------------------------------------------------------------- 1 | # Patches 2 | 3 | 1.9.3: 4 | 5 | Requires strict hostname checking patch to be secure. Currently only applied to -p551, if you need other 1.9.3 versions please submit a PR or open an issue and I'll add it. 6 | 7 | 2.0.0-pX: 8 | 9 | Some -p levels require a readline patch 10 | 11 | 2.1.0 and 2.1.1 require: 12 | 13 | https://gist.github.com/mislav/a18b9d7f0dc5b9efc162 14 | 15 | 2.1.2 builds cleanly 16 | 17 | 2.2.x build cleanly 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!NOTE] 2 | > Superceded by [basecamp/docker-ruby](https://github.com/basecamp/docker-ruby) 3 | 4 | # Build ruby packages 5 | 6 | *build_ruby* is a tool for building Ruby packages using Docker. Currently it can build .deb packages for Ubuntu and .rpms for Centos. The packages that it creates will install Ruby to ````/opt/ruby````, eg ````/opt/ruby2.1.0```` or ````/opt/ruby1.9.3-p429````. This is to allow for multiple concurrent installs (that we symlink into the rbenv dir) and is how we install Ruby at [Basecamp](https://basecamp.com/). I have a branch to default to a more traditional path that I might release if anyone is interested. 7 | 8 | ## Installation 9 | 10 | ### 1 Install Docker and tools: 11 | 12 | #### 1.1 Linux 13 | 14 | [Follow the instructions here to install Docker](http://docs.docker.io/installation/) 15 | [Follow the instructions here to install Go if necessary](https://go.dev/doc/install) 16 | 17 | #### 1.2 OS X 18 | 19 | [Follow the instructions here to install Docker](https://docs.docker.com/engine/installation/mac/) to install Docker for Mac. 20 | 21 | If you need to install `go` on your Mac, best install it through Homebrew: 22 | 23 | ``` 24 | brew install go 25 | go version 26 | ``` 27 | Please note that in newer installations of Go, `GOPATH` is assumed at your $HOME/go. For this repository to build however, you'll still need to explicitly set the GOPATH variable to run `make`. 28 | 29 | ``` 30 | echo 'export GOPATH=$HOME/go' >> ~/.bash_profile 31 | source ~/.bash_profile 32 | ``` 33 | 34 | #### Install pre-requisite tools and dependencies 35 | 36 | make setup 37 | make deps 38 | 39 | ## Running it 40 | 41 | make 42 | 43 | ## Usage 44 | 45 | bin/build_ruby -d ubuntu:18.04 -a amd64 -i "37s~bionic" -r 2.4.1 46 | bin/build_ruby -d ubuntu:18.04:libssl -a amd64 -i "37s~bionic.libssl" -r 3.1.2 47 | 48 | # Ruby 3.2.0 + YJIT support 49 | bin/build_ruby -d ubuntu:18.04:yjit -a amd64 -i "37s~bionic" -r 3.2.0 50 | bin/build_ruby -d ubuntu:18.04:libssl-yjit -a amd64 -i "37s~bionic.libssl" -r 3.2.0 51 | 52 | ### Other options 53 | 54 | #### -c, --cpus 55 | 56 | Specify the number of CPUs to use in the make process. If omitted defaults to the number of CPUs in your local machine (useful if you're building using a local Docker daemon), but if you're building on a VM, or a remote Docker installation specify this number to match the CPUs available: 57 | 58 | bin/build_ruby -r 2.1.0 -c 16 59 | bin/build_ruby -r 2.1.0 --cpus 16 60 | 61 | ### Building 62 | 63 | Just run: 64 | 65 | make 66 | 67 | If you need to update the deps run: 68 | 69 | make update_deps 70 | 71 | See the Makefile for more functions. 72 | 73 | ### Testing 74 | 75 | _Known to be broken!_ 76 | 77 | make test 78 | 79 | ## Troubleshooting 80 | 81 | ### You get an error ````dial unix /var/run/docker.sock: no such file or directory```` 82 | 83 | 2014/05/08 21:50:45 dial unix /var/run/docker.sock: no such file or directory 84 | 85 | Make sure you ran ````export DOCKER_HOST=tcp://localhost:4243```` in the terminal you are trying to use docker/build_ruby from 86 | 87 | ## Errors while running `make` 88 | 89 | This repository collects its internal dependencies in `Goopfile.lock`. If you run into issues while running `make`, try upgrading a problematic package to a newer commit SHA. So far, that has helped solve cryptic nested dependency issues. 90 | 91 | ## Todo 92 | 93 | * Test that a package test is actually created, perhaps requiring Docker to be running 94 | * Support Other Linux distros/package types 95 | * Migrate out of `goop` dependency management 96 | 97 | ## How to contribute 98 | 99 | Here's the most direct way to get your work merged into the project: 100 | 101 | 1. Fork the project 102 | 2. Clone down your fork 103 | 3. Create a feature branch 104 | 4. Add your feature + tests 105 | 5. Document new features in the README 106 | 6. Make sure everything still passes by running the tests 107 | 7. If necessary, rebase your commits into logical chunks, without errors 108 | 8. Push the branch up 109 | 9. Send a pull request for your branch 110 | 111 | Take a look at the TODO list or known issues for some inspiration if you need it, or email me. If you're going to make a major change ask first to maje sure it's in line with the project goals. 112 | 113 | ## Authors 114 | 115 | * [Will Jessop](mailto:will@willj.net) 116 | 117 | ## Background reading 118 | 119 | * [The Docker API docs](http://docs.docker.io/reference/api/docker_remote_api_v1.10/) 120 | * [The Ruby download page](http://docs.docker.io/reference/api/docker_remote_api_v1.10/) 121 | * [The go-dockerclient lib](https://github.com/fsouza/go-dockerclient) 122 | * [go-bindata Github page](https://github.com/kevinburke/go-bindata) 123 | 124 | ## LICENSE 125 | 126 | See LICENSE.md 127 | -------------------------------------------------------------------------------- /bin/build_ruby: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basecamp/build_ruby/737e29f8d07c74d44dfedae275f8e4f08074708a/bin/build_ruby -------------------------------------------------------------------------------- /bindata.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "compress/gzip" 6 | "fmt" 7 | "io" 8 | "strings" 9 | ) 10 | 11 | func bindata_read(data []byte, name string) ([]byte, error) { 12 | gz, err := gzip.NewReader(bytes.NewBuffer(data)) 13 | if err != nil { 14 | return nil, fmt.Errorf("Read %q: %v", name, err) 15 | } 16 | 17 | var buf bytes.Buffer 18 | _, err = io.Copy(&buf, gz) 19 | gz.Close() 20 | 21 | if err != nil { 22 | return nil, fmt.Errorf("Read %q: %v", name, err) 23 | } 24 | 25 | return buf.Bytes(), nil 26 | } 27 | 28 | var _data_dockerfile_bionic_libssl_template = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x54\x61\x6f\xdc\x36\x0f\xfe\xee\x5f\x41\x24\x2f\x10\xe0\x45\x65\xe7\x92\x34\xcd\x65\xcb\x80\x22\x59\x8b\x60\x5b\x53\x5c\xd6\xdd\x87\xb5\x40\x65\x8b\xbe\xe3\x22\x4b\x86\x48\xe7\x92\x7a\xfe\xef\x83\xe4\xbb\xd4\x59\x3b\x7f\x30\xc8\x87\xa4\x44\x49\x0f\x9f\x7d\xb8\x71\xf6\x11\xda\xe0\x4d\x57\x21\x43\xd9\x91\x35\x0c\xb5\x0f\x10\xba\xf2\x11\x7e\xba\x80\xa3\xfc\x04\x4c\x87\x20\x1e\x64\x8d\xe0\x70\x83\x01\x7c\x8b\x8e\xd9\x66\xfb\xc0\x88\xb0\x16\x69\xf9\xbc\x28\x8e\xf3\x52\x33\x56\xba\x69\xf3\xca\x37\xc5\xd1\x7c\x76\x72\xf8\x6a\x5e\x94\x5d\x75\x87\xc2\xc5\xd1\xec\xf8\xe5\xe1\xe9\xfc\xb0\x10\x6f\x3c\x17\x27\x47\x87\xf3\xb3\x93\xf9\xec\xe8\x2c\xdb\xcf\xf6\x61\x89\xc0\x6b\xdf\x59\x03\x26\xf8\x16\x64\x4d\x0c\xf7\x3a\x90\x76\x02\x9b\x35\x3a\xd8\x20\x34\xfe\x1e\xa1\xc4\x47\xef\x0c\x94\xe4\x1d\x55\x59\xb6\x0f\x97\xda\x1d\x08\x74\x8c\xd0\xf7\xf9\x15\xb1\x04\x3f\x0c\xc0\xe4\x2a\x04\x92\x03\x86\xae\xec\x9c\x74\xe7\xb3\xb3\xfc\xf0\xe4\xdc\x52\x19\x3b\x7f\xb3\xb8\xf9\xed\x59\x20\x5b\x7c\x78\x07\xba\x15\xb5\x42\x81\xae\x35\x5a\xf0\x19\x44\x8e\x45\x5b\x0b\xea\x71\xbc\x25\x85\xcc\xe8\x84\xb4\x85\x8f\x19\x00\x80\xa5\xb2\x3a\x55\x06\xef\xa3\x55\xd7\xb4\x33\x57\xa6\x6c\x76\xb6\xab\xba\xc0\xc8\x2f\x93\xff\x54\x16\x50\x1b\x4b\x0e\x77\x59\xcc\x76\x67\x3e\xea\x66\xb4\xbf\x58\x2a\x67\xab\x49\x5d\xd5\x05\x3b\x3e\x52\xfc\xc5\x40\x6a\xf7\xcf\xbd\xa2\xe3\x50\x94\xe4\x8a\x15\x36\x7b\x2f\x60\x6f\xdb\x78\x34\xcb\xce\x19\x8b\x21\x9a\xea\x3e\xfe\x67\xf9\xec\x55\x7e\x9c\x7c\xe5\xbc\x0a\xc6\x57\x5f\x1d\xda\xfb\x94\xbd\xbe\xba\x82\xb7\xd8\xd4\x64\x11\x8a\xa9\x97\x5b\x5f\xdd\x41\xb1\xdd\x73\x5c\x78\xba\xdb\xa7\x2c\x85\x52\x97\xf1\x59\xfc\xc6\x59\xaf\xcd\x87\x60\x87\xe1\x6f\xd1\x01\xfc\xc3\x97\x4b\x28\xa4\x69\xb3\xbe\x0f\xda\xad\x10\xf2\xf7\x5a\xaa\x35\xf2\x30\xc4\x7d\xfa\x3e\x1f\x06\x28\xb2\xbe\x47\x67\x86\x21\x5b\xde\x2c\x7e\xb9\xba\x5e\xa4\x92\x22\x1d\xb9\xef\xf3\x45\x57\x3e\xfe\x81\x81\xc9\xbb\x61\x48\x1b\x46\xea\x12\x90\x83\xcf\xe9\x0e\x2c\x43\xf1\xff\xbc\x8d\x0b\x7f\xfe\x01\x8c\x87\x64\x82\x6a\x0f\xe1\x47\xf8\x1f\x45\xc8\x8d\xef\x7c\xf9\xe6\xd7\xd7\x6f\x6f\x2f\x0e\x54\xa3\x43\xb5\xbe\x78\x38\x3b\x55\xa7\x27\xa0\x6e\x8e\x41\xd5\xce\xab\x5a\xb3\xa8\x46\xcb\x1a\xd4\xea\x18\xd4\x6a\x65\x4a\x50\xcb\x44\x88\x25\x3e\x48\xd0\xa0\x96\xce\xab\xce\x75\x8c\x46\xb5\x3a\xe8\x06\x05\xc3\x88\xb6\x3a\xa0\x93\x35\x32\xf2\x08\x58\xef\x56\xe9\x37\xba\x0d\x31\x93\x5b\xa9\x9a\xd0\x1a\x45\x8e\x22\xad\xe8\x0b\x86\x98\xbe\x5d\x32\xcd\x42\x69\x11\xd4\xb2\xf5\xe4\x04\x83\xd2\x81\x62\x3f\xcb\x4d\x20\x41\xc5\x12\xc8\xad\x62\x85\xc1\xca\xea\xa0\x85\xbc\x53\xba\x8e\x99\x2c\x5a\xb0\x41\x27\xa0\x96\xd4\xb4\x96\x2a\x12\x55\x77\xae\x4a\x39\x93\xfc\x54\xdd\x06\xac\xb4\xa0\x99\x06\x78\x77\x92\xea\x0e\x8d\x2a\x49\xc6\x5e\x2b\xdf\xb4\x5a\x40\xb1\x98\x0b\x62\x3f\x3f\x9b\xcf\xcf\x67\xf3\xf9\x1c\x40\xd5\xef\xaf\x2f\x0f\x20\x2f\x2a\xef\x6a\x5a\x75\x01\x13\x71\x95\x6a\x03\xd6\xf4\x70\x51\xf8\x56\xd2\x3b\xfe\xfb\x19\xb7\x69\xe8\xe2\x69\x15\xaf\x75\x40\xb3\xc5\x0c\x71\x02\xb7\x24\x53\xc6\x57\xcf\xb3\x23\xc5\x54\x40\xab\x85\xee\x31\xdb\x87\x5b\xc4\x86\xa3\x74\xf9\x28\x73\xba\xae\xb1\x12\x60\xdf\x20\xcc\xf2\x39\x30\x06\x42\x86\x45\x57\x12\xf2\x0b\x28\x3b\x49\x12\x57\xf9\xa6\x24\x87\x06\x1a\x7d\x87\xc0\x82\xed\x79\x52\xa8\xf8\x45\xa6\x24\x58\xfd\x75\xf6\x24\x09\x57\x3f\xdf\xfe\x7e\x75\xbd\xb8\x48\xd4\xac\xdb\x26\x65\xcb\x5a\x0b\x04\xed\xd2\x92\xa9\x44\xa2\x8a\x25\x6b\x5b\xf8\x02\x36\x9a\xa1\x0c\xfe\x0e\x5d\x0e\xb7\xad\x25\x11\x72\x2b\xa0\x28\x40\x40\x4e\x7c\x5c\x67\xe3\x81\x31\x12\x4a\x52\x6b\x8d\x76\x86\x61\xe3\xc3\x1d\x43\x4d\x0e\xcf\xb3\x49\x4f\x7d\x9f\xbf\xeb\x9a\xcb\xf7\x1f\xb6\xd3\x30\xdd\xed\xdb\x36\xbf\xce\xd4\x38\x3a\x6d\xb3\xd5\x16\xc5\x60\x28\xec\x1c\x01\x83\xe5\xce\x71\xf0\xdd\xd9\xdb\x85\x75\x9c\xdb\xd7\xa1\x5a\x7f\x85\xee\xe1\x3f\x92\xfb\x3e\xbf\x16\x1c\xe9\x35\x0c\x63\xb2\x99\xc8\xe8\xc7\x09\xb4\xd3\xd3\x29\xf6\x24\xac\x53\xf0\x3b\x0a\x3b\x06\x9e\x89\xec\x34\xb0\x53\xdb\x29\xf6\x24\xbb\x4f\xe0\x37\xfa\xab\x46\xf5\x2a\x26\xb7\xd6\x42\xd1\xf7\xf9\x1b\xb2\xf8\x4e\x37\xf8\x74\x4e\xdf\x4a\xf6\x4f\x00\x00\x00\xff\xff\xdb\xb9\x89\xd9\x69\x07\x00\x00") 29 | 30 | func data_dockerfile_bionic_libssl_template() ([]byte, error) { 31 | return bindata_read( 32 | _data_dockerfile_bionic_libssl_template, 33 | "data/Dockerfile-bionic-libssl.template", 34 | ) 35 | } 36 | 37 | var _data_dockerfile_bionic_template = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x54\x4d\x6f\xe4\x36\x0c\xbd\xfb\x57\x10\x49\x81\x05\x8a\xc8\xde\x41\xda\x34\x93\x36\x87\x20\xd3\x2c\x82\xb6\x49\x30\x69\x3a\x87\xee\x02\x2b\x5b\xb4\x87\x8d\x3e\x0c\x89\xce\x97\xeb\xff\x5e\x48\x9e\x99\x38\xdd\xdd\x8b\x40\x3e\x3e\x4a\x94\x44\xbe\x8b\xe5\xf5\x1f\xd0\xf7\xf9\x82\x02\x7b\x37\x0c\xd9\xf2\xee\x0a\x64\xcb\xa2\x41\x86\xae\x55\x92\xf1\x0d\x44\x36\xb0\xd4\x1a\xc4\x33\x94\x1d\x69\x25\x30\x04\xb4\x4c\x52\xc3\xc7\x0c\x00\x40\x53\x59\x1d\x09\x85\x0f\xd1\xaa\x6b\xda\x9a\x8d\x2a\xcd\xd6\xb6\x55\xe7\x03\x86\x1f\x93\xbf\x4b\xf3\x28\x95\x26\x8b\x5b\x56\x08\x7a\x96\xbf\xdf\x7a\xcf\xd2\xe8\x64\xbf\x68\x2a\x67\xcd\x24\xb5\xea\xbc\x06\xdf\x95\xcf\x69\x89\x81\x54\xf1\xdf\x7b\x45\x17\x7c\x51\x92\x2d\x1a\x34\x7b\x07\xb0\xb7\xa9\x3d\x9a\x65\x67\x95\x46\x1f\x4d\xf1\x10\xd7\x59\x3e\xfb\x29\x3f\x4c\xbe\xb0\x4e\x78\xe5\xaa\x57\x87\xf6\x3e\x65\x67\x8b\x05\x7c\x40\x53\x93\x46\x28\xa6\x5e\xae\x5d\x75\x0f\xc5\xe6\xcc\x71\xe3\xe9\x69\x9f\xb2\x14\x4a\x55\xc6\x87\x76\x8f\x56\x3b\xa9\xee\xbc\x1e\x86\x7f\x59\x7a\x70\x4f\x2f\xe7\x50\xb0\x69\xb3\xbe\xf7\xd2\x36\x08\xf9\x8d\xe4\x6a\x8d\x61\x18\xe2\x39\x7d\x9f\x0f\x03\x14\x59\xdf\xa3\x55\xc3\x90\xad\xae\x97\xbf\x2d\x2e\x97\x29\xa5\x48\x57\xee\xfb\x7c\xd9\x95\xcf\x7f\xa1\x0f\xe4\xec\xe6\x13\x6b\xe7\x81\x80\x2c\x7c\x4e\x6f\xa0\x03\x14\xdf\xe7\x6d\xdc\xf8\xf3\xcf\xa0\x1c\x24\x13\x44\xfb\x1e\x7e\x81\xef\x28\x42\x76\xfc\xea\xf3\x8b\xdf\xcf\x3e\xdc\x9e\xbe\x13\x46\xfa\x6a\x7d\xfa\x74\x7c\x24\x8e\x7e\x00\x71\x7d\x08\xa2\xb6\x4e\xd4\x32\xb0\x30\x92\xd7\x20\x9a\x43\x10\x4d\xa3\x4a\x10\xab\xd4\x13\x2b\x7c\x62\x2f\x41\xac\xac\x13\x9d\xed\x02\x2a\xd1\x4a\x2f\x0d\x32\xfa\x11\x6d\xa5\x47\xcb\x6b\x0c\x18\x46\x40\x3b\xdb\xa4\x65\x74\x0d\x85\x40\xb6\x11\x35\xa1\x56\x82\x2c\xc5\xce\xa2\x17\xf4\x91\xbe\xd9\xf2\x41\x7a\x92\xa5\x46\x10\xab\xd6\x91\x65\xf4\x42\x7a\x8a\xf5\xac\x1e\x3d\x31\x8a\xc0\x9e\x6c\x13\x33\x14\x56\x5a\x7a\xc9\xe4\xac\x90\x75\x64\x06\x96\x8c\x06\x2d\x83\x58\x91\x69\x35\x55\xc4\xa2\xee\x6c\x95\x38\x13\x7e\xca\x6e\x3d\x56\x92\x51\x4d\x03\x61\x7b\x93\xea\x1e\x95\x28\x89\xc7\x5a\x2b\x67\x5a\xc9\x20\x02\xab\x53\x0a\x6e\x7e\x3c\x9f\x9f\xcc\xe6\xf3\x39\x80\xa8\x6f\x2e\xcf\xdf\x41\x5e\x54\xce\xd6\xd4\x74\x1e\x53\xe3\x0a\xd1\x7a\xac\xe9\xe9\xb4\x70\x2d\xa7\x7f\xfc\xff\x37\x6e\x68\x68\xe3\x6d\x45\x58\x4b\x8f\x6a\x83\x29\x0a\x09\xdc\x34\x99\x50\xae\x7a\xcb\x8e\x2d\x26\x3c\x6a\xc9\xf4\x80\xd9\x3e\xdc\x22\x9a\x00\xec\xc0\x59\xfd\x0c\xb2\xae\xb1\x62\x08\xce\x20\xcc\xf2\x39\x04\xf4\x84\x01\x96\x5d\x49\x18\x0e\xa0\xec\x18\x78\x8d\x50\x39\x53\x92\x45\x05\x46\xde\x23\x04\xc6\xf6\x24\xdb\xcf\xf6\xe3\xd0\x41\xec\x94\x04\x8b\x7f\x8e\x77\xaa\xb0\xf8\xf5\xf6\xcf\xc5\xe5\xf2\x34\xb5\x66\xdd\x9a\xc4\xe6\xb5\x64\xf0\xd2\xa6\x2d\x53\x0a\xaf\xd1\x8e\xd6\x26\xf1\x00\x1e\x65\x80\xd2\xbb\x7b\xb4\x39\xdc\xb6\x9a\x98\xc9\x36\x40\x51\x83\x80\x2c\xbb\xb8\xcf\xa3\x83\x80\xb1\xa1\x38\x95\x66\xa4\x55\x01\x1e\x9d\xbf\x0f\x50\x93\xc5\x93\x6c\x52\x53\xdf\xe7\x57\x9d\x39\xbf\xb9\xdb\x4c\xc3\xf4\xb4\x2f\xcb\x7c\x9d\xa9\x71\x74\x5a\xb3\xd1\x16\x11\x40\x91\xdf\x3a\x0c\x0a\xcb\xad\x63\xe1\xab\xb3\xb7\x0d\xcb\x38\xb7\x67\xbe\x5a\xbf\x42\x0f\xf0\x0d\x72\xdf\xe7\x97\x8c\x63\x7b\x0d\xc3\x48\x56\x13\x25\xfd\x38\x81\xb6\x92\x3a\xc5\x76\xda\x3a\x05\xbf\x22\xb2\x63\xe0\x8d\xce\x4e\x03\x13\xc1\x9d\xc2\x3b\xe5\xdd\x81\x5f\x48\xb0\x18\x05\xac\x98\x3c\x5c\x0b\x45\xdf\xe7\x17\xa4\xf1\x4a\x1a\xdc\x5d\xd5\xb5\x9c\xfd\x17\x00\x00\xff\xff\x50\x85\x58\xfc\x74\x06\x00\x00") 38 | 39 | func data_dockerfile_bionic_template() ([]byte, error) { 40 | return bindata_read( 41 | _data_dockerfile_bionic_template, 42 | "data/Dockerfile-bionic.template", 43 | ) 44 | } 45 | 46 | var _data_gemfile_bionic = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x14\xca\x31\x0e\xc2\x30\x0c\x05\xd0\xdd\xa7\xf8\x12\x83\x17\xe4\x12\x24\x16\x56\x4e\x42\x5b\x93\x7a\x48\x53\xd9\x8e\x80\xdb\x23\xf6\x77\xc2\xc3\xf5\x99\xba\xe2\x6d\xb9\xc1\xc7\xfc\xc5\x55\x6e\xf2\xc1\x08\x5d\x61\x3b\x66\xeb\xbb\x2d\x44\xd1\x87\x2f\x0a\xde\x32\x8f\xb8\x4f\xd3\x9f\x56\x6d\x21\xdd\x2b\x13\x55\x6d\xe0\xd7\xd1\xf8\x0c\x2e\x52\x8a\x5c\x98\x7e\x01\x00\x00\xff\xff\x00\x44\x8f\xaf\x5d\x00\x00\x00") 47 | 48 | func data_gemfile_bionic() ([]byte, error) { 49 | return bindata_read( 50 | _data_gemfile_bionic, 51 | "data/Gemfile.bionic", 52 | ) 53 | } 54 | 55 | var _data_gemfile_bionic_lock = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x92\x4b\x8f\xd3\x30\x14\x85\xf7\xfe\x15\x77\x99\x91\xa6\xb7\xb1\x23\x9a\x49\x45\x23\x01\x09\x30\xd2\xb4\x54\x50\xc4\x3a\x4d\xdd\x36\x34\x2f\xd9\x0e\x02\x16\xfd\xed\xc8\x8f\xbc\x98\x55\xec\x73\x6f\xae\xcf\x77\xec\x4f\xe9\x96\x00\x08\x5e\x35\x8a\xaf\xe1\xaa\x54\x2b\xd7\xcb\xa5\xe8\x8e\x7f\x2e\xbc\x92\xd8\x88\xcb\x92\x00\xc8\x96\xe7\x72\x4d\x00\x00\x32\x21\x16\x6d\x05\x9e\x8f\x3e\x52\xff\xc1\x68\x00\x79\x76\x2c\x6a\xf0\x62\x70\xca\x31\xcb\x6f\x6d\x23\x94\x04\x2f\x40\x46\xd1\xc9\xae\xcd\xc7\x68\x50\xae\x45\x79\x6a\x45\x93\x73\x29\x67\x05\x80\xf3\xb9\x00\xef\x1e\x03\x45\xff\x11\xe2\x8d\xfe\x22\xa5\xee\xb7\x32\xab\x5a\xf0\x8c\x64\x95\x53\xa3\x78\xfd\x0b\x3c\x86\x21\xae\xac\x64\x06\x50\xa4\x6f\xfa\x9e\xb3\x36\x4e\x91\xd2\xf1\x90\x1e\xe7\x1e\xc3\x9c\x68\x42\x10\x6f\x80\xe1\x0a\xd9\xff\xb0\x1b\xf0\x71\x35\x8e\x9a\xa3\xe8\xe2\x04\xc6\x19\xb6\x38\x33\x46\xb7\xfa\x29\x1b\x3b\x93\x62\x88\xe1\x23\xbc\x05\x36\xb6\xb5\x25\xcf\x24\x17\x5d\x3d\x18\x65\x51\x5f\xd3\x77\xb5\xf8\xfd\xd7\x55\x18\x06\x7d\x41\xaa\xee\x64\x96\x45\x2d\x0b\xa9\x6c\x5a\x6e\x64\xd1\x2c\xca\xe2\xc6\x75\xe2\x41\x9f\x8e\x75\x40\xf1\xa9\xcf\xaf\xea\xa4\xca\xf2\xab\xe9\x8a\x22\x7c\xb2\xea\xc4\x8b\x36\x12\xbc\x8a\x05\xe6\xd0\x6e\x6d\xef\xc7\x6d\xac\x23\xb7\x19\x8f\x31\x99\x0d\x07\x4d\x08\x06\xc6\x19\xe0\xf8\x40\x86\x30\x06\x2e\x13\x86\xeb\xd4\x63\xac\x59\x16\x3c\x10\xb2\x7f\x79\x77\xf8\xf8\xe5\xeb\xf6\x1b\xb1\x83\x09\x49\xd2\x7d\xba\x4b\xd2\xdd\x87\xe7\x54\x8b\xe6\x99\xe8\x8b\xb0\x0f\x85\xbc\xff\xbe\x4b\x5e\xd2\x04\x7e\x3c\x1f\x3e\xeb\x81\x14\x69\x88\x01\xf9\x17\x00\x00\xff\xff\xe7\x44\x7f\x54\x3b\x03\x00\x00") 56 | 57 | func data_gemfile_bionic_lock() ([]byte, error) { 58 | return bindata_read( 59 | _data_gemfile_bionic_lock, 60 | "data/Gemfile.bionic.lock", 61 | ) 62 | } 63 | 64 | var _data_patches_1_0_0_01_for_tests = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4a\x4a\x2c\x02\x04\x00\x00\xff\xff\xaa\x8c\xff\x76\x03\x00\x00\x00") 65 | 66 | func data_patches_1_0_0_01_for_tests() ([]byte, error) { 67 | return bindata_read( 68 | _data_patches_1_0_0_01_for_tests, 69 | "data/patches/1.0.0/01_for_tests", 70 | ) 71 | } 72 | 73 | var _data_patches_1_0_0_02_for_tests = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4a\x4a\xac\x02\x04\x00\x00\xff\xff\x98\x04\x24\x78\x03\x00\x00\x00") 74 | 75 | func data_patches_1_0_0_02_for_tests() ([]byte, error) { 76 | return bindata_read( 77 | _data_patches_1_0_0_02_for_tests, 78 | "data/patches/1.0.0/02_for_tests", 79 | ) 80 | } 81 | 82 | var _data_patches_1_9_3_p551_01_strict_hostname_checking_patch = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\xfd\x6e\xdb\x38\x12\xff\xdf\x4f\x31\x67\x03\x8d\x9d\xc8\xf2\x47\xec\x7c\x18\x9b\xdd\xfa\x9c\x64\xb7\x40\xe2\x14\x75\x8a\xbd\x43\x92\x33\x28\x69\x64\x73\x2b\x91\x5e\x92\x8e\x9d\x6c\x7b\xef\xb2\xcf\xb2\x2f\x76\xa0\xbe\xfd\xed\xa6\x69\x5a\x2c\x2e\x28\xe0\x8a\x1a\x0d\x67\x7e\xf3\xe3\x70\x86\xd2\xb9\xe0\x3e\x1c\xdb\xf5\xfd\x43\x72\x74\x58\xb7\xf6\xab\x56\xb5\x51\xb3\x1a\xb5\x46\xa3\xda\xac\x37\x8f\x0e\x8e\xeb\x2e\x56\xab\xb5\xa3\x23\xbb\x8e\x4d\xb8\xe4\x0c\x7a\x38\x82\xda\x21\x54\xab\xad\xe0\x1f\xd4\xab\xd5\x5a\x4e\xab\x69\xc1\x35\x67\x0f\xd0\x16\x36\x45\x41\xe1\x07\x8b\x48\x7b\xec\xe1\xeb\x81\x4f\xa8\x67\xda\xdc\xff\x31\x77\x4a\x14\xb6\xa0\x37\x66\x06\xd4\x8f\xe1\x92\x08\xa8\x57\x6b\x4d\xa8\x1d\xb6\xea\x47\xad\x46\x03\xca\xd5\xc3\x6a\x35\xd7\x1b\x5b\xbf\xa1\xad\x5a\x70\xf3\xb6\x7d\xdd\xf9\xe5\x0e\x7a\x4a\x50\x5b\xa1\x80\x21\x97\x8a\x11\x1f\xe1\x1e\x05\x75\xa9\x4d\x14\xe5\x0c\x5c\xee\x79\x7c\x42\xd9\x00\xde\x9d\x77\xe0\xa0\x56\x6f\x9a\xb9\xdc\xf5\x90\xb0\x0f\x12\x14\x87\xd7\x8c\x0c\x29\xb8\x5c\x80\x1a\x22\x28\x94\x4a\x02\x61\x0e\x50\x46\x15\x25\x1e\x38\xdc\x1e\xfb\xc8\x54\xa0\xcc\xcc\x95\xcb\xe5\x1c\xe0\x54\x55\xf8\x08\x99\x94\x5e\xc5\xa3\x56\xf2\x7f\x29\xbd\x32\x65\x0a\x05\x23\x9e\x29\x2c\xf8\x08\x70\x50\x87\xbd\x25\x7f\x5a\x8b\x9e\x2b\x79\x54\x5f\xf4\xa5\x0c\x1e\x03\xf8\x08\xb5\x66\x75\xe9\x83\x1b\xff\x72\x50\x07\x97\x7a\x28\xc1\x1e\x12\x36\x40\xc7\x80\x7a\xf5\x08\x28\x93\x28\xb4\x0b\xb2\xb8\x57\x32\xa0\x01\x0e\x7a\x18\x5e\x97\x4b\xb9\x9c\x43\x5d\x17\xca\xe5\x01\x55\x40\x2a\x6b\xdc\xd3\xe6\x59\x1b\x04\x72\x94\x39\x38\x05\xd7\xad\x39\x0d\x74\x4d\xd3\x26\x6e\xd5\x3a\x26\x50\xab\x56\x0f\x1a\x0d\x8d\xe0\xb6\x00\xe6\xf6\xf6\xf6\xb6\x96\x7d\xfd\x1a\xca\xb5\xc6\xbe\x71\x04\x7b\xfa\xe7\x10\x5e\xbf\x06\x07\xdd\x90\x0c\x0f\x7d\x5b\xbb\x1f\x90\x02\xfb\xd4\x41\xa6\xa8\x7a\x28\xea\x41\x23\xe1\x4d\x29\x07\xe9\x9f\x4d\x24\x82\x24\xcc\x54\x64\x90\x1d\x9f\x0c\x91\x41\x1d\x0a\xe0\x74\x7b\x5d\x4d\x36\xca\xe0\x67\x64\x28\x88\x17\x5c\x16\xdf\x9d\x77\x9a\xf5\xa3\xea\x8c\x32\x00\x39\xe4\x63\xcf\xe9\xc7\xc6\x70\xdf\xe7\xac\x1f\x90\xf5\x04\x5c\xe2\x49\xcc\x95\xb3\xe2\x02\x07\x70\x02\xef\x70\x80\xd3\x91\x89\xd2\x26\x23\x2c\x6a\x63\xee\x89\x37\xc6\x92\x39\x90\x63\xab\x58\xb9\xbd\xbd\xdd\xad\x18\x90\xbf\xf9\x8f\x79\xb7\x97\x2f\xcd\x6b\x50\x63\xc1\x40\x89\x31\x02\x75\xa1\x72\xdb\x2e\xfc\x21\x70\xf0\xe9\xf6\xb1\x42\xe1\xe4\xbf\x89\xd3\xb9\xbd\x35\x4f\x45\xe6\xc6\xb2\xc5\xf8\x3f\x06\xa4\xc6\x2c\x80\x73\x08\x05\xa0\x6f\xdb\x8e\x23\x50\xca\x67\x83\x67\x46\xbc\x10\xad\x6a\x09\x3f\x9f\x75\xcf\xde\xb5\x2f\xfa\xdd\xf6\xe5\x59\x7f\x24\x28\x53\xc5\x92\x9e\x73\xda\xac\x1e\xdf\xef\x57\xee\xf7\xfb\xc4\x53\xa6\x1d\xb2\xa3\x79\x1c\xb0\xa3\x79\xf4\x45\xec\xa0\xee\x6a\x73\x53\x33\xf5\xc3\xa6\x0c\x73\x95\xa9\x78\x9f\x98\x48\xec\xe1\x1f\x1f\x39\x75\x0c\x08\x90\xfb\x98\xf5\x89\xba\xc0\xa9\x03\x27\x27\x90\xef\x74\xf3\x9b\xc9\xf0\xdd\x10\x61\x91\x04\xc8\x9c\xf4\xf2\x53\x2e\x33\x1a\x04\xe1\xe0\xc8\xa8\xd5\x60\xaf\x76\x70\x60\x1c\x3c\x3d\x0c\xc9\x24\x3e\x77\xc6\x1e\xf6\xdd\x31\xb3\x83\x74\xdf\x5a\xa3\x2a\x17\xfa\x98\x99\x70\x39\xb3\x4b\x50\x80\x16\xe3\x0e\xb7\x5b\x31\x2a\x85\x60\xf7\xd0\xcc\x35\xe0\x4d\xbb\xa9\xf7\x1c\x36\x00\x2a\xc1\xa3\x3e\x55\xe8\xe8\xad\x44\x6f\x20\x12\x15\x70\x17\xda\xbd\xce\x9b\x37\x3a\x03\x0b\xa2\xb7\x26\x19\xab\x89\x60\x0d\x28\x0d\x63\xe6\xe9\x15\xa2\x97\x12\x91\x36\xa5\x7d\xce\xbc\x87\x9f\xd6\x89\xc6\x56\xce\xca\xa7\x36\xf6\x10\x93\x5d\xce\x00\x89\x21\x24\x07\x66\xc3\xac\xa5\x42\x97\x44\xd9\xc3\xc8\x7a\x9d\xe5\xca\x7a\x6f\x60\x92\x2a\x7a\x8f\x66\x2c\x26\x09\xeb\x8f\x88\x50\x12\x4e\x02\x03\x1d\x3e\x61\x5a\xd8\x94\x23\x8f\xaa\x62\xde\xcc\x97\xb2\x13\x5f\x5f\x9d\x5e\xb5\x40\x0d\xa9\x04\x0b\x87\xe4\x9e\x72\x11\x2d\x12\x18\x09\x6e\x11\xcb\x7b\x00\x0b\xc1\xe7\x02\x41\x06\xfb\xf5\x9c\x9b\x92\x30\x4d\xfe\x64\x0b\xd7\x8b\x2c\x36\xc1\x94\xf4\x11\xe1\x07\xa8\x67\x67\xdc\xca\x0b\xad\x2e\x71\x23\x01\x6f\x83\x2f\xcb\x01\xdc\x37\x40\x8e\x2d\xaa\xd0\x87\xba\x99\x0a\xbf\x71\x83\xb0\x4f\xa8\xe7\xd8\x44\x38\x69\xc8\xb5\x5d\xfa\x8e\x8e\x51\x66\x94\x87\xf2\x1e\xba\xaa\xec\x73\xa9\x52\x4d\x1e\xb1\xd0\xd3\xa9\x4b\xdf\x1f\x09\x94\xc8\x34\xaf\x42\xee\xba\x14\x85\x11\xdc\xb1\x3d\x8a\x4c\x41\xef\x97\xab\xf7\x17\xa7\xd0\xbd\xba\x06\x9b\xfb\x23\x22\x30\xd5\x44\x06\x84\x32\xa9\x80\xb0\x07\x15\x40\x64\x8d\xd5\xec\xac\xd1\x64\x91\x31\x02\x5d\x14\xc8\xec\x8c\x8a\x74\x56\x28\xa2\x39\x30\x0d\xd8\x35\x71\x4a\xfc\x91\x87\xba\x56\x83\x49\x10\x5a\x5f\xc7\x00\x5c\xce\x67\xee\x59\xe3\x8c\x57\x8c\x2b\xb0\x88\x30\xe7\x85\xb8\x80\xcc\x65\xc9\xdc\xb0\x40\xb2\x44\x88\x68\x92\x19\xfa\xac\xe8\xd5\x32\xd1\xbb\x5e\x0a\x28\x51\x0a\xfd\x91\xd2\x4b\x3a\xf4\x90\x2c\x8d\x07\x50\x96\x6a\x9a\x0c\xa9\x3d\x5c\x45\x05\x1d\x21\x41\x25\x4a\x20\x31\xf2\x6a\x88\xba\xe2\x24\x41\xb8\x33\x24\x98\x8b\x50\x04\xbe\xc3\x03\x20\x43\x6b\x34\x9c\x69\x34\x18\xaa\xf5\xe8\x45\x99\x2e\x36\xab\x98\xc5\x6e\x48\x5d\x65\x64\xf1\xd5\x03\x99\xc5\x90\xde\xf9\x8d\x53\x16\xac\x94\x39\xf8\x93\xf1\xf0\x11\x9d\x96\xf7\xd6\xa5\xe5\x74\xb7\x59\xc8\xc5\x89\x85\x0e\xf7\x09\x65\x7a\x5b\x1d\x71\x86\x2c\xb2\x30\xb9\x5c\x92\x9d\x33\x99\x2a\x95\x8b\x97\xf7\x6e\xde\x80\x72\x2d\xe3\xd5\x0c\x4a\xd4\x85\x0c\xb7\x7e\xd4\x49\x66\x3e\x31\xa5\x2a\xb5\xf3\xf3\xd6\xcd\x69\x38\x39\x81\xda\x67\xf1\x71\xff\xb9\xf8\x98\x25\x23\x0a\x5c\x93\x97\xd0\xb7\xd0\x71\xd0\x81\x09\xd5\x09\x02\x08\x83\x76\x39\x22\x66\x46\xcd\xfb\x72\x92\x26\x08\x83\xa8\xd6\xd6\x2e\x10\x8f\x3e\xa2\x13\x21\x01\x41\x4e\x5d\x85\xed\x3c\x5a\xa6\x54\x44\xa8\xbe\x9e\xf8\xa7\x62\x7e\xca\xca\xe5\x7c\x09\x5e\xbd\x9a\x83\xf9\x1f\x27\x90\xdf\xcd\xa7\x30\x06\xf8\xde\x54\xef\x4c\x0f\xd9\x40\x0d\x61\x2f\x1a\xa9\x25\x23\x3f\x2c\xce\x14\xdd\x79\xf5\x2a\xd6\xb2\xd6\x96\x78\x8a\xd2\xba\x07\x90\x39\x33\xe2\xb5\xbb\x6d\x79\x1f\x07\x22\xb7\x17\x96\x2d\xb6\x47\xa4\x84\x5e\xef\xa2\xc7\xed\x0f\xa8\x92\xda\x92\xd9\xde\xd8\x41\xf8\xe7\xd8\x75\x51\x97\x18\xf3\x37\x42\xf1\x73\x2e\x26\x44\x38\x28\xe6\x6f\x77\x39\xb3\x3c\x6e\x7f\xc8\x25\x51\x2c\xa4\xf1\x7c\x8b\xc2\xe5\xc2\x5f\xd1\x27\x13\x57\xb3\x83\x30\x6d\x14\xd8\x9c\xb1\x88\xae\x9a\x2f\x52\x11\xcb\xa3\x72\x88\x4e\xa2\x2d\x4b\x5a\x2a\xc1\x47\x35\xe4\x0e\x5c\xbe\xef\x5d\xeb\x8d\xde\x26\x9e\x87\x4e\xa4\x53\x5f\xe8\x6d\xa8\x10\x69\xd5\x44\x46\x26\xc7\x01\x47\x89\x9a\xcd\x80\x89\x71\x9a\x75\x20\xd0\xe7\x0a\x61\x84\xba\xbd\x27\xba\xb8\x40\x16\x99\x8d\x8e\x19\x7b\xaf\x93\xc8\x48\xe7\xa4\xd4\xec\xbe\x3d\x44\xfb\x43\x71\x49\x6b\x17\xa5\xc5\xab\x11\xb2\x5e\xef\xa2\xd5\xea\xf5\x2e\xcc\x75\xe5\xa7\x9e\xbb\xbf\xa6\x51\x14\x84\x4a\xd4\xa0\x9d\x09\xc1\x85\x01\xf9\xc4\x83\xdb\x7c\xe1\x8f\xf8\xe2\xd3\x6d\x1e\x1c\x8e\x32\x93\xc7\xc3\x72\x51\xdc\x6b\x84\xd2\x89\xf3\xb3\xbd\xf8\xca\x43\x02\x6b\xe5\xad\xa8\xff\xb6\x0e\x9a\xfb\xc7\xc7\xae\x69\x36\xea\x8d\x6a\xed\xa8\x9e\xed\xbf\x57\x3e\xaa\x1b\xee\x95\x37\x75\xf9\xde\xa8\x1f\x18\x07\xb0\xa7\x7f\x6a\xcd\x83\xb8\x7c\x0f\xa4\xd6\x15\xde\x00\x69\xcd\xae\x7f\x74\xbc\xe7\x1f\x9c\x6d\x44\x88\x94\x28\x54\x1f\x7f\x1f\x13\xaf\xa8\xdb\x10\x03\x96\xc6\x2c\xa9\xe0\xf3\x93\xc9\x24\x5b\x62\xe4\x0d\xc8\xcf\x14\x2d\xf9\x52\x69\x89\xea\x20\x53\x19\x5b\xa8\x96\x63\x2b\xcc\x07\xdb\x4c\x12\xe4\x83\x65\x4e\xa6\x79\xe0\x73\x2c\x49\xb6\xc6\xbc\xcb\xb9\x9e\x73\xba\xbb\xdc\x9b\x35\x40\x2d\xe8\xd0\x3f\x5f\xae\xe4\x19\x0c\x59\xa1\x62\x2b\x3c\x88\x65\xef\x5a\xb6\xa3\xd5\x10\xfd\xfb\x74\x4d\x7a\x2f\xfa\xdd\xf9\xd0\xb0\x8e\xad\x75\x08\x3f\x45\xd7\x6e\x7a\xf5\x74\xb0\xe6\xed\x63\xf3\x4a\x13\xce\x15\xa0\xc3\x7d\x1f\x99\x92\x61\x3b\xa1\x3b\x11\x94\x2a\xc8\xe4\x53\x1b\xc5\x48\xd7\x0d\xae\xe0\x3e\x0c\x95\x1a\xb5\x2a\x15\xc5\xb9\x27\x4d\x8a\xca\x35\xb9\x18\x54\x86\xca\xf7\x2a\xc2\xb5\x75\xd9\x52\x18\x91\x01\x96\xeb\x87\x33\x5c\x5e\x9a\x6b\x13\x53\xfb\x92\x44\x85\x71\x61\xa1\x33\x8b\x1b\xe3\xa0\x65\xa1\x92\x27\x82\x6b\xbb\xd6\x42\x2c\x95\x37\x4d\x3f\xee\xfb\xe6\x9b\x97\x6c\x65\x1e\x77\x40\xab\x5a\xa9\x58\x1f\x95\x30\x0a\x37\x45\x74\xc0\x7a\x88\xed\x62\x83\x6c\x2f\x9f\x29\x73\xc2\xaa\x5c\xc2\x58\x6a\x19\xb2\xb5\x97\x06\x10\xa9\xb7\xfc\x70\xdf\xd2\x33\xdd\x9c\x76\x7b\xe5\x4e\xbb\x77\x76\x17\xd5\xf8\x89\x8b\xbf\xfe\xfa\xab\x79\x16\x25\x94\x0e\xf7\xf3\x51\xaf\x65\x21\x78\x7c\x82\xa2\xac\x27\x0b\x8e\x1b\x16\x12\x1e\xb8\x3c\xf1\x2c\x9d\x1b\x46\x63\x31\xe2\x12\xe5\x6a\xe6\x6d\xbd\x17\xc6\xdb\xb4\x2d\x50\x8f\x6b\x99\xa0\x1e\xd2\x21\x2f\xee\x9c\x76\x7b\xad\x99\x64\xb8\x53\x32\x60\x67\xce\xca\x9d\x35\x2b\xe0\x59\xed\x48\x30\xbc\xba\xfc\xa6\x76\xcc\xe3\x31\x13\x5f\x6d\x5b\x29\x8e\x59\xcd\x84\x67\xea\x48\x0b\x81\x55\xcf\xd0\x93\x86\x8a\xbe\xa8\x2b\xdd\x36\x7b\x3e\x11\x60\x1d\xd6\xdd\x8d\x64\x2b\x40\xdd\x84\x67\x3a\xac\x89\x30\x79\x96\xe3\x9a\x50\xd7\x17\x1e\xd8\x84\x4a\x9e\xe5\xc8\x26\x54\xf5\x79\x87\x36\x2f\xbd\x80\xe6\xac\x5a\xbe\x90\x9f\x9f\x68\x8b\x86\x2c\x81\x28\x43\xb8\xfd\xd9\xd5\x7c\xd9\xfe\xf7\xa6\xb5\xbb\x64\xc1\x66\xa3\x32\xc3\x56\x1d\xa2\x35\x8c\xcd\x2c\xd3\xac\x0a\x8b\x3c\xce\xac\xd1\xe0\x4d\xe7\xae\x45\x1e\x17\x06\xad\xdd\xd9\xb1\x80\x3d\x33\xaa\x10\x14\xf9\x80\x2c\xcd\x49\x16\x79\xac\x2d\xe8\x71\x39\x5f\xa2\x7e\x46\xd1\xf8\x71\xe6\xbe\x01\x02\xe5\x48\x17\x01\xf7\xe8\x3d\x94\x4c\x00\xd3\x7c\x11\xa6\xcd\x80\x93\xc6\x38\xe3\xd4\x0b\x6e\x1b\x59\xd0\x32\xc4\x5f\x18\x7e\x11\x6b\xb2\x64\x48\x80\xc9\x86\x6d\x96\xf9\xbd\xec\x41\x97\xa6\xe4\xbb\xf3\x8e\xae\xed\x40\x2a\xa2\x50\x86\x4d\x7f\xb4\x2c\xa2\x97\x04\x3a\x31\x86\x2c\x5a\x2c\xd2\xc2\xd3\xac\x24\x69\x53\x99\xdd\xa9\xe6\x32\xa4\x39\x57\x30\xb6\x3d\xc9\x81\xfa\x23\x8f\xda\x54\x79\x0f\xa0\xab\x62\xca\x99\x5c\xb5\x0f\x04\xcb\x89\x32\xd0\xf5\xdd\xd8\x23\x42\x97\x54\x7e\xb2\x84\x34\xa1\x1d\x2a\x6d\x3e\x16\x64\x80\x12\x92\x5a\x34\x4e\xe0\xc1\xfb\x8d\xc0\x2e\xce\x52\xfd\xf3\x46\x2d\x7f\x4b\x73\x68\xd6\x17\x5f\x31\x7c\xed\x9c\x66\x2d\x32\x9e\x58\xf6\x37\x49\xaf\x4b\x4d\xf9\x5e\x2c\x59\x81\x49\x01\x36\xfc\x99\xa6\x09\xf0\x0b\x9f\xe0\xfd\xca\x82\x20\xd5\xb4\x6d\x95\xb7\x78\xbc\x9b\xea\xd8\xfe\x9c\x37\x39\xde\xbd\x79\x73\xda\x6d\x97\x4f\xcf\xce\x7b\x77\xc0\xdd\x8c\x39\x1b\xce\x7c\xa3\x07\xdf\xbe\xbb\xba\xbe\xba\x7b\x91\x0c\x3d\x65\x8b\x91\x99\xb2\x9a\x4d\x56\x04\x67\x44\x44\xf8\x36\x36\xf4\xf4\x45\xd8\xa3\xfb\xf2\x65\x56\x96\xcb\x9b\xed\x7c\x9f\xb5\x73\xe6\x0b\x93\xe8\xab\x09\x1d\x54\xc2\x32\x2f\xa0\x25\x4f\xc2\x98\xc9\xa4\x16\x02\xf1\x74\xb7\x98\x10\x43\xe0\x80\x08\x27\x38\xf8\xe4\xee\xda\xc4\xd4\x4b\xd3\x51\x94\xba\x83\xb7\xde\xad\x94\x17\x4f\x78\xfd\xfd\x32\xd9\xec\xaf\x3f\x17\x81\xff\xeb\xcf\x65\xdb\xf7\xe2\xf1\xdc\x86\x23\x0d\x9b\x7d\x45\x7e\x07\x67\x8c\x3b\xdf\xb8\x73\x8e\x8d\xf8\xa6\x6d\xf3\x2a\x24\x56\xf5\xcc\x5f\x87\x50\xa1\x15\xdb\x35\x96\x2f\x0a\xc3\xcb\x76\x3e\xab\xac\x58\xd7\xf6\x7c\x45\x38\xbe\x83\xf2\x3c\x42\xe4\x7b\xa8\xcd\x23\x4c\xfe\x5f\x98\xff\xad\x0a\xf3\x98\x60\xdf\xba\x2a\x5f\x67\xc7\x77\x61\xc6\x36\x68\x3c\xef\x52\xfb\xbc\xda\xf3\x6b\xe2\xf1\x8c\x15\x66\xf4\x2d\x7d\xb6\xc2\x8c\x52\xc1\xc6\x57\x1a\x7f\x8f\xda\x31\x44\xf4\x89\x85\xe3\xd2\x4a\x54\x12\x16\x7f\x13\xe2\xc2\x49\x6a\xe2\xbf\x9a\xd5\xe3\x56\xeb\x6c\xaa\x34\xa2\x9c\x9d\x13\x5b\x71\xf1\x60\x32\x9c\x84\xd2\x5a\xcb\xa2\x7c\x27\xf5\x66\x56\x34\xfe\xb4\x78\xf1\x11\xdd\x32\x98\x23\x22\x24\x16\xf3\x95\xd3\xce\x89\xe4\x3e\x06\xbf\x54\x61\xa5\xd3\x3d\xe9\x71\x1f\xa1\x47\x15\x26\xdf\x6c\x4d\xb5\x16\x74\xcd\xc8\x1f\x9c\xaa\xe2\x4e\xa4\xbe\xed\x29\xad\x6f\x27\xfc\x2c\x36\x33\x3d\x71\x1c\x2d\x18\x3a\x53\xc4\xa9\xca\xdc\xdc\x0c\x54\x00\x7b\xf8\x25\xc5\x57\x70\x9e\xe1\xa4\x78\x73\xb3\x73\xda\xd9\x31\x60\x47\xbb\xbf\x73\x67\x40\x72\x4d\x55\x74\xdd\xe9\xee\x18\x41\x23\x7b\x77\xb7\xdc\xf8\x5c\x40\xda\x4e\x60\x3c\x74\xdf\x5f\x5c\x80\xf5\xa0\x10\x7a\xed\x6e\xf6\x83\x8d\x1c\xcc\x38\xc9\xc6\x9e\xd7\xd7\x72\xfd\x5e\xbb\x9b\x65\x63\xd1\x16\x54\x51\x9b\x78\xf1\x27\xed\xf1\x97\xcc\x5b\xd2\xe4\x7f\x01\x00\x00\xff\xff\x3c\x67\x0d\x81\x8c\x33\x00\x00") 83 | 84 | func data_patches_1_9_3_p551_01_strict_hostname_checking_patch() ([]byte, error) { 85 | return bindata_read( 86 | _data_patches_1_9_3_p551_01_strict_hostname_checking_patch, 87 | "data/patches/1.9.3-p551/01_strict_hostname_checking.patch", 88 | ) 89 | } 90 | 91 | var _data_patches_2_0_0_p0_01_readline_patch = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\x61\x4f\xdb\x30\x10\xfd\xee\x5f\x71\x0a\x93\x48\xe6\x24\x24\xb4\xa3\x89\xa0\x52\x10\x63\x03\x0d\x01\x02\xb6\xaf\x96\x89\x2f\xad\x45\xea\x44\xb6\x83\xca\xbf\x9f\x1c\xb5\x55\x3b\x9a\xee\x8b\x5b\x3d\xbf\x7b\x77\xf7\xfc\x22\x64\x55\x41\x14\xcd\xa4\x05\x5c\xda\x13\x8d\x5c\xd4\x52\xe1\x09\x2e\x6d\xd9\xa8\x2a\xd6\xaf\x43\x38\x91\x4a\xe0\x12\xc6\xf9\x69\x92\x8e\x26\x71\x9c\x61\x96\x9e\x7e\x1b\x41\x9a\x24\x67\xe3\x31\x89\xa2\x68\xb0\x92\x52\x3a\x78\x57\x14\x10\xa5\x79\x78\x06\x34\xcd\xc3\x34\x81\xa2\x00\x81\x15\xac\xa9\xf1\x9c\xbf\x23\xab\x3a\x55\xfa\xee\x08\x08\x00\x68\xb4\x9d\x56\x60\xba\x16\x75\x8f\x86\x30\x47\x2e\x50\x9b\x80\x00\x2a\x41\x08\xfd\x2c\x61\x3f\x5a\xf4\xdd\x11\x10\xfa\x8f\x84\x43\xb7\x24\xa8\x93\xa0\x04\x84\xd4\xcc\x4d\x29\x67\xfe\x71\xd9\x69\x83\xe6\x38\xd8\x45\xd5\x7e\xd8\xa2\x5e\x94\xbc\x3d\x0e\xfa\xe5\xf2\x51\x38\x06\x9a\x4f\xc2\xdc\xed\xb6\x67\x2f\x4f\xe3\xa2\x79\x47\x36\x97\xc6\x36\xfa\xc3\x0b\xc8\x5e\x56\x59\x23\xd7\xff\x23\xe9\x9a\x69\x14\xd2\xb4\x35\x3f\xc4\x91\xca\xa0\xb6\xcc\xe2\xd2\x7a\x01\xa1\x84\x76\xaa\x46\x63\xf6\x59\xe6\xe8\xf3\xa6\x79\xeb\x8b\x59\x4f\x07\xf8\x22\xb0\x32\x70\x71\x01\x5e\xf4\x7d\xf7\x7e\xfa\xa3\x53\xa5\x95\x8d\xf2\x36\x3e\x96\x1a\xb9\x45\xb6\xe0\x6f\x58\xc9\xda\x29\xae\xba\x78\x01\x19\x8a\xe3\x66\x90\x72\x08\x5f\xc5\x71\x84\x93\x0a\x91\xc7\xf1\x38\x3b\x7d\xad\xb2\x64\x30\x8e\x5b\x95\x9f\xe2\xb8\x75\xd7\xc7\x31\xcb\x46\xe1\x04\xe8\xea\xb7\x28\xe0\x56\x49\xcb\xd6\x2c\x3f\x20\x2e\x85\x00\xba\x66\xdc\x5a\x5c\xb4\x16\x05\x2b\x9b\x45\x5b\xa3\xdb\xbc\x77\xc2\xfd\x81\xe9\xc6\xd0\xc3\xc4\x73\x02\x47\xb2\x72\xb9\x97\x0a\x85\x7f\x73\xf9\xe7\x9a\x3d\xdd\xb1\xc7\xa7\x6b\x76\x7b\xff\xf8\xfb\x85\xdd\x3c\x3c\xfc\x0a\x48\xb4\x6a\xda\x6a\x64\x52\xb5\x9d\xed\x8d\x87\x29\xf8\x6b\xd3\xe1\x6b\xb0\xe9\xb8\xcb\x3a\x77\xcf\x36\x50\xbd\xfb\x82\x87\x34\xe0\x08\x95\x90\x55\x3f\xae\xfb\xc4\xd6\x93\x5e\x5d\xbe\x5c\xdd\xb0\xe7\xdb\x9f\xf7\x97\x77\xcf\x1b\x73\x4a\x6e\xcb\x39\x33\x72\xa6\x78\x6d\x60\x0a\xc9\x39\xf9\x1b\x00\x00\xff\xff\x71\xae\x9c\xc9\x7f\x04\x00\x00") 92 | 93 | func data_patches_2_0_0_p0_01_readline_patch() ([]byte, error) { 94 | return bindata_read( 95 | _data_patches_2_0_0_p0_01_readline_patch, 96 | "data/patches/2.0.0-p0/01_readline.patch", 97 | ) 98 | } 99 | 100 | var _data_patches_2_0_0_p195_01_readline_patch = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\x61\x4f\xdb\x30\x10\xfd\xee\x5f\x71\x0a\x93\x48\xe6\x24\x24\xb4\xa3\x89\xa0\x52\x10\x63\x03\x0d\x01\x02\xb6\xaf\x96\x89\x2f\xad\x45\xea\x44\xb6\x83\xca\xbf\x9f\x1c\xb5\x55\x3b\x9a\xee\x8b\x5b\x3d\xbf\x7b\x77\xf7\xfc\x22\x64\x55\x41\x14\xcd\xa4\x05\x5c\xda\x13\x8d\x5c\xd4\x52\xe1\x09\x2e\x6d\xd9\xa8\x2a\xd6\xaf\x43\x38\x91\x4a\xe0\x12\xc6\xf9\x69\x92\x8e\x26\x71\x9c\x61\x96\x9e\x7e\x1b\x41\x9a\x24\x67\xe3\x31\x89\xa2\x68\xb0\x92\x52\x3a\x78\x57\x14\x10\xa5\x79\x78\x06\x34\xcd\xc3\x34\x81\xa2\x00\x81\x15\xac\xa9\xf1\x9c\xbf\x23\xab\x3a\x55\xfa\xee\x08\x08\x00\x68\xb4\x9d\x56\x60\xba\x16\x75\x8f\x86\x30\x47\x2e\x50\x9b\x80\x00\x2a\x41\x08\xfd\x2c\x61\x3f\x5a\xf4\xdd\x11\x10\xfa\x8f\x84\x43\xb7\x24\xa8\x93\xa0\x04\x84\xd4\xcc\x4d\x29\x67\xfe\x71\xd9\x69\x83\xe6\x38\xd8\x45\xd5\x7e\xd8\xa2\x5e\x94\xbc\x3d\x0e\xfa\xe5\xf2\x51\x38\x06\x9a\x4f\xc2\xdc\xed\xb6\x67\x2f\x4f\xe3\xa2\x79\x47\x36\x97\xc6\x36\xfa\xc3\x0b\xc8\x5e\x56\x59\x23\xd7\xff\x23\xe9\x9a\x69\x14\xd2\xb4\x35\x3f\xc4\x91\xca\xa0\xb6\xcc\xe2\xd2\x7a\x01\xa1\x84\x76\xaa\x46\x63\xf6\x59\xe6\xe8\xf3\xa6\x79\xeb\x8b\x59\x4f\x07\xf8\x22\xb0\x32\x70\x71\x01\x5e\xf4\x7d\xf7\x7e\xfa\xa3\x53\xa5\x95\x8d\xf2\x36\x3e\x96\x1a\xb9\x45\xb6\xe0\x6f\x58\xc9\xda\x29\xae\xba\x78\x01\x19\x8a\xe3\x66\x90\x72\x08\x5f\xc5\x71\x84\x93\x0a\x91\xc7\xf1\x38\x3b\x7d\xad\xb2\x64\x30\x8e\x5b\x95\x9f\xe2\xb8\x75\xd7\xc7\x31\xcb\x46\xe1\x04\xe8\xea\xb7\x28\xe0\x56\x49\xcb\xd6\x2c\x3f\x20\x2e\x85\x00\xba\x66\xdc\x5a\x5c\xb4\x16\x05\x2b\x9b\x45\x5b\xa3\xdb\xbc\x77\xc2\xfd\x81\xe9\xc6\xd0\xc3\xc4\x73\x02\x47\xb2\x72\xb9\x97\x0a\x85\x7f\x73\xf9\xe7\x9a\x3d\xdd\xb1\xc7\xa7\x6b\x76\x7b\xff\xf8\xfb\x85\xdd\x3c\x3c\xfc\x0a\x48\xb4\x6a\xda\x6a\x64\x52\xb5\x9d\xed\x8d\x87\x29\xf8\x6b\xd3\xe1\x6b\xb0\xe9\xb8\xcb\x3a\x77\xcf\x36\x50\xbd\xfb\x82\x87\x34\xe0\x08\x95\x90\x55\x3f\xae\xfb\xc4\xd6\x93\x5e\x5d\xbe\x5c\xdd\xb0\xe7\xdb\x9f\xf7\x97\x77\xcf\x1b\x73\x4a\x6e\xcb\x39\x33\x72\xa6\x78\x6d\x60\x0a\xc9\x39\xf9\x1b\x00\x00\xff\xff\x71\xae\x9c\xc9\x7f\x04\x00\x00") 101 | 102 | func data_patches_2_0_0_p195_01_readline_patch() ([]byte, error) { 103 | return bindata_read( 104 | _data_patches_2_0_0_p195_01_readline_patch, 105 | "data/patches/2.0.0-p195/01_readline.patch", 106 | ) 107 | } 108 | 109 | var _data_patches_2_0_0_p247_01_readline_patch = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\x61\x4f\xdb\x30\x10\xfd\xee\x5f\x71\x0a\x93\x48\xe6\x24\x24\xb4\xa3\x89\xa0\x52\x10\x63\x03\x0d\x01\x02\xb6\xaf\x96\x89\x2f\xad\x45\xea\x44\xb6\x83\xca\xbf\x9f\x1c\xb5\x55\x3b\x9a\xee\x8b\x5b\x3d\xbf\x7b\x77\xf7\xfc\x22\x64\x55\x41\x14\xcd\xa4\x05\x5c\xda\x13\x8d\x5c\xd4\x52\xe1\x09\x2e\x6d\xd9\xa8\x2a\xd6\xaf\x43\x38\x91\x4a\xe0\x12\xc6\xf9\x69\x92\x8e\x26\x71\x9c\x61\x96\x9e\x7e\x1b\x41\x9a\x24\x67\xe3\x31\x89\xa2\x68\xb0\x92\x52\x3a\x78\x57\x14\x10\xa5\x79\x78\x06\x34\xcd\xc3\x34\x81\xa2\x00\x81\x15\xac\xa9\xf1\x9c\xbf\x23\xab\x3a\x55\xfa\xee\x08\x08\x00\x68\xb4\x9d\x56\x60\xba\x16\x75\x8f\x86\x30\x47\x2e\x50\x9b\x80\x00\x2a\x41\x08\xfd\x2c\x61\x3f\x5a\xf4\xdd\x11\x10\xfa\x8f\x84\x43\xb7\x24\xa8\x93\xa0\x04\x84\xd4\xcc\x4d\x29\x67\xfe\x71\xd9\x69\x83\xe6\x38\xd8\x45\xd5\x7e\xd8\xa2\x5e\x94\xbc\x3d\x0e\xfa\xe5\xf2\x51\x38\x06\x9a\x4f\xc2\xdc\xed\xb6\x67\x2f\x4f\xe3\xa2\x79\x47\x36\x97\xc6\x36\xfa\xc3\x0b\xc8\x5e\x56\x59\x23\xd7\xff\x23\xe9\x9a\x69\x14\xd2\xb4\x35\x3f\xc4\x91\xca\xa0\xb6\xcc\xe2\xd2\x7a\x01\xa1\x84\x76\xaa\x46\x63\xf6\x59\xe6\xe8\xf3\xa6\x79\xeb\x8b\x59\x4f\x07\xf8\x22\xb0\x32\x70\x71\x01\x5e\xf4\x7d\xf7\x7e\xfa\xa3\x53\xa5\x95\x8d\xf2\x36\x3e\x96\x1a\xb9\x45\xb6\xe0\x6f\x58\xc9\xda\x29\xae\xba\x78\x01\x19\x8a\xe3\x66\x90\x72\x08\x5f\xc5\x71\x84\x93\x0a\x91\xc7\xf1\x38\x3b\x7d\xad\xb2\x64\x30\x8e\x5b\x95\x9f\xe2\xb8\x75\xd7\xc7\x31\xcb\x46\xe1\x04\xe8\xea\xb7\x28\xe0\x56\x49\xcb\xd6\x2c\x3f\x20\x2e\x85\x00\xba\x66\xdc\x5a\x5c\xb4\x16\x05\x2b\x9b\x45\x5b\xa3\xdb\xbc\x77\xc2\xfd\x81\xe9\xc6\xd0\xc3\xc4\x73\x02\x47\xb2\x72\xb9\x97\x0a\x85\x7f\x73\xf9\xe7\x9a\x3d\xdd\xb1\xc7\xa7\x6b\x76\x7b\xff\xf8\xfb\x85\xdd\x3c\x3c\xfc\x0a\x48\xb4\x6a\xda\x6a\x64\x52\xb5\x9d\xed\x8d\x87\x29\xf8\x6b\xd3\xe1\x6b\xb0\xe9\xb8\xcb\x3a\x77\xcf\x36\x50\xbd\xfb\x82\x87\x34\xe0\x08\x95\x90\x55\x3f\xae\xfb\xc4\xd6\x93\x5e\x5d\xbe\x5c\xdd\xb0\xe7\xdb\x9f\xf7\x97\x77\xcf\x1b\x73\x4a\x6e\xcb\x39\x33\x72\xa6\x78\x6d\x60\x0a\xc9\x39\xf9\x1b\x00\x00\xff\xff\x71\xae\x9c\xc9\x7f\x04\x00\x00") 110 | 111 | func data_patches_2_0_0_p247_01_readline_patch() ([]byte, error) { 112 | return bindata_read( 113 | _data_patches_2_0_0_p247_01_readline_patch, 114 | "data/patches/2.0.0-p247/01_readline.patch", 115 | ) 116 | } 117 | 118 | var _data_patches_2_0_0_p353_01_readline_patch = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\x61\x4f\xdb\x30\x10\xfd\xee\x5f\x71\x0a\x93\x48\xe6\x24\x24\xb4\xa3\x89\xa0\x52\x10\x63\x03\x0d\x01\x02\xb6\xaf\x96\x89\x2f\xad\x45\xea\x44\xb6\x83\xca\xbf\x9f\x1c\xb5\x55\x3b\x9a\xee\x8b\x5b\x3d\xbf\x7b\x77\xf7\xfc\x22\x64\x55\x41\x14\xcd\xa4\x05\x5c\xda\x13\x8d\x5c\xd4\x52\xe1\x09\x2e\x6d\xd9\xa8\x2a\xd6\xaf\x43\x38\x91\x4a\xe0\x12\xc6\xf9\x69\x92\x8e\x26\x71\x9c\x61\x96\x9e\x7e\x1b\x41\x9a\x24\x67\xe3\x31\x89\xa2\x68\xb0\x92\x52\x3a\x78\x57\x14\x10\xa5\x79\x78\x06\x34\xcd\xc3\x34\x81\xa2\x00\x81\x15\xac\xa9\xf1\x9c\xbf\x23\xab\x3a\x55\xfa\xee\x08\x08\x00\x68\xb4\x9d\x56\x60\xba\x16\x75\x8f\x86\x30\x47\x2e\x50\x9b\x80\x00\x2a\x41\x08\xfd\x2c\x61\x3f\x5a\xf4\xdd\x11\x10\xfa\x8f\x84\x43\xb7\x24\xa8\x93\xa0\x04\x84\xd4\xcc\x4d\x29\x67\xfe\x71\xd9\x69\x83\xe6\x38\xd8\x45\xd5\x7e\xd8\xa2\x5e\x94\xbc\x3d\x0e\xfa\xe5\xf2\x51\x38\x06\x9a\x4f\xc2\xdc\xed\xb6\x67\x2f\x4f\xe3\xa2\x79\x47\x36\x97\xc6\x36\xfa\xc3\x0b\xc8\x5e\x56\x59\x23\xd7\xff\x23\xe9\x9a\x69\x14\xd2\xb4\x35\x3f\xc4\x91\xca\xa0\xb6\xcc\xe2\xd2\x7a\x01\xa1\x84\x76\xaa\x46\x63\xf6\x59\xe6\xe8\xf3\xa6\x79\xeb\x8b\x59\x4f\x07\xf8\x22\xb0\x32\x70\x71\x01\x5e\xf4\x7d\xf7\x7e\xfa\xa3\x53\xa5\x95\x8d\xf2\x36\x3e\x96\x1a\xb9\x45\xb6\xe0\x6f\x58\xc9\xda\x29\xae\xba\x78\x01\x19\x8a\xe3\x66\x90\x72\x08\x5f\xc5\x71\x84\x93\x0a\x91\xc7\xf1\x38\x3b\x7d\xad\xb2\x64\x30\x8e\x5b\x95\x9f\xe2\xb8\x75\xd7\xc7\x31\xcb\x46\xe1\x04\xe8\xea\xb7\x28\xe0\x56\x49\xcb\xd6\x2c\x3f\x20\x2e\x85\x00\xba\x66\xdc\x5a\x5c\xb4\x16\x05\x2b\x9b\x45\x5b\xa3\xdb\xbc\x77\xc2\xfd\x81\xe9\xc6\xd0\xc3\xc4\x73\x02\x47\xb2\x72\xb9\x97\x0a\x85\x7f\x73\xf9\xe7\x9a\x3d\xdd\xb1\xc7\xa7\x6b\x76\x7b\xff\xf8\xfb\x85\xdd\x3c\x3c\xfc\x0a\x48\xb4\x6a\xda\x6a\x64\x52\xb5\x9d\xed\x8d\x87\x29\xf8\x6b\xd3\xe1\x6b\xb0\xe9\xb8\xcb\x3a\x77\xcf\x36\x50\xbd\xfb\x82\x87\x34\xe0\x08\x95\x90\x55\x3f\xae\xfb\xc4\xd6\x93\x5e\x5d\xbe\x5c\xdd\xb0\xe7\xdb\x9f\xf7\x97\x77\xcf\x1b\x73\x4a\x6e\xcb\x39\x33\x72\xa6\x78\x6d\x60\x0a\xc9\x39\xf9\x1b\x00\x00\xff\xff\x71\xae\x9c\xc9\x7f\x04\x00\x00") 119 | 120 | func data_patches_2_0_0_p353_01_readline_patch() ([]byte, error) { 121 | return bindata_read( 122 | _data_patches_2_0_0_p353_01_readline_patch, 123 | "data/patches/2.0.0-p353/01_readline.patch", 124 | ) 125 | } 126 | 127 | var _data_patches_2_0_0_p451_01_readline_patch = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\x61\x4f\xdb\x30\x10\xfd\xee\x5f\x71\x0a\x93\x48\xe6\x24\x24\xb4\xa3\x89\xa0\x52\x10\x63\x03\x0d\x01\x02\xb6\xaf\x96\x89\x2f\xad\x45\xea\x44\xb6\x83\xca\xbf\x9f\x1c\xb5\x55\x3b\x9a\xee\x8b\x5b\x3d\xbf\x7b\x77\xf7\xfc\x22\x64\x55\x41\x14\xcd\xa4\x05\x5c\xda\x13\x8d\x5c\xd4\x52\xe1\x09\x2e\x6d\xd9\xa8\x2a\xd6\xaf\x43\x38\x91\x4a\xe0\x12\xc6\xf9\x69\x92\x8e\x26\x71\x9c\x61\x96\x9e\x7e\x1b\x41\x9a\x24\x67\xe3\x31\x89\xa2\x68\xb0\x92\x52\x3a\x78\x57\x14\x10\xa5\x79\x78\x06\x34\xcd\xc3\x34\x81\xa2\x00\x81\x15\xac\xa9\xf1\x9c\xbf\x23\xab\x3a\x55\xfa\xee\x08\x08\x00\x68\xb4\x9d\x56\x60\xba\x16\x75\x8f\x86\x30\x47\x2e\x50\x9b\x80\x00\x2a\x41\x08\xfd\x2c\x61\x3f\x5a\xf4\xdd\x11\x10\xfa\x8f\x84\x43\xb7\x24\xa8\x93\xa0\x04\x84\xd4\xcc\x4d\x29\x67\xfe\x71\xd9\x69\x83\xe6\x38\xd8\x45\xd5\x7e\xd8\xa2\x5e\x94\xbc\x3d\x0e\xfa\xe5\xf2\x51\x38\x06\x9a\x4f\xc2\xdc\xed\xb6\x67\x2f\x4f\xe3\xa2\x79\x47\x36\x97\xc6\x36\xfa\xc3\x0b\xc8\x5e\x56\x59\x23\xd7\xff\x23\xe9\x9a\x69\x14\xd2\xb4\x35\x3f\xc4\x91\xca\xa0\xb6\xcc\xe2\xd2\x7a\x01\xa1\x84\x76\xaa\x46\x63\xf6\x59\xe6\xe8\xf3\xa6\x79\xeb\x8b\x59\x4f\x07\xf8\x22\xb0\x32\x70\x71\x01\x5e\xf4\x7d\xf7\x7e\xfa\xa3\x53\xa5\x95\x8d\xf2\x36\x3e\x96\x1a\xb9\x45\xb6\xe0\x6f\x58\xc9\xda\x29\xae\xba\x78\x01\x19\x8a\xe3\x66\x90\x72\x08\x5f\xc5\x71\x84\x93\x0a\x91\xc7\xf1\x38\x3b\x7d\xad\xb2\x64\x30\x8e\x5b\x95\x9f\xe2\xb8\x75\xd7\xc7\x31\xcb\x46\xe1\x04\xe8\xea\xb7\x28\xe0\x56\x49\xcb\xd6\x2c\x3f\x20\x2e\x85\x00\xba\x66\xdc\x5a\x5c\xb4\x16\x05\x2b\x9b\x45\x5b\xa3\xdb\xbc\x77\xc2\xfd\x81\xe9\xc6\xd0\xc3\xc4\x73\x02\x47\xb2\x72\xb9\x97\x0a\x85\x7f\x73\xf9\xe7\x9a\x3d\xdd\xb1\xc7\xa7\x6b\x76\x7b\xff\xf8\xfb\x85\xdd\x3c\x3c\xfc\x0a\x48\xb4\x6a\xda\x6a\x64\x52\xb5\x9d\xed\x8d\x87\x29\xf8\x6b\xd3\xe1\x6b\xb0\xe9\xb8\xcb\x3a\x77\xcf\x36\x50\xbd\xfb\x82\x87\x34\xe0\x08\x95\x90\x55\x3f\xae\xfb\xc4\xd6\x93\x5e\x5d\xbe\x5c\xdd\xb0\xe7\xdb\x9f\xf7\x97\x77\xcf\x1b\x73\x4a\x6e\xcb\x39\x33\x72\xa6\x78\x6d\x60\x0a\xc9\x39\xf9\x1b\x00\x00\xff\xff\x71\xae\x9c\xc9\x7f\x04\x00\x00") 128 | 129 | func data_patches_2_0_0_p451_01_readline_patch() ([]byte, error) { 130 | return bindata_read( 131 | _data_patches_2_0_0_p451_01_readline_patch, 132 | "data/patches/2.0.0-p451/01_readline.patch", 133 | ) 134 | } 135 | 136 | var _data_patches_2_1_0_01_readline_patch = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x54\xeb\x4f\xdb\x3e\x14\xfd\xfc\xf3\x5f\x71\x15\x7e\x52\x93\xe5\xb1\x3e\xc2\x23\x83\x4a\x65\x3c\x56\x34\x04\x88\xb2\x7d\xb5\x4c\x7c\x43\x2d\x52\x27\xb2\xdd\xae\xfc\xf7\x93\x43\x13\x16\xd4\x56\xb0\x69\xd2\xfc\x21\xb1\x6e\xce\x3d\xf7\xe4\xde\x63\x5f\x48\x8e\xcb\x4f\x80\x4b\xf3\x51\x21\xe3\xb9\x90\xd8\x6c\xa2\x94\x0c\xff\x7c\x91\x30\x0c\x37\xf1\xff\xe7\x2a\x5c\x08\x2d\x0a\x09\xf1\x6e\xbf\x1f\x7b\xc4\xf7\xfd\x37\x82\x77\x3d\x32\x1a\x41\xd8\x4b\xf6\xe3\x60\x1f\xfc\xd5\x7b\x34\x22\x40\xc0\x2e\x95\x53\x66\x0c\xce\x4a\x83\x9c\xa6\xc5\xac\xcc\xd1\x88\x42\xd2\x6c\x2e\x53\xbb\x81\x21\xd4\xdc\xdb\x81\x87\x04\x76\x44\x06\x1c\x33\x21\x91\xbb\xe3\xe3\xef\x67\xf4\xf6\x92\xde\xdc\x9e\xd1\x8b\xab\x9b\x6f\x77\x74\x7c\x7d\xfd\xd5\x23\xe1\xaa\x68\xa9\x90\x0a\x59\xce\x0d\x9d\x16\xc5\x23\x0c\xc1\x3d\xaf\x2b\x7e\xf0\x9a\x8a\x6d\xd4\x21\xf1\x37\x66\xab\xbc\xda\x56\x72\xa8\xd9\xc6\x01\x3b\x28\xb9\xc8\x2a\xb9\x1c\x33\xa8\x95\x9e\x1c\xdf\x9d\x8c\xe9\xe4\xe2\xcb\xd5\xf1\xe5\xa4\x69\x4e\xca\x4c\x3a\xa5\x5a\x3c\x48\x96\x6b\x18\x42\xf7\x90\xac\x33\x03\x2e\x4d\x5a\xc8\x2c\x52\xf7\x7f\xc7\x0c\x2f\xfc\xed\xf9\x0e\x92\x35\x66\xd8\x04\x8e\xbb\xb5\x19\x82\x3d\x6b\x85\xa0\xd7\xad\x9c\x00\xa0\xd0\xcc\x95\x04\x3d\x2f\x51\xb9\xb6\x85\x01\x4c\x91\x71\x54\xda\x23\x80\x92\x13\x20\xbe\xed\x55\x63\xb3\x29\x5b\x20\x35\x4f\x25\xba\xf6\xe1\xd9\xc1\xb4\x38\x6c\xf4\x17\x0e\xdf\x72\xf8\x04\xb8\x50\xd4\x4a\x13\x0f\x6e\x27\x9d\x2b\x8d\xba\xe3\xb5\xa3\x72\x7d\xd8\xa0\x9a\xa5\xac\xec\x3c\xff\x40\x12\x07\x31\xf8\xc9\x41\x70\x50\xe9\x6f\xab\xb2\xf2\x5d\x47\xe5\x54\x21\x17\xba\xcc\xd9\x93\xe3\x6d\xc4\x08\xa9\x51\x19\x6a\x70\x69\xb6\xa0\x38\xe6\x68\xb0\x46\xf9\x73\x99\xa3\xd6\xeb\x9a\xe1\xb4\x6d\xe8\x54\x8d\xf9\xff\xf4\xec\x7c\x02\x47\x47\xe0\x84\xa7\xed\xef\xc3\xda\xf3\x4e\xd3\xa1\x54\x21\x33\x48\x67\xec\x11\x33\x91\x5b\xc6\x55\x15\xc7\xfb\xa7\x8c\x17\xf7\xdf\x63\xbc\xc1\x6a\x6e\x95\xf1\x92\x24\x48\xb6\xcd\xed\x77\x66\x02\xef\x9c\xc9\x0e\xbc\xba\x30\x84\x06\xb6\x60\x22\x67\xf7\x39\x82\x16\x32\xc5\x86\x2b\x8c\xa3\x3e\xb8\xfd\x6e\xb7\xe7\x45\xcf\xb9\xcd\x55\x25\x6c\xc5\x59\xb1\x40\x0e\xcc\xbc\x24\xec\x45\x03\x9b\xd0\x8b\xeb\x84\x71\xf1\x03\x17\xa8\x02\x40\x2e\x8c\x85\x80\x7b\x85\xe6\xf3\xe4\x14\xf6\xa2\x5e\x34\x08\xa0\x02\x03\x2f\x50\xcb\x8e\x01\x2b\xfe\x95\xc0\xc8\x1e\xd3\x37\x39\xc9\x9e\xd7\x9f\x01\x00\x00\xff\xff\xdd\x85\xa5\xd3\xb0\x06\x00\x00") 137 | 138 | func data_patches_2_1_0_01_readline_patch() ([]byte, error) { 139 | return bindata_read( 140 | _data_patches_2_1_0_01_readline_patch, 141 | "data/patches/2.1.0/01_readline.patch", 142 | ) 143 | } 144 | 145 | var _data_patches_2_1_1_01_readline_patch = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x54\xeb\x4f\xdb\x3e\x14\xfd\xfc\xf3\x5f\x71\x15\x7e\x52\x93\xe5\xb1\x3e\xc2\x23\x83\x4a\x65\x3c\x56\x34\x04\x88\xb2\x7d\xb5\x4c\x7c\x43\x2d\x52\x27\xb2\xdd\xae\xfc\xf7\x93\x43\x13\x16\xd4\x56\xb0\x69\xd2\xfc\x21\xb1\x6e\xce\x3d\xf7\xe4\xde\x63\x5f\x48\x8e\xcb\x4f\x80\x4b\xf3\x51\x21\xe3\xb9\x90\xd8\x6c\xa2\x94\x0c\xff\x7c\x91\x30\x0c\x37\xf1\xff\xe7\x2a\x5c\x08\x2d\x0a\x09\xf1\x6e\xbf\x1f\x7b\xc4\xf7\xfd\x37\x82\x77\x3d\x32\x1a\x41\xd8\x4b\xf6\xe3\x60\x1f\xfc\xd5\x7b\x34\x22\x40\xc0\x2e\x95\x53\x66\x0c\xce\x4a\x83\x9c\xa6\xc5\xac\xcc\xd1\x88\x42\xd2\x6c\x2e\x53\xbb\x81\x21\xd4\xdc\xdb\x81\x87\x04\x76\x44\x06\x1c\x33\x21\x91\xbb\xe3\xe3\xef\x67\xf4\xf6\x92\xde\xdc\x9e\xd1\x8b\xab\x9b\x6f\x77\x74\x7c\x7d\xfd\xd5\x23\xe1\xaa\x68\xa9\x90\x0a\x59\xce\x0d\x9d\x16\xc5\x23\x0c\xc1\x3d\xaf\x2b\x7e\xf0\x9a\x8a\x6d\xd4\x21\xf1\x37\x66\xab\xbc\xda\x56\x72\xa8\xd9\xc6\x01\x3b\x28\xb9\xc8\x2a\xb9\x1c\x33\xa8\x95\x9e\x1c\xdf\x9d\x8c\xe9\xe4\xe2\xcb\xd5\xf1\xe5\xa4\x69\x4e\xca\x4c\x3a\xa5\x5a\x3c\x48\x96\x6b\x18\x42\xf7\x90\xac\x33\x03\x2e\x4d\x5a\xc8\x2c\x52\xf7\x7f\xc7\x0c\x2f\xfc\xed\xf9\x0e\x92\x35\x66\xd8\x04\x8e\xbb\xb5\x19\x82\x3d\x6b\x85\xa0\xd7\xad\x9c\x00\xa0\xd0\xcc\x95\x04\x3d\x2f\x51\xb9\xb6\x85\x01\x4c\x91\x71\x54\xda\x23\x80\x92\x13\x20\xbe\xed\x55\x63\xb3\x29\x5b\x20\x35\x4f\x25\xba\xf6\xe1\xd9\xc1\xb4\x38\x6c\xf4\x17\x0e\xdf\x72\xf8\x04\xb8\x50\xd4\x4a\x13\x0f\x6e\x27\x9d\x2b\x8d\xba\xe3\xb5\xa3\x72\x7d\xd8\xa0\x9a\xa5\xac\xec\x3c\xff\x40\x12\x07\x31\xf8\xc9\x41\x70\x50\xe9\x6f\xab\xb2\xf2\x5d\x47\xe5\x54\x21\x17\xba\xcc\xd9\x93\xe3\x6d\xc4\x08\xa9\x51\x19\x6a\x70\x69\xb6\xa0\x38\xe6\x68\xb0\x46\xf9\x73\x99\xa3\xd6\xeb\x9a\xe1\xb4\x6d\xe8\x54\x8d\xf9\xff\xf4\xec\x7c\x02\x47\x47\xe0\x84\xa7\xed\xef\xc3\xda\xf3\x4e\xd3\xa1\x54\x21\x33\x48\x67\xec\x11\x33\x91\x5b\xc6\x55\x15\xc7\xfb\xa7\x8c\x17\xf7\xdf\x63\xbc\xc1\x6a\x6e\x95\xf1\x92\x24\x48\xb6\xcd\xed\x77\x66\x02\xef\x9c\xc9\x0e\xbc\xba\x30\x84\x06\xb6\x60\x22\x67\xf7\x39\x82\x16\x32\xc5\x86\x2b\x8c\xa3\x3e\xb8\xfd\x6e\xb7\xe7\x45\xcf\xb9\xcd\x55\x25\x6c\xc5\x59\xb1\x40\x0e\xcc\xbc\x24\xec\x45\x03\x9b\xd0\x8b\xeb\x84\x71\xf1\x03\x17\xa8\x02\x40\x2e\x8c\x85\x80\x7b\x85\xe6\xf3\xe4\x14\xf6\xa2\x5e\x34\x08\xa0\x02\x03\x2f\x50\xcb\x8e\x01\x2b\xfe\x95\xc0\xc8\x1e\xd3\x37\x39\xc9\x9e\xd7\x9f\x01\x00\x00\xff\xff\xdd\x85\xa5\xd3\xb0\x06\x00\x00") 146 | 147 | func data_patches_2_1_1_01_readline_patch() ([]byte, error) { 148 | return bindata_read( 149 | _data_patches_2_1_1_01_readline_patch, 150 | "data/patches/2.1.1/01_readline.patch", 151 | ) 152 | } 153 | 154 | // Asset loads and returns the asset for the given name. 155 | // It returns an error if the asset could not be found or 156 | // could not be loaded. 157 | func Asset(name string) ([]byte, error) { 158 | cannonicalName := strings.Replace(name, "\\", "/", -1) 159 | if f, ok := _bindata[cannonicalName]; ok { 160 | return f() 161 | } 162 | return nil, fmt.Errorf("Asset %s not found", name) 163 | } 164 | 165 | // AssetNames returns the names of the assets. 166 | func AssetNames() []string { 167 | names := make([]string, 0, len(_bindata)) 168 | for name := range _bindata { 169 | names = append(names, name) 170 | } 171 | return names 172 | } 173 | 174 | // _bindata is a table, holding each asset generator, mapped to its name. 175 | var _bindata = map[string]func() ([]byte, error){ 176 | "data/Dockerfile-bionic-libssl.template": data_dockerfile_bionic_libssl_template, 177 | "data/Dockerfile-bionic.template": data_dockerfile_bionic_template, 178 | "data/Gemfile.bionic": data_gemfile_bionic, 179 | "data/Gemfile.bionic.lock": data_gemfile_bionic_lock, 180 | "data/patches/1.0.0/01_for_tests": data_patches_1_0_0_01_for_tests, 181 | "data/patches/1.0.0/02_for_tests": data_patches_1_0_0_02_for_tests, 182 | "data/patches/1.9.3-p551/01_strict_hostname_checking.patch": data_patches_1_9_3_p551_01_strict_hostname_checking_patch, 183 | "data/patches/2.0.0-p0/01_readline.patch": data_patches_2_0_0_p0_01_readline_patch, 184 | "data/patches/2.0.0-p195/01_readline.patch": data_patches_2_0_0_p195_01_readline_patch, 185 | "data/patches/2.0.0-p247/01_readline.patch": data_patches_2_0_0_p247_01_readline_patch, 186 | "data/patches/2.0.0-p353/01_readline.patch": data_patches_2_0_0_p353_01_readline_patch, 187 | "data/patches/2.0.0-p451/01_readline.patch": data_patches_2_0_0_p451_01_readline_patch, 188 | "data/patches/2.1.0/01_readline.patch": data_patches_2_1_0_01_readline_patch, 189 | "data/patches/2.1.1/01_readline.patch": data_patches_2_1_1_01_readline_patch, 190 | } 191 | // AssetDir returns the file names below a certain 192 | // directory embedded in the file by go-bindata. 193 | // For example if you run go-bindata on data/... and data contains the 194 | // following hierarchy: 195 | // data/ 196 | // foo.txt 197 | // img/ 198 | // a.png 199 | // b.png 200 | // then AssetDir("data") would return []string{"foo.txt", "img"} 201 | // AssetDir("data/img") would return []string{"a.png", "b.png"} 202 | // AssetDir("foo.txt") and AssetDir("notexist") would return an error 203 | // AssetDir("") will return []string{"data"}. 204 | func AssetDir(name string) ([]string, error) { 205 | node := _bintree 206 | if len(name) != 0 { 207 | cannonicalName := strings.Replace(name, "\\", "/", -1) 208 | pathList := strings.Split(cannonicalName, "/") 209 | for _, p := range pathList { 210 | node = node.Children[p] 211 | if node == nil { 212 | return nil, fmt.Errorf("Asset %s not found", name) 213 | } 214 | } 215 | } 216 | if node.Func != nil { 217 | return nil, fmt.Errorf("Asset %s not found", name) 218 | } 219 | rv := make([]string, 0, len(node.Children)) 220 | for name := range node.Children { 221 | rv = append(rv, name) 222 | } 223 | return rv, nil 224 | } 225 | 226 | type _bintree_t struct { 227 | Func func() ([]byte, error) 228 | Children map[string]*_bintree_t 229 | } 230 | var _bintree = &_bintree_t{nil, map[string]*_bintree_t{ 231 | "data": &_bintree_t{nil, map[string]*_bintree_t{ 232 | "Dockerfile-bionic-libssl.template": &_bintree_t{data_dockerfile_bionic_libssl_template, map[string]*_bintree_t{ 233 | }}, 234 | "Dockerfile-bionic.template": &_bintree_t{data_dockerfile_bionic_template, map[string]*_bintree_t{ 235 | }}, 236 | "Gemfile.bionic": &_bintree_t{data_gemfile_bionic, map[string]*_bintree_t{ 237 | }}, 238 | "Gemfile.bionic.lock": &_bintree_t{data_gemfile_bionic_lock, map[string]*_bintree_t{ 239 | }}, 240 | "patches": &_bintree_t{nil, map[string]*_bintree_t{ 241 | "1.0.0": &_bintree_t{nil, map[string]*_bintree_t{ 242 | "01_for_tests": &_bintree_t{data_patches_1_0_0_01_for_tests, map[string]*_bintree_t{ 243 | }}, 244 | "02_for_tests": &_bintree_t{data_patches_1_0_0_02_for_tests, map[string]*_bintree_t{ 245 | }}, 246 | }}, 247 | "1.9.3-p551": &_bintree_t{nil, map[string]*_bintree_t{ 248 | "01_strict_hostname_checking.patch": &_bintree_t{data_patches_1_9_3_p551_01_strict_hostname_checking_patch, map[string]*_bintree_t{ 249 | }}, 250 | }}, 251 | "2.0.0-p0": &_bintree_t{nil, map[string]*_bintree_t{ 252 | "01_readline.patch": &_bintree_t{data_patches_2_0_0_p0_01_readline_patch, map[string]*_bintree_t{ 253 | }}, 254 | }}, 255 | "2.0.0-p195": &_bintree_t{nil, map[string]*_bintree_t{ 256 | "01_readline.patch": &_bintree_t{data_patches_2_0_0_p195_01_readline_patch, map[string]*_bintree_t{ 257 | }}, 258 | }}, 259 | "2.0.0-p247": &_bintree_t{nil, map[string]*_bintree_t{ 260 | "01_readline.patch": &_bintree_t{data_patches_2_0_0_p247_01_readline_patch, map[string]*_bintree_t{ 261 | }}, 262 | }}, 263 | "2.0.0-p353": &_bintree_t{nil, map[string]*_bintree_t{ 264 | "01_readline.patch": &_bintree_t{data_patches_2_0_0_p353_01_readline_patch, map[string]*_bintree_t{ 265 | }}, 266 | }}, 267 | "2.0.0-p451": &_bintree_t{nil, map[string]*_bintree_t{ 268 | "01_readline.patch": &_bintree_t{data_patches_2_0_0_p451_01_readline_patch, map[string]*_bintree_t{ 269 | }}, 270 | }}, 271 | "2.1.0": &_bintree_t{nil, map[string]*_bintree_t{ 272 | "01_readline.patch": &_bintree_t{data_patches_2_1_0_01_readline_patch, map[string]*_bintree_t{ 273 | }}, 274 | }}, 275 | "2.1.1": &_bintree_t{nil, map[string]*_bintree_t{ 276 | "01_readline.patch": &_bintree_t{data_patches_2_1_1_01_readline_patch, map[string]*_bintree_t{ 277 | }}, 278 | }}, 279 | }}, 280 | }}, 281 | }} 282 | -------------------------------------------------------------------------------- /build_ruby.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/tar" 5 | "bytes" 6 | "fmt" 7 | "github.com/fsouza/go-dockerclient" 8 | "github.com/google/uuid" 9 | "github.com/urfave/cli" 10 | "io" 11 | "os" 12 | "path/filepath" 13 | "runtime" 14 | "sort" 15 | "strings" 16 | "text/template" 17 | ) 18 | 19 | var ( 20 | distros = map[string]string{ 21 | "ubuntu:18.04": "ubuntu:18.04", 22 | "ubuntu:18.04:libssl": "ubuntu:18.04:libssl", // drop this variant once we move beyond bionic 23 | "ubuntu:18.04:yjit": "ubuntu:18.04:yjit", // used for building 3.2.0 with yjit support 24 | "ubuntu:18.04:libssl-yjit": "ubuntu:18.04:libssl-yjit", // used for building 3.2.0 with yjit support and new libssl 25 | } 26 | 27 | docker_client *docker.Client 28 | docker_endpoint string 29 | red func(string) string 30 | green func(string) string 31 | light_green func(string) string 32 | ) 33 | 34 | const image_tag string = "ruby_build" 35 | 36 | func init() { 37 | endpoint := "unix:///var/run/docker.sock" 38 | client, err := docker.NewClient(endpoint) 39 | if err != nil { 40 | panic(err) 41 | } 42 | 43 | docker_client = client 44 | } 45 | 46 | func main() { 47 | 48 | app := cli.NewApp() 49 | app.Name = "build_ruby" 50 | app.Usage = "Build ruby debs from source for Ubuntu" 51 | 52 | app.Flags = []cli.Flag{ 53 | cli.StringFlag{ 54 | Name: "ruby, r", 55 | Value: "", 56 | Usage: "Required. The version to build, eg. 2.1.0 (for recent versions with no patch release) or 2.0.0-p451", 57 | }, 58 | cli.StringFlag{ 59 | Name: "distro, d", 60 | Value: "ubuntu:12.04", 61 | Usage: "Which distro to use for the build", 62 | }, 63 | cli.StringFlag{ 64 | Name: "arch, a", 65 | Value: "amd64", 66 | Usage: "Arch to use in package filename, eg: 'none', 'all', 'amd64' etc.", 67 | }, 68 | cli.StringFlag{ 69 | Name: "iteration, i", 70 | Value: "", 71 | Usage: "eg: 37s~precise", 72 | }, 73 | cli.IntFlag{ 74 | Name: "cpus, c", 75 | Usage: "The number of CPUs to use for the make process, defaults to the number in the local machine. Change if you're running on a remote docker host", 76 | }, 77 | } 78 | app.Action = buildRuby 79 | app.Run(os.Args) 80 | } 81 | 82 | func buildRuby(c *cli.Context) error { 83 | if c.String("ruby") == "" { 84 | fmt.Fprintln(os.Stderr, "@{r!}You didn't specify a Ruby version to build!") 85 | cli.ShowAppHelp(c) 86 | os.Exit(1) 87 | } 88 | 89 | if distros[c.String("distro")] == "" { 90 | fmt.Fprintln(os.Stderr, "@{r!}You specified a distro that I don't know how to build for") 91 | cli.ShowAppHelp(c) 92 | os.Exit(1) 93 | } 94 | 95 | var parallel_make_tasks int 96 | if c.Int("cpus") != 0 { 97 | parallel_make_tasks = c.Int("cpus") 98 | } else { 99 | parallel_make_tasks = runtime.NumCPU() 100 | } 101 | 102 | var patch_file_full_paths []string = patchFilePathsFromRubyVersion(c.String("ruby")) 103 | var gemfile_path, gemfile_lock_path = gemfilesFromDistro(distros[c.String("distro")]) 104 | 105 | var dockerfile *bytes.Buffer = dockerFileFromTemplate(distros[c.String("distro")], c.String("ruby"), c.String("arch"), c.String("iteration"), fileBasePaths(patch_file_full_paths), parallel_make_tasks) 106 | fmt.Println("@{g!}Using Dockerfile:") 107 | fmt.Printf("@{gc}%s\n", dockerfile) 108 | 109 | var build_tarfile *bytes.Buffer = createTarFileFromDockerfile(dockerfile, patch_file_full_paths, gemfile_path, gemfile_lock_path) 110 | 111 | image_uuid, err := uuid.NewRandom() 112 | if err != nil { 113 | panic(err) 114 | } 115 | image_name := fmt.Sprintf("ruby_build_%s_image", image_uuid) 116 | opts := docker.BuildImageOptions{ 117 | Name: image_name, 118 | NoCache: true, 119 | SuppressOutput: false, 120 | RmTmpContainer: true, 121 | ForceRmTmpContainer: true, 122 | InputStream: build_tarfile, 123 | OutputStream: os.Stdout, 124 | } 125 | if err := docker_client.BuildImage(opts); err != nil { 126 | panic(err) 127 | } 128 | fmt.Printf("@{g!}Created image with name %s\n", image_name) 129 | 130 | image, err := docker_client.InspectImage(image_name) 131 | if err != nil { 132 | panic(err) 133 | } 134 | 135 | /* 136 | Create a container with the created image id 137 | 138 | This seems like a hack. We need a "container" to enable us to copy the ruby 139 | package out, but I can't see how to do this without needed to run a command 140 | or just use specify an image ID directly, hence the noop 'date' command. 141 | 142 | */ 143 | 144 | fmt.Printf("@{g!}Creating container with from image id %s\n", image.ID) 145 | config := docker.Config{AttachStdout: false, AttachStdin: false, Image: image.ID, Cmd: []string{"date"}} 146 | container_uuid, err := uuid.NewRandom() 147 | if err != nil { 148 | panic(err) 149 | } 150 | container_name := fmt.Sprintf("ruby_build_%s_container", container_uuid) 151 | create_container_opts := docker.CreateContainerOptions{Name: container_name, Config: &config} 152 | container, err := docker_client.CreateContainer(create_container_opts) 153 | if err != nil { 154 | panic(err) 155 | } 156 | 157 | // See https://github.com/wjessop/build_ruby/issues/2 158 | if err := docker_client.StopContainer(container.ID, 1); err != nil { 159 | // panic(err) 160 | fmt.Printf("@{r!}Failed to stop container %d, error was: %s\n", container.ID, err.Error()) 161 | } 162 | 163 | copyPackageFromContainerToLocalFs(container, rubyPackageFileName(c.String("ruby"), c.String("iteration"), c.String("arch"), c.String("distro"))) 164 | 165 | fmt.Println("@{g!}Removing container:", container.ID) 166 | if err := docker_client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID, RemoveVolumes: true, Force: false}); err != nil { 167 | panic(err) 168 | } 169 | 170 | return nil 171 | } 172 | 173 | func patchFilePathsFromRubyVersion(version string) []string { 174 | var patch_files []string 175 | for _, name := range AssetNames() { 176 | if strings.Contains(name, fmt.Sprintf("/%s/", version)) { 177 | patch_files = append(patch_files, name) 178 | } 179 | } 180 | 181 | sort.Strings(patch_files) 182 | fmt.Printf("@{g}Found patch files for current Ruby version: %v\n", patch_files) 183 | return patch_files 184 | } 185 | 186 | func createTarFileFromDockerfile(dockerfile *bytes.Buffer, patch_file_paths []string, gemfile_path string, gemfile_lock_path string) *bytes.Buffer { 187 | // Create a buffer to write our archive to. 188 | buf := new(bytes.Buffer) 189 | 190 | // Create a new tar archive. 191 | tw := tar.NewWriter(buf) 192 | 193 | // Add the Dockerfile 194 | hdr := &tar.Header{ 195 | Name: "Dockerfile", 196 | Size: int64(dockerfile.Len()), 197 | } 198 | 199 | if err := tw.WriteHeader(hdr); err != nil { 200 | panic(err) 201 | } 202 | 203 | if _, err := tw.Write(dockerfile.Bytes()); err != nil { 204 | panic(err) 205 | } 206 | 207 | for _, path := range patch_file_paths { 208 | fmt.Printf("@{g}Adding patch file to the tar: %s (at path %s)\n", patch_file_paths, filepath.Base(path)) 209 | 210 | asset_bytes, err := Asset(path) 211 | if err != nil { 212 | panic(err) 213 | } 214 | 215 | // We store the patch files flat in the root dir, hence the Base call 216 | hdr := &tar.Header{ 217 | Name: filepath.Base(path), 218 | Size: int64(len(asset_bytes)), 219 | } 220 | if err := tw.WriteHeader(hdr); err != nil { 221 | panic(err) 222 | } 223 | 224 | if _, err := tw.Write(asset_bytes); err != nil { 225 | panic(err) 226 | } 227 | } 228 | 229 | fmt.Printf("@{g}Adding %s to the tar as Gemfile\n", gemfile_path) 230 | 231 | asset_bytes, err := Asset(gemfile_path) 232 | if err != nil { 233 | panic(err) 234 | } 235 | 236 | hdr = &tar.Header{ 237 | Name: "Gemfile", 238 | Size: int64(len(asset_bytes)), 239 | } 240 | if err := tw.WriteHeader(hdr); err != nil { 241 | panic(err) 242 | } 243 | 244 | if _, err := tw.Write(asset_bytes); err != nil { 245 | panic(err) 246 | } 247 | 248 | fmt.Printf("@{g}Adding %s to the tar as Gemfile.lock\n", gemfile_lock_path) 249 | 250 | asset_bytes, err = Asset(gemfile_path) 251 | if err != nil { 252 | panic(err) 253 | } 254 | 255 | hdr = &tar.Header{ 256 | Name: "Gemfile.lock", 257 | Size: int64(len(asset_bytes)), 258 | } 259 | if err := tw.WriteHeader(hdr); err != nil { 260 | panic(err) 261 | } 262 | 263 | if _, err := tw.Write(asset_bytes); err != nil { 264 | panic(err) 265 | } 266 | 267 | // Make sure to check the error on Close. 268 | if err := tw.Close(); err != nil { 269 | panic(err) 270 | } 271 | 272 | return buf 273 | } 274 | 275 | func copyPackageFromContainerToLocalFs(container *docker.Container, filename string) { 276 | fmt.Println("@{g!}Copying package out of the container") 277 | 278 | var buf bytes.Buffer 279 | if err := docker_client.DownloadFromContainer(container.ID, docker.DownloadFromContainerOptions{ 280 | Path: filename, 281 | OutputStream: &buf, 282 | }); err != nil { 283 | panic(err) 284 | } 285 | 286 | buffer := bytes.NewReader(buf.Bytes()) 287 | 288 | var tar_out *tar.Reader = tar.NewReader(buffer) 289 | tar_header, err := tar_out.Next() 290 | if err != nil { 291 | panic(err) 292 | } 293 | 294 | fmt.Printf("@{g!}Extracting package file %s (%d bytes)\n", tar_header.Name, tar_header.Size) 295 | 296 | out, err := os.Create(filename) 297 | if err != nil { 298 | panic(err) 299 | } 300 | defer out.Close() 301 | 302 | io.Copy(out, tar_out) 303 | } 304 | 305 | func rubyPackageFileName(version, iteration, arch string, distro string) string { 306 | var formatted_iteration = "" 307 | if iteration != "" { 308 | formatted_iteration = "_" + iteration 309 | } 310 | 311 | var formatted_arch = "" 312 | if arch != "none" { 313 | formatted_arch = "_" + arch 314 | } 315 | return "ruby-" + version + formatted_iteration + formatted_arch + packageFormat(distro) 316 | } 317 | 318 | func packageFormat(distro string) string { 319 | if strings.Contains(distro, "centos") || strings.Contains(distro, "rhel") { 320 | return ".rpm" 321 | } else { 322 | return ".deb" 323 | } 324 | } 325 | 326 | func dockerFileFromTemplate(distro, ruby_version, arch, iteration string, patches []string, parallel_make_jobs int) *bytes.Buffer { 327 | type buildVars struct { 328 | Distro string 329 | RubyVersion string 330 | Arch string 331 | Iteration string 332 | DownloadUrl string 333 | FileName string 334 | Patches []string 335 | NumCPU int 336 | } 337 | 338 | var formatted_iteration = "" 339 | if iteration != "" { 340 | formatted_iteration = fmt.Sprintf("--iteration %s \\", iteration) 341 | } 342 | 343 | download_url := rubyDownloadUrl(ruby_version) 344 | dockerfile_vars := buildVars{distro, ruby_version, arch, formatted_iteration, download_url, rubyPackageFileName(ruby_version, iteration, arch, distro), patches, parallel_make_jobs} 345 | 346 | // This would be way better as a look up table, or with a more formal lookup process 347 | var template_location string 348 | switch distro { 349 | case "ubuntu:18.04": 350 | template_location = "data/Dockerfile-bionic.template" 351 | case "ubuntu:18.04:libssl": // drop this variant once we move beyond bionic 352 | template_location = "data/Dockerfile-bionic-libssl.template" 353 | case "ubuntu:18.04:yjit": // used for building 3.2.0 with yjit support 354 | template_location = "data/Dockerfile-bionic-yjit.template" 355 | case "ubuntu:18.04:libssl-yjit": // used for building 3.2.0 with yjit support and new libssl 356 | template_location = "data/Dockerfile-bionic-libssl-yjit.template" 357 | default: 358 | template_location = "data/Dockerfile.template" 359 | } 360 | 361 | dockerfile_template, err := Asset(template_location) 362 | if err != nil { 363 | panic(err) 364 | } 365 | if len(dockerfile_template) == 0 { 366 | panic("Couldn't find Dockerfile template in bindata") 367 | } 368 | 369 | tmpl, err := template.New("dockerfile_template").Parse(string(dockerfile_template)) 370 | if err != nil { 371 | panic(err) 372 | } 373 | 374 | buf := new(bytes.Buffer) 375 | 376 | err = tmpl.Execute(buf, dockerfile_vars) 377 | if err != nil { 378 | panic(err) 379 | } 380 | 381 | return buf 382 | } 383 | 384 | func gemfilesFromDistro(distro string) (string, string) { 385 | switch distro { 386 | case "ubuntu:18.04": 387 | return "data/Gemfile.bionic", "data/Gemfile.bionic.lock" 388 | case "ubuntu:18.04:libssl": // drop this variant once we move beyond bionic 389 | return "data/Gemfile.bionic", "data/Gemfile.bionic.lock" 390 | case "ubuntu:18.04:yjit": // used for building 3.2.0 with yjit support 391 | return "data/Gemfile.bionic", "data/Gemfile.bionic.lock" 392 | case "ubuntu:18.04:libssl-yjit": // used for building 3.2.0 with yjit support and new libssl 393 | return "data/Gemfile.bionic", "data/Gemfile.bionic.lock" 394 | default: 395 | return "data/Gemfile.template", "data/Gemfile.template.lock" 396 | } 397 | } 398 | 399 | func rubyDownloadUrl(version string) string { 400 | // eg: 401 | // http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.1.tar.gz 402 | // http://cache.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p451.tar.gz 403 | 404 | v := majorMinorVersionOnly(version) 405 | return "http://cache.ruby-lang.org/pub/ruby/" + v + "/ruby-" + version + ".tar.gz" 406 | } 407 | 408 | func majorMinorVersionOnly(full_version string) string { 409 | return strings.Join(strings.SplitN(full_version, ".", 3)[0:2], ".") 410 | } 411 | 412 | func fileBasePaths(full_paths []string) (base_paths []string) { 413 | for _, p := range full_paths { 414 | base_paths = append(base_paths, filepath.Base(p)) 415 | } 416 | 417 | return 418 | } 419 | -------------------------------------------------------------------------------- /build_ruby_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/tar" 5 | "bytes" 6 | "fmt" 7 | "github.com/stretchr/testify/assert" 8 | "io/ioutil" 9 | "path/filepath" 10 | "testing" 11 | ) 12 | 13 | /* 14 | 15 | Unit tests. Skipped the tests that would have required mocking the Docker API 16 | for now, may make them actually create package files. 17 | 18 | */ 19 | 20 | func Test_majorMinorVersionOnly(t *testing.T) { 21 | assert.Equal(t, majorMinorVersionOnly("2.1.34"), "2.1") 22 | assert.Equal(t, majorMinorVersionOnly("1.9.3-p635"), "1.9") 23 | } 24 | 25 | func Test_rubyDownloadUrl(t *testing.T) { 26 | assert.Equal(t, rubyDownloadUrl("2.1.34"), "http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.34.tar.gz") 27 | assert.Equal(t, rubyDownloadUrl("2.0.34-p451"), "http://cache.ruby-lang.org/pub/ruby/2.0/ruby-2.0.34-p451.tar.gz") 28 | } 29 | 30 | // Could do with pushing this out to go-bindata or similar 31 | func Test_dockerFileFromTemplate(t *testing.T) { 32 | dockerfile_output := fmt.Sprintf(`FROM ubuntu:12.04 33 | RUN apt-get update 34 | RUN apt-get install -y ruby1.9.3 build-essential \ 35 | libc6-dev libffi-dev libgdbm-dev libncurses5-dev \ 36 | libreadline-dev libssl-dev libyaml-dev zlib1g-dev \ 37 | curl 38 | RUN ["/usr/bin/gem", "install", "fpm", "--bindir=/usr/bin", "--no-rdoc", "--no-ri"] 39 | RUN curl http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.34.tar.gz|tar oxzC /tmp 40 | ADD 01_strict_hostname_checking.patch / 41 | 42 | WORKDIR /tmp/ruby-2.1.34 43 | RUN for i in `+"`/bin/ls /*.patch`"+`; do patch -p0 < $i; done 44 | RUN CFLAGS='-march=x86-64 -O3 -fno-fast-math -g3 -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -std=iso9899:1999 -fPIC' ./configure \ 45 | --prefix=/usr/local \ 46 | --enable-shared \ 47 | --disable-install-doc \ 48 | --enable-load-relative 49 | # Seems to only affect some 1.9 series Rubies, but the combined make step: 50 | # 51 | # RUN make -j8 install DESTDIR=/tmp/fpm 52 | # 53 | # that ran the make then make install, was broken. Splitting it up into 54 | # two separate commands works fine: 55 | RUN make -j%d 56 | RUN make install DESTDIR=/tmp/fpm 57 | 58 | WORKDIR / 59 | RUN fpm \ 60 | -s dir \ 61 | -t deb \ 62 | -n ruby \ 63 | -a amd64 \ 64 | -v 2.1.34 \ 65 | --iteration 37s~precise \ 66 | -d libc6-dev \ 67 | -d libffi-dev \ 68 | -d libgdbm-dev \ 69 | -d libncurses5-dev \ 70 | -d libreadline-dev \ 71 | -d libssl-dev \ 72 | -d libyaml-dev \ 73 | -d zlib1g-dev \ 74 | -C /tmp/fpm \ 75 | -p /ruby-2.1.34_37s~precise_amd64.deb \ 76 | usr 77 | `, 18) 78 | 79 | assert.Equal(t, dockerFileFromTemplate("ubuntu:12.04", "2.1.34", "amd64", "37s~precise", []string{"01_strict_hostname_checking.patch"}, 18).String(), dockerfile_output) 80 | } 81 | 82 | func Test_rubyPackageFileName(t *testing.T) { 83 | assert.Equal(t, "ruby-2.1.0_37s~raring_amd64.deb", rubyPackageFileName("2.1.0", "37s~raring", "amd64", "ubuntu:12.04")) 84 | } 85 | 86 | func Test_createTarFileFromDockerfile(t *testing.T) { 87 | patch_files := []string{"Dockerfile", "data/patches/1.0.0/01_for_tests", "data/patches/1.0.0/02_for_tests"} 88 | file_data := []string{"foo", "bar", "baz"} 89 | 90 | tar_in_buffer := createTarFileFromDockerfile(bytes.NewBufferString("foo"), patch_files[1:3]) 91 | 92 | var tar_out *tar.Reader = tar.NewReader(tar_in_buffer) 93 | 94 | for i, filename := range patch_files { 95 | // Get the header so we can check the names of the files 96 | tar_header, err := tar_out.Next() 97 | if err != nil { 98 | panic(err) 99 | } 100 | 101 | var out_bytes []byte 102 | out_bytes, err = ioutil.ReadAll(tar_out) 103 | if err != nil { 104 | panic(err) 105 | } 106 | 107 | assert.Equal(t, tar_header.Name, filepath.Base(filename)) 108 | assert.Equal(t, string(out_bytes), file_data[i]) 109 | } 110 | } 111 | 112 | func Test_patchFilePathsFromRubyVersion(t *testing.T) { 113 | patches := patchFilePathsFromRubyVersion("1.0.0") 114 | expected_patches := []string{"data/patches/1.0.0/01_for_tests", "data/patches/1.0.0/02_for_tests"} 115 | assert.Equal(t, patches, expected_patches) 116 | } 117 | 118 | func Test_copyPackageFromContainerToLocalFs(t *testing.T) { 119 | t.Skip() 120 | } 121 | 122 | func Test_buildRuby(t *testing.T) { 123 | t.Skip() 124 | } 125 | -------------------------------------------------------------------------------- /data/Dockerfile-bionic-libssl-yjit.template: -------------------------------------------------------------------------------- 1 | # Only produces builds for ruby >= 2.4 due to the newer openssl 2 | # see https://3.basecamp.com/2914079/buckets/21350690/todos/4209849128 3 | # 4 | # We should drop this variant when we move beyond bionic 5 | 6 | # Can't use {{.Distro}} since it's ubuntu:18.04:libssl 7 | FROM ubuntu:18.04 8 | RUN apt-get update 9 | RUN apt-get install -y build-essential \ 10 | libc6-dev libffi-dev libgdbm-dev libncurses5-dev \ 11 | libreadline-dev libssl-dev libyaml-dev zlib1g-dev rustc \ 12 | curl ruby ruby-dev 13 | RUN ["/usr/bin/gem", "install", "bundler", "-v", "1.17.3", "--no-rdoc", "--no-ri"] 14 | ADD Gemfile / 15 | ADD Gemfile.lock / 16 | RUN ["bundle", "install"] 17 | 18 | RUN curl {{.DownloadUrl}}|tar oxzC /tmp 19 | {{range .Patches}}ADD {{.}} / 20 | {{end}} 21 | WORKDIR /tmp/ruby-{{.RubyVersion}} 22 | RUN for i in `/bin/ls /*.patch`; do patch -p0 < $i; done 23 | RUN CFLAGS='-march=x86-64 -O3 -fno-fast-math -g3 -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -std=iso9899:1999 -fPIC' ./configure \ 24 | --prefix=/opt/ruby{{.RubyVersion}} \ 25 | --enable-shared \ 26 | --disable-install-doc \ 27 | --enable-load-relative \ 28 | --enable-yjit 29 | # Seems to only affect some 1.9 series Rubies, but the combined make step: 30 | # 31 | # RUN make -j8 install DESTDIR=/tmp/fpm 32 | # 33 | # that ran the make then make install, was broken. Splitting it up into 34 | # two separate commands works fine: 35 | RUN make -j{{.NumCPU}} 36 | RUN make install DESTDIR=/tmp/fpm 37 | 38 | WORKDIR / 39 | RUN fpm \ 40 | -s dir \ 41 | -t deb \ 42 | -n ruby-{{.RubyVersion}} \ 43 | -a {{.Arch}} \ 44 | -v {{.RubyVersion}} \ 45 | {{.Iteration}} 46 | -d libc6-dev \ 47 | -d libffi-dev \ 48 | -d libgdbm-dev \ 49 | -d libncurses5-dev \ 50 | -d libreadline-dev \ 51 | -d libssl-dev \ 52 | -d libyaml-dev \ 53 | -d zlib1g-dev \ 54 | -C /tmp/fpm \ 55 | -p /{{.FileName}} \ 56 | opt 57 | -------------------------------------------------------------------------------- /data/Dockerfile-bionic-libssl.template: -------------------------------------------------------------------------------- 1 | # Only produces builds for ruby >= 2.4 due to the newer openssl 2 | # see https://3.basecamp.com/2914079/buckets/21350690/todos/4209849128 3 | # 4 | # We should drop this variant when we move beyond bionic 5 | 6 | # Can't use {{.Distro}} since it's ubuntu:18.04:libssl 7 | FROM ubuntu:18.04 8 | RUN apt-get update 9 | RUN apt-get install -y build-essential \ 10 | libc6-dev libffi-dev libgdbm-dev libncurses5-dev \ 11 | libreadline-dev libssl-dev libyaml-dev zlib1g-dev \ 12 | curl ruby ruby-dev 13 | RUN ["/usr/bin/gem", "install", "bundler", "-v", "1.17.3", "--no-rdoc", "--no-ri"] 14 | ADD Gemfile / 15 | ADD Gemfile.lock / 16 | RUN ["bundle", "install"] 17 | 18 | RUN curl {{.DownloadUrl}}|tar oxzC /tmp 19 | {{range .Patches}}ADD {{.}} / 20 | {{end}} 21 | WORKDIR /tmp/ruby-{{.RubyVersion}} 22 | RUN for i in `/bin/ls /*.patch`; do patch -p0 < $i; done 23 | RUN CFLAGS='-march=x86-64 -O3 -fno-fast-math -g3 -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -std=iso9899:1999 -fPIC' ./configure \ 24 | --prefix=/opt/ruby{{.RubyVersion}} \ 25 | --enable-shared \ 26 | --disable-install-doc \ 27 | --enable-load-relative 28 | # Seems to only affect some 1.9 series Rubies, but the combined make step: 29 | # 30 | # RUN make -j8 install DESTDIR=/tmp/fpm 31 | # 32 | # that ran the make then make install, was broken. Splitting it up into 33 | # two separate commands works fine: 34 | RUN make -j{{.NumCPU}} 35 | RUN make install DESTDIR=/tmp/fpm 36 | 37 | WORKDIR / 38 | RUN fpm \ 39 | -s dir \ 40 | -t deb \ 41 | -n ruby-{{.RubyVersion}} \ 42 | -a {{.Arch}} \ 43 | -v {{.RubyVersion}} \ 44 | {{.Iteration}} 45 | -d libc6-dev \ 46 | -d libffi-dev \ 47 | -d libgdbm-dev \ 48 | -d libncurses5-dev \ 49 | -d libreadline-dev \ 50 | -d libssl-dev \ 51 | -d libyaml-dev \ 52 | -d zlib1g-dev \ 53 | -C /tmp/fpm \ 54 | -p /{{.FileName}} \ 55 | opt 56 | -------------------------------------------------------------------------------- /data/Dockerfile-bionic-yjit.template: -------------------------------------------------------------------------------- 1 | # Can't use {{.Distro}} since it's ubuntu:18.04:yjit 2 | FROM ubuntu:18.04 3 | RUN apt-get update 4 | RUN apt-get install -y build-essential \ 5 | libc6-dev libffi-dev libgdbm-dev libncurses5-dev \ 6 | libreadline-dev libssl1.0-dev libyaml-dev zlib1g-dev rustc \ 7 | curl ruby ruby-dev 8 | RUN ["/usr/bin/gem", "install", "bundler", "-v", "1.17.3", "--no-rdoc", "--no-ri"] 9 | ADD Gemfile / 10 | ADD Gemfile.lock / 11 | RUN ["bundle", "install"] 12 | 13 | RUN curl {{.DownloadUrl}}|tar oxzC /tmp 14 | {{range .Patches}}ADD {{.}} / 15 | {{end}} 16 | WORKDIR /tmp/ruby-{{.RubyVersion}} 17 | RUN for i in `/bin/ls /*.patch`; do patch -p0 < $i; done 18 | RUN CFLAGS='-march=x86-64 -O3 -fno-fast-math -g3 -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -std=iso9899:1999 -fPIC' ./configure \ 19 | --prefix=/opt/ruby{{.RubyVersion}} \ 20 | --enable-shared \ 21 | --disable-install-doc \ 22 | --enable-load-relative \ 23 | --enable-yjit 24 | # Seems to only affect some 1.9 series Rubies, but the combined make step: 25 | # 26 | # RUN make -j8 install DESTDIR=/tmp/fpm 27 | # 28 | # that ran the make then make install, was broken. Splitting it up into 29 | # two separate commands works fine: 30 | RUN make -j{{.NumCPU}} 31 | RUN make install DESTDIR=/tmp/fpm 32 | 33 | WORKDIR / 34 | RUN fpm \ 35 | -s dir \ 36 | -t deb \ 37 | -n ruby-{{.RubyVersion}} \ 38 | -a {{.Arch}} \ 39 | -v {{.RubyVersion}} \ 40 | {{.Iteration}} 41 | -d libc6-dev \ 42 | -d libffi-dev \ 43 | -d libgdbm-dev \ 44 | -d libncurses5-dev \ 45 | -d libreadline-dev \ 46 | -d libssl1.0-dev \ 47 | -d libyaml-dev \ 48 | -d zlib1g-dev \ 49 | -C /tmp/fpm \ 50 | -p /{{.FileName}} \ 51 | opt 52 | -------------------------------------------------------------------------------- /data/Dockerfile-bionic.template: -------------------------------------------------------------------------------- 1 | FROM {{.Distro}} 2 | RUN apt-get update 3 | RUN apt-get install -y build-essential \ 4 | libc6-dev libffi-dev libgdbm-dev libncurses5-dev \ 5 | libreadline-dev libssl1.0-dev libyaml-dev zlib1g-dev \ 6 | curl ruby ruby-dev 7 | RUN ["/usr/bin/gem", "install", "bundler", "-v", "1.17.3", "--no-rdoc", "--no-ri"] 8 | ADD Gemfile / 9 | ADD Gemfile.lock / 10 | RUN ["bundle", "install"] 11 | 12 | RUN curl {{.DownloadUrl}}|tar oxzC /tmp 13 | {{range .Patches}}ADD {{.}} / 14 | {{end}} 15 | WORKDIR /tmp/ruby-{{.RubyVersion}} 16 | RUN for i in `/bin/ls /*.patch`; do patch -p0 < $i; done 17 | RUN CFLAGS='-march=x86-64 -O3 -fno-fast-math -g3 -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -std=iso9899:1999 -fPIC' ./configure \ 18 | --prefix=/opt/ruby{{.RubyVersion}} \ 19 | --enable-shared \ 20 | --disable-install-doc \ 21 | --enable-load-relative 22 | # Seems to only affect some 1.9 series Rubies, but the combined make step: 23 | # 24 | # RUN make -j8 install DESTDIR=/tmp/fpm 25 | # 26 | # that ran the make then make install, was broken. Splitting it up into 27 | # two separate commands works fine: 28 | RUN make -j{{.NumCPU}} 29 | RUN make install DESTDIR=/tmp/fpm 30 | 31 | WORKDIR / 32 | RUN fpm \ 33 | -s dir \ 34 | -t deb \ 35 | -n ruby-{{.RubyVersion}} \ 36 | -a {{.Arch}} \ 37 | -v {{.RubyVersion}} \ 38 | {{.Iteration}} 39 | -d libc6-dev \ 40 | -d libffi-dev \ 41 | -d libgdbm-dev \ 42 | -d libncurses5-dev \ 43 | -d libreadline-dev \ 44 | -d libssl1.0-dev \ 45 | -d libyaml-dev \ 46 | -d zlib1g-dev \ 47 | -C /tmp/fpm \ 48 | -p /{{.FileName}} \ 49 | opt 50 | -------------------------------------------------------------------------------- /data/Dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM {{.Distro}} 2 | RUN apt-get update || true 3 | RUN apt-get install -y ruby1.9.3 build-essential \ 4 | libc6-dev libffi-dev libgdbm-dev libncurses5-dev \ 5 | libreadline-dev libssl-dev libyaml-dev zlib1g-dev \ 6 | curl 7 | RUN ["/usr/bin/gem", "install", "bundler", "-v", "1.17.3", "--no-rdoc", "--no-ri"] 8 | ADD Gemfile / 9 | ADD Gemfile.lock / 10 | RUN ["bundle", "install"] 11 | 12 | RUN curl {{.DownloadUrl}}|tar oxzC /tmp 13 | {{range .Patches}}ADD {{.}} / 14 | {{end}} 15 | WORKDIR /tmp/ruby-{{.RubyVersion}} 16 | RUN for i in `/bin/ls /*.patch`; do patch -p0 < $i; done 17 | RUN CFLAGS='-march=x86-64 -O3 -fno-fast-math -g3 -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -std=iso9899:1999 -fPIC' ./configure \ 18 | --prefix=/opt/ruby{{.RubyVersion}} \ 19 | --enable-shared \ 20 | --disable-install-doc \ 21 | --enable-load-relative 22 | # Seems to only affect some 1.9 series Rubies, but the combined make step: 23 | # 24 | # RUN make -j8 install DESTDIR=/tmp/fpm 25 | # 26 | # that ran the make then make install, was broken. Splitting it up into 27 | # two separate commands works fine: 28 | RUN make -j{{.NumCPU}} 29 | RUN make install DESTDIR=/tmp/fpm 30 | 31 | WORKDIR / 32 | RUN fpm \ 33 | -s dir \ 34 | -t deb \ 35 | -n ruby-{{.RubyVersion}} \ 36 | -a {{.Arch}} \ 37 | -v {{.RubyVersion}} \ 38 | {{.Iteration}} 39 | -d libc6-dev \ 40 | -d libffi-dev \ 41 | -d libgdbm-dev \ 42 | -d libncurses5-dev \ 43 | -d libreadline-dev \ 44 | -d libssl-dev \ 45 | -d libyaml-dev \ 46 | -d zlib1g-dev \ 47 | -C /tmp/fpm \ 48 | -p /{{.FileName}} \ 49 | opt 50 | -------------------------------------------------------------------------------- /data/Gemfile.bionic: -------------------------------------------------------------------------------- 1 | # Created with ruby 2.5.x used in bionic 2 | 3 | source 'https://rubygems.org' 4 | 5 | gem 'fpm', '1.11.0' 6 | -------------------------------------------------------------------------------- /data/Gemfile.bionic.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | arr-pm (0.0.10) 5 | cabin (> 0) 6 | backports (3.21.0) 7 | cabin (0.9.0) 8 | childprocess (0.9.0) 9 | ffi (~> 1.0, >= 1.0.11) 10 | clamp (1.0.1) 11 | dotenv (2.7.6) 12 | ffi (1.15.1) 13 | fpm (1.11.0) 14 | arr-pm (~> 0.0.10) 15 | backports (>= 2.6.2) 16 | cabin (>= 0.6.0) 17 | childprocess (= 0.9.0) 18 | clamp (~> 1.0.0) 19 | ffi 20 | json (>= 1.7.7, < 2.0) 21 | pleaserun (~> 0.0.29) 22 | ruby-xz (~> 0.2.3) 23 | stud 24 | insist (1.0.0) 25 | io-like (0.3.1) 26 | json (1.8.6) 27 | mustache (0.99.8) 28 | pleaserun (0.0.32) 29 | cabin (> 0) 30 | clamp 31 | dotenv 32 | insist 33 | mustache (= 0.99.8) 34 | stud 35 | ruby-xz (0.2.3) 36 | ffi (~> 1.9) 37 | io-like (~> 0.3) 38 | stud (0.0.23) 39 | 40 | PLATFORMS 41 | ruby 42 | 43 | DEPENDENCIES 44 | fpm (= 1.11.0) 45 | 46 | BUNDLED WITH 47 | 1.17.3 48 | -------------------------------------------------------------------------------- /data/Gemfile.template: -------------------------------------------------------------------------------- 1 | # Created with ruby 1.9.x used in trusty 2 | 3 | source 'https://rubygems.org' 4 | 5 | gem 'fpm', '1.10.2' 6 | -------------------------------------------------------------------------------- /data/Gemfile.template.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | arr-pm (0.0.10) 5 | cabin (> 0) 6 | backports (3.21.0) 7 | cabin (0.9.0) 8 | childprocess (1.0.1) 9 | rake (< 13.0) 10 | clamp (1.0.1) 11 | dotenv (2.7.6) 12 | ffi (1.10.0) 13 | fpm (1.10.2) 14 | arr-pm (~> 0.0.10) 15 | backports (>= 2.6.2) 16 | cabin (>= 0.6.0) 17 | childprocess 18 | clamp (~> 1.0.0) 19 | ffi 20 | json (>= 1.7.7, < 2.0) 21 | pleaserun (~> 0.0.29) 22 | ruby-xz (~> 0.2.3) 23 | stud 24 | insist (1.0.0) 25 | io-like (0.3.1) 26 | json (1.8.6) 27 | mustache (0.99.8) 28 | pleaserun (0.0.32) 29 | cabin (> 0) 30 | clamp 31 | dotenv 32 | insist 33 | mustache (= 0.99.8) 34 | stud 35 | rake (12.2.1) 36 | ruby-xz (0.2.3) 37 | ffi (~> 1.9) 38 | io-like (~> 0.3) 39 | stud (0.0.23) 40 | 41 | PLATFORMS 42 | ruby 43 | 44 | DEPENDENCIES 45 | fpm (= 1.10.2) 46 | 47 | BUNDLED WITH 48 | 1.17.3 49 | -------------------------------------------------------------------------------- /data/patches/1.0.0/01_for_tests: -------------------------------------------------------------------------------- 1 | bar -------------------------------------------------------------------------------- /data/patches/1.0.0/02_for_tests: -------------------------------------------------------------------------------- 1 | baz -------------------------------------------------------------------------------- /data/patches/1.9.3-p551/01_strict_hostname_checking.patch: -------------------------------------------------------------------------------- 1 | From 9c237a872b30b041b414405258692fe00188c2e5 Mon Sep 17 00:00:00 2001 2 | From: Tony Arcieri 3 | Date: Sun, 29 Mar 2015 17:28:44 -0700 4 | Subject: [PATCH] Stricter hostname verification following RFC 6125. 5 | 6 | Thanks to @nahi for the tests and initial documentation. 7 | --- 8 | ext/openssl/lib/openssl/ssl-internal.rb | 62 ++++++++++++++++++++-- 9 | test/openssl/test_ssl.rb | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 | 2 files changed, 208 insertions(+), 4 deletions(-) 11 | 12 | diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb 13 | index ff1d4ef..caf0b9a 100644 14 | --- ext/openssl/lib/openssl/ssl-internal.rb 15 | +++ ext/openssl/lib/openssl/ssl-internal.rb 16 | @@ -143,8 +143,7 @@ def verify_certificate_identity(cert, hostname) 17 | case san.tag 18 | when 2 # dNSName in GeneralName (RFC5280) 19 | should_verify_common_name = false 20 | - reg = Regexp.escape(san.value).gsub(/\\\*/, "[^.]+") 21 | - return true if /\A#{reg}\z/i =~ hostname 22 | + return true if verify_hostname(hostname, san.value) 23 | when 7 # iPAddress in GeneralName (RFC5280) 24 | should_verify_common_name = false 25 | # follows GENERAL_NAME_print() in x509v3/v3_alt.c 26 | @@ -159,8 +158,7 @@ def verify_certificate_identity(cert, hostname) 27 | if should_verify_common_name 28 | cert.subject.to_a.each{|oid, value| 29 | if oid == "CN" 30 | - reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") 31 | - return true if /\A#{reg}\z/i =~ hostname 32 | + return true if verify_hostname(hostname, value) 33 | end 34 | } 35 | end 36 | @@ -168,11 +166,67 @@ def verify_certificate_identity(cert, hostname) 37 | end 38 | module_function :verify_certificate_identity 39 | 40 | + def verify_hostname(hostname, san) # :nodoc: 41 | + # RFC 5280, IA5String is limited to the set of ASCII characters 42 | + return false unless san.ascii_only? 43 | + return false unless hostname.ascii_only? 44 | + 45 | + # See RFC 6125, section 6.4.1 46 | + # Matching is case-insensitive. 47 | + san_parts = san.downcase.split(".") 48 | + 49 | + # TODO: this behavior should probably be more strict 50 | + return san == hostname if san_parts.size < 2 51 | + 52 | + # Matching is case-insensitive. 53 | + host_parts = hostname.downcase.split(".") 54 | + 55 | + # RFC 6125, section 6.4.3, subitem 2. 56 | + # If the wildcard character is the only character of the left-most 57 | + # label in the presented identifier, the client SHOULD NOT compare 58 | + # against anything but the left-most label of the reference 59 | + # identifier (e.g., *.example.com would match foo.example.com but 60 | + # not bar.foo.example.com or example.com). 61 | + return false unless san_parts.size == host_parts.size 62 | + 63 | + # RFC 6125, section 6.4.3, subitem 1. 64 | + # The client SHOULD NOT attempt to match a presented identifier in 65 | + # which the wildcard character comprises a label other than the 66 | + # left-most label (e.g., do not match bar.*.example.net). 67 | + return false unless verify_wildcard(host_parts.shift, san_parts.shift) 68 | + 69 | + san_parts.join(".") == host_parts.join(".") 70 | + end 71 | + module_function :verify_hostname 72 | + 73 | + def verify_wildcard(domain_component, san_component) # :nodoc: 74 | + parts = san_component.split("*", -1) 75 | + 76 | + return false if parts.size > 2 77 | + return san_component == domain_component if parts.size == 1 78 | + 79 | + # RFC 6125, section 6.4.3, subitem 3. 80 | + # The client SHOULD NOT attempt to match a presented identifier 81 | + # where the wildcard character is embedded within an A-label or 82 | + # U-label of an internationalized domain name. 83 | + return false if domain_component.start_with?("xn--") && san_component != "*" 84 | + 85 | + parts[0].length + parts[1].length < domain_component.length && 86 | + domain_component.start_with?(parts[0]) && 87 | + domain_component.end_with?(parts[1]) 88 | + end 89 | + module_function :verify_wildcard 90 | + 91 | class SSLSocket 92 | include Buffering 93 | include SocketForwarder 94 | include Nonblock 95 | 96 | + ## 97 | + # Perform hostname verification after an SSL connection is established 98 | + # 99 | + # This method MUST be called after calling #connect to ensure that the 100 | + # hostname of a remote peer has been verified. 101 | def post_connection_check(hostname) 102 | unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) 103 | raise SSLError, "hostname \"#{hostname}\" does not match the server certificate" 104 | diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb 105 | index b65399f..4240182 100644 106 | --- test/openssl/test_ssl.rb 107 | +++ test/openssl/test_ssl.rb 108 | @@ -426,6 +426,156 @@ def test_verify_certificate_identity 109 | end 110 | end 111 | 112 | + def test_verify_hostname 113 | + assert_equal(true, OpenSSL::SSL.verify_hostname("www.example.com", "*.example.com")) 114 | + assert_equal(false, OpenSSL::SSL.verify_hostname("www.subdomain.example.com", "*.example.com")) 115 | + end 116 | + 117 | + def test_verify_wildcard 118 | + assert_equal(false, OpenSSL::SSL.verify_wildcard("foo", "x*")) 119 | + assert_equal(true, OpenSSL::SSL.verify_wildcard("foo", "foo")) 120 | + assert_equal(true, OpenSSL::SSL.verify_wildcard("foo", "f*")) 121 | + assert_equal(true, OpenSSL::SSL.verify_wildcard("foo", "*")) 122 | + assert_equal(false, OpenSSL::SSL.verify_wildcard("abc*bcd", "abcd")) 123 | + assert_equal(false, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "x*")) 124 | + assert_equal(false, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "*--qdk4b9b")) 125 | + assert_equal(true, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "xn--qdk4b9b")) 126 | + end 127 | + 128 | + # Comments in this test is excerpted from http://tools.ietf.org/html/rfc6125#page-27 129 | + def test_post_connection_check_wildcard_san 130 | + # case-insensitive ASCII comparison 131 | + # RFC 6125, section 6.4.1 132 | + # 133 | + # "..matching of the reference identifier against the presented identifier 134 | + # is performed by comparing the set of domain name labels using a 135 | + # case-insensitive ASCII comparison, as clarified by [DNS-CASE] (e.g., 136 | + # "WWW.Example.Com" would be lower-cased to "www.example.com" for 137 | + # comparison purposes) 138 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 139 | + create_cert_with_san('DNS:*.example.com'), 'www.example.com')) 140 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 141 | + create_cert_with_san('DNS:*.Example.COM'), 'www.example.com')) 142 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 143 | + create_cert_with_san('DNS:*.example.com'), 'WWW.Example.COM')) 144 | + # 1. The client SHOULD NOT attempt to match a presented identifier in 145 | + # which the wildcard character comprises a label other than the 146 | + # left-most label (e.g., do not match bar.*.example.net). 147 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 148 | + create_cert_with_san('DNS:www.*.com'), 'www.example.com')) 149 | + # 2. If the wildcard character is the only character of the left-most 150 | + # label in the presented identifier, the client SHOULD NOT compare 151 | + # against anything but the left-most label of the reference 152 | + # identifier (e.g., *.example.com would match foo.example.com but 153 | + # not bar.foo.example.com or example.com). 154 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 155 | + create_cert_with_san('DNS:*.example.com'), 'foo.example.com')) 156 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 157 | + create_cert_with_san('DNS:*.example.com'), 'bar.foo.example.com')) 158 | + # 3. The client MAY match a presented identifier in which the wildcard 159 | + # character is not the only character of the label (e.g., 160 | + # baz*.example.net and *baz.example.net and b*z.example.net would 161 | + # be taken to match baz1.example.net and foobaz.example.net and 162 | + # buzz.example.net, respectively). ... 163 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 164 | + create_cert_with_san('DNS:baz*.example.com'), 'baz1.example.com')) 165 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 166 | + create_cert_with_san('DNS:*baz.example.com'), 'foobaz.example.com')) 167 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 168 | + create_cert_with_san('DNS:b*z.example.com'), 'buzz.example.com')) 169 | + # Section 6.4.3 of RFC6125 states that client should NOT match identifier 170 | + # where wildcard is other than left-most label. 171 | + # 172 | + # Also implicitly mentions the wildcard character only in singular form, 173 | + # and discourages matching against more than one wildcard. 174 | + # 175 | + # See RFC 6125, section 7.2, subitem 2. 176 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 177 | + create_cert_with_san('DNS:*b*.example.com'), 'abc.example.com')) 178 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 179 | + create_cert_with_san('DNS:*b*.example.com'), 'ab.example.com')) 180 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 181 | + create_cert_with_san('DNS:*b*.example.com'), 'bc.example.com')) 182 | + # ... However, the client SHOULD NOT 183 | + # attempt to match a presented identifier where the wildcard 184 | + # character is embedded within an A-label or U-label [IDNA-DEFS] of 185 | + # an internationalized domain name [IDNA-PROTO]. 186 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 187 | + create_cert_with_san('DNS:xn*.example.com'), 'xn1ca.example.com')) 188 | + # part of A-label 189 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 190 | + create_cert_with_san('DNS:xn--*.example.com'), 'xn--1ca.example.com')) 191 | + # part of U-label 192 | + # dNSName in RFC5280 is an IA5String so U-label should NOT be allowed 193 | + # regardless of wildcard. 194 | + # 195 | + # See Section 7.2 of RFC 5280: 196 | + # IA5String is limited to the set of ASCII characters. 197 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 198 | + create_cert_with_san('DNS:á*.example.com'), 'á1.example.com')) 199 | + end 200 | + 201 | + def test_post_connection_check_wildcard_cn 202 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 203 | + create_cert_with_name('*.example.com'), 'www.example.com')) 204 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 205 | + create_cert_with_name('*.Example.COM'), 'www.example.com')) 206 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 207 | + create_cert_with_name('*.example.com'), 'WWW.Example.COM')) 208 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 209 | + create_cert_with_name('www.*.com'), 'www.example.com')) 210 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 211 | + create_cert_with_name('*.example.com'), 'foo.example.com')) 212 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 213 | + create_cert_with_name('*.example.com'), 'bar.foo.example.com')) 214 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 215 | + create_cert_with_name('baz*.example.com'), 'baz1.example.com')) 216 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 217 | + create_cert_with_name('*baz.example.com'), 'foobaz.example.com')) 218 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 219 | + create_cert_with_name('b*z.example.com'), 'buzz.example.com')) 220 | + # Section 6.4.3 of RFC6125 states that client should NOT match identifier 221 | + # where wildcard is other than left-most label. 222 | + # 223 | + # Also implicitly mentions the wildcard character only in singular form, 224 | + # and discourages matching against more than one wildcard. 225 | + # 226 | + # See RFC 6125, section 7.2, subitem 2. 227 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 228 | + create_cert_with_name('*b*.example.com'), 'abc.example.com')) 229 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 230 | + create_cert_with_name('*b*.example.com'), 'ab.example.com')) 231 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 232 | + create_cert_with_name('*b*.example.com'), 'bc.example.com')) 233 | + assert_equal(true, OpenSSL::SSL.verify_certificate_identity( 234 | + create_cert_with_name('xn*.example.com'), 'xn1ca.example.com')) 235 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 236 | + create_cert_with_name('xn--*.example.com'), 'xn--1ca.example.com')) 237 | + # part of U-label 238 | + # Subject in RFC5280 states case-insensitive ASCII comparison. 239 | + # 240 | + # See Section 7.2 of RFC 5280: 241 | + # IA5String is limited to the set of ASCII characters. 242 | + assert_equal(false, OpenSSL::SSL.verify_certificate_identity( 243 | + create_cert_with_name('á*.example.com'), 'á1.example.com')) 244 | + end 245 | + 246 | + def create_cert_with_san(san) 247 | + ef = OpenSSL::X509::ExtensionFactory.new 248 | + cert = OpenSSL::X509::Certificate.new 249 | + cert.subject = OpenSSL::X509::Name.parse("/DC=some/DC=site/CN=Some Site") 250 | + ext = ef.create_ext('subjectAltName', san) 251 | + cert.add_extension(ext) 252 | + cert 253 | + end 254 | + 255 | + def create_cert_with_name(name) 256 | + cert = OpenSSL::X509::Certificate.new 257 | + cert.subject = OpenSSL::X509::Name.new([['DC', 'some'], ['DC', 'site'], ['CN', name]]) 258 | + cert 259 | + end 260 | + 261 | + 262 | # Create NULL byte SAN certificate 263 | def create_null_byte_SAN_certificate(critical = false) 264 | ef = OpenSSL::X509::ExtensionFactory.new -------------------------------------------------------------------------------- /data/patches/2.0.0-p0/01_readline.patch: -------------------------------------------------------------------------------- 1 | diff --git ext/readline/extconf.rb ext/readline/extconf.rb 2 | index 4920137..8e81253 100644 3 | --- ext/readline/extconf.rb 4 | +++ ext/readline/extconf.rb 5 | @@ -19,6 +19,10 @@ def readline.have_func(func) 6 | return super(func, headers) 7 | end 8 | 9 | +def readline.have_type(type) 10 | + return super(type, headers) 11 | +end 12 | + 13 | dir_config('curses') 14 | dir_config('ncurses') 15 | dir_config('termcap') 16 | @@ -93,4 +97,9 @@ readline.have_func("remove_history") 17 | readline.have_func("clear_history") 18 | readline.have_func("rl_redisplay") 19 | readline.have_func("rl_insert_text") 20 | + 21 | +unless readline.have_type("rl_hook_func_t") 22 | + $defs << "-Drl_hook_func_t=Function" 23 | +end 24 | + 25 | create_makefile("readline") 26 | diff --git ext/readline/readline.c ext/readline/readline.c 27 | index 3e7feea..482bf80 100644 28 | --- ext/readline/readline.c 29 | +++ ext/readline/readline.c 30 | @@ -1883,7 +1883,7 @@ Init_readline() 31 | 32 | rl_attempted_completion_function = readline_attempted_completion_function; 33 | #if defined(HAVE_RL_PRE_INPUT_HOOK) 34 | - rl_pre_input_hook = (Function *)readline_pre_input_hook; 35 | + rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook; 36 | #endif 37 | #ifdef HAVE_RL_CATCH_SIGNALS 38 | rl_catch_signals = 0; 39 | -------------------------------------------------------------------------------- /data/patches/2.0.0-p195/01_readline.patch: -------------------------------------------------------------------------------- 1 | diff --git ext/readline/extconf.rb ext/readline/extconf.rb 2 | index 4920137..8e81253 100644 3 | --- ext/readline/extconf.rb 4 | +++ ext/readline/extconf.rb 5 | @@ -19,6 +19,10 @@ def readline.have_func(func) 6 | return super(func, headers) 7 | end 8 | 9 | +def readline.have_type(type) 10 | + return super(type, headers) 11 | +end 12 | + 13 | dir_config('curses') 14 | dir_config('ncurses') 15 | dir_config('termcap') 16 | @@ -93,4 +97,9 @@ readline.have_func("remove_history") 17 | readline.have_func("clear_history") 18 | readline.have_func("rl_redisplay") 19 | readline.have_func("rl_insert_text") 20 | + 21 | +unless readline.have_type("rl_hook_func_t") 22 | + $defs << "-Drl_hook_func_t=Function" 23 | +end 24 | + 25 | create_makefile("readline") 26 | diff --git ext/readline/readline.c ext/readline/readline.c 27 | index 3e7feea..482bf80 100644 28 | --- ext/readline/readline.c 29 | +++ ext/readline/readline.c 30 | @@ -1883,7 +1883,7 @@ Init_readline() 31 | 32 | rl_attempted_completion_function = readline_attempted_completion_function; 33 | #if defined(HAVE_RL_PRE_INPUT_HOOK) 34 | - rl_pre_input_hook = (Function *)readline_pre_input_hook; 35 | + rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook; 36 | #endif 37 | #ifdef HAVE_RL_CATCH_SIGNALS 38 | rl_catch_signals = 0; 39 | -------------------------------------------------------------------------------- /data/patches/2.0.0-p247/01_readline.patch: -------------------------------------------------------------------------------- 1 | diff --git ext/readline/extconf.rb ext/readline/extconf.rb 2 | index 4920137..8e81253 100644 3 | --- ext/readline/extconf.rb 4 | +++ ext/readline/extconf.rb 5 | @@ -19,6 +19,10 @@ def readline.have_func(func) 6 | return super(func, headers) 7 | end 8 | 9 | +def readline.have_type(type) 10 | + return super(type, headers) 11 | +end 12 | + 13 | dir_config('curses') 14 | dir_config('ncurses') 15 | dir_config('termcap') 16 | @@ -93,4 +97,9 @@ readline.have_func("remove_history") 17 | readline.have_func("clear_history") 18 | readline.have_func("rl_redisplay") 19 | readline.have_func("rl_insert_text") 20 | + 21 | +unless readline.have_type("rl_hook_func_t") 22 | + $defs << "-Drl_hook_func_t=Function" 23 | +end 24 | + 25 | create_makefile("readline") 26 | diff --git ext/readline/readline.c ext/readline/readline.c 27 | index 3e7feea..482bf80 100644 28 | --- ext/readline/readline.c 29 | +++ ext/readline/readline.c 30 | @@ -1883,7 +1883,7 @@ Init_readline() 31 | 32 | rl_attempted_completion_function = readline_attempted_completion_function; 33 | #if defined(HAVE_RL_PRE_INPUT_HOOK) 34 | - rl_pre_input_hook = (Function *)readline_pre_input_hook; 35 | + rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook; 36 | #endif 37 | #ifdef HAVE_RL_CATCH_SIGNALS 38 | rl_catch_signals = 0; 39 | -------------------------------------------------------------------------------- /data/patches/2.0.0-p353/01_readline.patch: -------------------------------------------------------------------------------- 1 | diff --git ext/readline/extconf.rb ext/readline/extconf.rb 2 | index 4920137..8e81253 100644 3 | --- ext/readline/extconf.rb 4 | +++ ext/readline/extconf.rb 5 | @@ -19,6 +19,10 @@ def readline.have_func(func) 6 | return super(func, headers) 7 | end 8 | 9 | +def readline.have_type(type) 10 | + return super(type, headers) 11 | +end 12 | + 13 | dir_config('curses') 14 | dir_config('ncurses') 15 | dir_config('termcap') 16 | @@ -93,4 +97,9 @@ readline.have_func("remove_history") 17 | readline.have_func("clear_history") 18 | readline.have_func("rl_redisplay") 19 | readline.have_func("rl_insert_text") 20 | + 21 | +unless readline.have_type("rl_hook_func_t") 22 | + $defs << "-Drl_hook_func_t=Function" 23 | +end 24 | + 25 | create_makefile("readline") 26 | diff --git ext/readline/readline.c ext/readline/readline.c 27 | index 3e7feea..482bf80 100644 28 | --- ext/readline/readline.c 29 | +++ ext/readline/readline.c 30 | @@ -1883,7 +1883,7 @@ Init_readline() 31 | 32 | rl_attempted_completion_function = readline_attempted_completion_function; 33 | #if defined(HAVE_RL_PRE_INPUT_HOOK) 34 | - rl_pre_input_hook = (Function *)readline_pre_input_hook; 35 | + rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook; 36 | #endif 37 | #ifdef HAVE_RL_CATCH_SIGNALS 38 | rl_catch_signals = 0; 39 | -------------------------------------------------------------------------------- /data/patches/2.0.0-p451/01_readline.patch: -------------------------------------------------------------------------------- 1 | diff --git ext/readline/extconf.rb ext/readline/extconf.rb 2 | index 4920137..8e81253 100644 3 | --- ext/readline/extconf.rb 4 | +++ ext/readline/extconf.rb 5 | @@ -19,6 +19,10 @@ def readline.have_func(func) 6 | return super(func, headers) 7 | end 8 | 9 | +def readline.have_type(type) 10 | + return super(type, headers) 11 | +end 12 | + 13 | dir_config('curses') 14 | dir_config('ncurses') 15 | dir_config('termcap') 16 | @@ -93,4 +97,9 @@ readline.have_func("remove_history") 17 | readline.have_func("clear_history") 18 | readline.have_func("rl_redisplay") 19 | readline.have_func("rl_insert_text") 20 | + 21 | +unless readline.have_type("rl_hook_func_t") 22 | + $defs << "-Drl_hook_func_t=Function" 23 | +end 24 | + 25 | create_makefile("readline") 26 | diff --git ext/readline/readline.c ext/readline/readline.c 27 | index 3e7feea..482bf80 100644 28 | --- ext/readline/readline.c 29 | +++ ext/readline/readline.c 30 | @@ -1883,7 +1883,7 @@ Init_readline() 31 | 32 | rl_attempted_completion_function = readline_attempted_completion_function; 33 | #if defined(HAVE_RL_PRE_INPUT_HOOK) 34 | - rl_pre_input_hook = (Function *)readline_pre_input_hook; 35 | + rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook; 36 | #endif 37 | #ifdef HAVE_RL_CATCH_SIGNALS 38 | rl_catch_signals = 0; 39 | -------------------------------------------------------------------------------- /data/patches/2.1.0/01_readline.patch: -------------------------------------------------------------------------------- 1 | Index: ext/readline/readline.c 2 | =================================================================== 3 | --- ext/readline/readline.c (revision 45224) 4 | +++ ext/readline/readline.c (revision 45225) 5 | @@ -1974,7 +1974,7 @@ 6 | 7 | rl_attempted_completion_function = readline_attempted_completion_function; 8 | #if defined(HAVE_RL_PRE_INPUT_HOOK) 9 | - rl_pre_input_hook = (Function *)readline_pre_input_hook; 10 | + rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook; 11 | #endif 12 | #ifdef HAVE_RL_CATCH_SIGNALS 13 | rl_catch_signals = 0; 14 | Index: ext/readline/extconf.rb 15 | =================================================================== 16 | --- ext/readline/extconf.rb (revision 45239) 17 | +++ ext/readline/extconf.rb (revision 45240) 18 | @@ -19,6 +19,10 @@ 19 | return super(func, headers) 20 | end 21 | 22 | +def readline.have_type(type) 23 | + return super(type, headers) 24 | +end 25 | + 26 | dir_config('curses') 27 | dir_config('ncurses') 28 | dir_config('termcap') 29 | @@ -94,4 +98,8 @@ 30 | readline.have_func("rl_redisplay") 31 | readline.have_func("rl_insert_text") 32 | readline.have_func("rl_delete_text") 33 | +unless readline.have_type("rl_hook_func_t") 34 | + $DEFS << "-Drl_hook_func_t=Function" 35 | +end 36 | + 37 | create_makefile("readline") 38 | Index: ext/readline/extconf.rb 39 | =================================================================== 40 | --- ext/readline/extconf.rb (revision 45242) 41 | +++ ext/readline/extconf.rb (revision 45243) 42 | @@ -99,6 +99,9 @@ 43 | readline.have_func("rl_insert_text") 44 | readline.have_func("rl_delete_text") 45 | unless readline.have_type("rl_hook_func_t") 46 | + # rl_hook_func_t is available since readline-4.2 (2001). 47 | + # Function is removed at readline-6.3 (2014). 48 | + # However, editline (NetBSD 6.1.3, 2014) doesn't have rl_hook_func_t. 49 | $DEFS << "-Drl_hook_func_t=Function" 50 | end -------------------------------------------------------------------------------- /data/patches/2.1.1/01_readline.patch: -------------------------------------------------------------------------------- 1 | Index: ext/readline/readline.c 2 | =================================================================== 3 | --- ext/readline/readline.c (revision 45224) 4 | +++ ext/readline/readline.c (revision 45225) 5 | @@ -1974,7 +1974,7 @@ 6 | 7 | rl_attempted_completion_function = readline_attempted_completion_function; 8 | #if defined(HAVE_RL_PRE_INPUT_HOOK) 9 | - rl_pre_input_hook = (Function *)readline_pre_input_hook; 10 | + rl_pre_input_hook = (rl_hook_func_t *)readline_pre_input_hook; 11 | #endif 12 | #ifdef HAVE_RL_CATCH_SIGNALS 13 | rl_catch_signals = 0; 14 | Index: ext/readline/extconf.rb 15 | =================================================================== 16 | --- ext/readline/extconf.rb (revision 45239) 17 | +++ ext/readline/extconf.rb (revision 45240) 18 | @@ -19,6 +19,10 @@ 19 | return super(func, headers) 20 | end 21 | 22 | +def readline.have_type(type) 23 | + return super(type, headers) 24 | +end 25 | + 26 | dir_config('curses') 27 | dir_config('ncurses') 28 | dir_config('termcap') 29 | @@ -94,4 +98,8 @@ 30 | readline.have_func("rl_redisplay") 31 | readline.have_func("rl_insert_text") 32 | readline.have_func("rl_delete_text") 33 | +unless readline.have_type("rl_hook_func_t") 34 | + $DEFS << "-Drl_hook_func_t=Function" 35 | +end 36 | + 37 | create_makefile("readline") 38 | Index: ext/readline/extconf.rb 39 | =================================================================== 40 | --- ext/readline/extconf.rb (revision 45242) 41 | +++ ext/readline/extconf.rb (revision 45243) 42 | @@ -99,6 +99,9 @@ 43 | readline.have_func("rl_insert_text") 44 | readline.have_func("rl_delete_text") 45 | unless readline.have_type("rl_hook_func_t") 46 | + # rl_hook_func_t is available since readline-4.2 (2001). 47 | + # Function is removed at readline-6.3 (2014). 48 | + # However, editline (NetBSD 6.1.3, 2014) doesn't have rl_hook_func_t. 49 | $DEFS << "-Drl_hook_func_t=Function" 50 | end --------------------------------------------------------------------------------