├── .gitignore ├── COPYING ├── Makefile ├── NOTES ├── README ├── TODO ├── doc └── official_installation_guide_en ├── examples ├── fancy-install-on-sda ├── generic-install-on-sda └── simple-lvm-install-on-sda ├── make-doc.sh ├── src ├── aif-report-issues.sh ├── aif-test.sh ├── aif.sh ├── core │ ├── libs │ │ ├── lib-blockdevices-filesystems.sh │ │ ├── lib-flowcontrol.sh │ │ ├── lib-misc.sh │ │ ├── lib-network.sh │ │ ├── lib-pacman.sh │ │ ├── lib-software.sh │ │ ├── lib-ui-interactive.sh │ │ └── lib-ui.sh │ └── procedures │ │ ├── automatic │ │ ├── base │ │ ├── interactive │ │ ├── partial-configure-network │ │ ├── partial-disks │ │ └── partial-keymap └── user │ └── whatsthis.txt ├── tests ├── buildtime │ ├── test-check_is_in.sh │ └── test-menus.sh ├── lib │ ├── framework-runtime │ ├── setup-file │ ├── test-file │ ├── test-lvm-lv │ ├── test-mount │ ├── test-nofile │ ├── test-nopackage │ ├── test-ping │ └── test-swap └── runtime │ ├── automatic-dmcrypt-lvm-install-sda │ ├── install.sh │ ├── perform_test.sh │ ├── profile │ └── setup_test.sh │ ├── automatic-lvm-dmcrypt-install-sda │ ├── install.sh │ ├── perform_test.sh │ ├── profile │ └── setup_test.sh │ └── automatic-reuse-fs-sda │ ├── install.sh │ ├── perform_test.sh │ ├── profile │ └── setup_test.sh └── unofficial ├── dieter-desktop-a7n8x.automaticprofile ├── jdd-generic-install-sda-using-host-packages └── modules └── dieter └── procedures └── dieter-automatic /.gitignore: -------------------------------------------------------------------------------- 1 | doc/*.html 2 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: install 2 | 3 | install: 4 | install -d $(DESTDIR)/sbin 5 | install -d $(DESTDIR)/usr/share/aif/docs 6 | install -d $(DESTDIR)/usr/share/aif/examples 7 | install -d $(DESTDIR)/usr/share/aif/tests 8 | install -d $(DESTDIR)/usr/lib/aif/core 9 | install -d $(DESTDIR)/usr/lib/aif/user 10 | install -D -m755 src/aif.sh $(DESTDIR)/sbin/aif 11 | install -D -m755 src/aif-test.sh $(DESTDIR)/sbin/aif-test 12 | install -D -m755 src/aif-report-issues.sh $(DESTDIR)/sbin/aif-report-issues.sh 13 | install -D -m644 README $(DESTDIR)/usr/share/aif/docs 14 | install -D -m644 doc/* $(DESTDIR)/usr/share/aif/docs 15 | cp -rp src/core $(DESTDIR)/usr/lib/aif 16 | chmod -R 755 $(DESTDIR)/usr/lib/aif/core 17 | cp -rp src/user $(DESTDIR)/usr/lib/aif 18 | chmod -R 755 $(DESTDIR)/usr/lib/aif/user 19 | cp -rp examples $(DESTDIR)/usr/share/aif 20 | chmod -R 755 $(DESTDIR)/usr/share/aif/examples 21 | cp -rp tests $(DESTDIR)/usr/share/aif 22 | chmod -R 755 $(DESTDIR)/usr/share/aif/tests 23 | 24 | 25 | uninstall: 26 | rm -f $(DESTDIR)/sbin/aif 27 | rm -f $(DESTDIR)/sbin/aif-test 28 | rm -f $(DESTDIR)/sbin/aif-report-issues.sh 29 | rm -rf $(DESTDIR)/usr/share/aif 30 | rm -rf $(DESTDIR)/usr/lib/aif 31 | -------------------------------------------------------------------------------- /NOTES: -------------------------------------------------------------------------------- 1 | * umounting/destructing blockdevice/filesystem stuff in the blockdevice library. 2 | ** Goals 3 | not break while trying to build the setup like the user requested (breakage could happen if a device mapper volume is still active or a filesystem is still mounted) 4 | still allow user to mount stuff himself behind the installers back. he is smarter then us. just do what we're told. 5 | ** Options 6 | *** umount/deconstruct before trying to build 7 | problems: - it's hard to know what we should delete, our 'build' plan might be different then the current environment (eg devices with same name but other function), 8 | usually because of a previous run with the wrong settings, or which failed 9 | - we can't base ourselves on things like "we should only have / and /dev/shm". The user can mount things himself 10 | - quite complicated code if want to make it smart, but it's a dead end anyway. 11 | *** if buildup fails, ask user to rollback -> implemented approach 12 | - user should not ctrl-c and installer should not crash. this is doable. a 'wrong' state can be an acceptable exception. 13 | - right now we can start repartitioning a disks that has filesystems mounted. is this harmfull? this only happens if unclean rollback or user did it, so NP i think 14 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | AIF is the Arch Linux Installation Framework. 2 | 3 | License: GPL3. See COPYING. 4 | Authors: Dieter Plaetinck 5 | Patches from Gerhard Brauer, Matthias Dienstbier, Jud Film, Laszlo Papp and 'tuxce' 6 | Quite some code has been taken from the installer project @ http://projects.archlinux.org/?p=installer.git;a=summary 7 | The main authors/contributors of that project are Judd Vinet, Tobias Powalowski, Simo Leone, Aaron Griffin and Dan McGee 8 | Homepage: http://github.com/Dieterbe/aif 9 | 10 | 11 | ** Dependencies ** 12 | - util-linux-ng 13 | - bash >=4 14 | - pacman >=3.4 15 | - coreutils 16 | - grep 17 | - awk 18 | - sed 19 | - libui-sh 20 | - iproute2 21 | Optionally: 22 | - markdown: to generate the html installation guide 23 | - cryptsetup: for encryption support 24 | - lvm2: for LVM support 25 | - dhcpd: for dhcp networking support 26 | - btrfs-progs-unstable: for btrfs support 27 | - e2fsprogs: Ext support 28 | - jfsutils: JFS support 29 | - reiserfsprogs: ReiserFS support 30 | - nilfs-utils: Nilfs2 support 31 | - xfsprogs: XFS support 32 | - ntp: setting date with NTP 33 | - dialog: for ncurses support 34 | - curl: for the aif-report-issues.sh script 35 | - grub: for grub support 36 | - syslinux: for syslinux support 37 | 38 | ** Goals ** 39 | 40 | The goal of this project is to: 41 | 1) provide reasonable clean, DRY, modular and maintainable code for the Arch Linux installer 42 | 2) provide complete, easily-reusable libraries for disk partitioning, UI, package management, etc 43 | 3) provide some sensible default installation methods (eg interative, automatic (prescripted), ..) 44 | 4) allow power users to easily override certain aspects of the installation procedures 45 | or creating customized procedures, leveraging the available code. 46 | 47 | The goal of AIF is not (yet) to: 48 | 1) provide an installer who detects your stuff and tries to be smart and configures all your stuff. 49 | If you're interested in this, feel free to build it and I may incorporate it someday. 50 | 2) be more fancy then needed 51 | 52 | 53 | ** Branches ** 54 | -> master: "stable" tree, infrequent updates 55 | -> develop: unstable development tree, which may get rewritten at some points, 56 | only when things have settled down (every x weeks/months), gets pushed to master 57 | -> optionally: more topic branches which are rewriteable and which come and go 58 | 59 | ** A bit of history ** 60 | 61 | AIF is based on the old archlinux-installer, but the code has been madly refactored, reorganized, cleaned 62 | up, improved and in some places replaced. 63 | The initial goal was to build an automated installer with a reusable 64 | backend, but the porting of the userfriendly, interactive installer from /arch/setup quickly became a proof of concept 65 | and even main focus point. See http://www.nabble.com/Fifa:-Flexible-Installer-Framework-for-Arch-linux-td20256427.html 66 | 67 | arch-installer used to be installed as /arch/setup and /arch/quickinst; wheres AIF adheres to the FHS spec, 68 | but archiso images come with an /arch/setup 1-line script which now just calls aif with the interactive procedure and dialog (ncurses) frontend. 69 | 70 | ** Bug/feature request tracking. Getting in touch ** 71 | 72 | AIF developement happens under the umbrella of the release engineering project of Arch Linux. 73 | 74 | - bug tracker: the Arch Linux bugtracker, "Release Engineering" project, category 'AIF'. 75 | http://bugs.archlinux.org/toplevel/proj6 76 | - mailing list: http://www.archlinux.org/mailman/listinfo/arch-releng 77 | 78 | There are some known issues (see the bugtracker, TODO file and various TODO's in the source code) 79 | If you encounter issues, please report them on the bugtracker, after checking if they are not reported yet of course. 80 | If you want to get in touch with us, to ask/discuss/.. things, please send to the mailing list. 81 | 82 | 83 | 84 | ** Lingo ** 85 | 86 | - procedure = a 'plugin' for aif that controls how the installation advances and how the interaction with the user happens 87 | - lib = a library for aif with some useful functions (eg lib-pacman handles all pacman related things) 88 | - module = a bundle that can contain zero or more procedures and libraries. 89 | - profile = a fancier name for a config file. some procedures support the use of profiles (eg automatic), others don't (eg interactive) 90 | - partial procedure = a 'mini' procedure that lets the user perform one or more smaller aspects of (or related to) an installation 91 | 92 | 93 | ** Basic workflow ** 94 | 95 | AIF comes by default with these procedures: 96 | - base: basic, little-interactivity installation with some common defaults. 97 | This procedure is used by the others to inherit from, it is NOT meant to be used directly by end users 98 | - interactive: An interactive installation procedure. 99 | Asks you some questions, guides you through an installation 100 | and even helps you a bit by updating configuration files on the target 101 | system with your usettings 102 | - automatic: An automated, deploy-tool-alike procedure. designed for low- 103 | to zero interactivity. uses profiles for configuration of the installation/target system. 104 | See /usr/share/aif/examples/ for example profile files. 105 | - partial-configure-network: exposes the network configuration step from the interactive procedure 106 | - partial-disks: Process disk subsystem or do a rollback 107 | - partial-keymap: change your keymap/console font settings. The benefit of this method over a simple loadkeys is that the interactive procedure will 108 | automatically update the rc.conf on the target system with your settings. 109 | 110 | You would usually invoke aif like this: 111 | aif -p interactive 112 | aif -p automatic -c [-l] 113 | aif -p / 114 | Type `aif -h` or just aif to see more details. 115 | 116 | 117 | 118 | ** Packages and file locations: ** 119 | 120 | The officially supported package is aif, in extra. There are also 121 | unsupported development git packages in AUR. See HOWTO 122 | 123 | File locations: 124 | * aif.sh -> /sbin/aif 125 | * docs -> /usr/share/aif/docs 126 | * core module -> /usr/lib/aif/core 127 | * user modules -> /usr/lib/aif/user/ (put your own modules here) 128 | * runtime files -> /tmp/aif 129 | * logs -> /var/log/aif and $target/var/log/aif for things installed in the chroot 130 | 131 | 132 | 133 | ** (Internal) Workflow ** 134 | There is a very basic but powerful workflow defined by variables, phases and workers. 135 | Depending on the procedure you choose (or write yourself), these will differ 136 | In the code, they are very recognizable and are named like this: 137 | - variable -> var_ 138 | - phase -> phase_ (an array in which each element is a worker to be executed, with optionally arguments for that worker) 139 | There are 4 phases: preparation, basics, system, finish. (executed in that order) 140 | - worker -> worker_ ( a worker function, called by a phase. implements some specific logic. 141 | eg runtime_packages, prepare_disks, package_list etc) 142 | 143 | 144 | You can depend on whatever procedure you like (like core/base), to save 145 | yourself some work (you only need to override a few things) 146 | 147 | Notes: 148 | - You don't need to use the concept of phases, for example the interactive procedure doesn't use them. 149 | - The phases are started by the start_process function. You can also override this function to take flow control in your own hands (like interactive does) 150 | - you _can_ override _all_ variables and functions in your modules, but you should be able to achieve your goals by 151 | overriding only the 3 basic things and the start_process function, and only in procedures. 152 | - you _must_ specify a procedure, to avoid errors. take 'interactive' if unsure 153 | - don't edit the base procedure (or any other core item), rather make your own. It's easy! 154 | - you're not supposed to define new phases. just override them. logic goes in workers/libariers 155 | - workers and phases are pretty regular functions, except that they are invoked through a wrapper (the `execute` function), which tracks the exitcodes 156 | this allows to get reports at the end of the install showing which steps completed successfully and where things failed. Other then that, there is nothing 157 | special about them. It is even possible to have your workers function as a callback by having library functions invoking them. 158 | 159 | 160 | ** Extending AIF ** 161 | 162 | *** Modules *** 163 | -> Modules are the building blocks in aif 164 | -> user modules are just directories with a 'libs' and 'procedures' subdirectory 165 | where you can put your customized.. guess what. See 'file locations' 166 | -> The core module comes by default and contains everything 99% of the users will need. 167 | Don't name your custom module 'core' (it will be ignored). 168 | Don't call it http either, because you can specify 'http://some/path/to/a/procedure', 169 | aif will download that procedure and execute it (and the module will be 'http') 170 | 171 | *** Procedures *** 172 | -> You can take a procedure, copy it, modify it and call it. that's fine. 173 | -> You can also write a new one from scratch, inheriting some other procedure using 174 | the depend_procedure call and just overriding what you need. 175 | 176 | -> Commandline arguments are parsed by aif.sh but you can extend/override it's 177 | behaviour by overriding $var_OPTS_STRING and the process_vars variable. 178 | Also, you do not _have_ to use the variables they set (eg arg_ui_type). You 179 | usually will set defaults in the configure worker and override with 180 | arguments passed by the user (eg to use cli mode unless user wants dia) 181 | 182 | *** Libraries ** 183 | -> If you have logic that may be reusable by several procedures, consider 184 | putting the functions in a library so you, and others can easily use it. 185 | 186 | *** Profiles *** 187 | -> You can take a profile and modify it 188 | -> you can also use the depend_profile call and just override what you need. 189 | 190 | 191 | Note that if you load a module and a library has the same function names as 192 | the core module, it will override the functions from core. 193 | This means you can 'inject' new backend code into core procedures, but you 194 | can also write your own procedures that use your own, or the core libraries. 195 | If you load a module, you actually load it's libraries, not it's procedures! 196 | Procedures are only loaded when needed (because you request them because 197 | of dependencies) 198 | 199 | If you need a library from another user contributed module, execute 200 | 'depend_module ' for each module. This way you load all the 201 | libs of that module (not the procedures, use depend_procedure for that. 202 | keep in mind that the position of the depend_procedure statement defines 203 | where your variables/functions might be overridden...) 204 | (very basic dependencies, no version checking etc) 205 | 206 | You can specify a core procedure on the command line by specifying 207 | '', to specify a user contriubuted procedure, specify 208 | '/' 209 | 210 | 211 | 212 | ** Contributing ** 213 | 214 | Install a VM (I use virtualbox-ose, works fine), make a vm, boot the install cd and just follow the HOWTO. 215 | It's probably easiest if you set up your own git clone that you can easily 216 | acces from the VM (You can open a github account and fork my code). 217 | You can edit on the cd itself, but given the low resolution of the VM, you'll probably edit on your pc, commit, push to github 218 | and pull from the clone on the cd. 219 | If you want to do debugging, just call the debug function and export DEBUG=1 220 | before calling the scripts. (or pass -d) 221 | Keep in mind there are 3 kinds of variables. Those that affect/belong to 222 | the runtime (install cd live environment), target (affects/belongs to the 223 | target installation) and TMP (everything in between or extra). Variablenames 224 | should have _TARGET or _TMP suffixes or none for runtime. (That's the 225 | theory, it isn't always the case like that now, I need to do more refactoring) 226 | 227 | ** Test suite ** 228 | 229 | AIF also has a (WIP) test-suited. the source is the documentation. 230 | 231 | ** Reporting issues / getting help ** 232 | 233 | Run the aif-report-issues.sh script, which will submit valuable (for debugging) 234 | info to a public pastebin, you can then give the url to the people who need to help you 235 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | See also the FIXME's and TODO's in the code, and http://bugs.archlinux.org/toplevel/proj6 2 | 3 | 4 | CURRENT ISSUES: 5 | * fix (hd0,0) not showing up in automatic procedure 6 | * all grub related code could use a refactor 7 | * do we use a squashfs on usb images? is this needed? how to make changes persistent? 8 | * time choosing: put 'ok' at bottom again but make it default 9 | * implement depend_profile 10 | * add /var/lib/aif/profiles directory to packages and document it. 11 | * > It displays the current time in UTC (if utc selected) not the users localtime (UTC +- TIMEZONE) 12 | * more vars for automatic profile: hostname (check that adding to /etc/hosts can be done procedure-independently), 13 | LOCALE, HARDWARECLOCK, TIMEZONE, KEYMAP, MODULES, DAEMONS, network config? (or take the config from runtime) 14 | * what to do with /etc/groups, passwd, modprobe.conf, mkinitcpio.conf, rc.local etc with automatic procedure? configure through automatic profile or let user check out files from svn or so? 15 | * depend statements for automatic profiles (+ example) 16 | * use traps and initiate rollback when user wants to abort. see also http://www.davidpashley.com/articles/writing-robust-shell-scripts.html 17 | * differentiate between framework and installer in src/aif.sh, some things should be in base 18 | * after unlocking dm_crypt, FS check fails (reiserfs, must try other) 19 | * interactive FS display could use aligned columns. maybe with dialog --column-separator? 20 | * sometimes we call die_error but we go back to the menu.. eg when we run as non-root and can't log 21 | * fs_params in partition editor: do we really need to show them? isn't this where we store our "own" stuff? 22 | * move "/tmp/pacman.conf" to runtime directory and variablize everywhere 23 | * a nice way to be able to "inject" functions/logic without: 24 | * needing to redefine phases with only 1 entry different (duplicate code is not nice, less maintainable etc) 25 | * override worker functions which are 90% copy-pasted because the parent functionality is mostly okay, but not exactly what we want 26 | useful for: profiles for the automatic procedures, or all other procedures 27 | -> optional pre/post callbacks (for workers and phases)? 28 | -> disadvantages? 29 | * ended_ok must comprise callbacks too.. or if callback didn't exit cleanly, maybe we should update the exit code of the worker/phase 30 | * we lose semantics: a function usually has a better suited name then 'pre_'. 31 | -> maybe we should in the callback do an execute call for another worker, then we also can check it's exitcode in a good way 32 | -> too. although that's only good for separate functions, not the 'copypaste 90% and add 10% to the same worker scenario' 33 | -> phases are arrays.. adding elements at the back is easy. for in the middle, we could maybe write some functions to add a worker before/after another in a phase 34 | * show_report does not show workers. 35 | * 'keep in mind trottled' not on separate screen 36 | * look if you can hook into bash so that on any syntax/.. error you can bind the debug/log function 37 | * when you have 2 LV's and you delete one, both are erased from the VG, but there is still the entry for the other one as blockdevice 38 | * in usage, procedure specific opts points to parent profile when using inheritance 39 | * refactor all pacman stuff (modularize/functionize etc) 40 | * port from /arch/setup: grub install chroot thing (http://projects.archlinux.org/?p=installer.git;a=commitdiff;h=4565577dbd2182dd49612f1e0b68288f5573bf7b) (waiting for ticket http://bugs.archlinux.org/task/13277) 41 | * ext4 default options? -O dir_index,extent,uninit_bg ? 42 | * find a way to not have to preload libs and stuff, only load them when needed. -> faster start of install program 43 | * core/interactive: do not check hard for the dependencies. a user could really know what he's doing or need to reboot after partitioning a disk and 44 | skip that check or something. Alternatively, maybe just show which steps are done successfully in the main menu 45 | * support setting mount options for fs'es (to go into fstab) in at least automatic procedures. interactive > you can edit fstab right.. 46 | 47 | 48 | SOMEDAY/MAYBE/RANDOM THOUGHTS: 49 | * core/interactive: do pacman -Sy in the background during early phases, to lessen the wait period before selecting packages 50 | * write bash completion thing for aif modules/procedures 51 | * add dmraid/mdadm support -> patches welcome. i don't care about this. 52 | * check if it would be useful to support kickstart config files. we can look at quickstart for that http://dev.gentoo.org/~agaffney/quickstart.php 53 | * profiles like 'desktop','server' (~-> package list, configs, disk setup,..) are crossconcerns 54 | compared to procedures (which are about "how" the installation goes: 55 | prescripted, autodetection, interactive,...). 56 | support for profiles could be built in certain procedures), maybe by supplying extra commandline 57 | arguments to the procedure or asking a few questions. 58 | For automatic procedures, a profile could be the fundamental entitiy, 59 | whereas for interactive procedures it could provide some other defaults. 60 | * all dialog windows are equally sized. noone cares, right? 61 | * we run mkinitcpio twice: one while installing kernel packages, once after configuring system (mkinitcpio.conf) 62 | configuring the system (mkinitcpio.conf). can we optimize this? 63 | * split up lib-ui as sep project, make a generic 'LIF' project, set $DISTRO somewhere and use that everywhere... 64 | 65 | 66 | WORRIES FOR MAYBE NO GOOD REASON 67 | * instead of every procedure using and overriding the 'base' procedure, 68 | we should maybe have even more flexibilty to take parts from different, specific procedures. 69 | eg: dieter procedure maybe wants to use something interactive. or base procedure wants to do something 70 | from interactive profile (Will this really happen?) 71 | interactive functions maybe dont belong in a procedure? 72 | -> depend_procedure good enough? or do we need more fine-grained dependencies (take function foo from procedure bar from module baz). 73 | for now let's try like this.. -> we can call explicit functions from libraries from modules.. so then just stick it in a lib -> 74 | lots of stuff can go into lib-ui, making the procedure itself just the 75 | 'execution plan'.. sounds good actually. 76 | problem with this is functions can have the same names (or you need to prepend modulename always, but that's not clean + 'fallback'/overriding doesn't work well anymore. 77 | alternative -> each lib is a directory, each function in a file, make it possible to source all libs, one lib, or one function from one lib 78 | 79 | -------------------------------------------------------------------------------- /doc/official_installation_guide_en: -------------------------------------------------------------------------------- 1 | **Article summary** 2 | 3 | General installation documentation for the Arch Linux distribution. 4 | 5 | This guide is only valid for release 2010.05 or newer. 6 | This guide is maintained in [aif git](http://projects.archlinux.org/?p=aif.git) 7 | Git pull requests, patches, comments are welcome on the arch 8 | [releng mailing list](http://www.archlinux.org/mailman/listinfo/arch-releng) 9 | 10 | This guide is available in the /usr/share/aif/docs directory of release media and on 11 | [The arch wiki](http://wiki.archlinux.org/index.php/Official_Arch_Linux_Install_Guide) 12 | 13 | **Related articles** 14 | 15 | [Beginners Guide](http://wiki.archlinux.org/index.php/Beginners_Guide) (If you are new to Arch) 16 | 17 | # Introduction 18 | 19 | ## What is Arch Linux? 20 | 21 | Arch Linux is an independently developed i686 and x86_64 optimized Linux 22 | distribution that was originally based on ideas from CRUX. 23 | Development is focused on a balance of simplicity, elegance, code-correctness 24 | and bleeding edge software. 25 | Its lightweight and simple design makes it easy to extend and mold into 26 | whatever kind of system you're building. 27 | 28 | ## License 29 | 30 | Arch Linux and scripts are copyright 31 | 32 | 2002-2007 Judd Vinet 33 | 34 | 2007-2012 Aaron Griffin 35 | 36 | and are licensed under the GNU General Public License (GPL). 37 | 38 | # Pre-Installation 39 | 40 | ## Architectures 41 | 42 | Arch Linux is optimized for i686 and x86_64 processors and therefore will not 43 | run on any lower or incompatible generations of x86 CPUs (i386, i486 or i586). 44 | A Pentium Pro, Pentium II or AMD Athlon (K7) processor or higher is required. 45 | (technically, cpu's without the cmov instruction such as AMD K6 and via C3 are also 46 | i686, but we use gcc and it uses cmov instructions) 47 | Before installing Arch Linux, 48 | you should decide which installation method you would like to use. 49 | 50 | ## Available images 51 | 52 | Arch Linux provides isofiles which can be written to CD-roms or to disks and usb sticks 53 | 54 | The Isolinux bootloader is used. 55 | There are two variants of each installation medium which only differ 56 | in terms of supplied packages. 57 | 58 | * The "core" images contain a snapshot of the core packages. 59 | These images are best suited for people who have an internet connection 60 | which is slow or difficult to set up. 61 | 62 | * The "netinstall" images contain no packages at all, 63 | and will always use the network to install packages. 64 | 65 | Both types of images can be used to perform a netinstall, yielding an up- 66 | to-date system, although with a "core" image you don't have to. 67 | All images can also be used as fully functioning recovery environments. 68 | The images run like any regular installed Arch Linux system. 69 | In fact, they're exactly the same, just installed to a CD or USB image instead 70 | of a hard disk. 71 | They include the entire "base" package set, as well as various 72 | networking utilities and drivers and have the aif package installed. 73 | If there's something else you happen to need 74 | at runtime, just get your Internet connection up and install it using pacman. 75 | A short pacman command reference is available at the end of this document. 76 | 77 | All images are available in a i686, x86_64 or dual variant. The latter contains both and lets you choose 78 | an architecture at boot. 79 | 80 | ## AIF, the installation tool 81 | 82 | Arch Linux uses AIF aka 'Arch Linux Installation Framework' to perform 83 | installations. 84 | This tool - written in bash - consists of some libraries to perform various 85 | functions (installing packages, setting up disks etc) and some so called 86 | procedures which use these libraries to provide an easy means to do 87 | an installation or to smaller related tasks ('partial procedures'). 88 | These procedures are shipped by default: 89 | 90 | * interactive: An interactive installation procedure, which asks you some 91 | questions, guides you through an installation and helps you 92 | configuring the target system by automatically changing some 93 | settings for you depending on what you did earlier 94 | (eg network settings) 95 | The installed system will initially have only a customisable 96 | set of "base" packages installed with whatever utilities 97 | and drivers you need to get online. 98 | Then once you've 99 | successfully booted the installed system, you'll run a full 100 | system upgrade and install any other packages you want. 101 | (aliased as `/arch/setup`) 102 | * automatic: An automated, deploy-tool-alike procedure designed for 103 | low-to zero interactivity. 104 | uses profiles for configuration of the target system. 105 | See /usr/share/aif/examples/ for example profile files. 106 | The examples implement quite generic scenarios but you're 107 | free to change them how you like to install extra packages, 108 | do configuration tweaks, etc. 109 | * base: basic, little-interactivity installation with some 110 | common defaults. 111 | This procedure is used by the others to inherit from, 112 | it is NOT meant to be used directly by end users 113 | * partial-configure-network: exposes the network configuration step from 114 | the interactive procedure, to help you setup 115 | the network in the live environment 116 | * partial-disks: Process disk subsystem or do a rollback 117 | * partial-keymap: change your keymap/console font settings. (aliased as `km`) 118 | 119 | The benefit of procedures such as partial-keymap and partial-configure-network 120 | over direct usage of tools such as loadkeys or ip is that when running the 121 | interactive procedure, you will be asked if you want to apply your settings 122 | to the config files of the target system. 123 | 124 | If you want to go further, you can also: 125 | 126 | * write your own procedures from scratch or by overriding certain parts of 127 | other procedures 128 | * write your own libraries, to provide new, reusable functionality 129 | * create your own configs for the procedures that support them (eg automatic) 130 | 131 | For more information, consult the readme of AIF. 132 | 133 | ## Acquiring Arch Linux 134 | 135 | * You can download Arch Linux from any of the mirrors listed on the 136 | [download][45] page. 137 | 138 | * You may also purchase an installation CD from Archux, OSDisc or LinuxCD 139 | and have it shipped anywhere in the world. 140 | 141 | [45]: http://www.archlinux.org/download/ 142 | (http://www.archlinux.org/download/) 143 | 144 | ## Preparing the Installation Media 145 | 146 | * Download your chosen medium through torrent (preferred) or from your favorite mirror. 147 | 148 | * Download iso//sha1sums.txt 149 | 150 | * Verify the integrity of the .iso image using sha1sum: 151 | 152 | 153 | sha1sum --check sha1sums.txt 154 | 155 | archlinux-XXX.iso: OK 156 | 157 | 158 | * Burn the ISO image to a CD-R or CD-RW using any software of your choice, or if using a USB mass storage device, such as a thumb drive, 159 | using dd or similar raw-write software: 160 | 161 | 162 | dd if=archlinux-XXX.iso of=/dev/sdX 163 | 164 | 165 | Make sure to use /dev/sdX and not /dev/sdX1. 166 | This command will irrevocably delete all files on your USB stick, 167 | so make sure you don't have any important files on it before doing this. 168 | 169 | 170 | # Installing Arch Linux 171 | 172 | ## Using the Install Media 173 | 174 | ### Pre-boot 175 | 176 | Make sure your BIOS is set in a way to allow booting from your CD-ROM or USB 177 | device. Reboot your computer with the Arch Linux Installation CD in the drive or 178 | the USB stick plugged in the port. Once the installation medium has started 179 | booting, you will see the Arch Linux logo and an Isolinux menu waiting for your 180 | selection. Most likely you can just hit enter at this point. 181 | 182 | 183 | ### Post-boot 184 | At the end of the boot procedure, you should be at a login prompt with some 185 | simple instructions at the top of the screen. 186 | You should login as root. At this point you can 187 | optionally perform manual preparations and commence the actual installation 188 | 189 | * If you prefer a non-US keymap or specific consolefont, type `km` to change 190 | any of these. 191 | * If for some reason you need network access before starting the installer 192 | (the interactive procedure lets you configure the network for NET 193 | installations) 194 | you can type `aif -p partial-configure-network` 195 | 196 | For both items, changed settings will be remembered to be optionally applied 197 | to the target system when using the interactive procedure. 198 | 199 | There is also an `arch` login which can be usefull if you want to do things 200 | as non-privileged user. 201 | Most people don't need this. 202 | 203 | You will find that everything you need to perform this installation 204 | (a copy of this guide, aif README, shortcuts to common aif procedures) 205 | can be found in /arch 206 | 207 | ## Using PXE (Network booting) 208 | 209 | ### Server 210 | 211 | On another machine running (Arch) Linux (live or normal), 212 | you need to install and configure a dhcp and tftpd daemon. 213 | Dnsmasq is a fine choice which can do both. 214 | You also need a nbd (network block device) daemon so the client can load 215 | the needed files. 216 | 217 | You can find more info on the wiki 218 | [Community contributed documentation](http://wiki.archlinux.org/index.php/Archiso-as-pxe-server) 219 | 220 | (this section could be a bit more elaborate) 221 | ### Client 222 | 223 | Configure your system to try network booting (pxe) first. 224 | On most systems this happen by default. 225 | You will get an IP from the server and load all needed files over the network 226 | automatically. Once booted, you can proceed as normal. 227 | 228 | ## Performing the installation 229 | You can either use the interactive procedure or the automatic one. 230 | See section [2.3 AIF, the installation tool](#Aif_the_installation_tool) 231 | or the AIF readme for more info. 232 | 233 | ### Interactive Installation Procedure 234 | 235 | Type `/arch/setup` (or `aif -p interactive -d -l`, which is the same) to start. 236 | 237 | After the welcome message and disclaimer you will be presented with the main 238 | installation menu. You can use UP and DOWN arrow to navigate menus. Use TAB to 239 | switch between buttons and ENTER to select. At any point during the install 240 | process, you can switch to your 7th virtual console (ALT-F7) to view the 241 | output from the commands the setup is running. Use (ALT-F1) to get back to 242 | your first console where the installer is running, and any F-key in between if 243 | you need to open another console to intervene manually for any reason. 244 | 245 | #### Select Source 246 | 247 | As a first step you must choose repositories where to install Arch Linux from. 248 | If you have a fast Internet connection, you might prefer enabling network 249 | mirrors to ensure you get the latest packages instead of using the potentially 250 | outdated CD or USB image contents. 251 | If you're using a NET image you don't have much choice ;-). 252 | You can also mount your own repositories in the filesystem tree manually. 253 | If you are using a core image and don't have a fast internet connection, you 254 | probably want to use the included core archive, unless it's very outdated. 255 | The only requirement is you select a core repository. 256 | You can combine local and remote repositories but only do this if you know what 257 | you're doing. (combining an older core archive with newer packages from a 258 | network mirror will result in broken packages) 259 | 260 | ##### Optional: only when using network mirror 261 | 262 | ###### Setup Network 263 | 264 | The entry Setup Network will allow you to install and configure your 265 | network device. If you are using a wireless device you will still need to use 266 | the usual utilities to configure it manually, in which case this part of the 267 | installer isn't much use to you. A list of all currently available network 268 | devices is presented to you. If no ethernet device is available yet, or the 269 | one you wish to use is missing, either hit OK and go on to probe for it, or 270 | switch to another console and load the module manually. If you still can't 271 | configure your network card, make sure it's physically been properly 272 | installed, and that it is supported by the Linux kernel. 273 | 274 | When the correct module is loaded, and your desired network card is listed, 275 | you should select the ethernet device you want to configure and you will be 276 | given the option to configure your network with DHCP. If your network uses 277 | DHCP, hit YES and let the installer do the rest. If you select NO, you will be 278 | asked to enter the networking information manually. Either way, your network 279 | should be successfully configured, and you may check connectivity using 280 | standard tools like ping on another console. 281 | 282 | ###### Choose Mirror 283 | 284 | Choose Mirror will allow you to choose the preferred mirror to download the 285 | packages that will be installed in your Arch Linux system. You should choose a 286 | mirror situated near where you live, in order to achieve faster download 287 | speed. At some later point of the installation, you will be given the option 288 | to use the mirror you choose at this step, as the default mirror to download 289 | packages from. 290 | 291 | **Note: ** ftp.archlinux.org is throttled to 50 KB/s. 292 | 293 | These menu entries are only available when choosing FTP Installation, for 294 | rather obvious reasons. After successful preparation, choose Return to Main 295 | Menu. 296 | 297 | ### Set Editor 298 | 299 | Allows you to change your editor preference. 300 | You'll have the choice between nano and vi (and pico/joe/vim if you install those 301 | in a separate console). You can skip this menu, but you will be asked again when 302 | needed. 303 | 304 | #### Set Clock 305 | 306 | Set Clock will allow you to set up your system clock and date. 307 | First you have to say if your hardwareclock is (or should be) in UTC or 308 | localtime. 309 | UTC is preferred, but if you have an OS installed which cannot handle UTC 310 | BIOS times correctly -like Windows- you'll have to choose localtime. 311 | Next the setup will want you to select your continent/country (timezone), 312 | and allow you to set the date and time (for which you can also use 313 | [NTP](http://www.ntp.org/) if your network is up) 314 | 315 | #### Prepare Hard Drive 316 | 317 | Prepare Hard Drive will lead you into a submenu offering two alternatives of 318 | preparing your target drive(s) for installation, and a means to undo changes if 319 | you want to retry. 320 | 321 | * Auto-prepare will automatically partition (and fully overwrite) one disk 322 | of your choice. 323 | It creates a simple layout with a /boot, swap, / and /home partition where 324 | you have some control over the used filesystems and sizes thereof. 325 | * If you wish/need more control you can manually partition one or more hard 326 | disks and then manually specify a complete setup using the partitions on your 327 | disks. You can also use things such as lvm and dm_crypt here. 328 | * The Rollback feature will check which filesystems were created by either 329 | of these methods, unmount the relevant filesystems and destroy lvm and 330 | dm_crypt volumes if they were created by you. You need this option if you 331 | want to undo or redo a certain scheme. You will be prompted for this if 332 | you forget. 333 | 334 | Notes: 335 | 336 | * AIF can help you set up new dm_crypt and lvm volumes, but not (yet) softraid. 337 | * AIF currently doesn't help you creating volumegroups that span multiple 338 | physical volumes. (if you need this -unlikely- : use vgcreate) 339 | * AIF supports reusing filesystems, but only if it can find the blockdevice. 340 | If you want to reuse a filesystem that is on top of lvm/dm_crypt/softraid, 341 | you'll need to bring up the volumes yourself. 342 | 343 | ##### Auto-Prepare 344 | 345 | Auto-Prepare will automatically partition a hard drive of your choice 346 | into a /boot, swap, a root partition, and a /home and then create filesystems 347 | on all four. These partitions will also be automatically mounted 348 | in the proper place. To be exact, this option will create: 349 | 350 | * 32 MB ext2 /boot partition 351 | * 256 MB swap partition 352 | * 7.5 GB root partition 353 | * /home partition with the remaining space 354 | 355 | You will be prompted to modify the sizes to your requirements, but /home will 356 | always use the remaining disk space. You can customize the used filesystem 357 | for /boot and for both of root and /home at once. 358 | 359 | **AUTO-PREPARE WILL ERASE ALL DATA ON THE CHOSEN HARD DRIVE!** 360 | 361 | ##### Manually partition Hard Drives 362 | 363 | Here you can select the disk(s) you want to partition, and you'll be 364 | dropped into the cfdisk program where you can freely modify the partitioning 365 | information until you [Write] and [Quit]. You will need at least a root 366 | partition to continue the installation. 367 | 368 | ##### Manually configure block devices, filesystems and mountpoints 369 | 370 | In this menu all recognized partitions are listed. On top of these you can 371 | create new filesystems. 372 | You should be aware of these things: 373 | 374 | * All of this is just a model, everything will only be set up after you confirm. 375 | * Not all blockdevices support all filesystems (Eg you cannot put an LVM 376 | volumegroup on something other then a LVM physical volume). 377 | The installer will automatically filter the list of possible filesystems 378 | and even select the one automatically for you if there's only one option. 379 | * Some filesystems will cause new blockdevices to be created. 380 | This is the case for dm_crypt and lvm volumes. 381 | You will see them appear in the model and you can use them to put another 382 | filesystem on top of it. 383 | * When asked for (optional) options to mkfs tools, pass 384 | arguments which will literally be added when calling mkfs. 385 | For example, to disable the journal on ext filesystems: 386 | * don't do: `^has_journal` 387 | * but rather: `-O ^has_journal` 388 | * Use 'dev' for the most straightforward way to refer to your disks in config 389 | files such as fstab and the grub menu.lst (plain devicefiles). 390 | Kernel updates can cause devices to be renamed, which can cause issues. 391 | 'uuid' is a hassle-free (albeit a bit ugly), solid way to refer to your 392 | disks, 'label' will use filesystem labels - which you can choose - and 393 | fallback to 'dev' if needed. 394 | 395 | When filesystems setup is complete, you can select 'Done'. At this point a 396 | check will be run which will tell you any critical errors (such as no root 397 | filesystem) and/or give you some warnings which you may ignore (like no 398 | swap). 399 | If anything is found, you can go back to fix these issues, or continue at 400 | which point everything will be setup the way you asked. 401 | 402 | For example, if you want a setup that uses LVM on top of dm_crypt, you would: 403 | 404 | * make sure that you have a 2 partitions: a small one for the unencrypted 405 | boot (about 100M) and one for the rest of the (encrypted) system. 406 | (do this in "Manually partition hard drives") 407 | * on your /dev/sdX1, make an ext2 filesystem with mountpoint /boot 408 | * on your /dev/sdX2, make a dm_crypt volume, with label sdX2crypt 409 | (or whatever you want) 410 | * /dev/mapper/sdX2crypt will appear. Put a LVM physical volume on this 411 | * /dev/mapper/sdX2crypt+ appears. This is the representation of the 412 | physical volume. Put a volumegroup on this, with label cryptpool 413 | (or whatever you want) 414 | * /dev/mapper/cryptpool appears. On this volumegroup you are able to put 415 | multiple logical volumes. Make 2: 416 | * one with size 5G: label this cryptroot 417 | * one with size 10G: label this crypthome 418 | * 2 new volumes appear: 419 | * /dev/mapper/cryptpool-cryptroot: on this blockdevice, you can put your 420 | root filesystem, with mountpoint /. 421 | * /dev/mapper/cryptpool-crypthome is the blockdevice on which you can put 422 | the filesystem with mountpoint /home. 423 | * If you want swapspace, make a logical volume for swap and put 424 | a swap volume on it. 425 | * That's it! If you select 'done' it should process the model and create 426 | your disk setup the way you specified. 427 | The cool part is that you can pick relatively small 428 | values for your volumes to start with, and if you need more space later 429 | you can grow the logical volume and the filesystem on top of it. 430 | 431 | 432 | ##### Rollbacks 433 | 434 | The rollback function will do everything necessary to "undo" changes you 435 | made in the 'Manually configure block devices, filesystems and mountpoints' 436 | or 'Autoprepare' step, to allow you completely redo your setup. 437 | 438 | It will: 439 | 440 | * unmount filesystems from the target system 441 | * destroy/undo lvm and dm_crypt volumes. 442 | 443 | It will not: 444 | 445 | * undo any partitioning 446 | * remove 'simple' filesystems such as ext3, xfs, swap etc. 447 | 448 | The reason for this is simple: only things that might disturb subsequent 449 | hard disk preparations need to be undone. 450 | 451 | #### Select Packages 452 | 453 | Select Packages will let you select the packages you wish to install from the 454 | CD, USB or your NET mirror. First, you are prompted to select a bootloader 455 | package (the bootloader will be configured later on in the "Install Bootloader" 456 | stage). After this, you can select package groups from which you'd generally 457 | like to install packages, then fine-tune your coarse selection by (de)selecting 458 | individual packages from the groups you have chosen using the space bar. It is 459 | recommended that you install all the "base" packages, but not anything else at 460 | this point. The only exception to this rule is installing any packages you need 461 | for setting up Internet connectivity. 462 | 463 | Once you're done selecting the packages you need, leave the selection screen 464 | and continue to the next step. 465 | 466 | #### Install Packages 467 | 468 | Install Packages will now install the base system and any other packages you 469 | selected with resolved dependencies onto your harddisk. 470 | 471 | #### Configure System 472 | 473 | Configure System does multiple things: 474 | 475 | * automatically preseed some configuration files (eg grub's menu.lst, 476 | mkinitcpio.conf's HOOKS, keymap settings in rc.conf, pacman mirror etc) 477 | * preseed some configuration files after you agreed. (eg network settings) 478 | * allow you to manually change important config files for your target system. 479 | * allow you to set the root password for the target. 480 | * automatically run some tools which use the updated configuration (locales, 481 | mkinitcpio, time settings, etc) 482 | 483 | **Configuration Files** 484 | 485 | These are the core configuration files for Arch Linux. 486 | If you need help configuring a specific service, please read the appropriate 487 | manpage or refer to any online documentation you need. 488 | In many cases, the Arch Linux [Wiki][46] and 489 | [forums][47] are a rich source for help as well. 490 | 491 | [46]: http://wiki.archlinux.org/ (http://wiki.archlinux.org/) 492 | 493 | [47]: http://bbs.archlinux.org/ (http://bbs.archlinux.org/) 494 | 495 | * /etc/rc.conf 496 | * [ /etc/fstab][48] 497 | * /etc/mkinitcpio.conf 498 | * /etc/modprobe.d/modprobe.conf 499 | * /etc/resolv.conf 500 | * /etc/hosts 501 | * /etc/locale.gen 502 | * /etc/pacman.d/mirrorlist 503 | * /etc/pacman.conf 504 | * /etc/crypttab 505 | 506 | [48]: http://wiki.archlinux.org/index.php/Fstab (Fstab) 507 | 508 | 509 | 510 | **/etc/rc.conf** 511 | This is the main configuration file for Arch Linux. It allows you to set your 512 | keyboard, timezone, hostname, network, daemons to run and modules to load at 513 | bootup and more. This file is properly documented (man rc.conf). 514 | AIF will automatically fill the hostname in /etc/hosts based on what you 515 | enter here. 516 | 517 | **[ /etc/fstab][50]** 518 | 519 | [50]: http://wiki.archlinux.org/index.php/Fstab (Fstab) 520 | 521 | Filesystem settings and mountpoints are configured here. The installer 522 | should have created the necessary entries. Ensure they are accurate and 523 | correct. 524 | 525 | **/etc/mkinitcpio.conf** 526 | 527 | This file allows you to fine-tune the initial ramdisk for your system. The 528 | ramdisk is a gzipped image that is read by the kernel during bootup. Its 529 | purpose is to bootstrap the system to the point where it can access the root 530 | filesystem. This means it has to load any modules that are required to "see" 531 | things like IDE, SCSI, or SATA drives (or USB/FW, if you are booting off a 532 | USB/FW drive). Once the ramdisk loads the proper modules, either manually or 533 | through udev, it passes control to the Arch system and your bootup continues. 534 | For this reason, the ramdisk only needs to contain the modules necessary to 535 | access the root filesystem. It does not need to contain every module you would 536 | ever want to use. The majority of your everyday modules will be loaded later 537 | on by udev, during the init process. 538 | 539 | By default, mkinitcpio.conf is configured to autodetect all needed modules for 540 | IDE, SCSI, or SATA systems through so-called HOOKS. The installer should 541 | also have inserted hooks like crypt, lvm, keymap and usbinput if relevant. 542 | This means the default initrd should work for almost everybody. 543 | You can edit mkinitcpio.conf and remove the subsystem HOOKS 544 | (ie, IDE, SCSI, RAID, USB, etc) that you don't need. 545 | You can customize even further by specifying the exact modules you need 546 | in the MODULES array and remove even more of the hooks, but proceed with 547 | caution. 548 | 549 | If you're using RAID on your root filesystem, the RAID settings near the 550 | bottom must be configured. See the wiki pages for 551 | RAID and mkinitcpio for more info. If you're using 552 | a non-US keyboard, you should also add the 'keymap' hook, as well as the 553 | 'usbinput' hook if you are using a USB keyboard. 554 | 555 | 556 | **/etc/modprobe.d/modprobe.conf** 557 | 558 | This tells the kernel which modules to load for system devices, and 559 | what options to set. For example, to have the kernel load the Realtek 8139 560 | ethernet module when it starts the network (ie. tries to setup eth0), use this 561 | line: 562 | 563 | 564 | alias eth0 8139too 565 | 566 | You can also use it to blacklist modules. See "man modprobe.conf" 567 | Most people will not need to edit this file. 568 | 569 | 570 | **/etc/resolv.conf** 571 | 572 | Use this file to manually setup your preferred nameserver(s). It 573 | should basically look like this: 574 | 575 | 576 | search domain.tld 577 | 578 | nameserver 192.168.0.1 579 | 580 | nameserver 192.168.0.2 581 | 582 | 583 | Replace domain.tld and the ip addresses with your settings. The so-called 584 | search domain specifies the default domain that is appended to unqualified 585 | hostnames automatically. By setting this, a ping myhost will effectively 586 | become a ping myhost.domain.tld with the above values. These settings usually 587 | aren't mighty important, though, and most people should leave them alone for 588 | now. If you use DHCP, this file will be replaced with the correct values 589 | automatically when networking is started, meaning you can and should happily 590 | ignore this file. 591 | 592 | 593 | **/etc/hosts** 594 | 595 | This is where you stick hostname/ip associations of computers on your network. 596 | If a hostname isn't known to your DNS, you can add it here to allow proper 597 | resolving, or override DNS replies. You usually don't need to change anything 598 | here, but you might want to add the hostname and hostname + domain of the 599 | local machine to this file, resolving to the IP of your network interface. 600 | Some services, postfix for example, will bomb otherwise. If you don't know 601 | what you're doing, leave this file alone until you read man hosts. 602 | 603 | 604 | **/etc/locale.gen** 605 | 606 | This file contains a list of all supported locales and charsets available to 607 | you. When choosing a LOCALE in your /etc/rc.conf or when starting a program, 608 | it is required to uncomment the respective locale in this file, to make a 609 | "compiled" version available to the system, and run the locale-gen command as 610 | root to generate all uncommented locales and put them in their place 611 | afterwards. You should uncomment all locales you intend to use. 612 | 613 | During the installation process, you do not need to run locale-gen manually, 614 | this will be taken care of automatically after saving your changes to this 615 | file. By default, all locales are enabled that would make sense by rc.conf's 616 | LOCALE= setting. To make your system work smoothly, you should edit this file 617 | and uncomment at least the one locale you're using in your rc.conf. 618 | 619 | 620 | **/etc/pacman.d/mirrorlist** 621 | 622 | This file contains a list of mirrors from which pacman will download packages 623 | for the official Arch Linux repositories. The mirrors are tried in the order 624 | in which they are listed. The $repo macro is automatically expanded by pacman 625 | depending on the repository (core, extra, community or testing). 626 | 627 | If you are performing an FTP installation, the mirror you used to download the 628 | packages from will be added on top of the mirror list, in order to be used as 629 | the default mirror in your new Arch Linux system. 630 | 631 | 632 | **/etc/pacman.conf** 633 | 634 | Here you can customize pacman settings such as which repositories to use. 635 | 636 | 637 | **/etc/crypttab** 638 | 639 | If you use encryption on a device which is not used to bring up your root, 640 | (and hence is not enabled by the encrypt hook in mkinitcpio.conf), you should 641 | configure the volume in this file. 642 | 643 | 644 | **Set Root Password** 645 | 646 | At this step, you must set the root password for your system. Choose this 647 | password carefully, preferably as a mixture of alphanumeric and special 648 | characters, since this password allows you to modify critical parts of your 649 | system. 650 | 651 | When you are done editing the configuration files choose Return to return to 652 | the main menu. The setup will regenerate the initial ramdisk to enable the 653 | changes you made in mkinitcpio.conf. 654 | 655 | #### Install Bootloader 656 | 657 | Install Bootloader will install and help you configure the bootloader that you 658 | selected in the "Select Packages" stage. 659 | 660 | 661 | An editor will open, allowing you to edit the appropriate bootloader 662 | configuration file which the installer has pre-populated. You should check and 663 | modify this file, if needed, to accommodate your boot setup. 664 | 665 | **/boot/syslinux/syslinux.cfg** (Syslinux) 666 | 667 | After checking your bootloader configuration for correctness, you'll be asked to 668 | allow the installer to Set the Boot Flag and install the Syslinux MBR. 669 | 670 | **/boot/grub/menu.lst** (Grub) 671 | 672 | After checking your bootloader configuration for correctness, you'll be 673 | prompted for a disk to install the loader to. You should install GRUB to the MBR 674 | of the installation disk. 675 | 676 | #### Exit Install 677 | 678 | You will be shown a summary of the installation, listing the steps and whether 679 | they executed successfully or not. 680 | If all went well, exit the installer, type reboot at the command line, remove 681 | your installation media and cross your fingers! 682 | 683 | 684 | ### Automatic Installation Procedure 685 | 686 | With the automatic installation procedure, you can do scripted/automatic 687 | installations. 688 | See [2.3 AIF, the installation tool](#Aif_the_installation_tool) 689 | In /usr/share/aif/examples you will find example profiles which will need 690 | no or minimal editing in order to install a system: 691 | 692 | * generic-install-on-sda 693 | this file demonstrates some things you can do (adding custom packages, 694 | setting timezone, update config files etc) 695 | it sets up a simple installation (with a structure similar to what you get 696 | with Auto-prepare) on /dev/sda 697 | * fancy-install-on-sda 698 | very similar to generic-install-on-sda, 699 | but sets up a "filesystems on lvm on dm_crypt" system on /dev/sda 700 | 701 | Note that these files are plain bash files, so if you want to define for 702 | example `SYNC_URL` it must be singlequoted to prevent bash expanding `$repo` 703 | 704 | Invoke as `aif -p automatic -c /path/to/configfile` 705 | Obviously, don't forget to change the hard disk names unless you want 706 | to use /dev/sda. 707 | 708 | #### Config file syntax 709 | 710 | Config files will be sourced by the bash shell, so they need to be valid 711 | bash code. 712 | 713 | **PARTITIONS:** Allows you to define partitions for your hard disk, 714 | separated by spaces. 715 | 716 | * first comes the device file for the hard disk 717 | * then for each partition you want: size in MiB (or '*' for all remaining 718 | space),filesystem type and optionally a '+' to toggle the bootable flag. 719 | separated by colons (':') 720 | 721 | **BLOCKDATA:** In this multi-line variable you can describe for each 722 | partition you'll have how it should be used. Study the examples to see how 723 | it works. 724 | 725 | ### Customizing Installations 726 | 727 | You can also customize your installation experience by writing new 728 | procedures (possibly inheriting from current procedures) or config files for 729 | procedures that support it (eg automatic). 730 | You have all the aif libraries at your disposal and you can create new 731 | libraries. (see /usr/lib/aif) 732 | This is a moving target, so consult the AIF readme for more information. 733 | 734 | 735 | # Your new system 736 | If all went well, you can reboot your system (make sure you don't boot again 737 | from the same USB disk or CD-ROM drive) and your new system will boot. 738 | 739 | You'll notice that in the early userspace (the part that comes after the 740 | bootloader) the hooks (as defined in mkinitcpio.conf) needed to get your root 741 | filesystem are run. 742 | If you have lvm, it will run the lvm hook. If you use encryption, it will 743 | run the keymap and encrypt hooks so you can enter your password to decrypt the 744 | volume. 745 | 746 | Once the system is booted, login as root. By default the password is empty 747 | but in the interactive procedure you can change it. 748 | 749 | # More information 750 | ## Package Management 751 | 752 | Pacman is the package manager which tracks all the software installed on your 753 | system. It has simple dependency support and uses the standard gzipped tar 754 | archive format for all packages. Some common tasks you might need to use 755 | during installation, are explained below with their respective commands. For 756 | an extensive explanation of pacman's options, read man pacman or consult the 757 | Arch Linux [Wiki][51]. 758 | 759 | [51]: http://wiki.archlinux.org/index.php/Pacman 760 | (http://wiki.archlinux.org/index.php/Pacman) 761 | 762 | 763 | **Typical tasks:** 764 | 765 | * Refreshing the package list 766 | 767 | 768 | # pacman --sync --refresh 769 | 770 | # pacman -Sy 771 | 772 | 773 | This will retrieve a fresh master package list from the repositories defined 774 | in the /etc/pacman.conf file and decompress it into the database area. 775 | 776 | * Search the repositories for a package 777 | 778 | 779 | # pacman --sync --search 780 | 781 | # pacman -Ss 782 | 783 | 784 | Search each package in the sync databases for names or descriptions that match 785 | regexp. 786 | 787 | * Display specific package info from the repository database 788 | 789 | 790 | # pacman --sync --info foo 791 | 792 | # pacman -Si foo 793 | 794 | 795 | Displays information from the repository database on package foo (size, 796 | build date, dependencies, conflicts, etc.) 797 | 798 | * Adding a package from the repositories 799 | 800 | 801 | # pacman --sync foo 802 | 803 | # pacman -S foo 804 | 805 | 806 | Retrieve and install package foo, complete with all dependencies it requires. 807 | Before using any sync option, make sure you refreshed the package list. 808 | 809 | * List installed packages 810 | 811 | 812 | # pacman --query 813 | 814 | # pacman -Q 815 | 816 | 817 | Displays a list of all installed packages in the system. 818 | 819 | * Check if a specific package is installed 820 | 821 | 822 | # pacman --query foo 823 | 824 | # pacman -Q foo 825 | 826 | 827 | This command will display the name and version of the foo package if it is 828 | installed, nothing otherwise. 829 | 830 | * Display specific package info 831 | 832 | 833 | # pacman --query --info foo 834 | 835 | # pacman -Qi foo 836 | 837 | 838 | Displays information on the installed package foo (size, install date, build 839 | date, dependencies, conflicts, etc.) 840 | 841 | * Display list of files contained in package 842 | 843 | 844 | # pacman --query --list foo 845 | 846 | # pacman -Ql foo 847 | 848 | 849 | Lists all files belonging to package foo. 850 | 851 | * Find out which package a specific file belongs to 852 | 853 | 854 | # pacman --query --owns /path/to/file 855 | 856 | # pacman -Qo /path/to/file 857 | 858 | 859 | This query displays the name and version of the package which contains the 860 | file referenced by its full path as a parameter. 861 | 862 | ## APPENDIX 863 | 864 | See [General Recommendations](https://wiki.archlinux.org/index.php/General_Recommendations) 865 | for some related unofficial documentation, new users may find useful. 866 | -------------------------------------------------------------------------------- /examples/fancy-install-on-sda: -------------------------------------------------------------------------------- 1 | # this config is like generic-install-on-sda (check out that file first), but more fancy 2 | 3 | if [ -d /repo/core ]; then 4 | TARGET_REPOSITORIES=(core 'file:///repo/$repo/$arch') 5 | else 6 | MIRROR='ftp://mirrors.kernel.org/archlinux/$repo/os/$arch' 7 | TARGET_REPOSITORIES=(core $var_MIRRORLIST) 8 | fi 9 | 10 | 11 | RUNTIME_REPOSITORIES= 12 | RUNTIME_PACKAGES= 13 | 14 | # packages to install 15 | TARGET_GROUPS=base 16 | TARGET_PACKAGES_EXCLUDE='reiserfsprogs' 17 | TARGET_PACKAGES='openssh e2fsprogs cryptsetup lvm2 xfsprogs' 18 | 19 | # you can optionally also override some functions... 20 | worker_intro () { 21 | inform "Automatic procedure running the fancy-install-on-sda example config. this will install a system with lvm on top of dm_crypt. THIS WILL ERASE AND OVERWRITE YOUR /DEV/SDA. IF YOU DO NOT WANT THIS PRESS CTRL+C WITHIN 10 SECONDS" 22 | sleep 10 23 | } 24 | 25 | worker_configure_system () { 26 | preconfigure_target 27 | sed -i 's/^HOSTNAME="myhost"/HOSTNAME="arch-fancy-install"/' $var_TARGET_DIR/etc/rc.conf 28 | postconfigure_target 29 | } 30 | 31 | PART_ACCESS= 32 | 33 | # These variables are mandatory 34 | 35 | PARTITIONS='/dev/sda 100:ext2:+ *:ext4' 36 | BLOCKDATA='/dev/sda1 raw no_label ext2;yes;/boot;target;no_opts;no_label;no_params 37 | /dev/sda2 raw no_label dm_crypt;yes;no_mountpoint;target;no_opts;sda2crypt;-c__aes-xts-plain__-y__-s__512 38 | /dev/mapper/sda2crypt dm_crypt no_label lvm-pv;yes;no_mountpoint;target;no_opts;no_label;no_params 39 | /dev/mapper/sda2crypt+ lvm-pv no_label lvm-vg;yes;no_mountpoint;target;no_opts;cryptpool;/dev/mapper/sda2crypt 40 | /dev/mapper/cryptpool lvm-vg cryptpool lvm-lv;yes;no_mountpoint;target;no_opts;cryptswap;1G|lvm-lv;yes;no_mountpoint;target;no_opts;cryptroot;5G|lvm-lv;yes;no_mountpoint;target;no_opts;crypthome;5G 41 | /dev/mapper/cryptpool-cryptswap lvm-lv no_label swap;yes;no_mountpoint;target;no_opts;no_label;no_params 42 | /dev/mapper/cryptpool-cryptroot lvm-lv no_label xfs;yes;/;target;no_opts;no_label;no_params 43 | /dev/mapper/cryptpool-crypthome lvm-lv no_label xfs;yes;/home;target;no_opts;no_label;no_params' 44 | -------------------------------------------------------------------------------- /examples/generic-install-on-sda: -------------------------------------------------------------------------------- 1 | # this config explains the (all) available options. 2 | # the variables are optional and we define their defaults here (so you could omit the 3 | # definitions), unless otherwise specified. 4 | 5 | # Add all repositories you want to use here. Same style as for pacman.conf: 6 | # Local: file://... 7 | # Remote: something like ftp://ftp.belnet.be/mirror/archlinux.org/$repo/os/$arch 8 | # You should list both the name of the repo as well as the location, as separate 9 | # elements. 10 | # You can add multiple repositories and even mix remote and local ones. 11 | # The order they are in here, will be the order in pacman.conf 12 | # This is a mandatory variable, which should contain at least 1 core repository 13 | # This example will do the most sensible thing on both core and netinstall images: 14 | if [ -d /repo/core ]; then 15 | TARGET_REPOSITORIES=(core 'file:///repo/$repo/$arch') 16 | else 17 | MIRROR='ftp://mirrors.kernel.org/archlinux/$repo/os/$arch' 18 | TARGET_REPOSITORIES=(core $var_MIRRORLIST) # $var_MIRRORLIST is set by AIF 19 | fi 20 | 21 | HARDWARECLOCK=localtime # UTC is the better option, but some OS'es don't support it (i.e. Windows) 22 | TIMEZONE=Canada/Pacific 23 | # Do you want to have additional pacman repositories or packages available at runtime (during installation)? 24 | # RUNTIME_REPOSITORIES same format as TARGET_REPOSITORIES 25 | RUNTIME_REPOSITORIES= 26 | # space separated list 27 | RUNTIME_PACKAGES= 28 | 29 | # packages to install 30 | TARGET_GROUPS=base # all packages in this group will be installed (defaults to base if no group and no packages are specified) 31 | TARGET_PACKAGES_EXCLUDE= # Exclude these packages if they are member of one of the groups in TARGET_GROUPS. example: 'nano reiserfsprogs' (they are in base) 32 | TARGET_PACKAGES='openssh e2fsprogs' # you can also specify separate packages to install (this is empty by default) 33 | 34 | # you can optionally also override some functions... 35 | # This way you can change/extend/remove pretty much all functionality in AIF ! 36 | worker_intro () { 37 | inform "Automatic procedure running the generic-install-on-sda example config. THIS WILL ERASE AND OVERWRITE YOUR /DEV/SDA. IF YOU DO NOT WANT THIS PRESS CTRL+C WITHIN 10 SECONDS" 38 | sleep 10 39 | } 40 | 41 | worker_configure_system () { 42 | preconfigure_target 43 | sed -i 's/^HOSTNAME="myhost"/HOSTNAME="arch-generic-install"/' $var_TARGET_DIR/etc/rc.conf 44 | postconfigure_target 45 | } 46 | 47 | PART_ACCESS= # can be set to 'uuid', 'dev', 'label', or leave empty for 'dev' 48 | 49 | # These variables are mandatory 50 | 51 | # '*' means all the remaining space 52 | # '+' means the bootable flag 53 | PARTITIONS='/dev/sda 100:ext2:+ 512:swap *:ext4' 54 | # if you wanted everything other than swap and boot on an extended partition, you can do like this: 55 | # PARTITIONS='/dev/sda 100:ext2:+ 512:swap :extended *:ext4' 56 | 57 | BLOCKDATA='/dev/sda1 raw no_label ext2;yes;/boot;target;no_opts;no_label;no_params 58 | /dev/sda2 raw no_label swap;yes;no_mountpoint;target;no_opts;no_label;no_params 59 | /dev/sda3 raw no_label ext4;yes;/;target;no_opts;no_label;no_params' 60 | -------------------------------------------------------------------------------- /examples/simple-lvm-install-on-sda: -------------------------------------------------------------------------------- 1 | # this config is like generic-install-on-sda (check out that file first), but installs a very simple LVM setup 2 | 3 | if [ -d /repo/core ]; then 4 | TARGET_REPOSITORIES=(core 'file:///repo/$repo/$arch') 5 | else 6 | MIRROR='ftp://mirrors.kernel.org/archlinux/$repo/os/$arch' 7 | TARGET_REPOSITORIES=(core $var_MIRRORLIST) 8 | fi 9 | 10 | 11 | RUNTIME_REPOSITORIES= 12 | RUNTIME_PACKAGES= 13 | 14 | # packages to install 15 | TARGET_GROUPS=base 16 | TARGET_PACKAGES_EXCLUDE='reiserfsprogs' 17 | TARGET_PACKAGES='openssh e2fsprogs lvm2 xfsprogs' 18 | 19 | # you can optionally also override some functions... 20 | worker_intro () { 21 | inform "Automatic procedure running the simple-lvm-install-on-sda example config. this will install an LVM system. THIS WILL ERASE AND OVERWRITE YOUR /DEV/SDA. IF YOU DO NOT WANT THIS PRESS CTRL+C WITHIN 10 SECONDS" 22 | sleep 10 23 | } 24 | 25 | worker_configure_system () { 26 | preconfigure_target 27 | sed -i 's/^HOSTNAME="myhost"/HOSTNAME="arch-simple-lvm-install"/' $var_TARGET_DIR/etc/rc.conf 28 | postconfigure_target 29 | } 30 | 31 | PART_ACCESS= 32 | 33 | 34 | # very simple LVM setup: 35 | # sda1 gets an 100MB ext2 for /boot 36 | # sda2 becomes a PV, which hosts a VG named 'myvg', which hosts 1 5GB LV named myroot, which gets an ext4 mounted at / 37 | # These variables are mandatory 38 | GRUB_DEVICE=/dev/sda 39 | PARTITIONS='/dev/sda 100:ext2:+ *:ext4' 40 | BLOCKDATA='/dev/sda1 raw no_label ext2;yes;/boot;target;no_opts;no_label;no_params 41 | /dev/sda2 raw no_label lvm-pv;yes;no_mountpoint;target;no_opts;no_label;no_params 42 | /dev/sda2+ lvm-pv no_label lvm-vg;yes;no_mountpoint;target;no_opts;myvg;/dev/sda2 43 | /dev/mapper/myvg lvm-vg myvg lvm-lv;yes;no_mountpoint;target;no_opts;myroot;5G 44 | /dev/mapper/myvg-myroot lvm-lv no_label ext4;yes;/;target;no_opts;no_label;no_params' 45 | -------------------------------------------------------------------------------- /make-doc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | which markdown &>/dev/null || echo "Need markdown utility!" >&2 3 | 4 | echo "generating html..." 5 | for i in doc/official_installation_guide_?? 6 | do 7 | echo $i 8 | # convert markdown to html, convert html links to wiki ones. 9 | cat $i | markdown | sed 's|]*>\([^<]*\)|[\1 \2]|g' > $i.html 10 | # turn code markup into a syntax that mediawiki understands 11 | sed -i 's#
#
#g' $i.html
12 | 	sed -i 's#
#
#g' $i.html 13 | 14 | done 15 | 16 | echo "adding special wiki thingies..." 17 | 18 | i=doc/official_installation_guide_en 19 | echo $i 20 | 21 | 22 | summary_begin='

Article summary<\/strong><\/p>' 23 | summary_end_plus_one='

Related articles<\/strong><\/p>' 24 | related_begin='

Related articles<\/strong><\/p>' 25 | related_end_plus_one='

Introduction<\/h1>' 26 | 27 | summary=`sed -n "/$summary_begin/, /$summary_end_plus_one/p;" $i.html | sed "/$summary_begin/d; /$summary_end_plus_one/d"` 28 | related=`sed -n "/$related_begin/, /$related_end_plus_one/p;" $i.html | sed "/$related_begin/d; /$related_end_plus_one/d"` 29 | 30 | # prepare $related for wikiing. 31 | # note that like this we always keep the absulolute url's even if they are on the same subdomain eg: {{Article summary wiki|http://foo/bar bar}} (note). 32 | # wiki renders absolute url a bit uglier. always having absolute url's is not needed if the page can be looked up on the same wiki, but like this it was simplest to implement.. 33 | related=`echo "$related"| sed -e 's#

\[\(.*\)\] \(.*\)<\/p>#{{Article summary wiki|\1}} \2#'` 34 | 35 | # preare $summary for wiiking: replace email address by nice mailto links 36 | summary=`echo "$summary" | sed 's/\([^"|, ]*@[-A-Za-z0-9_.]*\)/[mailto:\1 \1]/'` 37 | 38 | 39 | echo -e "[[Category:Getting and installing Arch (English)]]\n[[Category:HOWTOs (English)]] 40 | [[Category:Accessibility (English)]] 41 | [[Category:Website Resources]] 42 | {{Article summary start}}\n{{Article summary text| 1=$summary}}\n{{Article summary heading|Available Languages}}\n 43 | {{i18n_entry|English|Official Arch Linux Install Guide}}\n 44 | {{Article summary heading|Related articles}} 45 | $related 46 | {{Article summary end}}" | cat - $i.html > $i.html.tmp && mv $i.html.tmp $i.html 47 | 48 | # remove summary and related articles from actual content 49 | sed "/$summary_end_plus_one/p; /$summary_begin/, /$summary_end_plus_one/d" $i.html > $i.html.tmp && mv $i.html.tmp $i.html 50 | sed "/$related_end_plus_one/p; /$related_begin/, /$related_end_plus_one/d" $i.html > $i.html.tmp && mv $i.html.tmp $i.html 51 | -------------------------------------------------------------------------------- /src/aif-report-issues.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | RUNTIME_DIR=/tmp/aif 3 | LOG_DIR=/var/log/aif 4 | source /usr/lib/libui.sh 5 | cat - </dev/null 13 | ls -lh $LOG_DIR/* 2>/dev/null 14 | if ! ping -c 1 sprunge.us >/dev/null 15 | then 16 | msg="Please setup your networking using one of 17 | * dhcpcd eth0 # or whatever your interface is 18 | * aif -p partial-configure-network 19 | 20 | If your networking works fine and you think sprunge.us is down, please upload the files to another pastebin" 21 | show_warning "Connection error" "Cannot ping sprunge.us (pastebin server). $msg" 22 | die_error "cannot reach pastebin" 23 | fi 24 | report="Uploaded data:" 25 | if ask_yesno "Send these files?" 26 | then 27 | shopt -s nullglob 28 | for i in $RUNTIME_DIR/* $LOG_DIR/* 29 | do 30 | bin=$(cat $i | curl -sF 'sprunge=<-' http://sprunge.us) 31 | bin=${bin/ /} # for some reason there is a space in the beginning 32 | report="$report\n$i $bin" 33 | done 34 | shopt -u nullglob 35 | fi 36 | 37 | echo "It can also be useful to upload a list of currently mounted filesystems:" 38 | df -hT 39 | if ask_yesno "Is this ok?" 40 | then 41 | bin=$(df -hT | curl -sF 'sprunge=<-' http://sprunge.us) 42 | bin=${bin/ /} 43 | report="$report\ndf -hT $bin" 44 | fi 45 | echo -e "$report" 46 | echo "For your convenience, I will paste the report online" 47 | echo "So you just need to give the following url:" 48 | echo -e "$report" | curl -sF 'sprunge=<-' http://sprunge.us 49 | -------------------------------------------------------------------------------- /src/aif-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # make sure you install aif onto the target system so you can use its testing libraries 4 | 5 | echo "Aif-test: a 'unit-testing' tool for AIF" 6 | echo " for a list of available tests: ls -l /usr/share/aif/tests/runtime" 7 | [ "$1" != runtime ] && echo "\$1: type of test to execute (runtime. no support for buildtime yet)" >&2 && exit 1 8 | [ -z "$2" ] && echo "\$2: name of test to execute" >&2 && exit 1 9 | 10 | test_dir="/usr/share/aif/tests/$1/$2" 11 | 12 | [ ! -d "$test_dir" ] && echo "No such test found: $test_dir" >&2 && exit 2 13 | 14 | echo "Running test $test_dir. THIS WILL PROBABLY ERASE DATA ON ONE OR MORE OF YOUR HARD DISKS. TO ABORT PRESS CTRL-C WITHIN 10 SECONDS" 15 | sleep 10 16 | 17 | # this script should install the system 18 | $test_dir/install.sh || fail=1 19 | 20 | # this script does any additional things such as touching files that we should recognize later 21 | $test_dir/setup_test.sh || fail=1 22 | 23 | # this script will do the actual testing (network check, recognize filesystems and files, ..) 24 | cp $test_dir/perform_test.sh /mnt/etc/rc.d/perform_test || fail=1 25 | 26 | # make sure the test will run on the target system 27 | sed -i 's#^DAEMONS=(\(.*\))#DAEMONS=(\1 perform_test)#' /mnt/etc/rc.conf || fail=1 28 | 29 | # and that /etc/issue won't blank the screen 30 | sed -i 's/^H//' /mnt/etc/issue 31 | 32 | [ "$fail" == '1' ] && echo "Something failed. will not reboot" >&2 && exit 3 33 | 34 | reboot 35 | -------------------------------------------------------------------------------- /src/aif.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | ###### Set some default variables ###### 5 | TITLE="Arch Linux Installation Framework" 6 | LOG="/dev/tty7" 7 | LIB_CORE=/usr/lib/aif/core 8 | LIB_USER=/usr/lib/aif/user 9 | RUNTIME_DIR=/tmp/aif 10 | LOG_DIR=/var/log/aif 11 | LOGFILE=$LOG_DIR/aif.log 12 | DISCLAIMER="Note that despite our careful coding and proper testing there may still be bugs in this software.\n 13 | When you are doing this installation on a system where some data must be preserved, we suggest you make a backup first" 14 | export LC_COLLATE=C # for consistent sorting behavior 15 | shopt -s extglob # used in find_usable_blockdevices() and useful in general. (shopt statement cannot be put inside function) 16 | 17 | ###### Early bootstrap ###### 18 | 19 | # load the lib-ui, it is one we need everywhere so we must load it early. 20 | source $LIB_CORE/libs/lib-ui.sh || { echo "Something went wrong while sourcing library $LIB_CORE/libs/lib-ui.sh" >&2 ; exit 2; } 21 | ui_init 22 | # load the lib-flowcontrol. we also need some of it's functions early (like usage()). 23 | source $LIB_CORE/libs/lib-flowcontrol.sh || { echo "Something went wrong while sourcing library $LIB_CORE/libs/lib-flowcontrol.sh" >&2 ; exit 2; } 24 | # lib-misc. we need it early, at least for check_is_in whis is used by the debug function. 25 | source $LIB_CORE/libs/lib-misc.sh || { echo "Something went wrong while sourcing library $LIB_CORE/libs/lib-misc.sh" >&2 ; exit 2; } 26 | 27 | # default function to process additional arguments. can be overridden by procedures. 28 | process_args () 29 | { 30 | true 31 | } 32 | 33 | 34 | 35 | 36 | ###### perform actual logic ###### 37 | echo "Welcome to $TITLE" 38 | 39 | [[ $EUID -ne 0 ]] && die_error "You must have root privileges to run AIF" 40 | 41 | mount -o remount,rw / &>/dev/null 42 | cleanup_runtime 43 | needed_pkgs_fs= # will hold extra needed packages for blockdevices/filesystems, populated when the Fs'es are created 44 | 45 | ### Set configuration values ### 46 | # note : you're free to use or ignore these in your procedure. probably you want to use these variables to override defaults in your configure worker 47 | 48 | #DEBUG: don't touch it. it can be set in the env 49 | arg_ui_type= 50 | LOG_TO_FILE=0 51 | module= 52 | procedure= 53 | 54 | 55 | 56 | # in that case -p needs to be the first option, but that's doable imho 57 | # an alternative would be to provide an argumentstring for the profile. eg aif -p profile -a "-a a -b b -c c" 58 | 59 | # you can override these variables in your procedures 60 | var_OPTS_STRING="" 61 | var_ARGS_USAGE="" 62 | 63 | # Processes args that were not already matched by the basic rules. 64 | process_args () 65 | { 66 | # known options: we don't know any yet 67 | # return 0 68 | 69 | # if we are still here, we didn't return 0 for a known option. hence this is an unknown option 70 | usage 71 | exit 5 72 | } 73 | 74 | 75 | # Check if the first args are -p . If so, we can load the procedure, and hence $var_OPTS_STRING and process_args can be overridden 76 | if [ "$1" = '-p' ] 77 | then 78 | [ -z "$2" ] && usage && exit 1 79 | # note that we allow procedures like http://foo/bar. module -> http:, procedure -> http://foo/bar. 80 | if [[ $2 =~ ^http:// ]] 81 | then 82 | module=http 83 | procedure="$2" 84 | elif grep -q '\/' <<< "$2" 85 | then 86 | #user specified module/procedure 87 | module=`dirname "$2"` 88 | procedure=`basename "$2"` 89 | else 90 | module=core 91 | procedure="$2" 92 | fi 93 | 94 | shift 2 95 | fi 96 | 97 | # If no procedure given, bail out 98 | [ -z "$procedure" ] && usage && exit 5 99 | 100 | load_module core 101 | [ "$module" != core -a "$module" != http ] && load_module "$module" 102 | # this is a workaround for bash <4.2, where associative arrays are inherently local, 103 | # so we must source these variables in the main scope 104 | source $LIB_CORE/libs/lib-blockdevices-filesystems.sh 105 | 106 | load_procedure "$module" "$procedure" 107 | 108 | while getopts ":i:dlp:$var_OPTS_STRING" OPTION 109 | do 110 | case $OPTION in 111 | i) 112 | [ -z "$OPTARG" ] && usage && exit 1 #TODO: check if it's necessary to do this. the ':' in $var_OPTS_STRING might be enough 113 | [ "$OPTARG" != cli -a "$OPTARG" = !dia ] && die_error "-i must be dia or cli" 114 | arg_ui_type=$OPTARG 115 | ui_init 116 | ;; 117 | d) 118 | export DEBUG=1 119 | LOG_TO_FILE=1 120 | ;; 121 | l) 122 | LOG_TO_FILE=1 123 | ;; 124 | p) 125 | die_error "If you pass -p , it must be the FIRST option" 126 | ;; 127 | h) 128 | usage 129 | exit 130 | ;; 131 | ?) 132 | # If we hit something elso, call process_args 133 | process_args -$OPTION $OPTARG # you can override this function in your profile to parse additional arguments and/or override the behavior above 134 | ;; 135 | esac 136 | 137 | done 138 | 139 | 140 | # Set pacman vars. allow procedures to have set $var_TARGET_DIR (TODO: look up how delayed variable substitution works. then we can put this at the top again) 141 | # flags like --noconfirm should not be specified here. it's up to the procedure to decide the interactivity 142 | # NOTE: Pacman will run with currently active locale, if you want to parse output, you should prefix with LANG=C 143 | PACMAN=pacman 144 | PACMAN_TARGET="pacman --root $var_TARGET_DIR --config /tmp/pacman.conf" 145 | 146 | start_installer 147 | 148 | start_process 149 | 150 | stop_installer $? 151 | -------------------------------------------------------------------------------- /src/core/libs/lib-blockdevices-filesystems.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # FORMAT DEFINITIONS: 4 | 5 | # -- formats used to interface with this library -- 6 | # these files will persist during the entire aif session (and even after stopping aif) 7 | # so you can use them to retrieve data from them (or use functions in this library to do that for you) 8 | # $TMP_PARTITIONS 9 | # one line per partition, blockdevice + partioning string for sfdisk. See docs for function partition for more info. 10 | # $TMP_BLOCKDEVICES 11 | # one line per blockdevice, multiple fs'es in 1 'fs-string' 12 | # $TMP_BLOCKDEVICES entry. 13 | # type label/no_label /no_fs 14 | # FS-string: 15 | # type;recreate(yes/no);mountpoint;mount?(target,runtime,no);opts;label;params[|FS-string|...] where opts/params have _'s instead of whitespace if needed 16 | # NOTE: the 'mount?' for now just matters for the location (if 'target', the target path gets prepended and mounted in the runtime system) 17 | # NOTE: filesystems that span multiple underlying filesystems/devices (eg lvm VG) should specify those in params, separated by colons. \ 18 | # the in the beginning doesn't matter much, it can be pretty much any device, or not existent, i think. But it's probably best to make it one of the devices listed in params 19 | # no '+' characters allowed for devices in $fs_params (eg use the real names) 20 | # NOTE: if you want spaces in params or opts, you must "encode" them by replacing them with 2 underscores. 21 | 22 | # -- ADDITIONAL INTERNAL FORMATS -- 23 | # $TMP_FILESYSTEMS: each filesystem on a separate line, so block devices can appear multiple times be on multiple lines (eg LVM volumegroups with more lvm LV's) 24 | # uses spaces for separation (so you can easily do 'while.. read' loops. so fs_params and fs_opts are encoded here also 25 | # part part_type part_label fs_type fs_create fs_mountpoint fs_mount fs_opts fs_label fs_params 26 | 27 | 28 | 29 | modprobe -q dm-crypt || show_warning modprobe 'Could not modprobe dm-crypt. no support for disk encryption' 30 | modprobe -q aes-i586 || modprobe -q aes-x86-64 || show_warning modprobe 'Could not modprobe aes-i586 or aes-x86-64. no support for disk encryption' 31 | 32 | TMP_DEV_MAP=$RUNTIME_DIR/aif-dev.map 33 | TMP_FSTAB=$RUNTIME_DIR/aif-fstab 34 | TMP_PARTITIONS=$RUNTIME_DIR/aif-partitions 35 | TMP_FILESYSTEMS=$RUNTIME_DIR/aif-filesystems # Only used internally by this library. Do not even think about using this as interface to this library. it won't work 36 | TMP_BLOCKDEVICES=$RUNTIME_DIR/aif-blockdata 37 | 38 | declare -A filesystem_programs=(["swap"]="mkswap" ["reiserfs"]="mkreiserfs" ["lvm-pv"]="pvcreate" ["lvm-vg"]="vgcreate" ["lvm-lv"]="lvcreate" ["dm_crypt"]="cryptsetup") 39 | for simple in ext2 ext3 ext4 nilfs2 xfs jfs vfat btrfs 40 | do 41 | filesystem_programs+=([$simple]=mkfs.$simple) 42 | done 43 | 44 | declare -A label_programs=(["swap"]="swaplabel" ["xfs"]="xfs_admin" ["jfs"]="jfs_tune" ["reiserfs"]="reiserfstune" ["nilfs2"]="nilfs-tune" ["vfat"]="dosfslabel") 45 | for ext in ext2 ext3 ext4 46 | do 47 | label_programs+=([$ext]=tune2fs) 48 | done 49 | 50 | # names for filesystems (which are shown to users in dialogs etc, don't use spaces!) 51 | declare -A filesystem_names=(["nilfs2"]="Nilfs2 (EXPERIMENTAL)" ["btrfs"]="Btrfs (EXPERIMENTAL)" ["vfat"]="vFat" ["dm_crypt"]="dm_crypt (LUKS)" ["lvm-pv"]="lvm Physical Volume" ["lvm-vg"]="lvm Volume Group" ["lvm-lv"]="lvm Logical Volume") 52 | for i in ext2 ext3 ext4 reiserfs xfs jfs swap 53 | do 54 | name=$(echo $i | capitalize) 55 | filesystem_names+=([$i]=$name) 56 | done 57 | 58 | # specify which filesystems can be stored on which blockdevices 59 | fs_on_raw=(swap ext2 ext3 ext4 reiserfs nilfs2 xfs jfs vfat dm_crypt lvm-pv btrfs) 60 | fs_on_lvm_lv=(swap ext2 ext3 ext4 reiserfs nilfs2 xfs jfs vfat dm_crypt btrfs) 61 | fs_on_dm_crypt=(swap ext2 ext3 ext4 reiserfs nilfs2 xfs jfs vfat lvm-pv btrfs) 62 | fs_on_lvm_pv=(lvm-vg) 63 | fs_on_lvm_vg=(lvm-lv) 64 | 65 | # the following is useful to do checks like check_is_in $fs_type ${fs_on[$part_type]} (or iterate it) 66 | # bash does not allow lists (array) in associative arrays, but this seems to work. 67 | # maybe it stores them as strings, which in this case is ok (no spaces in elements) 68 | declare -A fs_on 69 | fs_on[raw]=${fs_on_raw[@]} 70 | fs_on[lvm-lv]=${fs_on_lvm_lv[@]} 71 | fs_on[lvm-pv]=${fs_on_lvm_pv[@]} 72 | fs_on[lvm-vg]=${fs_on_lvm_vg[@]} 73 | fs_on[dm_crypt]=${fs_on_dm_crypt[@]} 74 | 75 | fs_mountable=(btrfs ext2 ext3 ext4 nilfs2 xfs jfs vfat reiserfs) 76 | fs_label_mandatory=('lvm-vg' 'lvm-lv' 'dm_crypt') 77 | fs_label_optional=('swap' 'ext2' 'ext3' 'ext4' 'reiserfs' 'nilfs2' 'xfs' 'jfs' 'vfat') 78 | 79 | # list needed packages per filesystem 80 | declare -A filesystem_pkg=(["lvm-pv"]="lvm2" ["xfs"]="xfsprogs" ["jfs"]="jfsutils" ["reiserfs"]="reiserfsprogs" ["nilfs2"]="nilfs-utils" ["vfat"]="dosfstools" ["dm_crypt"]="cryptsetup" ["btrfs"]=btrfs-progs-unstable) 81 | for i in ext2 ext3 ext4 82 | do 83 | filesystem_pkg+=([$i]=e2fsprogs) 84 | done 85 | 86 | # returns which filesystems you can create based on the locally available utilities 87 | get_possible_fs () { 88 | possible_fs= 89 | local fs 90 | for fs in "${!filesystem_programs[@]}" 91 | do 92 | which ${filesystem_programs[$fs]} &>/dev/null && possible_fs=("${possible_fs[@]}" $fs) 93 | done 94 | true 95 | } 96 | 97 | syslinux_supported_fs=('ext2' 'ext3' 'ext4' 'btrfs' 'vfat') 98 | supported_bootloaders=('syslinux') 99 | 100 | # procedural code from quickinst functionized and fixed. 101 | # there were functions like this in the setup script too, with some subtle differences. see below 102 | # NOTE: why were the functions in the setup called CHROOT_mount/umount? this is not chrooting ? ASKDEV 103 | target_special_fs () 104 | { 105 | [ "$1" = on -o "$1" = off ] || die_error "special_fs needs on/off argument" 106 | if [ "$1" = on ] 107 | then 108 | # mount proc/sysfs first, so mkinitrd can use auto-detection if it wants 109 | ! [ -d $var_TARGET_DIR/proc ] && mkdir $var_TARGET_DIR/proc 110 | ! [ -d $var_TARGET_DIR/sys ] && mkdir $var_TARGET_DIR/sys 111 | ! [ -d $var_TARGET_DIR/dev ] && mkdir $var_TARGET_DIR/dev 112 | #mount, if not mounted yet 113 | mount | grep -q "$var_TARGET_DIR/proc" || mount -t proc proc $var_TARGET_DIR/proc || die_error "Could not mount $var_TARGET_DIR/proc" 114 | mount | grep -q "$var_TARGET_DIR/sys" || mount -t sysfs sysfs $var_TARGET_DIR/sys || die_error "Could not mount $var_TARGET_DIR/sys" 115 | mount | grep -q "$var_TARGET_DIR/dev" || mount -o bind /dev $var_TARGET_DIR/dev || die_error "Could not mount $var_TARGET_DIR/dev" 116 | elif [ "$1" = off ] 117 | then 118 | umount $var_TARGET_DIR/proc || die_error "Could not umount $var_TARGET_DIR/proc" 119 | umount $var_TARGET_DIR/sys || die_error "Could not umount $var_TARGET_DIR/sys" 120 | umount $var_TARGET_DIR/dev || die_error "Could not umount $var_TARGET_DIR/dev" 121 | fi 122 | } 123 | 124 | 125 | # taken from setup #TODO: we should be able to not need this function. although it may still be useful. but maybe we shouldn't tie it to $var_TARGET_DIR, and let the user specify the base point as $1 126 | # Disable swap and umount all mounted filesystems for the target system in the correct order. (eg first $var_TARGET_DIR/a/b/c, then $var_TARGET_DIR/a/b, then $var_TARGET_DIR/a until lastly $var_TARGET_DIR 127 | target_umountall() 128 | { 129 | inform "Disabling all swapspace..." disks 130 | swapoff -a >/dev/null 2>&1 131 | declare target=${var_TARGET_DIR//\//\\/} # escape all slashes otherwise awk complains 132 | for mountpoint in $(mount | awk "/\/$target/ {print \$3}" | sort | tac ) 133 | do 134 | inform "Unmounting mountpoint $mountpoint" disks 135 | umount $mountpoint >/dev/null 2>$LOG 136 | done 137 | } 138 | 139 | # tells you which blockdevice is configured for the specific mountpoint 140 | # $1 mountpoint 141 | get_device_with_mount () { 142 | ANSWER_DEVICE=`grep ";$1;" $TMP_BLOCKDEVICES 2>/dev/null | cut -d ' ' -f1` 143 | [ -n "$ANSWER_DEVICE" ] # set correct exit code 144 | } 145 | 146 | # gives you a newline separated list of the blockdevice that hosts a certain filesystem, and below it, all underlying blockdevices supporting it, with also the blockdevice type. 147 | # example: 148 | # get_anchestors_mount ';/;' (suppose '/' is a filesystem on top of lvm on top of dm_crypt, you will get something like): 149 | # /dev/cryptpool/cryptroot lvm-lv 150 | # /dev/mapper/cryptpool lvm-vg 151 | # /dev/mapper/sda2crypt+ lvm-pv 152 | # /dev/mapper/sda2crypt dm_crypt 153 | # /dev/sda2 raw 154 | # $1 a "recognizer": a string that will match the filesystem section uniquely (using egrep), such as ';;' or other specific attributes of the hosted filesystem(s) 155 | get_anchestors_mount () { 156 | debug 'FS' "Finding anchestor for: $1" 157 | local buffer= 158 | read block type leftovers <<< `egrep "$1" $TMP_BLOCKDEVICES 2>/dev/null` 159 | [ -z "$type" ] && return 1 160 | buffer="$block $type" 161 | if [ $type != 'raw' ] 162 | then 163 | if [ $type == lvm-lv ] 164 | then 165 | lv=$(basename $block) # /dev/cryptpool/cryptroot -> cryptroot. 166 | recognizer="lvm-lv;(yes|no);no_mountpoint;[^;]{1,};[^;]{1,};$lv;[^;]{1,}" 167 | elif [ $type == lvm-vg ] 168 | then 169 | recognizer="lvm-vg;(yes|no);no_mountpoint;[^;]{1,};[^;]{1,};`basename $block`;[^;]{1,}" 170 | elif [ $type == lvm-pv ] 171 | then 172 | # here we cheat a bit: we cannot match the FS section because usually we don't give a PV recognizable attributes, but since we name a PV as blockdevice + '+' we can match the blockdevice 173 | recognizer="^${block/+/} .* lvm-pv;" 174 | elif [ $type == dm_crypt ] 175 | then 176 | recognizer="dm_crypt;(yes|no);no_mountpoint;[^;]{1,};[^;]{1,};`basename $block`;[^;]{1,}" 177 | fi 178 | get_anchestors_mount "$recognizer" && buffer="$buffer 179 | $ANSWER_DEVICES" 180 | fi 181 | ANSWER_DEVICES=$buffer 182 | debug 'FS' "Found anchestors: $ANSWER_DEVICES" 183 | [ -n "$ANSWER_DEVICES" ] 184 | } 185 | 186 | 187 | # parameters: device file 188 | # outputs: UUID on success 189 | # nothing on failure 190 | # returns: 0 if the attribute is found, 1 otherwise 191 | getuuid() { 192 | [ -n "$1" -a -b "$1" ] || die_error "getuuid needs a device file argument" 193 | uuid=$(blkid -s UUID -o value ${1}) 194 | echo $uuid 195 | [ -n "$uuid" ] 196 | } 197 | 198 | # parameters: device file 199 | # outputs: LABEL on success 200 | # nothing on failure 201 | # returns: 0 if the attribute is found, 1 otherwise 202 | getlabel() { 203 | [ -n "$1" -a -b "$1" ] || die_error "getlabel needs a device file argument" 204 | label=$(blkid -s LABEL -o value ${1}) 205 | echo "$label" 206 | [ -n "$label" ] 207 | } 208 | 209 | # find partitionable blockdevices 210 | # $1 extra things to echo for each device (optional) (backslash escapes will get interpreted) 211 | finddisks() { 212 | shopt -s nullglob 213 | 214 | # Block Devices 215 | for dev in /sys/block/*; do 216 | # devices without a size are no good 217 | [[ -e $dev/size ]] || continue 218 | 219 | # size <= 0 is stuff like empty card reader 220 | read -r size < "$dev/size" 221 | (( size )) || continue 222 | 223 | # type 5 is a CDROM 224 | if [[ -e $dev/device/type ]]; then 225 | read -r type < "$dev/device/type" 226 | (( type == 5 )) && continue 227 | fi 228 | 229 | 230 | unset DEVTYPE 231 | . "$dev/uevent" 232 | dev_used_by_environment /dev/$DEVNAME && continue 233 | [[ $DEVTYPE = disk || $DEVTYPE = vbd ]] && echo -ne "/dev/$DEVNAME $1" 234 | done 235 | 236 | # cciss controllers 237 | for dev in /dev/cciss/*; do 238 | if [[ $dev != *[[:digit:]]p[[:digit:]]* ]]; then 239 | dev_used_by_environment $dev && continue 240 | echo "$dev $1" 241 | fi 242 | done 243 | 244 | # Smart 2 Controller 245 | for dev in /dev/ida/*; do 246 | if [[ $dev != *[[:digit:]]p[[:digit:]]* ]]; then 247 | dev_used_by_environment $dev && continue 248 | echo "$dev $1" 249 | fi 250 | done 251 | 252 | shopt -u nullglob 253 | } 254 | 255 | 256 | # find usable blockdevices: RAID + LVM volumes, partitioned and unpartitioned devices 257 | # $1 extra things to echo for each device (optional) (backslash escapes will get interpreted) 258 | # $2,$3,$4 control whether the following should be included in output (in that order): 259 | # * devices/partitions that are part of a RAID or LVM volume 260 | # (although we strongly encourage users to setup LVM in AIF, we want to make 261 | # life a bit easier for those who have setup LVM/softraid before running AIF) 262 | # * root block devices (ex. sda) that are partitioned 263 | # * extended partitions 264 | # options: 1, 0 (default) 265 | find_usable_blockdevices() { 266 | shopt -s nullglob 267 | local include_dm=${2:-0} 268 | local include_root=${3:-0} 269 | local include_ext=${4:-0} 270 | 271 | local has_parts 272 | 273 | for devpath in $(finddisks); do 274 | has_parts=0 275 | 276 | # Deal with partitions first 277 | # Glob allows for following matches (not device itself): 278 | # /dev/sda -> /dev/sda1 279 | # /dev/cciss/c0d1 -> /dev/cciss/c0d1p1 280 | for dev in ${devpath}*[[:digit:]]*; do 281 | has_parts=1 282 | if ((include_ext)) || ! dev_is_extended_partition $dev; then 283 | dev_used_by_environment $dev && continue 284 | echo -ne "$dev $1" 285 | fi 286 | 287 | if ((include_dm)) || ! dev_is_in_softraid_or_lvmpv $dev; then 288 | dev_used_by_environment $dev && continue 289 | echo -ne "$dev $1" 290 | fi 291 | done 292 | 293 | # Then deal with the "parent" device 294 | if ((include_dm)) || ! dev_is_in_softraid_or_lvmpv $devpath; then 295 | if ((include_root)) || ((! has_parts)); then 296 | echo -ne "$devpath $1" 297 | fi 298 | fi 299 | done 300 | 301 | # mapped devices 302 | for devpath in /dev/mapper/*; do 303 | dev_used_by_environment $devpath && continue 304 | # Exclude /control directory and other non-block files (such as??) 305 | if [[ -b $devpath ]]; then 306 | echo -ne "$devpath $1" 307 | fi 308 | done 309 | 310 | # raid md devices 311 | for devpath in /dev/md[0-9]*; do 312 | dev_used_by_environment $devpath && continue 313 | if grep -qw "${devpath//\/dev\//}" /proc/mdstat; then 314 | echo -ne "$devpath $1" 315 | fi 316 | done 317 | 318 | shopt -u nullglob 319 | } 320 | 321 | # if the environment in which AIF runs consists of block devices which AIF has no business with, 322 | # they can be listed in /run/aif/ignore_block_devices (example: archiso does this) 323 | # most likely this is just some loop files, some /dev/mapper/arch_* files and maybe /dev/sr0 324 | # but in theory, could be anything 325 | dev_used_by_environment () { 326 | local dev=$1 327 | grep -q "^$dev$" /run/aif/ignore_block_devices 2>/dev/null 328 | } 329 | 330 | dev_is_extended_partition () { 331 | local dev=$1 332 | local disk="${dev%%[[:digit:]]*}" 333 | local partnum="${dev##*[[:alpha:]]}" 334 | [ "$(sfdisk -c "$disk" "$partnum" 2>/dev/null)" = 5 ] 335 | } 336 | 337 | dev_is_in_softraid_or_lvmpv () { 338 | local dev=$1 339 | grep -qsw "${dev##*/}" /proc/mdstat || { pvscan -s 2>/dev/null | grep -q "$dev"; } 340 | } 341 | 342 | 343 | # preprocess fstab file 344 | # comments out old fields and inserts new ones 345 | # according to $TMP_FSTAB, set through process_filesystem calls 346 | target_configure_fstab() 347 | { 348 | [ -f $TMP_FSTAB ] || return 0 # we can't do anything, but not really a failure 349 | sed -i 's!^\(/dev/\|LABEL=\|UUID=\)!#\1!' $var_TARGET_DIR/etc/fstab || return 1 350 | sort $TMP_FSTAB >> $var_TARGET_DIR/etc/fstab || return 1 351 | return 0 352 | } 353 | 354 | 355 | # partitions a disk. heavily altered 356 | # $1 device to partition 357 | # $2 a string of the form: :[:+] (the + is bootable flag) 358 | partition() 359 | { 360 | debug 'FS' "Partition called like: partition '$1' '$2'" 361 | [ -z "$1" ] && die_error "partition() requires a device file and a partition string" 362 | [ -z "$2" ] && die_error "partition() requires a partition string" 363 | 364 | DEVICE=$1 365 | STRING=$2 366 | 367 | # validate DEVICE 368 | if [ ! -b "$DEVICE" ]; then 369 | notify "Device '$DEVICE' is not valid" 370 | return 1 371 | fi 372 | 373 | target_umountall 374 | 375 | # setup input var for sfdisk 376 | # format: each line=1 part. [ ] 377 | 378 | read -r -a fsspecs <<< "$STRING" # split up like this otherwise '*' will be globbed. which usually means an entry containing * is lost 379 | sfdisk_input= 380 | for fsspec in "${fsspecs[@]}"; do 381 | fssize=$(echo $fsspec | tr -d ' ' | cut -f1 -d:) 382 | fssize_spec=",$fssize" 383 | [ "$fssize" = "*" ] && fssize_spec=';' 384 | 385 | fstype=$(echo $fsspec | tr -d ' ' | cut -f2 -d:) 386 | fstype_spec="," 387 | [ "$fstype" = "swap" ] && fstype_spec=",S" 388 | [ "$fstype" = "extended" ] && fstype_spec=",E" 389 | 390 | bootflag=$(echo $fsspec | tr -d ' ' | cut -f3 -d:) 391 | bootflag_spec="" 392 | [ "$bootflag" = "+" ] && bootflag_spec=",*" 393 | 394 | sfdisk_input="${sfdisk_input}${fssize_spec}${fstype_spec}${bootflag_spec}\n" 395 | done 396 | 397 | sfdisk_input=$(printf "$sfdisk_input") # convert \n to newlines 398 | 399 | # invoke sfdisk 400 | debug 'FS' "Partition calls: sfdisk $DEVICE -uM >$LOG 2>&1 <<< $sfdisk_input" 401 | printk off 402 | sfdisk -D $DEVICE -uM >$LOG 2>&1 < $TMP_FILESYSTEMS 487 | while read part part_type part_label fs_string 488 | do 489 | if [ "$fs_string" != no_fs ] 490 | then 491 | local fs 492 | for fs in `sed 's/|/ /g' <<< $fs_string` # this splits multiple fs'es up, or just takes the one if there is only one (lvm vg's can have more then one lv) 493 | do 494 | parse_filesystem_string "$fs" 495 | echo "$part $part_type $part_label $fs_type $fs_create $fs_mountpoint $fs_mount $fs_opts $fs_label $fs_params" >> $TMP_FILESYSTEMS 496 | done 497 | fi 498 | done < $TMP_BLOCKDEVICES 499 | 500 | } 501 | 502 | # $1: part_type of underlying device 503 | # $2: name of underlying device 504 | # $3: fs_params (needed because VG's have a list of needed lvm-pv's in there) 505 | underlying_exists () { 506 | local part_type=$1 507 | local part=$2 508 | local fs_params=$3 509 | if [ "$part_type" = lvm-vg ]; then 510 | # We can't always do -b on the lvm VG. because the devicefile sometimes doesn't exist for a VG. vgdisplay to the rescue! 511 | # we can't use vgdisplay because that exists 0 when the requisted VG doesn't exist 512 | vgdisplay $part | grep -q 'VG Name' 513 | return 514 | elif [ "$part_type" = lvm-pv ]; then 515 | # check if all needed pv's exist. note that pvdisplay exits 5 as long as one of the args doesn't exist 516 | pvdisplay ${fs_params//__/ } >/dev/null 517 | return 518 | fi 519 | # part type is raw (a physical disk), or dm_crypt or lvm-pv 520 | [ -b "$part" ] 521 | return 522 | } 523 | 524 | # process all entries in $TMP_BLOCKDEVICES, create all blockdevices and filesystems and mount them correctly 525 | process_filesystems () 526 | { 527 | debug 'FS' "process_filesystems Called. checking all entries in $TMP_BLOCKDEVICES" 528 | rm -f $TMP_FSTAB 529 | generate_filesystem_list 530 | local ret=0 531 | 532 | # phase 1: create all blockdevices and filesystems in the correct order (for each fs, the underlying block/lvm/devicemapper device must be available so dependencies must be resolved. for lvm:first pv's, then vg's, then lv's etc) 533 | # don't let them mount yet. we take care of all that ourselves in the next phase 534 | 535 | inform "Phase 1: Creating filesystems & blockdevices" disks 536 | done_filesystems= 537 | for i in `seq 1 10` 538 | do 539 | open_items=0 540 | while read part part_type part_label fs_type fs_create fs_mountpoint fs_mount fs_opts fs_label fs_params 541 | do 542 | fs_id="$part $fs_type $fs_mountpoint $fs_opts $fs_label $fs_params" 543 | if [ "$fs_create" = yes ] 544 | then 545 | if check_is_in "$fs_id" "${done_filesystems[@]}" 546 | then 547 | debug 'FS' "phase 1 iteration $i: $fs_id ->Already done" 548 | elif underlying_exists $part_type $part $fs_params 549 | then 550 | debug 'FS' "phase 1 iteration $i: Creating $fs_type on $part_type $part ($fs_id)" 551 | inform "Making $fs_type filesystem on $part" disks 552 | needs_pkg=${filesystem_pkg[$fs_type]} 553 | [ -n "$needs_pkg" ] && check_is_in $needs_pkg "${needed_pkgs_fs[@]}" || needed_pkgs_fs+=($needs_pkg) 554 | BLOCK_ROLLBACK_USELESS=0 555 | if process_filesystem ${part/+} $fs_type $fs_create $fs_mountpoint no_mount $fs_opts $fs_label $fs_params; then 556 | done_filesystems+=("$fs_id") 557 | else 558 | debug 'FS' "phase 1 iteration $i: FAILED to reating $fs_type on $part_type $part ($fs_id)" 559 | ret=1 560 | break 2 561 | fi 562 | else 563 | debug 'FS' "phase 1 iteration $i: Cannot create $fs_type yet on $part_type $part, because it is not yet available ($fs_id)" 564 | open_items=1 565 | fi 566 | fi 567 | done < $TMP_FILESYSTEMS 568 | [ $open_items -eq 0 ] && break 569 | done 570 | if ((open_items||ret)); then 571 | show_warning "Filesystem/blockdevice processor problem" "Warning: Could not create all needed filesystems. Either the underlying blockdevices didn't appear in 10 iterations, or process_filesystem failed" 572 | return 1 573 | fi 574 | 575 | # phase 2: mount all filesystems in the vfs in the correct order. (also swapon where appropriate) 576 | 577 | inform "Phase 2: Mounting filesystems" disks 578 | while read part part_type part_label fs_type fs_create fs_mountpoint fs_mount fs_opts fs_label fs_params 579 | do 580 | if [[ $fs_mountpoint != no_mountpoint || $fs_type = swap ]]; then 581 | debug 'FS' "phase 2: swapon/mounting $part - $fs_type" 582 | [[ $fs_mountpoint != no_mountpoint ]] && inform "Mounting $part ($fs_type) on $fs_mountpoint" disks 583 | [[ $fs_type = swap ]] && inform "Swaponning $part" disks 584 | BLOCK_ROLLBACK_USELESS=0 585 | if ! process_filesystem $part $fs_type no $fs_mountpoint $fs_mount $fs_opts $fs_label $fs_params; then 586 | debug 'FS' "phase 2: FAILED to swapon/mount $part - $fs_type" 587 | ret=1 588 | break 589 | fi 590 | else 591 | debug 'FS' "phase 2: no need to mount: $part - $fs_type" 592 | fi 593 | done < <(sort -t \ -k 6 $TMP_FILESYSTEMS) 594 | 595 | [ $ret -eq 0 ] && inform "Done processing filesystems/blockdevices" disks 1 && return 0 596 | return $ret 597 | } 598 | 599 | 600 | # Roll back all "filesystems" (normal ones and dm-mapper based stuff) specified in $BLOCK_DATA. Not partitions. Doesn't restore data after you erased it, of course. 601 | rollback_filesystems () 602 | { 603 | inform "Rolling back filesystems..." disks 604 | generate_filesystem_list 605 | local warnings= 606 | rm -f $TMP_FSTAB 607 | 608 | # phase 1: destruct all mounts in the vfs and swapoff swap volumes who are listed in $BLOCK_DATA 609 | # re-order list so that we umount in the correct order. eg first umount /a/b/c, then /a/b. we sort alphabetically, which has the side-effect of sorting by stringlength, hence by vfs dependencies. 610 | 611 | inform "Phase 1: Umounting all specified mountpoints" disks 612 | done_umounts= # We translate some devices back to their original (eg /dev/sda3+ -> /dev/sda3 for lvm PV's). No need to bother user twice for such devices. 613 | while read part part_type part_label fs_type fs_create fs_mountpoint fs_mount fs_opts fs_label fs_params 614 | do 615 | if [ "$fs_type" = swap ] 616 | then 617 | inform "(Maybe) Swapoffing $part" disks 618 | swapoff $part &>/dev/null # could be that it was not swappedon yet. that's not a problem at all. 619 | elif [ "$fs_mountpoint" != no_mountpoint ] 620 | then 621 | part_real=${part/+/} 622 | if ! check_is_in "$part_real" "${done_umounts[@]}" 623 | then 624 | inform "(Maybe) Umounting $part_real" disks 625 | if mount | grep -q "^$part_real " # could be that this was not mounted yet. no problem, we can just skip it then. 626 | then 627 | if umount $part_real >$LOG 628 | then 629 | done_umounts+=("$part_real") 630 | else 631 | warnings="$warnings\nCould not umount umount $part_real . Probably device is still busy. See $LOG" 632 | show_warning "Umount failure" "Could not umount umount $part_real . Probably device is still busy. See $LOG" #TODO: fix device busy things 633 | fi 634 | fi 635 | fi 636 | fi 637 | done < <(sort -t \ -k 6 -r $TMP_FILESYSTEMS) 638 | 639 | 640 | # phase 2: destruct blockdevices listed in $BLOCK_DATA if they would exist already, in the correct order (first lvm LV, then VG, then PV etc) 641 | # targets are device-mapper devices such as any lvm things, dm_crypt devices, etc and lvm PV's. 642 | 643 | # Possible approach 1 (not implemented): for each target in $TMP_BLOCKDEVICES, check that it has no_fs or has a non-lvm/dm_crypt fs. (egrep -v ' lvm-pv;| lvm-vg;| lvm-lv;| dm_crypt;' ) and clean it 644 | # -> requires updating of underlying block device string when you clean something, on a copy of .block_data etc. too complicated 645 | # Approach 2 : iterate over all targets in $TMP_BLOCKDEVICES as much as needed, until a certain limit, and in each loop check what can be cleared by looking at the real, live usage of / dependencies on the partition. 646 | # -> easier (implemented) 647 | 648 | 649 | inform "Phase 2: destructing relevant blockdevices" disks 650 | for i in `seq 1 10` 651 | do 652 | open_items=0 653 | while read part part_type part_label fs_string 654 | do 655 | check_is_in "$part_type" dm_crypt lvm-pv lvm-vg lvm-lv || continue 656 | 657 | real_part=${part/+/} 658 | 659 | # do not destroy a blockdevice if it hosts one or more filesystems that were set to not recreate 660 | # fs_string = one or more "$fs_type;$fs_create;$fs_mountpoint;target;$fs_opts;$fs_label;$fs_params", separated by ':' 661 | # there is probably a nice regex to check this but i'm bad at regexes. 662 | if echo "$fs_string" | grep -q ';yes;/' || echo "$fs_string" | grep -q ';yes;no_mountpoint' 663 | then 664 | inform "Skipping destruction of $part ($part_type) because one of the filesystems on it contains data you want to keep" 665 | # TODO: it's possible that if we don't clear a blockdevice here because there is something on it with valuable data, that this blockdevice itself is hosted on some other blockdevice (eg lvm VG,PV or dm_crypt), \ 666 | # that blockdevice cannot be cleared as well because it depends on this one, so after 10 iterations the user will get a warning that not everything is cleared. so we should fix this someday. 667 | elif [ "$part_type" = dm_crypt ] # Can be in use for: lvm-pv or raw. we don't need to care about raw (it will be unmounted so it can be destroyed) 668 | then 669 | if [ -b $real_part ] && cryptsetup status $real_part &>/dev/null # don't use 'isLuks' it only works for the "underlying" device (eg in /dev/sda1 -> luksOpen -> /dev/mapper/foo, isLuks works only on the former. status works on the latter too) 670 | then 671 | if pvdisplay $real_part &>/dev/null 672 | then 673 | debug 'FS' "$part ->Cannot do right now..." 674 | open_items=1 675 | else 676 | inform "Attempting destruction of device $part (type $part_type)" disks 677 | if ! cryptsetup luksClose $real_part &>$LOG 678 | then 679 | warnings="$warnings\nCould not cryptsetup luksClose $real_part" 680 | show_warning "process_filesystems blockdevice destruction" "Could not cryptsetup luksClose $real_part" 681 | fi 682 | fi 683 | else 684 | debug 'FS' "Skipping destruction of device $part (type $part_type) because it doesn't exist" 685 | fi 686 | elif [ "$part_type" = lvm-pv ] # Can be in use for: lvm-vg 687 | then 688 | if [ -b $real_part ] && pvdisplay $real_part &>/dev/null 689 | then 690 | if vgdisplay -v 2>/dev/null | grep -q $real_part # check if it's in use 691 | then 692 | debug 'FS' "$part ->Cannot do right now..." 693 | open_items=1 694 | else 695 | inform "Attempting destruction of device $part (type $part_type)" disks 696 | if ! pvremove $real_part &>$LOG 697 | then 698 | warnings="$warnings\nCould not pvremove $part" 699 | show_warning "process_filesystems blockdevice destruction" "Could not pvremove $part" 700 | fi 701 | fi 702 | else 703 | debug 'FS' "Skipping destruction of device $part (type $part_type) because it doesn't exist" 704 | fi 705 | elif [ "$part_type" = lvm-vg ] #Can be in use for: lvm-lv 706 | then 707 | if vgdisplay $part 2>/dev/null | grep -q 'VG Name' # workaround for non-existing lvm VG device files 708 | then 709 | open_lv=`vgdisplay -c $part 2>/dev/null | cut -d ':' -f6` 710 | if [ $open_lv -gt 0 ] 711 | then 712 | debug 'FS' "$part ->Cannot do right now..." 713 | open_items=1 714 | else 715 | inform "Attempting destruction of device $part (type $part_type)" disks 716 | if ! vgremove $part &>$LOG # we shouldn't need -f because we clean up the lv's first. 717 | then 718 | warnings="$warnings\nCould not vgremove $part" 719 | show_warning "process_filesystems blockdevice destruction" "Could not vgremove $part" 720 | fi 721 | fi 722 | else 723 | debug 'FS' "Skipping destruction of device $part (type $part_type) because it doesn't exist" 724 | fi 725 | elif [ "$part_type" = lvm-lv ] #Can be in use for: dm_crypt or raw. we don't need to care about raw (it will be unmounted so it can be destroyed) 726 | then 727 | if lvdisplay $part &>/dev/null && ! vgdisplay $part 2>/dev/null | grep -q 'VG Name' # it exists: lvdisplay works, and it's not a volume group (you can do lvdisplay $volumegroup) 728 | then 729 | if cryptsetup isLuks $part &>/dev/null 730 | then 731 | debug 'FS' "$part ->Cannot do right now..." 732 | open_items=1 733 | else 734 | inform "Attempting destruction of device $part (type $part_type)" disks 735 | if ! lvremove -f $part &>$LOG 736 | then 737 | warnings="$warnings\nCould not lvremove -f $part" 738 | show_warning "process_filesystems blockdevice destruction" "Could not lvremove -f $part" 739 | fi 740 | fi 741 | else 742 | debug 'FS' "Skipping destruction of device $part (type $part_type) because it doesn't exist" 743 | fi 744 | else 745 | die_error "Unrecognised partition type $part_type for partition $part. This should never happen. please report this" 746 | fi 747 | done < $TMP_BLOCKDEVICES 748 | [ $open_items -eq 0 ] && break 749 | done 750 | 751 | if [ $open_items -eq 1 ] 752 | then 753 | warnings="$warnings\nCould not destruct all filesystems/blockdevices. It appears some depending filesystems/blockdevices could not be cleared in 10 iterations" 754 | show_warning "Filesystem/blockdevice processor problem" "Warning: Could not destruct all filesystems/blockdevices. It appears some depending filesystems/blockdevices could not be cleared in 10 iterations" 755 | fi 756 | [ -n "$warnings" ] && inform "Rollback failed" disks 1 && show_warning "Rollback problems" "Some problems occurred while rolling back: $warnings.\n Thisk needs to be fixed before retrying disk/filesystem creation or restarting the installer" && return 1 757 | inform "Rollback succeeded" disks 1 758 | done_filesystems= 759 | needed_pkgs_fs= 760 | BLOCK_ROLLBACK_USELESS=1 761 | return 0 762 | } 763 | 764 | 765 | # make a filesystem on a blockdevice and mount if needed. 766 | # parameters: (all encoded) 767 | # $1 partition 768 | # $2 fs_type 769 | # $3 fs_create (optional. defaults to yes) 770 | # $4 fs_mountpoint (optional. defaults to no_mountpoint) 771 | # $5 fs_mount (optional. defaults to no_mount) 772 | # $6 fs_opts (optional. defaults to no_opts) 773 | # $7 fs_label (optional. defaults to no_label or for lvm volumes who need a label (VG's and LV's) vg1,vg2,lv1 etc). Note that if there's no label for a VG you probably did something wrong, because you probably want LV's on it so you need a label for the VG. 774 | # $8 fs_params (optional. defaults to no_params) 775 | 776 | process_filesystem () 777 | { 778 | [ "$2" != lvm-lv ] && [ -z "$1" -o ! -b "$1" ] && die_error "process_filesystem needs a partition as \$1" # Don't do this for lv's. It's a hack to workaround non-existence of VG device files. 779 | [ -z "$2" ] && die_error "process_filesystem needs a filesystem type as \$2" 780 | debug 'FS' "process_filesystem $@" 781 | local ret=0 782 | part=$1 783 | parse_filesystem_string "$2;$3;$4;$5;$6;$7;$8" '' '' 784 | 785 | # Create the FS 786 | if [ "$fs_create" = yes ] 787 | then 788 | if ! check_is_in $fs_type "${!filesystem_programs[@]}" 789 | then 790 | show_warning "process_filesystem error" "Cannot determine filesystem program for $fs_type on $part. Not creating this FS" 791 | return 1 792 | fi 793 | [ -z "$fs_label" ] && [ "$fs_type" = lvm-vg -o "$fs_type" = lvm-pv ] && fs_label=default #TODO. implement the incrementing numbers label for lvm vg's and lv's 794 | 795 | #TODO: health checks on $fs_params etc 796 | program="${filesystem_programs[$fs_type]}" 797 | case ${fs_type} in 798 | xfs) 799 | $program -f $part $fs_opts >$LOG 2>&1; ret=$? ;; 800 | jfs|reiserfs) 801 | yes | $program $part $fs_opts >$LOG 2>&1; ret=$? ;; 802 | swap|ext2|ext3|ext4|nilfs2|vfat|btrfs) 803 | $program $part $fs_opts >$LOG 2>&1; ret=$? ;; 804 | dm_crypt) 805 | [ -z "$fs_params" ] && fs_params='-c aes-xts-plain -y -s 512'; 806 | inform "Please enter your passphrase to encrypt the device (with confirmation)" 807 | $program $fs_params $fs_opts luksFormat -q $part >$LOG 2>&1 < /dev/tty ; ret=$? #hack to give cryptsetup the approriate stdin. keep in mind we're in a loop (see process_filesystems where something else is on stdin) 808 | inform "Please enter your passphrase to unlock the device" 809 | $program luksOpen $part $fs_label >$LOG 2>&1 < /dev/tty; ret=$? || ( show_warning 'cryptsetup' "Error luksOpening $part on /dev/mapper/$fs_label" ) ;; 810 | lvm-pv) 811 | $program $fs_opts $part >$LOG 2>&1; ret=$? ;; 812 | lvm-vg) 813 | # $fs_params: list of PV's 814 | $program $fs_opts $fs_label $fs_params >$LOG 2>&1; ret=$? ;; 815 | lvm-lv) 816 | # $fs_params = size string (eg '5G') 817 | $program -L $fs_params $fs_opts -n $fs_label $(basename $part) >$LOG 2>&1; ret=$? ;; #$fs_opts is usually something like -L 10G # Strip '/dev/mapper/' part because device file may not exist. TODO: do i need to activate them? 818 | *) 819 | die_error "AIF error. somebody needs to update process_filesystem() to support $fs_type" 820 | esac 821 | # The udevadm settle is a workaround for a bug/racecondition in cryptsetup. See: 822 | # http://mailman.archlinux.org/pipermail/arch-releng/2010-April/000974.html 823 | # It may not be needed (anymore), or not after every type of FS, but we're rather safe then sorry. and it seems to always return in less then a second 824 | udevadm settle 825 | BLOCK_ROLLBACK_USELESS=0 826 | [ "$ret" -gt 0 ] && { show_warning "process_filesystem error" "Error creating filesystem $fs_type on $part."; return 1; } 827 | sleep 2 828 | fi 829 | 830 | if [ -n "$fs_label" ] && check_is_in $fs_type "${!label_programs[@]}" 831 | then 832 | program="${label_programs[$fs_type]}" 833 | case ${fs_type} in 834 | swap|xfs|jfs|nilfs2|ext2|ext3|ext4|btrfs) 835 | $program -L $fs_label $part >$LOG 2>&1; ret=$?;; 836 | reiserfs) 837 | $program -l $fs_label $part >$LOG 2>&1; ret=$?;; 838 | vfat) 839 | $program $part $fs_label >$LOG 2>&1; ret=$?;; 840 | *) 841 | die_error "AIF error. somebody needs to update process_filesystem() to support $fs_type" 842 | esac 843 | [ "$ret" -gt 0 ] && { show_warning "process_filesystem error" "Error setting label $fs_label on $part." ; return 1; } 844 | fi 845 | 846 | # Mount it, if requested. Note that it's your responsability to figure out if you want this or not before calling me. This will only work for 'raw' filesystems (ext,reiser,xfs, swap etc. not lvm stuff,dm_crypt etc) 847 | if [ "$fs_mount" = runtime -o "$fs_mount" = target ] 848 | then 849 | BLOCK_ROLLBACK_USELESS=0 850 | if [ "$fs_type" = swap ] 851 | then 852 | debug 'FS' "swaponning $part" 853 | swapon $part >$LOG 2>&1 || ( show_warning 'Swapon' "Error activating swap: swapon $part" ; ret=1 ) 854 | fs_mountpoint="none" 855 | else 856 | [ "$fs_mount" = runtime ] && dst=$fs_mountpoint 857 | [ "$fs_mount" = target ] && dst=$var_TARGET_DIR$fs_mountpoint 858 | debug 'FS' "mounting $part on $dst" 859 | mkdir -p $dst &>/dev/null # directories may or may not already exist 860 | mount -t $fs_type $part $dst >$LOG 2>&1 || ( show_warning 'Mount' "Error mounting $part on $dst" ; ret=1 ) 861 | fi 862 | fi 863 | 864 | 865 | # Add to temp fstab, if not already there. 866 | if [ -n "$fs_mountpoint" -a "$fs_mount" = target ] 867 | then 868 | case "$PART_ACCESS" in 869 | label) 870 | local label 871 | label="$(getlabel $part)" && part="LABEL=$label";; 872 | uuid) 873 | local uuid 874 | uuid="$(getuuid $part)" && part="UUID=$uuid";; 875 | esac 876 | fs_passno=2 877 | [[ $fs_mountpoint = "/" ]] && fs_passno=1 878 | [[ $fs_type = "swap" ]] && fs_passno=0 879 | line="$part $fs_mountpoint $fs_type defaults 0 $fs_passno" 880 | # the file $TMP_FSTAB might not exist yet 881 | grep -q "$line" $TMP_FSTAB 2>/dev/null || echo "$line" >> $TMP_FSTAB 882 | fi 883 | 884 | return $ret 885 | 886 | #TODO: if target has LVM volumes, copy /etc/lvm/backup to /etc on target (or maybe it can be regenerated with a command, i should look that up) 887 | 888 | } 889 | 890 | 891 | # $1 blockdevice 892 | # $2 unit: B, KiB, kB, MiB, MB, GiB or GB. defaults to B (we follow IEEE 1541-2002 ) 893 | # output will be in $BLOCKDEVICE_SIZE 894 | get_blockdevice_size () 895 | { 896 | [ -b "$1" ] || die_error "get_blockdevice_size needs a blockdevice as \$1 ($1 given)" 897 | unit=${2:-B} 898 | allowed_units=(B KiB kB MiB MB GiB GB) 899 | if ! check_is_in $unit "${allowed_units[@]}" 900 | then 901 | die_error "Unrecognized unit $unit!" 902 | fi 903 | 904 | # NOTES about older, deprecated methods: 905 | # - BLOCKDEVICE_SIZE=$(hdparm -I $1 | grep -F '1000*1000' | sed "s/^.*:[ \t]*\([0-9]*\) MBytes.*$/\1/") # if you do this on a partition, you get the size of the entire disk ! + hdparm only supports sata and ide. not scsi. 906 | # - unreliable method: on some interwebs they say 1 block = 512B, on other internets they say 1 block = 1kiB. 1kiB seemed to work for me. 907 | # blocks=`fdisk -s $1` || show_warning "Fdisk problem" "Something failed when trying to do fdisk -s $1" 908 | # BLOCKDEVICE_SIZE=$(($blocks/1024)) 909 | 910 | bytes=$((`fdisk -l $1 2>/dev/null | sed -n '2p' | cut -d' ' -f5`)) 911 | [[ $bytes = *[^0-9]* ]] && die_error "Could not parse fdisk -l output for $1" 912 | [ $unit = B ] && BLOCKDEVICE_SIZE=$bytes 913 | [ $unit = KiB ] && BLOCKDEVICE_SIZE=$((bytes/2**10)) # /1024 914 | [ $unit = kB ] && BLOCKDEVICE_SIZE=$((bytes/10**3)) # /1000 915 | [ $unit = MiB ] && BLOCKDEVICE_SIZE=$((bytes/2**20)) # ... 916 | [ $unit = MB ] && BLOCKDEVICE_SIZE=$((bytes/10**6)) 917 | [ $unit = GiB ] && BLOCKDEVICE_SIZE=$((bytes/2**30)) 918 | [ $unit = GB ] && BLOCKDEVICE_SIZE=$((bytes/10**9)) 919 | true 920 | } 921 | 922 | 923 | # $1 blockdevice (ex: /dev/md0 or /dev/sda1) 924 | # All MD RAID block devices have a major id of 9 925 | device_is_raid() { 926 | [[ -b "$1" ]] || die_error "device_is_raid needs a blockdevice as \$1 ($1 given)" 927 | [[ -f /proc/mdstast ]] || return 1 928 | local devmajor=$(stat -c %t "$1") 929 | (( devmajor == 9 )) 930 | } 931 | 932 | 933 | # $1 md raid blockdevice (ex: /dev/md0) 934 | # return a list of array members from given md array 935 | # ex: /dev/md0 has slaves: "/dev/sda1 /dev/sdb2 /dev/sdc2" 936 | mdraid_all_slaves () 937 | { 938 | shopt -s nullglob 939 | local slave= 940 | local slaves= 941 | for slave in /sys/class/block/${1##*/}/slaves/*; do 942 | source "$slave/uevent" 943 | slaves="$slaves/dev/$DEVNAME " 944 | unset DEVNAME 945 | done 946 | shopt -u nullglob 947 | echo $slaves 948 | } 949 | -------------------------------------------------------------------------------- /src/core/libs/lib-flowcontrol.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | usage () 4 | { 5 | msg="aif -p Select a procedure # If given, this *must* be the first option 6 | -i Override interface type (optional) 7 | -d Explicitly enable debugging (/var/log/aif/debug.log) (optional) 8 | -l Explicitly enable logging to file (/var/log/aif/aif.log) (optional) 9 | -h Help: show usage (optional)\n 10 | If the procedurename starts with 'http://' it will be wget'ed. Otherwise it's assumed to be a procedure in the VFS tree 11 | If the procedurename is prefixed with '/' it will be loaded from user module .\n 12 | For more info, see the README which you can find in /usr/share/aif/docs\n 13 | Available procedures: 14 | ==core== 15 | `find $LIB_CORE/procedures -type f | sed \"s#$LIB_CORE/procedures/##\" | sort` 16 | ==user== 17 | `find $LIB_USER/*/procedures -type f 2>/dev/null | sed \"s#$LIB_USER/\(.*\)/procedures/#\1/#\" | sort`" 18 | [ -n "$procedure" ] && msg="$msg\nProcedure ($procedure) specific options:\n$var_ARGS_USAGE" 19 | 20 | echo -e "$msg" 21 | } 22 | 23 | 24 | # $1 module name 25 | load_module () 26 | { 27 | [ -z "$1" ] && die_error "load_module needs a module argument" 28 | log "Loading module $1 ..." 29 | local path=$LIB_USER/"$1" 30 | [ "$1" = core ] && path=$LIB_CORE 31 | 32 | for submodule in lib #procedure don't load procedures automatically! 33 | do 34 | if [ ! -d "$path/${submodule}s" ] 35 | then 36 | # ignore this problem for not-core modules 37 | [ "$1" = core ] && die_error "$path/${submodule}s does not exist. something is horribly wrong with this installation" 38 | else 39 | shopt -s nullglob 40 | local module 41 | for module in "$path/${submodule}s"/* 42 | do 43 | # I have the habit of editing files while testing, don't source my backup files! 44 | [[ "$module" == *~ ]] && continue 45 | module=$(basename "$module") 46 | load_${submodule} "$1" "$module" 47 | done 48 | shopt -u nullglob 49 | fi 50 | done 51 | 52 | } 53 | 54 | 55 | # $1 module name 56 | # $2 procedure name 57 | load_procedure() 58 | { 59 | [ -z "$1" ] && die_error "load_procedure needs a module as \$1 and procedure as \$2" 60 | [ -z "$2" ] && die_error "load_procedure needs a procedure as \$2" 61 | if [ "$1" = 'http' ] 62 | then 63 | log "Loading procedure $2 ..." 64 | local procedure=$RUNTIME_DIR/aif-procedure-downloaded-`basename $2` 65 | wget "$2" -q -O $procedure >/dev/null || die_error "Could not download procedure $2" 66 | else 67 | log "Loading procedure $1/procedures/$2 ..." 68 | local procedure=$LIB_USER/"$1"/procedures/"$2" 69 | [ "$1" = core ] && procedure=$LIB_CORE/procedures/"$2" 70 | fi 71 | [ -f "$procedure" ] && source "$procedure" || die_error "Something went wrong while sourcing procedure $procedure" 72 | } 73 | 74 | 75 | # $1 module name 76 | # $2 library name 77 | load_lib () 78 | { 79 | [ -z "$1" ] && die_error "load_library needs a module als \$1 and library as \$2" 80 | [ -z "$2" ] && die_error "load_library needs a library as \$2" 81 | log "Loading library $1/libs/$2 ..." 82 | local lib=$LIB_USER/"$1"/libs/"$2" 83 | [ "$1" = core ] && lib=$LIB_CORE/libs/"$2" 84 | source $lib || die_error "Something went wrong while sourcing library $lib" 85 | } 86 | 87 | 88 | # $1 phase/worker 89 | # $2 phase/worker name 90 | # $3... extra args for phase/worker (optional) 91 | execute () 92 | { 93 | [ -z "$1" -o -z "$2" ] && debug 'MAIN' "execute $@" && die_error "Use the execute function like this: execute with type=phase/worker" 94 | [ "$1" != phase -a "$1" != worker ] && debug 'MAIN' "execute $@" && die_error "execute's first argument must be a valid type (phase/worker)" 95 | local PWD_BACKUP=`pwd` 96 | local object=$1_$2 97 | 98 | if [ "$1" = worker ] 99 | then 100 | log "*** Executing worker $2" 101 | if type -t $object | grep -q function 102 | then 103 | shift 2 104 | $object "$@" 105 | local ret=$? 106 | local exit_var=exit_$object 107 | read $exit_var <<< $ret # maintain exit status of each worker 108 | else 109 | die_error "$object is not defined!" 110 | fi 111 | elif [ "$1" = phase ] 112 | then 113 | log "******* Executing phase $2" 114 | local exit_var=exit_$object 115 | read $exit_var <<< 0 116 | # TODO: for some reason the hack below does not work (tested in virtualbox), even though it really should. Someday I must get indirect array variables working and clean this up... 117 | # debug 'MAIN' "\$1: $1, \$2: $2, \$object: $object, \$exit_$object: $exit_object" 118 | # debug 'MAIN' "declare: `declare | grep -e "^${object}=" | cut -d"=" -f 2-`" 119 | # props to jedinerd at #bash for this hack. 120 | # eval phase=$(declare | grep -e "^${object}=" | cut -d"=" -f 2-) 121 | #debug 'MAIN' "\$phase: $phase - ${phase[@]}" 122 | unset phase 123 | [ "$2" = preparation ] && phase=( "${phase_preparation[@]}" ) 124 | [ "$2" = basics ] && phase=( "${phase_basics[@]}" ) 125 | [ "$2" = system ] && phase=( "${phase_system[@]}" ) 126 | [ "$2" = finish ] && phase=( "${phase_finish[@]}" ) 127 | # worker_str contains the name of the worker and optionally any arguments 128 | for worker_str in "${phase[@]}" 129 | do 130 | debug 'MAIN' "Loop iteration. \$worker_str: $worker_str" 131 | execute worker $worker_str || read $exit_var <<< $? # assign last failing exit code to exit_phase_, if any. 132 | done 133 | local ret=${!exit_var} 134 | fi 135 | 136 | debug 'MAIN' "Execute(): $object exit state was $ret" 137 | cd $PWD_BACKUP 138 | return $ret 139 | } 140 | 141 | 142 | # check if a phase/worker executed successfully 143 | # returns 0 if ok, the phase/workers' exit state otherwise (and returns 1 if not executed yet) 144 | # $1 phase/worker 145 | # $2 phase/worker name 146 | ended_ok () 147 | { 148 | [ -z "$1" -o -z "$2" ] && die_error "Use the ended_ok function like this: ended_ok with type=phase/worker" 149 | [ "$1" != phase -a "$1" != worker ] && die_error "ended_ok's first argument must be a valid type (phase/worker)" 150 | object=$1_$2 151 | exit_var=exit_$object 152 | debug 'MAIN' "Ended_ok? -> Exit state of $object was: ${!exit_var} (if empty. it's not executed yet)" 153 | [ "${!exit_var}" = '0' ] && return 0 154 | [ "${!exit_var}" = '' ] && return 1 155 | return ${!exit_var} 156 | } 157 | 158 | 159 | depend_module () 160 | { 161 | load_module "$1" 162 | } 163 | 164 | 165 | depend_procedure () 166 | { 167 | load_procedure "$1" "$2" 168 | } 169 | 170 | 171 | start_process () 172 | { 173 | local ret=0 174 | execute phase preparation || ret=$? 175 | execute phase basics || ret=$? 176 | execute phase system || ret=$? 177 | execute phase finish || ret=$? 178 | return $ret 179 | } 180 | 181 | 182 | show_report () 183 | { 184 | data="Execution Report:" 185 | data="$data\n-----------------" 186 | for phase in preparation basics system finish 187 | do 188 | object=phase_$phase 189 | exit_var=exit_$object 190 | local ret=${!exit_var} 191 | [ "$ret" = "0" ] && data="$data\nPhase $phase: Success" 192 | [ "$ret" = "0" ] || data="$data\nPhase $phase: Failed" 193 | eval phase_array=$(declare | grep -e "^${object}=" | cut -d"=" -f 2-) 194 | for worker_str in "${phase_array[@]}" 195 | do 196 | worker=${worker_str%% *} 197 | exit_var=exit_worker_$worker 198 | ret=${!exit_var} 199 | case "$ret" in 200 | "") data="$data\n > Worker $worker: Skipped";; 201 | "0") data="$data\n > Worker $worker: Success";; 202 | *) data="$data\n > Worker $worker: Failed";; 203 | esac 204 | done 205 | done 206 | inform "$data" 207 | } 208 | 209 | 210 | start_installer () 211 | { 212 | log "################## START OF INSTALLATION ##################" 213 | } 214 | 215 | 216 | # use this function to stop the installation procedure. 217 | # $1 exit code (optional, defaults to 0) 218 | stop_installer () 219 | { 220 | log "-------------- STOPPING INSTALLATION ----------" 221 | cleanup_runtime 222 | [ "$var_UI_TYPE" = dia ] && clear 223 | exit ${1:-0} 224 | } 225 | -------------------------------------------------------------------------------- /src/core/libs/lib-misc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # runs a process and makes sure the output is shown to the user. sets the exit state of the executed program ($CONTROLLED_EXIT) so the caller can show a concluding message. 5 | # when in dia mode, we will run the program and a dialog instance in the background (cause that's just how it works with dia) 6 | # when in cli mode, the program will just run in the foreground. technically it can be run backgrounded but then we need tail -f (cli_follow_progress), and we miss the beginning of the output if it goes too fast, not to mention because of the sleep in run_background 7 | # $1 identifier (no spaces allowed, hyphen and underscore are ok) 8 | # $2 command (will be eval'ed) 9 | # $3 logfile 10 | # $4 title to show while process is running 11 | run_controlled () 12 | { 13 | [ -z "$1" ] && die_error "run_controlled: please specify an identifier to keep track of the command!" 14 | [ -z "$2" ] && die_error "run_controlled needs a command to execute!" 15 | [ -z "$3" ] && die_error "run_controlled needs a logfile to redirect output to!" 16 | [ -z "$4" ] && die_error "run_controlled needs a title to show while your process is running!" 17 | 18 | log_parent=$(dirname $3) 19 | if [ ! -d $log_parent ]; then 20 | mkdir -p $log_parent || die_error "Could not create $log_parent, we were asked to log $1 to $3" 21 | fi 22 | if [ "$var_UI_TYPE" = dia ] 23 | then 24 | run_background $1 "$2" $3 25 | follow_progress " $4 " $3 $BACKGROUND_PID # dia mode ignores the pid. cli uses it to know how long it must do tail -f 26 | wait_for $1 $FOLLOW_PID || die_error "Internal AIF error, the following call failed: wait_for $1 $FOLLOW_PID. This should never happen" 27 | CONTROLLED_EXIT=$BACKGROUND_EXIT 28 | else 29 | notify "$4" 30 | eval "$2" >>$3 2>&1 31 | CONTROLLED_EXIT=$? 32 | fi 33 | debug 'MISC' "run_controlled done with $1: exitcode (\$CONTROLLED_EXIT): $CONTROLLED_EXIT .Logfile $3" 34 | return $CONTROLLED_EXIT 35 | } 36 | 37 | 38 | # run a process in the background, and log it's stdout and stderr to a specific logfile 39 | # returncode is stored in BACKGROUND_EXIT 40 | # pid of the backgrounded wrapper process is stored in BACKGROUND_PID (this is _not_ the pid of $2) 41 | # $1 identifier 42 | # $2 command (will be eval'ed) 43 | # $3 logfile 44 | run_background () 45 | { 46 | [ -z "$1" ] && die_error "run_background: please specify an identifier to keep track of the command!" 47 | [ -z "$2" ] && die_error "run_background needs a command to execute!" 48 | [ -z "$3" ] && die_error "run_background needs a logfile to redirect output to!" 49 | 50 | log_parent=$(dirname $3) 51 | if [ ! -d $log_parent ]; then 52 | mkdir -p $log_parent || die_error "Could not create $log_parent, we were asked to log $1 to $3" 53 | fi 54 | 55 | debug 'MISC' "run_background called. identifier: $1, command: $2, logfile: $3" 56 | ( \ 57 | touch $RUNTIME_DIR/aif-$1-running 58 | debug 'MISC' "run_background starting $1: $2 >>$3 2>&1" 59 | [ -f $3 ] && echo -e "\n\n\n" >>$3 60 | echo "STARTING $1 . Executing $2 >>$3 2>&1\n" >> $3; 61 | eval "$2" >>$3 2>&1 62 | BACKGROUND_EXIT=$? 63 | debug 'MISC' "run_background done with $1: exitcode (\$BACKGROUND_EXIT): $BACKGROUND_EXIT .Logfile $3" 64 | echo >> $3 65 | echo $BACKGROUND_EXIT > $RUNTIME_DIR/aif-$1-exit 66 | rm -f $RUNTIME_DIR/aif-$1-running 67 | ) & 68 | BACKGROUND_PID=$! 69 | 70 | sleep 2 71 | } 72 | 73 | 74 | # wait until a process - spawned by run_background - is done 75 | # $1 identifier. WARNING! see above 76 | # $2 pid of a process to kill when done (optional). useful for dialog --no-kill --tailboxbg's pid. 77 | # returns 0 unless anything failed in the wait_for logic (not tied to the exitcode of the program we actually wait for) 78 | wait_for () 79 | { 80 | [ -z "$1" ] && die_error "wait_for needs an identifier to known on which command to wait!" 81 | local ret=0 82 | while [ -f $RUNTIME_DIR/aif-$1-running ] 83 | do 84 | sleep 1 85 | done 86 | BACKGROUND_EXIT=$(cat $RUNTIME_DIR/aif-$1-exit) || ret=1 87 | rm $RUNTIME_DIR/aif-$1-exit || ret=1 88 | if [ -n "$2" ] 89 | then 90 | kill $2 || ret=1 91 | fi 92 | return $ret 93 | } 94 | 95 | 96 | # $1 needle 97 | # $2 set (array) haystack 98 | check_is_in () 99 | { 100 | [ -z "$1" ] && die_error "check_is_in needs a non-empty needle as \$1 and a haystack as \$2!(got: check_is_in '$1' '$2'" # haystack can be empty though 101 | 102 | local needle="$1" element 103 | shift 104 | for element 105 | do 106 | [[ $element = $needle ]] && return 0 107 | done 108 | return 1 109 | } 110 | 111 | 112 | # cleans up file in the runtime directory who can be deleted, make dir first if needed 113 | cleanup_runtime () 114 | { 115 | mkdir -p $RUNTIME_DIR || die_error "Cannot create $RUNTIME_DIR" 116 | rm -rf $RUNTIME_DIR/aif-dia* &>/dev/null 117 | } 118 | 119 | 120 | # $1 UTC or localtime (hardwareclock) 121 | # $2 direction (systohc or hctosys) 122 | dohwclock() { 123 | # TODO: we probably only need to do this once and then actually use adjtime on next invocations 124 | inform "Resetting hardware clock adjustment file" 125 | [ -d /var/lib/hwclock ] || mkdir -p /var/lib/hwclock || return 1 126 | if [ ! -f /var/lib/hwclock/adjtime ]; then 127 | echo "0.0 0 0.0" > /var/lib/hwclock/adjtime || return 1 128 | fi 129 | 130 | inform "Syncing clocks ($2), hc being $1 ..." 131 | if [ "$1" = "UTC" ]; then 132 | if ! hwclock --$2 --utc 133 | then 134 | show_warning 'Hwclock failure' "Could not hwclock --$2 --utc" 135 | return 1 136 | fi 137 | else 138 | if ! hwclock --$2 --localtime 139 | then 140 | show_warning 'Hwclock failure' "Could not hwclock --$2 --localtime" 141 | return 1 142 | fi 143 | fi 144 | return 0 145 | } 146 | 147 | target_configure_initial_keymap_font () 148 | { 149 | local ret=0 150 | if [ -n "$var_KEYMAP" ]; then 151 | sed -i "s/^KEYMAP=.*/KEYMAP=\"`basename $var_KEYMAP .map.gz`\"/" ${var_TARGET_DIR}/etc/rc.conf || ret=$? 152 | fi 153 | if [ -n "$var_CONSOLEFONT" ]; then 154 | sed -i "s/^CONSOLEFONT=.*/CONSOLEFONT=\"${var_CONSOLEFONT/\.*/}\"/" ${var_TARGET_DIR}/etc/rc.conf || ret=$? 155 | fi 156 | return $ret 157 | } 158 | 159 | target_configure_time () { 160 | # /etc/rc.conf 161 | # Make sure timezone and utc info are what we want 162 | # NOTE: If a timezone string never contains more then 1 slash, we can use ${TIMEZONE/\//\\/} 163 | sed -i -e "s/^TIMEZONE=.*/TIMEZONE=\"${TIMEZONE//\//\\/}\"/g" \ 164 | -e "s/^HARDWARECLOCK=.*/HARDWARECLOCK=\"$HARDWARECLOCK\"/g" \ 165 | ${var_TARGET_DIR}/etc/rc.conf 166 | } 167 | 168 | target_localtime () { 169 | if [ -f /etc/localtime ] 170 | then 171 | cp /etc/localtime ${var_TARGET_DIR}/etc/localtime || return 1 172 | fi 173 | return 0 174 | } 175 | 176 | # apped string after last line matching regex in a file. 177 | # $1 regex 178 | # $2 string (can contain "\n", "\t" etc) 179 | # $3 file 180 | append_after_last () 181 | { 182 | [ -r "$3" -a -w "$3" ] || return 1 183 | line_no=$(sed -ne "$1=" "$3" | tail -n 1) 184 | [ -n "$line_no" ] || return 1 185 | sed -i ${line_no}a"$2" "$3" 186 | } 187 | -------------------------------------------------------------------------------- /src/core/libs/lib-network.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # configures network on host system according to installer settings 4 | # if some variables are not set, we handle that transparantly 5 | # however, at least $DHCP must be set, so we know what do to 6 | # we assume that you checked whether networking has been setup before calling us 7 | target_configure_network() 8 | { 9 | # networking setup could have happened in a separate process (eg partial-configure-network), 10 | # so check if the settings file was created to be sure 11 | if [[ -f "$RUNTIME_DIR/aif-network-settings" ]]; then 12 | 13 | debug NETWORK "Configuring network settings on target system according to installer settings" 14 | 15 | source "$RUNTIME_DIR/aif-network-settings" 2>/dev/null || return 1 16 | 17 | IFN=${INTERFACE:-eth0} # new iface: a specified one, or the arch default 18 | 19 | if [[ -f "${var_TARGET_DIR}/etc/profile.d/proxy.sh" ]]; then 20 | sed -i "s/^export/#export/" "${var_TARGET_DIR}/etc/profile.d/proxy.sh" || return 1 21 | fi 22 | 23 | sed -i "s/^\(interface\)=.*/\1=$IFN/" "${var_TARGET_DIR}/etc/rc.conf" || return 1 24 | if (( ! DHCP )); then 25 | sed -i -e "s/^\(address\)=.*/\1=$IPADDR/" \ 26 | -e "s/^\(netmask\)=.*/\1=$SUBNET/" \ 27 | -e "s/^\(broadcast\)=.*/\1=$BROADCAST/" \ 28 | -e "s/^\(gateway\)=.*/\1=$GW/" "${var_TARGET_DIR}/etc/rc.conf" || return 1 29 | 30 | if [[ $DNS ]]; then 31 | for prev_dns in "${auto_added_dns[@]}"; do 32 | sed -i "/nameserver $prev_dns$/d" "${var_TARGET_DIR}/etc/resolv.conf" 33 | done 34 | echo "nameserver $DNS" >> "${var_TARGET_DIR}/etc/resolv.conf" || return 2 35 | auto_added_dns+=("$DNS") 36 | fi 37 | fi 38 | 39 | if [[ $PROXY_HTTP ]]; then 40 | echo "export http_proxy=$PROXY_HTTP" >> "${var_TARGET_DIR}/etc/profile.d/proxy.sh" || return 1 41 | chmod a+x "${var_TARGET_DIR}/etc/profile.d/proxy.sh" || return 1 42 | fi 43 | 44 | if [[ $PROXY_FTP ]]; then 45 | echo "export ftp_proxy=$PROXY_FTP" >> "${var_TARGET_DIR}/etc/profile.d/proxy.sh" || return 1 46 | chmod a+x "${var_TARGET_DIR}/etc/profile.d/proxy.sh" || return 1 47 | fi 48 | else 49 | debug NETWORK "Skipping Host Network Configuration - aif-network-settings not found" 50 | fi 51 | return 0 52 | } 53 | -------------------------------------------------------------------------------- /src/core/libs/lib-pacman.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # target_prepare_pacman(): 4 | # configures pacman to run from live environment, but working on target system. 5 | # syncs for the first time on destination system 6 | # Enables all reposities specified by TARGET_REPOSITORIES 7 | # returns: 1 on error 8 | target_prepare_pacman() { 9 | # Setup a pacman.conf in /tmp 10 | echo "[options]" > /tmp/pacman.conf 11 | echo "CacheDir = ${var_TARGET_DIR}/var/cache/pacman/pkg" >> /tmp/pacman.conf 12 | # construct real directory names from pseudonyms like (2 array elements): 13 | # core file:///repo/$repo/$arch 14 | # ideally, we would query those from pacman (which is also who interprets 15 | # these), but pacman does not support something like that, so we do it a bit 16 | # uglier. See https://bugs.archlinux.org/task/25568 17 | arch=$(uname -m) 18 | for line in $(echo ${TARGET_REPOSITORIES[@]} | tr ' ' '\n' | grep -B 1 'file://' | grep -v '\-\-'); do 19 | if ! echo $line | grep -q '^file://'; then 20 | repo=$line 21 | else 22 | cachedir=$(echo $line | sed -e "s#file://##;s#\$repo#$repo#;s#\$arch#$arch#") 23 | [ -d $cachedir ] || die_error "You specified $line (->$cachedir) as a directory to be used as repository, but it does not exist" 24 | echo "CacheDir = $cachedir" >> /tmp/pacman.conf 25 | fi 26 | done 27 | echo "Architecture = auto" >> /tmp/pacman.conf 28 | echo "SigLevel = Never" >> /tmp/pacman.conf 29 | 30 | for i in `seq 0 $((${#TARGET_REPOSITORIES[@]}/2-1))` 31 | do 32 | repo=${TARGET_REPOSITORIES[$(($i*2))]} 33 | location=${TARGET_REPOSITORIES[$(($i*2+1))]} 34 | add_pacman_repo target $repo $location || return 1 35 | done 36 | 37 | if [ -n "$MIRROR" ]; then 38 | configure_mirrorlist runtime || return 1 39 | fi 40 | 41 | # Set up the necessary directories for pacman use 42 | for dir in var/cache/pacman/pkg var/lib/pacman 43 | do 44 | if [ ! -d "${var_TARGET_DIR}/$dir" ] 45 | then 46 | mkdir -m 755 -p "${var_TARGET_DIR}/$dir" || return 1 47 | fi 48 | done 49 | 50 | inform "Refreshing package database..." 51 | $PACMAN_TARGET -Sy >$LOG 2>&1 || return 1 52 | return 0 53 | } 54 | 55 | 56 | # $1 target/runtime 57 | list_pacman_repos () 58 | { 59 | [ "$1" != runtime -a "$1" != target ] && die_error "list_pacman_repos needs target/runtime argument" 60 | [ "$1" = target ] && conf=/tmp/pacman.conf 61 | [ "$1" = runtime ] && conf=/etc/pacman.conf 62 | grep '\[.*\]' $conf | grep -v options | grep -v '^#' | sed 's/\[//g' | sed 's/\]//g' 63 | } 64 | 65 | # returns all repositories you could possibly use (core, extra, testing, community, ...) 66 | list_possible_repos () 67 | { 68 | grep -B 2 'Include = /etc/' /etc/pacman.conf | grep '\[' | sed 's/#*\[\(.*\)\]/\1/' 69 | } 70 | 71 | 72 | # $1 target/runtime 73 | # $2 repo name 74 | # $3 string 75 | # automatically knows that if $3 contains the word 'mirrorlist', it should save 76 | # as 'Include = $3', otherwise as 'Server = $3' (for both local and remote) 77 | add_pacman_repo () 78 | { 79 | [ "$1" != runtime -a "$1" != target ] && die_error "add_pacman_repo needs target/runtime argument" 80 | [ -z "$3" ] && die_error "target_add_repo needs \$2 repo-name and \$3 string (eg Server = ...)" 81 | repo=$2 82 | if echo "$3" | grep -q 'mirrorlist'; then 83 | location="Include = $3" 84 | else 85 | location="Server = $3" 86 | fi 87 | [ "$1" = target ] && conf=/tmp/pacman.conf 88 | [ "$1" = runtime ] && conf=/etc/pacman.conf 89 | cat << EOF >> $conf 90 | 91 | [$repo] 92 | $location 93 | EOF 94 | } 95 | 96 | # not sorted 97 | list_package_groups () 98 | { 99 | $PACMAN_TARGET -Sg 100 | } 101 | 102 | 103 | # List the packages in one or more repos or groups. output is one or more lines, each line being like this: 104 | # packagename [version, if $1=repo] [installed] 105 | # lines are sorted by packagename, per repo, repos in the order you gave them to us. 106 | # $1 repo or group 107 | # $2 one or more repo or group names 108 | list_packages () 109 | { 110 | [ "$1" = repo -o "$1" = group ] || die_error "list_packages \$1 must be repo or group. not $1!" 111 | [ "$1" = repo ] && $PACMAN_TARGET -Sl $2 112 | [ "$1" = group ] && $PACMAN_TARGET -Sg $2 113 | } 114 | 115 | # find out the group to which one or more packages belong 116 | # arguments: packages 117 | # output format: multiple lines, each line like: 118 | # 119 | # order is the same as the input 120 | which_group () 121 | { 122 | PACKAGE_GROUPS=`LANG=C $PACMAN_TARGET -Si "$@" | awk '/^Name/{ printf("%s ",$3) } /^Group/{ print $3 }'` 123 | } 124 | 125 | # get group and packagedesc for packages 126 | # arguments: packages 127 | # output format: multiple lines, each line like: 128 | # 129 | # order is the same as the input 130 | # note that space is used as separator, but desc is the only thing that will contain spaces. 131 | pkginfo () 132 | { 133 | PACKAGE_INFO=`LANG=C $PACMAN_TARGET -Si "$@" | awk '/^Name/{ printf("%s ",$3) } /^Version/{ printf("%s ",$3) } /^Group/{ printf("%s", $3) } /^Description/{ for(i=3;i<=NF;++i) printf(" %s",$i); printf ("\n")}' | awk '!x[$1]++'` 134 | } 135 | 136 | # $1 target/runtime 137 | configure_mirrorlist () { 138 | local file 139 | [ "$1" != runtime -a "$1" != target ] && die_error "configure_mirrorlist needs target/runtime argument" 140 | # add installer-selected mirror to the top of the mirrorlist, unless it's already at the top. previously added mirrors are kept (a bit lower), you never know.. 141 | [ "$1" = 'runtime' ] && file="$var_MIRRORLIST" 142 | [ "$1" = 'target' ] && file="${var_TARGET_DIR}/$var_MIRRORLIST" 143 | if [ -n "$MIRROR" ]; then 144 | if ! grep "^Server =" -m 1 "$file" | grep -q "$MIRROR" 145 | then 146 | debug 'PACMAN PROCEDURE' "Adding choosen mirror ($MIRROR) to $file" 147 | mirrorlist=`awk "BEGIN { printf(\"# Mirror selected during installation\nServer = "$MIRROR"\n\n\") } 1 " "$file"` || return $? 148 | echo "$mirrorlist" > "$file" || return $? 149 | fi 150 | fi 151 | return 0 152 | } 153 | 154 | -------------------------------------------------------------------------------- /src/core/libs/lib-software.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TMP_MKINITCPIO_LOG=$LOG_DIR/mkinitcpio.log 4 | TMP_PACMAN_LOG=$LOG_DIR/pacman.log 5 | 6 | # runs mkinitcpio on the target system, displays output 7 | # $1 preset name. default: linux 8 | target_run_mkinitcpio() 9 | { 10 | local preset=${1:-linux} 11 | target_special_fs on 12 | 13 | run_controlled mkinitcpio "chroot $var_TARGET_DIR mkinitcpio -p $preset" $TMP_MKINITCPIO_LOG "Rebuilding initcpio images ..." 14 | 15 | target_special_fs off 16 | 17 | # alert the user to fatal errors 18 | [ $CONTROLLED_EXIT -ne 0 ] && show_warning "MKINITCPIO FAILED - SYSTEM MAY NOT BOOT" "$TMP_MKINITCPIO_LOG" text 19 | return $CONTROLLED_EXIT 20 | } 21 | 22 | 23 | # perform package installation to the target system 24 | installpkg() { 25 | ALL_PACKAGES= 26 | [ -n "$var_TARGET_GROUPS" ] && ALL_PACKAGES=`list_packages group "$var_TARGET_GROUPS" | awk '{print $2}'` 27 | if [ -n "$var_TARGET_PACKAGES_EXCLUDE" ] 28 | then 29 | for excl in $var_TARGET_PACKAGES_EXCLUDE 30 | do 31 | ALL_PACKAGES=${ALL_PACKAGES//$excl/} 32 | done 33 | fi 34 | 35 | if [ -n "$var_TARGET_PACKAGES" ] 36 | then 37 | [ -n "$ALL_PACKAGES" ] && ALL_PACKAGES="$ALL_PACKAGES $var_TARGET_PACKAGES" 38 | [ -z "$ALL_PACKAGES" ] && ALL_PACKAGES=$var_TARGET_PACKAGES 39 | fi 40 | ALL_PACKAGES=`echo $ALL_PACKAGES` 41 | [ -z "$ALL_PACKAGES" ] && die_error "No packages/groups specified to install" 42 | 43 | target_special_fs on 44 | 45 | notify "Package installation will begin now. You can watch the output in the progress window. Please be patient." 46 | 47 | run_controlled pacman_installpkg "$PACMAN_TARGET --noconfirm -S $ALL_PACKAGES" $TMP_PACMAN_LOG "Installing... Please Wait" 48 | 49 | local _result='' 50 | if [ $CONTROLLED_EXIT -ne 0 ]; then 51 | _result="Installation Failed (see errors below)" 52 | echo -e "\nPackage Installation FAILED." >>$TMP_PACMAN_LOG 53 | else 54 | _result="Installation Complete" 55 | echo -e "\nPackage Installation Complete." >>$TMP_PACMAN_LOG 56 | fi 57 | 58 | show_warning "$_result" "$TMP_PACMAN_LOG" text || return 1 59 | 60 | target_special_fs off 61 | sync 62 | 63 | return $CONTROLLED_EXIT 64 | } 65 | 66 | 67 | # enable glibc locales from rc.conf and build initial locale DB 68 | target_configure_initial_locale() 69 | { 70 | for i in $(grep "^LOCALE=" ${var_TARGET_DIR}/etc/rc.conf | sed -e 's/.*="//g' -e's/\..*//g'); do 71 | sed -i -e "s/^#$i/$i/g" ${var_TARGET_DIR}/etc/locale.gen 72 | done 73 | target_locale-gen 74 | } 75 | 76 | 77 | target_locale-gen () 78 | { 79 | inform "Generating glibc base locales..." 80 | chroot ${var_TARGET_DIR} locale-gen >/dev/null 81 | } 82 | 83 | target_configure_initcpio () { 84 | local ret=0 85 | # Give initcpio the encrypt hook when / depends on an encrypted volume 86 | # (other encrypted volumes, not related to / don't need the encrypt hook, afaik) 87 | # If / also depends on lvm, this way the lvm2 hook will also be included in the right place 88 | if get_anchestors_mount ';/;' 89 | then 90 | hooks=`echo "$ANSWER_DEVICES" | cut -d ' ' -f2 | egrep 'lvm-lv|dm_crypt' | sed -e 's/lvm-lv/lvm2/' -e 's/dm_crypt/encrypt/' | tac` 91 | hooks=`echo $hooks` # $hooks is now a space separated, correctly ordered list of needed hooks 92 | if [ -n "$hooks" ] 93 | then 94 | # for each hook we're about to add, remove it first if it's already in 95 | for hook in $hooks 96 | do 97 | sed -i "/^HOOKS/ s/$hook //" ${var_TARGET_DIR}/etc/mkinitcpio.conf || ret=$? 98 | done 99 | # now add the correctly ordered string 100 | sed -i "/^HOOKS/ s/filesystems/$hooks filesystems/" ${var_TARGET_DIR}/etc/mkinitcpio.conf || ret=$? 101 | fi 102 | fi 103 | # The lvm2 hook however is needed for any lvm LV, no matter the involved mountpoints, so include it if we still need to 104 | if grep -q lvm-lv $TMP_BLOCKDEVICES && ! grep -q '^HOOKS.*lvm2' ${var_TARGET_DIR}/etc/mkinitcpio.conf 105 | then 106 | sed -i "/^HOOKS/ s/filesystems/lvm2 filesystems/" ${var_TARGET_DIR}/etc/mkinitcpio.conf || ret=$? 107 | fi 108 | 109 | # if keymap/usbinput are not in mkinitcpio.conf, but encrypt is, we should probably add it 110 | if line=`grep '^HOOKS.*encrypt' ${var_TARGET_DIR}/etc/mkinitcpio.conf` 111 | then 112 | if ! echo "$line" | grep -q keymap 113 | then 114 | sed -i '/^HOOKS/ s/encrypt/keymap encrypt/' ${var_TARGET_DIR}/etc/mkinitcpio.conf || ret=$? 115 | fi 116 | if ! echo "$line" | grep -q usbinput 117 | then 118 | sed -i '/^HOOKS/ s/keymap/usbinput keymap/' ${var_TARGET_DIR}/etc/mkinitcpio.conf || ret=$? 119 | fi 120 | fi 121 | return $ret 122 | } 123 | -------------------------------------------------------------------------------- /src/core/libs/lib-ui.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Note that $var_UI_TYPE may not be set here. especially if being loaded in the "early bootstrap" phase 3 | 4 | source /usr/lib/libui.sh 5 | 6 | # mandatory to call me when you want to use me. call me again after setting $var_UI_TYPE 7 | ui_init () 8 | { 9 | cats="MAIN PROCEDURE UI UI-INTERACTIVE FS MISC NETWORK PACMAN SOFTWARE" 10 | if [ "$LOG_TO_FILE" = '1' ]; then 11 | logs="$LOG $LOGFILE" 12 | else 13 | logs=$LOG 14 | fi 15 | if [ "$DEBUG" = '1' ]; then 16 | libui_sh_init "${var_UI_TYPE:-cli}" "$RUNTIME_DIR" "$logs" "$cats" 17 | else 18 | libui_sh_init "${var_UI_TYPE:-cli}" "$RUNTIME_DIR" "$logs" 19 | fi 20 | 21 | # get keymap/font (maybe configured by aif allready in another process or even in another shell) 22 | # otherwise, take default keymap and consolefont as configured in /etc/rc.conf. can be overridden 23 | # Note that the vars in /etc/rc.conf can also be empty! 24 | [ -e $RUNTIME_DIR/aif-keymap ] && var_KEYMAP=` cat $RUNTIME_DIR/aif-keymap` 25 | [ -e $RUNTIME_DIR/aif-consolefont ] && var_CONSOLEFONT=`cat $RUNTIME_DIR/aif-consolefont` 26 | [ -z "$var_KEYMAP" ] && source /etc/rc.conf && var_KEYMAP=$KEYMAP 27 | [ -z "$var_CONSOLEFONT" ] && source /etc/rc.conf && var_CONSOLEFONT=$CONSOLEFONT 28 | } 29 | 30 | # taken from setup 31 | printk() 32 | { 33 | case $1 in 34 | "on") echo 4 >/proc/sys/kernel/printk ;; 35 | "off") echo 0 >/proc/sys/kernel/printk ;; 36 | esac 37 | } 38 | 39 | 40 | # Get a list of available partionable blockdevices for use in ask_option 41 | # populates array $BLOCKFRIENDLY with elements like: 42 | # '/dev/sda' '/dev/sda 640133 MiB (640 GiB)' 43 | listblockfriendly() 44 | { 45 | BLOCKFRIENDLY=() 46 | for i in $(finddisks) 47 | do 48 | get_blockdevice_size $i MiB 49 | size_GiB=$(($BLOCKDEVICE_SIZE/2**10)) 50 | BLOCKFRIENDLY+=($i "$i ${BLOCKDEVICE_SIZE} MiB ($size_GiB GiB)") 51 | done 52 | } 53 | 54 | # captitalize first character 55 | function capitalize () { 56 | sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g'; 57 | } 58 | 59 | set_keymap () 60 | { 61 | KBDDIR="/usr/share/kbd" 62 | 63 | KEYMAPS=() 64 | local keymap 65 | for keymap in $(find $KBDDIR/keymaps -name "*.gz" | sort); do 66 | KEYMAPS+=("${keymap##$KBDDIR/keymaps/}" -) 67 | done 68 | ask_option "${var_KEYMAP:-no}" "Select a keymap" '' optional "${KEYMAPS[@]}" 69 | if [ -n "$ANSWER_OPTION" ] 70 | then 71 | loadkeys -q $KBDDIR/keymaps/$ANSWER_OPTION 72 | var_KEYMAP=$ANSWER_OPTION 73 | echo "$var_KEYMAP" > $RUNTIME_DIR/aif-keymap 74 | fi 75 | 76 | FONTS=() 77 | local font 78 | for font in $(find $KBDDIR/consolefonts -maxdepth 1 -name "*.gz" | sed 's|^.*/||g' | sort); do 79 | FONTS+=("$font" -) 80 | done 81 | ask_option "${var_CONSOLEFONT:-no}" "Select a console font" '' optional "${FONTS[@]}" 82 | if [ -n "$ANSWER_OPTION" ] 83 | then 84 | var_CONSOLEFONT=$ANSWER_OPTION 85 | local i 86 | for i in 1 2 3 4 87 | do 88 | if [ -d /dev/vc ]; then 89 | setfont $KBDDIR/consolefonts/$var_CONSOLEFONT -C /dev/vc/$i 90 | else 91 | setfont $KBDDIR/consolefonts/$var_CONSOLEFONT -C /dev/tty$i 92 | fi 93 | done 94 | echo "$var_CONSOLEFONT" > $RUNTIME_DIR/aif-consolefont 95 | fi 96 | } 97 | 98 | # $1 "topic" 99 | # shift 1; "$@" list of failed things 100 | warn_failed () { 101 | local topic=$1 102 | shift 103 | if [ -n "$1" ] 104 | then 105 | local list_failed= 106 | while [ -n "$1" ] 107 | do 108 | [ -n "$list_failed" ] && list_failed="$list_failed, " 109 | list_failed="${list_failed}$1" 110 | shift 111 | done 112 | show_warning "Preconfigure failed" "Beware: the following steps failed: $list_failed. Please report this. Continue at your own risk" 113 | fi 114 | return 0 115 | } 116 | 117 | # $1 basedir. default: empty 118 | ask_mkinitcpio_preset () { 119 | local basedir=$1 120 | presets=($(for i in $(ls -1 $basedir/etc/mkinitcpio.d/*.preset | grep -v example\.preset); do basename $i .preset; echo '-'; done)) 121 | num_presets=$((${#presets[@]}/2)) 122 | if [[ $num_presets -lt 1 ]]; then 123 | die_error "Not a single mkinitcpio preset found in $basedir/etc/mkinitcpio.d/ ? No kernel installed? WTF?" 124 | elif [[ $num_presets -eq 1 ]]; then 125 | # this is the most likely case: the user just installed 1 kernel.. 126 | echo ${presets[0]} 127 | else 128 | ask_option 'no' "Build initcpio for which preset/kernel?" '' '' "${presets[@]}" 129 | echo $ANSWER_OPTION 130 | fi 131 | return 0 132 | } 133 | 134 | # $1 default option, or 'no' for none 135 | # $1 name of the filesystem (or partition/device) to ask for 136 | ask_mountpoint () { 137 | local default=$1 138 | local part=$2 139 | local opts=(/ 'root' /boot 'files for booting' /home 'home directories' /var 'variable files' /tmp 'temporary files' custom 'enter a custom mountpoint') 140 | ask_option $default "Select the mountpoint" "Select a mountpoint for $part" required "${opts[@]}" || return 1 141 | if [ "$ANSWER_OPTION" == custom ]; then 142 | [ "$default" == 'no' ] && default= 143 | ask_string "Enter the custom mountpoint for $part" "$default" || return 1 144 | echo $ANSWER_STRING 145 | else 146 | echo $ANSWER_OPTION 147 | fi 148 | } 149 | -------------------------------------------------------------------------------- /src/core/procedures/automatic: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This is a procedure for automatic deployment/installation/configuration of systems. 3 | # check /usr/share/aif/examples for some example config files. 4 | # This procedure can easily replace the old quickinst script if you look at the "generic install" config file 5 | # Look at the base procedure to see the phases and which workers they'll execute. 6 | # It should be: 7 | # phase_preparation=(configure intro sysprep select_source runtime_network runtime_repositories runtime_packages) 8 | # phase_basics=(set_clock prepare_disks) 9 | # phase_system=(package_list install_packages configure_system install_bootloader) 10 | # phase_finish=(msg_report) 11 | 12 | # In theory, the only manual thing should maybe be configuring the runtime network and putting the configfile in place 13 | # I don't know if you can do non-interactive dm_crypt stuff.. maybe by pulling luks keyfiles from svn/git/..? 14 | # TODO: implement setting hostname, keymap, consolefont, network settings, root pass, etc 15 | # for a list of recognized variables, see examples/generic-install-on-sda 16 | 17 | depend_procedure core base # important, don't be confused when worker/variable definitions seem to be missing here. 18 | 19 | var_OPTS_STRING="c:" 20 | var_ARGS_USAGE="-c : Specify a configfile (profile) to be used" 21 | var_AUTOMATIC_PROFILE="" 22 | # TODO: if the user does aif -p automatic -c, then $1 is ":-" ??? if you do -c then it's ok. 23 | process_args () 24 | { 25 | if [ "$1" = '-c' ] 26 | then 27 | [ -z "$2" ] && die_error "You must specify a config" 28 | var_AUTOMATIC_PROFILE=$2 29 | else 30 | usage 31 | exit 5 32 | fi 33 | } 34 | 35 | 36 | worker_intro () 37 | { 38 | notify "Automatic procedure running profile $var_AUTOMATIC_PROFILE ...\n$DISCLAIMER" 39 | } 40 | 41 | 42 | worker_configure () 43 | { 44 | var_UI_TYPE=${arg_ui_type:-cli} 45 | ui_init 46 | [ -z "$var_AUTOMATIC_PROFILE" ] && die_error "You must specify a config file to use this procedure" 47 | source $var_AUTOMATIC_PROFILE || die_error "Could not source config $var_AUTOMATIC_PROFILE" 48 | # Check mandatory options 49 | [ -z "$PARTITIONS" ] && die_error "You did not specify a partition scheme" 50 | [ -z "$BLOCKDATA" ] && die_error "You did not specify a partition scheme" 51 | [ -z "$TARGET_REPOSITORIES" ] && die_error "You did not specify \$TARGET_REPOSITORIES" 52 | # initialize internal variables based on variables set by the user (some of the vars are handled in other workers): 53 | var_RUNTIME_REPOSITORIES=$RUNTIME_REPOSITORIES 54 | var_RUNTIME_PACKAGES=$RUNTIME_PACKAGES 55 | var_PARTITIONS=$PARTITIONS 56 | var_BLOCKDATA=$BLOCKDATA 57 | HARDWARECLOCK=${HARDWARECLOCK:-localtime} 58 | TIMEZONE=${TIMEZONE:-Canada/Pacific} 59 | } 60 | 61 | worker_select_source () 62 | { 63 | true # TARGET_REPOSITORIES, MIRROR is already sourced from config 64 | } 65 | 66 | worker_prepare_disks () 67 | { 68 | get_possible_fs 69 | echo "$var_PARTITIONS" > $TMP_PARTITIONS 70 | echo "$var_BLOCKDATA" > $TMP_BLOCKDEVICES 71 | process_disks || die_error "Could not process_disks" 72 | if ! process_filesystems 73 | then 74 | show_warning 'Disk processing' "Could not process_filesystems" 75 | txt='also failed to execute properly' 76 | rollback_filesystems && txt='ended successfully' 77 | die_error "Something failed while processing the filesystem. A rollback was executed, which $txt" 78 | fi 79 | inform "Partitions and filesystems made successfully" 80 | 81 | # TODO: fstab? auto-add to fstab with libs? auto mkdir's on target_dir? 82 | } 83 | 84 | worker_package_list () 85 | { 86 | var_TARGET_PACKAGES="$TARGET_PACKAGES syslinux" 87 | var_TARGET_GROUPS=$TARGET_GROUPS 88 | var_TARGET_PACKAGES_EXCLUDE=$TARGET_PACKAGES_EXCLUDE 89 | [ -z "$var_TARGET_PACKAGES" -a -z "$var_TARGET_GROUPS" ] && var_TARGET_GROUPS=base 90 | true 91 | } 92 | 93 | 94 | worker_install_packages () 95 | { 96 | target_prepare_pacman && installpkg 97 | } 98 | 99 | 100 | worker_set_clock () 101 | { 102 | # uses $TIMEZONE, clock itself remains untouched. 103 | copy_timezone_file 104 | } 105 | 106 | 107 | worker_install_bootloader () 108 | { 109 | syslinux-install_update -iam -c "$var_TARGET_DIR" || return 1 110 | } 111 | -------------------------------------------------------------------------------- /src/core/procedures/base: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this procedure is meant to be inherited from 4 | var_DEFAULTFS="/boot:32:ext2:+ swap:256:swap /:7500:ext3 /home:*:ext3" 5 | var_TARGET_DIR="/mnt" # When overriding this, do _not_ add a trailing /. It's not needed and maybe you could even break something 6 | var_RUNTIME_REPOSITORIES= # array like this ('name1' 'location of repo 1' ['name2' 'location of repo2',..]) 7 | var_RUNTIME_PACKAGES= 8 | var_PKG_FILE=$RUNTIME_DIR/aif-package-list # not used by default in base/interactive. can be used by custom procedures or profiles for the automatic procedure 9 | var_MIRRORLIST="/etc/pacman.d/mirrorlist" 10 | var_UI_TYPE="cli" # set to cli or dia for dialog 11 | var_ARCH=`uname -m` #i686 or x86_64. NOTE: this assumes you want to install the same arch as the installation environment you're using. maybe we could decouple those someday.. 12 | [ -z "$var_ARCH" ] && die_error "Could not determine your architecture" 13 | syslinuxmenu="$var_TARGET_DIR$syslinuxmenu" 14 | 15 | ###### Phases ( can be overridden by more specific procedures) ###### 16 | phase_preparation=(\ 17 | configure \ 18 | intro \ 19 | sysprep \ 20 | select_source \ 21 | runtime_network \ 22 | runtime_repositories \ 23 | runtime_packages) 24 | 25 | phase_basics=(\ 26 | set_clock \ 27 | prepare_disks) 28 | 29 | phase_system=(\ 30 | package_list \ 31 | install_packages \ 32 | configure_system \ 33 | install_bootloader) 34 | 35 | phase_finish=(msg_report) 36 | 37 | 38 | 39 | ###### Workers ( can be overridden by more specific procedures) ###### 40 | worker_intro () 41 | { 42 | ask_yesno "This is a low-interactivity 'common defaults' installation, not meant for direct invocation. Do you really want to do this? We may overwrite your data." 43 | if [ $? -gt 0 ] 44 | then 45 | die_error "User aborted base profile execution" 46 | fi 47 | true 48 | } 49 | 50 | 51 | worker_sysprep () 52 | { 53 | mount -o remount,rw / &>/dev/null 54 | } 55 | 56 | 57 | worker_configure () 58 | { 59 | var_UI_TYPE=${arg_ui_type:-cli} 60 | ui_init 61 | } 62 | 63 | 64 | # this function must set TARGET_REPOSITORIES, which should contain at least 1 65 | # core repo If you want to use a network mirror, $MIRROR should be 66 | # set, we will populate the needed mirrorlists after select_source. although 67 | # you can also use a remote repository directly without using a mirrorlist but 68 | # either way you should set $MIRROR so that we can know when networking is 69 | # needed, we do this in a few places in the code. 70 | worker_select_source () 71 | { 72 | true 73 | } 74 | 75 | 76 | worker_runtime_network () 77 | { 78 | #override if needed 79 | true 80 | } 81 | 82 | 83 | worker_runtime_repositories () 84 | { 85 | for i in `seq 0 $((${#var_RUNTIME_REPOSITORIES[@]}/2-1))` 86 | do 87 | repo=${var_RUNTIME_REPOSITORIES[$(($i*2))]} 88 | location=${var_RUNTIME_REPOSITORIES[$(($i*2+1))]} 89 | if ! list_pacman_repos runtime | grep -q $repo 90 | then 91 | add_pacman_repo runtime $repo "$location" || return 1 92 | fi 93 | done 94 | return 0 95 | } 96 | 97 | 98 | worker_runtime_packages () 99 | { 100 | if [ -n "$var_RUNTIME_PACKAGES" ] 101 | then 102 | $PACMAN -Sy --noconfirm --needed $var_RUNTIME_PACKAGES 103 | fi 104 | } 105 | 106 | 107 | worker_set_clock () 108 | { 109 | local default=no 110 | local timezone_file_copied=0 111 | while true; do 112 | ask_option $default "Date/time configuration" '' required \ 113 | "1" "Select region and timezone" \ 114 | "2" "Set time and date" \ 115 | "3" "Return to Main Menu" || return 1 116 | case $ANSWER_OPTION in 117 | "1") execute worker interactive_timezone && copy_timezone_file && timezone_file_copied=1 && default=2 || return 1 ;; 118 | "2") if check_depend worker interactive_timezone 119 | then 120 | execute worker interactive_time && default=3 || return 1 121 | fi ;; 122 | "3") break ;; 123 | esac 124 | done 125 | [ $timezone_file_copied -eq 1 ] || copy_timezone_file || return 1 126 | return 0 127 | } 128 | 129 | 130 | worker_interactive_timezone () 131 | { 132 | interactive_timezone 133 | } 134 | 135 | 136 | worker_interactive_time () 137 | { 138 | interactive_time 139 | } 140 | 141 | 142 | worker_prepare_disks () 143 | { 144 | partition && get_possible_fs 145 | # in official installer: autoprepare or diy first partitions, then mountpoints 146 | } 147 | 148 | 149 | # Put the list of packages to be installed in $var_TARGET_PACKAGES and $var_TARGET_GROUPS 150 | worker_package_list () 151 | { 152 | var_TARGET_GROUPS=base 153 | } 154 | 155 | 156 | worker_install_packages () 157 | { 158 | target_prepare_pacman && installpkg 159 | } 160 | 161 | worker_configure_system () 162 | { 163 | preconfigure_target && postconfigure_target 164 | } 165 | 166 | 167 | worker_install_bootloader () 168 | { 169 | true 170 | } 171 | 172 | worker_msg_report () 173 | { 174 | show_report 175 | } 176 | -------------------------------------------------------------------------------- /src/core/procedures/interactive: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | depend_procedure core base # esp for auto_network, intro and set_clock workers 3 | 4 | 5 | # This is a port of the original /arch/setup script. It doesn't use aif phases but uses it's own menu-based flow (phase) control 6 | 7 | BLOCK_ROLLBACK_USELESS=1 8 | 9 | # clock 10 | HARDWARECLOCK= 11 | TIMEZONE= 12 | 13 | # default filesystem specs (the + is bootable flag) 14 | # ::[:+] 15 | DEFAULTFS="/boot:32:ext2:+ swap:256:swap /:7500:ext3 /home:*:ext3" 16 | 17 | # this is a workaround for bash <4.2, where associative arrays are inherently local 18 | # once we have 4.2 we can just declare this array global. eval $settitles where needed 19 | settitles="declare -A workertitles 20 | workertitles['select_source']='Select source' 21 | workertitles['set_editor']='Set editor' 22 | workertitles['runtime_network']='Setup network' 23 | workertitles['set_clock']='Set clock' 24 | workertitles['prepare_disks']='Prepare hard drive(s)' 25 | workertitles['package_list']='Select packages' 26 | workertitles['install_packages']='Install packages' 27 | workertitles['configure_system']='Configure system' 28 | workertitles['install_bootloader']='Install bootloader' 29 | workertitles['msg_report']='Exit Install'" 30 | 31 | menu_workers=(select_source set_editor set_clock prepare_disks package_list install_packages configure_system install_bootloader msg_report) 32 | 33 | start_process () 34 | { 35 | ##################### 36 | ## begin execution ## 37 | 38 | execute worker configure 39 | execute worker intro 40 | execute worker sysprep 41 | 42 | mainmenu 43 | } 44 | 45 | 46 | mainmenu() 47 | { 48 | local default=1 49 | while true 50 | do 51 | eval "$settitles" 52 | menu=() 53 | for i in ${!menu_workers[@]} 54 | do 55 | worker=${menu_workers[$i]} 56 | title=${workertitles[$worker]} 57 | let i+=1 # in menu, we count from 1 onwards, not from 0 58 | menu+=($i "$title") 59 | done 60 | 61 | ask_option $default "MAIN MENU" '' required "${menu[@]}" 62 | case $ANSWER_OPTION in 63 | "1") execute worker select_source && \ 64 | execute worker runtime_packages && default=2 ;; 65 | "2") execute worker set_editor && default=3 ;; 66 | "3") execute worker set_clock && default=4 ;; 67 | "4") execute worker prepare_disks && default=5 ;; 68 | "5") check_depend worker prepare_disks && \ 69 | check_depend worker select_source && execute worker package_list && default=6 ;; 70 | "6") check_depend worker package_list && \ 71 | check_depend worker select_source && execute worker install_packages && default=7 ;; 72 | "7") check_depend worker install_packages && execute worker configure_system && default=8 ;; 73 | "8") check_depend worker configure_system && execute worker install_bootloader && default=9 ;; 74 | "9") execute worker msg_report ;; 75 | *) execute worker abort_installer;; 76 | esac 77 | done 78 | } 79 | 80 | 81 | worker_configure_system() 82 | { 83 | interactive_configure_system 84 | } 85 | 86 | 87 | worker_prepare_disks() 88 | { 89 | get_possible_fs && interactive_prepare_disks 90 | } 91 | 92 | 93 | worker_select_source () 94 | { 95 | interactive_select_source || return $? 96 | if [ -n "$MIRROR" ]; then 97 | if ask_yesno "Make sure the network is ok before continuing the installer. ${workertitles['runtime_network']} now?"; then 98 | execute worker runtime_network || return $? 99 | fi 100 | fi 101 | return 0 102 | } 103 | 104 | worker_set_editor () 105 | { 106 | seteditor force 107 | } 108 | 109 | worker_intro () 110 | { 111 | notify "Welcome to the Arch Linux Installation program. The install\ 112 | process is fairly straightforward, and you should run through the options in\ 113 | the order they are presented. If you are unfamiliar with partitioning/making\ 114 | filesystems, you may want to consult some documentation before continuing.\ 115 | You can view all output from commands by viewing your VC7 console (ALT-F7).\ 116 | ALT-F1 will bring you back here.\n\n$DISCLAIMER" 117 | } 118 | 119 | 120 | worker_configure () 121 | { 122 | var_UI_TYPE=${arg_ui_type:-dia} 123 | ui_init 124 | } 125 | 126 | 127 | # select_packages() 128 | # prompts the user to select packages to install 129 | worker_package_list() { 130 | # if selection has been done before, warn about loss of input and let the user exit gracefully 131 | ended_ok worker package_list && ! ask_yesno "WARNING: Running this stage again will result in the loss of previous package selections.\n\nDo you wish to continue?" && return 0 132 | 133 | interactive_select_packages 134 | } 135 | 136 | 137 | worker_install_packages () 138 | { 139 | installpkg 140 | } 141 | 142 | 143 | # Hand-hold through setting up networking 144 | worker_runtime_network() { 145 | interactive_runtime_network 146 | } 147 | 148 | worker_install_bootloader () 149 | { 150 | interactive_install_bootloader 151 | } 152 | 153 | # override show_report because this procedure does not use phases, but it's own menu 154 | show_report () 155 | { 156 | eval "$settitles" 157 | data="Execution Report:" 158 | data="$data\n-----------------" 159 | for worker in ${menu_workers[@]} 160 | do 161 | [ "$worker" = 'msg_report' ] && continue # this worker is the one calling show_report, we can't know our exitcode yet 162 | title=${workertitles[$worker]} 163 | exit_var=exit_worker_$worker 164 | local ret=${!exit_var} 165 | case "$ret" in 166 | "") data="$data\n > $title: Skipped";; 167 | "0") data="$data\n > $title: Success";; 168 | *) data="$data\n > $title: Failed";; 169 | esac 170 | done 171 | notify "$data\nIf the install finished successfully, you can type 'reboot' to restart the system." || return $? 172 | } 173 | 174 | worker_msg_report () { 175 | show_report && stop_installer 176 | } 177 | 178 | worker_abort_installer () 179 | { 180 | local ret=0 181 | ask_yesno "Abort Installation?" || return 182 | maybe_interactive_rollback_filesystems || ret=$? 183 | stop_installer || ret=$? 184 | return $ret 185 | } 186 | -------------------------------------------------------------------------------- /src/core/procedures/partial-configure-network: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | depend_procedure core interactive 3 | 4 | start_process () 5 | { 6 | execute worker runtime_network 7 | } -------------------------------------------------------------------------------- /src/core/procedures/partial-disks: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | depend_procedure core base 3 | 4 | var_OPTS_STRING="o:" 5 | var_ARGS_USAGE="-o process/rollback: Operation: process the blockdevice layer or roll it back?" 6 | 7 | process_args () 8 | { 9 | if [ "$1" = '-o' ] 10 | then 11 | [ "$2" != process -a "$2" != rollback ] && die_error "You must specify 'process' or 'rollback'" 12 | OPERATION=$2 13 | else 14 | usage 15 | exit 5 16 | fi 17 | } 18 | 19 | 20 | start_process () 21 | { 22 | [ -z "$OPERATION" ] && usage && exit 5 23 | 24 | if [ "$OPERATION" = process ] 25 | then 26 | process_disks 27 | process_filesystems 28 | elif [ "$OPERATION" = rollback ] 29 | then 30 | rollback_filesystems 31 | fi 32 | } 33 | -------------------------------------------------------------------------------- /src/core/procedures/partial-keymap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | start_process () 4 | { 5 | var_UI_TYPE=dia 6 | ui_init 7 | set_keymap 8 | } 9 | -------------------------------------------------------------------------------- /src/user/whatsthis.txt: -------------------------------------------------------------------------------- 1 | put user-specific modules here. should be empty in the 'official' version -------------------------------------------------------------------------------- /tests/buildtime/test-check_is_in.sh: -------------------------------------------------------------------------------- 1 | basedir=$(dirname "`dirname $0`") 2 | source $basedir/src/core/libs/lib-ui.sh #dependency needed 3 | source $basedir/src/core/libs/lib-misc.sh 4 | 5 | vars=(A B C D E F) 6 | check_is_in C "${vars[@]}" && echo 'ok C was in there' || echo 'wtf' 7 | check_is_in AOEUAU "${vars[@]}" && echo wtf || echo 'ok it was not in there' 8 | -------------------------------------------------------------------------------- /tests/buildtime/test-menus.sh: -------------------------------------------------------------------------------- 1 | basedir=$(dirname "`dirname $0`") 2 | source $basedir/src/core/libs/lib-ui.sh 3 | ANSWER="/tmp/aif-test-dialog-answer" 4 | for ui in dia cli 5 | do 6 | for type in required optional 7 | do 8 | for default in no tag-c 9 | do 10 | var_UI_TYPE=$ui 11 | ask_option $default 'menu title ($2)' 'extra explanation ($3)'" settings: type: $type, default:$default" $type tagA itemA "tag B" 'item B' tag-c item\ C 12 | notify "RETURN CODE: $?\nANSWER: $ANSWER_OPTION" 13 | done 14 | done 15 | done 16 | -------------------------------------------------------------------------------- /tests/lib/framework-runtime: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | lib="/usr/share/aif/tests/lib" 3 | STATUS=0 4 | 5 | # $1 name of test 6 | # $2... other args 7 | function aiftest () { 8 | name=$1 9 | shift 10 | if [ ! -f $lib/test-$name ] 11 | then 12 | echo "NO SUCH TEST: $lib/test-$1" >&2 13 | return 2 14 | else 15 | $lib/test-$name "$@" 16 | local ret=$? 17 | fi 18 | if [ $ret -eq 0 ] 19 | then 20 | echo "$name $@ : OK" 21 | else 22 | echo "$name $@ : NOT OK ($ret)" 23 | fi 24 | [ $ret -gt $STATUS ] && STATUS=$ret 25 | } 26 | 27 | aiftest-done () { 28 | if [ $STATUS -eq 0 ] 29 | then 30 | echo 'ALL TESTS ENDED SUCCESSFULLY' 31 | exit 0 32 | else 33 | echo 'ONE OR MORE TESTS FAILED!' >&2 34 | exit $STATUS 35 | fi 36 | } 37 | -------------------------------------------------------------------------------- /tests/lib/setup-file: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | for i in "$@" 3 | do 4 | touch $i/test_file 5 | done 6 | -------------------------------------------------------------------------------- /tests/lib/test-file: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 filename 3 | 4 | [ -f "$1" ] 5 | -------------------------------------------------------------------------------- /tests/lib/test-lvm-lv: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 VG 3 | # $2 LV 4 | # $2 SIZE eg '800.00 MB' 5 | 6 | lvdisplay | grep -A 5 "LV Name.*/dev/$1/$2" | grep -q available || exit 1 7 | lvdisplay | grep -A 7 "LV Name.*/dev/$1/$2"| grep -q 'LV Size.*'"$2" || exit 2 8 | -------------------------------------------------------------------------------- /tests/lib/test-mount: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 mount output string 3 | 4 | mount | grep -q '/dev/cryptpool/crypthome on /home type xfs (rw)' 5 | -------------------------------------------------------------------------------- /tests/lib/test-nofile: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 filename 3 | 4 | [ ! -f "$1" ] 5 | -------------------------------------------------------------------------------- /tests/lib/test-nopackage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 packagename 3 | 4 | if pacman -Qi $1 &>/dev/null 5 | then 6 | exit 1 7 | else 8 | exit 0 9 | fi 10 | -------------------------------------------------------------------------------- /tests/lib/test-ping: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 iterations 3 | # $2 host 4 | 5 | ping -c $1 $2 6 | -------------------------------------------------------------------------------- /tests/lib/test-swap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | free -m | grep -q 'Swap:.*'$1'.*' -------------------------------------------------------------------------------- /tests/runtime/automatic-dmcrypt-lvm-install-sda/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | aif -p automatic -c /usr/share/aif/tests/runtime/automatic-dmcrypt-lvm-install-sda/profile -d -------------------------------------------------------------------------------- /tests/runtime/automatic-dmcrypt-lvm-install-sda/perform_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source /usr/share/aif/tests/lib/framework-runtime 4 | 5 | aiftest swap 19 6 | aiftest lvm-lv mypool root '800.00 MB' 7 | aiftest mount '/dev/mypool/rootcrypt on / type xfs (rw)' 8 | for i in /etc/ / /root/ /home/ /var/ 9 | do 10 | aiftest file "$i"test_file 11 | done 12 | aiftest file /usr/bin/ssh 13 | aiftest nofile /sbin/mkfs.reiserfs 14 | aiftest nopackage sudo 15 | aiftest ping 2 archlinux.org 16 | 17 | aiftest-done 18 | -------------------------------------------------------------------------------- /tests/runtime/automatic-dmcrypt-lvm-install-sda/profile: -------------------------------------------------------------------------------- 1 | TARGET_REPOSITORIES=(core 'file:///repo/$repo/$arch') 2 | RUNTIME_REPOSITORIES=(testing ftp://mir1.archlinuxfr.org/archlinux/testing/os/$var_ARCH) 3 | RUNTIME_PACKAGES= 4 | 5 | # packages to install 6 | TARGET_GROUPS=base 7 | TARGET_PACKAGES_EXCLUDE='reiserfsprogs' 8 | TARGET_PACKAGES='openssh aif e2fsprogs cryptsetup lvm2 xfsprogs' 9 | 10 | # These variables are mandatory 11 | 12 | PARTITIONS='/dev/sda 40:ext2:+ *:ext4' 13 | BLOCKDATA='/dev/sda1 raw no_label ext2;yes;/boot;target;no_opts;no_label;no_params 14 | /dev/sda2 raw lvm-pv;yes;no_mountpoint;target;no_opts;no_label;no_params 15 | /dev/sda2+ lvm-pv no_label lvm-vg;yes;no_mountpoint;target;no_opts;mypool;/dev/sda2 16 | /dev/mapper/mypool lvm-vg mypool lvm-lv;yes;no_mountpoint;target;no_opts;root;800M 17 | /dev/mapper/mypool-root lvm-lv no_label dm_crypt;yes;no_mountpoint;target;no_opts;mypool-rootcrypt;-c__aes-xts-plain__-y__-s__512 18 | /dev/mapper/mypool-rootcrypt dm_crypt no_label xfs;yes;/;target;no_opts;no_label;no_params' 19 | -------------------------------------------------------------------------------- /tests/runtime/automatic-dmcrypt-lvm-install-sda/setup_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in /etc/ / /root/ /home/ /var/ 4 | do 5 | touch /mnt${i}test_file 6 | done 7 | -------------------------------------------------------------------------------- /tests/runtime/automatic-lvm-dmcrypt-install-sda/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | aif -p automatic -c /usr/share/aif/tests/runtime/automatic-lvm-dmcrypt-install-sda/profile -d -------------------------------------------------------------------------------- /tests/runtime/automatic-lvm-dmcrypt-install-sda/perform_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source /usr/share/aif/tests/lib/framework-runtime 4 | 5 | aiftest swap 19 6 | aiftest lvm-lv cryptpool cryptroot '800.00 MB' 7 | aiftest mount '/dev/cryptpool/cryptroot on / type xfs (rw)' 8 | aiftest mount '/dev/cryptpool/crypthome on /home type xfs (rw)' 9 | for i in /etc/ / /root/ /home/ /var/ 10 | do 11 | aiftest file "$i"test_file 12 | done 13 | aiftest file /usr/bin/ssh 14 | aiftest nofile /sbin/mkfs.reiserfs 15 | aiftest nopackage sudo 16 | aiftest ping 2 archlinux.org 17 | 18 | aiftest-done 19 | -------------------------------------------------------------------------------- /tests/runtime/automatic-lvm-dmcrypt-install-sda/profile: -------------------------------------------------------------------------------- 1 | TARGET_REPOSITORIES=(core 'file:///repo/$repo/$arch') 2 | RUNTIME_REPOSITORIES=(testing ftp://mir1.archlinuxfr.org/archlinux/testing/os/$var_ARCH) 3 | RUNTIME_PACKAGES= 4 | 5 | # packages to install 6 | TARGET_GROUPS=base 7 | TARGET_PACKAGES_EXCLUDE='reiserfsprogs' 8 | TARGET_PACKAGES='openssh aif e2fsprogs cryptsetup lvm2 xfsprogs' 9 | 10 | # These variables are mandatory 11 | 12 | PARTITIONS='/dev/sda 40:ext2:+ *:ext4' 13 | BLOCKDATA='/dev/sda1 raw no_label ext2;yes;/boot;target;no_opts;no_label;no_params 14 | /dev/sda2 raw no_label dm_crypt;yes;no_mountpoint;target;no_opts;sda2crypt;-c__aes-xts-plain__-y__-s__512 15 | /dev/mapper/sda2crypt dm_crypt no_label lvm-pv;yes;no_mountpoint;target;no_opts;no_label;no_params 16 | /dev/mapper/sda2crypt+ lvm-pv no_label lvm-vg;yes;no_mountpoint;target;no_opts;cryptpool;/dev/mapper/sda2crypt 17 | /dev/mapper/cryptpool lvm-vg cryptpool lvm-lv;yes;no_mountpoint;target;no_opts;cryptswap;20M|lvm-lv;yes;no_mountpoint;target;no_opts;cryptroot;800M|lvm-lv;yes;no_mountpoint;target;no_opts;crypthome;50M 18 | /dev/mapper/cryptpool-cryptswap lvm-lv no-label swap;yes;no_mountpoint;target;no_opts;no_label;no_params 19 | /dev/mapper/cryptpool-cryptroot lvm-lv no_label xfs;yes;/;target;no_opts;no_label;no_params 20 | /dev/mapper/cryptpool-crypthome lvm-lv no_label xfs;yes;/home;target;no_opts;no_label;no_params' 21 | -------------------------------------------------------------------------------- /tests/runtime/automatic-lvm-dmcrypt-install-sda/setup_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in /etc/ / /root/ /home/ /var/ 4 | do 5 | touch /mnt${i}test_file 6 | done 7 | -------------------------------------------------------------------------------- /tests/runtime/automatic-reuse-fs-sda/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # sda1 boot, sda2 will be swap, sda3 /, sda4 which will contain the "existing filesystem of the user" with "important data" on it. 4 | sfdisk -D /dev/sda -uM << EOF 5 | ,50,,* 6 | ,20,S 7 | ,800, 8 | ,, 9 | EOF 10 | mke2fs -j /dev/sda4 11 | mkdir /tmp/aif-test-mount 12 | mount /dev/sda4 /tmp/aif-test-mount 13 | touch /tmp/aif-test-mount/important-userdata 14 | umount /tmp/aif-test-mount 15 | aif -p automatic -c /usr/share/aif/tests/runtime/automatic-reuse-fs-sda/profile -d -------------------------------------------------------------------------------- /tests/runtime/automatic-reuse-fs-sda/perform_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source /usr/share/aif/tests/lib/framework-runtime 4 | 5 | aiftest swap 48 6 | aiftest lvm-lv cryptpool cryptroot '800.00 MB' 7 | aiftest mount '/dev/sda3 on / type ext4 (rw)' 8 | aiftest mount '/dev/sda4 on /home type ext3 (rw)' 9 | for i in /etc/ / /root/ /home/ /var/ 10 | do 11 | aiftest file "$i"test_file 12 | done 13 | aiftest file /home/important-userdata 14 | aiftest ping 2 archlinux.org 15 | 16 | aiftest-done 17 | -------------------------------------------------------------------------------- /tests/runtime/automatic-reuse-fs-sda/profile: -------------------------------------------------------------------------------- 1 | TARGET_PACKAGES='aif e2fsprogs' 2 | RUNTIME_REPOSITORIES=(testing ftp://mir1.archlinuxfr.org/archlinux/testing/os/$var_ARCH) 3 | 4 | # modify worker_prepare_disks: we don't want to repartition (process_disks). also we want to do a rollback + setup again 5 | 6 | worker_prepare_disks () 7 | { 8 | echo "$var_BLOCKDATA" > $TMP_BLOCKDEVICES 9 | if process_filesystems 10 | then 11 | inform "disk processing ok" 12 | else 13 | show_warning 'disks processing' "PROCESSING FAILED" 14 | return 1 15 | fi 16 | if rollback_filesystems 17 | then 18 | inform "rollback ok" 19 | else 20 | show_warning 'disks rollback' "ROLLBACK FAILED" 21 | return 1 22 | fi 23 | if process_filesystems 24 | then 25 | inform "disk processing ok" 26 | else 27 | show_warning 'disk processing' "PROCESSING FAILED" 28 | return 1 29 | fi 30 | } 31 | 32 | PARTITIONS=this_wont_be_used 33 | BLOCKDATA='/dev/sda1 raw no_label ext2;yes;/boot;target;no_opts;no_label;no_params 34 | /dev/sda2 raw no_label swap;yes;no_mountpoint;target;no_opts;no_label;no_params 35 | /dev/sda3 raw no_label ext4;yes;/;target;no_opts;no_label;no_params 36 | /dev/sda4 raw no_label ext3;no;/home;target;no_opts;no_label;no_params' 37 | -------------------------------------------------------------------------------- /tests/runtime/automatic-reuse-fs-sda/setup_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in /etc/ / /root/ /home/ /var/ 4 | do 5 | touch /mnt${i}test_file 6 | done 7 | -------------------------------------------------------------------------------- /unofficial/dieter-desktop-a7n8x.automaticprofile: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # An example config for the deployment procedure 3 | 4 | # Use var_* for "standard" variables recognized by the automatic procedure. these should work for everyone. 5 | # use all other variable names for your own stuff. (eg i use them to define some things needed to pull my stuff from svn.) 6 | 7 | # TODO: install ruby-gems too 8 | # TODO * dieter/automatic: wait for yaourt --config fix ( http://forums.archlinux.fr/post23171.html#23171 ) 9 | # TODO:* dieter/automatic: put config files from svn in place first, so that if a package has an update, it can do it's thing. 10 | 11 | 12 | # when checking out /etc, configs may be outdated (meant for older packages), and we have no pacnew/pacsave files. but this should not cause too much problems.. 13 | var_RUNTIME_REPOSITORIES=(archlinuxfr http://repo.archlinux.fr/$var_ARCH) 14 | var_RUNTIME_PACKAGES="svn yaourt" 15 | 16 | DEPLOY_CLASS=desktop-a7n8x 17 | HOSTNAME=dieter-ws 18 | SVN_USERNAME=dieter 19 | SVN_PASSWORD= 20 | SVN_BASE=https://192.168.1.2/svn/repos 21 | 22 | var_PARTITIONS='/dev/sda 100:ext2:+ 2048:swap *:xfs' 23 | var_BLOCKDATA='/dev/sda1 raw no_label ext2;yes;/boot;target;no_opts;no_label;no_params 24 | /dev/sda2 raw no_label swap;yes;no_mountpoint;target;no_opts;no_label;no_params 25 | /dev/sda3 raw no_label dm_crypt;yes;no_mountpoint;target;no_opts;sda3crypt;-c__aes-xts-plain__-y__-s__512 26 | /dev/mapper/sda3crypt dm_crypt no_label lvm-pv;yes;no_mountpoint;target;no_opts;no_label;no_params 27 | /dev/mapper/sda3crypt+ lvm-pv no_label lvm-vg;yes;no_mountpoint;target;no_opts;cryptpool;/dev/mapper/sda3crypt 28 | /dev/mapper/cryptpool lvm-vg cryptpool lvm-lv;yes;no_mountpoint;target;no_opts;cryptroot;5G|lvm-lv;yes;no_mountpoint;target;no_opts;crypthome;5G 29 | /dev/cryptpool/cryptroot lvm-lv no_label xfs;yes;/;target;no_opts;no_label;no_params 30 | /dev/cryptpool/crypthome lvm-lv no_label xfs;yes;/home;target;no_opts;no_label;no_params' 31 | 32 | 33 | TARGET_PACKAGES='openssh e2fsprogs cryptsetup lvm2 xfsprogs' 34 | 35 | phase_preparation=(accept_ssl_cert "${phase_preparation[@]}") # make accept_ssl_cert the very first thing. it needs to go before fetch_configs and it's not easy to put it somewhere in the middle, so... 36 | phase_system+=(configure_home) 37 | 38 | 39 | # Deprecated. I try to keep everything in 1 config file now. that's cooler. 40 | #worker_fetch_configs () 41 | #{ 42 | # $SVN export $SVN_BASE/ddm-configs/$DEPLOY_CLASS/trunk/disks/.blockdata $RUNTIME_DIR/aif-blockdata || die_error "Could not svn export $SVN_BASE/ddm-configs/$DEPLOY_CLASS/trunk/disks/.blockdata to $RUNTIME_DIR/aif-blockdata" 43 | # $SVN export $SVN_BASE/ddm-configs/$DEPLOY_CLASS/trunk/disks/.partitions $RUNTIME_DIR/aif-partitions || die_error "Could not svn export $SVN_BASE/ddm-configs/$DEPLOY_CLASS/trunk/disks/.partitions to $RUNTIME_DIR/aif-partitions" 44 | #} 45 | 46 | 47 | 48 | worker_package_list () 49 | { 50 | $SVN export $SVN_BASE/ddm-configs/$DEPLOY_CLASS/trunk/package-list $var_PKG_FILE || die_error "Could not export package list!" 51 | # cat -> there are newlines in it -> var=`echo $var` -> not anymore :) 52 | TARGET_PACKAGES=`cat $var_PKG_FILE` && TARGET_PACKAGES=`echo $TARGET_PACKAGES` || die_error "Could not cat package list. THIS SHOULD NEVER HAPPEN." 53 | # Strip away all packages not known by pacman. To get all packages, you'll need to do that when the system is installed TODO: don't do this. WAITINGFOR: --config support in yaourt + 'list of md5s of trusted pkgbuilds' support in yaourt 54 | # NOTE: maybe chrooting could be an option too (to avoid --config support, but problem 2 stays) 55 | TARGET_PACKAGES=`$PACMAN_TARGET -Si $TARGET_PACKAGES 2>/dev/null | awk '/Name/ {print $3}'` 56 | TARGET_PACKAGES=`echo $TARGET_PACKAGES` #TODO: some stuff goes wrong here 57 | } 58 | 59 | 60 | worker_accept_ssl_cert () 61 | { 62 | mkdir -p /root/.subversion/auth/svn.ssl.server 63 | cat > /root/.subversion/auth/svn.ssl.server/1123d3c8b27895efee3848cc779e526a << EOF 64 | K 10 65 | ascii_cert 66 | V 716 67 | MIICFTCCAX6gAwIBAgIBAjANBgkqhkiG9w0BAQQFADBVMRswGQYDVQQKExJBcGFjaGUgSFRUUCBTZXJ2ZXIxIjAgBgNVBAsTGUZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0wNjA3MjQxMjUwMzdaFw0wNzA3MjQxMjUwMzdaMEwxGzAZBgNVBAoTEkFwYWNoZSBIVFRQIFNlcnZlcjEZMBcGA1UECxMQVGVzdCBDZXJ0aWZpY2F0ZTESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDF5PB1NnUve2jkisDTGsxKC9qzpnl+eX8UIR/1s+yX2ZIPNnIryeqTc6sS3cBHz2/AufIr0xbpXkTa4V5Es5bXA7W1D7+ZzuFHjjyi4E2eqYVkhkv1sRL5TpAovfjAA+96iaFHp3yKYiuw/nWwQTSW9M1VrDEym4ODxyJOtNdgQQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABY0bnBf9tL1WMC1sLxB1eDXvs5qNY96mny+EKGAbyQROPaXwsRQB0HrAkuWfHzQlgIdD6AfGsd+YMcEuqSPzIz6t6mA45jl++WvI6we9t3eYChtdPD2xjgHti0aSiDyVLTJbXPnkdgzKvIjYZcXBwbmbQSrg0STO5m+cSYt3chx 68 | K 8 69 | failures 70 | V 2 71 | 14 72 | K 15 73 | svn:realmstring 74 | V 23 75 | https://192.168.1.2:443 76 | END 77 | EOF 78 | } 79 | 80 | 81 | worker_configure_home () 82 | { 83 | #TODO checkout from svn 84 | true 85 | } 86 | 87 | 88 | 89 | # See http://wiki.archlinux.org/index.php/Yaourt 90 | 91 | # Not needed yet... 92 | #worker_install_packages () #pre_ / post_ callbacks would be useful here 93 | #{ 94 | # PACMAN_BACKUP=$PACMAN 95 | # PACMAN_TARGET_BACKUP=$PACMAN_TARGET 96 | # PACMAN=${PACMAN//pacman/yaourt} 97 | # PACMAN_TARGET=${PACMAN_TARGET//pacman/yaourt} 98 | 99 | # target_prepare_pacman core 100 | # [ -z "$TARGET_PACKAGES" ] && die_error "No packages listed to be installed!" 101 | # installpkg 102 | 103 | # PACMAN=$PACMAN_BACKUP 104 | # PACMAN_TARGET=$PACMAN_TARGET_BACKUP 105 | #} 106 | 107 | 108 | worker_set_clock () 109 | { 110 | #Not doing anything. hwclock is set already, configs are coming from svn anyway and we'll use ntp. 111 | true 112 | } 113 | 114 | worker_runtime_yaourt () 115 | { 116 | _yaourt_replace_pacman 117 | } 118 | -------------------------------------------------------------------------------- /unofficial/jdd-generic-install-sda-using-host-packages: -------------------------------------------------------------------------------- 1 | # this config explains the (all) available options. 2 | # the variables are optional and we define their defaults here (so you could omit the 3 | # definitions), unless otherwise specified. 4 | 5 | # Add all repositories you want to use here. Same style as for pacman.conf: 6 | # Local: file://... 7 | # Remote: something like ftp://ftp.belnet.be/mirror/archlinux.org/$repo/os/$arch 8 | # You should list both the name of the repo as well as the location, as separate 9 | # elements. 10 | # You can add multiple repositories and even mix remote and local ones. 11 | # The order they are in here, will be the order in pacman.conf 12 | # This is a mandatory variable, which should contain at least 1 core repository 13 | # This example will do the most sensible thing on both core and netinstall images: 14 | if [ -d /repo/core ]; then 15 | TARGET_REPOSITORIES=(core 'file:///repo/$repo/$arch') 16 | else 17 | MIRROR='ftp://mirrors.kernel.org/archlinux/$repo/os/$arch' 18 | TARGET_REPOSITORIES=(core 'http://10.0.2.2:15678/request/$repo/$arch') 19 | fi 20 | 21 | HARDWARECLOCK=localtime # UTC is the better option, but some OS'es don't support it (i.e. Windows) 22 | TIMEZONE=Canada/Pacific 23 | # Do you want to have additional pacman repositories or packages available at runtime (during installation)? 24 | # RUNTIME_REPOSITORIES same format as TARGET_REPOSITORIES 25 | RUNTIME_REPOSITORIES= 26 | # space separated list 27 | RUNTIME_PACKAGES= 28 | 29 | # packages to install 30 | TARGET_GROUPS=base # all packages in this group will be installed (defaults to base if no group and no packages are specified) 31 | TARGET_PACKAGES_EXCLUDE= # Exclude these packages if they are member of one of the groups in TARGET_GROUPS. example: 'nano reiserfsprogs' (they are in base) 32 | TARGET_PACKAGES='openssh e2fsprogs' # you can also specify separate packages to install (this is empty by default) 33 | 34 | # you can optionally also override some functions... 35 | # This way you can change/extend/remove pretty much all functionality in AIF ! 36 | worker_intro () { 37 | inform "Automatic procedure running the generic-install-on-sda example config. THIS WILL ERASE AND OVERWRITE YOUR /DEV/SDA. IF YOU DO NOT WANT THIS PRESS CTRL+C WITHIN 10 SECONDS" 38 | sleep 10 39 | } 40 | 41 | worker_configure_system () { 42 | preconfigure_target 43 | sed -i 's/^HOSTNAME="myhost"/HOSTNAME="arch-generic-install"/' $var_TARGET_DIR/etc/rc.conf 44 | postconfigure_target 45 | } 46 | 47 | PART_ACCESS= # can be set to 'uuid', 'dev', 'label', or leave empty for 'dev' 48 | 49 | # These variables are mandatory 50 | 51 | # '*' means all the remaining space 52 | # '+' means the bootable flag 53 | PARTITIONS='/dev/sda 100:ext2:+ 512:swap *:ext4' 54 | # if you wanted everything other than swap and boot on an extended partition, you can do like this: 55 | # PARTITIONS='/dev/sda 100:ext2:+ 512:swap :extended *:ext4' 56 | 57 | BLOCKDATA='/dev/sda1 raw no_label ext2;yes;/boot;target;no_opts;no_label;no_params 58 | /dev/sda2 raw no_label swap;yes;no_mountpoint;target;no_opts;no_label;no_params 59 | /dev/sda3 raw no_label ext4;yes;/;target;no_opts;no_label;no_params' 60 | -------------------------------------------------------------------------------- /unofficial/modules/dieter/procedures/dieter-automatic: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Dieters personal procedure, adds a bit on top of the official automatic procedure. 3 | # TODO: implement this. 4 | 5 | depend_procedure core automatic 6 | 7 | 8 | # Check if we have all needed settings loaded from the profile 9 | worker_runtime_settings () #TODO: add to a phase 10 | { 11 | if check_is_in svn $var_RUNTIME_PACKAGES 12 | then 13 | [ -z "$SVN_USERNAME" ] && ask_string "Please enter your svn username" && SVN_USERNAME=$ANSWER_STRING 14 | [ -z "$SVN_PASSWORD" ] && ask_password svn #TODO: if user entered incorrect password, the install process will just fail.. 15 | [ -z "$SVN_BASE" ] && ask_string "What's the base path of your svn repo? (no ending /) " && SVN_BASE=$ANSWER_STRING 16 | [ -z "$DEPLOY_CLASS" ] && ask_string "Which hostclass are you installing? (optional)" '' 0 && DEPLOY_CLASS=$ANSWER_STRING 17 | SVN="svn --username $SVN_USERNAME --password $SVN_PASSWORD" 18 | elif check_is_in moo $var_RUNTIME_PACKAGES 19 | then 20 | # Maybe more stuff later 21 | true 22 | fi 23 | [ -z "$HOSTNAME" ] && ask_string "Hostname of target system?" && 24 | HOSTNAME=$ANSWER_STRING 25 | 26 | return 0 27 | } 28 | --------------------------------------------------------------------------------