├── .github └── workflows │ └── rust.yml ├── .gitignore ├── COPYING ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src ├── cmdrunext.rs ├── coretoolbox.rs └── podman.rs /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v1 14 | - name: Build 15 | run: cargo build --verbose 16 | - name: Run tests 17 | run: cargo test --verbose 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "ansi_term" 5 | version = "0.11.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | dependencies = [ 8 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 9 | ] 10 | 11 | [[package]] 12 | name = "arc-swap" 13 | version = "0.4.2" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | 16 | [[package]] 17 | name = "arrayvec" 18 | version = "0.4.11" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | dependencies = [ 21 | "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 22 | ] 23 | 24 | [[package]] 25 | name = "atty" 26 | version = "0.2.13" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | dependencies = [ 29 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 30 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 31 | ] 32 | 33 | [[package]] 34 | name = "autocfg" 35 | version = "0.1.6" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | 38 | [[package]] 39 | name = "backtrace" 40 | version = "0.3.37" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | dependencies = [ 43 | "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 44 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 45 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 46 | "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 47 | ] 48 | 49 | [[package]] 50 | name = "backtrace-sys" 51 | version = "0.1.31" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | dependencies = [ 54 | "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", 55 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 56 | ] 57 | 58 | [[package]] 59 | name = "bitflags" 60 | version = "1.1.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | 63 | [[package]] 64 | name = "c2-chacha" 65 | version = "0.2.2" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | dependencies = [ 68 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 69 | "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 70 | ] 71 | 72 | [[package]] 73 | name = "cc" 74 | version = "1.0.45" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | 77 | [[package]] 78 | name = "cfg-if" 79 | version = "0.1.9" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | 82 | [[package]] 83 | name = "clap" 84 | version = "2.33.0" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | dependencies = [ 87 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 88 | "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 89 | "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 90 | "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 91 | "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 92 | "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 93 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 94 | ] 95 | 96 | [[package]] 97 | name = "cloudabi" 98 | version = "0.0.3" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | dependencies = [ 101 | "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 102 | ] 103 | 104 | [[package]] 105 | name = "coretoolbox" 106 | version = "0.1.0" 107 | dependencies = [ 108 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", 109 | "directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 110 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 111 | "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 112 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 113 | "nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", 114 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 115 | "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 116 | "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", 117 | "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", 118 | "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", 119 | "signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 120 | "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", 121 | "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 122 | "varlink 8.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 123 | ] 124 | 125 | [[package]] 126 | name = "crossbeam-deque" 127 | version = "0.7.1" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | dependencies = [ 130 | "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 131 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 132 | ] 133 | 134 | [[package]] 135 | name = "crossbeam-epoch" 136 | version = "0.7.2" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | dependencies = [ 139 | "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 140 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 141 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 142 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 143 | "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 144 | "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 145 | ] 146 | 147 | [[package]] 148 | name = "crossbeam-queue" 149 | version = "0.1.2" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | dependencies = [ 152 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 153 | ] 154 | 155 | [[package]] 156 | name = "crossbeam-utils" 157 | version = "0.6.6" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | dependencies = [ 160 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 161 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 162 | ] 163 | 164 | [[package]] 165 | name = "directories" 166 | version = "1.0.2" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | dependencies = [ 169 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 170 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 171 | ] 172 | 173 | [[package]] 174 | name = "either" 175 | version = "1.5.2" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | 178 | [[package]] 179 | name = "failure" 180 | version = "0.1.5" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | dependencies = [ 183 | "backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)", 184 | "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 185 | ] 186 | 187 | [[package]] 188 | name = "failure_derive" 189 | version = "0.1.5" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | dependencies = [ 192 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 193 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 194 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 195 | "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", 196 | ] 197 | 198 | [[package]] 199 | name = "fs2" 200 | version = "0.4.3" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | dependencies = [ 203 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 204 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 205 | ] 206 | 207 | [[package]] 208 | name = "fuchsia-cprng" 209 | version = "0.1.1" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | 212 | [[package]] 213 | name = "getrandom" 214 | version = "0.1.12" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | dependencies = [ 217 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 218 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 219 | "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 220 | ] 221 | 222 | [[package]] 223 | name = "heck" 224 | version = "0.3.1" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | dependencies = [ 227 | "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 228 | ] 229 | 230 | [[package]] 231 | name = "itoa" 232 | version = "0.4.4" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | 235 | [[package]] 236 | name = "kernel32-sys" 237 | version = "0.2.2" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | dependencies = [ 240 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 241 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 242 | ] 243 | 244 | [[package]] 245 | name = "lazy_static" 246 | version = "1.4.0" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | 249 | [[package]] 250 | name = "libc" 251 | version = "0.2.62" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | 254 | [[package]] 255 | name = "memoffset" 256 | version = "0.5.1" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | dependencies = [ 259 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 260 | ] 261 | 262 | [[package]] 263 | name = "nix" 264 | version = "0.13.1" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | dependencies = [ 267 | "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 268 | "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", 269 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 270 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 271 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 272 | ] 273 | 274 | [[package]] 275 | name = "nodrop" 276 | version = "0.1.13" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | 279 | [[package]] 280 | name = "num_cpus" 281 | version = "1.10.1" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | dependencies = [ 284 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 285 | ] 286 | 287 | [[package]] 288 | name = "ppv-lite86" 289 | version = "0.2.5" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | 292 | [[package]] 293 | name = "proc-macro2" 294 | version = "0.4.30" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | dependencies = [ 297 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 298 | ] 299 | 300 | [[package]] 301 | name = "proc-macro2" 302 | version = "1.0.3" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | dependencies = [ 305 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 306 | ] 307 | 308 | [[package]] 309 | name = "quote" 310 | version = "0.6.13" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | dependencies = [ 313 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 314 | ] 315 | 316 | [[package]] 317 | name = "quote" 318 | version = "1.0.2" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | dependencies = [ 321 | "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 322 | ] 323 | 324 | [[package]] 325 | name = "rand" 326 | version = "0.4.6" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | dependencies = [ 329 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 330 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 331 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 332 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 333 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 334 | ] 335 | 336 | [[package]] 337 | name = "rand" 338 | version = "0.6.5" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | dependencies = [ 341 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 342 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 343 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 344 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 345 | "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 346 | "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 347 | "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 348 | "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 349 | "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 350 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 351 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 352 | ] 353 | 354 | [[package]] 355 | name = "rand" 356 | version = "0.7.0" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | dependencies = [ 359 | "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 360 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 361 | "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 362 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 363 | "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 364 | ] 365 | 366 | [[package]] 367 | name = "rand_chacha" 368 | version = "0.1.1" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | dependencies = [ 371 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 373 | ] 374 | 375 | [[package]] 376 | name = "rand_chacha" 377 | version = "0.2.1" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | dependencies = [ 380 | "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 381 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 382 | ] 383 | 384 | [[package]] 385 | name = "rand_core" 386 | version = "0.3.1" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | dependencies = [ 389 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 390 | ] 391 | 392 | [[package]] 393 | name = "rand_core" 394 | version = "0.4.2" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | 397 | [[package]] 398 | name = "rand_core" 399 | version = "0.5.1" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | dependencies = [ 402 | "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 403 | ] 404 | 405 | [[package]] 406 | name = "rand_hc" 407 | version = "0.1.0" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | dependencies = [ 410 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 411 | ] 412 | 413 | [[package]] 414 | name = "rand_hc" 415 | version = "0.2.0" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | dependencies = [ 418 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 419 | ] 420 | 421 | [[package]] 422 | name = "rand_isaac" 423 | version = "0.1.1" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | dependencies = [ 426 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 427 | ] 428 | 429 | [[package]] 430 | name = "rand_jitter" 431 | version = "0.1.4" 432 | source = "registry+https://github.com/rust-lang/crates.io-index" 433 | dependencies = [ 434 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 435 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 436 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 437 | ] 438 | 439 | [[package]] 440 | name = "rand_os" 441 | version = "0.1.3" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | dependencies = [ 444 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 445 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 446 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 447 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 448 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 449 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 450 | ] 451 | 452 | [[package]] 453 | name = "rand_pcg" 454 | version = "0.1.2" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | dependencies = [ 457 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 458 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 459 | ] 460 | 461 | [[package]] 462 | name = "rand_xorshift" 463 | version = "0.1.1" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | dependencies = [ 466 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 467 | ] 468 | 469 | [[package]] 470 | name = "rayon" 471 | version = "1.2.0" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | dependencies = [ 474 | "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 475 | "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 476 | "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 477 | ] 478 | 479 | [[package]] 480 | name = "rayon-core" 481 | version = "1.6.0" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | dependencies = [ 484 | "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 485 | "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 486 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 487 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 488 | "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 489 | ] 490 | 491 | [[package]] 492 | name = "rdrand" 493 | version = "0.4.0" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | dependencies = [ 496 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 497 | ] 498 | 499 | [[package]] 500 | name = "redox_syscall" 501 | version = "0.1.56" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | 504 | [[package]] 505 | name = "remove_dir_all" 506 | version = "0.5.2" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | dependencies = [ 509 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 510 | ] 511 | 512 | [[package]] 513 | name = "rustc-demangle" 514 | version = "0.1.16" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | 517 | [[package]] 518 | name = "rustc_version" 519 | version = "0.2.3" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | dependencies = [ 522 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 523 | ] 524 | 525 | [[package]] 526 | name = "ryu" 527 | version = "1.0.0" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | 530 | [[package]] 531 | name = "scopeguard" 532 | version = "1.0.0" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | 535 | [[package]] 536 | name = "semver" 537 | version = "0.9.0" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | dependencies = [ 540 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 541 | ] 542 | 543 | [[package]] 544 | name = "semver-parser" 545 | version = "0.7.0" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | 548 | [[package]] 549 | name = "serde" 550 | version = "1.0.100" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | dependencies = [ 553 | "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", 554 | ] 555 | 556 | [[package]] 557 | name = "serde_derive" 558 | version = "1.0.100" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | dependencies = [ 561 | "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 562 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 563 | "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 564 | ] 565 | 566 | [[package]] 567 | name = "serde_json" 568 | version = "1.0.40" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | dependencies = [ 571 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 572 | "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 573 | "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", 574 | ] 575 | 576 | [[package]] 577 | name = "signal-hook" 578 | version = "0.1.10" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | dependencies = [ 581 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 582 | "signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 583 | ] 584 | 585 | [[package]] 586 | name = "signal-hook-registry" 587 | version = "1.1.1" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | dependencies = [ 590 | "arc-swap 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 591 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 592 | ] 593 | 594 | [[package]] 595 | name = "strsim" 596 | version = "0.8.0" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | 599 | [[package]] 600 | name = "structopt" 601 | version = "0.2.18" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | dependencies = [ 604 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", 605 | "structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", 606 | ] 607 | 608 | [[package]] 609 | name = "structopt-derive" 610 | version = "0.2.18" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | dependencies = [ 613 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 614 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 615 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 616 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 617 | ] 618 | 619 | [[package]] 620 | name = "syn" 621 | version = "0.15.44" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | dependencies = [ 624 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 625 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 626 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 627 | ] 628 | 629 | [[package]] 630 | name = "syn" 631 | version = "1.0.5" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | dependencies = [ 634 | "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 635 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 636 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 637 | ] 638 | 639 | [[package]] 640 | name = "synstructure" 641 | version = "0.10.2" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | dependencies = [ 644 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 645 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 646 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 647 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 648 | ] 649 | 650 | [[package]] 651 | name = "tempdir" 652 | version = "0.3.7" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | dependencies = [ 655 | "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 656 | "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 657 | ] 658 | 659 | [[package]] 660 | name = "tempfile" 661 | version = "3.1.0" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | dependencies = [ 664 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 665 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 666 | "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 667 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 668 | "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 669 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 670 | ] 671 | 672 | [[package]] 673 | name = "textwrap" 674 | version = "0.11.0" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | dependencies = [ 677 | "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 678 | ] 679 | 680 | [[package]] 681 | name = "uds_windows" 682 | version = "0.1.4" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | dependencies = [ 685 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 686 | "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 687 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 688 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 689 | ] 690 | 691 | [[package]] 692 | name = "unicode-segmentation" 693 | version = "1.3.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | 696 | [[package]] 697 | name = "unicode-width" 698 | version = "0.1.6" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | 701 | [[package]] 702 | name = "unicode-xid" 703 | version = "0.1.0" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | 706 | [[package]] 707 | name = "unicode-xid" 708 | version = "0.2.0" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | 711 | [[package]] 712 | name = "unix_socket" 713 | version = "0.5.0" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | dependencies = [ 716 | "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 717 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 718 | ] 719 | 720 | [[package]] 721 | name = "varlink" 722 | version = "8.1.0" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | dependencies = [ 725 | "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", 726 | "serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", 727 | "serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)", 728 | "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", 729 | "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 730 | "uds_windows 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 731 | "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 732 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 733 | ] 734 | 735 | [[package]] 736 | name = "vec_map" 737 | version = "0.8.1" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | 740 | [[package]] 741 | name = "void" 742 | version = "1.0.2" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | 745 | [[package]] 746 | name = "wasi" 747 | version = "0.7.0" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | 750 | [[package]] 751 | name = "winapi" 752 | version = "0.2.8" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | 755 | [[package]] 756 | name = "winapi" 757 | version = "0.3.8" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | dependencies = [ 760 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 761 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 762 | ] 763 | 764 | [[package]] 765 | name = "winapi-build" 766 | version = "0.1.1" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | 769 | [[package]] 770 | name = "winapi-i686-pc-windows-gnu" 771 | version = "0.4.0" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | 774 | [[package]] 775 | name = "winapi-x86_64-pc-windows-gnu" 776 | version = "0.4.0" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | 779 | [[package]] 780 | name = "ws2_32-sys" 781 | version = "0.2.1" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | dependencies = [ 784 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 785 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 786 | ] 787 | 788 | [metadata] 789 | "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 790 | "checksum arc-swap 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "854ede29f7a0ce90519fb2439d030320c6201119b87dab0ee96044603e1130b9" 791 | "checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" 792 | "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" 793 | "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" 794 | "checksum backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2" 795 | "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" 796 | "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" 797 | "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" 798 | "checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" 799 | "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" 800 | "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" 801 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 802 | "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" 803 | "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" 804 | "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" 805 | "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" 806 | "checksum directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72d337a64190607d4fcca2cb78982c5dd57f4916e19696b48a575fa746b6cb0f" 807 | "checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" 808 | "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" 809 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" 810 | "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" 811 | "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 812 | "checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" 813 | "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 814 | "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" 815 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 816 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 817 | "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" 818 | "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" 819 | "checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b" 820 | "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" 821 | "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" 822 | "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" 823 | "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 824 | "checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8" 825 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 826 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 827 | "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 828 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 829 | "checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" 830 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 831 | "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" 832 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 833 | "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 834 | "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 835 | "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 836 | "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 837 | "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 838 | "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 839 | "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 840 | "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 841 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 842 | "checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" 843 | "checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" 844 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 845 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 846 | "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 847 | "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 848 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 849 | "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" 850 | "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" 851 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 852 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 853 | "checksum serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "f4473e8506b213730ff2061073b48fa51dcc66349219e2e7c5608f0296a1d95a" 854 | "checksum serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "11e410fde43e157d789fc290d26bc940778ad0fdd47836426fbac36573710dbb" 855 | "checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" 856 | "checksum signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4f61c4d59f3aaa9f61bba6450a9b80ba48362fd7d651689e7a10c453b1f6dc68" 857 | "checksum signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1797d48f38f91643908bb14e35e79928f9f4b3cefb2420a564dde0991b4358dc" 858 | "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 859 | "checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" 860 | "checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" 861 | "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 862 | "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" 863 | "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" 864 | "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" 865 | "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 866 | "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 867 | "checksum uds_windows 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf61006548cd6cf63fcc45d6cee370859692c2dcf7f15e8fc6e73da9ce36e5a3" 868 | "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" 869 | "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" 870 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 871 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 872 | "checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" 873 | "checksum varlink 8.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50961469dd0df40c00640ec7a552b48fae0813dd1430cefae11d1fbb87a1f40a" 874 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" 875 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 876 | "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" 877 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 878 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 879 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 880 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 881 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 882 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 883 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "coretoolbox" 3 | version = "0.1.0" 4 | authors = ["Colin Walters "] 5 | edition = "2018" 6 | license = "MIT/Apache-2.0" 7 | keywords = ["podman", "containers", "toolbox"] 8 | homepage = "https://github.com/cgwalters/coretoolbox" 9 | 10 | [dependencies] 11 | nix = "0.13" 12 | fs2 = "0.4.3" 13 | rand = "0.6.5" 14 | rayon = "1.0.3" 15 | clap = "2.32.0" 16 | structopt = "0.2" 17 | directories = "1.0" 18 | failure = "0.1.1" 19 | lazy_static = "1.2.0" 20 | tempfile = "3.0.7" 21 | serde = { version = "1.0.78", features = ["derive"] } 22 | serde_derive = "1.0.78" 23 | serde_json = "1.0" 24 | signal-hook = "0.1.9" 25 | varlink = "8.1.0" 26 | 27 | [[bin]] 28 | name = "coretoolbox" 29 | path = "src/coretoolbox.rs" 30 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The openat Developers 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | coreos-toolbox 2 | === 3 | 4 | This is a new implementation of https://github.com/debarshiray/toolbox/ 5 | 6 | Installation 7 | --- 8 | 9 | Be sure you have [cargo installed](https://doc.rust-lang.org/cargo/getting-started/installation.html). 10 | 11 | Then: 12 | `cargo install --git https://github.com/cgwalters/coretoolbox` 13 | 14 | In the future we may invest in packaging this for different distributions, or 15 | see about shipping it with e.g. podman by default. 16 | 17 | Getting started 18 | --- 19 | 20 | One time setup 21 | 22 | ``` 23 | $ coretoolbox create 24 | 25 | $ 26 | ``` 27 | 28 | Now, each time you want to enter the toolbox: 29 | 30 | ``` 31 | $ coretoolbox run 32 | ``` 33 | 34 | One suggestion is to add a "profile" or configuration to your terminal 35 | emulator that runs `coretoolbox run` by default, so that you can 36 | easily create new tabs/windows in the toolbox. 37 | 38 | Rationale 39 | --- 40 | 41 | In order to disambiguate in this text we'll call this tool 42 | "ctb", and the other one "dtb". 43 | 44 | The main reason to introduce a new tool is that dtb too strongly 45 | encourages true "pet" containers, where significant state is stored 46 | inside. We want to make it easy for people to build their own 47 | toolbox "base images" derived from the upstream image. For example, 48 | rather than doing `yum install cargo` inside a toolbox container, 49 | you use a `Dockerfile` that does: 50 | 51 | ``` 52 | FROM registry.fedoraproject.org/f30/fedora-toolbox:30 53 | RUN yum -y install cargo 54 | ``` 55 | 56 | The `toolbox` command should ideally have at least a basic 57 | concept of a "build" that regenerates the base container, but 58 | at a minimum should support more easily specifying that base image. 59 | 60 | A related problem with dtb is that it actually does create 61 | a derived image locally with e.g. the username added; this 62 | forces the image to be specific to one user or machine. 63 | 64 | What "ctb" does instead is inject dynamic state (username, `HOME` path) 65 | into the container at runtime. This allows a lot more flexibility. 66 | 67 | Today "dtb" has a hardcoded list of bind mounts for e.g. `HOME` 68 | and the DBus system bus socket. 69 | I ran into a case where I wanted e.g. the system libvirt socket. 70 | 71 | In general, we aren't trying to confine `toolbox` - it's a privileged 72 | container. So "ctb" takes the approach of mounting in most 73 | things from the host into the `/host` directory, and then uses 74 | symlinks into `/host`. This again makes everything a lot more 75 | flexible as the set of things exposed can easily be changed 76 | while the container is running. 77 | 78 | Finally, ctb is written in a real programming language; bash 79 | gets problematic once one goes beyond 10-20 lines 80 | of code. 81 | 82 | License 83 | --- 84 | 85 | Licensed under either of 86 | 87 | * Apache License, Version 2.0, 88 | (./LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) 89 | * MIT license (./LICENSE-MIT or http://opensource.org/licenses/MIT) 90 | at your option. 91 | -------------------------------------------------------------------------------- /src/cmdrunext.rs: -------------------------------------------------------------------------------- 1 | use failure::{bail, Fallible}; 2 | use std::process::Command; 3 | 4 | pub(crate) trait CommandRunExt { 5 | fn run(&mut self) -> Fallible<()>; 6 | } 7 | 8 | impl CommandRunExt for Command { 9 | fn run(&mut self) -> Fallible<()> { 10 | let r = self.status()?; 11 | if !r.success() { 12 | bail!("Child [{:?}] exited: {}", self, r); 13 | } 14 | Ok(()) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/coretoolbox.rs: -------------------------------------------------------------------------------- 1 | use directories; 2 | use failure::{bail, Fallible, ResultExt}; 3 | use lazy_static::lazy_static; 4 | use serde::{Deserialize, Serialize}; 5 | use serde_json; 6 | use std::io::prelude::*; 7 | use std::os::unix::process::CommandExt; 8 | use std::path::Path; 9 | use std::process::{Command, Stdio}; 10 | use structopt::StructOpt; 11 | 12 | mod cmdrunext; 13 | mod podman; 14 | use cmdrunext::CommandRunExt; 15 | 16 | static DEFAULT_IMAGE: &str = "registry.fedoraproject.org/f30/fedora-toolbox:30"; 17 | /// The label set on toolbox images and containers. 18 | static TOOLBOX_LABEL: &str = "com.coreos.toolbox"; 19 | /// The label set on github.com/debarshiray/fedora-toolbox images and containers. 20 | static D_TOOLBOX_LABEL: &str = "com.github.debarshiray.toolbox"; 21 | /// The default container name 22 | static DEFAULT_NAME: &str = "coreos-toolbox"; 23 | /// The path to our binary inside the container 24 | static USR_BIN_SELF: &str = "/usr/bin/coretoolbox"; 25 | static STATE_ENV: &str = "TOOLBOX_STATE"; 26 | 27 | lazy_static! { 28 | static ref APPDIRS: directories::ProjectDirs = 29 | directories::ProjectDirs::from("com", "coreos", "toolbox").expect("creating appdirs"); 30 | } 31 | 32 | static MAX_UID_COUNT: u32 = 65536; 33 | 34 | /// Set of statically known paths to files/directories 35 | /// that we redirect inside the container to /host. 36 | static STATIC_HOST_FORWARDS: &[&str] = &["/run/dbus", "/run/libvirt", "/tmp", "/var/tmp"]; 37 | /// Set of devices we forward (if they exist) 38 | static FORWARDED_DEVICES: &[&str] = &["bus", "dri", "kvm", "fuse"]; 39 | 40 | static PRESERVED_ENV: &[&str] = &[ 41 | "COLORTERM", 42 | "DBUS_SESSION_BUS_ADDRESS", 43 | "DESKTOP_SESSION", 44 | "DISPLAY", 45 | "USER", 46 | "LANG", 47 | "SSH_AUTH_SOCK", 48 | "TERM", 49 | "VTE_VERSION", 50 | "XDG_CURRENT_DESKTOP", 51 | "XDG_DATA_DIRS", 52 | "XDG_MENU_PREFIX", 53 | "XDG_RUNTIME_DIR", 54 | "XDG_SEAT", 55 | "XDG_SESSION_DESKTOP", 56 | "XDG_SESSION_ID", 57 | "XDG_SESSION_TYPE", 58 | "XDG_VTNR", 59 | "WAYLAND_DISPLAY", 60 | ]; 61 | 62 | #[derive(Debug, StructOpt)] 63 | struct CreateOpts { 64 | #[structopt(short = "I", long = "image")] 65 | /// Use a different base image 66 | image: Option, 67 | 68 | #[structopt(short = "n", long = "name")] 69 | /// Name the container 70 | name: Option, 71 | 72 | #[structopt(short = "N", long = "nested")] 73 | /// Allow running inside a container 74 | nested: bool, 75 | 76 | #[structopt(short = "D", long = "destroy")] 77 | /// Destroy any existing container 78 | destroy: bool, 79 | } 80 | 81 | #[derive(Debug, StructOpt)] 82 | #[structopt(rename_all = "kebab-case")] 83 | struct RunOpts { 84 | #[structopt(short = "n", long = "name")] 85 | /// Name of container 86 | name: Option, 87 | 88 | #[structopt(short = "N", long = "nested")] 89 | /// Allow running inside a container 90 | nested: bool, 91 | 92 | #[structopt(long)] 93 | /// Run as (user namespace) root, do not change to unprivileged uid 94 | as_userns_root: bool, 95 | } 96 | 97 | #[derive(Debug, StructOpt)] 98 | struct RmOpts { 99 | #[structopt(short = "n", long = "name", default_value = "coreos-toolbox")] 100 | /// Name for container 101 | name: String, 102 | } 103 | 104 | #[derive(Debug, StructOpt)] 105 | #[structopt(name = "coretoolbox", about = "Toolbox")] 106 | #[structopt(rename_all = "kebab-case")] 107 | enum Opt { 108 | /// Create a toolbox 109 | Create(CreateOpts), 110 | /// Enter the toolbox 111 | Run(RunOpts), 112 | /// Delete the toolbox container 113 | Rm(RmOpts), 114 | /// Display names of already downloaded images with toolbox labels 115 | ListToolboxImages, 116 | } 117 | 118 | #[derive(Debug, StructOpt)] 119 | #[structopt(rename_all = "kebab-case")] 120 | struct ExecOpts { 121 | #[structopt(long)] 122 | /// See run --as-userns-root 123 | as_userns_root: bool, 124 | } 125 | 126 | #[derive(Debug, StructOpt)] 127 | #[structopt(rename_all = "kebab-case")] 128 | enum InternalOpt { 129 | /// Internal implementation detail; do not use 130 | RunPid1, 131 | /// Internal implementation detail; do not use 132 | Exec(ExecOpts), 133 | } 134 | 135 | fn get_toolbox_images() -> Fallible> { 136 | let label = format!("label={}=true", TOOLBOX_LABEL); 137 | let mut ret = podman::image_inspect(&["--filter", label.as_str()]).with_context(|e| { 138 | format!( 139 | r#"Finding containers with label "{}": {}"#, 140 | TOOLBOX_LABEL, e 141 | ) 142 | })?; 143 | let dlabel = format!("label={}=true", D_TOOLBOX_LABEL); 144 | ret.extend( 145 | podman::image_inspect(&["--filter", dlabel.as_str()]).with_context(|e| { 146 | format!( 147 | r#"Finding containers with label "{}": {}"#, 148 | D_TOOLBOX_LABEL, e 149 | ) 150 | })?, 151 | ); 152 | Ok(ret.drain(..).filter(|p| p.names.is_some()).collect()) 153 | } 154 | 155 | /// Pull a container image if not present 156 | fn ensure_image(name: &str) -> Fallible<()> { 157 | if !podman::has_object(podman::InspectType::Image, name)? { 158 | podman::cmd().args(&["pull", name]).run()?; 159 | } 160 | Ok(()) 161 | } 162 | 163 | /// Parse an extant environment variable as UTF-8 164 | fn getenv_required_utf8(n: &str) -> Fallible { 165 | if let Some(v) = std::env::var_os(n) { 166 | Ok(v.to_str() 167 | .ok_or_else(|| failure::format_err!("{} is invalid UTF-8", n))? 168 | .to_string()) 169 | } else { 170 | bail!("{} is unset", n) 171 | } 172 | } 173 | 174 | #[derive(Serialize, Deserialize, Debug)] 175 | struct EntrypointState { 176 | username: String, 177 | uid: u32, 178 | home: String, 179 | } 180 | 181 | fn append_preserved_env(c: &mut Command) -> Fallible<()> { 182 | for n in PRESERVED_ENV.iter() { 183 | let v = match std::env::var_os(n) { 184 | Some(v) => v, 185 | None => continue, 186 | }; 187 | let v = v 188 | .to_str() 189 | .ok_or_else(|| failure::format_err!("{} contains invalid UTF-8", n))?; 190 | c.arg(format!("--env={}={}", n, v)); 191 | } 192 | Ok(()) 193 | } 194 | 195 | fn get_default_image() -> Fallible { 196 | let toolboxes = get_toolbox_images()?; 197 | Ok(match toolboxes.len() { 198 | 0 => { 199 | print!( 200 | "Welcome to coretoolbox 201 | Enter a pull spec for toolbox image; default: {defimg} 202 | Image: ", 203 | defimg = DEFAULT_IMAGE 204 | ); 205 | std::io::stdout().flush()?; 206 | let mut input = String::new(); 207 | std::io::stdin().read_line(&mut input)?; 208 | input.truncate(input.trim_end().len()); 209 | if input.is_empty() { 210 | DEFAULT_IMAGE.to_owned() 211 | } else { 212 | input 213 | } 214 | } 215 | 1 => toolboxes[0].names.as_ref().unwrap()[0].clone(), 216 | _ => bail!("Multiple toolbox images found, must specify via -I"), 217 | }) 218 | } 219 | 220 | /// Return the user's runtime directory, and create it if it doesn't exist. 221 | /// The latter behavior is mostly necessary for running `sudo`. 222 | fn get_ensure_runtime_dir() -> Fallible { 223 | let real_uid: u32 = nix::unistd::getuid().into(); 224 | let runtime_dir_val = std::env::var_os("XDG_RUNTIME_DIR"); 225 | Ok(match runtime_dir_val.as_ref() { 226 | Some(d) => d 227 | .to_str() 228 | .ok_or_else(|| failure::format_err!("XDG_RUNTIME_DIR is invalid UTF-8"))? 229 | .to_string(), 230 | None => format!("/run/user/{}", real_uid), 231 | }) 232 | } 233 | 234 | fn create(opts: &CreateOpts) -> Fallible<()> { 235 | if in_container() && !opts.nested { 236 | bail!("Already inside a container"); 237 | } 238 | 239 | let image = if opts.image.is_none() 240 | && opts.name.is_none() 241 | && !podman::has_object(podman::InspectType::Container, DEFAULT_NAME)? 242 | { 243 | get_default_image()? 244 | } else { 245 | opts.image 246 | .as_ref() 247 | .map(|s| s.as_str()) 248 | .unwrap_or(DEFAULT_IMAGE) 249 | .to_owned() 250 | }; 251 | 252 | let name = opts 253 | .name 254 | .as_ref() 255 | .map(|s| s.as_str()) 256 | .unwrap_or(DEFAULT_NAME); 257 | 258 | if opts.destroy { 259 | rm(&RmOpts { 260 | name: name.to_owned(), 261 | })?; 262 | } 263 | 264 | ensure_image(&image)?; 265 | 266 | // exec ourself as the entrypoint. In the future this 267 | // would be better with podman fd passing. 268 | let self_bin = std::fs::read_link("/proc/self/exe")?; 269 | let self_bin = self_bin 270 | .as_path() 271 | .to_str() 272 | .ok_or_else(|| failure::err_msg("non-UTF8 self"))?; 273 | 274 | let real_uid: u32 = nix::unistd::getuid().into(); 275 | let privileged = real_uid == 0; 276 | 277 | let runtime_dir = get_ensure_runtime_dir()?; 278 | std::fs::create_dir_all(&runtime_dir)?; 279 | 280 | let mut podman = podman::cmd(); 281 | // The basic arguments. 282 | podman.args(&[ 283 | "create", 284 | "--interactive", 285 | "--tty", 286 | "--hostname=toolbox", 287 | "--network=host", 288 | // We are not aiming for security isolation here; besides these, the 289 | // user's home directory is mounted in, so anything that wants to "escape" 290 | // can just mutate ~/.bashrc for example. 291 | "--ipc=host", 292 | "--privileged", 293 | "--security-opt=label=disable", 294 | "--tmpfs=/run:rw", 295 | ]); 296 | podman.arg(format!("--label={}=true", TOOLBOX_LABEL)); 297 | podman.arg(format!("--name={}", name)); 298 | // In privileged mode we assume we want to control all host processes by default; 299 | // we're more about debugging/management and less of a "dev container". 300 | if privileged { 301 | podman.arg("--pid=host"); 302 | } 303 | // We bind ourself in so we can handle recursive invocation. 304 | podman.arg(format!("--volume={}:{}:ro", self_bin, USR_BIN_SELF)); 305 | 306 | // In true privileged mode we don't use userns 307 | if !privileged { 308 | let uid_plus_one = real_uid + 1; 309 | let max_minus_uid = MAX_UID_COUNT - real_uid; 310 | podman.args(&[ 311 | format!("--uidmap={}:0:1", real_uid), 312 | format!("--uidmap=0:1:{}", real_uid), 313 | format!( 314 | "--uidmap={}:{}:{}", 315 | uid_plus_one, uid_plus_one, max_minus_uid 316 | ), 317 | ]); 318 | } 319 | 320 | // Bind in the whole host rootfs 321 | podman.arg("--volume=/:/host:rslave"); 322 | append_preserved_env(&mut podman)?; 323 | 324 | podman.arg(&image); 325 | podman.args(&[USR_BIN_SELF, "internals", "run-pid1"]); 326 | podman.stdout(Stdio::null()); 327 | podman.run()?; 328 | Ok(()) 329 | } 330 | 331 | fn in_container() -> bool { 332 | Path::new("/run/.containerenv").exists() 333 | } 334 | 335 | fn run(opts: &RunOpts) -> Fallible<()> { 336 | if in_container() && !opts.nested { 337 | bail!("Already inside a container"); 338 | } 339 | 340 | let name = opts 341 | .name 342 | .as_ref() 343 | .map(|s| s.as_str()) 344 | .unwrap_or(DEFAULT_NAME); 345 | 346 | if !podman::has_object(podman::InspectType::Container, &name)? { 347 | let toolboxes = get_toolbox_images()?; 348 | if toolboxes.len() == 0 { 349 | bail!("No toolbox container or images found; use `create` to create one") 350 | } else { 351 | bail!("No toolbox container '{}' found", name) 352 | } 353 | } 354 | 355 | podman::cmd() 356 | .args(&["start", name]) 357 | .stdout(Stdio::null()) 358 | .run()?; 359 | 360 | let mut podman = podman::cmd(); 361 | podman.args(&["exec", "--interactive", "--tty"]); 362 | append_preserved_env(&mut podman)?; 363 | let state = EntrypointState { 364 | username: getenv_required_utf8("USER")?, 365 | uid: nix::unistd::getuid().into(), 366 | home: getenv_required_utf8("HOME")?, 367 | }; 368 | let state = serde_json::to_string(&state)?; 369 | podman.arg(format!("--env={}={}", STATE_ENV, state.as_str())); 370 | podman.args(&[name, USR_BIN_SELF, "internals", "exec"]); 371 | if opts.as_userns_root { 372 | podman.arg("--as-userns-root"); 373 | } 374 | return Err(podman.exec().into()); 375 | } 376 | 377 | fn rm(opts: &RmOpts) -> Fallible<()> { 378 | if !podman::has_object(podman::InspectType::Container, opts.name.as_str())? { 379 | return Ok(()); 380 | } 381 | let mut podman = podman::cmd(); 382 | podman 383 | .args(&["rm", "-f", opts.name.as_str()]) 384 | .stdout(Stdio::null()); 385 | Err(podman.exec().into()) 386 | } 387 | 388 | fn list_toolbox_images() -> Fallible<()> { 389 | let toolboxes = get_toolbox_images()?; 390 | if toolboxes.is_empty() { 391 | println!("No toolbox images found.") 392 | } else { 393 | for i in toolboxes { 394 | println!("{}", i.names.unwrap()[0]); 395 | } 396 | } 397 | Ok(()) 398 | } 399 | 400 | mod entrypoint { 401 | use super::CommandRunExt; 402 | use super::{EntrypointState, ExecOpts}; 403 | use failure::{bail, Fallible, ResultExt}; 404 | use fs2::FileExt; 405 | use rayon::prelude::*; 406 | use std::fs::File; 407 | use std::io::prelude::*; 408 | use std::os::unix; 409 | use std::os::unix::process::CommandExt; 410 | use std::path::Path; 411 | use std::process::Command; 412 | 413 | static CONTAINER_INITIALIZED_LOCK: &str = "/run/coreos-toolbox.lock"; 414 | /// This file is created when we've generated a "container image" (overlayfs layer) 415 | /// that has things like our modifications to /etc/passwd, and the root `/`. 416 | static CONTAINER_INITIALIZED_STAMP: &str = "/etc/coreos-toolbox.initialized"; 417 | /// This file is created when we've completed *runtime* state configuration 418 | /// changes such as bind mounts. 419 | static CONTAINER_INITIALIZED_RUNTIME_STAMP: &str = "/run/coreos-toolbox.initialized"; 420 | 421 | /// Set of directories we explicitly make bind mounts rather than symlinks to /host. 422 | /// To ensure that paths are the same inside and out. 423 | static DATADIRS: &[&str] = &["/srv", "/mnt", "/home"]; 424 | 425 | fn rbind, D: AsRef>(src: S, dest: D) -> Fallible<()> { 426 | let src = src.as_ref(); 427 | let dest = dest.as_ref(); 428 | let mut c = Command::new("mount"); 429 | c.arg("--rbind"); 430 | c.arg(src); 431 | c.arg(dest); 432 | c.run()?; 433 | Ok(()) 434 | } 435 | 436 | /// Update /etc/passwd with the same user from the host, 437 | /// and bind mount the homedir. 438 | fn adduser(state: &EntrypointState, with_sudo: bool) -> Fallible<()> { 439 | if state.uid == 0 { 440 | return Ok(()); 441 | } 442 | let uidstr = format!("{}", state.uid); 443 | let mut cmd = Command::new("useradd"); 444 | cmd.args(&[ 445 | "--no-create-home", 446 | "--home-dir", 447 | &state.home, 448 | "--uid", 449 | &uidstr, 450 | ]); 451 | if with_sudo { 452 | cmd.args(&["--groups", "wheel"]); 453 | } 454 | cmd.arg(state.username.as_str()); 455 | cmd.run()?; 456 | 457 | // Bind mount the homedir rather than use symlinks 458 | // as various software is unhappy if the path isn't canonical. 459 | std::fs::create_dir_all(&state.home)?; 460 | let uid = nix::unistd::Uid::from_raw(state.uid); 461 | let gid = nix::unistd::Gid::from_raw(state.uid); 462 | nix::unistd::chown(state.home.as_str(), Some(uid), Some(gid))?; 463 | let host_home = format!("/host{}", state.home); 464 | rbind(host_home.as_str(), state.home.as_str())?; 465 | Ok(()) 466 | } 467 | 468 | /// Symlink a path e.g. /run/dbus/system_bus_socket to the 469 | /// /host equivalent, creating any necessary parent directories. 470 | fn host_symlink + std::fmt::Display>(p: P) -> Fallible<()> { 471 | let path = p.as_ref(); 472 | std::fs::create_dir_all(path.parent().unwrap())?; 473 | match std::fs::remove_dir_all(path) { 474 | Ok(_) => Ok(()), 475 | Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), 476 | Err(e) => Err(e), 477 | }?; 478 | unix::fs::symlink(format!("/host{}", p), path)?; 479 | Ok(()) 480 | } 481 | 482 | fn init_container_static() -> Fallible { 483 | let initstamp = Path::new(CONTAINER_INITIALIZED_STAMP); 484 | 485 | let lockf = std::fs::OpenOptions::new() 486 | .read(true) 487 | .write(true) 488 | .create(true) 489 | .open(CONTAINER_INITIALIZED_LOCK)?; 490 | lockf.lock_exclusive()?; 491 | 492 | let state: EntrypointState = 493 | serde_json::from_str(super::getenv_required_utf8(super::STATE_ENV)?.as_str())?; 494 | 495 | if initstamp.exists() { 496 | return Ok(state); 497 | } 498 | 499 | let ostree_based_host = std::path::Path::new("/host/run/ostree-booted").exists(); 500 | 501 | // Convert the container to ostree-style layout 502 | if ostree_based_host { 503 | DATADIRS 504 | .par_iter() 505 | .try_for_each(|d| -> Fallible<()> { 506 | std::fs::remove_dir(d)?; 507 | let vard = format!("var{}", d); 508 | unix::fs::symlink(&vard, d)?; 509 | std::fs::create_dir(&vard)?; 510 | Ok(()) 511 | }) 512 | .with_context(|e| format!("Converting container to ostree-style layout: {}", e))?; 513 | } 514 | 515 | // This is another mount point used by udisks 516 | unix::fs::symlink("/host/run/media", "/run/media") 517 | .with_context(|e| format!("Symlinking /run/media: {}", e))?; 518 | 519 | // Remove anaconda cruft 520 | std::fs::read_dir("/tmp")?.try_for_each(|e| -> Fallible<()> { 521 | let e = e?; 522 | if let Some(name) = e.file_name().to_str() { 523 | if name.starts_with("ks-script-") { 524 | std::fs::remove_file(e.path())?; 525 | } 526 | } 527 | Ok(()) 528 | })?; 529 | 530 | // These symlinks into /host are our set of default forwarded APIs/state 531 | // directories. 532 | super::STATIC_HOST_FORWARDS 533 | .par_iter() 534 | .try_for_each(host_symlink) 535 | .with_context(|e| format!("Enabling static host forwards: {}", e))?; 536 | 537 | // And these are into /dev 538 | if state.uid != 0 { 539 | super::FORWARDED_DEVICES 540 | .par_iter() 541 | .try_for_each(|d| -> Fallible<()> { 542 | let devd = format!("/dev/{}", d); 543 | let hostd = format!("/host{}", devd); 544 | if !Path::new(&devd).exists() && Path::new(&hostd).exists() { 545 | unix::fs::symlink(&hostd, &devd) 546 | .with_context(|e| format!("symlinking {}: {}", d, e))?; 547 | } 548 | Ok(()) 549 | }) 550 | .with_context(|e| format!("Forwarding devices: {}", e))?; 551 | } 552 | 553 | // Allow sudo 554 | let mut with_sudo = false; 555 | if Path::new("/etc/sudoers.d").exists() { 556 | || -> Fallible<()> { 557 | let f = File::create(format!("/etc/sudoers.d/toolbox-{}", state.username))?; 558 | let mut perms = f.metadata()?.permissions(); 559 | perms.set_readonly(true); 560 | f.set_permissions(perms)?; 561 | let mut f = std::io::BufWriter::new(f); 562 | writeln!(&mut f, "{} ALL=(ALL) NOPASSWD: ALL", state.username)?; 563 | f.flush()?; 564 | with_sudo = true; 565 | Ok(()) 566 | }() 567 | .with_context(|e| format!("Enabling sudo: {}", e))?; 568 | } 569 | 570 | adduser(&state, with_sudo)?; 571 | let _ = File::create(&initstamp)?; 572 | 573 | Ok(state) 574 | } 575 | 576 | fn init_container_runtime() -> Fallible<()> { 577 | let initstamp = Path::new(CONTAINER_INITIALIZED_RUNTIME_STAMP); 578 | if initstamp.exists() { 579 | return Ok(()); 580 | } 581 | 582 | let lockf = std::fs::OpenOptions::new() 583 | .read(true) 584 | .write(true) 585 | .create(true) 586 | .open(CONTAINER_INITIALIZED_LOCK)?; 587 | lockf.lock_exclusive()?; 588 | 589 | if initstamp.exists() { 590 | return Ok(()); 591 | } 592 | 593 | // Forward the runtime dir 594 | { 595 | let runtime_dir = super::get_ensure_runtime_dir()?; 596 | let runtime_dir_p = std::path::Path::new(&runtime_dir); 597 | if !runtime_dir_p.exists() { 598 | std::fs::create_dir_all(runtime_dir_p.parent().expect("runtime dir parent"))?; 599 | host_symlink(runtime_dir) 600 | .with_context(|e| format!("Forwarding runtime dir: {}", e))?; 601 | } 602 | } 603 | 604 | // Podman unprivileged mode has a bug where it exposes the host 605 | // selinuxfs which is bad because it can make e.g. librpm 606 | // think it can do domain transitions to rpm_exec_t, which 607 | // isn't actually permitted. 608 | let sysfs_selinux = "/sys/fs/selinux"; 609 | if Path::new(sysfs_selinux).join("status").exists() { 610 | let empty_path = Path::new("/usr/share/empty"); 611 | let empty_path = if empty_path.exists() { 612 | empty_path 613 | } else { 614 | let empty_path = Path::new("/usr/share/coretoolbox/empty"); 615 | std::fs::create_dir_all(empty_path)?; 616 | empty_path 617 | }; 618 | rbind(empty_path, sysfs_selinux)?; 619 | } 620 | 621 | let ostree_based_host = std::path::Path::new("/host/run/ostree-booted").exists(); 622 | 623 | // Propagate standard mount points into the container. 624 | // We make these bind mounts instead of symlinks as 625 | // some programs get confused by absolute paths. 626 | if ostree_based_host { 627 | DATADIRS.par_iter().try_for_each(|d| -> Fallible<()> { 628 | let vard = format!("var{}", d); 629 | let hostd = format!("/host/{}", &vard); 630 | rbind(&hostd, &vard)?; 631 | Ok(()) 632 | })?; 633 | } else { 634 | DATADIRS.par_iter().try_for_each(|d| -> Fallible<()> { 635 | let hostd = format!("/host/{}", d); 636 | rbind(&hostd, d)?; 637 | Ok(()) 638 | })?; 639 | } 640 | 641 | Ok(()) 642 | } 643 | 644 | pub(crate) fn exec(opts: ExecOpts) -> Fallible<()> { 645 | use nix::sys::stat::Mode; 646 | if !super::in_container() { 647 | bail!("Not inside a container"); 648 | } 649 | let state = init_container_static() 650 | .with_context(|e| format!("Initializing container (static): {}", e))?; 651 | init_container_runtime() 652 | .with_context(|e| format!("Initializing container (runtime): {}", e))?; 653 | let initstamp = Path::new(CONTAINER_INITIALIZED_STAMP); 654 | if !initstamp.exists() { 655 | bail!("toolbox not initialized"); 656 | } 657 | // Set a sane umask (022) by default; something seems to be setting it to 077 658 | nix::sys::stat::umask(Mode::S_IWGRP | Mode::S_IWOTH); 659 | let mut cmd = if opts.as_userns_root || !Path::new("/etc/sudoers.d").exists() { 660 | Command::new("/bin/bash") 661 | } else { 662 | let mut cmd = Command::new("setpriv"); 663 | cmd.args(&[ 664 | "--inh-caps=-all", 665 | "su", 666 | "--preserve-environment", 667 | state.username.as_str(), 668 | ]) 669 | .env("HOME", state.home.as_str()); 670 | cmd 671 | }; 672 | 673 | Err(cmd.env_remove(super::STATE_ENV).exec().into()) 674 | } 675 | 676 | pub(crate) fn run_pid1() -> Fallible<()> { 677 | unsafe { 678 | signal_hook::register(signal_hook::SIGCHLD, waitpid_all)?; 679 | signal_hook::register(signal_hook::SIGTERM, || std::process::exit(0))?; 680 | }; 681 | loop { 682 | std::thread::sleep(std::time::Duration::from_secs(1_000_000)); 683 | } 684 | } 685 | 686 | fn waitpid_all() { 687 | use nix::sys::wait::WaitStatus; 688 | loop { 689 | match nix::sys::wait::waitpid(None, Some(nix::sys::wait::WaitPidFlag::WNOHANG)) { 690 | Ok(status) => match status { 691 | WaitStatus::StillAlive => break, 692 | _ => {} 693 | }, 694 | Err(_) => break, 695 | } 696 | } 697 | } 698 | } 699 | 700 | /// Primary entrypoint 701 | fn main() { 702 | || -> Fallible<()> { 703 | let mut args: Vec = std::env::args().collect(); 704 | if let Some("internals") = args.get(1).map(|s| s.as_str()) { 705 | args.remove(1); 706 | let opts = InternalOpt::from_iter(args.iter()); 707 | match opts { 708 | InternalOpt::Exec(execopts) => entrypoint::exec(execopts), 709 | InternalOpt::RunPid1 => entrypoint::run_pid1(), 710 | } 711 | } else { 712 | let opts = Opt::from_iter(args.iter()); 713 | match opts { 714 | Opt::Create(ref opts) => create(opts), 715 | Opt::Run(ref opts) => run(opts), 716 | Opt::Rm(ref opts) => rm(opts), 717 | Opt::ListToolboxImages => list_toolbox_images(), 718 | } 719 | } 720 | }() 721 | .unwrap_or_else(|e| { 722 | eprintln!("error: {}", e); 723 | std::process::exit(1) 724 | }) 725 | } 726 | -------------------------------------------------------------------------------- /src/podman.rs: -------------------------------------------------------------------------------- 1 | use failure::{bail, Fallible}; 2 | use serde::Deserialize; 3 | use serde_json; 4 | use std::io::prelude::*; 5 | use std::process::{Command, Stdio}; 6 | 7 | #[allow(dead_code)] 8 | pub(crate) enum InspectType { 9 | Container, 10 | Image, 11 | } 12 | 13 | #[derive(Deserialize, Clone, Debug)] 14 | pub(crate) struct ImageInspect { 15 | // Podman 2.x changed this 16 | #[serde(alias="Id")] 17 | pub id: String, 18 | pub names: Option>, 19 | } 20 | 21 | pub(crate) fn cmd() -> Command { 22 | if let Some(podman) = std::env::var_os("podman") { 23 | Command::new(podman) 24 | } else { 25 | Command::new("podman") 26 | } 27 | } 28 | 29 | /// Returns true if an image or container is in the podman 30 | /// storage. 31 | pub(crate) fn has_object(t: InspectType, name: &str) -> Fallible { 32 | let typearg = match t { 33 | InspectType::Container => "container", 34 | InspectType::Image => "image", 35 | }; 36 | Ok(cmd() 37 | .args(&["inspect", "--type", typearg, name]) 38 | .stdout(Stdio::null()) 39 | .stderr(Stdio::null()) 40 | .status()? 41 | .success()) 42 | } 43 | 44 | pub(crate) fn image_inspect(args: I) -> Fallible> 45 | where 46 | I: IntoIterator, 47 | S: AsRef, 48 | { 49 | let mut proc = cmd() 50 | .stdout(Stdio::piped()) 51 | .args(&["images", "--format", "json"]) 52 | .args(args) 53 | .spawn()?; 54 | let sout = proc.stdout.take().expect("stdout piped"); 55 | let mut sout = std::io::BufReader::new(sout); 56 | let res = if sout.fill_buf()?.len() > 0 { 57 | serde_json::from_reader(sout)? 58 | } else { 59 | Vec::new() 60 | }; 61 | if !proc.wait()?.success() { 62 | bail!("podman images failed") 63 | } 64 | Ok(res) 65 | } 66 | --------------------------------------------------------------------------------